]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/ata/ahci.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[net-next-2.6.git] / drivers / ata / ahci.c
index 6bd930b93bccf8f19eb80967429d6a980908dd29..5326af28a4100fbb4c611c8aa76bcb490938bb97 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
 #include <linux/dmi.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/libata.h>
@@ -641,6 +642,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq },     /* MCP67 */
        { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq },     /* MCP67 */
        { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0581), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_yesncq },     /* Linux ID */
+       { PCI_VDEVICE(NVIDIA, 0x058f), board_ahci_yesncq },     /* Linux ID */
        { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq },     /* MCP73 */
        { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq },     /* MCP73 */
        { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq },     /* MCP73 */
@@ -2263,7 +2279,7 @@ static void ahci_port_intr(struct ata_port *ap)
        struct ahci_port_priv *pp = ap->private_data;
        struct ahci_host_priv *hpriv = ap->host->private_data;
        int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
-       u32 status, qc_active;
+       u32 status, qc_active = 0;
        int rc;
 
        status = readl(port_mmio + PORT_IRQ_STAT);
@@ -2321,11 +2337,22 @@ static void ahci_port_intr(struct ata_port *ap)
                }
        }
 
-       /* pp->active_link is valid iff any command is in flight */
-       if (ap->qc_active && pp->active_link->sactive)
-               qc_active = readl(port_mmio + PORT_SCR_ACT);
-       else
-               qc_active = readl(port_mmio + PORT_CMD_ISSUE);
+       /* pp->active_link is not reliable once FBS is enabled, both
+        * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because
+        * NCQ and non-NCQ commands may be in flight at the same time.
+        */
+       if (pp->fbs_enabled) {
+               if (ap->qc_active) {
+                       qc_active = readl(port_mmio + PORT_SCR_ACT);
+                       qc_active |= readl(port_mmio + PORT_CMD_ISSUE);
+               }
+       } else {
+               /* pp->active_link is valid iff any command is in flight */
+               if (ap->qc_active && pp->active_link->sactive)
+                       qc_active = readl(port_mmio + PORT_SCR_ACT);
+               else
+                       qc_active = readl(port_mmio + PORT_CMD_ISSUE);
+       }
 
        rc = ata_qc_complete_multiple(ap, qc_active);
 
@@ -3022,6 +3049,14 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                 * On HP dv[4-6] and HDX18 with earlier BIOSen, link
                 * to the harddisk doesn't become online after
                 * resuming from STR.  Warn and fail suspend.
+                *
+                * http://bugzilla.kernel.org/show_bug.cgi?id=12276
+                *
+                * Use dates instead of versions to match as HP is
+                * apparently recycling both product and version
+                * strings.
+                *
+                * http://bugzilla.kernel.org/show_bug.cgi?id=15462
                 */
                {
                        .ident = "dv4",
@@ -3030,7 +3065,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_PRODUCT_NAME,
                                          "HP Pavilion dv4 Notebook PC"),
                        },
-                       .driver_data = "F.30", /* cutoff BIOS version */
+                       .driver_data = "20090105",      /* F.30 */
                },
                {
                        .ident = "dv5",
@@ -3039,7 +3074,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_PRODUCT_NAME,
                                          "HP Pavilion dv5 Notebook PC"),
                        },
-                       .driver_data = "F.16", /* cutoff BIOS version */
+                       .driver_data = "20090506",      /* F.16 */
                },
                {
                        .ident = "dv6",
@@ -3048,7 +3083,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_PRODUCT_NAME,
                                          "HP Pavilion dv6 Notebook PC"),
                        },
-                       .driver_data = "F.21",  /* cutoff BIOS version */
+                       .driver_data = "20090423",      /* F.21 */
                },
                {
                        .ident = "HDX18",
@@ -3057,7 +3092,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_PRODUCT_NAME,
                                          "HP HDX18 Notebook PC"),
                        },
-                       .driver_data = "F.23",  /* cutoff BIOS version */
+                       .driver_data = "20090430",      /* F.23 */
                },
                /*
                 * Acer eMachines G725 has the same problem.  BIOS
@@ -3065,6 +3100,8 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                 * work.  Inbetween, there are V1.06, V2.06 and V3.03
                 * that we don't have much idea about.  For now,
                 * blacklist anything older than V3.04.
+                *
+                * http://bugzilla.kernel.org/show_bug.cgi?id=15104
                 */
                {
                        .ident = "G725",
@@ -3072,19 +3109,21 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
                                DMI_MATCH(DMI_SYS_VENDOR, "eMachines"),
                                DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"),
                        },
-                       .driver_data = "V3.04", /* cutoff BIOS version */
+                       .driver_data = "20091216",      /* V3.04 */
                },
                { }     /* terminate list */
        };
        const struct dmi_system_id *dmi = dmi_first_match(sysids);
-       const char *ver;
+       int year, month, date;
+       char buf[9];
 
        if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2))
                return false;
 
-       ver = dmi_get_system_info(DMI_BIOS_VERSION);
+       dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
+       snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
 
-       return !ver || strcmp(ver, dmi->driver_data) < 0;
+       return strcmp(buf, dmi->driver_data) < 0;
 }
 
 static bool ahci_broken_online(struct pci_dev *pdev)