aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c21
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