]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From 8794806469a35ab09378e9ee7ad39da6284cb8ff Mon Sep 17 00:00:00 2001 |
2 | From: Rafael J. Wysocki <rjw@sisk.pl> | |
3 | Date: Mon, 3 Nov 2008 19:01:04 +0900 | |
4 | Subject: [PATCH] SATA: Blacklisting of systems that spin off disks during ACPI power off (rev. 2) | |
5 | References: bnc#441721 | |
6 | ||
7 | Introduce new libata flags ATA_FLAG_NO_POWEROFF_SPINDOWN and | |
8 | ATA_FLAG_NO_HIBERNATE_SPINDOWN that, if set, will prevent disks from | |
9 | being spun off during system power off and hibernation, respectively | |
10 | (to handle the hibernation case we need the new system state | |
11 | SYSTEM_HIBERNATE_ENTER that can be checked against by libata, in | |
12 | analogy with SYSTEM_POWER_OFF). | |
13 | ||
14 | Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> | |
15 | Signed-off-by: Tejun Heo <tj@kernel.org> | |
16 | Signed-off-by: Jeff Garzik <jgarzik@redhat.com> | |
17 | Signed-off-by: Tejun Heo <teheo@suse.de> | |
18 | --- | |
19 | drivers/ata/libata-scsi.c | 20 +++++++++++++++++--- | |
20 | include/linux/libata.h | 2 ++ | |
21 | 2 files changed, 19 insertions(+), 3 deletions(-) | |
22 | ||
23 | Index: linux-2.6.27/drivers/ata/libata-scsi.c | |
24 | =================================================================== | |
25 | --- linux-2.6.27.orig/drivers/ata/libata-scsi.c | |
26 | +++ linux-2.6.27/drivers/ata/libata-scsi.c | |
27 | @@ -46,6 +46,7 @@ | |
28 | #include <linux/libata.h> | |
29 | #include <linux/hdreg.h> | |
30 | #include <linux/uaccess.h> | |
31 | +#include <linux/suspend.h> | |
32 | ||
33 | #include "libata.h" | |
34 | ||
35 | @@ -1181,6 +1182,17 @@ static unsigned int ata_scsi_start_stop_ | |
36 | ||
37 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ | |
38 | } else { | |
39 | + /* Some odd clown BIOSen issue spindown on power off (ACPI S4 | |
40 | + * or S5) causing some drives to spin up and down again. | |
41 | + */ | |
42 | + if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) && | |
43 | + system_state == SYSTEM_POWER_OFF) | |
44 | + goto skip; | |
45 | + | |
46 | + if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && | |
47 | + system_entering_hibernation()) | |
48 | + goto skip; | |
49 | + | |
50 | /* XXX: This is for backward compatibility, will be | |
51 | * removed. Read Documentation/feature-removal-schedule.txt | |
52 | * for more info. | |
53 | @@ -1204,8 +1216,7 @@ static unsigned int ata_scsi_start_stop_ | |
54 | scmd->scsi_done = qc->scsidone; | |
55 | qc->scsidone = ata_delayed_done; | |
56 | } | |
57 | - scmd->result = SAM_STAT_GOOD; | |
58 | - return 1; | |
59 | + goto skip; | |
60 | } | |
61 | ||
62 | /* Issue ATA STANDBY IMMEDIATE command */ | |
63 | @@ -1221,10 +1232,13 @@ static unsigned int ata_scsi_start_stop_ | |
64 | ||
65 | return 0; | |
66 | ||
67 | -invalid_fld: | |
68 | + invalid_fld: | |
69 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); | |
70 | /* "Invalid field in cbd" */ | |
71 | return 1; | |
72 | + skip: | |
73 | + scmd->result = SAM_STAT_GOOD; | |
74 | + return 1; | |
75 | } | |
76 | ||
77 | ||
78 | Index: linux-2.6.27/include/linux/libata.h | |
79 | =================================================================== | |
80 | --- linux-2.6.27.orig/include/linux/libata.h | |
81 | +++ linux-2.6.27/include/linux/libata.h | |
82 | @@ -186,6 +186,8 @@ enum { | |
83 | ATA_FLAG_PIO_POLLING = (1 << 9), /* use polling PIO if LLD | |
84 | * doesn't handle PIO interrupts */ | |
85 | ATA_FLAG_NCQ = (1 << 10), /* host supports NCQ */ | |
86 | + ATA_FLAG_NO_POWEROFF_SPINDOWN = (1 << 11), /* don't spindown before poweroff */ | |
87 | + ATA_FLAG_NO_HIBERNATE_SPINDOWN = (1 << 12), /* don't spindown before hibernation */ | |
88 | ATA_FLAG_DEBUGMSG = (1 << 13), | |
89 | ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */ | |
90 | ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */ |