|
@@ -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;
|