ide-park.c revision 4abdc6ee7c47a1a6e12f95717e461baeebee5df7
1#include <linux/kernel.h> 2#include <linux/ide.h> 3#include <linux/jiffies.h> 4#include <linux/blkdev.h> 5 6DECLARE_WAIT_QUEUE_HEAD(ide_park_wq); 7 8static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) 9{ 10 struct request_queue *q = drive->queue; 11 struct request *rq; 12 int rc; 13 14 timeout += jiffies; 15 spin_lock_irq(&ide_lock); 16 if (drive->dev_flags & IDE_DFLAG_PARKED) { 17 ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; 18 int reset_timer; 19 20 reset_timer = time_before(timeout, drive->sleep); 21 drive->sleep = timeout; 22 wake_up_all(&ide_park_wq); 23 if (reset_timer && hwgroup->sleeping && 24 del_timer(&hwgroup->timer)) { 25 hwgroup->sleeping = 0; 26 hwgroup->busy = 0; 27 blk_start_queueing(q); 28 } 29 spin_unlock_irq(&ide_lock); 30 return; 31 } 32 spin_unlock_irq(&ide_lock); 33 34 rq = blk_get_request(q, READ, __GFP_WAIT); 35 rq->cmd[0] = REQ_PARK_HEADS; 36 rq->cmd_len = 1; 37 rq->cmd_type = REQ_TYPE_SPECIAL; 38 rq->special = &timeout; 39 rc = blk_execute_rq(q, NULL, rq, 1); 40 blk_put_request(rq); 41 if (rc) 42 goto out; 43 44 /* 45 * Make sure that *some* command is sent to the drive after the 46 * timeout has expired, so power management will be reenabled. 47 */ 48 rq = blk_get_request(q, READ, GFP_NOWAIT); 49 if (unlikely(!rq)) 50 goto out; 51 52 rq->cmd[0] = REQ_UNPARK_HEADS; 53 rq->cmd_len = 1; 54 rq->cmd_type = REQ_TYPE_SPECIAL; 55 elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 1); 56 57out: 58 return; 59} 60 61ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, 62 char *buf) 63{ 64 ide_drive_t *drive = to_ide_device(dev); 65 unsigned long now; 66 unsigned int msecs; 67 68 if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD) 69 return -EOPNOTSUPP; 70 71 spin_lock_irq(&ide_lock); 72 now = jiffies; 73 if (drive->dev_flags & IDE_DFLAG_PARKED && 74 time_after(drive->sleep, now)) 75 msecs = jiffies_to_msecs(drive->sleep - now); 76 else 77 msecs = 0; 78 spin_unlock_irq(&ide_lock); 79 80 return snprintf(buf, 20, "%u\n", msecs); 81} 82 83ssize_t ide_park_store(struct device *dev, struct device_attribute *attr, 84 const char *buf, size_t len) 85{ 86#define MAX_PARK_TIMEOUT 30000 87 ide_drive_t *drive = to_ide_device(dev); 88 long int input; 89 int rc; 90 91 rc = strict_strtol(buf, 10, &input); 92 if (rc || input < -2) 93 return -EINVAL; 94 if (input > MAX_PARK_TIMEOUT) { 95 input = MAX_PARK_TIMEOUT; 96 rc = -EOVERFLOW; 97 } 98 99 mutex_lock(&ide_setting_mtx); 100 if (input >= 0) { 101 if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD) 102 rc = -EOPNOTSUPP; 103 else if (input || drive->dev_flags & IDE_DFLAG_PARKED) 104 issue_park_cmd(drive, msecs_to_jiffies(input)); 105 } else { 106 if (drive->media == ide_disk) 107 switch (input) { 108 case -1: 109 drive->dev_flags &= ~IDE_DFLAG_NO_UNLOAD; 110 break; 111 case -2: 112 drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; 113 break; 114 } 115 else 116 rc = -EOPNOTSUPP; 117 } 118 mutex_unlock(&ide_setting_mtx); 119 120 return rc ? rc : len; 121} 122