ide: IORDY handling fixes
Bartlomiej Zolnierkiewicz [Mon, 15 Jun 2009 16:52:53 +0000 (18:52 +0200)]
Add ide_pio_need_iordy() helper and convert host drivers to use it.

This fixes it8172, it8213, pdc202xx_old, piix, slc90e66 and siimage
host drivers to handle IORDY correctly.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

drivers/ide/at91_ide.c
drivers/ide/ide-xfer-mode.c
drivers/ide/it8172.c
drivers/ide/it8213.c
drivers/ide/pdc202xx_old.c
drivers/ide/piix.c
drivers/ide/siimage.c
drivers/ide/sl82c105.c
drivers/ide/slc90e66.c
include/linux/ide.h

index fc0949a..dbfeda4 100644 (file)
@@ -185,8 +185,7 @@ static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
        timing = ide_timing_find_mode(XFER_PIO_0 + pio);
        BUG_ON(!timing);
 
-       if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
-           !(ata_id_is_cfa(drive->id) && pio > 4))
+       if (ide_pio_need_iordy(drive, pio))
                use_iordy = 1;
 
        apply_timings(chipselect, pio, timing, use_iordy);
index af44be9..0b47ca1 100644 (file)
@@ -107,6 +107,12 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
 }
 EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
 
+int ide_pio_need_iordy(ide_drive_t *drive, const u8 pio)
+{
+       return ata_id_pio_need_iordy(drive->id, pio);
+}
+EXPORT_SYMBOL_GPL(ide_pio_need_iordy);
+
 int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
 {
        ide_hwif_t *hwif = drive->hwif;
index e021078..0d266a5 100644 (file)
@@ -66,7 +66,7 @@ static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
        if (drive->media == ide_disk)
                /* enable prefetch */
                drive_enables |= 0x0004 << (drive->dn * 4);
-       if (ata_id_has_iordy(drive->id))
+       if (ide_pio_need_iordy(drive, pio))
                /* enable IORDY sample-point */
                drive_enables |= 0x0002 << (drive->dn * 4);
 
index d7969b6..4797616 100644 (file)
@@ -50,7 +50,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
                control |= 1;   /* Programmable timing on */
        if (drive->media != ide_disk)
                control |= 4;   /* ATAPI */
-       if (pio > 2)
+       if (ide_pio_need_iordy(drive, pio))
                control |= 2;   /* IORDY */
        if (is_slave) {
                master_data |=  0x4000;
index b6abf7e..4f5b536 100644 (file)
@@ -73,7 +73,7 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
                 * Prefetch_EN / IORDY_EN / PA[3:0] bits of register A
                 */
                AP &= ~0x3f;
-               if (ata_id_iordy_disable(drive->id))
+               if (ide_pio_need_iordy(drive, speed - XFER_PIO_0))
                        AP |= 0x20;     /* set IORDY_EN bit */
                if (drive->media == ide_disk)
                        AP |= 0x10;     /* set Prefetch_EN bit */
index 69860de..bf14f39 100644 (file)
@@ -98,7 +98,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
                control |= 1;   /* Programmable timing on */
        if (drive->media == ide_disk)
                control |= 4;   /* Prefetch, post write */
-       if (pio > 2)
+       if (ide_pio_need_iordy(drive, pio))
                control |= 2;   /* IORDY */
        if (is_slave) {
                master_data |=  0x4000;
index bd82d22..6a643fd 100644 (file)
@@ -32,7 +32,6 @@
  *  smarter code in libata.
  *
  * TODO:
- * - IORDY fixes
  * - VDMA support
  */
 
@@ -234,8 +233,7 @@ static u8 sil_sata_udma_filter(ide_drive_t *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
+ *     controller.
  */
 
 static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
@@ -276,13 +274,16 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
        /* now set up IORDY */
        speedp = sil_ioread16(dev, tfaddr - 2);
        speedp &= ~0x200;
-       if (pio > 2)
-               speedp |= 0x200;
-       sil_iowrite16(dev, speedp, tfaddr - 2);
 
        mode = sil_ioread8(dev, base + addr_mask);
        mode &= ~(unit ? 0x30 : 0x03);
-       mode |= unit ? 0x10 : 0x01;
+
+       if (ide_pio_need_iordy(drive, pio)) {
+               speedp |= 0x200;
+               mode |= unit ? 0x10 : 0x01;
+       }
+
+       sil_iowrite16(dev, speedp, tfaddr - 2);
        sil_iowrite8(dev, mode, base + addr_mask);
 }
 
index 0924abf..88ac470 100644 (file)
@@ -61,8 +61,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
        if (cmd_off == 0)
                cmd_off = 1;
 
-       if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
-           !(pio > 4 && ata_id_is_cfa(drive->id)))
+       if (ide_pio_need_iordy(drive, pio))
                iordy = 0x40;
 
        return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
index f55d7d6..9aec78d 100644 (file)
@@ -44,7 +44,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
                control |= 1;   /* Programmable timing on */
        if (drive->media == ide_disk)
                control |= 4;   /* Prefetch, post write */
-       if (pio > 2)
+       if (ide_pio_need_iordy(drive, pio))
                control |= 2;   /* IORDY */
        if (is_slave) {
                master_data |=  0x4000;
index cdb29b6..8c7f5e5 100644 (file)
@@ -1514,6 +1514,7 @@ int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int);
 int ide_scan_pio_blacklist(char *);
 const char *ide_xfer_verbose(u8);
 u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
+int ide_pio_need_iordy(ide_drive_t *, const u8);
 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);