diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2009-01-19 14:56:43 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-01-27 02:15:49 -0500 |
commit | 2a6e58d2731dcc05dafa7f976d935e0f0627fcd7 (patch) | |
tree | 836d0ec85dccde709aeaaedb3b7686ac51805ad1 /drivers/ata | |
parent | d7b1956fed33d30c4815e848fd7a143722916868 (diff) |
SATA: Blacklisting of systems that spin off disks during ACPI power off
Introduce new libata flags ATA_FLAG_NO_POWEROFF_SPINDOWN and
ATA_FLAG_NO_HIBERNATE_SPINDOWN that, if set, will prevent disks from
being spun off during system power off and hibernation, respectively
(to handle the hibernation case we need the new system state
SYSTEM_HIBERNATE_ENTER that can be checked against by libata, in
analogy with SYSTEM_POWER_OFF).
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-scsi.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a1a6e6298c33..3c4c5ae277ba 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/libata.h> | 46 | #include <linux/libata.h> |
47 | #include <linux/hdreg.h> | 47 | #include <linux/hdreg.h> |
48 | #include <linux/uaccess.h> | 48 | #include <linux/uaccess.h> |
49 | #include <linux/suspend.h> | ||
49 | 50 | ||
50 | #include "libata.h" | 51 | #include "libata.h" |
51 | 52 | ||
@@ -1303,6 +1304,17 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
1303 | 1304 | ||
1304 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ | 1305 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ |
1305 | } else { | 1306 | } else { |
1307 | /* Some odd clown BIOSen issue spindown on power off (ACPI S4 | ||
1308 | * or S5) causing some drives to spin up and down again. | ||
1309 | */ | ||
1310 | if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) && | ||
1311 | system_state == SYSTEM_POWER_OFF) | ||
1312 | goto skip; | ||
1313 | |||
1314 | if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && | ||
1315 | system_entering_hibernation()) | ||
1316 | goto skip; | ||
1317 | |||
1306 | /* XXX: This is for backward compatibility, will be | 1318 | /* XXX: This is for backward compatibility, will be |
1307 | * removed. Read Documentation/feature-removal-schedule.txt | 1319 | * removed. Read Documentation/feature-removal-schedule.txt |
1308 | * for more info. | 1320 | * for more info. |
@@ -1326,8 +1338,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
1326 | scmd->scsi_done = qc->scsidone; | 1338 | scmd->scsi_done = qc->scsidone; |
1327 | qc->scsidone = ata_delayed_done; | 1339 | qc->scsidone = ata_delayed_done; |
1328 | } | 1340 | } |
1329 | scmd->result = SAM_STAT_GOOD; | 1341 | goto skip; |
1330 | return 1; | ||
1331 | } | 1342 | } |
1332 | 1343 | ||
1333 | /* Issue ATA STANDBY IMMEDIATE command */ | 1344 | /* Issue ATA STANDBY IMMEDIATE command */ |
@@ -1343,10 +1354,13 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
1343 | 1354 | ||
1344 | return 0; | 1355 | return 0; |
1345 | 1356 | ||
1346 | invalid_fld: | 1357 | invalid_fld: |
1347 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); | 1358 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); |
1348 | /* "Invalid field in cbd" */ | 1359 | /* "Invalid field in cbd" */ |
1349 | return 1; | 1360 | return 1; |
1361 | skip: | ||
1362 | scmd->result = SAM_STAT_GOOD; | ||
1363 | return 1; | ||
1350 | } | 1364 | } |
1351 | 1365 | ||
1352 | 1366 | ||