aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/feature-removal-schedule.txt19
-rw-r--r--drivers/ata/libata-core.c6
-rw-r--r--drivers/ata/libata-scsi.c28
-rw-r--r--drivers/ata/libata.h1
4 files changed, 53 insertions, 1 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index c6322c76034..498ff31f3aa 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -328,3 +328,22 @@ Who: Adrian Bunk <bunk@stusta.de>
---------------------------
+What: libata.spindown_compat module parameter
+When: Dec 2008
+Why: halt(8) synchronizes caches for and spins down libata disks
+ because libata didn't use to spin down disk on system halt
+ (only synchronized caches).
+ Spin down on system halt is now implemented and can be tested
+ using sysfs node /sys/class/scsi_disk/h:c:i:l/manage_start_stop.
+ Because issuing spin down command to an already spun down disk
+ makes some disks spin up just to spin down again, the old
+ behavior needs to be maintained till userspace tool is updated
+ to check the sysfs node and not to spin down disks with the
+ node set to one.
+ This module parameter is to give userspace tool the time to
+ get updated and should be removed after userspace is
+ reasonably updated.
+Who: Tejun Heo <htejun@gmail.com>
+
+---------------------------
+
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 2e2a2fa8e9e..bf8f65b0959 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -101,6 +101,12 @@ int libata_noacpi = 1;
module_param_named(noacpi, libata_noacpi, int, 0444);
MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
+int ata_spindown_compat = 1;
+module_param_named(spindown_compat, ata_spindown_compat, int, 0644);
+MODULE_PARM_DESC(spindown_compat, "Enable backward compatible spindown "
+ "behavior. Will be removed. More info can be found in "
+ "Documentation/feature-removal-schedule.txt\n");
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Library module for ATA devices");
MODULE_LICENSE("GPL");
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 8f800196d59..dd81fa78cdc 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -944,9 +944,35 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
}
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
- } else
+ } else {
+ /* XXX: This is for backward compatibility, will be
+ * removed. Read Documentation/feature-removal-schedule.txt
+ * for more info.
+ */
+ if (ata_spindown_compat &&
+ (system_state == SYSTEM_HALT ||
+ system_state == SYSTEM_POWER_OFF)) {
+ static int warned = 0;
+
+ if (!warned) {
+ spin_unlock_irq(qc->ap->lock);
+ ata_dev_printk(qc->dev, KERN_WARNING,
+ "DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
+ "UPDATE SHUTDOWN UTILITY\n");
+ ata_dev_printk(qc->dev, KERN_WARNING,
+ "For more info, visit "
+ "http://linux-ata.org/shutdown.html\n");
+ warned = 1;
+ ssleep(5);
+ spin_lock_irq(qc->ap->lock);
+ }
+ scmd->result = SAM_STAT_GOOD;
+ return 1;
+ }
+
/* Issue ATA STANDBY IMMEDIATE command */
tf->command = ATA_CMD_STANDBYNOW1;
+ }
/*
* Standby and Idle condition timers could be implemented but that
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 5f4d40cd328..316bf8ae453 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -58,6 +58,7 @@ extern int atapi_enabled;
extern int atapi_dmadir;
extern int libata_fua;
extern int libata_noacpi;
+extern int ata_spindown_compat;
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,