Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=5f226c6bf78edab023ed1ea679531731d9df92a6
Commit:     5f226c6bf78edab023ed1ea679531731d9df92a6
Parent:     1c954a4d9a9e351fa3509533fd8dd5f3821206cd
Author:     Tejun Heo <[EMAIL PROTECTED]>
AuthorDate: Tue Oct 9 15:02:23 2007 +0900
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Fri Oct 12 14:55:47 2007 -0400

    ahci: fix notification handling
    
    Asynchronous notification on ICH9 didn't work because it didn't write
    AN FIS into the RX area - it only updates SNotification.  Also,
    snooping SDB_FIS RX area is racy against further SDB FIS receptions.
    Let sata_async_notification() determine using SNTF if it's available
    and snoop RX area iff SNTF isn't available
    
    Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>
    Cc: Kristen Carlson Accardi <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/ata/ahci.c |   30 +++++++++++++++++++++---------
 1 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 6633c74..abfb72a 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1420,6 +1420,7 @@ static void ahci_port_intr(struct ata_port *ap)
        void __iomem *port_mmio = ap->ioaddr.cmd_addr;
        struct ata_eh_info *ehi = &ap->link.eh_info;
        struct ahci_port_priv *pp = ap->private_data;
+       struct ahci_host_priv *hpriv = ap->host->private_data;
        u32 status, qc_active;
        int rc, known_irq = 0;
 
@@ -1432,17 +1433,28 @@ static void ahci_port_intr(struct ata_port *ap)
        }
 
        if (status & PORT_IRQ_SDB_FIS) {
-               /* If the 'N' bit in word 0 of the FIS is set, we just
-                * received asynchronous notification.  Tell libata
-                * about it.  Note that as the SDB FIS itself is
-                * accessible, SNotification can be emulated by the
-                * driver but don't bother for the time being.
+               /* If SNotification is available, leave notification
+                * handling to sata_async_notification().  If not,
+                * emulate it by snooping SDB FIS RX area.
+                *
+                * Snooping FIS RX area is probably cheaper than
+                * poking SNotification but some constrollers which
+                * implement SNotification, ICH9 for example, don't
+                * store AN SDB FIS into receive area.
                 */
-               const __le32 *f = pp->rx_fis + RX_FIS_SDB;
-               u32 f0 = le32_to_cpu(f[0]);
-
-               if (f0 & (1 << 15))
+               if (hpriv->cap & HOST_CAP_SNTF)
                        sata_async_notification(ap);
+               else {
+                       /* If the 'N' bit in word 0 of the FIS is set,
+                        * we just received asynchronous notification.
+                        * Tell libata about it.
+                        */
+                       const __le32 *f = pp->rx_fis + RX_FIS_SDB;
+                       u32 f0 = le32_to_cpu(f[0]);
+
+                       if (f0 & (1 << 15))
+                               sata_async_notification(ap);
+               }
        }
 
        /* pp->active_link is valid iff any command is in flight */
-
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