]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/sata_sil.c
SATA Sil: Blacklist system that spins off disks during ACPI power off
[linux-2.6-omap-h63xx.git] / drivers / ata / sata_sil.c
index 564c142b03b043ec9faf0c930b5ded6af1dc8b1d..bfd55b085ae63f55065ca85833b2a48fa6721dd6 100644 (file)
@@ -695,11 +695,38 @@ static void sil_init_controller(struct ata_host *host)
        }
 }
 
+static bool sil_broken_system_poweroff(struct pci_dev *pdev)
+{
+       static const struct dmi_system_id broken_systems[] = {
+               {
+                       .ident = "HP Compaq nx6325",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
+                       },
+                       /* PCI slot number of the controller */
+                       .driver_data = (void *)0x12UL,
+               },
+
+               { }     /* terminate list */
+       };
+       const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
+
+       if (dmi) {
+               unsigned long slot = (unsigned long)dmi->driver_data;
+               /* apply the quirk only to on-board controllers */
+               return slot == PCI_SLOT(pdev->devfn);
+       }
+
+       return false;
+}
+
 static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        int board_id = ent->driver_data;
-       const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL };
+       struct ata_port_info pi = sil_port_info[board_id];
+       const struct ata_port_info *ppi[] = { &pi, NULL };
        struct ata_host *host;
        void __iomem *mmio_base;
        int n_ports, rc;
@@ -713,6 +740,13 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (board_id == sil_3114)
                n_ports = 4;
 
+       if (sil_broken_system_poweroff(pdev)) {
+               pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN |
+                                       ATA_FLAG_NO_HIBERNATE_SPINDOWN;
+               dev_info(&pdev->dev, "quirky BIOS, skipping spindown "
+                               "on poweroff and hibernation\n");
+       }
+
        host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
        if (!host)
                return -ENOMEM;