From c9ef59ff01b6bd1c7360a64fcc8556a1193c2ed0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 15 Jun 2009 18:52:53 +0200 Subject: ide: IORDY handling fixes 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 --- drivers/ide/at91_ide.c | 3 +-- drivers/ide/ide-xfer-mode.c | 6 ++++++ drivers/ide/it8172.c | 2 +- drivers/ide/it8213.c | 2 +- drivers/ide/pdc202xx_old.c | 2 +- drivers/ide/piix.c | 2 +- drivers/ide/siimage.c | 15 ++++++++------- drivers/ide/sl82c105.c | 3 +-- drivers/ide/slc90e66.c | 2 +- include/linux/ide.h | 1 + 10 files changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c index fc0949a8cfde..dbfeda42b940 100644 --- a/drivers/ide/at91_ide.c +++ b/drivers/ide/at91_ide.c @@ -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); diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c index af44be9d546c..0b47ca139079 100644 --- a/drivers/ide/ide-xfer-mode.c +++ b/drivers/ide/ide-xfer-mode.c @@ -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; diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c index e021078cd06b..0d266a5b524d 100644 --- a/drivers/ide/it8172.c +++ b/drivers/ide/it8172.c @@ -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); diff --git a/drivers/ide/it8213.c b/drivers/ide/it8213.c index d7969b6d139e..47976167796a 100644 --- a/drivers/ide/it8213.c +++ b/drivers/ide/it8213.c @@ -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; diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index b6abf7e52cac..4f5b536282af 100644 --- a/drivers/ide/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c @@ -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 */ diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 69860dea3820..bf14f39bd3a7 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -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; diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c index bd82d228608c..6a643fdf0e6e 100644 --- a/drivers/ide/siimage.c +++ b/drivers/ide/siimage.c @@ -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); } diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c index 0924abff52ff..88ac47085cd9 100644 --- a/drivers/ide/sl82c105.c +++ b/drivers/ide/sl82c105.c @@ -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; diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c index f55d7d6313e8..9aec78d3bcff 100644 --- a/drivers/ide/slc90e66.c +++ b/drivers/ide/slc90e66.c @@ -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; diff --git a/include/linux/ide.h b/include/linux/ide.h index cdb29b6c195f..8c7f5e50e912 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -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); -- cgit v1.2.3-58-ga151