aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-01-19 14:56:43 -0500
committerJeff Garzik <jgarzik@redhat.com>2009-01-27 02:15:49 -0500
commit2a6e58d2731dcc05dafa7f976d935e0f0627fcd7 (patch)
tree836d0ec85dccde709aeaaedb3b7686ac51805ad1 /drivers/ata
parentd7b1956fed33d30c4815e848fd7a143722916868 (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.c20
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
1346invalid_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