forked from Minki/linux
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 <bzolnier@gmail.com>
This commit is contained in:
parent
6dae44f9a5
commit
c9ef59ff01
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user