aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorElias Oltmanns <eo@nebensachen.de>2008-10-13 15:39:50 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-13 15:39:50 -0400
commit4abdc6ee7c47a1a6e12f95717e461baeebee5df7 (patch)
tree51cac3d66891d026483838563e35124467a8eb86 /include
parent08243ba731ee08ff42cf1589379c81567690218f (diff)
ide: Implement disk shock protection support (v4)
On user request (through sysfs), the IDLE IMMEDIATE command with UNLOAD FEATURE as specified in ATA-7 is issued to the device and processing of the request queue is stopped thereafter until the specified timeout expires or user space asks to resume normal operation. This is supposed to prevent the heads of a hard drive from accidentally crashing onto the platter when a heavy shock is anticipated (like a falling laptop expected to hit the floor). Port resets are deferred whenever a device on that port is in the parked state. v3: Elias Oltmanns <eo@nebensachen.de> wrote: [...] > >> 1. Make sure that no negative value is being passed to > >> jiffies_to_msecs() in ide_park_show(). > >> 2. Drop the superfluous variable hwif in ide_special_rq(). > >> 3. Skip initialisation of task and tf in ide_special_rq() if we are not > >> handling a (un)park request. > > > > Well, #3 should have been done differently because we donn't want to > > check for REQ_(UN)?PARK_HEADS more often than is necessary. > > While preparing the backport to 2.6.27, it has just occurred to me that > we need to clear the IDE_DFLAG_PARKED flag in ide_disk_pre_reset() > because this flag must not be set after *any* sort of access to the > device. v4: Fix a memory leak due to a missing blk_put_request() in issue_park_cmd(). Additionally, we should plug the queue when enqueueing the unpark request because there is no guarantee that the park timeout has not expired by then. Even though the chance for that to happen is very slim, the request might end up hanging in the queue until the next I/O operation is queued up. While at it, clean up the code a little: - make issue_park_cmd() a function of type void since nobody cares for the return value anyway; - use blk_start_queueing() instead of __blk_run_queue() since we don't have to worry about recursion; - remove a superfluous pointer deference in task_no_data_intr(). Signed-off-by: Elias Oltmanns <eo@nebensachen.de> Cc: Jeff Garzik <jeff@garzik.org>, Cc: Randy Dunlap <randy.dunlap@oracle.com> Cc: Tejun Heo <htejun@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/ide.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 8247b286838d..c47e371554c1 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -156,6 +156,8 @@ enum {
156 */ 156 */
157#define REQ_DRIVE_RESET 0x20 157#define REQ_DRIVE_RESET 0x20
158#define REQ_DEVSET_EXEC 0x21 158#define REQ_DEVSET_EXEC 0x21
159#define REQ_PARK_HEADS 0x22
160#define REQ_UNPARK_HEADS 0x23
159 161
160/* 162/*
161 * Check for an interrupt and acknowledge the interrupt status 163 * Check for an interrupt and acknowledge the interrupt status
@@ -573,6 +575,10 @@ enum {
573 /* retrying in PIO */ 575 /* retrying in PIO */
574 IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), 576 IDE_DFLAG_DMA_PIO_RETRY = (1 << 25),
575 IDE_DFLAG_LBA = (1 << 26), 577 IDE_DFLAG_LBA = (1 << 26),
578 /* don't unload heads */
579 IDE_DFLAG_NO_UNLOAD = (1 << 27),
580 /* heads unloaded, please don't reset port */
581 IDE_DFLAG_PARKED = (1 << 28)
576}; 582};
577 583
578struct ide_drive_s { 584struct ide_drive_s {
@@ -1207,6 +1213,13 @@ int ide_check_atapi_device(ide_drive_t *, const char *);
1207 1213
1208void ide_init_pc(struct ide_atapi_pc *); 1214void ide_init_pc(struct ide_atapi_pc *);
1209 1215
1216/* Disk head parking */
1217extern wait_queue_head_t ide_park_wq;
1218ssize_t ide_park_show(struct device *dev, struct device_attribute *attr,
1219 char *buf);
1220ssize_t ide_park_store(struct device *dev, struct device_attribute *attr,
1221 const char *buf, size_t len);
1222
1210/* 1223/*
1211 * Special requests for ide-tape block device strategy routine. 1224 * Special requests for ide-tape block device strategy routine.
1212 * 1225 *