summaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_sil.c
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@linux.vnet.ibm.com>2009-02-02 20:40:55 +0100
committerDave Kleikamp <shaggy@linux.vnet.ibm.com>2009-02-02 20:40:55 +0100
commit8db0c5d5ef3ab99fe9e5151872b75f45c4282e3c (patch)
treeda9759151e00221c58cdd9f4de893c0b08753670 /drivers/ata/sata_sil.c
parentjfs: Fix error handling in metapage_writepage() (diff)
parentMerge branch 'header-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/k... (diff)
downloadlinux-8db0c5d5ef3ab99fe9e5151872b75f45c4282e3c.tar.xz
linux-8db0c5d5ef3ab99fe9e5151872b75f45c4282e3c.zip
Merge branch 'master' of /home/shaggy/git/linus-clean/
Diffstat (limited to 'drivers/ata/sata_sil.c')
-rw-r--r--drivers/ata/sata_sil.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 564c142b03b0..9f029595f454 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -44,6 +44,7 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include <linux/dmi.h>
#define DRV_NAME "sata_sil"
#define DRV_VERSION "2.4"
@@ -695,11 +696,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 +741,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;