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