Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
ide
ide-park.c
Go to the documentation of this file.
1
#include <linux/kernel.h>
2
#include <
linux/gfp.h
>
3
#include <
linux/ide.h
>
4
#include <
linux/jiffies.h
>
5
#include <
linux/blkdev.h
>
6
7
DECLARE_WAIT_QUEUE_HEAD
(ide_park_wq);
8
9
static
void
issue_park_cmd(
ide_drive_t
*drive,
unsigned
long
timeout)
10
{
11
ide_hwif_t
*hwif = drive->
hwif
;
12
struct
request_queue
*
q
= drive->
queue
;
13
struct
request
*
rq
;
14
int
rc
;
15
16
timeout +=
jiffies
;
17
spin_lock_irq(&hwif->
lock
);
18
if
(drive->
dev_flags
&
IDE_DFLAG_PARKED
) {
19
int
reset_timer
=
time_before
(timeout, drive->
sleep
);
20
int
start_queue = 0;
21
22
drive->
sleep
= timeout;
23
wake_up_all
(&ide_park_wq);
24
if
(reset_timer &&
del_timer
(&hwif->
timer
))
25
start_queue = 1;
26
spin_unlock_irq(&hwif->
lock
);
27
28
if
(start_queue)
29
blk_run_queue
(q);
30
return
;
31
}
32
spin_unlock_irq(&hwif->
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);
56
57
out
:
58
return
;
59
}
60
61
ide_startstop_t
ide_do_park_unpark
(
ide_drive_t
*drive,
struct
request
*rq)
62
{
63
struct
ide_cmd
cmd;
64
struct
ide_taskfile
*
tf
= &cmd.
tf
;
65
66
memset
(&cmd, 0,
sizeof
(cmd));
67
if
(rq->cmd[0] ==
REQ_PARK_HEADS
) {
68
drive->
sleep
= *(
unsigned
long
*)rq->special;
69
drive->
dev_flags
|=
IDE_DFLAG_SLEEPING
;
70
tf->
command
=
ATA_CMD_IDLEIMMEDIATE
;
71
tf->
feature
= 0x44;
72
tf->
lbal
= 0x4c;
73
tf->
lbam
= 0x4e;
74
tf->
lbah
= 0x55;
75
cmd.
valid
.out.tf =
IDE_VALID_OUT_TF
|
IDE_VALID_DEVICE
;
76
cmd.
valid
.in.tf =
IDE_VALID_IN_TF
|
IDE_VALID_DEVICE
;
77
}
else
/* cmd == REQ_UNPARK_HEADS */
78
tf->
command
=
ATA_CMD_CHK_POWER
;
79
80
cmd.
tf_flags
|=
IDE_TFLAG_CUSTOM_HANDLER
;
81
cmd.
protocol
=
ATA_PROT_NODATA
;
82
83
cmd.
rq
=
rq
;
84
85
return
do_rw_taskfile
(drive, &cmd);
86
}
87
88
ssize_t
ide_park_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
89
char
*
buf
)
90
{
91
ide_drive_t
*drive =
to_ide_device
(dev);
92
ide_hwif_t
*hwif = drive->
hwif
;
93
unsigned
long
now;
94
unsigned
int
msecs;
95
96
if
(drive->
dev_flags
&
IDE_DFLAG_NO_UNLOAD
)
97
return
-
EOPNOTSUPP
;
98
99
spin_lock_irq(&hwif->
lock
);
100
now =
jiffies
;
101
if
(drive->
dev_flags
&
IDE_DFLAG_PARKED
&&
102
time_after
(drive->
sleep
, now))
103
msecs =
jiffies_to_msecs
(drive->
sleep
- now);
104
else
105
msecs = 0;
106
spin_unlock_irq(&hwif->
lock
);
107
108
return
snprintf
(buf, 20,
"%u\n"
, msecs);
109
}
110
111
ssize_t
ide_park_store
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
112
const
char
*
buf
,
size_t
len)
113
{
114
#define MAX_PARK_TIMEOUT 30000
115
ide_drive_t
*drive =
to_ide_device
(dev);
116
long
int
input
;
117
int
rc
;
118
119
rc =
strict_strtol
(buf, 10, &input);
120
if
(rc || input < -2)
121
return
-
EINVAL
;
122
if
(input >
MAX_PARK_TIMEOUT
) {
123
input =
MAX_PARK_TIMEOUT
;
124
rc = -
EOVERFLOW
;
125
}
126
127
mutex_lock
(&
ide_setting_mtx
);
128
if
(input >= 0) {
129
if
(drive->
dev_flags
&
IDE_DFLAG_NO_UNLOAD
)
130
rc = -
EOPNOTSUPP
;
131
else
if
(input || drive->
dev_flags
&
IDE_DFLAG_PARKED
)
132
issue_park_cmd(drive,
msecs_to_jiffies
(input));
133
}
else
{
134
if
(drive->
media
==
ide_disk
)
135
switch
(input) {
136
case
-1:
137
drive->
dev_flags
&= ~
IDE_DFLAG_NO_UNLOAD
;
138
break
;
139
case
-2:
140
drive->
dev_flags
|=
IDE_DFLAG_NO_UNLOAD
;
141
break
;
142
}
143
else
144
rc = -
EOPNOTSUPP
;
145
}
146
mutex_unlock
(&
ide_setting_mtx
);
147
148
return
rc ? rc : len;
149
}
Generated on Thu Jan 10 2013 13:36:14 for Linux Kernel by
1.8.2