]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
ide: move ide_config_drive_speed() calls to upper layers (take 2)
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Sat, 13 Oct 2007 15:47:51 +0000 (17:47 +0200)
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Sat, 13 Oct 2007 15:47:51 +0000 (17:47 +0200)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.

* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
  the host for the transfer mode after programming the device.  Set it
  in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
  and via82cxxx host drivers.

* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
  skip programming of host/device for the transfer mode ("smart" hosts).
  Set it in it821x host driver and check it in ide_tune_dma().

* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
  direct ->set_pio_mode/->speedproc users to use these helpers.

* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
  methods to callers.

* Rename ->speedproc method to ->set_dma_mode, make it void and update
  all implementations accordingly.

* Update ide_set_xfer_rate() comments.

* Unexport ide_config_drive_speed().

v2:
* Fix issues noticed by Sergei:
  - export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
    to setting DMA modes from sc1200_set_pio_mode() to do_special()
  - check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
  - check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
  - check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
  - return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
  - don't set ->set_{pio,dma}_mode on it821x in "smart" mode
  - fix build problem in pmac.c
  - minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
  - improve patch description

Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
  PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
  the device (not really an issue since 0x00 is not supported correctly by
  any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)

Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
36 files changed:
drivers/ide/arm/icside.c
drivers/ide/cris/ide-cris.c
drivers/ide/ide-dma.c
drivers/ide/ide-iops.c
drivers/ide/ide-lib.c
drivers/ide/ide.c
drivers/ide/mips/au1xxx-ide.c
drivers/ide/pci/aec62xx.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/amd74xx.c
drivers/ide/pci/atiixp.c
drivers/ide/pci/cmd64x.c
drivers/ide/pci/cs5520.c
drivers/ide/pci/cs5530.c
drivers/ide/pci/cs5535.c
drivers/ide/pci/hpt34x.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/it8213.c
drivers/ide/pci/it821x.c
drivers/ide/pci/jmicron.c
drivers/ide/pci/pdc202xx_new.c
drivers/ide/pci/pdc202xx_old.c
drivers/ide/pci/piix.c
drivers/ide/pci/sc1200.c
drivers/ide/pci/scc_pata.c
drivers/ide/pci/serverworks.c
drivers/ide/pci/sgiioc4.c
drivers/ide/pci/siimage.c
drivers/ide/pci/sis5513.c
drivers/ide/pci/sl82c105.c
drivers/ide/pci/slc90e66.c
drivers/ide/pci/tc86c001.c
drivers/ide/pci/triflex.c
drivers/ide/pci/via82cxxx.c
drivers/ide/ppc/pmac.c
include/linux/ide.h

index 110e52377c7139dd04e7fa4ba814cb8d4d266f2b..bd1f5b6703784463df33404a74cd4fe12dc6ebdf 100644 (file)
@@ -248,7 +248,7 @@ static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
  *     MW1     80      50      50      150     C
  *     MW2     70      25      25      120     C
  */
-static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode)
+static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
 {
        int cycle_time, use_dma_info = 0;
 
@@ -273,7 +273,7 @@ static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode)
                cycle_time = 480;
                break;
        default:
-               return 1;
+               return;
        }
 
        /*
@@ -287,8 +287,6 @@ static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode)
 
        printk("%s: %s selected (peak %dMB/s)\n", drive->name,
                ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
-
-       return ide_config_drive_speed(drive, xfer_mode);
 }
 
 static void icside_dma_host_off(ide_drive_t *drive)
@@ -433,7 +431,7 @@ static void icside_dma_init(ide_hwif_t *hwif)
 
        hwif->dmatable_cpu      = NULL;
        hwif->dmatable_dma      = 0;
-       hwif->speedproc         = icside_set_speed;
+       hwif->set_dma_mode      = icside_set_dma_mode;
        hwif->autodma           = 1;
 
        hwif->ide_dma_check     = icside_dma_check;
index 4bb42b30bfc0d34874d5549abbb37b33b4c833ee..2b4d2a0ae5c26e1d7bf7f42b1630b0c36a6332ab 100644 (file)
@@ -716,11 +716,9 @@ static void cris_set_pio_mode(ide_drive_t *drive, const u8 pio)
        }
 
        cris_ide_set_speed(TYPE_PIO, setup, strobe, hold);
-
-       (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
 }
 
-static int speed_cris_ide(ide_drive_t *drive, const u8 speed)
+static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        int cyc = 0, dvs = 0, strobe = 0, hold = 0;
 
@@ -759,8 +757,6 @@ static int speed_cris_ide(ide_drive_t *drive, const u8 speed)
                cris_ide_set_speed(TYPE_UDMA, cyc, dvs, 0);
        else
                cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
-
-       return ide_config_drive_speed(drive, speed);
 }
 
 void __init
@@ -791,7 +787,7 @@ init_e100_ide (void)
                hwif->mmio = 1;
                hwif->chipset = ide_etrax100;
                hwif->set_pio_mode = &cris_set_pio_mode;
-               hwif->speedproc = &speed_cris_ide;
+               hwif->set_dma_mode = &cris_set_dma_mode;
                hwif->ata_input_data = &cris_ide_input_data;
                hwif->ata_output_data = &cris_ide_output_data;
                hwif->atapi_input_bytes = &cris_atapi_input_bytes;
index 05781faaddd8b9bf94f21dcd81440a691c6463b9..b453211ee0fc1364cebe09be3bd0296bf6500207 100644 (file)
@@ -774,7 +774,10 @@ int ide_tune_dma(ide_drive_t *drive)
        if (!speed)
                return 0;
 
-       if (drive->hwif->speedproc(drive, speed))
+       if (drive->hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+               return 0;
+
+       if (ide_set_dma_mode(drive, speed))
                return 0;
 
        return 1;
index e5fc2e5059594693901c04ecad5419111ab05ad0..f5e73e2950d433664e82d387675dda5f5bd62f50 100644 (file)
@@ -862,9 +862,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
        return error;
 }
 
-EXPORT_SYMBOL(ide_config_drive_speed);
-
-
 /*
  * This should get invoked any time we exit the driver to
  * wait for an interrupt response from a drive.  handler() points
index d97390c0543b823e4da4176e158f8a0061b6ebb9..0e2562f0f74ec55f8455b04f322ba866cea8a06b 100644 (file)
@@ -349,7 +349,7 @@ void ide_set_pio(ide_drive_t *drive, u8 req_pio)
                          drive->name, host_pio, req_pio,
                          req_pio == 255 ? "(auto-tune)" : "", pio);
 
-       hwif->set_pio_mode(drive, pio);
+       (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
 }
 
 EXPORT_SYMBOL_GPL(ide_set_pio);
@@ -378,39 +378,83 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
                blk_queue_bounce_limit(drive->queue, addr);
 }
 
+int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
+{
+       ide_hwif_t *hwif = drive->hwif;
+
+       if (hwif->set_pio_mode == NULL)
+               return -1;
+
+       /*
+        * TODO: temporary hack for some legacy host drivers that didn't
+        * set transfer mode on the device in ->set_pio_mode method...
+        */
+       if (hwif->set_dma_mode == NULL) {
+               hwif->set_pio_mode(drive, mode - XFER_PIO_0);
+               return 0;
+       }
+
+       if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+               if (ide_config_drive_speed(drive, mode))
+                       return -1;
+               hwif->set_pio_mode(drive, mode - XFER_PIO_0);
+               return 0;
+       } else {
+               hwif->set_pio_mode(drive, mode - XFER_PIO_0);
+               return ide_config_drive_speed(drive, mode);
+       }
+}
+
+int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
+{
+       ide_hwif_t *hwif = drive->hwif;
+
+       if (hwif->set_dma_mode == NULL)
+               return -1;
+
+       if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+               if (ide_config_drive_speed(drive, mode))
+                       return -1;
+               hwif->set_dma_mode(drive, mode);
+               return 0;
+       } else {
+               hwif->set_dma_mode(drive, mode);
+               return ide_config_drive_speed(drive, mode);
+       }
+}
+
+EXPORT_SYMBOL_GPL(ide_set_dma_mode);
+
 /**
  *     ide_set_xfer_rate       -       set transfer rate
  *     @drive: drive to set
- *     @speed: speed to attempt to set
+ *     @rate: speed to attempt to set
  *     
  *     General helper for setting the speed of an IDE device. This
  *     function knows about user enforced limits from the configuration
- *     which speedproc() does not.  High level drivers should never
- *     invoke speedproc() directly.
+ *     which ->set_pio_mode/->set_dma_mode does not.
  */
+
 int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
 {
        ide_hwif_t *hwif = drive->hwif;
 
-       if (hwif->speedproc == NULL)
+       if (hwif->set_dma_mode == NULL)
                return -1;
 
        rate = ide_rate_filter(drive, rate);
 
-       if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) {
-               if (hwif->set_pio_mode)
-                       hwif->set_pio_mode(drive, rate - XFER_PIO_0);
+       if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
+               return ide_set_pio_mode(drive, rate);
 
-               /*
-                * FIXME: this is incorrect to return zero here but
-                * since all users of ide_set_xfer_rate() ignore
-                * the return value it is not a problem currently
-                */
-               return 0;
-       }
+       /*
+        * TODO: transfer modes 0x00-0x07 passed from the user-space are
+        * currently handled here which needs fixing (please note that such
+        * case could happen iff the transfer mode has already been set on
+        * the device by ide-proc.c::set_xfer_rate()).
+        */
 
-       return hwif->speedproc(drive, rate);
+       return ide_set_dma_mode(drive, rate);
 }
 
 static void ide_dump_opcode(ide_drive_t *drive)
index a96a8b1b3539b8bdec2972fc0f07eeca21f4f420..5c0e4078b5cbf7dbbb398998fff7b08a3310b2c0 100644 (file)
@@ -397,7 +397,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 #endif
 
        hwif->set_pio_mode              = tmp_hwif->set_pio_mode;
-       hwif->speedproc                 = tmp_hwif->speedproc;
+       hwif->set_dma_mode              = tmp_hwif->set_dma_mode;
        hwif->mdma_filter               = tmp_hwif->mdma_filter;
        hwif->udma_filter               = tmp_hwif->udma_filter;
        hwif->selectproc                = tmp_hwif->selectproc;
index c319f61631276c289549a9fbb38014e521010772..aebde49365d16a68b28fdce811a95052c3262e1b 100644 (file)
@@ -101,14 +101,7 @@ void auide_outsw(unsigned long port, void *addr, u32 count)
 
 static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       int mem_sttime;
-       int mem_stcfg;
-
-       if (ide_config_drive_speed(drive, pio + XFER_PIO_0))
-               return;
-
-       mem_sttime = 0;
-       mem_stcfg  = au_readl(MEM_STCFG2);
+       int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
 
        /* set pio mode! */
        switch(pio) {
@@ -168,13 +161,9 @@ static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
        au_writel(mem_stcfg,MEM_STCFG2);
 }
 
-static int auide_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
-       int mem_sttime;
-       int mem_stcfg;
-
-       mem_sttime = 0;
-       mem_stcfg  = au_readl(MEM_STCFG2);
+       int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
 
        switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
@@ -210,16 +199,11 @@ static int auide_tune_chipset(ide_drive_t *drive, const u8 speed)
                break;
 #endif
        default:
-               return 1;
+               return;
        }
 
-       if (ide_config_drive_speed(drive, speed))
-               return 1;
-
        au_writel(mem_sttime,MEM_STTIME2);
        au_writel(mem_stcfg,MEM_STCFG2);
-
-       return 0;
 }
 
 /*
@@ -681,6 +665,7 @@ static int au_ide_probe(struct device *dev)
 #endif
 
        hwif->pio_mask = ATA_PIO4;
+       hwif->host_flags = IDE_HFLAG_POST_SET_MODE;
 
        hwif->noprobe = 0;
        hwif->drives[0].unmask          = 1;
@@ -701,7 +686,7 @@ static int au_ide_probe(struct device *dev)
 #endif
 
        hwif->set_pio_mode              = &au1xxx_set_pio_mode;
-       hwif->speedproc                 = &auide_tune_chipset;
+       hwif->set_dma_mode              = &auide_set_dma_mode;
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
        hwif->dma_off_quietly           = &auide_dma_off_quietly;
index 0d5f62c5dfaee248398be6e3a153b9d1e5eb7264..d6cb2d5143c8812151084e3640375f22ede8a7ec 100644 (file)
@@ -87,7 +87,7 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
        return chipset_table->ultra_settings;
 }
 
-static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -111,10 +111,9 @@ static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed)
        tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn))));
        pci_write_config_byte(dev, 0x54, tmp2);
        local_irq_restore(flags);
-       return(ide_config_drive_speed(drive, speed));
 }
 
-static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -135,12 +134,11 @@ static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed)
        tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit))));
        pci_write_config_byte(dev, (0x44|hwif->channel), tmp2);
        local_irq_restore(flags);
-       return(ide_config_drive_speed(drive, speed));
 }
 
 static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       (void) HWIF(drive)->speedproc(drive, pio + XFER_PIO_0);
+       drive->hwif->set_dma_mode(drive, pio + XFER_PIO_0);
 }
 
 static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
@@ -205,9 +203,9 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
        if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
                if(hwif->mate)
                        hwif->mate->serialized = hwif->serialized = 1;
-               hwif->speedproc = &aec6210_tune_chipset;
+               hwif->set_dma_mode = &aec6210_set_mode;
        } else
-               hwif->speedproc = &aec6260_tune_chipset;
+               hwif->set_dma_mode = &aec6260_set_mode;
 
        if (!hwif->dma_base) {
                hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
index d04b966b4347a4288dba72e4584cd807f8852492..88f084eae193aca126f2dde0c70453a76c2ca854 100644 (file)
@@ -283,14 +283,14 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
 #endif  /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */
 
 /**
- *     ali_tune_pio    -       set host controller for PIO mode
+ *     ali_set_pio_mode        -       set host controller for PIO mode
  *     @drive: drive
  *     @pio: PIO mode number
  *
  *     Program the controller for the given PIO mode.
  */
 
-static void ali_tune_pio(ide_drive_t *drive, const u8 pio)
+static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        ide_hwif_t *hwif = HWIF(drive);
        struct pci_dev *dev = hwif->pci_dev;
@@ -357,21 +357,6 @@ static void ali_tune_pio(ide_drive_t *drive, const u8 pio)
         */
 }
 
-/**
- *     ali_set_pio_mode        -       set up drive for PIO mode
- *     @drive: drive to tune
- *     @pio: desired mode
- *
- *     Program the controller with the desired PIO timing for the given drive.
- *     Then set up the drive itself.
- */
-
-static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       ali_tune_pio(drive, pio);
-       (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
 /**
  *     ali_udma_filter         -       compute UDMA mask
  *     @drive: IDE device
@@ -401,15 +386,14 @@ static u8 ali_udma_filter(ide_drive_t *drive)
 }
 
 /**
- *     ali15x3_tune_chipset    -       set up chipset/drive for new speed
- *     @drive: drive to configure for
- *     @speed: desired speed
+ *     ali_set_dma_mode        -       set host controller for DMA mode
+ *     @drive: drive
+ *     @speed: DMA mode
  *
  *     Configure the hardware for the desired IDE transfer mode.
- *     We also do the needed drive configuration through helpers
  */
 
-static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -419,7 +403,7 @@ static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed)
        int m5229_udma          = (hwif->channel) ? 0x57 : 0x56;
 
        if (speed < XFER_PIO_0)
-               return 1;
+               return;
 
        if (speed == XFER_UDMA_6)
                speed1 = 0x47;
@@ -450,7 +434,6 @@ static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed)
                        pci_write_config_byte(dev, 0x4b, tmpbyte);
                }
        }
-       return (ide_config_drive_speed(drive, speed));
 }
 
 /**
@@ -699,7 +682,7 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
 {
        hwif->autodma = 0;
        hwif->set_pio_mode = &ali_set_pio_mode;
-       hwif->speedproc = &ali15x3_tune_chipset;
+       hwif->set_dma_mode = &ali_set_dma_mode;
        hwif->udma_filter = &ali_udma_filter;
 
        /* don't use LBA48 DMA on ALi devices before rev 0xC5 */
index 71d2c670e97e797ee7381f9fed1e23e0822757e0..6ff4089a23793b8de6327cc1e2ec6ea3e50cbdc3 100644 (file)
@@ -229,20 +229,16 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi
 }
 
 /*
- * amd_set_drive() computes timing values configures the drive and
- * the chipset to a desired transfer mode. It also can be called
- * by upper layers.
+ * amd_set_drive() computes timing values and configures the chipset
+ * to a desired transfer mode.  It also can be called by upper layers.
  */
 
-static int amd_set_drive(ide_drive_t *drive, const u8 speed)
+static void amd_set_drive(ide_drive_t *drive, const u8 speed)
 {
        ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
        struct ide_timing t, p;
        int T, UT;
 
-       if (ide_config_drive_speed(drive, speed))
-               return 1;
-
        T = 1000000000 / amd_clock;
        UT = (amd_config->udma_mask == ATA_UDMA2) ? T : (T / 2);
 
@@ -257,8 +253,6 @@ static int amd_set_drive(ide_drive_t *drive, const u8 speed)
        if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15;
 
        amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
-
-       return 0;
 }
 
 /*
@@ -395,7 +389,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
        hwif->autodma = 0;
 
        hwif->set_pio_mode = &amd_set_pio_mode;
-       hwif->speedproc = &amd_set_drive;
+       hwif->set_dma_mode = &amd_set_drive;
 
        for (i = 0; i < 2; i++) {
                hwif->drives[i].io_32bit = 1;
@@ -437,7 +431,8 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
                .enablebits     = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
                .bootable       = ON_BOARD,                             \
                .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST            \
-                               | IDE_HFLAG_PIO_NO_DOWNGRADE,           \
+                               | IDE_HFLAG_PIO_NO_DOWNGRADE            \
+                               | IDE_HFLAG_POST_SET_MODE,              \
                .pio_mask       = ATA_PIO5,                             \
        }
 
@@ -450,7 +445,8 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
                .enablebits     = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
                .bootable       = ON_BOARD,                             \
                .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST            \
-                               | IDE_HFLAG_PIO_NO_DOWNGRADE,           \
+                               | IDE_HFLAG_PIO_NO_DOWNGRADE            \
+                               | IDE_HFLAG_POST_SET_MODE,              \
                .pio_mask       = ATA_PIO5,                             \
        }
 
index 178876a3afca7d50d94b4c802b61cd67c83913b5..0eb97f021d3982617b33e9e19529e966a912ec20 100644 (file)
@@ -122,14 +122,14 @@ static void atiixp_dma_host_off(ide_drive_t *drive)
 }
 
 /**
- *     atiixp_tune_pio -       tune a drive attached to a ATIIXP
- *     @drive: drive to tune
- *     @pio: desired PIO mode
+ *     atiixp_set_pio_mode     -       set host controller for PIO mode
+ *     @drive: drive
+ *     @pio: PIO mode number
  *
  *     Set the interface PIO mode.
  */
 
-static void atiixp_tune_pio(ide_drive_t *drive, u8 pio)
+static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        struct pci_dev *dev = drive->hwif->pci_dev;
        unsigned long flags;
@@ -153,23 +153,16 @@ static void atiixp_tune_pio(ide_drive_t *drive, u8 pio)
        spin_unlock_irqrestore(&atiixp_lock, flags);
 }
 
-static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       atiixp_tune_pio(drive, pio);
-       (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
 /**
- *     atiixp_tune_chipset     -       tune a ATIIXP interface
- *     @drive: IDE drive to tune
- *     @speed: speed to configure
+ *     atiixp_set_dma_mode     -       set host controller for DMA mode
+ *     @drive: drive
+ *     @speed: DMA mode
  *
- *     Set a ATIIXP interface channel to the desired speeds. This involves
- *     requires the right timing data into the ATIIXP configuration space
- *     then setting the drive parameters appropriately
+ *     Set a ATIIXP host controller to the desired DMA mode.  This involves
+ *     programming the right timing data into the PCI configuration space.
  */
 
-static int atiixp_speedproc(ide_drive_t *drive, const u8 speed)
+static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        struct pci_dev *dev = drive->hwif->pci_dev;
        unsigned long flags;
@@ -204,9 +197,7 @@ static int atiixp_speedproc(ide_drive_t *drive, const u8 speed)
        else
                pio = speed - XFER_PIO_0;
 
-       atiixp_tune_pio(drive, pio);
-
-       return ide_config_drive_speed(drive, speed);
+       atiixp_set_pio_mode(drive, pio);
 }
 
 /**
@@ -249,7 +240,7 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
 
        hwif->autodma = 0;
        hwif->set_pio_mode = &atiixp_set_pio_mode;
-       hwif->speedproc = &atiixp_speedproc;
+       hwif->set_dma_mode = &atiixp_set_dma_mode;
        hwif->drives[0].autotune = 1;
        hwif->drives[1].autotune = 1;
 
index 0b568c60f9263767d0936a32a94efeb4c7c72e16..d50f15e34b80fb6a63fc6997a89074b59509145a 100644 (file)
@@ -280,10 +280,9 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
                return;
 
        cmd64x_tune_pio(drive, pio);
-       (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
 }
 
-static int cmd64x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -324,13 +323,11 @@ static int cmd64x_tune_chipset(ide_drive_t *drive, const u8 speed)
                program_cycle_times(drive, 480, 215);
                break;
        default:
-               return 1;
+               return;
        }
 
        if (speed >= XFER_SW_DMA_0)
                (void) pci_write_config_byte(dev, pciU, regU);
-
-       return ide_config_drive_speed(drive, speed);
 }
 
 static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
@@ -524,7 +521,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
        pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
 
        hwif->set_pio_mode = &cmd64x_set_pio_mode;
-       hwif->speedproc = &cmd64x_tune_chipset;
+       hwif->set_dma_mode = &cmd64x_set_dma_mode;
 
        hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
 
index 1217d2a747fbbee24c305471dfe6e0113b66b1f4..cb2a10203dc41c631b6cb8617ac24ec1644f6266 100644 (file)
@@ -96,22 +96,13 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
        reg = inb(hwif->dma_base + 0x02 + 8*controller);
        reg |= 1<<((drive->dn&1)+5);
        outb(reg, hwif->dma_base + 0x02 + 8*controller);
-
-       (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
 }
 
-static int cs5520_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        printk(KERN_ERR "cs55x0: bad ide timing.\n");
 
        cs5520_set_pio_mode(drive, 0);
-
-       /*
-        * FIXME: this is incorrect to return zero here but
-        * since all users of ide_set_xfer_rate() ignore
-        * the return value it is not a problem currently
-        */
-       return 0;
 }
 
 static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
@@ -150,7 +141,7 @@ static int cs5520_dma_on(ide_drive_t *drive)
 static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
 {
        hwif->set_pio_mode = &cs5520_set_pio_mode;
-       hwif->speedproc = &cs5520_tune_chipset;
+       hwif->set_dma_mode = &cs5520_set_dma_mode;
        hwif->ide_dma_check = &cs5520_config_drive_xfer_rate;
        hwif->ide_dma_on = &cs5520_dma_on;
 
index 741507b4cd93b0c789599fec220240c8424e7c92..e4121577cef0291e71abb435cd88b7ab21b51ecb 100644 (file)
 #include <asm/io.h>
 #include <asm/irq.h>
 
-/**
- *     cs5530_xfer_set_mode    -       set a new transfer mode at the drive
- *     @drive: drive to tune
- *     @mode: new mode
- *
- *     Logging wrapper to the IDE driver speed configuration. This can
- *     probably go away now.
- */
-static int cs5530_set_xfer_mode (ide_drive_t *drive, u8 mode)
-{
-       printk(KERN_DEBUG "%s: cs5530_set_xfer_mode(%s)\n",
-               drive->name, ide_xfer_verbose(mode));
-       return (ide_config_drive_speed(drive, mode));
-}
-
 /*
  * Here are the standard PIO mode 0-4 timings for each "format".
  * Format-0 uses fast data reg timings, with slower command reg timings.
@@ -62,20 +46,12 @@ static unsigned int cs5530_pio_timings[2][5] = {
 #define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132)
 #define CS5530_BASEREG(hwif)   (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20))
 
-static void cs5530_tunepio(ide_drive_t *drive, u8 pio)
-{
-       unsigned long basereg = CS5530_BASEREG(drive->hwif);
-       unsigned int format = (inl(basereg + 4) >> 31) & 1;
-
-       outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3));
-}
-
 /**
- *     cs5530_set_pio_mode     -       set PIO mode
+ *     cs5530_set_pio_mode     -       set host controller for PIO mode
  *     @drive: drive
  *     @pio: PIO mode number
  *
- *     Handles setting of PIO mode for both the chipset and drive.
+ *     Handles setting of PIO mode for the chipset.
  *
  *     The init_hwif_cs5530() routine guarantees that all drives
  *     will have valid default PIO timings set up before we get here.
@@ -83,8 +59,10 @@ static void cs5530_tunepio(ide_drive_t *drive, u8 pio)
 
 static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0)
-               cs5530_tunepio(drive, pio);
+       unsigned long basereg = CS5530_BASEREG(drive->hwif);
+       unsigned int format = (inl(basereg + 4) >> 31) & 1;
+
+       outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3));
 }
 
 /**
@@ -142,20 +120,11 @@ static int cs5530_config_dma(ide_drive_t *drive)
        return 1;
 }
 
-static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode)
+static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
 {
        unsigned long basereg;
        unsigned int reg, timings = 0;
 
-       /*
-        * Tell the drive to switch to the new mode; abort on failure.
-        */
-       if (cs5530_set_xfer_mode(drive, mode))
-               return 1;       /* failure */
-
-       /*
-        * Now tune the chipset to match the drive:
-        */
        switch (mode) {
                case XFER_UDMA_0:       timings = 0x00921250; break;
                case XFER_UDMA_1:       timings = 0x00911140; break;
@@ -180,8 +149,6 @@ static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode)
                outl(reg, basereg + 4);         /* write drive0 config register */
                outl(timings, basereg + 12);    /* write drive1 config register */
        }
-
-       return 0;       /* success */
 }
 
 /**
@@ -299,7 +266,7 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
                hwif->serialized = hwif->mate->serialized = 1;
 
        hwif->set_pio_mode = &cs5530_set_pio_mode;
-       hwif->speedproc = &cs5530_tune_chipset;
+       hwif->set_dma_mode = &cs5530_set_dma_mode;
 
        basereg = CS5530_BASEREG(hwif);
        d0_timings = inl(basereg + 0);
@@ -340,6 +307,7 @@ static ide_pci_device_t cs5530_chipset __devinitdata = {
        .autodma        = AUTODMA,
        .bootable       = ON_BOARD,
        .pio_mask       = ATA_PIO4,
+       .host_flags     = IDE_HFLAG_POST_SET_MODE,
 };
 
 static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
index 5d1be657adca763fc04c13ea20d92b1006744ccb..da606ba6d28ce7278a3ac0348b647f781faf0982 100644 (file)
@@ -131,26 +131,21 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
        }
 }
 
-/****
- *     cs5535_set_drive         -     Configure the drive to the new speed
- *     @drive: Drive to set up
- *     @speed: desired speed
+/**
+ *     cs5535_set_dma_mode     -       set host controller for DMA mode
+ *     @drive: drive
+ *     @speed: DMA mode
  *
- *     cs5535_set_drive() configures the drive and the chipset to a
- *     new speed. It also can be called by upper layers.
+ *     Programs the chipset for DMA mode.
  */
-static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
-{
-       if (ide_config_drive_speed(drive, speed))
-               return 1;
 
+static void cs5535_set_dma_mode(ide_drive_t *drive, const u8 speed)
+{
        cs5535_set_speed(drive, speed);
-
-       return 0;
 }
 
 /**
- *     cs5535_set_pio_mode     -       PIO setup
+ *     cs5535_set_pio_mode     -       set host controller for PIO mode
  *     @drive: drive
  *     @pio: PIO mode number
  *
@@ -159,9 +154,6 @@ static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
 
 static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       if (ide_config_drive_speed(drive, XFER_PIO_0 + pio))
-               return;
-
        cs5535_set_speed(drive, XFER_PIO_0 + pio);
 }
 
@@ -203,7 +195,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
        hwif->autodma = 0;
 
        hwif->set_pio_mode = &cs5535_set_pio_mode;
-       hwif->speedproc = &cs5535_set_drive;
+       hwif->set_dma_mode = &cs5535_set_dma_mode;
        hwif->ide_dma_check = &cs5535_dma_check;
 
        hwif->atapi_dma = 1;
@@ -227,7 +219,7 @@ static ide_pci_device_t cs5535_chipset __devinitdata = {
        .init_hwif      = init_hwif_cs5535,
        .autodma        = AUTODMA,
        .bootable       = ON_BOARD,
-       .host_flags     = IDE_HFLAG_SINGLE,
+       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE,
        .pio_mask       = ATA_PIO4,
 };
 
index a1bb10188fe54da2e84b190745b009083305aea7..218852aaf22aa11329dae8d320f3b6be1ba091c2 100644 (file)
@@ -43,7 +43,7 @@
 
 #define HPT343_DEBUG_DRIVE_INFO                0
 
-static int hpt34x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void hpt34x_set_mode(ide_drive_t *drive, const u8 speed)
 {
        struct pci_dev *dev     = HWIF(drive)->pci_dev;
        u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
@@ -73,13 +73,11 @@ static int hpt34x_tune_chipset(ide_drive_t *drive, const u8 speed)
                drive->dn, reg1, tmp1, reg2, tmp2,
                hi_speed, lo_speed);
 #endif /* HPT343_DEBUG_DRIVE_INFO */
-
-       return(ide_config_drive_speed(drive, speed));
 }
 
 static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       (void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
+       hpt34x_set_mode(drive, XFER_PIO_0 + pio);
 }
 
 static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
@@ -145,7 +143,8 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
        hwif->autodma = 0;
 
        hwif->set_pio_mode = &hpt34x_set_pio_mode;
-       hwif->speedproc = &hpt34x_tune_chipset;
+       hwif->set_dma_mode = &hpt34x_set_mode;
+
        hwif->drives[0].autotune = 1;
        hwif->drives[1].autotune = 1;
 
index 0e7d3b60d43c324353c8dd8d8e449739da6fad33..8812a9bb032ff6f77f45334b984b2a6d37f71f6a 100644 (file)
@@ -600,7 +600,7 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
        return (*info->settings)[i];
 }
 
-static int hpt36x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void hpt36x_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev  *dev    = hwif->pci_dev;
@@ -623,11 +623,9 @@ static int hpt36x_tune_chipset(ide_drive_t *drive, const u8 speed)
        new_itr &= ~0xc0000000;
 
        pci_write_config_dword(dev, itr_addr, new_itr);
-
-       return ide_config_drive_speed(drive, speed);
 }
 
-static int hpt37x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void hpt37x_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev  *dev    = hwif->pci_dev;
@@ -647,24 +645,22 @@ static int hpt37x_tune_chipset(ide_drive_t *drive, const u8 speed)
        if (speed < XFER_MW_DMA_0)
                new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
        pci_write_config_dword(dev, itr_addr, new_itr);
-
-       return ide_config_drive_speed(drive, speed);
 }
 
-static int hpt3xx_tune_chipset(ide_drive_t *drive, u8 speed)
+static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct hpt_info *info   = pci_get_drvdata(hwif->pci_dev);
 
        if (info->chip_type >= HPT370)
-               return hpt37x_tune_chipset(drive, speed);
+               hpt37x_set_mode(drive, speed);
        else    /* hpt368: hpt_minimum_revision(dev, 2) */
-               return hpt36x_tune_chipset(drive, speed);
+               hpt36x_set_mode(drive, speed);
 }
 
 static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       (void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio);
+       hpt3xx_set_mode(drive, XFER_PIO_0 + pio);
 }
 
 static int hpt3xx_quirkproc(ide_drive_t *drive)
@@ -1257,7 +1253,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
        hwif->select_data       = hwif->channel ? 0x54 : 0x50;
 
        hwif->set_pio_mode      = &hpt3xx_set_pio_mode;
-       hwif->speedproc         = &hpt3xx_tune_chipset;
+       hwif->set_dma_mode      = &hpt3xx_set_mode;
        hwif->quirkproc         = &hpt3xx_quirkproc;
        hwif->intrproc          = &hpt3xx_intrproc;
        hwif->maskproc          = &hpt3xx_maskproc;
index 76e91ff9420b87221b144c4042dbe85d34452da5..ecf4ce078dce601863cf0d6cf18ff51e08cf9d71 100644 (file)
@@ -48,15 +48,15 @@ static u8 it8213_dma_2_pio (u8 xfer_rate) {
        }
 }
 
-/*
- *     it8213_tune_pio -       tune a drive
- *     @drive: drive to tune
- *     @pio: desired PIO mode
+/**
+ *     it8213_set_pio_mode     -       set host controller for PIO mode
+ *     @drive: drive
+ *     @pio: PIO mode number
  *
  *     Set the interface PIO mode.
  */
 
-static void it8213_tune_pio(ide_drive_t *drive, const u8 pio)
+static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -105,21 +105,15 @@ static void it8213_tune_pio(ide_drive_t *drive, const u8 pio)
        spin_unlock_irqrestore(&tune_lock, flags);
 }
 
-static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       it8213_tune_pio(drive, pio);
-       ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
 /**
- *     it8213_tune_chipset     -       set controller timings
- *     @drive: Drive to set up
- *     @speed: speed we want to achieve
+ *     it8213_set_dma_mode     -       set host controller for DMA mode
+ *     @drive: drive
+ *     @speed: DMA mode
  *
- *     Tune the ITE chipset for the desired mode.
+ *     Tune the ITE chipset for the DMA mode.
  */
 
-static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -152,7 +146,7 @@ static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed)
                case XFER_SW_DMA_2:
                        break;
                default:
-                       return -1;
+                       return;
        }
 
        if (speed >= XFER_UDMA_0) {
@@ -182,9 +176,7 @@ static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed)
                        pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
        }
 
-       it8213_tune_pio(drive, it8213_dma_2_pio(speed));
-
-       return ide_config_drive_speed(drive, speed);
+       it8213_set_pio_mode(drive, it8213_dma_2_pio(speed));
 }
 
 /**
@@ -220,7 +212,7 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
 {
        u8 reg42h = 0;
 
-       hwif->speedproc = &it8213_tune_chipset;
+       hwif->set_dma_mode = &it8213_set_dma_mode;
        hwif->set_pio_mode = &it8213_set_pio_mode;
 
        hwif->autodma = 0;
index 758a98230cc5fcf8183499c4fa74d24f12bdc685..1b69d82478c6b4942e34a4fcbb30630837585a65 100644 (file)
@@ -229,24 +229,24 @@ static void it821x_clock_strategy(ide_drive_t *drive)
 }
 
 /**
- *     it821x_tunepio  -       tune a drive
- *     @drive: drive to tune
- *     @pio: the desired PIO mode
+ *     it821x_set_pio_mode     -       set host controller for PIO mode
+ *     @drive: drive
+ *     @pio: PIO mode number
  *
- *     Try to tune the drive/host to the desired PIO mode taking into
- *     the consideration the maximum PIO mode supported by the other
- *     device on the cable.
+ *     Tune the host to the desired PIO mode taking into the consideration
+ *     the maximum PIO mode supported by the other device on the cable.
  */
 
-static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
+static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        ide_hwif_t *hwif        = drive->hwif;
        struct it821x_dev *itdev = ide_get_hwifdata(hwif);
        int unit = drive->select.b.unit;
        ide_drive_t *pair = &hwif->drives[1 - unit];
+       u8 set_pio = pio;
 
        /* Spec says 89 ref driver uses 88 */
-       static u16 pio[]        = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };
+       static u16 pio_timings[]= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };
        static u8 pio_want[]    = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY };
 
        /*
@@ -261,22 +261,12 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
                        set_pio = pair_pio;
        }
 
-       if (itdev->smart)
-               return 0;
-
        /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
        itdev->want[unit][1] = pio_want[set_pio];
        itdev->want[unit][0] = 1;       /* PIO is lowest priority */
-       itdev->pio[unit] = pio[set_pio];
+       itdev->pio[unit] = pio_timings[set_pio];
        it821x_clock_strategy(drive);
        it821x_program(drive, itdev->pio[unit]);
-
-       return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
-}
-
-static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       (void)it821x_tunepio(drive, pio);
 }
 
 /**
@@ -405,47 +395,24 @@ static int it821x_dma_end(ide_drive_t *drive)
 }
 
 /**
- *     it821x_tune_chipset     -       set controller timings
- *     @drive: Drive to set up
- *     @speed: speed we want to achieve
+ *     it821x_set_dma_mode     -       set host controller for DMA mode
+ *     @drive: drive
+ *     @speed: DMA mode
  *
- *     Tune the ITE chipset for the desired mode.
+ *     Tune the ITE chipset for the desired DMA mode.
  */
 
-static int it821x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
-
-       ide_hwif_t *hwif        = drive->hwif;
-       struct it821x_dev *itdev = ide_get_hwifdata(hwif);
-
-       if (itdev->smart == 0) {
-               switch (speed) {
-                       /* MWDMA tuning is really hard because our MWDMA and PIO
-                          timings are kept in the same place. We can switch in the
-                          host dma on/off callbacks */
-                       case XFER_MW_DMA_2:
-                       case XFER_MW_DMA_1:
-                       case XFER_MW_DMA_0:
-                               it821x_tune_mwdma(drive, (speed - XFER_MW_DMA_0));
-                               break;
-                       case XFER_UDMA_6:
-                       case XFER_UDMA_5:
-                       case XFER_UDMA_4:
-                       case XFER_UDMA_3:
-                       case XFER_UDMA_2:
-                       case XFER_UDMA_1:
-                       case XFER_UDMA_0:
-                               it821x_tune_udma(drive, (speed - XFER_UDMA_0));
-                               break;
-                       default:
-                               return 1;
-               }
-
-               return ide_config_drive_speed(drive, speed);
-       }
-
-       /* don't touch anything in the smart mode */
-       return 0;
+       /*
+        * MWDMA tuning is really hard because our MWDMA and PIO
+        * timings are kept in the same place.  We can switch in the
+        * host dma on/off callbacks.
+        */
+       if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_6)
+               it821x_tune_udma(drive, speed - XFER_UDMA_0);
+       else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
+               it821x_tune_mwdma(drive, speed - XFER_MW_DMA_0);
 }
 
 /**
@@ -629,14 +596,15 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
                        printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n");
        }
 
-       hwif->speedproc = &it821x_tune_chipset;
-       hwif->set_pio_mode = &it821x_set_pio_mode;
+       if (idev->smart == 0) {
+               hwif->set_pio_mode = &it821x_set_pio_mode;
+               hwif->set_dma_mode = &it821x_set_dma_mode;
 
-       /* MWDMA/PIO clock switching for pass through mode */
-       if(!idev->smart) {
+               /* MWDMA/PIO clock switching for pass through mode */
                hwif->dma_start = &it821x_dma_start;
                hwif->ide_dma_end = &it821x_dma_end;
-       }
+       } else
+               hwif->host_flags |= IDE_HFLAG_NO_SET_MODE;
 
        hwif->drives[0].autotune = 1;
        hwif->drives[1].autotune = 1;
index d379fbaf67434535a7162a4ef5acbd8c97b66876..582b4cae2b5358ebb2b150e0b2a5ebefbd15df32 100644 (file)
@@ -85,21 +85,18 @@ static u8 __devinit ata66_jmicron(ide_hwif_t *hwif)
 
 static void jmicron_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       ide_config_drive_speed(drive, XFER_PIO_0 + pio);
 }
 
 /**
- *     jmicron_tune_chipset    -       set controller timings
- *     @drive: Drive to set up
- *     @speed: speed we want to achieve
+ *     jmicron_set_dma_mode    -       set host controller for DMA mode
+ *     @drive: drive
+ *     @mode: DMA mode
  *
- *     As the JMicron snoops for timings all we actually need to do is
- *     set the transfer mode on the device.
+ *     As the JMicron snoops for timings we don't need to do anything here.
  */
 
-static int jmicron_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void jmicron_set_dma_mode(ide_drive_t *drive, const u8 mode)
 {
-       return ide_config_drive_speed(drive, speed);
 }
 
 /**
@@ -129,8 +126,8 @@ static int jmicron_config_drive_for_dma (ide_drive_t *drive)
 
 static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
 {
-       hwif->speedproc = &jmicron_tune_chipset;
        hwif->set_pio_mode = &jmicron_set_pio_mode;
+       hwif->set_dma_mode = &jmicron_set_dma_mode;
 
        hwif->drives[0].autotune = 1;
        hwif->drives[1].autotune = 1;
index 95600681bd3a8751d6edbca7efa83103c4d739d3..ad0bdcb0c02b97371ee1f8ccb9419c5775976d02 100644 (file)
@@ -146,19 +146,16 @@ static struct udma_timing {
        { 0x1a, 0x01, 0xcb },   /* UDMA mode 6 */
 };
 
-static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        u8 adj                  = (drive->dn & 1) ? 0x08 : 0x00;
 
        /*
-        * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will
+        * IDE core issues SETFEATURES_XFER to the drive first (thanks to
+        * IDE_HFLAG_POST_SET_MODE in ->host_flags).  PDC202xx hardware will
         * automatically set the timing registers based on 100 MHz PLL output.
-        */
-       if (ide_config_drive_speed(drive, speed))
-               return 1;
-
-       /*
+        *
         * As we set up the PLL to output 133 MHz for UltraDMA/133 capable
         * chips, we must override the default register settings...
         */
@@ -211,13 +208,11 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed)
 
                set_indexed_reg(hwif, 0x10 + adj, tmp & 0x7f);
        }
-
-       return 0;
 }
 
 static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       (void)pdcnew_tune_chipset(drive, XFER_PIO_0 + pio);
+       pdcnew_set_mode(drive, XFER_PIO_0 + pio);
 }
 
 static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
@@ -490,9 +485,9 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
        hwif->autodma = 0;
 
        hwif->set_pio_mode = &pdcnew_set_pio_mode;
+       hwif->set_dma_mode = &pdcnew_set_mode;
 
        hwif->quirkproc = &pdcnew_quirkproc;
-       hwif->speedproc = &pdcnew_tune_chipset;
        hwif->resetproc = &pdcnew_reset;
 
        hwif->err_stops_fifo = 1;
@@ -583,6 +578,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
                .bootable       = OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = 0x3f, /* udma0-5 */
+               .host_flags     = IDE_HFLAG_POST_SET_MODE,
        },{     /* 1 */
                .name           = "PDC20269",
                .init_setup     = init_setup_pdcnew,
@@ -592,6 +588,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
                .bootable       = OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = 0x7f, /* udma0-6*/
+               .host_flags     = IDE_HFLAG_POST_SET_MODE,
        },{     /* 2 */
                .name           = "PDC20270",
                .init_setup     = init_setup_pdc20270,
@@ -601,6 +598,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
                .bootable       = OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = 0x3f, /* udma0-5 */
+               .host_flags     = IDE_HFLAG_POST_SET_MODE,
        },{     /* 3 */
                .name           = "PDC20271",
                .init_setup     = init_setup_pdcnew,
@@ -610,6 +608,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
                .bootable       = OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = 0x7f, /* udma0-6*/
+               .host_flags     = IDE_HFLAG_POST_SET_MODE,
        },{     /* 4 */
                .name           = "PDC20275",
                .init_setup     = init_setup_pdcnew,
@@ -619,6 +618,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
                .bootable       = OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = 0x7f, /* udma0-6*/
+               .host_flags     = IDE_HFLAG_POST_SET_MODE,
        },{     /* 5 */
                .name           = "PDC20276",
                .init_setup     = init_setup_pdc20276,
@@ -628,6 +628,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
                .bootable       = OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = 0x7f, /* udma0-6*/
+               .host_flags     = IDE_HFLAG_POST_SET_MODE,
        },{     /* 6 */
                .name           = "PDC20277",
                .init_setup     = init_setup_pdcnew,
@@ -637,6 +638,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
                .bootable       = OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = 0x7f, /* udma0-6*/
+               .host_flags     = IDE_HFLAG_POST_SET_MODE,
        }
 };
 
index b578307fad51a3a1b1dd9320a14ccc35de015ee0..8c3e8cf36ec9da78e5dcbe7ba210ad9eb6a3fd37 100644 (file)
@@ -63,7 +63,7 @@ static const char *pdc_quirk_drives[] = {
 
 static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
 
-static int pdc202xx_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -138,13 +138,11 @@ static int pdc202xx_tune_chipset(ide_drive_t *drive, const u8 speed)
        pci_read_config_dword(dev, drive_pci, &drive_conf);
        printk("0x%08x\n", drive_conf);
 #endif
-
-       return ide_config_drive_speed(drive, speed);
 }
 
 static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       pdc202xx_tune_chipset(drive, XFER_PIO_0 + pio);
+       pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
 }
 
 static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
@@ -330,14 +328,13 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
        hwif->autodma = 0;
 
        hwif->set_pio_mode = &pdc202xx_set_pio_mode;
+       hwif->set_dma_mode = &pdc202xx_set_mode;
 
        hwif->quirkproc = &pdc202xx_quirkproc;
 
        if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
                hwif->resetproc = &pdc202xx_reset;
 
-       hwif->speedproc = &pdc202xx_tune_chipset;
-
        hwif->err_stops_fifo = 1;
 
        hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
index fd8214a7ab9877e2a7d73045df361ffb30fe911e..38c91ba6497b30252796f4020b5af9293535438b 100644 (file)
@@ -137,13 +137,14 @@ static u8 piix_dma_2_pio (u8 xfer_rate) {
 }
 
 /**
- *     piix_tune_pio           -       tune PIIX for PIO mode
- *     @drive: drive to tune
- *     @pio: desired PIO mode
+ *     piix_set_pio_mode       -       set host controller for PIO mode
+ *     @drive: drive
+ *     @pio: PIO mode number
  *
  *     Set the interface PIO mode based upon the settings done by AMI BIOS.
  */
-static void piix_tune_pio (ide_drive_t *drive, u8 pio)
+
+static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -204,31 +205,15 @@ static void piix_tune_pio (ide_drive_t *drive, u8 pio)
 }
 
 /**
- *     piix_set_pio_mode       -       set PIO mode
- *     @drive: drive to tune
- *     @pio: desired PIO mode
- *
- *     Set the drive's PIO mode (might be useful if drive is not registered
- *     in CMOS for any reason).
- */
-
-static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       piix_tune_pio(drive, pio);
-       (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
-/**
- *     piix_tune_chipset       -       tune a PIIX interface
- *     @drive: IDE drive to tune
- *     @speed: speed to configure
+ *     piix_set_dma_mode       -       set host controller for DMA mode
+ *     @drive: drive
+ *     @speed: DMA mode
  *
- *     Set a PIIX interface channel to the desired speeds. This involves
- *     requires the right timing data into the PIIX configuration space
- *     then setting the drive parameters appropriately
+ *     Set a PIIX host controller to the desired DMA mode.  This involves
+ *     programming the right timing data into the PCI configuration space.
  */
 
-static int piix_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -259,7 +244,7 @@ static int piix_tune_chipset(ide_drive_t *drive, const u8 speed)
                case XFER_MW_DMA_2:
                case XFER_MW_DMA_1:
                case XFER_SW_DMA_2:     break;
-               default:                return -1;
+               default:                return;
        }
 
        if (speed >= XFER_UDMA_0) {
@@ -288,9 +273,7 @@ static int piix_tune_chipset(ide_drive_t *drive, const u8 speed)
                        pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
        }
 
-       piix_tune_pio(drive, piix_dma_2_pio(speed));
-
-       return ide_config_drive_speed(drive, speed);
+       piix_set_pio_mode(drive, piix_dma_2_pio(speed));
 }
 
 /**
@@ -448,7 +431,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
        hwif->autodma = 0;
 
        hwif->set_pio_mode = &piix_set_pio_mode;
-       hwif->speedproc = &piix_tune_chipset;
+       hwif->set_dma_mode = &piix_set_dma_mode;
+
        hwif->drives[0].autotune = 1;
        hwif->drives[1].autotune = 1;
 
index 79ecab6894891de0480349cd3f98268ba3f2a24e..76f0868054a1e9b4b3ed1cb540b39d7c51318e2a 100644 (file)
@@ -68,17 +68,6 @@ static unsigned short sc1200_get_pci_clock (void)
        return pci_clock;
 }
 
-extern char *ide_xfer_verbose (byte xfer_rate);
-
-/*
- * Set a new transfer mode at the drive
- */
-static int sc1200_set_xfer_mode (ide_drive_t *drive, byte mode)
-{
-       printk("%s: sc1200_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode));
-       return ide_config_drive_speed(drive, mode);
-}
-
 /*
  * Here are the standard PIO mode 0-4 timings for each "format".
  * Format-0 uses fast data reg timings, with slower command reg timings.
@@ -138,7 +127,7 @@ out:
        return mask;
 }
 
-static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode)
+static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
 {
        ide_hwif_t              *hwif = HWIF(drive);
        int                     unit = drive->select.b.unit;
@@ -146,17 +135,9 @@ static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode)
        unsigned short          pci_clock;
        unsigned int            basereg = hwif->channel ? 0x50 : 0x40;
 
-       /*
-        * Tell the drive to switch to the new mode; abort on failure.
-        */
-       if (sc1200_set_xfer_mode(drive, mode))
-               return 1;       /* failure */
-
        pci_clock = sc1200_get_pci_clock();
 
        /*
-        * Now tune the chipset to match the drive:
-        *
         * Note that each DMA mode has several timings associated with it.
         * The correct timing depends on the fast PCI clock freq.
         */
@@ -216,8 +197,6 @@ static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode)
        } else {
                pci_write_config_dword(hwif->pci_dev, basereg+12, timings);
        }
-
-       return 0;       /* success */
 }
 
 /*
@@ -286,13 +265,12 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
        if (mode != -1) {
                printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
                hwif->dma_off_quietly(drive);
-               if (sc1200_tune_chipset(drive, mode) == 0)
+               if (ide_set_dma_mode(drive, mode) == 0)
                        hwif->dma_host_on(drive);
                return;
        }
 
-       if (sc1200_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0)
-               sc1200_tunepio(drive, pio);
+       sc1200_tunepio(drive, pio);
 }
 
 #ifdef CONFIG_PM
@@ -408,7 +386,7 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
                        hwif->autodma = 1;
 
                hwif->set_pio_mode = &sc1200_set_pio_mode;
-               hwif->speedproc = &sc1200_tune_chipset;
+               hwif->set_dma_mode = &sc1200_set_dma_mode;
        }
         hwif->atapi_dma = 1;
         hwif->ultra_mask = 0x07;
@@ -423,7 +401,7 @@ static ide_pci_device_t sc1200_chipset __devinitdata = {
        .init_hwif      = init_hwif_sc1200,
        .autodma        = AUTODMA,
        .bootable       = ON_BOARD,
-       .host_flags     = IDE_HFLAG_ABUSE_DMA_MODES,
+       .host_flags     = IDE_HFLAG_ABUSE_DMA_MODES | IDE_HFLAG_POST_SET_MODE,
        .pio_mask       = ATA_PIO4,
 };
 
index 66a526e0ece4bd4e1fbd127bde869b5b7cfc76b5..67f06dd11b341c7a840b9b3e5b95d6563c3e4326 100644 (file)
@@ -190,15 +190,15 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count)
 }
 
 /**
- *     scc_tune_pio    -       tune a drive PIO mode
- *     @drive: drive to tune
- *     @mode_wanted: the target operating mode
+ *     scc_set_pio_mode        -       set host controller for PIO mode
+ *     @drive: drive
+ *     @pio: PIO mode number
  *
  *     Load the timing settings for this device mode into the
  *     controller.
  */
 
-static void scc_tune_pio(ide_drive_t *drive, const u8 pio)
+static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        ide_hwif_t *hwif = HWIF(drive);
        struct scc_ports *ports = ide_get_hwifdata(hwif);
@@ -221,22 +221,16 @@ static void scc_tune_pio(ide_drive_t *drive, const u8 pio)
        out_be32((void __iomem *)pioct_port, reg);
 }
 
-static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       scc_tune_pio(drive, pio);
-       ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
 /**
- *     scc_tune_chipset        -       tune a drive DMA mode
- *     @drive: Drive to set up
- *     @speed: speed we want to achieve
+ *     scc_set_dma_mode        -       set host controller for DMA mode
+ *     @drive: drive
+ *     @speed: DMA mode
  *
  *     Load the timing settings for this device mode into the
  *     controller.
  */
 
-static int scc_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif = HWIF(drive);
        struct scc_ports *ports = ide_get_hwifdata(hwif);
@@ -271,7 +265,7 @@ static int scc_tune_chipset(ide_drive_t *drive, const u8 speed)
                idx = speed - XFER_UDMA_0;
                break;
        default:
-               return 1;
+               return;
        }
 
        jcactsel = JCACTSELtbl[offset][idx];
@@ -287,8 +281,6 @@ static int scc_tune_chipset(ide_drive_t *drive, const u8 speed)
        }
        reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx];
        out_be32((void __iomem *)udenvt_port, reg);
-
-       return ide_config_drive_speed(drive, speed);
 }
 
 /**
@@ -708,8 +700,8 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
 
        hwif->dma_setup = scc_dma_setup;
        hwif->ide_dma_end = scc_ide_dma_end;
-       hwif->speedproc = scc_tune_chipset;
        hwif->set_pio_mode = scc_set_pio_mode;
+       hwif->set_dma_mode = scc_set_dma_mode;
        hwif->ide_dma_check = scc_config_drive_for_dma;
        hwif->ide_dma_test_irq = scc_dma_test_irq;
        hwif->udma_filter = scc_udma_filter;
index 0351cf2104271bbdecb2869d46a8451bdf18d554..49ec0ac64a4beb6ce0f3e4a94cf80383ef921cb1 100644 (file)
@@ -124,7 +124,7 @@ static u8 svwks_csb_check (struct pci_dev *dev)
        return 0;
 }
 
-static void svwks_tune_pio(ide_drive_t *drive, const u8 pio)
+static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
        static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
@@ -145,7 +145,7 @@ static void svwks_tune_pio(ide_drive_t *drive, const u8 pio)
        }
 }
 
-static int svwks_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        static const u8 udma_modes[]            = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
        static const u8 dma_modes[]             = { 0x77, 0x21, 0x20 };
@@ -193,14 +193,6 @@ static int svwks_tune_chipset(ide_drive_t *drive, const u8 speed)
        pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing);
        pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing);
        pci_write_config_byte(dev, 0x54, ultra_enable);
-
-       return (ide_config_drive_speed(drive, speed));
-}
-
-static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       svwks_tune_pio(drive, pio);
-       (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
 }
 
 static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
@@ -384,7 +376,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
                hwif->irq = hwif->channel ? 15 : 14;
 
        hwif->set_pio_mode = &svwks_set_pio_mode;
-       hwif->speedproc = &svwks_tune_chipset;
+       hwif->set_dma_mode = &svwks_set_dma_mode;
        hwif->udma_filter = &svwks_udma_filter;
 
        hwif->atapi_dma = 1;
index c292e1de1d56aba4bd574eb4ed03fb7cbc521733..26352626c0e842e315934cb71e2ddad3b185822c 100644 (file)
@@ -291,12 +291,8 @@ static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
        drive->hwif->dma_host_off(drive);
 }
 
-static int sgiioc4_speedproc(ide_drive_t *drive, const u8 speed)
+static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
-       if (speed != XFER_MW_DMA_2)
-               return 1;
-
-       return ide_config_drive_speed(drive, speed);
 }
 
 static int sgiioc4_ide_dma_check(ide_drive_t *drive)
@@ -595,7 +591,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
        hwif->mwdma_mask = 0x04;
        hwif->pio_mask = 0x00;
        hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */
-       hwif->speedproc = &sgiioc4_speedproc;
+       hwif->set_dma_mode = &sgiioc4_set_dma_mode;
        hwif->selectproc = NULL;/* Use the default routine to select drive */
        hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */
        hwif->pre_reset = NULL; /* No HBA specific pre_set needed */
index 5d1e5e52a0447a02ebd481639fdd541b9cbc7912..ce7784996d12c09c747ecc11af7f3789649a2cae 100644 (file)
@@ -165,16 +165,16 @@ out:
 }
 
 /**
- *     sil_tune_pio    -       tune a drive
- *     @drive: drive to tune
- *     @pio: the desired PIO mode
+ *     sil_set_pio_mode        -       set host controller for PIO mode
+ *     @drive: drive
+ *     @pio: PIO mode number
  *
  *     Load the timing settings for this device mode into the
  *     controller. If we are in PIO mode 3 or 4 turn on IORDY
  *     monitoring (bit 9). The TF timing is bits 31:16
  */
 
-static void sil_tune_pio(ide_drive_t *drive, u8 pio)
+static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
 {
        const u16 tf_speed[]    = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
        const u16 data_speed[]  = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
@@ -234,21 +234,15 @@ static void sil_tune_pio(ide_drive_t *drive, u8 pio)
        }
 }
 
-static void sil_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       sil_tune_pio(drive, pio);
-       (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
 /**
- *     siimage_tune_chipset    -       set controller timings
- *     @drive: Drive to set up
- *     @speed: speed we want to achieve
+ *     sil_set_dma_mode        -       set host controller for DMA mode
+ *     @drive: drive
+ *     @speed: DMA mode
  *
- *     Tune the SII chipset for the desired mode.
+ *     Tune the SiI chipset for the desired DMA mode.
  */
 
-static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        u8 ultra6[]             = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
        u8 ultra5[]             = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
@@ -303,7 +297,7 @@ static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed)
                        mode |= ((unit) ? 0x30 : 0x03);
                        break;
                default:
-                       return 1;
+                       return;
        }
 
        if (hwif->mmio) {
@@ -315,7 +309,6 @@ static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed)
                pci_write_config_word(hwif->pci_dev, ma, multi);
                pci_write_config_word(hwif->pci_dev, ua, ultra);
        }
-       return (ide_config_drive_speed(drive, speed));
 }
 
 /**
@@ -904,8 +897,8 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
        hwif->autodma = 0;
        
        hwif->resetproc = &siimage_reset;
-       hwif->speedproc = &siimage_tune_chipset;
        hwif->set_pio_mode = &sil_set_pio_mode;
+       hwif->set_dma_mode = &sil_set_dma_mode;
        hwif->reset_poll = &siimage_reset_poll;
        hwif->pre_reset = &siimage_pre_reset;
        hwif->udma_filter = &sil_udma_filter;
index 3e18899de631450ac6c1dec6ae8158b7646f0df0..b375ee53d66d61997fd35bd4e49c395658b80bed 100644 (file)
@@ -451,7 +451,7 @@ static void config_drive_art_rwp (ide_drive_t *drive)
 }
 
 /* Set per-drive active and recovery time */
-static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
+static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -519,20 +519,14 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
        }
 }
 
-static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       config_art_rwp_pio(drive, pio);
-       (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
-static int sis5513_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
        u32 regdw;
        u8 drive_pci, reg;
 
-       /* See config_art_rwp_pio for drive pci config registers */
+       /* See sis_set_pio_mode() for drive PCI config registers */
        drive_pci = 0x40;
        if (chipset_family >= ATA_133) {
                u32 reg54h;
@@ -600,8 +594,6 @@ static int sis5513_tune_chipset(ide_drive_t *drive, const u8 speed)
                        BUG();
                        break;
        }
-
-       return ide_config_drive_speed(drive, speed);
 }
 
 static int sis5513_config_xfer_rate(ide_drive_t *drive)
@@ -841,7 +833,7 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
                hwif->irq = hwif->channel ? 15 : 14;
 
        hwif->set_pio_mode = &sis_set_pio_mode;
-       hwif->speedproc = &sis5513_tune_chipset;
+       hwif->set_dma_mode = &sis_set_dma_mode;
 
        if (chipset_family >= ATA_133)
                hwif->udma_filter = sis5513_ata133_udma_filter;
index f492318ba79724b0b702c9bb4fd794cc66aaf5f5..2ef26e3f7be4752e1b6d2e8331abd53cb5feb6db 100644 (file)
@@ -75,7 +75,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
 /*
  * Configure the chipset for PIO mode.
  */
-static void sl82c105_tune_pio(ide_drive_t *drive, const u8 pio)
+static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        struct pci_dev *dev     = HWIF(drive)->pci_dev;
        int reg                 = 0x44 + drive->dn * 4;
@@ -105,9 +105,9 @@ static void sl82c105_tune_pio(ide_drive_t *drive, const u8 pio)
 }
 
 /*
- * Configure the drive and chipset for a new transfer speed.
+ * Configure the chipset for DMA mode.
  */
-static int sl82c105_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200};
        u16 drv_ctrl;
@@ -140,10 +140,8 @@ static int sl82c105_tune_chipset(ide_drive_t *drive, const u8 speed)
                }
                break;
        default:
-               return -1;
+               return;
        }
-
-       return ide_config_drive_speed(drive, speed);
 }
 
 /*
@@ -306,17 +304,6 @@ static void sl82c105_resetproc(ide_drive_t *drive)
        pci_read_config_dword(dev, 0x40, &val);
        pci_set_drvdata(dev, (void *)val);
 }
-       
-/*
- * We only deal with PIO mode here - DMA mode 'using_dma' is not
- * initialised at the point that this function is called.
- */
-static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       sl82c105_tune_pio(drive, pio);
-
-       (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
 
 /*
  * Return the revision of the Winbond bridge
@@ -383,7 +370,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
        DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
 
        hwif->set_pio_mode      = &sl82c105_set_pio_mode;
-       hwif->speedproc         = &sl82c105_tune_chipset;
+       hwif->set_dma_mode      = &sl82c105_set_dma_mode;
        hwif->selectproc        = &sl82c105_selectproc;
        hwif->resetproc         = &sl82c105_resetproc;
 
index ae8e9132457773130336b02ac9110227bc595110..ebac87f7200a0d4af94199cc30bed6d95528217f 100644 (file)
@@ -42,7 +42,7 @@ static u8 slc90e66_dma_2_pio (u8 xfer_rate) {
        }
 }
 
-static void slc90e66_tune_pio (ide_drive_t *drive, u8 pio)
+static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -95,13 +95,7 @@ static void slc90e66_tune_pio (ide_drive_t *drive, u8 pio)
        spin_unlock_irqrestore(&ide_lock, flags);
 }
 
-static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-       slc90e66_tune_pio(drive, pio);
-       (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
-static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev *dev     = hwif->pci_dev;
@@ -125,7 +119,7 @@ static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed)
                case XFER_MW_DMA_2:
                case XFER_MW_DMA_1:
                case XFER_SW_DMA_2:     break;
-               default:                return -1;
+               default:                return;
        }
 
        if (speed >= XFER_UDMA_0) {
@@ -144,9 +138,7 @@ static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed)
                        pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
        }
 
-       slc90e66_tune_pio(drive, slc90e66_dma_2_pio(speed));
-
-       return ide_config_drive_speed(drive, speed);
+       slc90e66_set_pio_mode(drive, slc90e66_dma_2_pio(speed));
 }
 
 static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
@@ -172,8 +164,8 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
        if (!hwif->irq)
                hwif->irq = hwif->channel ? 15 : 14;
 
-       hwif->speedproc = &slc90e66_tune_chipset;
        hwif->set_pio_mode = &slc90e66_set_pio_mode;
+       hwif->set_dma_mode = &slc90e66_set_dma_mode;
 
        pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
 
index e23b9cfb6eb49816ad156f95ad0f5b4aaf78d983..840415d68d38e56482e24f5e9a61809d12db7a56 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/pci.h>
 #include <linux/ide.h>
 
-static int tc86c001_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        unsigned long scr_port  = hwif->config_data + (drive->dn ? 0x02 : 0x00);
@@ -39,13 +39,11 @@ static int tc86c001_tune_chipset(ide_drive_t *drive, const u8 speed)
        scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
        scr |= mode;
        outw(scr, scr_port);
-
-       return ide_config_drive_speed(drive, speed);
 }
 
 static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       (void) tc86c001_tune_chipset(drive, XFER_PIO_0 + pio);
+       tc86c001_set_mode(drive, XFER_PIO_0 + pio);
 }
 
 /*
@@ -193,7 +191,8 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
        hwif->config_data = sc_base;
 
        hwif->set_pio_mode = &tc86c001_set_pio_mode;
-       hwif->speedproc = &tc86c001_tune_chipset;
+       hwif->set_dma_mode = &tc86c001_set_mode;
+
        hwif->busproc   = &tc86c001_busproc;
 
        hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
index c3ff066eea5a1a4290a6cd3708e1d399d9acc4f5..54e411d4e56cfe5d2c538c85946b1651828fb1d4 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/ide.h>
 #include <linux/init.h>
 
-static int triflex_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif = HWIF(drive);
        struct pci_dev *dev = hwif->pci_dev;
@@ -82,20 +82,18 @@ static int triflex_tune_chipset(ide_drive_t *drive, const u8 speed)
                        timing = 0x0808;
                        break;
                default:
-                       return -1;
+                       return;
        }
 
        triflex_timings &= ~(0xFFFF << (16 * unit));
        triflex_timings |= (timing << (16 * unit));
        
        pci_write_config_dword(dev, channel_offset, triflex_timings);
-       
-       return (ide_config_drive_speed(drive, speed));
 }
 
 static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       (void)triflex_tune_chipset(drive, XFER_PIO_0 + pio);
+       triflex_set_mode(drive, XFER_PIO_0 + pio);
 }
 
 static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
@@ -111,7 +109,7 @@ static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
 static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
 {
        hwif->set_pio_mode = &triflex_set_pio_mode;
-       hwif->speedproc = &triflex_tune_chipset;
+       hwif->set_dma_mode = &triflex_set_mode;
 
        if (hwif->dma_base == 0)
                return;
index ac094e51d2bf03ea0a99ff8f60c895b74b9ac93e..479e4966103290cb1e18c2438ca2fbd7b1e27c45 100644 (file)
@@ -153,21 +153,17 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
  *     @drive: Drive to set up
  *     @speed: desired speed
  *
- *     via_set_drive() computes timing values configures the drive and
- *     the chipset to a desired transfer mode. It also can be called
- *     by upper layers.
+ *     via_set_drive() computes timing values configures the chipset to
+ *     a desired transfer mode.  It also can be called by upper layers.
  */
 
-static int via_set_drive(ide_drive_t *drive, const u8 speed)
+static void via_set_drive(ide_drive_t *drive, const u8 speed)
 {
        ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
        struct via82cxxx_dev *vdev = pci_get_drvdata(drive->hwif->pci_dev);
        struct ide_timing t, p;
        unsigned int T, UT;
 
-       if (ide_config_drive_speed(drive, speed))
-               return 1;
-
        T = 1000000000 / via_clock;
 
        switch (vdev->via_config->udma_mask) {
@@ -186,12 +182,10 @@ static int via_set_drive(ide_drive_t *drive, const u8 speed)
        }
 
        via_set_speed(HWIF(drive), drive->dn, &t);
-
-       return 0;
 }
 
 /**
- *     via_set_pio_mode        -       PIO setup
+ *     via_set_pio_mode        -       set host controller for PIO mode
  *     @drive: drive
  *     @pio: PIO mode number
  *
@@ -452,8 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
        hwif->autodma = 0;
 
        hwif->set_pio_mode = &via_set_pio_mode;
-       hwif->speedproc = &via_set_drive;
-
+       hwif->set_dma_mode = &via_set_drive;
 
 #ifdef CONFIG_PPC_CHRP
        if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
@@ -496,7 +489,8 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
                .enablebits     = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
                .bootable       = ON_BOARD,
                .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST
-                               | IDE_HFLAG_PIO_NO_DOWNGRADE,
+                               | IDE_HFLAG_PIO_NO_DOWNGRADE
+                               | IDE_HFLAG_POST_SET_MODE,
                .pio_mask       = ATA_PIO5,
        },{     /* 1 */
                .name           = "VP_IDE",
@@ -506,7 +500,8 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
                .enablebits     = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
                .bootable       = ON_BOARD,
                .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST
-                               | IDE_HFLAG_PIO_NO_DOWNGRADE,
+                               | IDE_HFLAG_PIO_NO_DOWNGRADE
+                               | IDE_HFLAG_POST_SET_MODE,
                .pio_mask       = ATA_PIO5,
        }
 };
index 313194a0f36e0b505809519cc64d2baab531dd6b..7d8873839e2103d8af49c7dd0fe73260c23af88a 100644 (file)
@@ -611,9 +611,6 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
                drive->name, pio,  *timings);
 #endif 
 
-       if (ide_config_drive_speed(drive, XFER_PIO_0 + pio))
-               return;
-
        *timings = t;
        pmac_ide_do_update_timings(drive);
 }
@@ -822,11 +819,7 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
 }
 #endif /* #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC */
 
-/* 
- * Speedproc. This function is called by the core to set any of the standard
- * DMA timing (MDMA or UDMA) to both the drive and the controller.
- */
-static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        int unit = (drive->select.b.unit & 0x01);
        int ret = 0;
@@ -867,25 +860,19 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed)
                case XFER_SW_DMA_2:
                case XFER_SW_DMA_1:
                case XFER_SW_DMA_0:
-                       return 1;
+                       return;
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
                default:
                        ret = 1;
        }
        if (ret)
-               return ret;
-
-       ret = ide_config_drive_speed(drive, speed);
-       if (ret)
-               return ret;
+               return;
 
        /* Apply timings to controller */
        *timings = tl[0];
        *timings2 = tl[1];
 
        pmac_ide_do_update_timings(drive);      
-
-       return 0;
 }
 
 /*
@@ -1147,7 +1134,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        hwif->drives[1].unmask = 1;
        hwif->drives[0].autotune = IDE_TUNE_AUTO;
        hwif->drives[1].autotune = IDE_TUNE_AUTO;
-       hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA;
+       hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
+                          IDE_HFLAG_POST_SET_MODE;
        hwif->pio_mask = ATA_PIO4;
        hwif->set_pio_mode = pmac_ide_set_pio_mode;
        if (pmif->kind == controller_un_ata6
@@ -1156,7 +1144,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
                hwif->selectproc = pmac_ide_kauai_selectproc;
        else
                hwif->selectproc = pmac_ide_selectproc;
-       hwif->speedproc = pmac_ide_tune_chipset;
+       hwif->set_dma_mode = pmac_ide_set_dma_mode;
 
        printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n",
               hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,
index a7d8b4bc7681eebb8c9b2a84b68533e11277eaab..02a27e8cbad2b250becd2edeb7d3c40102ac40bd 100644 (file)
@@ -681,7 +681,7 @@ typedef struct hwif_s {
        u8 straight8;   /* Alan's straight 8 check */
        u8 bus_state;   /* power state of the IDE bus */
 
-       u8 host_flags;
+       u16 host_flags;
 
        u8 pio_mask;
 
@@ -702,10 +702,10 @@ typedef struct hwif_s {
 #if 0
        ide_hwif_ops_t  *hwifops;
 #else
-       /* routine to set PIO mode for drives */
+       /* routine to program host for PIO mode */
        void    (*set_pio_mode)(ide_drive_t *, const u8);
-       /* routine to retune DMA modes for drives */
-       int     (*speedproc)(ide_drive_t *, const u8);
+       /* routine to program host for DMA mode */
+       void    (*set_dma_mode)(ide_drive_t *, const u8);
        /* tweaks hardware to select drive */
        void    (*selectproc)(ide_drive_t *);
        /* chipset polling based on hba specifics */
@@ -1257,6 +1257,10 @@ enum {
         * for hosts which have separate PIO and DMA timings (ie. PMAC)
         */
        IDE_HFLAG_SET_PIO_MODE_KEEP_DMA = (1 << 7),
+       /* program host for the transfer mode after programming device */
+       IDE_HFLAG_POST_SET_MODE         = (1 << 8),
+       /* don't program host/device for the transfer mode ("smart" hosts) */
+       IDE_HFLAG_NO_SET_MODE           = (1 << 9),
 };
 
 typedef struct ide_pci_device_s {
@@ -1273,7 +1277,7 @@ typedef struct ide_pci_device_s {
        u8                      bootable;
        unsigned int            extra;
        struct ide_pci_device_s *next;
-       u                     host_flags;
+       u16                     host_flags;
        u8                      pio_mask;
        u8                      udma_mask;
 } ide_pci_device_t;
@@ -1414,6 +1418,9 @@ unsigned int ide_pio_cycle_time(ide_drive_t *, u8);
 u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
 extern const ide_pio_timings_t ide_pio_timings[6];
 
+int ide_set_pio_mode(ide_drive_t *, u8);
+int ide_set_dma_mode(ide_drive_t *, u8);
+
 void ide_set_pio(ide_drive_t *, u8);
 
 static inline void ide_set_max_pio(ide_drive_t *drive)