diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/libata-core.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 1501d63db2c..aecbdad960f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3209,6 +3209,8 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask, unsigned long deadline) { struct ata_ioports *ioaddr = &ap->ioaddr; + struct ata_device *dev; + int i = 0; DPRINTK("ata%u: bus reset via SRST\n", ap->print_id); @@ -3219,6 +3221,25 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask, udelay(20); /* FIXME: flush */ iowrite8(ap->ctl, ioaddr->ctl_addr); + /* If we issued an SRST then an ATA drive (not ATAPI) + * may have changed configuration and be in PIO0 timing. If + * we did a hard reset (or are coming from power on) this is + * true for ATA or ATAPI. Until we've set a suitable controller + * mode we should not touch the bus as we may be talking too fast. + */ + + ata_link_for_each_dev(dev, &ap->link) + dev->pio_mode = XFER_PIO_0; + + /* If the controller has a pio mode setup function then use + it to set the chipset to rights. Don't touch the DMA setup + as that will be dealt with when revalidating */ + if (ap->ops->set_piomode) { + ata_link_for_each_dev(dev, &ap->link) + if (devmask & (1 << i++)) + ap->ops->set_piomode(ap, dev); + } + /* spec mandates ">= 2ms" before checking status. * We wait 150ms, because that was the magic delay used for * ATAPI devices in Hale Landis's ATADRVR, for the period of time |