diff options
-rw-r--r-- | drivers/ata/sata_sil.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 564c142b03b0..bfd55b085ae6 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -695,11 +695,38 @@ static void sil_init_controller(struct ata_host *host) | |||
695 | } | 695 | } |
696 | } | 696 | } |
697 | 697 | ||
698 | static bool sil_broken_system_poweroff(struct pci_dev *pdev) | ||
699 | { | ||
700 | static const struct dmi_system_id broken_systems[] = { | ||
701 | { | ||
702 | .ident = "HP Compaq nx6325", | ||
703 | .matches = { | ||
704 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
705 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), | ||
706 | }, | ||
707 | /* PCI slot number of the controller */ | ||
708 | .driver_data = (void *)0x12UL, | ||
709 | }, | ||
710 | |||
711 | { } /* terminate list */ | ||
712 | }; | ||
713 | const struct dmi_system_id *dmi = dmi_first_match(broken_systems); | ||
714 | |||
715 | if (dmi) { | ||
716 | unsigned long slot = (unsigned long)dmi->driver_data; | ||
717 | /* apply the quirk only to on-board controllers */ | ||
718 | return slot == PCI_SLOT(pdev->devfn); | ||
719 | } | ||
720 | |||
721 | return false; | ||
722 | } | ||
723 | |||
698 | static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 724 | static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
699 | { | 725 | { |
700 | static int printed_version; | 726 | static int printed_version; |
701 | int board_id = ent->driver_data; | 727 | int board_id = ent->driver_data; |
702 | const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL }; | 728 | struct ata_port_info pi = sil_port_info[board_id]; |
729 | const struct ata_port_info *ppi[] = { &pi, NULL }; | ||
703 | struct ata_host *host; | 730 | struct ata_host *host; |
704 | void __iomem *mmio_base; | 731 | void __iomem *mmio_base; |
705 | int n_ports, rc; | 732 | int n_ports, rc; |
@@ -713,6 +740,13 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
713 | if (board_id == sil_3114) | 740 | if (board_id == sil_3114) |
714 | n_ports = 4; | 741 | n_ports = 4; |
715 | 742 | ||
743 | if (sil_broken_system_poweroff(pdev)) { | ||
744 | pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN | | ||
745 | ATA_FLAG_NO_HIBERNATE_SPINDOWN; | ||
746 | dev_info(&pdev->dev, "quirky BIOS, skipping spindown " | ||
747 | "on poweroff and hibernation\n"); | ||
748 | } | ||
749 | |||
716 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | 750 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); |
717 | if (!host) | 751 | if (!host) |
718 | return -ENOMEM; | 752 | return -ENOMEM; |