return (unsigned char)cris_ide_inw(reg);
 }
 
-static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int);
-static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
+static void cris_ide_input_data(ide_drive_t *, struct request *,
+                               void *, unsigned int);
+static void cris_ide_output_data(ide_drive_t *, struct request *,
+                                void *, unsigned int);
 static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
 static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
 
 /*
  * This is used for most PIO data transfers *from* the IDE interface
  */
-static void
-cris_ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+static void cris_ide_input_data(ide_drive_t *drive, struct request *rq,
+                               void *buffer, unsigned int wcount)
 {
        cris_atapi_input_bytes(drive, buffer, wcount << 2);
 }
 /*
  * This is used for most PIO data transfers *to* the IDE interface
  */
-static void
-cris_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+static void cris_ide_output_data(ide_drive_t *drive, struct request *,
+                                void *buffer, unsigned int wcount)
 {
        cris_atapi_output_bytes(drive, buffer, wcount << 2);
 }
 
                u32 wcount = (i > 16) ? 16 : i;
 
                i -= wcount;
-               HWIF(drive)->ata_input_data(drive, buffer, wcount);
+               drive->hwif->ata_input_data(drive, NULL, buffer, wcount);
        }
 }
 
 
 /*
  * This is used for most PIO data transfers *from* the IDE interface
  */
-static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount)
+static void ata_input_data(ide_drive_t *drive, struct request *rq,
+                          void *buffer, u32 wcount)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct ide_io_ports *io_ports = &hwif->io_ports;
 /*
  * This is used for most PIO data transfers *to* the IDE interface
  */
-static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount)
+static void ata_output_data(ide_drive_t *drive, struct request *rq,
+                           void *buffer, u32 wcount)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct ide_io_ports *io_ports = &hwif->io_ports;
        ide_hwif_t *hwif = HWIF(drive);
 
        ++bytecount;
-#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
-       if (MACH_IS_ATARI || MACH_IS_Q40) {
-               /* Atari has a byte-swapped IDE interface */
-               insw_swapw(hwif->io_ports.data_addr, buffer, bytecount / 2);
-               return;
-       }
-#endif /* CONFIG_ATARI || CONFIG_Q40 */
-       hwif->ata_input_data(drive, buffer, bytecount / 4);
+       hwif->ata_input_data(drive, NULL, buffer, bytecount / 4);
        if ((bytecount & 0x03) >= 2)
                hwif->INSW(hwif->io_ports.data_addr,
                           (u8 *)buffer + (bytecount & ~0x03), 1);
        ide_hwif_t *hwif = HWIF(drive);
 
        ++bytecount;
-#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
-       if (MACH_IS_ATARI || MACH_IS_Q40) {
-               /* Atari has a byte-swapped IDE interface */
-               outsw_swapw(hwif->io_ports.data_addr, buffer, bytecount / 2);
-               return;
-       }
-#endif /* CONFIG_ATARI || CONFIG_Q40 */
-       hwif->ata_output_data(drive, buffer, bytecount / 4);
+       hwif->ata_output_data(drive, NULL, buffer, bytecount / 4);
        if ((bytecount & 0x03) >= 2)
                hwif->OUTSW(hwif->io_ports.data_addr,
                            (u8 *)buffer + (bytecount & ~0x03), 1);
                local_irq_restore(flags);
                return 0;
        }
-       hwif->ata_input_data(drive, id, SECTOR_WORDS);
+       hwif->ata_input_data(drive, NULL, id, SECTOR_WORDS);
        (void)ide_read_status(drive);   /* clear drive IRQ */
        local_irq_enable();
        local_irq_restore(flags);
 
 
        id = drive->id;
        /* read 512 bytes of id info */
-       hwif->ata_input_data(drive, id, SECTOR_WORDS);
+       hwif->ata_input_data(drive, NULL, id, SECTOR_WORDS);
 
        drive->id_read = 1;
        local_irq_enable();
 
        return stat;
 }
 
-static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
+static void ide_pio_sector(ide_drive_t *drive, struct request *rq,
+                          unsigned int write)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct scatterlist *sg = hwif->sg_table;
 
        /* do the actual data transfer */
        if (write)
-               hwif->ata_output_data(drive, buf, SECTOR_WORDS);
+               hwif->ata_output_data(drive, rq, buf, SECTOR_WORDS);
        else
-               hwif->ata_input_data(drive, buf, SECTOR_WORDS);
+               hwif->ata_input_data(drive, rq, buf, SECTOR_WORDS);
 
        kunmap_atomic(buf, KM_BIO_SRC_IRQ);
 #ifdef CONFIG_HIGHMEM
 #endif
 }
 
-static void ide_pio_multi(ide_drive_t *drive, unsigned int write)
+static void ide_pio_multi(ide_drive_t *drive, struct request *rq,
+                         unsigned int write)
 {
        unsigned int nsect;
 
        nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count);
        while (nsect--)
-               ide_pio_sector(drive, write);
+               ide_pio_sector(drive, rq, write);
 }
 
 static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
        switch (drive->hwif->data_phase) {
        case TASKFILE_MULTI_IN:
        case TASKFILE_MULTI_OUT:
-               ide_pio_multi(drive, write);
+               ide_pio_multi(drive, rq, write);
                break;
        default:
-               ide_pio_sector(drive, write);
+               ide_pio_sector(drive, rq, write);
                break;
        }
 
 
 int falconide_intr_lock;
 EXPORT_SYMBOL(falconide_intr_lock);
 
+static void falconide_atapi_input_bytes(ide_drive_t *drive, void *buf,
+                                       unsigned int len)
+{
+       insw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
+}
+
+static void falconide_atapi_output_bytes(ide_drive_t *drive, void *buf,
+                                        unsigned int len)
+{
+       outsw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
+}
+
+static void falconide_ata_input_data(ide_drive_t *drive, struct request *rq,
+                                    void *buf, unsigned int wcount)
+{
+       if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+               return insw(drive->hwif->io_ports.data_addr, buf, wcount * 2);
+
+       falconide_atapi_input_bytes(drive, buf, wcount * 4);
+}
+
+static void falconide_ata_output_data(ide_drive_t *drive, struct request *rq,
+                                     void *buf, unsigned int wcount)
+{
+       if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+               return outsw(drive->hwif->io_ports.data_addr, buf, wcount * 2);
+
+       falconide_atapi_output_bytes(drive, buf, wcount * 4);
+}
+
 static void __init falconide_setup_ports(hw_regs_t *hw)
 {
        int i;
                ide_init_port_data(hwif, index);
                ide_init_port_hw(hwif, &hw);
 
+               /* Atari has a byte-swapped IDE interface */
+               hwif->atapi_input_bytes  = falconide_atapi_input_bytes;
+               hwif->atapi_output_bytes = falconide_atapi_output_bytes;
+               hwif->ata_input_data     = falconide_ata_input_data;
+               hwif->ata_output_data    = falconide_ata_output_data;
+
                ide_get_lock(NULL, NULL);
                ide_device_add(idx, NULL);
                ide_release_lock();
 
        hw->ack_intr = ack_intr;
 }
 
+static void q40ide_atapi_input_bytes(ide_drive_t *drive, void *buf,
+                                    unsigned int len)
+{
+       insw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
+}
 
+static void q40ide_atapi_output_bytes(ide_drive_t *drive, void *buf,
+                                     unsigned int len)
+{
+       outsw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
+}
+
+static void q40ide_ata_input_data(ide_drive_t *drive, struct request *rq,
+                                 void *buf, unsigned int wcount)
+{
+       if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+               return insw(drive->hwif->io_ports.data_addr, buf, wcount * 2);
+
+       q40ide_atapi_input_bytes(drive, buf, wcount * 4);
+}
+
+static void q40ide_ata_output_data(ide_drive_t *drive, struct request *rq,
+                                  void *buf, unsigned int wcount)
+{
+       if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+               return outsw(drive->hwif->io_ports.data_addr, buf, wcount * 2);
+
+       q40ide_atapi_output_bytes(drive, buf, wcount * 4);
+}
 
 /* 
  * the static array is needed to have the name reported in /proc/ioports,
                ide_init_port_data(hwif, hwif->index);
                ide_init_port_hw(hwif, &hw);
 
+               /* Q40 has a byte-swapped IDE interface */
+               hwif->atapi_input_bytes  = q40ide_atapi_input_bytes;
+               hwif->atapi_output_bytes = q40ide_atapi_output_bytes;
+               hwif->ata_input_data     = q40ide_ata_input_data;
+               hwif->ata_output_data    = q40ide_ata_output_data;
+
                idx[i] = hwif->index;
        }
     }
 
        const struct ide_port_ops       *port_ops;
        const struct ide_dma_ops        *dma_ops;
 
-       void (*ata_input_data)(ide_drive_t *, void *, u32);
-       void (*ata_output_data)(ide_drive_t *, void *, u32);
+       void (*ata_input_data)(ide_drive_t *, struct request *, void *, u32);
+       void (*ata_output_data)(ide_drive_t *, struct request *, void *, u32);
 
        void (*atapi_input_bytes)(ide_drive_t *, void *, u32);
        void (*atapi_output_bytes)(ide_drive_t *, void *, u32);