Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=681c80b5d96076f447e8101ac4325c82d8dce508
Commit:     681c80b5d96076f447e8101ac4325c82d8dce508
Parent:     237d8440cb2b104a3b97fc971a9bce67960bb616
Author:     Alan Cox <[EMAIL PROTECTED]>
AuthorDate: Wed Oct 3 13:23:18 2007 +0100
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Fri Oct 12 14:55:45 2007 -0400

    libata: correct handling of SRST reset sequences
    
    Correct handling of SRST reset sequences.  After an SRST it is undefined
    whether the drive has gone back to PIO0.  In order to talk safely we should
    talk slowly and carefully until we know.
    
    Thus when we do the reset if the controller has a pio setup method we call 
it
    to flip back to PIO 0 and a known state.  After the reset completes the
    identify will then be done at the safe speed and the drive/controller will
    pick suitable faster modes and reconfigure the controller to these timings.
    
    As a side effect it means we force the controller to PIO 0 as we bring it up
    which fixes funnies on a few systems where the BIOS firmware leaves us in an
    interesting choice of modes, or embedded boxes with no firmware which come 
up
    in random states.
    
    For smart controllers there is nothing to do - they know about this
    internally.
    
    Signed-off-by: Alan Cox <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 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 1501d63..aecbdad 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
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to