]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From 60d90dc8151413ae21bc6adcf0cfd995628ae87f Mon Sep 17 00:00:00 2001 |
2 | From: Rafael J. Wysocki <rjw@sisk.pl> | |
3 | Date: Mon, 3 Nov 2008 19:01:05 +0900 | |
4 | Subject: [PATCH] SATA AHCI: Blacklist system that spins off disks during ACPI power off | |
5 | References: bnc#441721 | |
6 | ||
7 | Some notebooks from HP have the problem that their BIOSes attempt to | |
8 | spin down hard drives before entering ACPI system states S4 and S5. | |
9 | This leads to a yo-yo effect during system power-off shutdown and the | |
10 | last phase of hibernation when the disk is first spun down by the | |
11 | kernel and then almost immediately turned on and off by the BIOS. | |
12 | This, in turn, may result in shortening the disk's life times. | |
13 | ||
14 | To prevent this from happening we can blacklist the affected systems | |
15 | using DMI information. | |
16 | ||
17 | Blacklist HP nx6310 that uses the AHCI driver. | |
18 | ||
19 | Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> | |
20 | Signed-off-by: Tejun Heo <tj@kernel.org> | |
21 | Signed-off-by: Jeff Garzik <jgarzik@redhat.com> | |
22 | Signed-off-by: Tejun Heo <teheo@suse.de> | |
23 | --- | |
24 | drivers/ata/ahci.c | 32 ++++++++++++++++++++++++++++++++ | |
25 | 1 file changed, 32 insertions(+) | |
26 | ||
27 | Index: linux-2.6.27/drivers/ata/ahci.c | |
28 | =================================================================== | |
29 | --- linux-2.6.27.orig/drivers/ata/ahci.c | |
30 | +++ linux-2.6.27/drivers/ata/ahci.c | |
31 | @@ -2528,6 +2528,32 @@ static void ahci_p5wdh_workaround(struct | |
32 | } | |
33 | } | |
34 | ||
35 | +static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | |
36 | +{ | |
37 | + static const struct dmi_system_id broken_systems[] = { | |
38 | + { | |
39 | + .ident = "HP Compaq nx6310", | |
40 | + .matches = { | |
41 | + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | |
42 | + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6310"), | |
43 | + }, | |
44 | + /* PCI slot number of the controller */ | |
45 | + .driver_data = (void *)0x1FUL, | |
46 | + }, | |
47 | + | |
48 | + { } /* terminate list */ | |
49 | + }; | |
50 | + const struct dmi_system_id *dmi = dmi_first_match(broken_systems); | |
51 | + | |
52 | + if (dmi) { | |
53 | + unsigned long slot = (unsigned long)dmi->driver_data; | |
54 | + /* apply the quirk only to on-board controllers */ | |
55 | + return slot == PCI_SLOT(pdev->devfn); | |
56 | + } | |
57 | + | |
58 | + return false; | |
59 | +} | |
60 | + | |
61 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |
62 | { | |
63 | static int printed_version; | |
64 | @@ -2623,6 +2649,12 @@ static int ahci_init_one(struct pci_dev | |
65 | } | |
66 | } | |
67 | ||
68 | + if (ahci_broken_system_poweroff(pdev)) { | |
69 | + pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN; | |
70 | + dev_info(&pdev->dev, | |
71 | + "quirky BIOS, skipping spindown on poweroff\n"); | |
72 | + } | |
73 | + | |
74 | /* CAP.NP sometimes indicate the index of the last enabled | |
75 | * port, at other times, that of the last possible port, so | |
76 | * determining the maximum port number requires looking at |