]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From 285ddd34af077acb9148bba2569947c7af41b8ce Mon Sep 17 00:00:00 2001 |
2 | From: Rafael J. Wysocki <rjw@sisk.pl> | |
3 | Date: Mon, 3 Nov 2008 19:01:06 +0900 | |
4 | Subject: [PATCH] SATA Sil: 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 nx6325 that uses the sata_sil 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/sata_sil.c | 36 +++++++++++++++++++++++++++++++++++- | |
25 | 1 file changed, 35 insertions(+), 1 deletion(-) | |
26 | ||
27 | Index: linux-2.6.27/drivers/ata/sata_sil.c | |
28 | =================================================================== | |
29 | --- linux-2.6.27.orig/drivers/ata/sata_sil.c | |
30 | +++ linux-2.6.27/drivers/ata/sata_sil.c | |
31 | @@ -603,11 +603,38 @@ static void sil_init_controller(struct a | |
32 | } | |
33 | } | |
34 | ||
35 | +static bool sil_broken_system_poweroff(struct pci_dev *pdev) | |
36 | +{ | |
37 | + static const struct dmi_system_id broken_systems[] = { | |
38 | + { | |
39 | + .ident = "HP Compaq nx6325", | |
40 | + .matches = { | |
41 | + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | |
42 | + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), | |
43 | + }, | |
44 | + /* PCI slot number of the controller */ | |
45 | + .driver_data = (void *)0x12UL, | |
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 sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |
62 | { | |
63 | static int printed_version; | |
64 | int board_id = ent->driver_data; | |
65 | - const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL }; | |
66 | + struct ata_port_info pi = sil_port_info[board_id]; | |
67 | + const struct ata_port_info *ppi[] = { &pi, NULL }; | |
68 | struct ata_host *host; | |
69 | void __iomem *mmio_base; | |
70 | int n_ports, rc; | |
71 | @@ -621,6 +648,13 @@ static int sil_init_one(struct pci_dev * | |
72 | if (board_id == sil_3114) | |
73 | n_ports = 4; | |
74 | ||
75 | + if (sil_broken_system_poweroff(pdev)) { | |
76 | + pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN | | |
77 | + ATA_FLAG_NO_HIBERNATE_SPINDOWN; | |
78 | + dev_info(&pdev->dev, "quirky BIOS, skipping spindown " | |
79 | + "on poweroff and hibernation\n"); | |
80 | + } | |
81 | + | |
82 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | |
83 | if (!host) | |
84 | return -ENOMEM; |