Commit 34b7d2c957199834c474c9d46739265643f4d9c7
Committed by
Jens Axboe
1 parent
b079041030
Exists in
master
and in
7 other branches
ide: cleanup rq->data_len usages
With recent unification of fields, it's now guaranteed that rq->data_len always equals blk_rq_bytes(). Convert all direct users to accessors. [ Impact: convert direct rq->data_len usages to blk_rq_bytes() ] Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Cc: Borislav Petkov <petkovbb@googlemail.com> Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Showing 5 changed files with 13 additions and 24 deletions Inline Diff
drivers/ide/ide-atapi.c
1 | /* | 1 | /* |
2 | * ATAPI support. | 2 | * ATAPI support. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/cdrom.h> | 6 | #include <linux/cdrom.h> |
7 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
8 | #include <linux/ide.h> | 8 | #include <linux/ide.h> |
9 | #include <linux/scatterlist.h> | 9 | #include <linux/scatterlist.h> |
10 | 10 | ||
11 | #include <scsi/scsi.h> | 11 | #include <scsi/scsi.h> |
12 | 12 | ||
13 | #ifdef DEBUG | 13 | #ifdef DEBUG |
14 | #define debug_log(fmt, args...) \ | 14 | #define debug_log(fmt, args...) \ |
15 | printk(KERN_INFO "ide: " fmt, ## args) | 15 | printk(KERN_INFO "ide: " fmt, ## args) |
16 | #else | 16 | #else |
17 | #define debug_log(fmt, args...) do {} while (0) | 17 | #define debug_log(fmt, args...) do {} while (0) |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | #define ATAPI_MIN_CDB_BYTES 12 | 20 | #define ATAPI_MIN_CDB_BYTES 12 |
21 | 21 | ||
22 | static inline int dev_is_idecd(ide_drive_t *drive) | 22 | static inline int dev_is_idecd(ide_drive_t *drive) |
23 | { | 23 | { |
24 | return drive->media == ide_cdrom || drive->media == ide_optical; | 24 | return drive->media == ide_cdrom || drive->media == ide_optical; |
25 | } | 25 | } |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * Check whether we can support a device, | 28 | * Check whether we can support a device, |
29 | * based on the ATAPI IDENTIFY command results. | 29 | * based on the ATAPI IDENTIFY command results. |
30 | */ | 30 | */ |
31 | int ide_check_atapi_device(ide_drive_t *drive, const char *s) | 31 | int ide_check_atapi_device(ide_drive_t *drive, const char *s) |
32 | { | 32 | { |
33 | u16 *id = drive->id; | 33 | u16 *id = drive->id; |
34 | u8 gcw[2], protocol, device_type, removable, drq_type, packet_size; | 34 | u8 gcw[2], protocol, device_type, removable, drq_type, packet_size; |
35 | 35 | ||
36 | *((u16 *)&gcw) = id[ATA_ID_CONFIG]; | 36 | *((u16 *)&gcw) = id[ATA_ID_CONFIG]; |
37 | 37 | ||
38 | protocol = (gcw[1] & 0xC0) >> 6; | 38 | protocol = (gcw[1] & 0xC0) >> 6; |
39 | device_type = gcw[1] & 0x1F; | 39 | device_type = gcw[1] & 0x1F; |
40 | removable = (gcw[0] & 0x80) >> 7; | 40 | removable = (gcw[0] & 0x80) >> 7; |
41 | drq_type = (gcw[0] & 0x60) >> 5; | 41 | drq_type = (gcw[0] & 0x60) >> 5; |
42 | packet_size = gcw[0] & 0x03; | 42 | packet_size = gcw[0] & 0x03; |
43 | 43 | ||
44 | #ifdef CONFIG_PPC | 44 | #ifdef CONFIG_PPC |
45 | /* kludge for Apple PowerBook internal zip */ | 45 | /* kludge for Apple PowerBook internal zip */ |
46 | if (drive->media == ide_floppy && device_type == 5 && | 46 | if (drive->media == ide_floppy && device_type == 5 && |
47 | !strstr((char *)&id[ATA_ID_PROD], "CD-ROM") && | 47 | !strstr((char *)&id[ATA_ID_PROD], "CD-ROM") && |
48 | strstr((char *)&id[ATA_ID_PROD], "ZIP")) | 48 | strstr((char *)&id[ATA_ID_PROD], "ZIP")) |
49 | device_type = 0; | 49 | device_type = 0; |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | if (protocol != 2) | 52 | if (protocol != 2) |
53 | printk(KERN_ERR "%s: %s: protocol (0x%02x) is not ATAPI\n", | 53 | printk(KERN_ERR "%s: %s: protocol (0x%02x) is not ATAPI\n", |
54 | s, drive->name, protocol); | 54 | s, drive->name, protocol); |
55 | else if ((drive->media == ide_floppy && device_type != 0) || | 55 | else if ((drive->media == ide_floppy && device_type != 0) || |
56 | (drive->media == ide_tape && device_type != 1)) | 56 | (drive->media == ide_tape && device_type != 1)) |
57 | printk(KERN_ERR "%s: %s: invalid device type (0x%02x)\n", | 57 | printk(KERN_ERR "%s: %s: invalid device type (0x%02x)\n", |
58 | s, drive->name, device_type); | 58 | s, drive->name, device_type); |
59 | else if (removable == 0) | 59 | else if (removable == 0) |
60 | printk(KERN_ERR "%s: %s: the removable flag is not set\n", | 60 | printk(KERN_ERR "%s: %s: the removable flag is not set\n", |
61 | s, drive->name); | 61 | s, drive->name); |
62 | else if (drive->media == ide_floppy && drq_type == 3) | 62 | else if (drive->media == ide_floppy && drq_type == 3) |
63 | printk(KERN_ERR "%s: %s: sorry, DRQ type (0x%02x) not " | 63 | printk(KERN_ERR "%s: %s: sorry, DRQ type (0x%02x) not " |
64 | "supported\n", s, drive->name, drq_type); | 64 | "supported\n", s, drive->name, drq_type); |
65 | else if (packet_size != 0) | 65 | else if (packet_size != 0) |
66 | printk(KERN_ERR "%s: %s: packet size (0x%02x) is not 12 " | 66 | printk(KERN_ERR "%s: %s: packet size (0x%02x) is not 12 " |
67 | "bytes\n", s, drive->name, packet_size); | 67 | "bytes\n", s, drive->name, packet_size); |
68 | else | 68 | else |
69 | return 1; | 69 | return 1; |
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
72 | EXPORT_SYMBOL_GPL(ide_check_atapi_device); | 72 | EXPORT_SYMBOL_GPL(ide_check_atapi_device); |
73 | 73 | ||
74 | void ide_init_pc(struct ide_atapi_pc *pc) | 74 | void ide_init_pc(struct ide_atapi_pc *pc) |
75 | { | 75 | { |
76 | memset(pc, 0, sizeof(*pc)); | 76 | memset(pc, 0, sizeof(*pc)); |
77 | pc->buf = pc->pc_buf; | 77 | pc->buf = pc->pc_buf; |
78 | pc->buf_size = IDE_PC_BUFFER_SIZE; | 78 | pc->buf_size = IDE_PC_BUFFER_SIZE; |
79 | } | 79 | } |
80 | EXPORT_SYMBOL_GPL(ide_init_pc); | 80 | EXPORT_SYMBOL_GPL(ide_init_pc); |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * Add a special packet command request to the tail of the request queue, | 83 | * Add a special packet command request to the tail of the request queue, |
84 | * and wait for it to be serviced. | 84 | * and wait for it to be serviced. |
85 | */ | 85 | */ |
86 | int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, | 86 | int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, |
87 | struct ide_atapi_pc *pc) | 87 | struct ide_atapi_pc *pc) |
88 | { | 88 | { |
89 | struct request *rq; | 89 | struct request *rq; |
90 | int error; | 90 | int error; |
91 | 91 | ||
92 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 92 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
93 | rq->cmd_type = REQ_TYPE_SPECIAL; | 93 | rq->cmd_type = REQ_TYPE_SPECIAL; |
94 | rq->special = (char *)pc; | 94 | rq->special = (char *)pc; |
95 | 95 | ||
96 | if (pc->req_xfer) { | 96 | if (pc->req_xfer) { |
97 | error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer, | 97 | error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer, |
98 | GFP_NOIO); | 98 | GFP_NOIO); |
99 | if (error) | 99 | if (error) |
100 | goto put_req; | 100 | goto put_req; |
101 | } | 101 | } |
102 | 102 | ||
103 | memcpy(rq->cmd, pc->c, 12); | 103 | memcpy(rq->cmd, pc->c, 12); |
104 | if (drive->media == ide_tape) | 104 | if (drive->media == ide_tape) |
105 | rq->cmd[13] = REQ_IDETAPE_PC1; | 105 | rq->cmd[13] = REQ_IDETAPE_PC1; |
106 | error = blk_execute_rq(drive->queue, disk, rq, 0); | 106 | error = blk_execute_rq(drive->queue, disk, rq, 0); |
107 | put_req: | 107 | put_req: |
108 | blk_put_request(rq); | 108 | blk_put_request(rq); |
109 | return error; | 109 | return error; |
110 | } | 110 | } |
111 | EXPORT_SYMBOL_GPL(ide_queue_pc_tail); | 111 | EXPORT_SYMBOL_GPL(ide_queue_pc_tail); |
112 | 112 | ||
113 | int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk) | 113 | int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk) |
114 | { | 114 | { |
115 | struct ide_atapi_pc pc; | 115 | struct ide_atapi_pc pc; |
116 | 116 | ||
117 | ide_init_pc(&pc); | 117 | ide_init_pc(&pc); |
118 | pc.c[0] = TEST_UNIT_READY; | 118 | pc.c[0] = TEST_UNIT_READY; |
119 | 119 | ||
120 | return ide_queue_pc_tail(drive, disk, &pc); | 120 | return ide_queue_pc_tail(drive, disk, &pc); |
121 | } | 121 | } |
122 | EXPORT_SYMBOL_GPL(ide_do_test_unit_ready); | 122 | EXPORT_SYMBOL_GPL(ide_do_test_unit_ready); |
123 | 123 | ||
124 | int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start) | 124 | int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start) |
125 | { | 125 | { |
126 | struct ide_atapi_pc pc; | 126 | struct ide_atapi_pc pc; |
127 | 127 | ||
128 | ide_init_pc(&pc); | 128 | ide_init_pc(&pc); |
129 | pc.c[0] = START_STOP; | 129 | pc.c[0] = START_STOP; |
130 | pc.c[4] = start; | 130 | pc.c[4] = start; |
131 | 131 | ||
132 | if (drive->media == ide_tape) | 132 | if (drive->media == ide_tape) |
133 | pc.flags |= PC_FLAG_WAIT_FOR_DSC; | 133 | pc.flags |= PC_FLAG_WAIT_FOR_DSC; |
134 | 134 | ||
135 | return ide_queue_pc_tail(drive, disk, &pc); | 135 | return ide_queue_pc_tail(drive, disk, &pc); |
136 | } | 136 | } |
137 | EXPORT_SYMBOL_GPL(ide_do_start_stop); | 137 | EXPORT_SYMBOL_GPL(ide_do_start_stop); |
138 | 138 | ||
139 | int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) | 139 | int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) |
140 | { | 140 | { |
141 | struct ide_atapi_pc pc; | 141 | struct ide_atapi_pc pc; |
142 | 142 | ||
143 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) | 143 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) |
144 | return 0; | 144 | return 0; |
145 | 145 | ||
146 | ide_init_pc(&pc); | 146 | ide_init_pc(&pc); |
147 | pc.c[0] = ALLOW_MEDIUM_REMOVAL; | 147 | pc.c[0] = ALLOW_MEDIUM_REMOVAL; |
148 | pc.c[4] = on; | 148 | pc.c[4] = on; |
149 | 149 | ||
150 | return ide_queue_pc_tail(drive, disk, &pc); | 150 | return ide_queue_pc_tail(drive, disk, &pc); |
151 | } | 151 | } |
152 | EXPORT_SYMBOL_GPL(ide_set_media_lock); | 152 | EXPORT_SYMBOL_GPL(ide_set_media_lock); |
153 | 153 | ||
154 | void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc) | 154 | void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc) |
155 | { | 155 | { |
156 | ide_init_pc(pc); | 156 | ide_init_pc(pc); |
157 | pc->c[0] = REQUEST_SENSE; | 157 | pc->c[0] = REQUEST_SENSE; |
158 | if (drive->media == ide_floppy) { | 158 | if (drive->media == ide_floppy) { |
159 | pc->c[4] = 255; | 159 | pc->c[4] = 255; |
160 | pc->req_xfer = 18; | 160 | pc->req_xfer = 18; |
161 | } else { | 161 | } else { |
162 | pc->c[4] = 20; | 162 | pc->c[4] = 20; |
163 | pc->req_xfer = 20; | 163 | pc->req_xfer = 20; |
164 | } | 164 | } |
165 | } | 165 | } |
166 | EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd); | 166 | EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd); |
167 | 167 | ||
168 | void ide_prep_sense(ide_drive_t *drive, struct request *rq) | 168 | void ide_prep_sense(ide_drive_t *drive, struct request *rq) |
169 | { | 169 | { |
170 | struct request_sense *sense = &drive->sense_data; | 170 | struct request_sense *sense = &drive->sense_data; |
171 | struct request *sense_rq = &drive->sense_rq; | 171 | struct request *sense_rq = &drive->sense_rq; |
172 | unsigned int cmd_len, sense_len; | 172 | unsigned int cmd_len, sense_len; |
173 | int err; | 173 | int err; |
174 | 174 | ||
175 | debug_log("%s: enter\n", __func__); | 175 | debug_log("%s: enter\n", __func__); |
176 | 176 | ||
177 | switch (drive->media) { | 177 | switch (drive->media) { |
178 | case ide_floppy: | 178 | case ide_floppy: |
179 | cmd_len = 255; | 179 | cmd_len = 255; |
180 | sense_len = 18; | 180 | sense_len = 18; |
181 | break; | 181 | break; |
182 | case ide_tape: | 182 | case ide_tape: |
183 | cmd_len = 20; | 183 | cmd_len = 20; |
184 | sense_len = 20; | 184 | sense_len = 20; |
185 | break; | 185 | break; |
186 | default: | 186 | default: |
187 | cmd_len = 18; | 187 | cmd_len = 18; |
188 | sense_len = 18; | 188 | sense_len = 18; |
189 | } | 189 | } |
190 | 190 | ||
191 | BUG_ON(sense_len > sizeof(*sense)); | 191 | BUG_ON(sense_len > sizeof(*sense)); |
192 | 192 | ||
193 | if (blk_sense_request(rq) || drive->sense_rq_armed) | 193 | if (blk_sense_request(rq) || drive->sense_rq_armed) |
194 | return; | 194 | return; |
195 | 195 | ||
196 | memset(sense, 0, sizeof(*sense)); | 196 | memset(sense, 0, sizeof(*sense)); |
197 | 197 | ||
198 | blk_rq_init(rq->q, sense_rq); | 198 | blk_rq_init(rq->q, sense_rq); |
199 | 199 | ||
200 | err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len, | 200 | err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len, |
201 | GFP_NOIO); | 201 | GFP_NOIO); |
202 | if (unlikely(err)) { | 202 | if (unlikely(err)) { |
203 | if (printk_ratelimit()) | 203 | if (printk_ratelimit()) |
204 | printk(KERN_WARNING "%s: failed to map sense buffer\n", | 204 | printk(KERN_WARNING "%s: failed to map sense buffer\n", |
205 | drive->name); | 205 | drive->name); |
206 | return; | 206 | return; |
207 | } | 207 | } |
208 | 208 | ||
209 | sense_rq->rq_disk = rq->rq_disk; | 209 | sense_rq->rq_disk = rq->rq_disk; |
210 | sense_rq->cmd[0] = GPCMD_REQUEST_SENSE; | 210 | sense_rq->cmd[0] = GPCMD_REQUEST_SENSE; |
211 | sense_rq->cmd[4] = cmd_len; | 211 | sense_rq->cmd[4] = cmd_len; |
212 | sense_rq->cmd_type = REQ_TYPE_SENSE; | 212 | sense_rq->cmd_type = REQ_TYPE_SENSE; |
213 | sense_rq->cmd_flags |= REQ_PREEMPT; | 213 | sense_rq->cmd_flags |= REQ_PREEMPT; |
214 | 214 | ||
215 | if (drive->media == ide_tape) | 215 | if (drive->media == ide_tape) |
216 | sense_rq->cmd[13] = REQ_IDETAPE_PC1; | 216 | sense_rq->cmd[13] = REQ_IDETAPE_PC1; |
217 | 217 | ||
218 | drive->sense_rq_armed = true; | 218 | drive->sense_rq_armed = true; |
219 | } | 219 | } |
220 | EXPORT_SYMBOL_GPL(ide_prep_sense); | 220 | EXPORT_SYMBOL_GPL(ide_prep_sense); |
221 | 221 | ||
222 | int ide_queue_sense_rq(ide_drive_t *drive, void *special) | 222 | int ide_queue_sense_rq(ide_drive_t *drive, void *special) |
223 | { | 223 | { |
224 | /* deferred failure from ide_prep_sense() */ | 224 | /* deferred failure from ide_prep_sense() */ |
225 | if (!drive->sense_rq_armed) { | 225 | if (!drive->sense_rq_armed) { |
226 | printk(KERN_WARNING "%s: failed queue sense request\n", | 226 | printk(KERN_WARNING "%s: failed queue sense request\n", |
227 | drive->name); | 227 | drive->name); |
228 | return -ENOMEM; | 228 | return -ENOMEM; |
229 | } | 229 | } |
230 | 230 | ||
231 | drive->sense_rq.special = special; | 231 | drive->sense_rq.special = special; |
232 | drive->sense_rq_armed = false; | 232 | drive->sense_rq_armed = false; |
233 | 233 | ||
234 | drive->hwif->rq = NULL; | 234 | drive->hwif->rq = NULL; |
235 | 235 | ||
236 | elv_add_request(drive->queue, &drive->sense_rq, | 236 | elv_add_request(drive->queue, &drive->sense_rq, |
237 | ELEVATOR_INSERT_FRONT, 0); | 237 | ELEVATOR_INSERT_FRONT, 0); |
238 | return 0; | 238 | return 0; |
239 | } | 239 | } |
240 | EXPORT_SYMBOL_GPL(ide_queue_sense_rq); | 240 | EXPORT_SYMBOL_GPL(ide_queue_sense_rq); |
241 | 241 | ||
242 | /* | 242 | /* |
243 | * Called when an error was detected during the last packet command. | 243 | * Called when an error was detected during the last packet command. |
244 | * We queue a request sense packet command at the head of the request | 244 | * We queue a request sense packet command at the head of the request |
245 | * queue. | 245 | * queue. |
246 | */ | 246 | */ |
247 | void ide_retry_pc(ide_drive_t *drive) | 247 | void ide_retry_pc(ide_drive_t *drive) |
248 | { | 248 | { |
249 | struct request *sense_rq = &drive->sense_rq; | 249 | struct request *sense_rq = &drive->sense_rq; |
250 | struct ide_atapi_pc *pc = &drive->request_sense_pc; | 250 | struct ide_atapi_pc *pc = &drive->request_sense_pc; |
251 | 251 | ||
252 | (void)ide_read_error(drive); | 252 | (void)ide_read_error(drive); |
253 | 253 | ||
254 | /* init pc from sense_rq */ | 254 | /* init pc from sense_rq */ |
255 | ide_init_pc(pc); | 255 | ide_init_pc(pc); |
256 | memcpy(pc->c, sense_rq->cmd, 12); | 256 | memcpy(pc->c, sense_rq->cmd, 12); |
257 | pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */ | 257 | pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */ |
258 | pc->req_xfer = sense_rq->data_len; | 258 | pc->req_xfer = blk_rq_bytes(sense_rq); |
259 | 259 | ||
260 | if (drive->media == ide_tape) | 260 | if (drive->media == ide_tape) |
261 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); | 261 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); |
262 | 262 | ||
263 | if (ide_queue_sense_rq(drive, pc)) | 263 | if (ide_queue_sense_rq(drive, pc)) |
264 | ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); | 264 | ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); |
265 | } | 265 | } |
266 | EXPORT_SYMBOL_GPL(ide_retry_pc); | 266 | EXPORT_SYMBOL_GPL(ide_retry_pc); |
267 | 267 | ||
268 | int ide_cd_expiry(ide_drive_t *drive) | 268 | int ide_cd_expiry(ide_drive_t *drive) |
269 | { | 269 | { |
270 | struct request *rq = drive->hwif->rq; | 270 | struct request *rq = drive->hwif->rq; |
271 | unsigned long wait = 0; | 271 | unsigned long wait = 0; |
272 | 272 | ||
273 | debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]); | 273 | debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]); |
274 | 274 | ||
275 | /* | 275 | /* |
276 | * Some commands are *slow* and normally take a long time to complete. | 276 | * Some commands are *slow* and normally take a long time to complete. |
277 | * Usually we can use the ATAPI "disconnect" to bypass this, but not all | 277 | * Usually we can use the ATAPI "disconnect" to bypass this, but not all |
278 | * commands/drives support that. Let ide_timer_expiry keep polling us | 278 | * commands/drives support that. Let ide_timer_expiry keep polling us |
279 | * for these. | 279 | * for these. |
280 | */ | 280 | */ |
281 | switch (rq->cmd[0]) { | 281 | switch (rq->cmd[0]) { |
282 | case GPCMD_BLANK: | 282 | case GPCMD_BLANK: |
283 | case GPCMD_FORMAT_UNIT: | 283 | case GPCMD_FORMAT_UNIT: |
284 | case GPCMD_RESERVE_RZONE_TRACK: | 284 | case GPCMD_RESERVE_RZONE_TRACK: |
285 | case GPCMD_CLOSE_TRACK: | 285 | case GPCMD_CLOSE_TRACK: |
286 | case GPCMD_FLUSH_CACHE: | 286 | case GPCMD_FLUSH_CACHE: |
287 | wait = ATAPI_WAIT_PC; | 287 | wait = ATAPI_WAIT_PC; |
288 | break; | 288 | break; |
289 | default: | 289 | default: |
290 | if (!(rq->cmd_flags & REQ_QUIET)) | 290 | if (!(rq->cmd_flags & REQ_QUIET)) |
291 | printk(KERN_INFO "cmd 0x%x timed out\n", | 291 | printk(KERN_INFO "cmd 0x%x timed out\n", |
292 | rq->cmd[0]); | 292 | rq->cmd[0]); |
293 | wait = 0; | 293 | wait = 0; |
294 | break; | 294 | break; |
295 | } | 295 | } |
296 | return wait; | 296 | return wait; |
297 | } | 297 | } |
298 | EXPORT_SYMBOL_GPL(ide_cd_expiry); | 298 | EXPORT_SYMBOL_GPL(ide_cd_expiry); |
299 | 299 | ||
300 | int ide_cd_get_xferlen(struct request *rq) | 300 | int ide_cd_get_xferlen(struct request *rq) |
301 | { | 301 | { |
302 | if (blk_fs_request(rq)) | 302 | if (blk_fs_request(rq)) |
303 | return 32768; | 303 | return 32768; |
304 | else if (blk_sense_request(rq) || blk_pc_request(rq) || | 304 | else if (blk_sense_request(rq) || blk_pc_request(rq) || |
305 | rq->cmd_type == REQ_TYPE_ATA_PC) | 305 | rq->cmd_type == REQ_TYPE_ATA_PC) |
306 | return rq->data_len; | 306 | return blk_rq_bytes(rq); |
307 | else | 307 | else |
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); | 310 | EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); |
311 | 311 | ||
312 | void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) | 312 | void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) |
313 | { | 313 | { |
314 | struct ide_taskfile tf; | 314 | struct ide_taskfile tf; |
315 | 315 | ||
316 | drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT | | 316 | drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT | |
317 | IDE_VALID_LBAM | IDE_VALID_LBAH); | 317 | IDE_VALID_LBAM | IDE_VALID_LBAH); |
318 | 318 | ||
319 | *bcount = (tf.lbah << 8) | tf.lbam; | 319 | *bcount = (tf.lbah << 8) | tf.lbam; |
320 | *ireason = tf.nsect & 3; | 320 | *ireason = tf.nsect & 3; |
321 | } | 321 | } |
322 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); | 322 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); |
323 | 323 | ||
324 | /* | 324 | /* |
325 | * This is the usual interrupt handler which will be called during a packet | 325 | * This is the usual interrupt handler which will be called during a packet |
326 | * command. We will transfer some of the data (as requested by the drive) | 326 | * command. We will transfer some of the data (as requested by the drive) |
327 | * and will re-point interrupt handler to us. | 327 | * and will re-point interrupt handler to us. |
328 | */ | 328 | */ |
329 | static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | 329 | static ide_startstop_t ide_pc_intr(ide_drive_t *drive) |
330 | { | 330 | { |
331 | struct ide_atapi_pc *pc = drive->pc; | 331 | struct ide_atapi_pc *pc = drive->pc; |
332 | ide_hwif_t *hwif = drive->hwif; | 332 | ide_hwif_t *hwif = drive->hwif; |
333 | struct ide_cmd *cmd = &hwif->cmd; | 333 | struct ide_cmd *cmd = &hwif->cmd; |
334 | struct request *rq = hwif->rq; | 334 | struct request *rq = hwif->rq; |
335 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 335 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
336 | unsigned int timeout, done; | 336 | unsigned int timeout, done; |
337 | u16 bcount; | 337 | u16 bcount; |
338 | u8 stat, ireason, dsc = 0; | 338 | u8 stat, ireason, dsc = 0; |
339 | u8 write = !!(pc->flags & PC_FLAG_WRITING); | 339 | u8 write = !!(pc->flags & PC_FLAG_WRITING); |
340 | 340 | ||
341 | debug_log("Enter %s - interrupt handler\n", __func__); | 341 | debug_log("Enter %s - interrupt handler\n", __func__); |
342 | 342 | ||
343 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD | 343 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD |
344 | : WAIT_TAPE_CMD; | 344 | : WAIT_TAPE_CMD; |
345 | 345 | ||
346 | /* Clear the interrupt */ | 346 | /* Clear the interrupt */ |
347 | stat = tp_ops->read_status(hwif); | 347 | stat = tp_ops->read_status(hwif); |
348 | 348 | ||
349 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { | 349 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { |
350 | int rc; | 350 | int rc; |
351 | 351 | ||
352 | drive->waiting_for_dma = 0; | 352 | drive->waiting_for_dma = 0; |
353 | rc = hwif->dma_ops->dma_end(drive); | 353 | rc = hwif->dma_ops->dma_end(drive); |
354 | ide_dma_unmap_sg(drive, cmd); | 354 | ide_dma_unmap_sg(drive, cmd); |
355 | 355 | ||
356 | if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { | 356 | if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { |
357 | if (drive->media == ide_floppy) | 357 | if (drive->media == ide_floppy) |
358 | printk(KERN_ERR "%s: DMA %s error\n", | 358 | printk(KERN_ERR "%s: DMA %s error\n", |
359 | drive->name, rq_data_dir(pc->rq) | 359 | drive->name, rq_data_dir(pc->rq) |
360 | ? "write" : "read"); | 360 | ? "write" : "read"); |
361 | pc->flags |= PC_FLAG_DMA_ERROR; | 361 | pc->flags |= PC_FLAG_DMA_ERROR; |
362 | } else | 362 | } else |
363 | pc->xferred = pc->req_xfer; | 363 | pc->xferred = pc->req_xfer; |
364 | debug_log("%s: DMA finished\n", drive->name); | 364 | debug_log("%s: DMA finished\n", drive->name); |
365 | } | 365 | } |
366 | 366 | ||
367 | /* No more interrupts */ | 367 | /* No more interrupts */ |
368 | if ((stat & ATA_DRQ) == 0) { | 368 | if ((stat & ATA_DRQ) == 0) { |
369 | int uptodate, error; | 369 | int uptodate, error; |
370 | 370 | ||
371 | debug_log("Packet command completed, %d bytes transferred\n", | 371 | debug_log("Packet command completed, %d bytes transferred\n", |
372 | pc->xferred); | 372 | pc->xferred); |
373 | 373 | ||
374 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; | 374 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; |
375 | 375 | ||
376 | local_irq_enable_in_hardirq(); | 376 | local_irq_enable_in_hardirq(); |
377 | 377 | ||
378 | if (drive->media == ide_tape && | 378 | if (drive->media == ide_tape && |
379 | (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) | 379 | (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) |
380 | stat &= ~ATA_ERR; | 380 | stat &= ~ATA_ERR; |
381 | 381 | ||
382 | if ((stat & ATA_ERR) || (pc->flags & PC_FLAG_DMA_ERROR)) { | 382 | if ((stat & ATA_ERR) || (pc->flags & PC_FLAG_DMA_ERROR)) { |
383 | /* Error detected */ | 383 | /* Error detected */ |
384 | debug_log("%s: I/O error\n", drive->name); | 384 | debug_log("%s: I/O error\n", drive->name); |
385 | 385 | ||
386 | if (drive->media != ide_tape) | 386 | if (drive->media != ide_tape) |
387 | pc->rq->errors++; | 387 | pc->rq->errors++; |
388 | 388 | ||
389 | if (rq->cmd[0] == REQUEST_SENSE) { | 389 | if (rq->cmd[0] == REQUEST_SENSE) { |
390 | printk(KERN_ERR "%s: I/O error in request sense" | 390 | printk(KERN_ERR "%s: I/O error in request sense" |
391 | " command\n", drive->name); | 391 | " command\n", drive->name); |
392 | return ide_do_reset(drive); | 392 | return ide_do_reset(drive); |
393 | } | 393 | } |
394 | 394 | ||
395 | debug_log("[cmd %x]: check condition\n", rq->cmd[0]); | 395 | debug_log("[cmd %x]: check condition\n", rq->cmd[0]); |
396 | 396 | ||
397 | /* Retry operation */ | 397 | /* Retry operation */ |
398 | ide_retry_pc(drive); | 398 | ide_retry_pc(drive); |
399 | 399 | ||
400 | /* queued, but not started */ | 400 | /* queued, but not started */ |
401 | return ide_stopped; | 401 | return ide_stopped; |
402 | } | 402 | } |
403 | pc->error = 0; | 403 | pc->error = 0; |
404 | 404 | ||
405 | if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) | 405 | if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) |
406 | dsc = 1; | 406 | dsc = 1; |
407 | 407 | ||
408 | /* Command finished - Call the callback function */ | 408 | /* Command finished - Call the callback function */ |
409 | uptodate = drive->pc_callback(drive, dsc); | 409 | uptodate = drive->pc_callback(drive, dsc); |
410 | 410 | ||
411 | if (uptodate == 0) | 411 | if (uptodate == 0) |
412 | drive->failed_pc = NULL; | 412 | drive->failed_pc = NULL; |
413 | 413 | ||
414 | if (blk_special_request(rq)) { | 414 | if (blk_special_request(rq)) { |
415 | rq->errors = 0; | 415 | rq->errors = 0; |
416 | error = 0; | 416 | error = 0; |
417 | } else { | 417 | } else { |
418 | 418 | ||
419 | if (blk_fs_request(rq) == 0 && uptodate <= 0) { | 419 | if (blk_fs_request(rq) == 0 && uptodate <= 0) { |
420 | if (rq->errors == 0) | 420 | if (rq->errors == 0) |
421 | rq->errors = -EIO; | 421 | rq->errors = -EIO; |
422 | } | 422 | } |
423 | 423 | ||
424 | error = uptodate ? 0 : -EIO; | 424 | error = uptodate ? 0 : -EIO; |
425 | } | 425 | } |
426 | 426 | ||
427 | ide_complete_rq(drive, error, blk_rq_bytes(rq)); | 427 | ide_complete_rq(drive, error, blk_rq_bytes(rq)); |
428 | return ide_stopped; | 428 | return ide_stopped; |
429 | } | 429 | } |
430 | 430 | ||
431 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { | 431 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { |
432 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; | 432 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; |
433 | printk(KERN_ERR "%s: The device wants to issue more interrupts " | 433 | printk(KERN_ERR "%s: The device wants to issue more interrupts " |
434 | "in DMA mode\n", drive->name); | 434 | "in DMA mode\n", drive->name); |
435 | ide_dma_off(drive); | 435 | ide_dma_off(drive); |
436 | return ide_do_reset(drive); | 436 | return ide_do_reset(drive); |
437 | } | 437 | } |
438 | 438 | ||
439 | /* Get the number of bytes to transfer on this interrupt. */ | 439 | /* Get the number of bytes to transfer on this interrupt. */ |
440 | ide_read_bcount_and_ireason(drive, &bcount, &ireason); | 440 | ide_read_bcount_and_ireason(drive, &bcount, &ireason); |
441 | 441 | ||
442 | if (ireason & ATAPI_COD) { | 442 | if (ireason & ATAPI_COD) { |
443 | printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); | 443 | printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); |
444 | return ide_do_reset(drive); | 444 | return ide_do_reset(drive); |
445 | } | 445 | } |
446 | 446 | ||
447 | if (((ireason & ATAPI_IO) == ATAPI_IO) == write) { | 447 | if (((ireason & ATAPI_IO) == ATAPI_IO) == write) { |
448 | /* Hopefully, we will never get here */ | 448 | /* Hopefully, we will never get here */ |
449 | printk(KERN_ERR "%s: We wanted to %s, but the device wants us " | 449 | printk(KERN_ERR "%s: We wanted to %s, but the device wants us " |
450 | "to %s!\n", drive->name, | 450 | "to %s!\n", drive->name, |
451 | (ireason & ATAPI_IO) ? "Write" : "Read", | 451 | (ireason & ATAPI_IO) ? "Write" : "Read", |
452 | (ireason & ATAPI_IO) ? "Read" : "Write"); | 452 | (ireason & ATAPI_IO) ? "Read" : "Write"); |
453 | return ide_do_reset(drive); | 453 | return ide_do_reset(drive); |
454 | } | 454 | } |
455 | 455 | ||
456 | done = min_t(unsigned int, bcount, cmd->nleft); | 456 | done = min_t(unsigned int, bcount, cmd->nleft); |
457 | ide_pio_bytes(drive, cmd, write, done); | 457 | ide_pio_bytes(drive, cmd, write, done); |
458 | 458 | ||
459 | /* Update transferred byte count */ | 459 | /* Update transferred byte count */ |
460 | pc->xferred += done; | 460 | pc->xferred += done; |
461 | 461 | ||
462 | bcount -= done; | 462 | bcount -= done; |
463 | 463 | ||
464 | if (bcount) | 464 | if (bcount) |
465 | ide_pad_transfer(drive, write, bcount); | 465 | ide_pad_transfer(drive, write, bcount); |
466 | 466 | ||
467 | debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n", | 467 | debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n", |
468 | rq->cmd[0], done, bcount); | 468 | rq->cmd[0], done, bcount); |
469 | 469 | ||
470 | /* And set the interrupt handler again */ | 470 | /* And set the interrupt handler again */ |
471 | ide_set_handler(drive, ide_pc_intr, timeout); | 471 | ide_set_handler(drive, ide_pc_intr, timeout); |
472 | return ide_started; | 472 | return ide_started; |
473 | } | 473 | } |
474 | 474 | ||
475 | static void ide_init_packet_cmd(struct ide_cmd *cmd, u8 valid_tf, | 475 | static void ide_init_packet_cmd(struct ide_cmd *cmd, u8 valid_tf, |
476 | u16 bcount, u8 dma) | 476 | u16 bcount, u8 dma) |
477 | { | 477 | { |
478 | cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO; | 478 | cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO; |
479 | cmd->valid.out.tf = IDE_VALID_LBAH | IDE_VALID_LBAM | | 479 | cmd->valid.out.tf = IDE_VALID_LBAH | IDE_VALID_LBAM | |
480 | IDE_VALID_FEATURE | valid_tf; | 480 | IDE_VALID_FEATURE | valid_tf; |
481 | cmd->tf.command = ATA_CMD_PACKET; | 481 | cmd->tf.command = ATA_CMD_PACKET; |
482 | cmd->tf.feature = dma; /* Use PIO/DMA */ | 482 | cmd->tf.feature = dma; /* Use PIO/DMA */ |
483 | cmd->tf.lbam = bcount & 0xff; | 483 | cmd->tf.lbam = bcount & 0xff; |
484 | cmd->tf.lbah = (bcount >> 8) & 0xff; | 484 | cmd->tf.lbah = (bcount >> 8) & 0xff; |
485 | } | 485 | } |
486 | 486 | ||
487 | static u8 ide_read_ireason(ide_drive_t *drive) | 487 | static u8 ide_read_ireason(ide_drive_t *drive) |
488 | { | 488 | { |
489 | struct ide_taskfile tf; | 489 | struct ide_taskfile tf; |
490 | 490 | ||
491 | drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT); | 491 | drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT); |
492 | 492 | ||
493 | return tf.nsect & 3; | 493 | return tf.nsect & 3; |
494 | } | 494 | } |
495 | 495 | ||
496 | static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) | 496 | static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) |
497 | { | 497 | { |
498 | int retries = 100; | 498 | int retries = 100; |
499 | 499 | ||
500 | while (retries-- && ((ireason & ATAPI_COD) == 0 || | 500 | while (retries-- && ((ireason & ATAPI_COD) == 0 || |
501 | (ireason & ATAPI_IO))) { | 501 | (ireason & ATAPI_IO))) { |
502 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " | 502 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " |
503 | "a packet command, retrying\n", drive->name); | 503 | "a packet command, retrying\n", drive->name); |
504 | udelay(100); | 504 | udelay(100); |
505 | ireason = ide_read_ireason(drive); | 505 | ireason = ide_read_ireason(drive); |
506 | if (retries == 0) { | 506 | if (retries == 0) { |
507 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " | 507 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " |
508 | "a packet command, ignoring\n", | 508 | "a packet command, ignoring\n", |
509 | drive->name); | 509 | drive->name); |
510 | ireason |= ATAPI_COD; | 510 | ireason |= ATAPI_COD; |
511 | ireason &= ~ATAPI_IO; | 511 | ireason &= ~ATAPI_IO; |
512 | } | 512 | } |
513 | } | 513 | } |
514 | 514 | ||
515 | return ireason; | 515 | return ireason; |
516 | } | 516 | } |
517 | 517 | ||
518 | static int ide_delayed_transfer_pc(ide_drive_t *drive) | 518 | static int ide_delayed_transfer_pc(ide_drive_t *drive) |
519 | { | 519 | { |
520 | /* Send the actual packet */ | 520 | /* Send the actual packet */ |
521 | drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12); | 521 | drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12); |
522 | 522 | ||
523 | /* Timeout for the packet command */ | 523 | /* Timeout for the packet command */ |
524 | return WAIT_FLOPPY_CMD; | 524 | return WAIT_FLOPPY_CMD; |
525 | } | 525 | } |
526 | 526 | ||
527 | static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) | 527 | static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) |
528 | { | 528 | { |
529 | struct ide_atapi_pc *uninitialized_var(pc); | 529 | struct ide_atapi_pc *uninitialized_var(pc); |
530 | ide_hwif_t *hwif = drive->hwif; | 530 | ide_hwif_t *hwif = drive->hwif; |
531 | struct request *rq = hwif->rq; | 531 | struct request *rq = hwif->rq; |
532 | ide_expiry_t *expiry; | 532 | ide_expiry_t *expiry; |
533 | unsigned int timeout; | 533 | unsigned int timeout; |
534 | int cmd_len; | 534 | int cmd_len; |
535 | ide_startstop_t startstop; | 535 | ide_startstop_t startstop; |
536 | u8 ireason; | 536 | u8 ireason; |
537 | 537 | ||
538 | if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) { | 538 | if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) { |
539 | printk(KERN_ERR "%s: Strange, packet command initiated yet " | 539 | printk(KERN_ERR "%s: Strange, packet command initiated yet " |
540 | "DRQ isn't asserted\n", drive->name); | 540 | "DRQ isn't asserted\n", drive->name); |
541 | return startstop; | 541 | return startstop; |
542 | } | 542 | } |
543 | 543 | ||
544 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { | 544 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { |
545 | if (drive->dma) | 545 | if (drive->dma) |
546 | drive->waiting_for_dma = 1; | 546 | drive->waiting_for_dma = 1; |
547 | } | 547 | } |
548 | 548 | ||
549 | if (dev_is_idecd(drive)) { | 549 | if (dev_is_idecd(drive)) { |
550 | /* ATAPI commands get padded out to 12 bytes minimum */ | 550 | /* ATAPI commands get padded out to 12 bytes minimum */ |
551 | cmd_len = COMMAND_SIZE(rq->cmd[0]); | 551 | cmd_len = COMMAND_SIZE(rq->cmd[0]); |
552 | if (cmd_len < ATAPI_MIN_CDB_BYTES) | 552 | if (cmd_len < ATAPI_MIN_CDB_BYTES) |
553 | cmd_len = ATAPI_MIN_CDB_BYTES; | 553 | cmd_len = ATAPI_MIN_CDB_BYTES; |
554 | 554 | ||
555 | timeout = rq->timeout; | 555 | timeout = rq->timeout; |
556 | expiry = ide_cd_expiry; | 556 | expiry = ide_cd_expiry; |
557 | } else { | 557 | } else { |
558 | pc = drive->pc; | 558 | pc = drive->pc; |
559 | 559 | ||
560 | cmd_len = ATAPI_MIN_CDB_BYTES; | 560 | cmd_len = ATAPI_MIN_CDB_BYTES; |
561 | 561 | ||
562 | /* | 562 | /* |
563 | * If necessary schedule the packet transfer to occur 'timeout' | 563 | * If necessary schedule the packet transfer to occur 'timeout' |
564 | * miliseconds later in ide_delayed_transfer_pc() after the | 564 | * miliseconds later in ide_delayed_transfer_pc() after the |
565 | * device says it's ready for a packet. | 565 | * device says it's ready for a packet. |
566 | */ | 566 | */ |
567 | if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { | 567 | if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { |
568 | timeout = drive->pc_delay; | 568 | timeout = drive->pc_delay; |
569 | expiry = &ide_delayed_transfer_pc; | 569 | expiry = &ide_delayed_transfer_pc; |
570 | } else { | 570 | } else { |
571 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD | 571 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD |
572 | : WAIT_TAPE_CMD; | 572 | : WAIT_TAPE_CMD; |
573 | expiry = NULL; | 573 | expiry = NULL; |
574 | } | 574 | } |
575 | 575 | ||
576 | ireason = ide_read_ireason(drive); | 576 | ireason = ide_read_ireason(drive); |
577 | if (drive->media == ide_tape) | 577 | if (drive->media == ide_tape) |
578 | ireason = ide_wait_ireason(drive, ireason); | 578 | ireason = ide_wait_ireason(drive, ireason); |
579 | 579 | ||
580 | if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { | 580 | if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { |
581 | printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " | 581 | printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " |
582 | "a packet command\n", drive->name); | 582 | "a packet command\n", drive->name); |
583 | 583 | ||
584 | return ide_do_reset(drive); | 584 | return ide_do_reset(drive); |
585 | } | 585 | } |
586 | } | 586 | } |
587 | 587 | ||
588 | hwif->expiry = expiry; | 588 | hwif->expiry = expiry; |
589 | 589 | ||
590 | /* Set the interrupt routine */ | 590 | /* Set the interrupt routine */ |
591 | ide_set_handler(drive, | 591 | ide_set_handler(drive, |
592 | (dev_is_idecd(drive) ? drive->irq_handler | 592 | (dev_is_idecd(drive) ? drive->irq_handler |
593 | : ide_pc_intr), | 593 | : ide_pc_intr), |
594 | timeout); | 594 | timeout); |
595 | 595 | ||
596 | /* Send the actual packet */ | 596 | /* Send the actual packet */ |
597 | if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) | 597 | if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) |
598 | hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); | 598 | hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); |
599 | 599 | ||
600 | /* Begin DMA, if necessary */ | 600 | /* Begin DMA, if necessary */ |
601 | if (dev_is_idecd(drive)) { | 601 | if (dev_is_idecd(drive)) { |
602 | if (drive->dma) | 602 | if (drive->dma) |
603 | hwif->dma_ops->dma_start(drive); | 603 | hwif->dma_ops->dma_start(drive); |
604 | } else { | 604 | } else { |
605 | if (pc->flags & PC_FLAG_DMA_OK) { | 605 | if (pc->flags & PC_FLAG_DMA_OK) { |
606 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | 606 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; |
607 | hwif->dma_ops->dma_start(drive); | 607 | hwif->dma_ops->dma_start(drive); |
608 | } | 608 | } |
609 | } | 609 | } |
610 | 610 | ||
611 | return ide_started; | 611 | return ide_started; |
612 | } | 612 | } |
613 | 613 | ||
614 | ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) | 614 | ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) |
615 | { | 615 | { |
616 | struct ide_atapi_pc *pc; | 616 | struct ide_atapi_pc *pc; |
617 | ide_hwif_t *hwif = drive->hwif; | 617 | ide_hwif_t *hwif = drive->hwif; |
618 | ide_expiry_t *expiry = NULL; | 618 | ide_expiry_t *expiry = NULL; |
619 | struct request *rq = hwif->rq; | 619 | struct request *rq = hwif->rq; |
620 | unsigned int timeout; | 620 | unsigned int timeout; |
621 | u16 bcount; | 621 | u16 bcount; |
622 | u8 valid_tf; | 622 | u8 valid_tf; |
623 | u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT); | 623 | u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT); |
624 | 624 | ||
625 | if (dev_is_idecd(drive)) { | 625 | if (dev_is_idecd(drive)) { |
626 | valid_tf = IDE_VALID_NSECT | IDE_VALID_LBAL; | 626 | valid_tf = IDE_VALID_NSECT | IDE_VALID_LBAL; |
627 | bcount = ide_cd_get_xferlen(rq); | 627 | bcount = ide_cd_get_xferlen(rq); |
628 | expiry = ide_cd_expiry; | 628 | expiry = ide_cd_expiry; |
629 | timeout = ATAPI_WAIT_PC; | 629 | timeout = ATAPI_WAIT_PC; |
630 | 630 | ||
631 | if (drive->dma) | 631 | if (drive->dma) |
632 | drive->dma = !ide_dma_prepare(drive, cmd); | 632 | drive->dma = !ide_dma_prepare(drive, cmd); |
633 | } else { | 633 | } else { |
634 | pc = drive->pc; | 634 | pc = drive->pc; |
635 | 635 | ||
636 | /* We haven't transferred any data yet */ | 636 | /* We haven't transferred any data yet */ |
637 | pc->xferred = 0; | 637 | pc->xferred = 0; |
638 | 638 | ||
639 | valid_tf = IDE_VALID_DEVICE; | 639 | valid_tf = IDE_VALID_DEVICE; |
640 | bcount = ((drive->media == ide_tape) ? | 640 | bcount = ((drive->media == ide_tape) ? |
641 | pc->req_xfer : | 641 | pc->req_xfer : |
642 | min(pc->req_xfer, 63 * 1024)); | 642 | min(pc->req_xfer, 63 * 1024)); |
643 | 643 | ||
644 | if (pc->flags & PC_FLAG_DMA_ERROR) { | 644 | if (pc->flags & PC_FLAG_DMA_ERROR) { |
645 | pc->flags &= ~PC_FLAG_DMA_ERROR; | 645 | pc->flags &= ~PC_FLAG_DMA_ERROR; |
646 | ide_dma_off(drive); | 646 | ide_dma_off(drive); |
647 | } | 647 | } |
648 | 648 | ||
649 | if (pc->flags & PC_FLAG_DMA_OK) | 649 | if (pc->flags & PC_FLAG_DMA_OK) |
650 | drive->dma = !ide_dma_prepare(drive, cmd); | 650 | drive->dma = !ide_dma_prepare(drive, cmd); |
651 | 651 | ||
652 | if (!drive->dma) | 652 | if (!drive->dma) |
653 | pc->flags &= ~PC_FLAG_DMA_OK; | 653 | pc->flags &= ~PC_FLAG_DMA_OK; |
654 | 654 | ||
655 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD | 655 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD |
656 | : WAIT_TAPE_CMD; | 656 | : WAIT_TAPE_CMD; |
657 | } | 657 | } |
658 | 658 | ||
659 | ide_init_packet_cmd(cmd, valid_tf, bcount, drive->dma); | 659 | ide_init_packet_cmd(cmd, valid_tf, bcount, drive->dma); |
660 | 660 | ||
661 | (void)do_rw_taskfile(drive, cmd); | 661 | (void)do_rw_taskfile(drive, cmd); |
662 | 662 | ||
663 | if (drq_int) { | 663 | if (drq_int) { |
664 | if (drive->dma) | 664 | if (drive->dma) |
665 | drive->waiting_for_dma = 0; | 665 | drive->waiting_for_dma = 0; |
666 | hwif->expiry = expiry; | 666 | hwif->expiry = expiry; |
667 | } | 667 | } |
668 | 668 | ||
669 | ide_execute_command(drive, cmd, ide_transfer_pc, timeout); | 669 | ide_execute_command(drive, cmd, ide_transfer_pc, timeout); |
670 | 670 | ||
671 | return drq_int ? ide_started : ide_transfer_pc(drive); | 671 | return drq_int ? ide_started : ide_transfer_pc(drive); |
672 | } | 672 | } |
673 | EXPORT_SYMBOL_GPL(ide_issue_pc); | 673 | EXPORT_SYMBOL_GPL(ide_issue_pc); |
674 | 674 |
drivers/ide/ide-cd.c
1 | /* | 1 | /* |
2 | * ATAPI CD-ROM driver. | 2 | * ATAPI CD-ROM driver. |
3 | * | 3 | * |
4 | * Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov> | 4 | * Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov> |
5 | * Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org> | 5 | * Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org> |
6 | * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de> | 6 | * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de> |
7 | * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz | 7 | * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz |
8 | * | 8 | * |
9 | * May be copied or modified under the terms of the GNU General Public | 9 | * May be copied or modified under the terms of the GNU General Public |
10 | * License. See linux/COPYING for more information. | 10 | * License. See linux/COPYING for more information. |
11 | * | 11 | * |
12 | * See Documentation/cdrom/ide-cd for usage information. | 12 | * See Documentation/cdrom/ide-cd for usage information. |
13 | * | 13 | * |
14 | * Suggestions are welcome. Patches that work are more welcome though. ;-) | 14 | * Suggestions are welcome. Patches that work are more welcome though. ;-) |
15 | * | 15 | * |
16 | * Documentation: | 16 | * Documentation: |
17 | * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards. | 17 | * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards. |
18 | * | 18 | * |
19 | * For historical changelog please see: | 19 | * For historical changelog please see: |
20 | * Documentation/ide/ChangeLog.ide-cd.1994-2004 | 20 | * Documentation/ide/ChangeLog.ide-cd.1994-2004 |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #define DRV_NAME "ide-cd" | 23 | #define DRV_NAME "ide-cd" |
24 | #define PFX DRV_NAME ": " | 24 | #define PFX DRV_NAME ": " |
25 | 25 | ||
26 | #define IDECD_VERSION "5.00" | 26 | #define IDECD_VERSION "5.00" |
27 | 27 | ||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/timer.h> | 32 | #include <linux/timer.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
36 | #include <linux/cdrom.h> | 36 | #include <linux/cdrom.h> |
37 | #include <linux/ide.h> | 37 | #include <linux/ide.h> |
38 | #include <linux/completion.h> | 38 | #include <linux/completion.h> |
39 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
40 | #include <linux/bcd.h> | 40 | #include <linux/bcd.h> |
41 | 41 | ||
42 | /* For SCSI -> ATAPI command conversion */ | 42 | /* For SCSI -> ATAPI command conversion */ |
43 | #include <scsi/scsi.h> | 43 | #include <scsi/scsi.h> |
44 | 44 | ||
45 | #include <linux/irq.h> | 45 | #include <linux/irq.h> |
46 | #include <linux/io.h> | 46 | #include <linux/io.h> |
47 | #include <asm/byteorder.h> | 47 | #include <asm/byteorder.h> |
48 | #include <linux/uaccess.h> | 48 | #include <linux/uaccess.h> |
49 | #include <asm/unaligned.h> | 49 | #include <asm/unaligned.h> |
50 | 50 | ||
51 | #include "ide-cd.h" | 51 | #include "ide-cd.h" |
52 | 52 | ||
53 | static DEFINE_MUTEX(idecd_ref_mutex); | 53 | static DEFINE_MUTEX(idecd_ref_mutex); |
54 | 54 | ||
55 | static void ide_cd_release(struct device *); | 55 | static void ide_cd_release(struct device *); |
56 | 56 | ||
57 | static struct cdrom_info *ide_cd_get(struct gendisk *disk) | 57 | static struct cdrom_info *ide_cd_get(struct gendisk *disk) |
58 | { | 58 | { |
59 | struct cdrom_info *cd = NULL; | 59 | struct cdrom_info *cd = NULL; |
60 | 60 | ||
61 | mutex_lock(&idecd_ref_mutex); | 61 | mutex_lock(&idecd_ref_mutex); |
62 | cd = ide_drv_g(disk, cdrom_info); | 62 | cd = ide_drv_g(disk, cdrom_info); |
63 | if (cd) { | 63 | if (cd) { |
64 | if (ide_device_get(cd->drive)) | 64 | if (ide_device_get(cd->drive)) |
65 | cd = NULL; | 65 | cd = NULL; |
66 | else | 66 | else |
67 | get_device(&cd->dev); | 67 | get_device(&cd->dev); |
68 | 68 | ||
69 | } | 69 | } |
70 | mutex_unlock(&idecd_ref_mutex); | 70 | mutex_unlock(&idecd_ref_mutex); |
71 | return cd; | 71 | return cd; |
72 | } | 72 | } |
73 | 73 | ||
74 | static void ide_cd_put(struct cdrom_info *cd) | 74 | static void ide_cd_put(struct cdrom_info *cd) |
75 | { | 75 | { |
76 | ide_drive_t *drive = cd->drive; | 76 | ide_drive_t *drive = cd->drive; |
77 | 77 | ||
78 | mutex_lock(&idecd_ref_mutex); | 78 | mutex_lock(&idecd_ref_mutex); |
79 | put_device(&cd->dev); | 79 | put_device(&cd->dev); |
80 | ide_device_put(drive); | 80 | ide_device_put(drive); |
81 | mutex_unlock(&idecd_ref_mutex); | 81 | mutex_unlock(&idecd_ref_mutex); |
82 | } | 82 | } |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Generic packet command support and error handling routines. | 85 | * Generic packet command support and error handling routines. |
86 | */ | 86 | */ |
87 | 87 | ||
88 | /* Mark that we've seen a media change and invalidate our internal buffers. */ | 88 | /* Mark that we've seen a media change and invalidate our internal buffers. */ |
89 | static void cdrom_saw_media_change(ide_drive_t *drive) | 89 | static void cdrom_saw_media_change(ide_drive_t *drive) |
90 | { | 90 | { |
91 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; | 91 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; |
92 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; | 92 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; |
93 | } | 93 | } |
94 | 94 | ||
95 | static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, | 95 | static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, |
96 | struct request_sense *sense) | 96 | struct request_sense *sense) |
97 | { | 97 | { |
98 | int log = 0; | 98 | int log = 0; |
99 | 99 | ||
100 | ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); | 100 | ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); |
101 | 101 | ||
102 | if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) | 102 | if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) |
103 | return 0; | 103 | return 0; |
104 | 104 | ||
105 | switch (sense->sense_key) { | 105 | switch (sense->sense_key) { |
106 | case NO_SENSE: | 106 | case NO_SENSE: |
107 | case RECOVERED_ERROR: | 107 | case RECOVERED_ERROR: |
108 | break; | 108 | break; |
109 | case NOT_READY: | 109 | case NOT_READY: |
110 | /* | 110 | /* |
111 | * don't care about tray state messages for e.g. capacity | 111 | * don't care about tray state messages for e.g. capacity |
112 | * commands or in-progress or becoming ready | 112 | * commands or in-progress or becoming ready |
113 | */ | 113 | */ |
114 | if (sense->asc == 0x3a || sense->asc == 0x04) | 114 | if (sense->asc == 0x3a || sense->asc == 0x04) |
115 | break; | 115 | break; |
116 | log = 1; | 116 | log = 1; |
117 | break; | 117 | break; |
118 | case ILLEGAL_REQUEST: | 118 | case ILLEGAL_REQUEST: |
119 | /* | 119 | /* |
120 | * don't log START_STOP unit with LoEj set, since we cannot | 120 | * don't log START_STOP unit with LoEj set, since we cannot |
121 | * reliably check if drive can auto-close | 121 | * reliably check if drive can auto-close |
122 | */ | 122 | */ |
123 | if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24) | 123 | if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24) |
124 | break; | 124 | break; |
125 | log = 1; | 125 | log = 1; |
126 | break; | 126 | break; |
127 | case UNIT_ATTENTION: | 127 | case UNIT_ATTENTION: |
128 | /* | 128 | /* |
129 | * Make good and sure we've seen this potential media change. | 129 | * Make good and sure we've seen this potential media change. |
130 | * Some drives (i.e. Creative) fail to present the correct sense | 130 | * Some drives (i.e. Creative) fail to present the correct sense |
131 | * key in the error register. | 131 | * key in the error register. |
132 | */ | 132 | */ |
133 | cdrom_saw_media_change(drive); | 133 | cdrom_saw_media_change(drive); |
134 | break; | 134 | break; |
135 | default: | 135 | default: |
136 | log = 1; | 136 | log = 1; |
137 | break; | 137 | break; |
138 | } | 138 | } |
139 | return log; | 139 | return log; |
140 | } | 140 | } |
141 | 141 | ||
142 | static void cdrom_analyze_sense_data(ide_drive_t *drive, | 142 | static void cdrom_analyze_sense_data(ide_drive_t *drive, |
143 | struct request *failed_command, | 143 | struct request *failed_command, |
144 | struct request_sense *sense) | 144 | struct request_sense *sense) |
145 | { | 145 | { |
146 | unsigned long sector; | 146 | unsigned long sector; |
147 | unsigned long bio_sectors; | 147 | unsigned long bio_sectors; |
148 | struct cdrom_info *info = drive->driver_data; | 148 | struct cdrom_info *info = drive->driver_data; |
149 | 149 | ||
150 | ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x", | 150 | ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x", |
151 | sense->error_code, sense->sense_key); | 151 | sense->error_code, sense->sense_key); |
152 | 152 | ||
153 | if (failed_command) | 153 | if (failed_command) |
154 | ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x", | 154 | ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x", |
155 | failed_command->cmd[0]); | 155 | failed_command->cmd[0]); |
156 | 156 | ||
157 | if (!cdrom_log_sense(drive, failed_command, sense)) | 157 | if (!cdrom_log_sense(drive, failed_command, sense)) |
158 | return; | 158 | return; |
159 | 159 | ||
160 | /* | 160 | /* |
161 | * If a read toc is executed for a CD-R or CD-RW medium where the first | 161 | * If a read toc is executed for a CD-R or CD-RW medium where the first |
162 | * toc has not been recorded yet, it will fail with 05/24/00 (which is a | 162 | * toc has not been recorded yet, it will fail with 05/24/00 (which is a |
163 | * confusing error) | 163 | * confusing error) |
164 | */ | 164 | */ |
165 | if (failed_command && failed_command->cmd[0] == GPCMD_READ_TOC_PMA_ATIP) | 165 | if (failed_command && failed_command->cmd[0] == GPCMD_READ_TOC_PMA_ATIP) |
166 | if (sense->sense_key == 0x05 && sense->asc == 0x24) | 166 | if (sense->sense_key == 0x05 && sense->asc == 0x24) |
167 | return; | 167 | return; |
168 | 168 | ||
169 | /* current error */ | 169 | /* current error */ |
170 | if (sense->error_code == 0x70) { | 170 | if (sense->error_code == 0x70) { |
171 | switch (sense->sense_key) { | 171 | switch (sense->sense_key) { |
172 | case MEDIUM_ERROR: | 172 | case MEDIUM_ERROR: |
173 | case VOLUME_OVERFLOW: | 173 | case VOLUME_OVERFLOW: |
174 | case ILLEGAL_REQUEST: | 174 | case ILLEGAL_REQUEST: |
175 | if (!sense->valid) | 175 | if (!sense->valid) |
176 | break; | 176 | break; |
177 | if (failed_command == NULL || | 177 | if (failed_command == NULL || |
178 | !blk_fs_request(failed_command)) | 178 | !blk_fs_request(failed_command)) |
179 | break; | 179 | break; |
180 | sector = (sense->information[0] << 24) | | 180 | sector = (sense->information[0] << 24) | |
181 | (sense->information[1] << 16) | | 181 | (sense->information[1] << 16) | |
182 | (sense->information[2] << 8) | | 182 | (sense->information[2] << 8) | |
183 | (sense->information[3]); | 183 | (sense->information[3]); |
184 | 184 | ||
185 | if (drive->queue->hardsect_size == 2048) | 185 | if (drive->queue->hardsect_size == 2048) |
186 | /* device sector size is 2K */ | 186 | /* device sector size is 2K */ |
187 | sector <<= 2; | 187 | sector <<= 2; |
188 | 188 | ||
189 | bio_sectors = max(bio_sectors(failed_command->bio), 4U); | 189 | bio_sectors = max(bio_sectors(failed_command->bio), 4U); |
190 | sector &= ~(bio_sectors - 1); | 190 | sector &= ~(bio_sectors - 1); |
191 | 191 | ||
192 | /* | 192 | /* |
193 | * The SCSI specification allows for the value | 193 | * The SCSI specification allows for the value |
194 | * returned by READ CAPACITY to be up to 75 2K | 194 | * returned by READ CAPACITY to be up to 75 2K |
195 | * sectors past the last readable block. | 195 | * sectors past the last readable block. |
196 | * Therefore, if we hit a medium error within the | 196 | * Therefore, if we hit a medium error within the |
197 | * last 75 2K sectors, we decrease the saved size | 197 | * last 75 2K sectors, we decrease the saved size |
198 | * value. | 198 | * value. |
199 | */ | 199 | */ |
200 | if (sector < get_capacity(info->disk) && | 200 | if (sector < get_capacity(info->disk) && |
201 | drive->probed_capacity - sector < 4 * 75) | 201 | drive->probed_capacity - sector < 4 * 75) |
202 | set_capacity(info->disk, sector); | 202 | set_capacity(info->disk, sector); |
203 | } | 203 | } |
204 | } | 204 | } |
205 | 205 | ||
206 | ide_cd_log_error(drive->name, failed_command, sense); | 206 | ide_cd_log_error(drive->name, failed_command, sense); |
207 | } | 207 | } |
208 | 208 | ||
209 | static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) | 209 | static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) |
210 | { | 210 | { |
211 | /* | 211 | /* |
212 | * For REQ_TYPE_SENSE, "rq->special" points to the original | 212 | * For REQ_TYPE_SENSE, "rq->special" points to the original |
213 | * failed request. Also, the sense data should be read | 213 | * failed request. Also, the sense data should be read |
214 | * directly from rq which might be different from the original | 214 | * directly from rq which might be different from the original |
215 | * sense buffer if it got copied during mapping. | 215 | * sense buffer if it got copied during mapping. |
216 | */ | 216 | */ |
217 | struct request *failed = (struct request *)rq->special; | 217 | struct request *failed = (struct request *)rq->special; |
218 | void *sense = bio_data(rq->bio); | 218 | void *sense = bio_data(rq->bio); |
219 | 219 | ||
220 | if (failed) { | 220 | if (failed) { |
221 | if (failed->sense) { | 221 | if (failed->sense) { |
222 | /* | 222 | /* |
223 | * Sense is always read into drive->sense_data. | 223 | * Sense is always read into drive->sense_data. |
224 | * Copy back if the failed request has its | 224 | * Copy back if the failed request has its |
225 | * sense pointer set. | 225 | * sense pointer set. |
226 | */ | 226 | */ |
227 | memcpy(failed->sense, sense, 18); | 227 | memcpy(failed->sense, sense, 18); |
228 | sense = failed->sense; | 228 | sense = failed->sense; |
229 | failed->sense_len = rq->sense_len; | 229 | failed->sense_len = rq->sense_len; |
230 | } | 230 | } |
231 | cdrom_analyze_sense_data(drive, failed, sense); | 231 | cdrom_analyze_sense_data(drive, failed, sense); |
232 | 232 | ||
233 | if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed))) | 233 | if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed))) |
234 | BUG(); | 234 | BUG(); |
235 | } else | 235 | } else |
236 | cdrom_analyze_sense_data(drive, NULL, sense); | 236 | cdrom_analyze_sense_data(drive, NULL, sense); |
237 | } | 237 | } |
238 | 238 | ||
239 | 239 | ||
240 | /* | 240 | /* |
241 | * Allow the drive 5 seconds to recover; some devices will return NOT_READY | 241 | * Allow the drive 5 seconds to recover; some devices will return NOT_READY |
242 | * while flushing data from cache. | 242 | * while flushing data from cache. |
243 | * | 243 | * |
244 | * returns: 0 failed (write timeout expired) | 244 | * returns: 0 failed (write timeout expired) |
245 | * 1 success | 245 | * 1 success |
246 | */ | 246 | */ |
247 | static int ide_cd_breathe(ide_drive_t *drive, struct request *rq) | 247 | static int ide_cd_breathe(ide_drive_t *drive, struct request *rq) |
248 | { | 248 | { |
249 | 249 | ||
250 | struct cdrom_info *info = drive->driver_data; | 250 | struct cdrom_info *info = drive->driver_data; |
251 | 251 | ||
252 | if (!rq->errors) | 252 | if (!rq->errors) |
253 | info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY; | 253 | info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY; |
254 | 254 | ||
255 | rq->errors = 1; | 255 | rq->errors = 1; |
256 | 256 | ||
257 | if (time_after(jiffies, info->write_timeout)) | 257 | if (time_after(jiffies, info->write_timeout)) |
258 | return 0; | 258 | return 0; |
259 | else { | 259 | else { |
260 | struct request_queue *q = drive->queue; | 260 | struct request_queue *q = drive->queue; |
261 | unsigned long flags; | 261 | unsigned long flags; |
262 | 262 | ||
263 | /* | 263 | /* |
264 | * take a breather relying on the unplug timer to kick us again | 264 | * take a breather relying on the unplug timer to kick us again |
265 | */ | 265 | */ |
266 | 266 | ||
267 | spin_lock_irqsave(q->queue_lock, flags); | 267 | spin_lock_irqsave(q->queue_lock, flags); |
268 | blk_plug_device(q); | 268 | blk_plug_device(q); |
269 | spin_unlock_irqrestore(q->queue_lock, flags); | 269 | spin_unlock_irqrestore(q->queue_lock, flags); |
270 | 270 | ||
271 | return 1; | 271 | return 1; |
272 | } | 272 | } |
273 | } | 273 | } |
274 | 274 | ||
275 | /** | 275 | /** |
276 | * Returns: | 276 | * Returns: |
277 | * 0: if the request should be continued. | 277 | * 0: if the request should be continued. |
278 | * 1: if the request will be going through error recovery. | 278 | * 1: if the request will be going through error recovery. |
279 | * 2: if the request should be ended. | 279 | * 2: if the request should be ended. |
280 | */ | 280 | */ |
281 | static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | 281 | static int cdrom_decode_status(ide_drive_t *drive, u8 stat) |
282 | { | 282 | { |
283 | ide_hwif_t *hwif = drive->hwif; | 283 | ide_hwif_t *hwif = drive->hwif; |
284 | struct request *rq = hwif->rq; | 284 | struct request *rq = hwif->rq; |
285 | int err, sense_key, do_end_request = 0; | 285 | int err, sense_key, do_end_request = 0; |
286 | u8 quiet = rq->cmd_flags & REQ_QUIET; | 286 | u8 quiet = rq->cmd_flags & REQ_QUIET; |
287 | 287 | ||
288 | /* get the IDE error register */ | 288 | /* get the IDE error register */ |
289 | err = ide_read_error(drive); | 289 | err = ide_read_error(drive); |
290 | sense_key = err >> 4; | 290 | sense_key = err >> 4; |
291 | 291 | ||
292 | ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, " | 292 | ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, " |
293 | "stat 0x%x", | 293 | "stat 0x%x", |
294 | rq->cmd[0], rq->cmd_type, err, stat); | 294 | rq->cmd[0], rq->cmd_type, err, stat); |
295 | 295 | ||
296 | if (blk_sense_request(rq)) { | 296 | if (blk_sense_request(rq)) { |
297 | /* | 297 | /* |
298 | * We got an error trying to get sense info from the drive | 298 | * We got an error trying to get sense info from the drive |
299 | * (probably while trying to recover from a former error). | 299 | * (probably while trying to recover from a former error). |
300 | * Just give up. | 300 | * Just give up. |
301 | */ | 301 | */ |
302 | rq->cmd_flags |= REQ_FAILED; | 302 | rq->cmd_flags |= REQ_FAILED; |
303 | return 2; | 303 | return 2; |
304 | } | 304 | } |
305 | 305 | ||
306 | /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ | 306 | /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ |
307 | if (blk_pc_request(rq) && !rq->errors) | 307 | if (blk_pc_request(rq) && !rq->errors) |
308 | rq->errors = SAM_STAT_CHECK_CONDITION; | 308 | rq->errors = SAM_STAT_CHECK_CONDITION; |
309 | 309 | ||
310 | if (blk_noretry_request(rq)) | 310 | if (blk_noretry_request(rq)) |
311 | do_end_request = 1; | 311 | do_end_request = 1; |
312 | 312 | ||
313 | switch (sense_key) { | 313 | switch (sense_key) { |
314 | case NOT_READY: | 314 | case NOT_READY: |
315 | if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) { | 315 | if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) { |
316 | if (ide_cd_breathe(drive, rq)) | 316 | if (ide_cd_breathe(drive, rq)) |
317 | return 1; | 317 | return 1; |
318 | } else { | 318 | } else { |
319 | cdrom_saw_media_change(drive); | 319 | cdrom_saw_media_change(drive); |
320 | 320 | ||
321 | if (blk_fs_request(rq) && !quiet) | 321 | if (blk_fs_request(rq) && !quiet) |
322 | printk(KERN_ERR PFX "%s: tray open\n", | 322 | printk(KERN_ERR PFX "%s: tray open\n", |
323 | drive->name); | 323 | drive->name); |
324 | } | 324 | } |
325 | do_end_request = 1; | 325 | do_end_request = 1; |
326 | break; | 326 | break; |
327 | case UNIT_ATTENTION: | 327 | case UNIT_ATTENTION: |
328 | cdrom_saw_media_change(drive); | 328 | cdrom_saw_media_change(drive); |
329 | 329 | ||
330 | if (blk_fs_request(rq) == 0) | 330 | if (blk_fs_request(rq) == 0) |
331 | return 0; | 331 | return 0; |
332 | 332 | ||
333 | /* | 333 | /* |
334 | * Arrange to retry the request but be sure to give up if we've | 334 | * Arrange to retry the request but be sure to give up if we've |
335 | * retried too many times. | 335 | * retried too many times. |
336 | */ | 336 | */ |
337 | if (++rq->errors > ERROR_MAX) | 337 | if (++rq->errors > ERROR_MAX) |
338 | do_end_request = 1; | 338 | do_end_request = 1; |
339 | break; | 339 | break; |
340 | case ILLEGAL_REQUEST: | 340 | case ILLEGAL_REQUEST: |
341 | /* | 341 | /* |
342 | * Don't print error message for this condition -- SFF8090i | 342 | * Don't print error message for this condition -- SFF8090i |
343 | * indicates that 5/24/00 is the correct response to a request | 343 | * indicates that 5/24/00 is the correct response to a request |
344 | * to close the tray if the drive doesn't have that capability. | 344 | * to close the tray if the drive doesn't have that capability. |
345 | * | 345 | * |
346 | * cdrom_log_sense() knows this! | 346 | * cdrom_log_sense() knows this! |
347 | */ | 347 | */ |
348 | if (rq->cmd[0] == GPCMD_START_STOP_UNIT) | 348 | if (rq->cmd[0] == GPCMD_START_STOP_UNIT) |
349 | break; | 349 | break; |
350 | /* fall-through */ | 350 | /* fall-through */ |
351 | case DATA_PROTECT: | 351 | case DATA_PROTECT: |
352 | /* | 352 | /* |
353 | * No point in retrying after an illegal request or data | 353 | * No point in retrying after an illegal request or data |
354 | * protect error. | 354 | * protect error. |
355 | */ | 355 | */ |
356 | if (!quiet) | 356 | if (!quiet) |
357 | ide_dump_status(drive, "command error", stat); | 357 | ide_dump_status(drive, "command error", stat); |
358 | do_end_request = 1; | 358 | do_end_request = 1; |
359 | break; | 359 | break; |
360 | case MEDIUM_ERROR: | 360 | case MEDIUM_ERROR: |
361 | /* | 361 | /* |
362 | * No point in re-trying a zillion times on a bad sector. | 362 | * No point in re-trying a zillion times on a bad sector. |
363 | * If we got here the error is not correctable. | 363 | * If we got here the error is not correctable. |
364 | */ | 364 | */ |
365 | if (!quiet) | 365 | if (!quiet) |
366 | ide_dump_status(drive, "media error " | 366 | ide_dump_status(drive, "media error " |
367 | "(bad sector)", stat); | 367 | "(bad sector)", stat); |
368 | do_end_request = 1; | 368 | do_end_request = 1; |
369 | break; | 369 | break; |
370 | case BLANK_CHECK: | 370 | case BLANK_CHECK: |
371 | /* disk appears blank? */ | 371 | /* disk appears blank? */ |
372 | if (!quiet) | 372 | if (!quiet) |
373 | ide_dump_status(drive, "media error (blank)", | 373 | ide_dump_status(drive, "media error (blank)", |
374 | stat); | 374 | stat); |
375 | do_end_request = 1; | 375 | do_end_request = 1; |
376 | break; | 376 | break; |
377 | default: | 377 | default: |
378 | if (blk_fs_request(rq) == 0) | 378 | if (blk_fs_request(rq) == 0) |
379 | break; | 379 | break; |
380 | if (err & ~ATA_ABORTED) { | 380 | if (err & ~ATA_ABORTED) { |
381 | /* go to the default handler for other errors */ | 381 | /* go to the default handler for other errors */ |
382 | ide_error(drive, "cdrom_decode_status", stat); | 382 | ide_error(drive, "cdrom_decode_status", stat); |
383 | return 1; | 383 | return 1; |
384 | } else if (++rq->errors > ERROR_MAX) | 384 | } else if (++rq->errors > ERROR_MAX) |
385 | /* we've racked up too many retries, abort */ | 385 | /* we've racked up too many retries, abort */ |
386 | do_end_request = 1; | 386 | do_end_request = 1; |
387 | } | 387 | } |
388 | 388 | ||
389 | if (blk_fs_request(rq) == 0) { | 389 | if (blk_fs_request(rq) == 0) { |
390 | rq->cmd_flags |= REQ_FAILED; | 390 | rq->cmd_flags |= REQ_FAILED; |
391 | do_end_request = 1; | 391 | do_end_request = 1; |
392 | } | 392 | } |
393 | 393 | ||
394 | /* | 394 | /* |
395 | * End a request through request sense analysis when we have sense data. | 395 | * End a request through request sense analysis when we have sense data. |
396 | * We need this in order to perform end of media processing. | 396 | * We need this in order to perform end of media processing. |
397 | */ | 397 | */ |
398 | if (do_end_request) | 398 | if (do_end_request) |
399 | goto end_request; | 399 | goto end_request; |
400 | 400 | ||
401 | /* if we got a CHECK_CONDITION status, queue a request sense command */ | 401 | /* if we got a CHECK_CONDITION status, queue a request sense command */ |
402 | if (stat & ATA_ERR) | 402 | if (stat & ATA_ERR) |
403 | return ide_queue_sense_rq(drive, NULL) ? 2 : 1; | 403 | return ide_queue_sense_rq(drive, NULL) ? 2 : 1; |
404 | return 1; | 404 | return 1; |
405 | 405 | ||
406 | end_request: | 406 | end_request: |
407 | if (stat & ATA_ERR) { | 407 | if (stat & ATA_ERR) { |
408 | struct request_queue *q = drive->queue; | 408 | struct request_queue *q = drive->queue; |
409 | unsigned long flags; | 409 | unsigned long flags; |
410 | 410 | ||
411 | spin_lock_irqsave(q->queue_lock, flags); | 411 | spin_lock_irqsave(q->queue_lock, flags); |
412 | blkdev_dequeue_request(rq); | 412 | blkdev_dequeue_request(rq); |
413 | spin_unlock_irqrestore(q->queue_lock, flags); | 413 | spin_unlock_irqrestore(q->queue_lock, flags); |
414 | 414 | ||
415 | hwif->rq = NULL; | 415 | hwif->rq = NULL; |
416 | 416 | ||
417 | return ide_queue_sense_rq(drive, rq) ? 2 : 1; | 417 | return ide_queue_sense_rq(drive, rq) ? 2 : 1; |
418 | } else | 418 | } else |
419 | return 2; | 419 | return 2; |
420 | } | 420 | } |
421 | 421 | ||
422 | /* | 422 | /* |
423 | * Check the contents of the interrupt reason register from the cdrom | 423 | * Check the contents of the interrupt reason register from the cdrom |
424 | * and attempt to recover if there are problems. Returns 0 if everything's | 424 | * and attempt to recover if there are problems. Returns 0 if everything's |
425 | * ok; nonzero if the request has been terminated. | 425 | * ok; nonzero if the request has been terminated. |
426 | */ | 426 | */ |
427 | static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, | 427 | static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, |
428 | int len, int ireason, int rw) | 428 | int len, int ireason, int rw) |
429 | { | 429 | { |
430 | ide_hwif_t *hwif = drive->hwif; | 430 | ide_hwif_t *hwif = drive->hwif; |
431 | 431 | ||
432 | ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw); | 432 | ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw); |
433 | 433 | ||
434 | /* | 434 | /* |
435 | * ireason == 0: the drive wants to receive data from us | 435 | * ireason == 0: the drive wants to receive data from us |
436 | * ireason == 2: the drive is expecting to transfer data to us | 436 | * ireason == 2: the drive is expecting to transfer data to us |
437 | */ | 437 | */ |
438 | if (ireason == (!rw << 1)) | 438 | if (ireason == (!rw << 1)) |
439 | return 0; | 439 | return 0; |
440 | else if (ireason == (rw << 1)) { | 440 | else if (ireason == (rw << 1)) { |
441 | 441 | ||
442 | /* whoops... */ | 442 | /* whoops... */ |
443 | printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n", | 443 | printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n", |
444 | drive->name, __func__); | 444 | drive->name, __func__); |
445 | 445 | ||
446 | ide_pad_transfer(drive, rw, len); | 446 | ide_pad_transfer(drive, rw, len); |
447 | } else if (rw == 0 && ireason == 1) { | 447 | } else if (rw == 0 && ireason == 1) { |
448 | /* | 448 | /* |
449 | * Some drives (ASUS) seem to tell us that status info is | 449 | * Some drives (ASUS) seem to tell us that status info is |
450 | * available. Just get it and ignore. | 450 | * available. Just get it and ignore. |
451 | */ | 451 | */ |
452 | (void)hwif->tp_ops->read_status(hwif); | 452 | (void)hwif->tp_ops->read_status(hwif); |
453 | return 0; | 453 | return 0; |
454 | } else { | 454 | } else { |
455 | /* drive wants a command packet, or invalid ireason... */ | 455 | /* drive wants a command packet, or invalid ireason... */ |
456 | printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n", | 456 | printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n", |
457 | drive->name, __func__, ireason); | 457 | drive->name, __func__, ireason); |
458 | } | 458 | } |
459 | 459 | ||
460 | if (rq->cmd_type == REQ_TYPE_ATA_PC) | 460 | if (rq->cmd_type == REQ_TYPE_ATA_PC) |
461 | rq->cmd_flags |= REQ_FAILED; | 461 | rq->cmd_flags |= REQ_FAILED; |
462 | 462 | ||
463 | return -1; | 463 | return -1; |
464 | } | 464 | } |
465 | 465 | ||
466 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) | 466 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) |
467 | { | 467 | { |
468 | struct request *rq = cmd->rq; | 468 | struct request *rq = cmd->rq; |
469 | 469 | ||
470 | ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); | 470 | ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); |
471 | 471 | ||
472 | /* | 472 | /* |
473 | * Some of the trailing request sense fields are optional, | 473 | * Some of the trailing request sense fields are optional, |
474 | * and some drives don't send them. Sigh. | 474 | * and some drives don't send them. Sigh. |
475 | */ | 475 | */ |
476 | if (rq->cmd[0] == GPCMD_REQUEST_SENSE && | 476 | if (rq->cmd[0] == GPCMD_REQUEST_SENSE && |
477 | cmd->nleft > 0 && cmd->nleft <= 5) | 477 | cmd->nleft > 0 && cmd->nleft <= 5) |
478 | cmd->nleft = 0; | 478 | cmd->nleft = 0; |
479 | } | 479 | } |
480 | 480 | ||
481 | int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, | 481 | int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, |
482 | int write, void *buffer, unsigned *bufflen, | 482 | int write, void *buffer, unsigned *bufflen, |
483 | struct request_sense *sense, int timeout, | 483 | struct request_sense *sense, int timeout, |
484 | unsigned int cmd_flags) | 484 | unsigned int cmd_flags) |
485 | { | 485 | { |
486 | struct cdrom_info *info = drive->driver_data; | 486 | struct cdrom_info *info = drive->driver_data; |
487 | struct request_sense local_sense; | 487 | struct request_sense local_sense; |
488 | int retries = 10; | 488 | int retries = 10; |
489 | unsigned int flags = 0; | 489 | unsigned int flags = 0; |
490 | 490 | ||
491 | if (!sense) | 491 | if (!sense) |
492 | sense = &local_sense; | 492 | sense = &local_sense; |
493 | 493 | ||
494 | ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, " | 494 | ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, " |
495 | "cmd_flags: 0x%x", | 495 | "cmd_flags: 0x%x", |
496 | cmd[0], write, timeout, cmd_flags); | 496 | cmd[0], write, timeout, cmd_flags); |
497 | 497 | ||
498 | /* start of retry loop */ | 498 | /* start of retry loop */ |
499 | do { | 499 | do { |
500 | struct request *rq; | 500 | struct request *rq; |
501 | int error; | 501 | int error; |
502 | 502 | ||
503 | rq = blk_get_request(drive->queue, write, __GFP_WAIT); | 503 | rq = blk_get_request(drive->queue, write, __GFP_WAIT); |
504 | 504 | ||
505 | memcpy(rq->cmd, cmd, BLK_MAX_CDB); | 505 | memcpy(rq->cmd, cmd, BLK_MAX_CDB); |
506 | rq->cmd_type = REQ_TYPE_ATA_PC; | 506 | rq->cmd_type = REQ_TYPE_ATA_PC; |
507 | rq->sense = sense; | 507 | rq->sense = sense; |
508 | rq->cmd_flags |= cmd_flags; | 508 | rq->cmd_flags |= cmd_flags; |
509 | rq->timeout = timeout; | 509 | rq->timeout = timeout; |
510 | if (buffer) { | 510 | if (buffer) { |
511 | error = blk_rq_map_kern(drive->queue, rq, buffer, | 511 | error = blk_rq_map_kern(drive->queue, rq, buffer, |
512 | *bufflen, GFP_NOIO); | 512 | *bufflen, GFP_NOIO); |
513 | if (error) { | 513 | if (error) { |
514 | blk_put_request(rq); | 514 | blk_put_request(rq); |
515 | return error; | 515 | return error; |
516 | } | 516 | } |
517 | } | 517 | } |
518 | 518 | ||
519 | error = blk_execute_rq(drive->queue, info->disk, rq, 0); | 519 | error = blk_execute_rq(drive->queue, info->disk, rq, 0); |
520 | 520 | ||
521 | if (buffer) | 521 | if (buffer) |
522 | *bufflen = rq->resid_len; | 522 | *bufflen = rq->resid_len; |
523 | 523 | ||
524 | flags = rq->cmd_flags; | 524 | flags = rq->cmd_flags; |
525 | blk_put_request(rq); | 525 | blk_put_request(rq); |
526 | 526 | ||
527 | /* | 527 | /* |
528 | * FIXME: we should probably abort/retry or something in case of | 528 | * FIXME: we should probably abort/retry or something in case of |
529 | * failure. | 529 | * failure. |
530 | */ | 530 | */ |
531 | if (flags & REQ_FAILED) { | 531 | if (flags & REQ_FAILED) { |
532 | /* | 532 | /* |
533 | * The request failed. Retry if it was due to a unit | 533 | * The request failed. Retry if it was due to a unit |
534 | * attention status (usually means media was changed). | 534 | * attention status (usually means media was changed). |
535 | */ | 535 | */ |
536 | struct request_sense *reqbuf = sense; | 536 | struct request_sense *reqbuf = sense; |
537 | 537 | ||
538 | if (reqbuf->sense_key == UNIT_ATTENTION) | 538 | if (reqbuf->sense_key == UNIT_ATTENTION) |
539 | cdrom_saw_media_change(drive); | 539 | cdrom_saw_media_change(drive); |
540 | else if (reqbuf->sense_key == NOT_READY && | 540 | else if (reqbuf->sense_key == NOT_READY && |
541 | reqbuf->asc == 4 && reqbuf->ascq != 4) { | 541 | reqbuf->asc == 4 && reqbuf->ascq != 4) { |
542 | /* | 542 | /* |
543 | * The drive is in the process of loading | 543 | * The drive is in the process of loading |
544 | * a disk. Retry, but wait a little to give | 544 | * a disk. Retry, but wait a little to give |
545 | * the drive time to complete the load. | 545 | * the drive time to complete the load. |
546 | */ | 546 | */ |
547 | ssleep(2); | 547 | ssleep(2); |
548 | } else { | 548 | } else { |
549 | /* otherwise, don't retry */ | 549 | /* otherwise, don't retry */ |
550 | retries = 0; | 550 | retries = 0; |
551 | } | 551 | } |
552 | --retries; | 552 | --retries; |
553 | } | 553 | } |
554 | 554 | ||
555 | /* end of retry loop */ | 555 | /* end of retry loop */ |
556 | } while ((flags & REQ_FAILED) && retries >= 0); | 556 | } while ((flags & REQ_FAILED) && retries >= 0); |
557 | 557 | ||
558 | /* return an error if the command failed */ | 558 | /* return an error if the command failed */ |
559 | return (flags & REQ_FAILED) ? -EIO : 0; | 559 | return (flags & REQ_FAILED) ? -EIO : 0; |
560 | } | 560 | } |
561 | 561 | ||
562 | static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) | 562 | static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd) |
563 | { | 563 | { |
564 | unsigned int nr_bytes = cmd->nbytes - cmd->nleft; | 564 | unsigned int nr_bytes = cmd->nbytes - cmd->nleft; |
565 | 565 | ||
566 | if (cmd->tf_flags & IDE_TFLAG_WRITE) | 566 | if (cmd->tf_flags & IDE_TFLAG_WRITE) |
567 | nr_bytes -= cmd->last_xfer_len; | 567 | nr_bytes -= cmd->last_xfer_len; |
568 | 568 | ||
569 | if (nr_bytes > 0) | 569 | if (nr_bytes > 0) |
570 | ide_complete_rq(drive, 0, nr_bytes); | 570 | ide_complete_rq(drive, 0, nr_bytes); |
571 | } | 571 | } |
572 | 572 | ||
573 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | 573 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) |
574 | { | 574 | { |
575 | ide_hwif_t *hwif = drive->hwif; | 575 | ide_hwif_t *hwif = drive->hwif; |
576 | struct ide_cmd *cmd = &hwif->cmd; | 576 | struct ide_cmd *cmd = &hwif->cmd; |
577 | struct request *rq = hwif->rq; | 577 | struct request *rq = hwif->rq; |
578 | ide_expiry_t *expiry = NULL; | 578 | ide_expiry_t *expiry = NULL; |
579 | int dma_error = 0, dma, thislen, uptodate = 0; | 579 | int dma_error = 0, dma, thislen, uptodate = 0; |
580 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0, nsectors; | 580 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0; |
581 | int sense = blk_sense_request(rq); | 581 | int sense = blk_sense_request(rq); |
582 | unsigned int timeout; | 582 | unsigned int timeout; |
583 | u16 len; | 583 | u16 len; |
584 | u8 ireason, stat; | 584 | u8 ireason, stat; |
585 | 585 | ||
586 | ide_debug_log(IDE_DBG_PC, "cmd: 0x%x, write: 0x%x", rq->cmd[0], write); | 586 | ide_debug_log(IDE_DBG_PC, "cmd: 0x%x, write: 0x%x", rq->cmd[0], write); |
587 | 587 | ||
588 | /* check for errors */ | 588 | /* check for errors */ |
589 | dma = drive->dma; | 589 | dma = drive->dma; |
590 | if (dma) { | 590 | if (dma) { |
591 | drive->dma = 0; | 591 | drive->dma = 0; |
592 | drive->waiting_for_dma = 0; | 592 | drive->waiting_for_dma = 0; |
593 | dma_error = hwif->dma_ops->dma_end(drive); | 593 | dma_error = hwif->dma_ops->dma_end(drive); |
594 | ide_dma_unmap_sg(drive, cmd); | 594 | ide_dma_unmap_sg(drive, cmd); |
595 | if (dma_error) { | 595 | if (dma_error) { |
596 | printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, | 596 | printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, |
597 | write ? "write" : "read"); | 597 | write ? "write" : "read"); |
598 | ide_dma_off(drive); | 598 | ide_dma_off(drive); |
599 | } | 599 | } |
600 | } | 600 | } |
601 | 601 | ||
602 | /* check status */ | 602 | /* check status */ |
603 | stat = hwif->tp_ops->read_status(hwif); | 603 | stat = hwif->tp_ops->read_status(hwif); |
604 | 604 | ||
605 | if (!OK_STAT(stat, 0, BAD_R_STAT)) { | 605 | if (!OK_STAT(stat, 0, BAD_R_STAT)) { |
606 | rc = cdrom_decode_status(drive, stat); | 606 | rc = cdrom_decode_status(drive, stat); |
607 | if (rc) { | 607 | if (rc) { |
608 | if (rc == 2) | 608 | if (rc == 2) |
609 | goto out_end; | 609 | goto out_end; |
610 | return ide_stopped; | 610 | return ide_stopped; |
611 | } | 611 | } |
612 | } | 612 | } |
613 | 613 | ||
614 | /* using dma, transfer is complete now */ | 614 | /* using dma, transfer is complete now */ |
615 | if (dma) { | 615 | if (dma) { |
616 | if (dma_error) | 616 | if (dma_error) |
617 | return ide_error(drive, "dma error", stat); | 617 | return ide_error(drive, "dma error", stat); |
618 | uptodate = 1; | 618 | uptodate = 1; |
619 | goto out_end; | 619 | goto out_end; |
620 | } | 620 | } |
621 | 621 | ||
622 | ide_read_bcount_and_ireason(drive, &len, &ireason); | 622 | ide_read_bcount_and_ireason(drive, &len, &ireason); |
623 | 623 | ||
624 | thislen = blk_fs_request(rq) ? len : cmd->nleft; | 624 | thislen = blk_fs_request(rq) ? len : cmd->nleft; |
625 | if (thislen > len) | 625 | if (thislen > len) |
626 | thislen = len; | 626 | thislen = len; |
627 | 627 | ||
628 | ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d", | 628 | ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d", |
629 | stat, thislen); | 629 | stat, thislen); |
630 | 630 | ||
631 | /* If DRQ is clear, the command has completed. */ | 631 | /* If DRQ is clear, the command has completed. */ |
632 | if ((stat & ATA_DRQ) == 0) { | 632 | if ((stat & ATA_DRQ) == 0) { |
633 | if (blk_fs_request(rq)) { | 633 | if (blk_fs_request(rq)) { |
634 | /* | 634 | /* |
635 | * If we're not done reading/writing, complain. | 635 | * If we're not done reading/writing, complain. |
636 | * Otherwise, complete the command normally. | 636 | * Otherwise, complete the command normally. |
637 | */ | 637 | */ |
638 | uptodate = 1; | 638 | uptodate = 1; |
639 | if (cmd->nleft > 0) { | 639 | if (cmd->nleft > 0) { |
640 | printk(KERN_ERR PFX "%s: %s: data underrun " | 640 | printk(KERN_ERR PFX "%s: %s: data underrun " |
641 | "(%u bytes)\n", drive->name, __func__, | 641 | "(%u bytes)\n", drive->name, __func__, |
642 | cmd->nleft); | 642 | cmd->nleft); |
643 | if (!write) | 643 | if (!write) |
644 | rq->cmd_flags |= REQ_FAILED; | 644 | rq->cmd_flags |= REQ_FAILED; |
645 | uptodate = 0; | 645 | uptodate = 0; |
646 | } | 646 | } |
647 | } else if (!blk_pc_request(rq)) { | 647 | } else if (!blk_pc_request(rq)) { |
648 | ide_cd_request_sense_fixup(drive, cmd); | 648 | ide_cd_request_sense_fixup(drive, cmd); |
649 | /* complain if we still have data left to transfer */ | 649 | /* complain if we still have data left to transfer */ |
650 | uptodate = cmd->nleft ? 0 : 1; | 650 | uptodate = cmd->nleft ? 0 : 1; |
651 | if (uptodate == 0) | 651 | if (uptodate == 0) |
652 | rq->cmd_flags |= REQ_FAILED; | 652 | rq->cmd_flags |= REQ_FAILED; |
653 | } | 653 | } |
654 | goto out_end; | 654 | goto out_end; |
655 | } | 655 | } |
656 | 656 | ||
657 | /* check which way to transfer data */ | 657 | /* check which way to transfer data */ |
658 | rc = ide_cd_check_ireason(drive, rq, len, ireason, write); | 658 | rc = ide_cd_check_ireason(drive, rq, len, ireason, write); |
659 | if (rc) | 659 | if (rc) |
660 | goto out_end; | 660 | goto out_end; |
661 | 661 | ||
662 | cmd->last_xfer_len = 0; | 662 | cmd->last_xfer_len = 0; |
663 | 663 | ||
664 | ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, " | 664 | ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, " |
665 | "ireason: 0x%x", | 665 | "ireason: 0x%x", |
666 | rq->cmd_type, ireason); | 666 | rq->cmd_type, ireason); |
667 | 667 | ||
668 | /* transfer data */ | 668 | /* transfer data */ |
669 | while (thislen > 0) { | 669 | while (thislen > 0) { |
670 | int blen = min_t(int, thislen, cmd->nleft); | 670 | int blen = min_t(int, thislen, cmd->nleft); |
671 | 671 | ||
672 | if (cmd->nleft == 0) | 672 | if (cmd->nleft == 0) |
673 | break; | 673 | break; |
674 | 674 | ||
675 | ide_pio_bytes(drive, cmd, write, blen); | 675 | ide_pio_bytes(drive, cmd, write, blen); |
676 | cmd->last_xfer_len += blen; | 676 | cmd->last_xfer_len += blen; |
677 | 677 | ||
678 | thislen -= blen; | 678 | thislen -= blen; |
679 | len -= blen; | 679 | len -= blen; |
680 | 680 | ||
681 | if (sense && write == 0) | 681 | if (sense && write == 0) |
682 | rq->sense_len += blen; | 682 | rq->sense_len += blen; |
683 | } | 683 | } |
684 | 684 | ||
685 | /* pad, if necessary */ | 685 | /* pad, if necessary */ |
686 | if (len > 0) { | 686 | if (len > 0) { |
687 | if (blk_fs_request(rq) == 0 || write == 0) | 687 | if (blk_fs_request(rq) == 0 || write == 0) |
688 | ide_pad_transfer(drive, write, len); | 688 | ide_pad_transfer(drive, write, len); |
689 | else { | 689 | else { |
690 | printk(KERN_ERR PFX "%s: confused, missing data\n", | 690 | printk(KERN_ERR PFX "%s: confused, missing data\n", |
691 | drive->name); | 691 | drive->name); |
692 | blk_dump_rq_flags(rq, "cdrom_newpc_intr"); | 692 | blk_dump_rq_flags(rq, "cdrom_newpc_intr"); |
693 | } | 693 | } |
694 | } | 694 | } |
695 | 695 | ||
696 | if (blk_pc_request(rq)) { | 696 | if (blk_pc_request(rq)) { |
697 | timeout = rq->timeout; | 697 | timeout = rq->timeout; |
698 | } else { | 698 | } else { |
699 | timeout = ATAPI_WAIT_PC; | 699 | timeout = ATAPI_WAIT_PC; |
700 | if (!blk_fs_request(rq)) | 700 | if (!blk_fs_request(rq)) |
701 | expiry = ide_cd_expiry; | 701 | expiry = ide_cd_expiry; |
702 | } | 702 | } |
703 | 703 | ||
704 | hwif->expiry = expiry; | 704 | hwif->expiry = expiry; |
705 | ide_set_handler(drive, cdrom_newpc_intr, timeout); | 705 | ide_set_handler(drive, cdrom_newpc_intr, timeout); |
706 | return ide_started; | 706 | return ide_started; |
707 | 707 | ||
708 | out_end: | 708 | out_end: |
709 | if (blk_pc_request(rq) && rc == 0) { | 709 | if (blk_pc_request(rq) && rc == 0) { |
710 | if (blk_end_request(rq, 0, rq->data_len)) | 710 | blk_end_request_all(rq, 0); |
711 | BUG(); | ||
712 | |||
713 | hwif->rq = NULL; | 711 | hwif->rq = NULL; |
714 | } else { | 712 | } else { |
715 | if (sense && uptodate) | 713 | if (sense && uptodate) |
716 | ide_cd_complete_failed_rq(drive, rq); | 714 | ide_cd_complete_failed_rq(drive, rq); |
717 | 715 | ||
718 | if (blk_fs_request(rq)) { | 716 | if (blk_fs_request(rq)) { |
719 | if (cmd->nleft == 0) | 717 | if (cmd->nleft == 0) |
720 | uptodate = 1; | 718 | uptodate = 1; |
721 | } else { | 719 | } else { |
722 | if (uptodate <= 0 && rq->errors == 0) | 720 | if (uptodate <= 0 && rq->errors == 0) |
723 | rq->errors = -EIO; | 721 | rq->errors = -EIO; |
724 | } | 722 | } |
725 | 723 | ||
726 | if (uptodate == 0) | 724 | if (uptodate == 0) |
727 | ide_cd_error_cmd(drive, cmd); | 725 | ide_cd_error_cmd(drive, cmd); |
728 | 726 | ||
729 | /* make sure it's fully ended */ | 727 | /* make sure it's fully ended */ |
730 | if (blk_pc_request(rq)) | ||
731 | nsectors = (rq->data_len + 511) >> 9; | ||
732 | else | ||
733 | nsectors = blk_rq_sectors(rq); | ||
734 | |||
735 | if (nsectors == 0) | ||
736 | nsectors = 1; | ||
737 | |||
738 | if (blk_fs_request(rq) == 0) { | 728 | if (blk_fs_request(rq) == 0) { |
739 | rq->resid_len = rq->data_len - | 729 | rq->resid_len = blk_rq_bytes(rq) - |
740 | (cmd->nbytes - cmd->nleft); | 730 | (cmd->nbytes - cmd->nleft); |
741 | if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) | 731 | if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) |
742 | rq->resid_len += cmd->last_xfer_len; | 732 | rq->resid_len += cmd->last_xfer_len; |
743 | } | 733 | } |
744 | 734 | ||
745 | ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); | 735 | ide_complete_rq(drive, uptodate ? 0 : -EIO, blk_rq_bytes(rq)); |
746 | 736 | ||
747 | if (sense && rc == 2) | 737 | if (sense && rc == 2) |
748 | ide_error(drive, "request sense failure", stat); | 738 | ide_error(drive, "request sense failure", stat); |
749 | } | 739 | } |
750 | return ide_stopped; | 740 | return ide_stopped; |
751 | } | 741 | } |
752 | 742 | ||
753 | static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) | 743 | static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) |
754 | { | 744 | { |
755 | struct cdrom_info *cd = drive->driver_data; | 745 | struct cdrom_info *cd = drive->driver_data; |
756 | struct request_queue *q = drive->queue; | 746 | struct request_queue *q = drive->queue; |
757 | int write = rq_data_dir(rq) == WRITE; | 747 | int write = rq_data_dir(rq) == WRITE; |
758 | unsigned short sectors_per_frame = | 748 | unsigned short sectors_per_frame = |
759 | queue_hardsect_size(q) >> SECTOR_BITS; | 749 | queue_hardsect_size(q) >> SECTOR_BITS; |
760 | 750 | ||
761 | ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, " | 751 | ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, " |
762 | "secs_per_frame: %u", | 752 | "secs_per_frame: %u", |
763 | rq->cmd[0], rq->cmd_flags, sectors_per_frame); | 753 | rq->cmd[0], rq->cmd_flags, sectors_per_frame); |
764 | 754 | ||
765 | if (write) { | 755 | if (write) { |
766 | /* disk has become write protected */ | 756 | /* disk has become write protected */ |
767 | if (get_disk_ro(cd->disk)) | 757 | if (get_disk_ro(cd->disk)) |
768 | return ide_stopped; | 758 | return ide_stopped; |
769 | } else { | 759 | } else { |
770 | /* | 760 | /* |
771 | * We may be retrying this request after an error. Fix up any | 761 | * We may be retrying this request after an error. Fix up any |
772 | * weirdness which might be present in the request packet. | 762 | * weirdness which might be present in the request packet. |
773 | */ | 763 | */ |
774 | q->prep_rq_fn(q, rq); | 764 | q->prep_rq_fn(q, rq); |
775 | } | 765 | } |
776 | 766 | ||
777 | /* fs requests *must* be hardware frame aligned */ | 767 | /* fs requests *must* be hardware frame aligned */ |
778 | if ((blk_rq_sectors(rq) & (sectors_per_frame - 1)) || | 768 | if ((blk_rq_sectors(rq) & (sectors_per_frame - 1)) || |
779 | (blk_rq_pos(rq) & (sectors_per_frame - 1))) | 769 | (blk_rq_pos(rq) & (sectors_per_frame - 1))) |
780 | return ide_stopped; | 770 | return ide_stopped; |
781 | 771 | ||
782 | /* use DMA, if possible */ | 772 | /* use DMA, if possible */ |
783 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | 773 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); |
784 | 774 | ||
785 | if (write) | 775 | if (write) |
786 | cd->devinfo.media_written = 1; | 776 | cd->devinfo.media_written = 1; |
787 | 777 | ||
788 | rq->timeout = ATAPI_WAIT_PC; | 778 | rq->timeout = ATAPI_WAIT_PC; |
789 | 779 | ||
790 | return ide_started; | 780 | return ide_started; |
791 | } | 781 | } |
792 | 782 | ||
793 | static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | 783 | static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) |
794 | { | 784 | { |
795 | 785 | ||
796 | ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x", | 786 | ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x", |
797 | rq->cmd[0], rq->cmd_type); | 787 | rq->cmd[0], rq->cmd_type); |
798 | 788 | ||
799 | if (blk_pc_request(rq)) | 789 | if (blk_pc_request(rq)) |
800 | rq->cmd_flags |= REQ_QUIET; | 790 | rq->cmd_flags |= REQ_QUIET; |
801 | else | 791 | else |
802 | rq->cmd_flags &= ~REQ_FAILED; | 792 | rq->cmd_flags &= ~REQ_FAILED; |
803 | 793 | ||
804 | drive->dma = 0; | 794 | drive->dma = 0; |
805 | 795 | ||
806 | /* sg request */ | 796 | /* sg request */ |
807 | if (rq->bio) { | 797 | if (rq->bio) { |
808 | struct request_queue *q = drive->queue; | 798 | struct request_queue *q = drive->queue; |
809 | char *buf = bio_data(rq->bio); | 799 | char *buf = bio_data(rq->bio); |
810 | unsigned int alignment; | 800 | unsigned int alignment; |
811 | 801 | ||
812 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | 802 | drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); |
813 | 803 | ||
814 | /* | 804 | /* |
815 | * check if dma is safe | 805 | * check if dma is safe |
816 | * | 806 | * |
817 | * NOTE! The "len" and "addr" checks should possibly have | 807 | * NOTE! The "len" and "addr" checks should possibly have |
818 | * separate masks. | 808 | * separate masks. |
819 | */ | 809 | */ |
820 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; | 810 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; |
821 | if ((unsigned long)buf & alignment | 811 | if ((unsigned long)buf & alignment |
822 | || rq->data_len & q->dma_pad_mask | 812 | || blk_rq_bytes(rq) & q->dma_pad_mask |
823 | || object_is_on_stack(buf)) | 813 | || object_is_on_stack(buf)) |
824 | drive->dma = 0; | 814 | drive->dma = 0; |
825 | } | 815 | } |
826 | } | 816 | } |
827 | 817 | ||
828 | static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | 818 | static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, |
829 | sector_t block) | 819 | sector_t block) |
830 | { | 820 | { |
831 | struct ide_cmd cmd; | 821 | struct ide_cmd cmd; |
832 | int uptodate = 0, nsectors; | 822 | int uptodate = 0, nsectors; |
833 | 823 | ||
834 | ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu", | 824 | ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu", |
835 | rq->cmd[0], (unsigned long long)block); | 825 | rq->cmd[0], (unsigned long long)block); |
836 | 826 | ||
837 | if (drive->debug_mask & IDE_DBG_RQ) | 827 | if (drive->debug_mask & IDE_DBG_RQ) |
838 | blk_dump_rq_flags(rq, "ide_cd_do_request"); | 828 | blk_dump_rq_flags(rq, "ide_cd_do_request"); |
839 | 829 | ||
840 | if (blk_fs_request(rq)) { | 830 | if (blk_fs_request(rq)) { |
841 | if (cdrom_start_rw(drive, rq) == ide_stopped) | 831 | if (cdrom_start_rw(drive, rq) == ide_stopped) |
842 | goto out_end; | 832 | goto out_end; |
843 | } else if (blk_sense_request(rq) || blk_pc_request(rq) || | 833 | } else if (blk_sense_request(rq) || blk_pc_request(rq) || |
844 | rq->cmd_type == REQ_TYPE_ATA_PC) { | 834 | rq->cmd_type == REQ_TYPE_ATA_PC) { |
845 | if (!rq->timeout) | 835 | if (!rq->timeout) |
846 | rq->timeout = ATAPI_WAIT_PC; | 836 | rq->timeout = ATAPI_WAIT_PC; |
847 | 837 | ||
848 | cdrom_do_block_pc(drive, rq); | 838 | cdrom_do_block_pc(drive, rq); |
849 | } else if (blk_special_request(rq)) { | 839 | } else if (blk_special_request(rq)) { |
850 | /* right now this can only be a reset... */ | 840 | /* right now this can only be a reset... */ |
851 | uptodate = 1; | 841 | uptodate = 1; |
852 | goto out_end; | 842 | goto out_end; |
853 | } else { | 843 | } else { |
854 | blk_dump_rq_flags(rq, DRV_NAME " bad flags"); | 844 | blk_dump_rq_flags(rq, DRV_NAME " bad flags"); |
855 | if (rq->errors == 0) | 845 | if (rq->errors == 0) |
856 | rq->errors = -EIO; | 846 | rq->errors = -EIO; |
857 | goto out_end; | 847 | goto out_end; |
858 | } | 848 | } |
859 | 849 | ||
860 | /* prepare sense request for this command */ | 850 | /* prepare sense request for this command */ |
861 | ide_prep_sense(drive, rq); | 851 | ide_prep_sense(drive, rq); |
862 | 852 | ||
863 | memset(&cmd, 0, sizeof(cmd)); | 853 | memset(&cmd, 0, sizeof(cmd)); |
864 | 854 | ||
865 | if (rq_data_dir(rq)) | 855 | if (rq_data_dir(rq)) |
866 | cmd.tf_flags |= IDE_TFLAG_WRITE; | 856 | cmd.tf_flags |= IDE_TFLAG_WRITE; |
867 | 857 | ||
868 | cmd.rq = rq; | 858 | cmd.rq = rq; |
869 | 859 | ||
870 | if (blk_fs_request(rq) || rq->data_len) { | 860 | if (blk_fs_request(rq) || blk_rq_bytes(rq)) { |
871 | ide_init_sg_cmd(&cmd, blk_fs_request(rq) ? | 861 | ide_init_sg_cmd(&cmd, blk_rq_bytes(rq)); |
872 | (blk_rq_sectors(rq) << 9) : rq->data_len); | ||
873 | ide_map_sg(drive, &cmd); | 862 | ide_map_sg(drive, &cmd); |
874 | } | 863 | } |
875 | 864 | ||
876 | return ide_issue_pc(drive, &cmd); | 865 | return ide_issue_pc(drive, &cmd); |
877 | out_end: | 866 | out_end: |
878 | nsectors = blk_rq_sectors(rq); | 867 | nsectors = blk_rq_sectors(rq); |
879 | 868 | ||
880 | if (nsectors == 0) | 869 | if (nsectors == 0) |
881 | nsectors = 1; | 870 | nsectors = 1; |
882 | 871 | ||
883 | ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); | 872 | ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); |
884 | 873 | ||
885 | return ide_stopped; | 874 | return ide_stopped; |
886 | } | 875 | } |
887 | 876 | ||
888 | /* | 877 | /* |
889 | * Ioctl handling. | 878 | * Ioctl handling. |
890 | * | 879 | * |
891 | * Routines which queue packet commands take as a final argument a pointer to a | 880 | * Routines which queue packet commands take as a final argument a pointer to a |
892 | * request_sense struct. If execution of the command results in an error with a | 881 | * request_sense struct. If execution of the command results in an error with a |
893 | * CHECK CONDITION status, this structure will be filled with the results of the | 882 | * CHECK CONDITION status, this structure will be filled with the results of the |
894 | * subsequent request sense command. The pointer can also be NULL, in which case | 883 | * subsequent request sense command. The pointer can also be NULL, in which case |
895 | * no sense information is returned. | 884 | * no sense information is returned. |
896 | */ | 885 | */ |
897 | static void msf_from_bcd(struct atapi_msf *msf) | 886 | static void msf_from_bcd(struct atapi_msf *msf) |
898 | { | 887 | { |
899 | msf->minute = bcd2bin(msf->minute); | 888 | msf->minute = bcd2bin(msf->minute); |
900 | msf->second = bcd2bin(msf->second); | 889 | msf->second = bcd2bin(msf->second); |
901 | msf->frame = bcd2bin(msf->frame); | 890 | msf->frame = bcd2bin(msf->frame); |
902 | } | 891 | } |
903 | 892 | ||
904 | int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) | 893 | int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) |
905 | { | 894 | { |
906 | struct cdrom_info *info = drive->driver_data; | 895 | struct cdrom_info *info = drive->driver_data; |
907 | struct cdrom_device_info *cdi = &info->devinfo; | 896 | struct cdrom_device_info *cdi = &info->devinfo; |
908 | unsigned char cmd[BLK_MAX_CDB]; | 897 | unsigned char cmd[BLK_MAX_CDB]; |
909 | 898 | ||
910 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 899 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
911 | 900 | ||
912 | memset(cmd, 0, BLK_MAX_CDB); | 901 | memset(cmd, 0, BLK_MAX_CDB); |
913 | cmd[0] = GPCMD_TEST_UNIT_READY; | 902 | cmd[0] = GPCMD_TEST_UNIT_READY; |
914 | 903 | ||
915 | /* | 904 | /* |
916 | * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs | 905 | * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs |
917 | * instead of supporting the LOAD_UNLOAD opcode. | 906 | * instead of supporting the LOAD_UNLOAD opcode. |
918 | */ | 907 | */ |
919 | cmd[7] = cdi->sanyo_slot % 3; | 908 | cmd[7] = cdi->sanyo_slot % 3; |
920 | 909 | ||
921 | return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, REQ_QUIET); | 910 | return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, REQ_QUIET); |
922 | } | 911 | } |
923 | 912 | ||
924 | static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | 913 | static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, |
925 | unsigned long *sectors_per_frame, | 914 | unsigned long *sectors_per_frame, |
926 | struct request_sense *sense) | 915 | struct request_sense *sense) |
927 | { | 916 | { |
928 | struct { | 917 | struct { |
929 | __be32 lba; | 918 | __be32 lba; |
930 | __be32 blocklen; | 919 | __be32 blocklen; |
931 | } capbuf; | 920 | } capbuf; |
932 | 921 | ||
933 | int stat; | 922 | int stat; |
934 | unsigned char cmd[BLK_MAX_CDB]; | 923 | unsigned char cmd[BLK_MAX_CDB]; |
935 | unsigned len = sizeof(capbuf); | 924 | unsigned len = sizeof(capbuf); |
936 | u32 blocklen; | 925 | u32 blocklen; |
937 | 926 | ||
938 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 927 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
939 | 928 | ||
940 | memset(cmd, 0, BLK_MAX_CDB); | 929 | memset(cmd, 0, BLK_MAX_CDB); |
941 | cmd[0] = GPCMD_READ_CDVD_CAPACITY; | 930 | cmd[0] = GPCMD_READ_CDVD_CAPACITY; |
942 | 931 | ||
943 | stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0, | 932 | stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0, |
944 | REQ_QUIET); | 933 | REQ_QUIET); |
945 | if (stat) | 934 | if (stat) |
946 | return stat; | 935 | return stat; |
947 | 936 | ||
948 | /* | 937 | /* |
949 | * Sanity check the given block size | 938 | * Sanity check the given block size |
950 | */ | 939 | */ |
951 | blocklen = be32_to_cpu(capbuf.blocklen); | 940 | blocklen = be32_to_cpu(capbuf.blocklen); |
952 | switch (blocklen) { | 941 | switch (blocklen) { |
953 | case 512: | 942 | case 512: |
954 | case 1024: | 943 | case 1024: |
955 | case 2048: | 944 | case 2048: |
956 | case 4096: | 945 | case 4096: |
957 | break; | 946 | break; |
958 | default: | 947 | default: |
959 | printk(KERN_ERR PFX "%s: weird block size %u\n", | 948 | printk(KERN_ERR PFX "%s: weird block size %u\n", |
960 | drive->name, blocklen); | 949 | drive->name, blocklen); |
961 | printk(KERN_ERR PFX "%s: default to 2kb block size\n", | 950 | printk(KERN_ERR PFX "%s: default to 2kb block size\n", |
962 | drive->name); | 951 | drive->name); |
963 | blocklen = 2048; | 952 | blocklen = 2048; |
964 | break; | 953 | break; |
965 | } | 954 | } |
966 | 955 | ||
967 | *capacity = 1 + be32_to_cpu(capbuf.lba); | 956 | *capacity = 1 + be32_to_cpu(capbuf.lba); |
968 | *sectors_per_frame = blocklen >> SECTOR_BITS; | 957 | *sectors_per_frame = blocklen >> SECTOR_BITS; |
969 | 958 | ||
970 | ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu", | 959 | ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu", |
971 | *capacity, *sectors_per_frame); | 960 | *capacity, *sectors_per_frame); |
972 | 961 | ||
973 | return 0; | 962 | return 0; |
974 | } | 963 | } |
975 | 964 | ||
976 | static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, | 965 | static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, |
977 | int format, char *buf, int buflen, | 966 | int format, char *buf, int buflen, |
978 | struct request_sense *sense) | 967 | struct request_sense *sense) |
979 | { | 968 | { |
980 | unsigned char cmd[BLK_MAX_CDB]; | 969 | unsigned char cmd[BLK_MAX_CDB]; |
981 | 970 | ||
982 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 971 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
983 | 972 | ||
984 | memset(cmd, 0, BLK_MAX_CDB); | 973 | memset(cmd, 0, BLK_MAX_CDB); |
985 | 974 | ||
986 | cmd[0] = GPCMD_READ_TOC_PMA_ATIP; | 975 | cmd[0] = GPCMD_READ_TOC_PMA_ATIP; |
987 | cmd[6] = trackno; | 976 | cmd[6] = trackno; |
988 | cmd[7] = (buflen >> 8); | 977 | cmd[7] = (buflen >> 8); |
989 | cmd[8] = (buflen & 0xff); | 978 | cmd[8] = (buflen & 0xff); |
990 | cmd[9] = (format << 6); | 979 | cmd[9] = (format << 6); |
991 | 980 | ||
992 | if (msf_flag) | 981 | if (msf_flag) |
993 | cmd[1] = 2; | 982 | cmd[1] = 2; |
994 | 983 | ||
995 | return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET); | 984 | return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET); |
996 | } | 985 | } |
997 | 986 | ||
998 | /* Try to read the entire TOC for the disk into our internal buffer. */ | 987 | /* Try to read the entire TOC for the disk into our internal buffer. */ |
999 | int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) | 988 | int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) |
1000 | { | 989 | { |
1001 | int stat, ntracks, i; | 990 | int stat, ntracks, i; |
1002 | struct cdrom_info *info = drive->driver_data; | 991 | struct cdrom_info *info = drive->driver_data; |
1003 | struct cdrom_device_info *cdi = &info->devinfo; | 992 | struct cdrom_device_info *cdi = &info->devinfo; |
1004 | struct atapi_toc *toc = info->toc; | 993 | struct atapi_toc *toc = info->toc; |
1005 | struct { | 994 | struct { |
1006 | struct atapi_toc_header hdr; | 995 | struct atapi_toc_header hdr; |
1007 | struct atapi_toc_entry ent; | 996 | struct atapi_toc_entry ent; |
1008 | } ms_tmp; | 997 | } ms_tmp; |
1009 | long last_written; | 998 | long last_written; |
1010 | unsigned long sectors_per_frame = SECTORS_PER_FRAME; | 999 | unsigned long sectors_per_frame = SECTORS_PER_FRAME; |
1011 | 1000 | ||
1012 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 1001 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
1013 | 1002 | ||
1014 | if (toc == NULL) { | 1003 | if (toc == NULL) { |
1015 | /* try to allocate space */ | 1004 | /* try to allocate space */ |
1016 | toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL); | 1005 | toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL); |
1017 | if (toc == NULL) { | 1006 | if (toc == NULL) { |
1018 | printk(KERN_ERR PFX "%s: No cdrom TOC buffer!\n", | 1007 | printk(KERN_ERR PFX "%s: No cdrom TOC buffer!\n", |
1019 | drive->name); | 1008 | drive->name); |
1020 | return -ENOMEM; | 1009 | return -ENOMEM; |
1021 | } | 1010 | } |
1022 | info->toc = toc; | 1011 | info->toc = toc; |
1023 | } | 1012 | } |
1024 | 1013 | ||
1025 | /* | 1014 | /* |
1026 | * Check to see if the existing data is still valid. If it is, | 1015 | * Check to see if the existing data is still valid. If it is, |
1027 | * just return. | 1016 | * just return. |
1028 | */ | 1017 | */ |
1029 | (void) cdrom_check_status(drive, sense); | 1018 | (void) cdrom_check_status(drive, sense); |
1030 | 1019 | ||
1031 | if (drive->atapi_flags & IDE_AFLAG_TOC_VALID) | 1020 | if (drive->atapi_flags & IDE_AFLAG_TOC_VALID) |
1032 | return 0; | 1021 | return 0; |
1033 | 1022 | ||
1034 | /* try to get the total cdrom capacity and sector size */ | 1023 | /* try to get the total cdrom capacity and sector size */ |
1035 | stat = cdrom_read_capacity(drive, &toc->capacity, §ors_per_frame, | 1024 | stat = cdrom_read_capacity(drive, &toc->capacity, §ors_per_frame, |
1036 | sense); | 1025 | sense); |
1037 | if (stat) | 1026 | if (stat) |
1038 | toc->capacity = 0x1fffff; | 1027 | toc->capacity = 0x1fffff; |
1039 | 1028 | ||
1040 | set_capacity(info->disk, toc->capacity * sectors_per_frame); | 1029 | set_capacity(info->disk, toc->capacity * sectors_per_frame); |
1041 | /* save a private copy of the TOC capacity for error handling */ | 1030 | /* save a private copy of the TOC capacity for error handling */ |
1042 | drive->probed_capacity = toc->capacity * sectors_per_frame; | 1031 | drive->probed_capacity = toc->capacity * sectors_per_frame; |
1043 | 1032 | ||
1044 | blk_queue_hardsect_size(drive->queue, | 1033 | blk_queue_hardsect_size(drive->queue, |
1045 | sectors_per_frame << SECTOR_BITS); | 1034 | sectors_per_frame << SECTOR_BITS); |
1046 | 1035 | ||
1047 | /* first read just the header, so we know how long the TOC is */ | 1036 | /* first read just the header, so we know how long the TOC is */ |
1048 | stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr, | 1037 | stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr, |
1049 | sizeof(struct atapi_toc_header), sense); | 1038 | sizeof(struct atapi_toc_header), sense); |
1050 | if (stat) | 1039 | if (stat) |
1051 | return stat; | 1040 | return stat; |
1052 | 1041 | ||
1053 | if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) { | 1042 | if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) { |
1054 | toc->hdr.first_track = bcd2bin(toc->hdr.first_track); | 1043 | toc->hdr.first_track = bcd2bin(toc->hdr.first_track); |
1055 | toc->hdr.last_track = bcd2bin(toc->hdr.last_track); | 1044 | toc->hdr.last_track = bcd2bin(toc->hdr.last_track); |
1056 | } | 1045 | } |
1057 | 1046 | ||
1058 | ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; | 1047 | ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; |
1059 | if (ntracks <= 0) | 1048 | if (ntracks <= 0) |
1060 | return -EIO; | 1049 | return -EIO; |
1061 | if (ntracks > MAX_TRACKS) | 1050 | if (ntracks > MAX_TRACKS) |
1062 | ntracks = MAX_TRACKS; | 1051 | ntracks = MAX_TRACKS; |
1063 | 1052 | ||
1064 | /* now read the whole schmeer */ | 1053 | /* now read the whole schmeer */ |
1065 | stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0, | 1054 | stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0, |
1066 | (char *)&toc->hdr, | 1055 | (char *)&toc->hdr, |
1067 | sizeof(struct atapi_toc_header) + | 1056 | sizeof(struct atapi_toc_header) + |
1068 | (ntracks + 1) * | 1057 | (ntracks + 1) * |
1069 | sizeof(struct atapi_toc_entry), sense); | 1058 | sizeof(struct atapi_toc_entry), sense); |
1070 | 1059 | ||
1071 | if (stat && toc->hdr.first_track > 1) { | 1060 | if (stat && toc->hdr.first_track > 1) { |
1072 | /* | 1061 | /* |
1073 | * Cds with CDI tracks only don't have any TOC entries, despite | 1062 | * Cds with CDI tracks only don't have any TOC entries, despite |
1074 | * of this the returned values are | 1063 | * of this the returned values are |
1075 | * first_track == last_track = number of CDI tracks + 1, | 1064 | * first_track == last_track = number of CDI tracks + 1, |
1076 | * so that this case is indistinguishable from the same layout | 1065 | * so that this case is indistinguishable from the same layout |
1077 | * plus an additional audio track. If we get an error for the | 1066 | * plus an additional audio track. If we get an error for the |
1078 | * regular case, we assume a CDI without additional audio | 1067 | * regular case, we assume a CDI without additional audio |
1079 | * tracks. In this case the readable TOC is empty (CDI tracks | 1068 | * tracks. In this case the readable TOC is empty (CDI tracks |
1080 | * are not included) and only holds the Leadout entry. | 1069 | * are not included) and only holds the Leadout entry. |
1081 | * | 1070 | * |
1082 | * Heiko Eiรfeldt. | 1071 | * Heiko Eiรfeldt. |
1083 | */ | 1072 | */ |
1084 | ntracks = 0; | 1073 | ntracks = 0; |
1085 | stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0, | 1074 | stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0, |
1086 | (char *)&toc->hdr, | 1075 | (char *)&toc->hdr, |
1087 | sizeof(struct atapi_toc_header) + | 1076 | sizeof(struct atapi_toc_header) + |
1088 | (ntracks + 1) * | 1077 | (ntracks + 1) * |
1089 | sizeof(struct atapi_toc_entry), | 1078 | sizeof(struct atapi_toc_entry), |
1090 | sense); | 1079 | sense); |
1091 | if (stat) | 1080 | if (stat) |
1092 | return stat; | 1081 | return stat; |
1093 | 1082 | ||
1094 | if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) { | 1083 | if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) { |
1095 | toc->hdr.first_track = (u8)bin2bcd(CDROM_LEADOUT); | 1084 | toc->hdr.first_track = (u8)bin2bcd(CDROM_LEADOUT); |
1096 | toc->hdr.last_track = (u8)bin2bcd(CDROM_LEADOUT); | 1085 | toc->hdr.last_track = (u8)bin2bcd(CDROM_LEADOUT); |
1097 | } else { | 1086 | } else { |
1098 | toc->hdr.first_track = CDROM_LEADOUT; | 1087 | toc->hdr.first_track = CDROM_LEADOUT; |
1099 | toc->hdr.last_track = CDROM_LEADOUT; | 1088 | toc->hdr.last_track = CDROM_LEADOUT; |
1100 | } | 1089 | } |
1101 | } | 1090 | } |
1102 | 1091 | ||
1103 | if (stat) | 1092 | if (stat) |
1104 | return stat; | 1093 | return stat; |
1105 | 1094 | ||
1106 | toc->hdr.toc_length = be16_to_cpu(toc->hdr.toc_length); | 1095 | toc->hdr.toc_length = be16_to_cpu(toc->hdr.toc_length); |
1107 | 1096 | ||
1108 | if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) { | 1097 | if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) { |
1109 | toc->hdr.first_track = bcd2bin(toc->hdr.first_track); | 1098 | toc->hdr.first_track = bcd2bin(toc->hdr.first_track); |
1110 | toc->hdr.last_track = bcd2bin(toc->hdr.last_track); | 1099 | toc->hdr.last_track = bcd2bin(toc->hdr.last_track); |
1111 | } | 1100 | } |
1112 | 1101 | ||
1113 | for (i = 0; i <= ntracks; i++) { | 1102 | for (i = 0; i <= ntracks; i++) { |
1114 | if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) { | 1103 | if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) { |
1115 | if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) | 1104 | if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) |
1116 | toc->ent[i].track = bcd2bin(toc->ent[i].track); | 1105 | toc->ent[i].track = bcd2bin(toc->ent[i].track); |
1117 | msf_from_bcd(&toc->ent[i].addr.msf); | 1106 | msf_from_bcd(&toc->ent[i].addr.msf); |
1118 | } | 1107 | } |
1119 | toc->ent[i].addr.lba = msf_to_lba(toc->ent[i].addr.msf.minute, | 1108 | toc->ent[i].addr.lba = msf_to_lba(toc->ent[i].addr.msf.minute, |
1120 | toc->ent[i].addr.msf.second, | 1109 | toc->ent[i].addr.msf.second, |
1121 | toc->ent[i].addr.msf.frame); | 1110 | toc->ent[i].addr.msf.frame); |
1122 | } | 1111 | } |
1123 | 1112 | ||
1124 | if (toc->hdr.first_track != CDROM_LEADOUT) { | 1113 | if (toc->hdr.first_track != CDROM_LEADOUT) { |
1125 | /* read the multisession information */ | 1114 | /* read the multisession information */ |
1126 | stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp, | 1115 | stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp, |
1127 | sizeof(ms_tmp), sense); | 1116 | sizeof(ms_tmp), sense); |
1128 | if (stat) | 1117 | if (stat) |
1129 | return stat; | 1118 | return stat; |
1130 | 1119 | ||
1131 | toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba); | 1120 | toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba); |
1132 | } else { | 1121 | } else { |
1133 | ms_tmp.hdr.last_track = CDROM_LEADOUT; | 1122 | ms_tmp.hdr.last_track = CDROM_LEADOUT; |
1134 | ms_tmp.hdr.first_track = ms_tmp.hdr.last_track; | 1123 | ms_tmp.hdr.first_track = ms_tmp.hdr.last_track; |
1135 | toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */ | 1124 | toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */ |
1136 | } | 1125 | } |
1137 | 1126 | ||
1138 | if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) { | 1127 | if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) { |
1139 | /* re-read multisession information using MSF format */ | 1128 | /* re-read multisession information using MSF format */ |
1140 | stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp, | 1129 | stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp, |
1141 | sizeof(ms_tmp), sense); | 1130 | sizeof(ms_tmp), sense); |
1142 | if (stat) | 1131 | if (stat) |
1143 | return stat; | 1132 | return stat; |
1144 | 1133 | ||
1145 | msf_from_bcd(&ms_tmp.ent.addr.msf); | 1134 | msf_from_bcd(&ms_tmp.ent.addr.msf); |
1146 | toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute, | 1135 | toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute, |
1147 | ms_tmp.ent.addr.msf.second, | 1136 | ms_tmp.ent.addr.msf.second, |
1148 | ms_tmp.ent.addr.msf.frame); | 1137 | ms_tmp.ent.addr.msf.frame); |
1149 | } | 1138 | } |
1150 | 1139 | ||
1151 | toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track); | 1140 | toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track); |
1152 | 1141 | ||
1153 | /* now try to get the total cdrom capacity */ | 1142 | /* now try to get the total cdrom capacity */ |
1154 | stat = cdrom_get_last_written(cdi, &last_written); | 1143 | stat = cdrom_get_last_written(cdi, &last_written); |
1155 | if (!stat && (last_written > toc->capacity)) { | 1144 | if (!stat && (last_written > toc->capacity)) { |
1156 | toc->capacity = last_written; | 1145 | toc->capacity = last_written; |
1157 | set_capacity(info->disk, toc->capacity * sectors_per_frame); | 1146 | set_capacity(info->disk, toc->capacity * sectors_per_frame); |
1158 | drive->probed_capacity = toc->capacity * sectors_per_frame; | 1147 | drive->probed_capacity = toc->capacity * sectors_per_frame; |
1159 | } | 1148 | } |
1160 | 1149 | ||
1161 | /* Remember that we've read this stuff. */ | 1150 | /* Remember that we've read this stuff. */ |
1162 | drive->atapi_flags |= IDE_AFLAG_TOC_VALID; | 1151 | drive->atapi_flags |= IDE_AFLAG_TOC_VALID; |
1163 | 1152 | ||
1164 | return 0; | 1153 | return 0; |
1165 | } | 1154 | } |
1166 | 1155 | ||
1167 | int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) | 1156 | int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) |
1168 | { | 1157 | { |
1169 | struct cdrom_info *info = drive->driver_data; | 1158 | struct cdrom_info *info = drive->driver_data; |
1170 | struct cdrom_device_info *cdi = &info->devinfo; | 1159 | struct cdrom_device_info *cdi = &info->devinfo; |
1171 | struct packet_command cgc; | 1160 | struct packet_command cgc; |
1172 | int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; | 1161 | int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; |
1173 | 1162 | ||
1174 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 1163 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
1175 | 1164 | ||
1176 | if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0) | 1165 | if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0) |
1177 | size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; | 1166 | size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; |
1178 | 1167 | ||
1179 | init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN); | 1168 | init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN); |
1180 | do { | 1169 | do { |
1181 | /* we seem to get stat=0x01,err=0x00 the first time (??) */ | 1170 | /* we seem to get stat=0x01,err=0x00 the first time (??) */ |
1182 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0); | 1171 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0); |
1183 | if (!stat) | 1172 | if (!stat) |
1184 | break; | 1173 | break; |
1185 | } while (--attempts); | 1174 | } while (--attempts); |
1186 | return stat; | 1175 | return stat; |
1187 | } | 1176 | } |
1188 | 1177 | ||
1189 | void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) | 1178 | void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) |
1190 | { | 1179 | { |
1191 | struct cdrom_info *cd = drive->driver_data; | 1180 | struct cdrom_info *cd = drive->driver_data; |
1192 | u16 curspeed, maxspeed; | 1181 | u16 curspeed, maxspeed; |
1193 | 1182 | ||
1194 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 1183 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
1195 | 1184 | ||
1196 | if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) { | 1185 | if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) { |
1197 | curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]); | 1186 | curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]); |
1198 | maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]); | 1187 | maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]); |
1199 | } else { | 1188 | } else { |
1200 | curspeed = be16_to_cpup((__be16 *)&buf[8 + 14]); | 1189 | curspeed = be16_to_cpup((__be16 *)&buf[8 + 14]); |
1201 | maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); | 1190 | maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); |
1202 | } | 1191 | } |
1203 | 1192 | ||
1204 | ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u", | 1193 | ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u", |
1205 | curspeed, maxspeed); | 1194 | curspeed, maxspeed); |
1206 | 1195 | ||
1207 | cd->current_speed = (curspeed + (176/2)) / 176; | 1196 | cd->current_speed = (curspeed + (176/2)) / 176; |
1208 | cd->max_speed = (maxspeed + (176/2)) / 176; | 1197 | cd->max_speed = (maxspeed + (176/2)) / 176; |
1209 | } | 1198 | } |
1210 | 1199 | ||
1211 | #define IDE_CD_CAPABILITIES \ | 1200 | #define IDE_CD_CAPABILITIES \ |
1212 | (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \ | 1201 | (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \ |
1213 | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \ | 1202 | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \ |
1214 | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R | \ | 1203 | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R | \ |
1215 | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \ | 1204 | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \ |
1216 | CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM) | 1205 | CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM) |
1217 | 1206 | ||
1218 | static struct cdrom_device_ops ide_cdrom_dops = { | 1207 | static struct cdrom_device_ops ide_cdrom_dops = { |
1219 | .open = ide_cdrom_open_real, | 1208 | .open = ide_cdrom_open_real, |
1220 | .release = ide_cdrom_release_real, | 1209 | .release = ide_cdrom_release_real, |
1221 | .drive_status = ide_cdrom_drive_status, | 1210 | .drive_status = ide_cdrom_drive_status, |
1222 | .media_changed = ide_cdrom_check_media_change_real, | 1211 | .media_changed = ide_cdrom_check_media_change_real, |
1223 | .tray_move = ide_cdrom_tray_move, | 1212 | .tray_move = ide_cdrom_tray_move, |
1224 | .lock_door = ide_cdrom_lock_door, | 1213 | .lock_door = ide_cdrom_lock_door, |
1225 | .select_speed = ide_cdrom_select_speed, | 1214 | .select_speed = ide_cdrom_select_speed, |
1226 | .get_last_session = ide_cdrom_get_last_session, | 1215 | .get_last_session = ide_cdrom_get_last_session, |
1227 | .get_mcn = ide_cdrom_get_mcn, | 1216 | .get_mcn = ide_cdrom_get_mcn, |
1228 | .reset = ide_cdrom_reset, | 1217 | .reset = ide_cdrom_reset, |
1229 | .audio_ioctl = ide_cdrom_audio_ioctl, | 1218 | .audio_ioctl = ide_cdrom_audio_ioctl, |
1230 | .capability = IDE_CD_CAPABILITIES, | 1219 | .capability = IDE_CD_CAPABILITIES, |
1231 | .generic_packet = ide_cdrom_packet, | 1220 | .generic_packet = ide_cdrom_packet, |
1232 | }; | 1221 | }; |
1233 | 1222 | ||
1234 | static int ide_cdrom_register(ide_drive_t *drive, int nslots) | 1223 | static int ide_cdrom_register(ide_drive_t *drive, int nslots) |
1235 | { | 1224 | { |
1236 | struct cdrom_info *info = drive->driver_data; | 1225 | struct cdrom_info *info = drive->driver_data; |
1237 | struct cdrom_device_info *devinfo = &info->devinfo; | 1226 | struct cdrom_device_info *devinfo = &info->devinfo; |
1238 | 1227 | ||
1239 | ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots); | 1228 | ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots); |
1240 | 1229 | ||
1241 | devinfo->ops = &ide_cdrom_dops; | 1230 | devinfo->ops = &ide_cdrom_dops; |
1242 | devinfo->speed = info->current_speed; | 1231 | devinfo->speed = info->current_speed; |
1243 | devinfo->capacity = nslots; | 1232 | devinfo->capacity = nslots; |
1244 | devinfo->handle = drive; | 1233 | devinfo->handle = drive; |
1245 | strcpy(devinfo->name, drive->name); | 1234 | strcpy(devinfo->name, drive->name); |
1246 | 1235 | ||
1247 | if (drive->atapi_flags & IDE_AFLAG_NO_SPEED_SELECT) | 1236 | if (drive->atapi_flags & IDE_AFLAG_NO_SPEED_SELECT) |
1248 | devinfo->mask |= CDC_SELECT_SPEED; | 1237 | devinfo->mask |= CDC_SELECT_SPEED; |
1249 | 1238 | ||
1250 | devinfo->disk = info->disk; | 1239 | devinfo->disk = info->disk; |
1251 | return register_cdrom(devinfo); | 1240 | return register_cdrom(devinfo); |
1252 | } | 1241 | } |
1253 | 1242 | ||
1254 | static int ide_cdrom_probe_capabilities(ide_drive_t *drive) | 1243 | static int ide_cdrom_probe_capabilities(ide_drive_t *drive) |
1255 | { | 1244 | { |
1256 | struct cdrom_info *cd = drive->driver_data; | 1245 | struct cdrom_info *cd = drive->driver_data; |
1257 | struct cdrom_device_info *cdi = &cd->devinfo; | 1246 | struct cdrom_device_info *cdi = &cd->devinfo; |
1258 | u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; | 1247 | u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; |
1259 | mechtype_t mechtype; | 1248 | mechtype_t mechtype; |
1260 | int nslots = 1; | 1249 | int nslots = 1; |
1261 | 1250 | ||
1262 | ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx", | 1251 | ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx", |
1263 | drive->media, drive->atapi_flags); | 1252 | drive->media, drive->atapi_flags); |
1264 | 1253 | ||
1265 | cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | | 1254 | cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | |
1266 | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO | | 1255 | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO | |
1267 | CDC_MO_DRIVE | CDC_RAM); | 1256 | CDC_MO_DRIVE | CDC_RAM); |
1268 | 1257 | ||
1269 | if (drive->media == ide_optical) { | 1258 | if (drive->media == ide_optical) { |
1270 | cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM); | 1259 | cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM); |
1271 | printk(KERN_ERR PFX "%s: ATAPI magneto-optical drive\n", | 1260 | printk(KERN_ERR PFX "%s: ATAPI magneto-optical drive\n", |
1272 | drive->name); | 1261 | drive->name); |
1273 | return nslots; | 1262 | return nslots; |
1274 | } | 1263 | } |
1275 | 1264 | ||
1276 | if (drive->atapi_flags & IDE_AFLAG_PRE_ATAPI12) { | 1265 | if (drive->atapi_flags & IDE_AFLAG_PRE_ATAPI12) { |
1277 | drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT; | 1266 | drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT; |
1278 | cdi->mask &= ~CDC_PLAY_AUDIO; | 1267 | cdi->mask &= ~CDC_PLAY_AUDIO; |
1279 | return nslots; | 1268 | return nslots; |
1280 | } | 1269 | } |
1281 | 1270 | ||
1282 | /* | 1271 | /* |
1283 | * We have to cheat a little here. the packet will eventually be queued | 1272 | * We have to cheat a little here. the packet will eventually be queued |
1284 | * with ide_cdrom_packet(), which extracts the drive from cdi->handle. | 1273 | * with ide_cdrom_packet(), which extracts the drive from cdi->handle. |
1285 | * Since this device hasn't been registered with the Uniform layer yet, | 1274 | * Since this device hasn't been registered with the Uniform layer yet, |
1286 | * it can't do this. Same goes for cdi->ops. | 1275 | * it can't do this. Same goes for cdi->ops. |
1287 | */ | 1276 | */ |
1288 | cdi->handle = drive; | 1277 | cdi->handle = drive; |
1289 | cdi->ops = &ide_cdrom_dops; | 1278 | cdi->ops = &ide_cdrom_dops; |
1290 | 1279 | ||
1291 | if (ide_cdrom_get_capabilities(drive, buf)) | 1280 | if (ide_cdrom_get_capabilities(drive, buf)) |
1292 | return 0; | 1281 | return 0; |
1293 | 1282 | ||
1294 | if ((buf[8 + 6] & 0x01) == 0) | 1283 | if ((buf[8 + 6] & 0x01) == 0) |
1295 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | 1284 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
1296 | if (buf[8 + 6] & 0x08) | 1285 | if (buf[8 + 6] & 0x08) |
1297 | drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT; | 1286 | drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT; |
1298 | if (buf[8 + 3] & 0x01) | 1287 | if (buf[8 + 3] & 0x01) |
1299 | cdi->mask &= ~CDC_CD_R; | 1288 | cdi->mask &= ~CDC_CD_R; |
1300 | if (buf[8 + 3] & 0x02) | 1289 | if (buf[8 + 3] & 0x02) |
1301 | cdi->mask &= ~(CDC_CD_RW | CDC_RAM); | 1290 | cdi->mask &= ~(CDC_CD_RW | CDC_RAM); |
1302 | if (buf[8 + 2] & 0x38) | 1291 | if (buf[8 + 2] & 0x38) |
1303 | cdi->mask &= ~CDC_DVD; | 1292 | cdi->mask &= ~CDC_DVD; |
1304 | if (buf[8 + 3] & 0x20) | 1293 | if (buf[8 + 3] & 0x20) |
1305 | cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM); | 1294 | cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM); |
1306 | if (buf[8 + 3] & 0x10) | 1295 | if (buf[8 + 3] & 0x10) |
1307 | cdi->mask &= ~CDC_DVD_R; | 1296 | cdi->mask &= ~CDC_DVD_R; |
1308 | if ((buf[8 + 4] & 0x01) || (drive->atapi_flags & IDE_AFLAG_PLAY_AUDIO_OK)) | 1297 | if ((buf[8 + 4] & 0x01) || (drive->atapi_flags & IDE_AFLAG_PLAY_AUDIO_OK)) |
1309 | cdi->mask &= ~CDC_PLAY_AUDIO; | 1298 | cdi->mask &= ~CDC_PLAY_AUDIO; |
1310 | 1299 | ||
1311 | mechtype = buf[8 + 6] >> 5; | 1300 | mechtype = buf[8 + 6] >> 5; |
1312 | if (mechtype == mechtype_caddy || | 1301 | if (mechtype == mechtype_caddy || |
1313 | mechtype == mechtype_popup || | 1302 | mechtype == mechtype_popup || |
1314 | (drive->atapi_flags & IDE_AFLAG_NO_AUTOCLOSE)) | 1303 | (drive->atapi_flags & IDE_AFLAG_NO_AUTOCLOSE)) |
1315 | cdi->mask |= CDC_CLOSE_TRAY; | 1304 | cdi->mask |= CDC_CLOSE_TRAY; |
1316 | 1305 | ||
1317 | if (cdi->sanyo_slot > 0) { | 1306 | if (cdi->sanyo_slot > 0) { |
1318 | cdi->mask &= ~CDC_SELECT_DISC; | 1307 | cdi->mask &= ~CDC_SELECT_DISC; |
1319 | nslots = 3; | 1308 | nslots = 3; |
1320 | } else if (mechtype == mechtype_individual_changer || | 1309 | } else if (mechtype == mechtype_individual_changer || |
1321 | mechtype == mechtype_cartridge_changer) { | 1310 | mechtype == mechtype_cartridge_changer) { |
1322 | nslots = cdrom_number_of_slots(cdi); | 1311 | nslots = cdrom_number_of_slots(cdi); |
1323 | if (nslots > 1) | 1312 | if (nslots > 1) |
1324 | cdi->mask &= ~CDC_SELECT_DISC; | 1313 | cdi->mask &= ~CDC_SELECT_DISC; |
1325 | } | 1314 | } |
1326 | 1315 | ||
1327 | ide_cdrom_update_speed(drive, buf); | 1316 | ide_cdrom_update_speed(drive, buf); |
1328 | 1317 | ||
1329 | printk(KERN_INFO PFX "%s: ATAPI", drive->name); | 1318 | printk(KERN_INFO PFX "%s: ATAPI", drive->name); |
1330 | 1319 | ||
1331 | /* don't print speed if the drive reported 0 */ | 1320 | /* don't print speed if the drive reported 0 */ |
1332 | if (cd->max_speed) | 1321 | if (cd->max_speed) |
1333 | printk(KERN_CONT " %dX", cd->max_speed); | 1322 | printk(KERN_CONT " %dX", cd->max_speed); |
1334 | 1323 | ||
1335 | printk(KERN_CONT " %s", (cdi->mask & CDC_DVD) ? "CD-ROM" : "DVD-ROM"); | 1324 | printk(KERN_CONT " %s", (cdi->mask & CDC_DVD) ? "CD-ROM" : "DVD-ROM"); |
1336 | 1325 | ||
1337 | if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0) | 1326 | if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0) |
1338 | printk(KERN_CONT " DVD%s%s", | 1327 | printk(KERN_CONT " DVD%s%s", |
1339 | (cdi->mask & CDC_DVD_R) ? "" : "-R", | 1328 | (cdi->mask & CDC_DVD_R) ? "" : "-R", |
1340 | (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM"); | 1329 | (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM"); |
1341 | 1330 | ||
1342 | if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0) | 1331 | if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0) |
1343 | printk(KERN_CONT " CD%s%s", | 1332 | printk(KERN_CONT " CD%s%s", |
1344 | (cdi->mask & CDC_CD_R) ? "" : "-R", | 1333 | (cdi->mask & CDC_CD_R) ? "" : "-R", |
1345 | (cdi->mask & CDC_CD_RW) ? "" : "/RW"); | 1334 | (cdi->mask & CDC_CD_RW) ? "" : "/RW"); |
1346 | 1335 | ||
1347 | if ((cdi->mask & CDC_SELECT_DISC) == 0) | 1336 | if ((cdi->mask & CDC_SELECT_DISC) == 0) |
1348 | printk(KERN_CONT " changer w/%d slots", nslots); | 1337 | printk(KERN_CONT " changer w/%d slots", nslots); |
1349 | else | 1338 | else |
1350 | printk(KERN_CONT " drive"); | 1339 | printk(KERN_CONT " drive"); |
1351 | 1340 | ||
1352 | printk(KERN_CONT ", %dkB Cache\n", | 1341 | printk(KERN_CONT ", %dkB Cache\n", |
1353 | be16_to_cpup((__be16 *)&buf[8 + 12])); | 1342 | be16_to_cpup((__be16 *)&buf[8 + 12])); |
1354 | 1343 | ||
1355 | return nslots; | 1344 | return nslots; |
1356 | } | 1345 | } |
1357 | 1346 | ||
1358 | /* standard prep_rq_fn that builds 10 byte cmds */ | 1347 | /* standard prep_rq_fn that builds 10 byte cmds */ |
1359 | static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq) | 1348 | static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq) |
1360 | { | 1349 | { |
1361 | int hard_sect = queue_hardsect_size(q); | 1350 | int hard_sect = queue_hardsect_size(q); |
1362 | long block = (long)blk_rq_pos(rq) / (hard_sect >> 9); | 1351 | long block = (long)blk_rq_pos(rq) / (hard_sect >> 9); |
1363 | unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9); | 1352 | unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9); |
1364 | 1353 | ||
1365 | memset(rq->cmd, 0, BLK_MAX_CDB); | 1354 | memset(rq->cmd, 0, BLK_MAX_CDB); |
1366 | 1355 | ||
1367 | if (rq_data_dir(rq) == READ) | 1356 | if (rq_data_dir(rq) == READ) |
1368 | rq->cmd[0] = GPCMD_READ_10; | 1357 | rq->cmd[0] = GPCMD_READ_10; |
1369 | else | 1358 | else |
1370 | rq->cmd[0] = GPCMD_WRITE_10; | 1359 | rq->cmd[0] = GPCMD_WRITE_10; |
1371 | 1360 | ||
1372 | /* | 1361 | /* |
1373 | * fill in lba | 1362 | * fill in lba |
1374 | */ | 1363 | */ |
1375 | rq->cmd[2] = (block >> 24) & 0xff; | 1364 | rq->cmd[2] = (block >> 24) & 0xff; |
1376 | rq->cmd[3] = (block >> 16) & 0xff; | 1365 | rq->cmd[3] = (block >> 16) & 0xff; |
1377 | rq->cmd[4] = (block >> 8) & 0xff; | 1366 | rq->cmd[4] = (block >> 8) & 0xff; |
1378 | rq->cmd[5] = block & 0xff; | 1367 | rq->cmd[5] = block & 0xff; |
1379 | 1368 | ||
1380 | /* | 1369 | /* |
1381 | * and transfer length | 1370 | * and transfer length |
1382 | */ | 1371 | */ |
1383 | rq->cmd[7] = (blocks >> 8) & 0xff; | 1372 | rq->cmd[7] = (blocks >> 8) & 0xff; |
1384 | rq->cmd[8] = blocks & 0xff; | 1373 | rq->cmd[8] = blocks & 0xff; |
1385 | rq->cmd_len = 10; | 1374 | rq->cmd_len = 10; |
1386 | return BLKPREP_OK; | 1375 | return BLKPREP_OK; |
1387 | } | 1376 | } |
1388 | 1377 | ||
1389 | /* | 1378 | /* |
1390 | * Most of the SCSI commands are supported directly by ATAPI devices. | 1379 | * Most of the SCSI commands are supported directly by ATAPI devices. |
1391 | * This transform handles the few exceptions. | 1380 | * This transform handles the few exceptions. |
1392 | */ | 1381 | */ |
1393 | static int ide_cdrom_prep_pc(struct request *rq) | 1382 | static int ide_cdrom_prep_pc(struct request *rq) |
1394 | { | 1383 | { |
1395 | u8 *c = rq->cmd; | 1384 | u8 *c = rq->cmd; |
1396 | 1385 | ||
1397 | /* transform 6-byte read/write commands to the 10-byte version */ | 1386 | /* transform 6-byte read/write commands to the 10-byte version */ |
1398 | if (c[0] == READ_6 || c[0] == WRITE_6) { | 1387 | if (c[0] == READ_6 || c[0] == WRITE_6) { |
1399 | c[8] = c[4]; | 1388 | c[8] = c[4]; |
1400 | c[5] = c[3]; | 1389 | c[5] = c[3]; |
1401 | c[4] = c[2]; | 1390 | c[4] = c[2]; |
1402 | c[3] = c[1] & 0x1f; | 1391 | c[3] = c[1] & 0x1f; |
1403 | c[2] = 0; | 1392 | c[2] = 0; |
1404 | c[1] &= 0xe0; | 1393 | c[1] &= 0xe0; |
1405 | c[0] += (READ_10 - READ_6); | 1394 | c[0] += (READ_10 - READ_6); |
1406 | rq->cmd_len = 10; | 1395 | rq->cmd_len = 10; |
1407 | return BLKPREP_OK; | 1396 | return BLKPREP_OK; |
1408 | } | 1397 | } |
1409 | 1398 | ||
1410 | /* | 1399 | /* |
1411 | * it's silly to pretend we understand 6-byte sense commands, just | 1400 | * it's silly to pretend we understand 6-byte sense commands, just |
1412 | * reject with ILLEGAL_REQUEST and the caller should take the | 1401 | * reject with ILLEGAL_REQUEST and the caller should take the |
1413 | * appropriate action | 1402 | * appropriate action |
1414 | */ | 1403 | */ |
1415 | if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) { | 1404 | if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) { |
1416 | rq->errors = ILLEGAL_REQUEST; | 1405 | rq->errors = ILLEGAL_REQUEST; |
1417 | return BLKPREP_KILL; | 1406 | return BLKPREP_KILL; |
1418 | } | 1407 | } |
1419 | 1408 | ||
1420 | return BLKPREP_OK; | 1409 | return BLKPREP_OK; |
1421 | } | 1410 | } |
1422 | 1411 | ||
1423 | static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq) | 1412 | static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq) |
1424 | { | 1413 | { |
1425 | if (blk_fs_request(rq)) | 1414 | if (blk_fs_request(rq)) |
1426 | return ide_cdrom_prep_fs(q, rq); | 1415 | return ide_cdrom_prep_fs(q, rq); |
1427 | else if (blk_pc_request(rq)) | 1416 | else if (blk_pc_request(rq)) |
1428 | return ide_cdrom_prep_pc(rq); | 1417 | return ide_cdrom_prep_pc(rq); |
1429 | 1418 | ||
1430 | return 0; | 1419 | return 0; |
1431 | } | 1420 | } |
1432 | 1421 | ||
1433 | struct cd_list_entry { | 1422 | struct cd_list_entry { |
1434 | const char *id_model; | 1423 | const char *id_model; |
1435 | const char *id_firmware; | 1424 | const char *id_firmware; |
1436 | unsigned int cd_flags; | 1425 | unsigned int cd_flags; |
1437 | }; | 1426 | }; |
1438 | 1427 | ||
1439 | #ifdef CONFIG_IDE_PROC_FS | 1428 | #ifdef CONFIG_IDE_PROC_FS |
1440 | static sector_t ide_cdrom_capacity(ide_drive_t *drive) | 1429 | static sector_t ide_cdrom_capacity(ide_drive_t *drive) |
1441 | { | 1430 | { |
1442 | unsigned long capacity, sectors_per_frame; | 1431 | unsigned long capacity, sectors_per_frame; |
1443 | 1432 | ||
1444 | if (cdrom_read_capacity(drive, &capacity, §ors_per_frame, NULL)) | 1433 | if (cdrom_read_capacity(drive, &capacity, §ors_per_frame, NULL)) |
1445 | return 0; | 1434 | return 0; |
1446 | 1435 | ||
1447 | return capacity * sectors_per_frame; | 1436 | return capacity * sectors_per_frame; |
1448 | } | 1437 | } |
1449 | 1438 | ||
1450 | static int proc_idecd_read_capacity(char *page, char **start, off_t off, | 1439 | static int proc_idecd_read_capacity(char *page, char **start, off_t off, |
1451 | int count, int *eof, void *data) | 1440 | int count, int *eof, void *data) |
1452 | { | 1441 | { |
1453 | ide_drive_t *drive = data; | 1442 | ide_drive_t *drive = data; |
1454 | int len; | 1443 | int len; |
1455 | 1444 | ||
1456 | len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive)); | 1445 | len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive)); |
1457 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | 1446 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
1458 | } | 1447 | } |
1459 | 1448 | ||
1460 | static ide_proc_entry_t idecd_proc[] = { | 1449 | static ide_proc_entry_t idecd_proc[] = { |
1461 | { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL }, | 1450 | { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL }, |
1462 | { NULL, 0, NULL, NULL } | 1451 | { NULL, 0, NULL, NULL } |
1463 | }; | 1452 | }; |
1464 | 1453 | ||
1465 | static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive) | 1454 | static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive) |
1466 | { | 1455 | { |
1467 | return idecd_proc; | 1456 | return idecd_proc; |
1468 | } | 1457 | } |
1469 | 1458 | ||
1470 | static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive) | 1459 | static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive) |
1471 | { | 1460 | { |
1472 | return NULL; | 1461 | return NULL; |
1473 | } | 1462 | } |
1474 | #endif | 1463 | #endif |
1475 | 1464 | ||
1476 | static const struct cd_list_entry ide_cd_quirks_list[] = { | 1465 | static const struct cd_list_entry ide_cd_quirks_list[] = { |
1477 | /* SCR-3231 doesn't support the SET_CD_SPEED command. */ | 1466 | /* SCR-3231 doesn't support the SET_CD_SPEED command. */ |
1478 | { "SAMSUNG CD-ROM SCR-3231", NULL, IDE_AFLAG_NO_SPEED_SELECT }, | 1467 | { "SAMSUNG CD-ROM SCR-3231", NULL, IDE_AFLAG_NO_SPEED_SELECT }, |
1479 | /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */ | 1468 | /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */ |
1480 | { "NEC CD-ROM DRIVE:260", "1.01", IDE_AFLAG_TOCADDR_AS_BCD | | 1469 | { "NEC CD-ROM DRIVE:260", "1.01", IDE_AFLAG_TOCADDR_AS_BCD | |
1481 | IDE_AFLAG_PRE_ATAPI12, }, | 1470 | IDE_AFLAG_PRE_ATAPI12, }, |
1482 | /* Vertos 300, some versions of this drive like to talk BCD. */ | 1471 | /* Vertos 300, some versions of this drive like to talk BCD. */ |
1483 | { "V003S0DS", NULL, IDE_AFLAG_VERTOS_300_SSD, }, | 1472 | { "V003S0DS", NULL, IDE_AFLAG_VERTOS_300_SSD, }, |
1484 | /* Vertos 600 ESD. */ | 1473 | /* Vertos 600 ESD. */ |
1485 | { "V006E0DS", NULL, IDE_AFLAG_VERTOS_600_ESD, }, | 1474 | { "V006E0DS", NULL, IDE_AFLAG_VERTOS_600_ESD, }, |
1486 | /* | 1475 | /* |
1487 | * Sanyo 3 CD changer uses a non-standard command for CD changing | 1476 | * Sanyo 3 CD changer uses a non-standard command for CD changing |
1488 | * (by default standard ATAPI support for CD changers is used). | 1477 | * (by default standard ATAPI support for CD changers is used). |
1489 | */ | 1478 | */ |
1490 | { "CD-ROM CDR-C3 G", NULL, IDE_AFLAG_SANYO_3CD }, | 1479 | { "CD-ROM CDR-C3 G", NULL, IDE_AFLAG_SANYO_3CD }, |
1491 | { "CD-ROM CDR-C3G", NULL, IDE_AFLAG_SANYO_3CD }, | 1480 | { "CD-ROM CDR-C3G", NULL, IDE_AFLAG_SANYO_3CD }, |
1492 | { "CD-ROM CDR_C36", NULL, IDE_AFLAG_SANYO_3CD }, | 1481 | { "CD-ROM CDR_C36", NULL, IDE_AFLAG_SANYO_3CD }, |
1493 | /* Stingray 8X CD-ROM. */ | 1482 | /* Stingray 8X CD-ROM. */ |
1494 | { "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_AFLAG_PRE_ATAPI12 }, | 1483 | { "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_AFLAG_PRE_ATAPI12 }, |
1495 | /* | 1484 | /* |
1496 | * ACER 50X CD-ROM and WPI 32X CD-ROM require the full spec length | 1485 | * ACER 50X CD-ROM and WPI 32X CD-ROM require the full spec length |
1497 | * mode sense page capabilities size, but older drives break. | 1486 | * mode sense page capabilities size, but older drives break. |
1498 | */ | 1487 | */ |
1499 | { "ATAPI CD ROM DRIVE 50X MAX", NULL, IDE_AFLAG_FULL_CAPS_PAGE }, | 1488 | { "ATAPI CD ROM DRIVE 50X MAX", NULL, IDE_AFLAG_FULL_CAPS_PAGE }, |
1500 | { "WPI CDS-32X", NULL, IDE_AFLAG_FULL_CAPS_PAGE }, | 1489 | { "WPI CDS-32X", NULL, IDE_AFLAG_FULL_CAPS_PAGE }, |
1501 | /* ACER/AOpen 24X CD-ROM has the speed fields byte-swapped. */ | 1490 | /* ACER/AOpen 24X CD-ROM has the speed fields byte-swapped. */ |
1502 | { "", "241N", IDE_AFLAG_LE_SPEED_FIELDS }, | 1491 | { "", "241N", IDE_AFLAG_LE_SPEED_FIELDS }, |
1503 | /* | 1492 | /* |
1504 | * Some drives used by Apple don't advertise audio play | 1493 | * Some drives used by Apple don't advertise audio play |
1505 | * but they do support reading TOC & audio datas. | 1494 | * but they do support reading TOC & audio datas. |
1506 | */ | 1495 | */ |
1507 | { "MATSHITADVD-ROM SR-8187", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, | 1496 | { "MATSHITADVD-ROM SR-8187", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, |
1508 | { "MATSHITADVD-ROM SR-8186", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, | 1497 | { "MATSHITADVD-ROM SR-8186", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, |
1509 | { "MATSHITADVD-ROM SR-8176", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, | 1498 | { "MATSHITADVD-ROM SR-8176", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, |
1510 | { "MATSHITADVD-ROM SR-8174", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, | 1499 | { "MATSHITADVD-ROM SR-8174", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, |
1511 | { "Optiarc DVD RW AD-5200A", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, | 1500 | { "Optiarc DVD RW AD-5200A", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, |
1512 | { "Optiarc DVD RW AD-7200A", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, | 1501 | { "Optiarc DVD RW AD-7200A", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, |
1513 | { "Optiarc DVD RW AD-7543A", NULL, IDE_AFLAG_NO_AUTOCLOSE }, | 1502 | { "Optiarc DVD RW AD-7543A", NULL, IDE_AFLAG_NO_AUTOCLOSE }, |
1514 | { "TEAC CD-ROM CD-224E", NULL, IDE_AFLAG_NO_AUTOCLOSE }, | 1503 | { "TEAC CD-ROM CD-224E", NULL, IDE_AFLAG_NO_AUTOCLOSE }, |
1515 | { NULL, NULL, 0 } | 1504 | { NULL, NULL, 0 } |
1516 | }; | 1505 | }; |
1517 | 1506 | ||
1518 | static unsigned int ide_cd_flags(u16 *id) | 1507 | static unsigned int ide_cd_flags(u16 *id) |
1519 | { | 1508 | { |
1520 | const struct cd_list_entry *cle = ide_cd_quirks_list; | 1509 | const struct cd_list_entry *cle = ide_cd_quirks_list; |
1521 | 1510 | ||
1522 | while (cle->id_model) { | 1511 | while (cle->id_model) { |
1523 | if (strcmp(cle->id_model, (char *)&id[ATA_ID_PROD]) == 0 && | 1512 | if (strcmp(cle->id_model, (char *)&id[ATA_ID_PROD]) == 0 && |
1524 | (cle->id_firmware == NULL || | 1513 | (cle->id_firmware == NULL || |
1525 | strstr((char *)&id[ATA_ID_FW_REV], cle->id_firmware))) | 1514 | strstr((char *)&id[ATA_ID_FW_REV], cle->id_firmware))) |
1526 | return cle->cd_flags; | 1515 | return cle->cd_flags; |
1527 | cle++; | 1516 | cle++; |
1528 | } | 1517 | } |
1529 | 1518 | ||
1530 | return 0; | 1519 | return 0; |
1531 | } | 1520 | } |
1532 | 1521 | ||
1533 | static int ide_cdrom_setup(ide_drive_t *drive) | 1522 | static int ide_cdrom_setup(ide_drive_t *drive) |
1534 | { | 1523 | { |
1535 | struct cdrom_info *cd = drive->driver_data; | 1524 | struct cdrom_info *cd = drive->driver_data; |
1536 | struct cdrom_device_info *cdi = &cd->devinfo; | 1525 | struct cdrom_device_info *cdi = &cd->devinfo; |
1537 | struct request_queue *q = drive->queue; | 1526 | struct request_queue *q = drive->queue; |
1538 | u16 *id = drive->id; | 1527 | u16 *id = drive->id; |
1539 | char *fw_rev = (char *)&id[ATA_ID_FW_REV]; | 1528 | char *fw_rev = (char *)&id[ATA_ID_FW_REV]; |
1540 | int nslots; | 1529 | int nslots; |
1541 | 1530 | ||
1542 | ide_debug_log(IDE_DBG_PROBE, "enter"); | 1531 | ide_debug_log(IDE_DBG_PROBE, "enter"); |
1543 | 1532 | ||
1544 | blk_queue_prep_rq(q, ide_cdrom_prep_fn); | 1533 | blk_queue_prep_rq(q, ide_cdrom_prep_fn); |
1545 | blk_queue_dma_alignment(q, 31); | 1534 | blk_queue_dma_alignment(q, 31); |
1546 | blk_queue_update_dma_pad(q, 15); | 1535 | blk_queue_update_dma_pad(q, 15); |
1547 | 1536 | ||
1548 | q->unplug_delay = max((1 * HZ) / 1000, 1); | 1537 | q->unplug_delay = max((1 * HZ) / 1000, 1); |
1549 | 1538 | ||
1550 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; | 1539 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; |
1551 | drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); | 1540 | drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); |
1552 | 1541 | ||
1553 | if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) && | 1542 | if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) && |
1554 | fw_rev[4] == '1' && fw_rev[6] <= '2') | 1543 | fw_rev[4] == '1' && fw_rev[6] <= '2') |
1555 | drive->atapi_flags |= (IDE_AFLAG_TOCTRACKS_AS_BCD | | 1544 | drive->atapi_flags |= (IDE_AFLAG_TOCTRACKS_AS_BCD | |
1556 | IDE_AFLAG_TOCADDR_AS_BCD); | 1545 | IDE_AFLAG_TOCADDR_AS_BCD); |
1557 | else if ((drive->atapi_flags & IDE_AFLAG_VERTOS_600_ESD) && | 1546 | else if ((drive->atapi_flags & IDE_AFLAG_VERTOS_600_ESD) && |
1558 | fw_rev[4] == '1' && fw_rev[6] <= '2') | 1547 | fw_rev[4] == '1' && fw_rev[6] <= '2') |
1559 | drive->atapi_flags |= IDE_AFLAG_TOCTRACKS_AS_BCD; | 1548 | drive->atapi_flags |= IDE_AFLAG_TOCTRACKS_AS_BCD; |
1560 | else if (drive->atapi_flags & IDE_AFLAG_SANYO_3CD) | 1549 | else if (drive->atapi_flags & IDE_AFLAG_SANYO_3CD) |
1561 | /* 3 => use CD in slot 0 */ | 1550 | /* 3 => use CD in slot 0 */ |
1562 | cdi->sanyo_slot = 3; | 1551 | cdi->sanyo_slot = 3; |
1563 | 1552 | ||
1564 | nslots = ide_cdrom_probe_capabilities(drive); | 1553 | nslots = ide_cdrom_probe_capabilities(drive); |
1565 | 1554 | ||
1566 | blk_queue_hardsect_size(q, CD_FRAMESIZE); | 1555 | blk_queue_hardsect_size(q, CD_FRAMESIZE); |
1567 | 1556 | ||
1568 | if (ide_cdrom_register(drive, nslots)) { | 1557 | if (ide_cdrom_register(drive, nslots)) { |
1569 | printk(KERN_ERR PFX "%s: %s failed to register device with the" | 1558 | printk(KERN_ERR PFX "%s: %s failed to register device with the" |
1570 | " cdrom driver.\n", drive->name, __func__); | 1559 | " cdrom driver.\n", drive->name, __func__); |
1571 | cd->devinfo.handle = NULL; | 1560 | cd->devinfo.handle = NULL; |
1572 | return 1; | 1561 | return 1; |
1573 | } | 1562 | } |
1574 | 1563 | ||
1575 | ide_proc_register_driver(drive, cd->driver); | 1564 | ide_proc_register_driver(drive, cd->driver); |
1576 | return 0; | 1565 | return 0; |
1577 | } | 1566 | } |
1578 | 1567 | ||
1579 | static void ide_cd_remove(ide_drive_t *drive) | 1568 | static void ide_cd_remove(ide_drive_t *drive) |
1580 | { | 1569 | { |
1581 | struct cdrom_info *info = drive->driver_data; | 1570 | struct cdrom_info *info = drive->driver_data; |
1582 | 1571 | ||
1583 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 1572 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
1584 | 1573 | ||
1585 | ide_proc_unregister_driver(drive, info->driver); | 1574 | ide_proc_unregister_driver(drive, info->driver); |
1586 | device_del(&info->dev); | 1575 | device_del(&info->dev); |
1587 | del_gendisk(info->disk); | 1576 | del_gendisk(info->disk); |
1588 | 1577 | ||
1589 | mutex_lock(&idecd_ref_mutex); | 1578 | mutex_lock(&idecd_ref_mutex); |
1590 | put_device(&info->dev); | 1579 | put_device(&info->dev); |
1591 | mutex_unlock(&idecd_ref_mutex); | 1580 | mutex_unlock(&idecd_ref_mutex); |
1592 | } | 1581 | } |
1593 | 1582 | ||
1594 | static void ide_cd_release(struct device *dev) | 1583 | static void ide_cd_release(struct device *dev) |
1595 | { | 1584 | { |
1596 | struct cdrom_info *info = to_ide_drv(dev, cdrom_info); | 1585 | struct cdrom_info *info = to_ide_drv(dev, cdrom_info); |
1597 | struct cdrom_device_info *devinfo = &info->devinfo; | 1586 | struct cdrom_device_info *devinfo = &info->devinfo; |
1598 | ide_drive_t *drive = info->drive; | 1587 | ide_drive_t *drive = info->drive; |
1599 | struct gendisk *g = info->disk; | 1588 | struct gendisk *g = info->disk; |
1600 | 1589 | ||
1601 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 1590 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
1602 | 1591 | ||
1603 | kfree(info->toc); | 1592 | kfree(info->toc); |
1604 | if (devinfo->handle == drive) | 1593 | if (devinfo->handle == drive) |
1605 | unregister_cdrom(devinfo); | 1594 | unregister_cdrom(devinfo); |
1606 | drive->driver_data = NULL; | 1595 | drive->driver_data = NULL; |
1607 | blk_queue_prep_rq(drive->queue, NULL); | 1596 | blk_queue_prep_rq(drive->queue, NULL); |
1608 | g->private_data = NULL; | 1597 | g->private_data = NULL; |
1609 | put_disk(g); | 1598 | put_disk(g); |
1610 | kfree(info); | 1599 | kfree(info); |
1611 | } | 1600 | } |
1612 | 1601 | ||
1613 | static int ide_cd_probe(ide_drive_t *); | 1602 | static int ide_cd_probe(ide_drive_t *); |
1614 | 1603 | ||
1615 | static struct ide_driver ide_cdrom_driver = { | 1604 | static struct ide_driver ide_cdrom_driver = { |
1616 | .gen_driver = { | 1605 | .gen_driver = { |
1617 | .owner = THIS_MODULE, | 1606 | .owner = THIS_MODULE, |
1618 | .name = "ide-cdrom", | 1607 | .name = "ide-cdrom", |
1619 | .bus = &ide_bus_type, | 1608 | .bus = &ide_bus_type, |
1620 | }, | 1609 | }, |
1621 | .probe = ide_cd_probe, | 1610 | .probe = ide_cd_probe, |
1622 | .remove = ide_cd_remove, | 1611 | .remove = ide_cd_remove, |
1623 | .version = IDECD_VERSION, | 1612 | .version = IDECD_VERSION, |
1624 | .do_request = ide_cd_do_request, | 1613 | .do_request = ide_cd_do_request, |
1625 | #ifdef CONFIG_IDE_PROC_FS | 1614 | #ifdef CONFIG_IDE_PROC_FS |
1626 | .proc_entries = ide_cd_proc_entries, | 1615 | .proc_entries = ide_cd_proc_entries, |
1627 | .proc_devsets = ide_cd_proc_devsets, | 1616 | .proc_devsets = ide_cd_proc_devsets, |
1628 | #endif | 1617 | #endif |
1629 | }; | 1618 | }; |
1630 | 1619 | ||
1631 | static int idecd_open(struct block_device *bdev, fmode_t mode) | 1620 | static int idecd_open(struct block_device *bdev, fmode_t mode) |
1632 | { | 1621 | { |
1633 | struct cdrom_info *info = ide_cd_get(bdev->bd_disk); | 1622 | struct cdrom_info *info = ide_cd_get(bdev->bd_disk); |
1634 | int rc = -ENOMEM; | 1623 | int rc = -ENOMEM; |
1635 | 1624 | ||
1636 | if (!info) | 1625 | if (!info) |
1637 | return -ENXIO; | 1626 | return -ENXIO; |
1638 | 1627 | ||
1639 | rc = cdrom_open(&info->devinfo, bdev, mode); | 1628 | rc = cdrom_open(&info->devinfo, bdev, mode); |
1640 | 1629 | ||
1641 | if (rc < 0) | 1630 | if (rc < 0) |
1642 | ide_cd_put(info); | 1631 | ide_cd_put(info); |
1643 | 1632 | ||
1644 | return rc; | 1633 | return rc; |
1645 | } | 1634 | } |
1646 | 1635 | ||
1647 | static int idecd_release(struct gendisk *disk, fmode_t mode) | 1636 | static int idecd_release(struct gendisk *disk, fmode_t mode) |
1648 | { | 1637 | { |
1649 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); | 1638 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); |
1650 | 1639 | ||
1651 | cdrom_release(&info->devinfo, mode); | 1640 | cdrom_release(&info->devinfo, mode); |
1652 | 1641 | ||
1653 | ide_cd_put(info); | 1642 | ide_cd_put(info); |
1654 | 1643 | ||
1655 | return 0; | 1644 | return 0; |
1656 | } | 1645 | } |
1657 | 1646 | ||
1658 | static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg) | 1647 | static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg) |
1659 | { | 1648 | { |
1660 | struct packet_command cgc; | 1649 | struct packet_command cgc; |
1661 | char buffer[16]; | 1650 | char buffer[16]; |
1662 | int stat; | 1651 | int stat; |
1663 | char spindown; | 1652 | char spindown; |
1664 | 1653 | ||
1665 | if (copy_from_user(&spindown, (void __user *)arg, sizeof(char))) | 1654 | if (copy_from_user(&spindown, (void __user *)arg, sizeof(char))) |
1666 | return -EFAULT; | 1655 | return -EFAULT; |
1667 | 1656 | ||
1668 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN); | 1657 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN); |
1669 | 1658 | ||
1670 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0); | 1659 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0); |
1671 | if (stat) | 1660 | if (stat) |
1672 | return stat; | 1661 | return stat; |
1673 | 1662 | ||
1674 | buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f); | 1663 | buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f); |
1675 | return cdrom_mode_select(cdi, &cgc); | 1664 | return cdrom_mode_select(cdi, &cgc); |
1676 | } | 1665 | } |
1677 | 1666 | ||
1678 | static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg) | 1667 | static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg) |
1679 | { | 1668 | { |
1680 | struct packet_command cgc; | 1669 | struct packet_command cgc; |
1681 | char buffer[16]; | 1670 | char buffer[16]; |
1682 | int stat; | 1671 | int stat; |
1683 | char spindown; | 1672 | char spindown; |
1684 | 1673 | ||
1685 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN); | 1674 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN); |
1686 | 1675 | ||
1687 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0); | 1676 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0); |
1688 | if (stat) | 1677 | if (stat) |
1689 | return stat; | 1678 | return stat; |
1690 | 1679 | ||
1691 | spindown = buffer[11] & 0x0f; | 1680 | spindown = buffer[11] & 0x0f; |
1692 | if (copy_to_user((void __user *)arg, &spindown, sizeof(char))) | 1681 | if (copy_to_user((void __user *)arg, &spindown, sizeof(char))) |
1693 | return -EFAULT; | 1682 | return -EFAULT; |
1694 | return 0; | 1683 | return 0; |
1695 | } | 1684 | } |
1696 | 1685 | ||
1697 | static int idecd_ioctl(struct block_device *bdev, fmode_t mode, | 1686 | static int idecd_ioctl(struct block_device *bdev, fmode_t mode, |
1698 | unsigned int cmd, unsigned long arg) | 1687 | unsigned int cmd, unsigned long arg) |
1699 | { | 1688 | { |
1700 | struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); | 1689 | struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); |
1701 | int err; | 1690 | int err; |
1702 | 1691 | ||
1703 | switch (cmd) { | 1692 | switch (cmd) { |
1704 | case CDROMSETSPINDOWN: | 1693 | case CDROMSETSPINDOWN: |
1705 | return idecd_set_spindown(&info->devinfo, arg); | 1694 | return idecd_set_spindown(&info->devinfo, arg); |
1706 | case CDROMGETSPINDOWN: | 1695 | case CDROMGETSPINDOWN: |
1707 | return idecd_get_spindown(&info->devinfo, arg); | 1696 | return idecd_get_spindown(&info->devinfo, arg); |
1708 | default: | 1697 | default: |
1709 | break; | 1698 | break; |
1710 | } | 1699 | } |
1711 | 1700 | ||
1712 | err = generic_ide_ioctl(info->drive, bdev, cmd, arg); | 1701 | err = generic_ide_ioctl(info->drive, bdev, cmd, arg); |
1713 | if (err == -EINVAL) | 1702 | if (err == -EINVAL) |
1714 | err = cdrom_ioctl(&info->devinfo, bdev, mode, cmd, arg); | 1703 | err = cdrom_ioctl(&info->devinfo, bdev, mode, cmd, arg); |
1715 | 1704 | ||
1716 | return err; | 1705 | return err; |
1717 | } | 1706 | } |
1718 | 1707 | ||
1719 | static int idecd_media_changed(struct gendisk *disk) | 1708 | static int idecd_media_changed(struct gendisk *disk) |
1720 | { | 1709 | { |
1721 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); | 1710 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); |
1722 | return cdrom_media_changed(&info->devinfo); | 1711 | return cdrom_media_changed(&info->devinfo); |
1723 | } | 1712 | } |
1724 | 1713 | ||
1725 | static int idecd_revalidate_disk(struct gendisk *disk) | 1714 | static int idecd_revalidate_disk(struct gendisk *disk) |
1726 | { | 1715 | { |
1727 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); | 1716 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); |
1728 | struct request_sense sense; | 1717 | struct request_sense sense; |
1729 | 1718 | ||
1730 | ide_cd_read_toc(info->drive, &sense); | 1719 | ide_cd_read_toc(info->drive, &sense); |
1731 | 1720 | ||
1732 | return 0; | 1721 | return 0; |
1733 | } | 1722 | } |
1734 | 1723 | ||
1735 | static struct block_device_operations idecd_ops = { | 1724 | static struct block_device_operations idecd_ops = { |
1736 | .owner = THIS_MODULE, | 1725 | .owner = THIS_MODULE, |
1737 | .open = idecd_open, | 1726 | .open = idecd_open, |
1738 | .release = idecd_release, | 1727 | .release = idecd_release, |
1739 | .locked_ioctl = idecd_ioctl, | 1728 | .locked_ioctl = idecd_ioctl, |
1740 | .media_changed = idecd_media_changed, | 1729 | .media_changed = idecd_media_changed, |
1741 | .revalidate_disk = idecd_revalidate_disk | 1730 | .revalidate_disk = idecd_revalidate_disk |
1742 | }; | 1731 | }; |
1743 | 1732 | ||
1744 | /* module options */ | 1733 | /* module options */ |
1745 | static unsigned long debug_mask; | 1734 | static unsigned long debug_mask; |
1746 | module_param(debug_mask, ulong, 0644); | 1735 | module_param(debug_mask, ulong, 0644); |
1747 | 1736 | ||
1748 | MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); | 1737 | MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); |
1749 | 1738 | ||
1750 | static int ide_cd_probe(ide_drive_t *drive) | 1739 | static int ide_cd_probe(ide_drive_t *drive) |
1751 | { | 1740 | { |
1752 | struct cdrom_info *info; | 1741 | struct cdrom_info *info; |
1753 | struct gendisk *g; | 1742 | struct gendisk *g; |
1754 | struct request_sense sense; | 1743 | struct request_sense sense; |
1755 | 1744 | ||
1756 | ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x", | 1745 | ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x", |
1757 | drive->driver_req, drive->media); | 1746 | drive->driver_req, drive->media); |
1758 | 1747 | ||
1759 | if (!strstr("ide-cdrom", drive->driver_req)) | 1748 | if (!strstr("ide-cdrom", drive->driver_req)) |
1760 | goto failed; | 1749 | goto failed; |
1761 | 1750 | ||
1762 | if (drive->media != ide_cdrom && drive->media != ide_optical) | 1751 | if (drive->media != ide_cdrom && drive->media != ide_optical) |
1763 | goto failed; | 1752 | goto failed; |
1764 | 1753 | ||
1765 | drive->debug_mask = debug_mask; | 1754 | drive->debug_mask = debug_mask; |
1766 | drive->irq_handler = cdrom_newpc_intr; | 1755 | drive->irq_handler = cdrom_newpc_intr; |
1767 | 1756 | ||
1768 | info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); | 1757 | info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); |
1769 | if (info == NULL) { | 1758 | if (info == NULL) { |
1770 | printk(KERN_ERR PFX "%s: Can't allocate a cdrom structure\n", | 1759 | printk(KERN_ERR PFX "%s: Can't allocate a cdrom structure\n", |
1771 | drive->name); | 1760 | drive->name); |
1772 | goto failed; | 1761 | goto failed; |
1773 | } | 1762 | } |
1774 | 1763 | ||
1775 | g = alloc_disk(1 << PARTN_BITS); | 1764 | g = alloc_disk(1 << PARTN_BITS); |
1776 | if (!g) | 1765 | if (!g) |
1777 | goto out_free_cd; | 1766 | goto out_free_cd; |
1778 | 1767 | ||
1779 | ide_init_disk(g, drive); | 1768 | ide_init_disk(g, drive); |
1780 | 1769 | ||
1781 | info->dev.parent = &drive->gendev; | 1770 | info->dev.parent = &drive->gendev; |
1782 | info->dev.release = ide_cd_release; | 1771 | info->dev.release = ide_cd_release; |
1783 | dev_set_name(&info->dev, dev_name(&drive->gendev)); | 1772 | dev_set_name(&info->dev, dev_name(&drive->gendev)); |
1784 | 1773 | ||
1785 | if (device_register(&info->dev)) | 1774 | if (device_register(&info->dev)) |
1786 | goto out_free_disk; | 1775 | goto out_free_disk; |
1787 | 1776 | ||
1788 | info->drive = drive; | 1777 | info->drive = drive; |
1789 | info->driver = &ide_cdrom_driver; | 1778 | info->driver = &ide_cdrom_driver; |
1790 | info->disk = g; | 1779 | info->disk = g; |
1791 | 1780 | ||
1792 | g->private_data = &info->driver; | 1781 | g->private_data = &info->driver; |
1793 | 1782 | ||
1794 | drive->driver_data = info; | 1783 | drive->driver_data = info; |
1795 | 1784 | ||
1796 | g->minors = 1; | 1785 | g->minors = 1; |
1797 | g->driverfs_dev = &drive->gendev; | 1786 | g->driverfs_dev = &drive->gendev; |
1798 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; | 1787 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; |
1799 | if (ide_cdrom_setup(drive)) { | 1788 | if (ide_cdrom_setup(drive)) { |
1800 | put_device(&info->dev); | 1789 | put_device(&info->dev); |
1801 | goto failed; | 1790 | goto failed; |
1802 | } | 1791 | } |
1803 | 1792 | ||
1804 | ide_cd_read_toc(drive, &sense); | 1793 | ide_cd_read_toc(drive, &sense); |
1805 | g->fops = &idecd_ops; | 1794 | g->fops = &idecd_ops; |
1806 | g->flags |= GENHD_FL_REMOVABLE; | 1795 | g->flags |= GENHD_FL_REMOVABLE; |
1807 | add_disk(g); | 1796 | add_disk(g); |
1808 | return 0; | 1797 | return 0; |
1809 | 1798 | ||
1810 | out_free_disk: | 1799 | out_free_disk: |
1811 | put_disk(g); | 1800 | put_disk(g); |
1812 | out_free_cd: | 1801 | out_free_cd: |
1813 | kfree(info); | 1802 | kfree(info); |
1814 | failed: | 1803 | failed: |
1815 | return -ENODEV; | 1804 | return -ENODEV; |
1816 | } | 1805 | } |
1817 | 1806 | ||
1818 | static void __exit ide_cdrom_exit(void) | 1807 | static void __exit ide_cdrom_exit(void) |
1819 | { | 1808 | { |
1820 | driver_unregister(&ide_cdrom_driver.gen_driver); | 1809 | driver_unregister(&ide_cdrom_driver.gen_driver); |
1821 | } | 1810 | } |
1822 | 1811 | ||
1823 | static int __init ide_cdrom_init(void) | 1812 | static int __init ide_cdrom_init(void) |
1824 | { | 1813 | { |
1825 | printk(KERN_INFO DRV_NAME " driver " IDECD_VERSION "\n"); | 1814 | printk(KERN_INFO DRV_NAME " driver " IDECD_VERSION "\n"); |
1826 | return driver_register(&ide_cdrom_driver.gen_driver); | 1815 | return driver_register(&ide_cdrom_driver.gen_driver); |
1827 | } | 1816 | } |
1828 | 1817 | ||
1829 | MODULE_ALIAS("ide:*m-cdrom*"); | 1818 | MODULE_ALIAS("ide:*m-cdrom*"); |
1830 | MODULE_ALIAS("ide-cd"); | 1819 | MODULE_ALIAS("ide-cd"); |
1831 | module_init(ide_cdrom_init); | 1820 | module_init(ide_cdrom_init); |
1832 | module_exit(ide_cdrom_exit); | 1821 | module_exit(ide_cdrom_exit); |
1833 | MODULE_LICENSE("GPL"); | 1822 | MODULE_LICENSE("GPL"); |
1834 | 1823 |
drivers/ide/ide-floppy.c
1 | /* | 1 | /* |
2 | * IDE ATAPI floppy driver. | 2 | * IDE ATAPI floppy driver. |
3 | * | 3 | * |
4 | * Copyright (C) 1996-1999 Gadi Oxman <gadio@netvision.net.il> | 4 | * Copyright (C) 1996-1999 Gadi Oxman <gadio@netvision.net.il> |
5 | * Copyright (C) 2000-2002 Paul Bristow <paul@paulbristow.net> | 5 | * Copyright (C) 2000-2002 Paul Bristow <paul@paulbristow.net> |
6 | * Copyright (C) 2005 Bartlomiej Zolnierkiewicz | 6 | * Copyright (C) 2005 Bartlomiej Zolnierkiewicz |
7 | * | 7 | * |
8 | * This driver supports the following IDE floppy drives: | 8 | * This driver supports the following IDE floppy drives: |
9 | * | 9 | * |
10 | * LS-120/240 SuperDisk | 10 | * LS-120/240 SuperDisk |
11 | * Iomega Zip 100/250 | 11 | * Iomega Zip 100/250 |
12 | * Iomega PC Card Clik!/PocketZip | 12 | * Iomega PC Card Clik!/PocketZip |
13 | * | 13 | * |
14 | * For a historical changelog see | 14 | * For a historical changelog see |
15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 | 15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/timer.h> | 22 | #include <linux/timer.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/major.h> | 25 | #include <linux/major.h> |
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/genhd.h> | 27 | #include <linux/genhd.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/cdrom.h> | 29 | #include <linux/cdrom.h> |
30 | #include <linux/ide.h> | 30 | #include <linux/ide.h> |
31 | #include <linux/hdreg.h> | 31 | #include <linux/hdreg.h> |
32 | #include <linux/bitops.h> | 32 | #include <linux/bitops.h> |
33 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
34 | #include <linux/scatterlist.h> | 34 | #include <linux/scatterlist.h> |
35 | 35 | ||
36 | #include <scsi/scsi_ioctl.h> | 36 | #include <scsi/scsi_ioctl.h> |
37 | 37 | ||
38 | #include <asm/byteorder.h> | 38 | #include <asm/byteorder.h> |
39 | #include <linux/irq.h> | 39 | #include <linux/irq.h> |
40 | #include <linux/uaccess.h> | 40 | #include <linux/uaccess.h> |
41 | #include <linux/io.h> | 41 | #include <linux/io.h> |
42 | #include <asm/unaligned.h> | 42 | #include <asm/unaligned.h> |
43 | 43 | ||
44 | #include "ide-floppy.h" | 44 | #include "ide-floppy.h" |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * After each failed packet command we issue a request sense command and retry | 47 | * After each failed packet command we issue a request sense command and retry |
48 | * the packet command IDEFLOPPY_MAX_PC_RETRIES times. | 48 | * the packet command IDEFLOPPY_MAX_PC_RETRIES times. |
49 | */ | 49 | */ |
50 | #define IDEFLOPPY_MAX_PC_RETRIES 3 | 50 | #define IDEFLOPPY_MAX_PC_RETRIES 3 |
51 | 51 | ||
52 | /* format capacities descriptor codes */ | 52 | /* format capacities descriptor codes */ |
53 | #define CAPACITY_INVALID 0x00 | 53 | #define CAPACITY_INVALID 0x00 |
54 | #define CAPACITY_UNFORMATTED 0x01 | 54 | #define CAPACITY_UNFORMATTED 0x01 |
55 | #define CAPACITY_CURRENT 0x02 | 55 | #define CAPACITY_CURRENT 0x02 |
56 | #define CAPACITY_NO_CARTRIDGE 0x03 | 56 | #define CAPACITY_NO_CARTRIDGE 0x03 |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * The following delay solves a problem with ATAPI Zip 100 drive where BSY bit | 59 | * The following delay solves a problem with ATAPI Zip 100 drive where BSY bit |
60 | * was apparently being deasserted before the unit was ready to receive data. | 60 | * was apparently being deasserted before the unit was ready to receive data. |
61 | */ | 61 | */ |
62 | #define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */ | 62 | #define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */ |
63 | 63 | ||
64 | static int ide_floppy_callback(ide_drive_t *drive, int dsc) | 64 | static int ide_floppy_callback(ide_drive_t *drive, int dsc) |
65 | { | 65 | { |
66 | struct ide_disk_obj *floppy = drive->driver_data; | 66 | struct ide_disk_obj *floppy = drive->driver_data; |
67 | struct ide_atapi_pc *pc = drive->pc; | 67 | struct ide_atapi_pc *pc = drive->pc; |
68 | struct request *rq = pc->rq; | 68 | struct request *rq = pc->rq; |
69 | int uptodate = pc->error ? 0 : 1; | 69 | int uptodate = pc->error ? 0 : 1; |
70 | 70 | ||
71 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 71 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
72 | 72 | ||
73 | if (drive->failed_pc == pc) | 73 | if (drive->failed_pc == pc) |
74 | drive->failed_pc = NULL; | 74 | drive->failed_pc = NULL; |
75 | 75 | ||
76 | if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || | 76 | if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || |
77 | (rq && blk_pc_request(rq))) | 77 | (rq && blk_pc_request(rq))) |
78 | uptodate = 1; /* FIXME */ | 78 | uptodate = 1; /* FIXME */ |
79 | else if (pc->c[0] == GPCMD_REQUEST_SENSE) { | 79 | else if (pc->c[0] == GPCMD_REQUEST_SENSE) { |
80 | u8 *buf = pc->buf; | 80 | u8 *buf = pc->buf; |
81 | 81 | ||
82 | if (!pc->error) { | 82 | if (!pc->error) { |
83 | floppy->sense_key = buf[2] & 0x0F; | 83 | floppy->sense_key = buf[2] & 0x0F; |
84 | floppy->asc = buf[12]; | 84 | floppy->asc = buf[12]; |
85 | floppy->ascq = buf[13]; | 85 | floppy->ascq = buf[13]; |
86 | floppy->progress_indication = buf[15] & 0x80 ? | 86 | floppy->progress_indication = buf[15] & 0x80 ? |
87 | (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; | 87 | (u16)get_unaligned((u16 *)&buf[16]) : 0x10000; |
88 | 88 | ||
89 | if (drive->failed_pc) | 89 | if (drive->failed_pc) |
90 | ide_debug_log(IDE_DBG_PC, "pc = %x", | 90 | ide_debug_log(IDE_DBG_PC, "pc = %x", |
91 | drive->failed_pc->c[0]); | 91 | drive->failed_pc->c[0]); |
92 | 92 | ||
93 | ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x," | 93 | ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x," |
94 | "ascq = %x", floppy->sense_key, | 94 | "ascq = %x", floppy->sense_key, |
95 | floppy->asc, floppy->ascq); | 95 | floppy->asc, floppy->ascq); |
96 | } else | 96 | } else |
97 | printk(KERN_ERR PFX "Error in REQUEST SENSE itself - " | 97 | printk(KERN_ERR PFX "Error in REQUEST SENSE itself - " |
98 | "Aborting request!\n"); | 98 | "Aborting request!\n"); |
99 | } | 99 | } |
100 | 100 | ||
101 | if (blk_special_request(rq)) | 101 | if (blk_special_request(rq)) |
102 | rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; | 102 | rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; |
103 | 103 | ||
104 | return uptodate; | 104 | return uptodate; |
105 | } | 105 | } |
106 | 106 | ||
107 | static void ide_floppy_report_error(struct ide_disk_obj *floppy, | 107 | static void ide_floppy_report_error(struct ide_disk_obj *floppy, |
108 | struct ide_atapi_pc *pc) | 108 | struct ide_atapi_pc *pc) |
109 | { | 109 | { |
110 | /* supress error messages resulting from Medium not present */ | 110 | /* supress error messages resulting from Medium not present */ |
111 | if (floppy->sense_key == 0x02 && | 111 | if (floppy->sense_key == 0x02 && |
112 | floppy->asc == 0x3a && | 112 | floppy->asc == 0x3a && |
113 | floppy->ascq == 0x00) | 113 | floppy->ascq == 0x00) |
114 | return; | 114 | return; |
115 | 115 | ||
116 | printk(KERN_ERR PFX "%s: I/O error, pc = %2x, key = %2x, " | 116 | printk(KERN_ERR PFX "%s: I/O error, pc = %2x, key = %2x, " |
117 | "asc = %2x, ascq = %2x\n", | 117 | "asc = %2x, ascq = %2x\n", |
118 | floppy->drive->name, pc->c[0], floppy->sense_key, | 118 | floppy->drive->name, pc->c[0], floppy->sense_key, |
119 | floppy->asc, floppy->ascq); | 119 | floppy->asc, floppy->ascq); |
120 | 120 | ||
121 | } | 121 | } |
122 | 122 | ||
123 | static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, | 123 | static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, |
124 | struct ide_cmd *cmd, | 124 | struct ide_cmd *cmd, |
125 | struct ide_atapi_pc *pc) | 125 | struct ide_atapi_pc *pc) |
126 | { | 126 | { |
127 | struct ide_disk_obj *floppy = drive->driver_data; | 127 | struct ide_disk_obj *floppy = drive->driver_data; |
128 | 128 | ||
129 | if (drive->failed_pc == NULL && | 129 | if (drive->failed_pc == NULL && |
130 | pc->c[0] != GPCMD_REQUEST_SENSE) | 130 | pc->c[0] != GPCMD_REQUEST_SENSE) |
131 | drive->failed_pc = pc; | 131 | drive->failed_pc = pc; |
132 | 132 | ||
133 | /* Set the current packet command */ | 133 | /* Set the current packet command */ |
134 | drive->pc = pc; | 134 | drive->pc = pc; |
135 | 135 | ||
136 | if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { | 136 | if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { |
137 | unsigned int done = blk_rq_bytes(drive->hwif->rq); | 137 | unsigned int done = blk_rq_bytes(drive->hwif->rq); |
138 | 138 | ||
139 | if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) | 139 | if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) |
140 | ide_floppy_report_error(floppy, pc); | 140 | ide_floppy_report_error(floppy, pc); |
141 | 141 | ||
142 | /* Giving up */ | 142 | /* Giving up */ |
143 | pc->error = IDE_DRV_ERROR_GENERAL; | 143 | pc->error = IDE_DRV_ERROR_GENERAL; |
144 | 144 | ||
145 | drive->failed_pc = NULL; | 145 | drive->failed_pc = NULL; |
146 | drive->pc_callback(drive, 0); | 146 | drive->pc_callback(drive, 0); |
147 | ide_complete_rq(drive, -EIO, done); | 147 | ide_complete_rq(drive, -EIO, done); |
148 | return ide_stopped; | 148 | return ide_stopped; |
149 | } | 149 | } |
150 | 150 | ||
151 | ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries); | 151 | ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries); |
152 | 152 | ||
153 | pc->retries++; | 153 | pc->retries++; |
154 | 154 | ||
155 | return ide_issue_pc(drive, cmd); | 155 | return ide_issue_pc(drive, cmd); |
156 | } | 156 | } |
157 | 157 | ||
158 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) | 158 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) |
159 | { | 159 | { |
160 | ide_init_pc(pc); | 160 | ide_init_pc(pc); |
161 | pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES; | 161 | pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES; |
162 | pc->c[7] = 255; | 162 | pc->c[7] = 255; |
163 | pc->c[8] = 255; | 163 | pc->c[8] = 255; |
164 | pc->req_xfer = 255; | 164 | pc->req_xfer = 255; |
165 | } | 165 | } |
166 | 166 | ||
167 | /* A mode sense command is used to "sense" floppy parameters. */ | 167 | /* A mode sense command is used to "sense" floppy parameters. */ |
168 | void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) | 168 | void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) |
169 | { | 169 | { |
170 | u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */ | 170 | u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */ |
171 | 171 | ||
172 | ide_init_pc(pc); | 172 | ide_init_pc(pc); |
173 | pc->c[0] = GPCMD_MODE_SENSE_10; | 173 | pc->c[0] = GPCMD_MODE_SENSE_10; |
174 | pc->c[1] = 0; | 174 | pc->c[1] = 0; |
175 | pc->c[2] = page_code; | 175 | pc->c[2] = page_code; |
176 | 176 | ||
177 | switch (page_code) { | 177 | switch (page_code) { |
178 | case IDEFLOPPY_CAPABILITIES_PAGE: | 178 | case IDEFLOPPY_CAPABILITIES_PAGE: |
179 | length += 12; | 179 | length += 12; |
180 | break; | 180 | break; |
181 | case IDEFLOPPY_FLEXIBLE_DISK_PAGE: | 181 | case IDEFLOPPY_FLEXIBLE_DISK_PAGE: |
182 | length += 32; | 182 | length += 32; |
183 | break; | 183 | break; |
184 | default: | 184 | default: |
185 | printk(KERN_ERR PFX "unsupported page code in %s\n", __func__); | 185 | printk(KERN_ERR PFX "unsupported page code in %s\n", __func__); |
186 | } | 186 | } |
187 | put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); | 187 | put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); |
188 | pc->req_xfer = length; | 188 | pc->req_xfer = length; |
189 | } | 189 | } |
190 | 190 | ||
191 | static void idefloppy_create_rw_cmd(ide_drive_t *drive, | 191 | static void idefloppy_create_rw_cmd(ide_drive_t *drive, |
192 | struct ide_atapi_pc *pc, struct request *rq, | 192 | struct ide_atapi_pc *pc, struct request *rq, |
193 | unsigned long sector) | 193 | unsigned long sector) |
194 | { | 194 | { |
195 | struct ide_disk_obj *floppy = drive->driver_data; | 195 | struct ide_disk_obj *floppy = drive->driver_data; |
196 | int block = sector / floppy->bs_factor; | 196 | int block = sector / floppy->bs_factor; |
197 | int blocks = blk_rq_sectors(rq) / floppy->bs_factor; | 197 | int blocks = blk_rq_sectors(rq) / floppy->bs_factor; |
198 | int cmd = rq_data_dir(rq); | 198 | int cmd = rq_data_dir(rq); |
199 | 199 | ||
200 | ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks); | 200 | ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks); |
201 | 201 | ||
202 | ide_init_pc(pc); | 202 | ide_init_pc(pc); |
203 | pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; | 203 | pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; |
204 | put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); | 204 | put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); |
205 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); | 205 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); |
206 | 206 | ||
207 | memcpy(rq->cmd, pc->c, 12); | 207 | memcpy(rq->cmd, pc->c, 12); |
208 | 208 | ||
209 | pc->rq = rq; | 209 | pc->rq = rq; |
210 | if (rq->cmd_flags & REQ_RW) | 210 | if (rq->cmd_flags & REQ_RW) |
211 | pc->flags |= PC_FLAG_WRITING; | 211 | pc->flags |= PC_FLAG_WRITING; |
212 | pc->buf = NULL; | 212 | pc->buf = NULL; |
213 | pc->req_xfer = pc->buf_size = blocks * floppy->block_size; | 213 | pc->req_xfer = pc->buf_size = blocks * floppy->block_size; |
214 | pc->flags |= PC_FLAG_DMA_OK; | 214 | pc->flags |= PC_FLAG_DMA_OK; |
215 | } | 215 | } |
216 | 216 | ||
217 | static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, | 217 | static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, |
218 | struct ide_atapi_pc *pc, struct request *rq) | 218 | struct ide_atapi_pc *pc, struct request *rq) |
219 | { | 219 | { |
220 | ide_init_pc(pc); | 220 | ide_init_pc(pc); |
221 | memcpy(pc->c, rq->cmd, sizeof(pc->c)); | 221 | memcpy(pc->c, rq->cmd, sizeof(pc->c)); |
222 | pc->rq = rq; | 222 | pc->rq = rq; |
223 | if (rq->data_len) { | 223 | if (blk_rq_bytes(rq)) { |
224 | pc->flags |= PC_FLAG_DMA_OK; | 224 | pc->flags |= PC_FLAG_DMA_OK; |
225 | if (rq_data_dir(rq) == WRITE) | 225 | if (rq_data_dir(rq) == WRITE) |
226 | pc->flags |= PC_FLAG_WRITING; | 226 | pc->flags |= PC_FLAG_WRITING; |
227 | } | 227 | } |
228 | /* pio will be performed by ide_pio_bytes() which handles sg fine */ | 228 | /* pio will be performed by ide_pio_bytes() which handles sg fine */ |
229 | pc->buf = NULL; | 229 | pc->buf = NULL; |
230 | pc->req_xfer = pc->buf_size = rq->data_len; | 230 | pc->req_xfer = pc->buf_size = blk_rq_bytes(rq); |
231 | } | 231 | } |
232 | 232 | ||
233 | static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, | 233 | static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, |
234 | struct request *rq, sector_t block) | 234 | struct request *rq, sector_t block) |
235 | { | 235 | { |
236 | struct ide_disk_obj *floppy = drive->driver_data; | 236 | struct ide_disk_obj *floppy = drive->driver_data; |
237 | struct ide_cmd cmd; | 237 | struct ide_cmd cmd; |
238 | struct ide_atapi_pc *pc; | 238 | struct ide_atapi_pc *pc; |
239 | 239 | ||
240 | ide_debug_log(IDE_DBG_FUNC, "enter, cmd: 0x%x\n", rq->cmd[0]); | 240 | ide_debug_log(IDE_DBG_FUNC, "enter, cmd: 0x%x\n", rq->cmd[0]); |
241 | 241 | ||
242 | if (drive->debug_mask & IDE_DBG_RQ) | 242 | if (drive->debug_mask & IDE_DBG_RQ) |
243 | blk_dump_rq_flags(rq, (rq->rq_disk | 243 | blk_dump_rq_flags(rq, (rq->rq_disk |
244 | ? rq->rq_disk->disk_name | 244 | ? rq->rq_disk->disk_name |
245 | : "dev?")); | 245 | : "dev?")); |
246 | 246 | ||
247 | if (rq->errors >= ERROR_MAX) { | 247 | if (rq->errors >= ERROR_MAX) { |
248 | if (drive->failed_pc) { | 248 | if (drive->failed_pc) { |
249 | ide_floppy_report_error(floppy, drive->failed_pc); | 249 | ide_floppy_report_error(floppy, drive->failed_pc); |
250 | drive->failed_pc = NULL; | 250 | drive->failed_pc = NULL; |
251 | } else | 251 | } else |
252 | printk(KERN_ERR PFX "%s: I/O error\n", drive->name); | 252 | printk(KERN_ERR PFX "%s: I/O error\n", drive->name); |
253 | 253 | ||
254 | if (blk_special_request(rq)) { | 254 | if (blk_special_request(rq)) { |
255 | rq->errors = 0; | 255 | rq->errors = 0; |
256 | ide_complete_rq(drive, 0, blk_rq_bytes(rq)); | 256 | ide_complete_rq(drive, 0, blk_rq_bytes(rq)); |
257 | return ide_stopped; | 257 | return ide_stopped; |
258 | } else | 258 | } else |
259 | goto out_end; | 259 | goto out_end; |
260 | } | 260 | } |
261 | if (blk_fs_request(rq)) { | 261 | if (blk_fs_request(rq)) { |
262 | if (((long)blk_rq_pos(rq) % floppy->bs_factor) || | 262 | if (((long)blk_rq_pos(rq) % floppy->bs_factor) || |
263 | (blk_rq_sectors(rq) % floppy->bs_factor)) { | 263 | (blk_rq_sectors(rq) % floppy->bs_factor)) { |
264 | printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", | 264 | printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", |
265 | drive->name); | 265 | drive->name); |
266 | goto out_end; | 266 | goto out_end; |
267 | } | 267 | } |
268 | pc = &floppy->queued_pc; | 268 | pc = &floppy->queued_pc; |
269 | idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); | 269 | idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); |
270 | } else if (blk_special_request(rq) || blk_sense_request(rq)) { | 270 | } else if (blk_special_request(rq) || blk_sense_request(rq)) { |
271 | pc = (struct ide_atapi_pc *)rq->special; | 271 | pc = (struct ide_atapi_pc *)rq->special; |
272 | } else if (blk_pc_request(rq)) { | 272 | } else if (blk_pc_request(rq)) { |
273 | pc = &floppy->queued_pc; | 273 | pc = &floppy->queued_pc; |
274 | idefloppy_blockpc_cmd(floppy, pc, rq); | 274 | idefloppy_blockpc_cmd(floppy, pc, rq); |
275 | } else { | 275 | } else { |
276 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); | 276 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); |
277 | goto out_end; | 277 | goto out_end; |
278 | } | 278 | } |
279 | 279 | ||
280 | ide_prep_sense(drive, rq); | 280 | ide_prep_sense(drive, rq); |
281 | 281 | ||
282 | memset(&cmd, 0, sizeof(cmd)); | 282 | memset(&cmd, 0, sizeof(cmd)); |
283 | 283 | ||
284 | if (rq_data_dir(rq)) | 284 | if (rq_data_dir(rq)) |
285 | cmd.tf_flags |= IDE_TFLAG_WRITE; | 285 | cmd.tf_flags |= IDE_TFLAG_WRITE; |
286 | 286 | ||
287 | cmd.rq = rq; | 287 | cmd.rq = rq; |
288 | 288 | ||
289 | if (blk_fs_request(rq) || pc->req_xfer) { | 289 | if (blk_fs_request(rq) || pc->req_xfer) { |
290 | ide_init_sg_cmd(&cmd, pc->req_xfer); | 290 | ide_init_sg_cmd(&cmd, pc->req_xfer); |
291 | ide_map_sg(drive, &cmd); | 291 | ide_map_sg(drive, &cmd); |
292 | } | 292 | } |
293 | 293 | ||
294 | pc->rq = rq; | 294 | pc->rq = rq; |
295 | 295 | ||
296 | return ide_floppy_issue_pc(drive, &cmd, pc); | 296 | return ide_floppy_issue_pc(drive, &cmd, pc); |
297 | out_end: | 297 | out_end: |
298 | drive->failed_pc = NULL; | 298 | drive->failed_pc = NULL; |
299 | if (blk_fs_request(rq) == 0 && rq->errors == 0) | 299 | if (blk_fs_request(rq) == 0 && rq->errors == 0) |
300 | rq->errors = -EIO; | 300 | rq->errors = -EIO; |
301 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); | 301 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); |
302 | return ide_stopped; | 302 | return ide_stopped; |
303 | } | 303 | } |
304 | 304 | ||
305 | /* | 305 | /* |
306 | * Look at the flexible disk page parameters. We ignore the CHS capacity | 306 | * Look at the flexible disk page parameters. We ignore the CHS capacity |
307 | * parameters and use the LBA parameters instead. | 307 | * parameters and use the LBA parameters instead. |
308 | */ | 308 | */ |
309 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive, | 309 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive, |
310 | struct ide_atapi_pc *pc) | 310 | struct ide_atapi_pc *pc) |
311 | { | 311 | { |
312 | struct ide_disk_obj *floppy = drive->driver_data; | 312 | struct ide_disk_obj *floppy = drive->driver_data; |
313 | struct gendisk *disk = floppy->disk; | 313 | struct gendisk *disk = floppy->disk; |
314 | u8 *page; | 314 | u8 *page; |
315 | int capacity, lba_capacity; | 315 | int capacity, lba_capacity; |
316 | u16 transfer_rate, sector_size, cyls, rpm; | 316 | u16 transfer_rate, sector_size, cyls, rpm; |
317 | u8 heads, sectors; | 317 | u8 heads, sectors; |
318 | 318 | ||
319 | ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); | 319 | ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); |
320 | 320 | ||
321 | if (ide_queue_pc_tail(drive, disk, pc)) { | 321 | if (ide_queue_pc_tail(drive, disk, pc)) { |
322 | printk(KERN_ERR PFX "Can't get flexible disk page params\n"); | 322 | printk(KERN_ERR PFX "Can't get flexible disk page params\n"); |
323 | return 1; | 323 | return 1; |
324 | } | 324 | } |
325 | 325 | ||
326 | if (pc->buf[3] & 0x80) | 326 | if (pc->buf[3] & 0x80) |
327 | drive->dev_flags |= IDE_DFLAG_WP; | 327 | drive->dev_flags |= IDE_DFLAG_WP; |
328 | else | 328 | else |
329 | drive->dev_flags &= ~IDE_DFLAG_WP; | 329 | drive->dev_flags &= ~IDE_DFLAG_WP; |
330 | 330 | ||
331 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); | 331 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); |
332 | 332 | ||
333 | page = &pc->buf[8]; | 333 | page = &pc->buf[8]; |
334 | 334 | ||
335 | transfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]); | 335 | transfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]); |
336 | sector_size = be16_to_cpup((__be16 *)&pc->buf[8 + 6]); | 336 | sector_size = be16_to_cpup((__be16 *)&pc->buf[8 + 6]); |
337 | cyls = be16_to_cpup((__be16 *)&pc->buf[8 + 8]); | 337 | cyls = be16_to_cpup((__be16 *)&pc->buf[8 + 8]); |
338 | rpm = be16_to_cpup((__be16 *)&pc->buf[8 + 28]); | 338 | rpm = be16_to_cpup((__be16 *)&pc->buf[8 + 28]); |
339 | heads = pc->buf[8 + 4]; | 339 | heads = pc->buf[8 + 4]; |
340 | sectors = pc->buf[8 + 5]; | 340 | sectors = pc->buf[8 + 5]; |
341 | 341 | ||
342 | capacity = cyls * heads * sectors * sector_size; | 342 | capacity = cyls * heads * sectors * sector_size; |
343 | 343 | ||
344 | if (memcmp(page, &floppy->flexible_disk_page, 32)) | 344 | if (memcmp(page, &floppy->flexible_disk_page, 32)) |
345 | printk(KERN_INFO PFX "%s: %dkB, %d/%d/%d CHS, %d kBps, " | 345 | printk(KERN_INFO PFX "%s: %dkB, %d/%d/%d CHS, %d kBps, " |
346 | "%d sector size, %d rpm\n", | 346 | "%d sector size, %d rpm\n", |
347 | drive->name, capacity / 1024, cyls, heads, | 347 | drive->name, capacity / 1024, cyls, heads, |
348 | sectors, transfer_rate / 8, sector_size, rpm); | 348 | sectors, transfer_rate / 8, sector_size, rpm); |
349 | 349 | ||
350 | memcpy(&floppy->flexible_disk_page, page, 32); | 350 | memcpy(&floppy->flexible_disk_page, page, 32); |
351 | drive->bios_cyl = cyls; | 351 | drive->bios_cyl = cyls; |
352 | drive->bios_head = heads; | 352 | drive->bios_head = heads; |
353 | drive->bios_sect = sectors; | 353 | drive->bios_sect = sectors; |
354 | lba_capacity = floppy->blocks * floppy->block_size; | 354 | lba_capacity = floppy->blocks * floppy->block_size; |
355 | 355 | ||
356 | if (capacity < lba_capacity) { | 356 | if (capacity < lba_capacity) { |
357 | printk(KERN_NOTICE PFX "%s: The disk reports a capacity of %d " | 357 | printk(KERN_NOTICE PFX "%s: The disk reports a capacity of %d " |
358 | "bytes, but the drive only handles %d\n", | 358 | "bytes, but the drive only handles %d\n", |
359 | drive->name, lba_capacity, capacity); | 359 | drive->name, lba_capacity, capacity); |
360 | floppy->blocks = floppy->block_size ? | 360 | floppy->blocks = floppy->block_size ? |
361 | capacity / floppy->block_size : 0; | 361 | capacity / floppy->block_size : 0; |
362 | drive->capacity64 = floppy->blocks * floppy->bs_factor; | 362 | drive->capacity64 = floppy->blocks * floppy->bs_factor; |
363 | } | 363 | } |
364 | 364 | ||
365 | return 0; | 365 | return 0; |
366 | } | 366 | } |
367 | 367 | ||
368 | /* | 368 | /* |
369 | * Determine if a media is present in the floppy drive, and if so, its LBA | 369 | * Determine if a media is present in the floppy drive, and if so, its LBA |
370 | * capacity. | 370 | * capacity. |
371 | */ | 371 | */ |
372 | static int ide_floppy_get_capacity(ide_drive_t *drive) | 372 | static int ide_floppy_get_capacity(ide_drive_t *drive) |
373 | { | 373 | { |
374 | struct ide_disk_obj *floppy = drive->driver_data; | 374 | struct ide_disk_obj *floppy = drive->driver_data; |
375 | struct gendisk *disk = floppy->disk; | 375 | struct gendisk *disk = floppy->disk; |
376 | struct ide_atapi_pc pc; | 376 | struct ide_atapi_pc pc; |
377 | u8 *cap_desc; | 377 | u8 *cap_desc; |
378 | u8 pc_buf[256], header_len, desc_cnt; | 378 | u8 pc_buf[256], header_len, desc_cnt; |
379 | int i, rc = 1, blocks, length; | 379 | int i, rc = 1, blocks, length; |
380 | 380 | ||
381 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 381 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
382 | 382 | ||
383 | drive->bios_cyl = 0; | 383 | drive->bios_cyl = 0; |
384 | drive->bios_head = drive->bios_sect = 0; | 384 | drive->bios_head = drive->bios_sect = 0; |
385 | floppy->blocks = 0; | 385 | floppy->blocks = 0; |
386 | floppy->bs_factor = 1; | 386 | floppy->bs_factor = 1; |
387 | drive->capacity64 = 0; | 387 | drive->capacity64 = 0; |
388 | 388 | ||
389 | ide_floppy_create_read_capacity_cmd(&pc); | 389 | ide_floppy_create_read_capacity_cmd(&pc); |
390 | pc.buf = &pc_buf[0]; | 390 | pc.buf = &pc_buf[0]; |
391 | pc.buf_size = sizeof(pc_buf); | 391 | pc.buf_size = sizeof(pc_buf); |
392 | 392 | ||
393 | if (ide_queue_pc_tail(drive, disk, &pc)) { | 393 | if (ide_queue_pc_tail(drive, disk, &pc)) { |
394 | printk(KERN_ERR PFX "Can't get floppy parameters\n"); | 394 | printk(KERN_ERR PFX "Can't get floppy parameters\n"); |
395 | return 1; | 395 | return 1; |
396 | } | 396 | } |
397 | header_len = pc.buf[3]; | 397 | header_len = pc.buf[3]; |
398 | cap_desc = &pc.buf[4]; | 398 | cap_desc = &pc.buf[4]; |
399 | desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ | 399 | desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ |
400 | 400 | ||
401 | for (i = 0; i < desc_cnt; i++) { | 401 | for (i = 0; i < desc_cnt; i++) { |
402 | unsigned int desc_start = 4 + i*8; | 402 | unsigned int desc_start = 4 + i*8; |
403 | 403 | ||
404 | blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); | 404 | blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); |
405 | length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); | 405 | length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); |
406 | 406 | ||
407 | ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " | 407 | ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " |
408 | "%d sector size", | 408 | "%d sector size", |
409 | i, blocks * length / 1024, | 409 | i, blocks * length / 1024, |
410 | blocks, length); | 410 | blocks, length); |
411 | 411 | ||
412 | if (i) | 412 | if (i) |
413 | continue; | 413 | continue; |
414 | /* | 414 | /* |
415 | * the code below is valid only for the 1st descriptor, ie i=0 | 415 | * the code below is valid only for the 1st descriptor, ie i=0 |
416 | */ | 416 | */ |
417 | 417 | ||
418 | switch (pc.buf[desc_start + 4] & 0x03) { | 418 | switch (pc.buf[desc_start + 4] & 0x03) { |
419 | /* Clik! drive returns this instead of CAPACITY_CURRENT */ | 419 | /* Clik! drive returns this instead of CAPACITY_CURRENT */ |
420 | case CAPACITY_UNFORMATTED: | 420 | case CAPACITY_UNFORMATTED: |
421 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) | 421 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
422 | /* | 422 | /* |
423 | * If it is not a clik drive, break out | 423 | * If it is not a clik drive, break out |
424 | * (maintains previous driver behaviour) | 424 | * (maintains previous driver behaviour) |
425 | */ | 425 | */ |
426 | break; | 426 | break; |
427 | case CAPACITY_CURRENT: | 427 | case CAPACITY_CURRENT: |
428 | /* Normal Zip/LS-120 disks */ | 428 | /* Normal Zip/LS-120 disks */ |
429 | if (memcmp(cap_desc, &floppy->cap_desc, 8)) | 429 | if (memcmp(cap_desc, &floppy->cap_desc, 8)) |
430 | printk(KERN_INFO PFX "%s: %dkB, %d blocks, %d " | 430 | printk(KERN_INFO PFX "%s: %dkB, %d blocks, %d " |
431 | "sector size\n", | 431 | "sector size\n", |
432 | drive->name, blocks * length / 1024, | 432 | drive->name, blocks * length / 1024, |
433 | blocks, length); | 433 | blocks, length); |
434 | memcpy(&floppy->cap_desc, cap_desc, 8); | 434 | memcpy(&floppy->cap_desc, cap_desc, 8); |
435 | 435 | ||
436 | if (!length || length % 512) { | 436 | if (!length || length % 512) { |
437 | printk(KERN_NOTICE PFX "%s: %d bytes block size" | 437 | printk(KERN_NOTICE PFX "%s: %d bytes block size" |
438 | " not supported\n", drive->name, length); | 438 | " not supported\n", drive->name, length); |
439 | } else { | 439 | } else { |
440 | floppy->blocks = blocks; | 440 | floppy->blocks = blocks; |
441 | floppy->block_size = length; | 441 | floppy->block_size = length; |
442 | floppy->bs_factor = length / 512; | 442 | floppy->bs_factor = length / 512; |
443 | if (floppy->bs_factor != 1) | 443 | if (floppy->bs_factor != 1) |
444 | printk(KERN_NOTICE PFX "%s: Warning: " | 444 | printk(KERN_NOTICE PFX "%s: Warning: " |
445 | "non 512 bytes block size not " | 445 | "non 512 bytes block size not " |
446 | "fully supported\n", | 446 | "fully supported\n", |
447 | drive->name); | 447 | drive->name); |
448 | drive->capacity64 = | 448 | drive->capacity64 = |
449 | floppy->blocks * floppy->bs_factor; | 449 | floppy->blocks * floppy->bs_factor; |
450 | rc = 0; | 450 | rc = 0; |
451 | } | 451 | } |
452 | break; | 452 | break; |
453 | case CAPACITY_NO_CARTRIDGE: | 453 | case CAPACITY_NO_CARTRIDGE: |
454 | /* | 454 | /* |
455 | * This is a KERN_ERR so it appears on screen | 455 | * This is a KERN_ERR so it appears on screen |
456 | * for the user to see | 456 | * for the user to see |
457 | */ | 457 | */ |
458 | printk(KERN_ERR PFX "%s: No disk in drive\n", | 458 | printk(KERN_ERR PFX "%s: No disk in drive\n", |
459 | drive->name); | 459 | drive->name); |
460 | break; | 460 | break; |
461 | case CAPACITY_INVALID: | 461 | case CAPACITY_INVALID: |
462 | printk(KERN_ERR PFX "%s: Invalid capacity for disk " | 462 | printk(KERN_ERR PFX "%s: Invalid capacity for disk " |
463 | "in drive\n", drive->name); | 463 | "in drive\n", drive->name); |
464 | break; | 464 | break; |
465 | } | 465 | } |
466 | ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d", | 466 | ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d", |
467 | pc.buf[desc_start + 4] & 0x03); | 467 | pc.buf[desc_start + 4] & 0x03); |
468 | } | 468 | } |
469 | 469 | ||
470 | /* Clik! disk does not support get_flexible_disk_page */ | 470 | /* Clik! disk does not support get_flexible_disk_page */ |
471 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) | 471 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
472 | (void) ide_floppy_get_flexible_disk_page(drive, &pc); | 472 | (void) ide_floppy_get_flexible_disk_page(drive, &pc); |
473 | 473 | ||
474 | return rc; | 474 | return rc; |
475 | } | 475 | } |
476 | 476 | ||
477 | static void ide_floppy_setup(ide_drive_t *drive) | 477 | static void ide_floppy_setup(ide_drive_t *drive) |
478 | { | 478 | { |
479 | struct ide_disk_obj *floppy = drive->driver_data; | 479 | struct ide_disk_obj *floppy = drive->driver_data; |
480 | u16 *id = drive->id; | 480 | u16 *id = drive->id; |
481 | 481 | ||
482 | drive->pc_callback = ide_floppy_callback; | 482 | drive->pc_callback = ide_floppy_callback; |
483 | 483 | ||
484 | /* | 484 | /* |
485 | * We used to check revisions here. At this point however I'm giving up. | 485 | * We used to check revisions here. At this point however I'm giving up. |
486 | * Just assume they are all broken, its easier. | 486 | * Just assume they are all broken, its easier. |
487 | * | 487 | * |
488 | * The actual reason for the workarounds was likely a driver bug after | 488 | * The actual reason for the workarounds was likely a driver bug after |
489 | * all rather than a firmware bug, and the workaround below used to hide | 489 | * all rather than a firmware bug, and the workaround below used to hide |
490 | * it. It should be fixed as of version 1.9, but to be on the safe side | 490 | * it. It should be fixed as of version 1.9, but to be on the safe side |
491 | * we'll leave the limitation below for the 2.2.x tree. | 491 | * we'll leave the limitation below for the 2.2.x tree. |
492 | */ | 492 | */ |
493 | if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) { | 493 | if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) { |
494 | drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; | 494 | drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE; |
495 | /* This value will be visible in the /proc/ide/hdx/settings */ | 495 | /* This value will be visible in the /proc/ide/hdx/settings */ |
496 | drive->pc_delay = IDEFLOPPY_PC_DELAY; | 496 | drive->pc_delay = IDEFLOPPY_PC_DELAY; |
497 | blk_queue_max_sectors(drive->queue, 64); | 497 | blk_queue_max_sectors(drive->queue, 64); |
498 | } | 498 | } |
499 | 499 | ||
500 | /* | 500 | /* |
501 | * Guess what? The IOMEGA Clik! drive also needs the above fix. It makes | 501 | * Guess what? The IOMEGA Clik! drive also needs the above fix. It makes |
502 | * nasty clicking noises without it, so please don't remove this. | 502 | * nasty clicking noises without it, so please don't remove this. |
503 | */ | 503 | */ |
504 | if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) { | 504 | if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) { |
505 | blk_queue_max_sectors(drive->queue, 64); | 505 | blk_queue_max_sectors(drive->queue, 64); |
506 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; | 506 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; |
507 | /* IOMEGA Clik! drives do not support lock/unlock commands */ | 507 | /* IOMEGA Clik! drives do not support lock/unlock commands */ |
508 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | 508 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
509 | } | 509 | } |
510 | 510 | ||
511 | (void) ide_floppy_get_capacity(drive); | 511 | (void) ide_floppy_get_capacity(drive); |
512 | 512 | ||
513 | ide_proc_register_driver(drive, floppy->driver); | 513 | ide_proc_register_driver(drive, floppy->driver); |
514 | 514 | ||
515 | drive->dev_flags |= IDE_DFLAG_ATTACH; | 515 | drive->dev_flags |= IDE_DFLAG_ATTACH; |
516 | } | 516 | } |
517 | 517 | ||
518 | static void ide_floppy_flush(ide_drive_t *drive) | 518 | static void ide_floppy_flush(ide_drive_t *drive) |
519 | { | 519 | { |
520 | } | 520 | } |
521 | 521 | ||
522 | static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) | 522 | static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) |
523 | { | 523 | { |
524 | int ret = 0; | 524 | int ret = 0; |
525 | 525 | ||
526 | if (ide_do_test_unit_ready(drive, disk)) | 526 | if (ide_do_test_unit_ready(drive, disk)) |
527 | ide_do_start_stop(drive, disk, 1); | 527 | ide_do_start_stop(drive, disk, 1); |
528 | 528 | ||
529 | ret = ide_floppy_get_capacity(drive); | 529 | ret = ide_floppy_get_capacity(drive); |
530 | 530 | ||
531 | set_capacity(disk, ide_gd_capacity(drive)); | 531 | set_capacity(disk, ide_gd_capacity(drive)); |
532 | 532 | ||
533 | return ret; | 533 | return ret; |
534 | } | 534 | } |
535 | 535 | ||
536 | const struct ide_disk_ops ide_atapi_disk_ops = { | 536 | const struct ide_disk_ops ide_atapi_disk_ops = { |
537 | .check = ide_check_atapi_device, | 537 | .check = ide_check_atapi_device, |
538 | .get_capacity = ide_floppy_get_capacity, | 538 | .get_capacity = ide_floppy_get_capacity, |
539 | .setup = ide_floppy_setup, | 539 | .setup = ide_floppy_setup, |
540 | .flush = ide_floppy_flush, | 540 | .flush = ide_floppy_flush, |
541 | .init_media = ide_floppy_init_media, | 541 | .init_media = ide_floppy_init_media, |
542 | .set_doorlock = ide_set_media_lock, | 542 | .set_doorlock = ide_set_media_lock, |
543 | .do_request = ide_floppy_do_request, | 543 | .do_request = ide_floppy_do_request, |
544 | .ioctl = ide_floppy_ioctl, | 544 | .ioctl = ide_floppy_ioctl, |
545 | }; | 545 | }; |
546 | 546 |
drivers/ide/ide-io.c
1 | /* | 1 | /* |
2 | * IDE I/O functions | 2 | * IDE I/O functions |
3 | * | 3 | * |
4 | * Basic PIO and command management functionality. | 4 | * Basic PIO and command management functionality. |
5 | * | 5 | * |
6 | * This code was split off from ide.c. See ide.c for history and original | 6 | * This code was split off from ide.c. See ide.c for history and original |
7 | * copyrights. | 7 | * copyrights. |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the | 10 | * under the terms of the GNU General Public License as published by the |
11 | * Free Software Foundation; either version 2, or (at your option) any | 11 | * Free Software Foundation; either version 2, or (at your option) any |
12 | * later version. | 12 | * later version. |
13 | * | 13 | * |
14 | * This program is distributed in the hope that it will be useful, but | 14 | * This program is distributed in the hope that it will be useful, but |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | * General Public License for more details. | 17 | * General Public License for more details. |
18 | * | 18 | * |
19 | * For the avoidance of doubt the "preferred form" of this code is one which | 19 | * For the avoidance of doubt the "preferred form" of this code is one which |
20 | * is in an open non patent encumbered format. Where cryptographic key signing | 20 | * is in an open non patent encumbered format. Where cryptographic key signing |
21 | * forms part of the process of creating an executable the information | 21 | * forms part of the process of creating an executable the information |
22 | * including keys needed to generate an equivalently functional executable | 22 | * including keys needed to generate an equivalently functional executable |
23 | * are deemed to be part of the source code. | 23 | * are deemed to be part of the source code. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | 26 | ||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/timer.h> | 31 | #include <linux/timer.h> |
32 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/major.h> | 34 | #include <linux/major.h> |
35 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
36 | #include <linux/genhd.h> | 36 | #include <linux/genhd.h> |
37 | #include <linux/blkpg.h> | 37 | #include <linux/blkpg.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/ide.h> | 42 | #include <linux/ide.h> |
43 | #include <linux/completion.h> | 43 | #include <linux/completion.h> |
44 | #include <linux/reboot.h> | 44 | #include <linux/reboot.h> |
45 | #include <linux/cdrom.h> | 45 | #include <linux/cdrom.h> |
46 | #include <linux/seq_file.h> | 46 | #include <linux/seq_file.h> |
47 | #include <linux/device.h> | 47 | #include <linux/device.h> |
48 | #include <linux/kmod.h> | 48 | #include <linux/kmod.h> |
49 | #include <linux/scatterlist.h> | 49 | #include <linux/scatterlist.h> |
50 | #include <linux/bitops.h> | 50 | #include <linux/bitops.h> |
51 | 51 | ||
52 | #include <asm/byteorder.h> | 52 | #include <asm/byteorder.h> |
53 | #include <asm/irq.h> | 53 | #include <asm/irq.h> |
54 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
55 | #include <asm/io.h> | 55 | #include <asm/io.h> |
56 | 56 | ||
57 | int ide_end_rq(ide_drive_t *drive, struct request *rq, int error, | 57 | int ide_end_rq(ide_drive_t *drive, struct request *rq, int error, |
58 | unsigned int nr_bytes) | 58 | unsigned int nr_bytes) |
59 | { | 59 | { |
60 | /* | 60 | /* |
61 | * decide whether to reenable DMA -- 3 is a random magic for now, | 61 | * decide whether to reenable DMA -- 3 is a random magic for now, |
62 | * if we DMA timeout more than 3 times, just stay in PIO | 62 | * if we DMA timeout more than 3 times, just stay in PIO |
63 | */ | 63 | */ |
64 | if ((drive->dev_flags & IDE_DFLAG_DMA_PIO_RETRY) && | 64 | if ((drive->dev_flags & IDE_DFLAG_DMA_PIO_RETRY) && |
65 | drive->retry_pio <= 3) { | 65 | drive->retry_pio <= 3) { |
66 | drive->dev_flags &= ~IDE_DFLAG_DMA_PIO_RETRY; | 66 | drive->dev_flags &= ~IDE_DFLAG_DMA_PIO_RETRY; |
67 | ide_dma_on(drive); | 67 | ide_dma_on(drive); |
68 | } | 68 | } |
69 | 69 | ||
70 | return blk_end_request(rq, error, nr_bytes); | 70 | return blk_end_request(rq, error, nr_bytes); |
71 | } | 71 | } |
72 | EXPORT_SYMBOL_GPL(ide_end_rq); | 72 | EXPORT_SYMBOL_GPL(ide_end_rq); |
73 | 73 | ||
74 | void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err) | 74 | void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err) |
75 | { | 75 | { |
76 | const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops; | 76 | const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops; |
77 | struct ide_taskfile *tf = &cmd->tf; | 77 | struct ide_taskfile *tf = &cmd->tf; |
78 | struct request *rq = cmd->rq; | 78 | struct request *rq = cmd->rq; |
79 | u8 tf_cmd = tf->command; | 79 | u8 tf_cmd = tf->command; |
80 | 80 | ||
81 | tf->error = err; | 81 | tf->error = err; |
82 | tf->status = stat; | 82 | tf->status = stat; |
83 | 83 | ||
84 | if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { | 84 | if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) { |
85 | u8 data[2]; | 85 | u8 data[2]; |
86 | 86 | ||
87 | tp_ops->input_data(drive, cmd, data, 2); | 87 | tp_ops->input_data(drive, cmd, data, 2); |
88 | 88 | ||
89 | cmd->tf.data = data[0]; | 89 | cmd->tf.data = data[0]; |
90 | cmd->hob.data = data[1]; | 90 | cmd->hob.data = data[1]; |
91 | } | 91 | } |
92 | 92 | ||
93 | ide_tf_readback(drive, cmd); | 93 | ide_tf_readback(drive, cmd); |
94 | 94 | ||
95 | if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) && | 95 | if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) && |
96 | tf_cmd == ATA_CMD_IDLEIMMEDIATE) { | 96 | tf_cmd == ATA_CMD_IDLEIMMEDIATE) { |
97 | if (tf->lbal != 0xc4) { | 97 | if (tf->lbal != 0xc4) { |
98 | printk(KERN_ERR "%s: head unload failed!\n", | 98 | printk(KERN_ERR "%s: head unload failed!\n", |
99 | drive->name); | 99 | drive->name); |
100 | ide_tf_dump(drive->name, cmd); | 100 | ide_tf_dump(drive->name, cmd); |
101 | } else | 101 | } else |
102 | drive->dev_flags |= IDE_DFLAG_PARKED; | 102 | drive->dev_flags |= IDE_DFLAG_PARKED; |
103 | } | 103 | } |
104 | 104 | ||
105 | if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | 105 | if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
106 | struct ide_cmd *orig_cmd = rq->special; | 106 | struct ide_cmd *orig_cmd = rq->special; |
107 | 107 | ||
108 | if (cmd->tf_flags & IDE_TFLAG_DYN) | 108 | if (cmd->tf_flags & IDE_TFLAG_DYN) |
109 | kfree(orig_cmd); | 109 | kfree(orig_cmd); |
110 | else | 110 | else |
111 | memcpy(orig_cmd, cmd, sizeof(*cmd)); | 111 | memcpy(orig_cmd, cmd, sizeof(*cmd)); |
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | /* obsolete, blk_rq_bytes() should be used instead */ | 115 | /* obsolete, blk_rq_bytes() should be used instead */ |
116 | unsigned int ide_rq_bytes(struct request *rq) | 116 | unsigned int ide_rq_bytes(struct request *rq) |
117 | { | 117 | { |
118 | if (blk_pc_request(rq)) | 118 | if (blk_pc_request(rq)) |
119 | return rq->data_len; | 119 | return blk_rq_bytes(rq); |
120 | else | 120 | else |
121 | return blk_rq_cur_sectors(rq) << 9; | 121 | return blk_rq_cur_sectors(rq) << 9; |
122 | } | 122 | } |
123 | EXPORT_SYMBOL_GPL(ide_rq_bytes); | 123 | EXPORT_SYMBOL_GPL(ide_rq_bytes); |
124 | 124 | ||
125 | int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes) | 125 | int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes) |
126 | { | 126 | { |
127 | ide_hwif_t *hwif = drive->hwif; | 127 | ide_hwif_t *hwif = drive->hwif; |
128 | struct request *rq = hwif->rq; | 128 | struct request *rq = hwif->rq; |
129 | int rc; | 129 | int rc; |
130 | 130 | ||
131 | /* | 131 | /* |
132 | * if failfast is set on a request, override number of sectors | 132 | * if failfast is set on a request, override number of sectors |
133 | * and complete the whole request right now | 133 | * and complete the whole request right now |
134 | */ | 134 | */ |
135 | if (blk_noretry_request(rq) && error <= 0) | 135 | if (blk_noretry_request(rq) && error <= 0) |
136 | nr_bytes = blk_rq_sectors(rq) << 9; | 136 | nr_bytes = blk_rq_sectors(rq) << 9; |
137 | 137 | ||
138 | rc = ide_end_rq(drive, rq, error, nr_bytes); | 138 | rc = ide_end_rq(drive, rq, error, nr_bytes); |
139 | if (rc == 0) | 139 | if (rc == 0) |
140 | hwif->rq = NULL; | 140 | hwif->rq = NULL; |
141 | 141 | ||
142 | return rc; | 142 | return rc; |
143 | } | 143 | } |
144 | EXPORT_SYMBOL(ide_complete_rq); | 144 | EXPORT_SYMBOL(ide_complete_rq); |
145 | 145 | ||
146 | void ide_kill_rq(ide_drive_t *drive, struct request *rq) | 146 | void ide_kill_rq(ide_drive_t *drive, struct request *rq) |
147 | { | 147 | { |
148 | u8 drv_req = blk_special_request(rq) && rq->rq_disk; | 148 | u8 drv_req = blk_special_request(rq) && rq->rq_disk; |
149 | u8 media = drive->media; | 149 | u8 media = drive->media; |
150 | 150 | ||
151 | drive->failed_pc = NULL; | 151 | drive->failed_pc = NULL; |
152 | 152 | ||
153 | if ((media == ide_floppy || media == ide_tape) && drv_req) { | 153 | if ((media == ide_floppy || media == ide_tape) && drv_req) { |
154 | rq->errors = 0; | 154 | rq->errors = 0; |
155 | ide_complete_rq(drive, 0, blk_rq_bytes(rq)); | 155 | ide_complete_rq(drive, 0, blk_rq_bytes(rq)); |
156 | } else { | 156 | } else { |
157 | if (media == ide_tape) | 157 | if (media == ide_tape) |
158 | rq->errors = IDE_DRV_ERROR_GENERAL; | 158 | rq->errors = IDE_DRV_ERROR_GENERAL; |
159 | else if (blk_fs_request(rq) == 0 && rq->errors == 0) | 159 | else if (blk_fs_request(rq) == 0 && rq->errors == 0) |
160 | rq->errors = -EIO; | 160 | rq->errors = -EIO; |
161 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); | 161 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); |
162 | } | 162 | } |
163 | } | 163 | } |
164 | 164 | ||
165 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 165 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
166 | { | 166 | { |
167 | tf->nsect = drive->sect; | 167 | tf->nsect = drive->sect; |
168 | tf->lbal = drive->sect; | 168 | tf->lbal = drive->sect; |
169 | tf->lbam = drive->cyl; | 169 | tf->lbam = drive->cyl; |
170 | tf->lbah = drive->cyl >> 8; | 170 | tf->lbah = drive->cyl >> 8; |
171 | tf->device = (drive->head - 1) | drive->select; | 171 | tf->device = (drive->head - 1) | drive->select; |
172 | tf->command = ATA_CMD_INIT_DEV_PARAMS; | 172 | tf->command = ATA_CMD_INIT_DEV_PARAMS; |
173 | } | 173 | } |
174 | 174 | ||
175 | static void ide_tf_set_restore_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 175 | static void ide_tf_set_restore_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
176 | { | 176 | { |
177 | tf->nsect = drive->sect; | 177 | tf->nsect = drive->sect; |
178 | tf->command = ATA_CMD_RESTORE; | 178 | tf->command = ATA_CMD_RESTORE; |
179 | } | 179 | } |
180 | 180 | ||
181 | static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 181 | static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
182 | { | 182 | { |
183 | tf->nsect = drive->mult_req; | 183 | tf->nsect = drive->mult_req; |
184 | tf->command = ATA_CMD_SET_MULTI; | 184 | tf->command = ATA_CMD_SET_MULTI; |
185 | } | 185 | } |
186 | 186 | ||
187 | static ide_startstop_t ide_disk_special(ide_drive_t *drive) | 187 | static ide_startstop_t ide_disk_special(ide_drive_t *drive) |
188 | { | 188 | { |
189 | special_t *s = &drive->special; | 189 | special_t *s = &drive->special; |
190 | struct ide_cmd cmd; | 190 | struct ide_cmd cmd; |
191 | 191 | ||
192 | memset(&cmd, 0, sizeof(cmd)); | 192 | memset(&cmd, 0, sizeof(cmd)); |
193 | cmd.protocol = ATA_PROT_NODATA; | 193 | cmd.protocol = ATA_PROT_NODATA; |
194 | 194 | ||
195 | if (s->b.set_geometry) { | 195 | if (s->b.set_geometry) { |
196 | s->b.set_geometry = 0; | 196 | s->b.set_geometry = 0; |
197 | ide_tf_set_specify_cmd(drive, &cmd.tf); | 197 | ide_tf_set_specify_cmd(drive, &cmd.tf); |
198 | } else if (s->b.recalibrate) { | 198 | } else if (s->b.recalibrate) { |
199 | s->b.recalibrate = 0; | 199 | s->b.recalibrate = 0; |
200 | ide_tf_set_restore_cmd(drive, &cmd.tf); | 200 | ide_tf_set_restore_cmd(drive, &cmd.tf); |
201 | } else if (s->b.set_multmode) { | 201 | } else if (s->b.set_multmode) { |
202 | s->b.set_multmode = 0; | 202 | s->b.set_multmode = 0; |
203 | ide_tf_set_setmult_cmd(drive, &cmd.tf); | 203 | ide_tf_set_setmult_cmd(drive, &cmd.tf); |
204 | } else if (s->all) { | 204 | } else if (s->all) { |
205 | int special = s->all; | 205 | int special = s->all; |
206 | s->all = 0; | 206 | s->all = 0; |
207 | printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special); | 207 | printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special); |
208 | return ide_stopped; | 208 | return ide_stopped; |
209 | } | 209 | } |
210 | 210 | ||
211 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; | 211 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
212 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | 212 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; |
213 | cmd.tf_flags = IDE_TFLAG_CUSTOM_HANDLER; | 213 | cmd.tf_flags = IDE_TFLAG_CUSTOM_HANDLER; |
214 | 214 | ||
215 | do_rw_taskfile(drive, &cmd); | 215 | do_rw_taskfile(drive, &cmd); |
216 | 216 | ||
217 | return ide_started; | 217 | return ide_started; |
218 | } | 218 | } |
219 | 219 | ||
220 | /** | 220 | /** |
221 | * do_special - issue some special commands | 221 | * do_special - issue some special commands |
222 | * @drive: drive the command is for | 222 | * @drive: drive the command is for |
223 | * | 223 | * |
224 | * do_special() is used to issue ATA_CMD_INIT_DEV_PARAMS, | 224 | * do_special() is used to issue ATA_CMD_INIT_DEV_PARAMS, |
225 | * ATA_CMD_RESTORE and ATA_CMD_SET_MULTI commands to a drive. | 225 | * ATA_CMD_RESTORE and ATA_CMD_SET_MULTI commands to a drive. |
226 | * | 226 | * |
227 | * It used to do much more, but has been scaled back. | 227 | * It used to do much more, but has been scaled back. |
228 | */ | 228 | */ |
229 | 229 | ||
230 | static ide_startstop_t do_special (ide_drive_t *drive) | 230 | static ide_startstop_t do_special (ide_drive_t *drive) |
231 | { | 231 | { |
232 | special_t *s = &drive->special; | 232 | special_t *s = &drive->special; |
233 | 233 | ||
234 | #ifdef DEBUG | 234 | #ifdef DEBUG |
235 | printk("%s: do_special: 0x%02x\n", drive->name, s->all); | 235 | printk("%s: do_special: 0x%02x\n", drive->name, s->all); |
236 | #endif | 236 | #endif |
237 | if (drive->media == ide_disk) | 237 | if (drive->media == ide_disk) |
238 | return ide_disk_special(drive); | 238 | return ide_disk_special(drive); |
239 | 239 | ||
240 | s->all = 0; | 240 | s->all = 0; |
241 | drive->mult_req = 0; | 241 | drive->mult_req = 0; |
242 | return ide_stopped; | 242 | return ide_stopped; |
243 | } | 243 | } |
244 | 244 | ||
245 | void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) | 245 | void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) |
246 | { | 246 | { |
247 | ide_hwif_t *hwif = drive->hwif; | 247 | ide_hwif_t *hwif = drive->hwif; |
248 | struct scatterlist *sg = hwif->sg_table; | 248 | struct scatterlist *sg = hwif->sg_table; |
249 | struct request *rq = cmd->rq; | 249 | struct request *rq = cmd->rq; |
250 | 250 | ||
251 | cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); | 251 | cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); |
252 | } | 252 | } |
253 | EXPORT_SYMBOL_GPL(ide_map_sg); | 253 | EXPORT_SYMBOL_GPL(ide_map_sg); |
254 | 254 | ||
255 | void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes) | 255 | void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes) |
256 | { | 256 | { |
257 | cmd->nbytes = cmd->nleft = nr_bytes; | 257 | cmd->nbytes = cmd->nleft = nr_bytes; |
258 | cmd->cursg_ofs = 0; | 258 | cmd->cursg_ofs = 0; |
259 | cmd->cursg = NULL; | 259 | cmd->cursg = NULL; |
260 | } | 260 | } |
261 | EXPORT_SYMBOL_GPL(ide_init_sg_cmd); | 261 | EXPORT_SYMBOL_GPL(ide_init_sg_cmd); |
262 | 262 | ||
263 | /** | 263 | /** |
264 | * execute_drive_command - issue special drive command | 264 | * execute_drive_command - issue special drive command |
265 | * @drive: the drive to issue the command on | 265 | * @drive: the drive to issue the command on |
266 | * @rq: the request structure holding the command | 266 | * @rq: the request structure holding the command |
267 | * | 267 | * |
268 | * execute_drive_cmd() issues a special drive command, usually | 268 | * execute_drive_cmd() issues a special drive command, usually |
269 | * initiated by ioctl() from the external hdparm program. The | 269 | * initiated by ioctl() from the external hdparm program. The |
270 | * command can be a drive command, drive task or taskfile | 270 | * command can be a drive command, drive task or taskfile |
271 | * operation. Weirdly you can call it with NULL to wait for | 271 | * operation. Weirdly you can call it with NULL to wait for |
272 | * all commands to finish. Don't do this as that is due to change | 272 | * all commands to finish. Don't do this as that is due to change |
273 | */ | 273 | */ |
274 | 274 | ||
275 | static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | 275 | static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, |
276 | struct request *rq) | 276 | struct request *rq) |
277 | { | 277 | { |
278 | struct ide_cmd *cmd = rq->special; | 278 | struct ide_cmd *cmd = rq->special; |
279 | 279 | ||
280 | if (cmd) { | 280 | if (cmd) { |
281 | if (cmd->protocol == ATA_PROT_PIO) { | 281 | if (cmd->protocol == ATA_PROT_PIO) { |
282 | ide_init_sg_cmd(cmd, blk_rq_sectors(rq) << 9); | 282 | ide_init_sg_cmd(cmd, blk_rq_sectors(rq) << 9); |
283 | ide_map_sg(drive, cmd); | 283 | ide_map_sg(drive, cmd); |
284 | } | 284 | } |
285 | 285 | ||
286 | return do_rw_taskfile(drive, cmd); | 286 | return do_rw_taskfile(drive, cmd); |
287 | } | 287 | } |
288 | 288 | ||
289 | /* | 289 | /* |
290 | * NULL is actually a valid way of waiting for | 290 | * NULL is actually a valid way of waiting for |
291 | * all current requests to be flushed from the queue. | 291 | * all current requests to be flushed from the queue. |
292 | */ | 292 | */ |
293 | #ifdef DEBUG | 293 | #ifdef DEBUG |
294 | printk("%s: DRIVE_CMD (null)\n", drive->name); | 294 | printk("%s: DRIVE_CMD (null)\n", drive->name); |
295 | #endif | 295 | #endif |
296 | rq->errors = 0; | 296 | rq->errors = 0; |
297 | ide_complete_rq(drive, 0, blk_rq_bytes(rq)); | 297 | ide_complete_rq(drive, 0, blk_rq_bytes(rq)); |
298 | 298 | ||
299 | return ide_stopped; | 299 | return ide_stopped; |
300 | } | 300 | } |
301 | 301 | ||
302 | static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) | 302 | static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) |
303 | { | 303 | { |
304 | u8 cmd = rq->cmd[0]; | 304 | u8 cmd = rq->cmd[0]; |
305 | 305 | ||
306 | switch (cmd) { | 306 | switch (cmd) { |
307 | case REQ_PARK_HEADS: | 307 | case REQ_PARK_HEADS: |
308 | case REQ_UNPARK_HEADS: | 308 | case REQ_UNPARK_HEADS: |
309 | return ide_do_park_unpark(drive, rq); | 309 | return ide_do_park_unpark(drive, rq); |
310 | case REQ_DEVSET_EXEC: | 310 | case REQ_DEVSET_EXEC: |
311 | return ide_do_devset(drive, rq); | 311 | return ide_do_devset(drive, rq); |
312 | case REQ_DRIVE_RESET: | 312 | case REQ_DRIVE_RESET: |
313 | return ide_do_reset(drive); | 313 | return ide_do_reset(drive); |
314 | default: | 314 | default: |
315 | BUG(); | 315 | BUG(); |
316 | } | 316 | } |
317 | } | 317 | } |
318 | 318 | ||
319 | /** | 319 | /** |
320 | * start_request - start of I/O and command issuing for IDE | 320 | * start_request - start of I/O and command issuing for IDE |
321 | * | 321 | * |
322 | * start_request() initiates handling of a new I/O request. It | 322 | * start_request() initiates handling of a new I/O request. It |
323 | * accepts commands and I/O (read/write) requests. | 323 | * accepts commands and I/O (read/write) requests. |
324 | * | 324 | * |
325 | * FIXME: this function needs a rename | 325 | * FIXME: this function needs a rename |
326 | */ | 326 | */ |
327 | 327 | ||
328 | static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | 328 | static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) |
329 | { | 329 | { |
330 | ide_startstop_t startstop; | 330 | ide_startstop_t startstop; |
331 | 331 | ||
332 | BUG_ON(!blk_rq_started(rq)); | 332 | BUG_ON(!blk_rq_started(rq)); |
333 | 333 | ||
334 | #ifdef DEBUG | 334 | #ifdef DEBUG |
335 | printk("%s: start_request: current=0x%08lx\n", | 335 | printk("%s: start_request: current=0x%08lx\n", |
336 | drive->hwif->name, (unsigned long) rq); | 336 | drive->hwif->name, (unsigned long) rq); |
337 | #endif | 337 | #endif |
338 | 338 | ||
339 | /* bail early if we've exceeded max_failures */ | 339 | /* bail early if we've exceeded max_failures */ |
340 | if (drive->max_failures && (drive->failures > drive->max_failures)) { | 340 | if (drive->max_failures && (drive->failures > drive->max_failures)) { |
341 | rq->cmd_flags |= REQ_FAILED; | 341 | rq->cmd_flags |= REQ_FAILED; |
342 | goto kill_rq; | 342 | goto kill_rq; |
343 | } | 343 | } |
344 | 344 | ||
345 | if (blk_pm_request(rq)) | 345 | if (blk_pm_request(rq)) |
346 | ide_check_pm_state(drive, rq); | 346 | ide_check_pm_state(drive, rq); |
347 | 347 | ||
348 | drive->hwif->tp_ops->dev_select(drive); | 348 | drive->hwif->tp_ops->dev_select(drive); |
349 | if (ide_wait_stat(&startstop, drive, drive->ready_stat, | 349 | if (ide_wait_stat(&startstop, drive, drive->ready_stat, |
350 | ATA_BUSY | ATA_DRQ, WAIT_READY)) { | 350 | ATA_BUSY | ATA_DRQ, WAIT_READY)) { |
351 | printk(KERN_ERR "%s: drive not ready for command\n", drive->name); | 351 | printk(KERN_ERR "%s: drive not ready for command\n", drive->name); |
352 | return startstop; | 352 | return startstop; |
353 | } | 353 | } |
354 | if (!drive->special.all) { | 354 | if (!drive->special.all) { |
355 | struct ide_driver *drv; | 355 | struct ide_driver *drv; |
356 | 356 | ||
357 | /* | 357 | /* |
358 | * We reset the drive so we need to issue a SETFEATURES. | 358 | * We reset the drive so we need to issue a SETFEATURES. |
359 | * Do it _after_ do_special() restored device parameters. | 359 | * Do it _after_ do_special() restored device parameters. |
360 | */ | 360 | */ |
361 | if (drive->current_speed == 0xff) | 361 | if (drive->current_speed == 0xff) |
362 | ide_config_drive_speed(drive, drive->desired_speed); | 362 | ide_config_drive_speed(drive, drive->desired_speed); |
363 | 363 | ||
364 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) | 364 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) |
365 | return execute_drive_cmd(drive, rq); | 365 | return execute_drive_cmd(drive, rq); |
366 | else if (blk_pm_request(rq)) { | 366 | else if (blk_pm_request(rq)) { |
367 | struct request_pm_state *pm = rq->special; | 367 | struct request_pm_state *pm = rq->special; |
368 | #ifdef DEBUG_PM | 368 | #ifdef DEBUG_PM |
369 | printk("%s: start_power_step(step: %d)\n", | 369 | printk("%s: start_power_step(step: %d)\n", |
370 | drive->name, pm->pm_step); | 370 | drive->name, pm->pm_step); |
371 | #endif | 371 | #endif |
372 | startstop = ide_start_power_step(drive, rq); | 372 | startstop = ide_start_power_step(drive, rq); |
373 | if (startstop == ide_stopped && | 373 | if (startstop == ide_stopped && |
374 | pm->pm_step == IDE_PM_COMPLETED) | 374 | pm->pm_step == IDE_PM_COMPLETED) |
375 | ide_complete_pm_rq(drive, rq); | 375 | ide_complete_pm_rq(drive, rq); |
376 | return startstop; | 376 | return startstop; |
377 | } else if (!rq->rq_disk && blk_special_request(rq)) | 377 | } else if (!rq->rq_disk && blk_special_request(rq)) |
378 | /* | 378 | /* |
379 | * TODO: Once all ULDs have been modified to | 379 | * TODO: Once all ULDs have been modified to |
380 | * check for specific op codes rather than | 380 | * check for specific op codes rather than |
381 | * blindly accepting any special request, the | 381 | * blindly accepting any special request, the |
382 | * check for ->rq_disk above may be replaced | 382 | * check for ->rq_disk above may be replaced |
383 | * by a more suitable mechanism or even | 383 | * by a more suitable mechanism or even |
384 | * dropped entirely. | 384 | * dropped entirely. |
385 | */ | 385 | */ |
386 | return ide_special_rq(drive, rq); | 386 | return ide_special_rq(drive, rq); |
387 | 387 | ||
388 | drv = *(struct ide_driver **)rq->rq_disk->private_data; | 388 | drv = *(struct ide_driver **)rq->rq_disk->private_data; |
389 | 389 | ||
390 | return drv->do_request(drive, rq, blk_rq_pos(rq)); | 390 | return drv->do_request(drive, rq, blk_rq_pos(rq)); |
391 | } | 391 | } |
392 | return do_special(drive); | 392 | return do_special(drive); |
393 | kill_rq: | 393 | kill_rq: |
394 | ide_kill_rq(drive, rq); | 394 | ide_kill_rq(drive, rq); |
395 | return ide_stopped; | 395 | return ide_stopped; |
396 | } | 396 | } |
397 | 397 | ||
398 | /** | 398 | /** |
399 | * ide_stall_queue - pause an IDE device | 399 | * ide_stall_queue - pause an IDE device |
400 | * @drive: drive to stall | 400 | * @drive: drive to stall |
401 | * @timeout: time to stall for (jiffies) | 401 | * @timeout: time to stall for (jiffies) |
402 | * | 402 | * |
403 | * ide_stall_queue() can be used by a drive to give excess bandwidth back | 403 | * ide_stall_queue() can be used by a drive to give excess bandwidth back |
404 | * to the port by sleeping for timeout jiffies. | 404 | * to the port by sleeping for timeout jiffies. |
405 | */ | 405 | */ |
406 | 406 | ||
407 | void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) | 407 | void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) |
408 | { | 408 | { |
409 | if (timeout > WAIT_WORSTCASE) | 409 | if (timeout > WAIT_WORSTCASE) |
410 | timeout = WAIT_WORSTCASE; | 410 | timeout = WAIT_WORSTCASE; |
411 | drive->sleep = timeout + jiffies; | 411 | drive->sleep = timeout + jiffies; |
412 | drive->dev_flags |= IDE_DFLAG_SLEEPING; | 412 | drive->dev_flags |= IDE_DFLAG_SLEEPING; |
413 | } | 413 | } |
414 | EXPORT_SYMBOL(ide_stall_queue); | 414 | EXPORT_SYMBOL(ide_stall_queue); |
415 | 415 | ||
416 | static inline int ide_lock_port(ide_hwif_t *hwif) | 416 | static inline int ide_lock_port(ide_hwif_t *hwif) |
417 | { | 417 | { |
418 | if (hwif->busy) | 418 | if (hwif->busy) |
419 | return 1; | 419 | return 1; |
420 | 420 | ||
421 | hwif->busy = 1; | 421 | hwif->busy = 1; |
422 | 422 | ||
423 | return 0; | 423 | return 0; |
424 | } | 424 | } |
425 | 425 | ||
426 | static inline void ide_unlock_port(ide_hwif_t *hwif) | 426 | static inline void ide_unlock_port(ide_hwif_t *hwif) |
427 | { | 427 | { |
428 | hwif->busy = 0; | 428 | hwif->busy = 0; |
429 | } | 429 | } |
430 | 430 | ||
431 | static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif) | 431 | static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif) |
432 | { | 432 | { |
433 | int rc = 0; | 433 | int rc = 0; |
434 | 434 | ||
435 | if (host->host_flags & IDE_HFLAG_SERIALIZE) { | 435 | if (host->host_flags & IDE_HFLAG_SERIALIZE) { |
436 | rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy); | 436 | rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy); |
437 | if (rc == 0) { | 437 | if (rc == 0) { |
438 | if (host->get_lock) | 438 | if (host->get_lock) |
439 | host->get_lock(ide_intr, hwif); | 439 | host->get_lock(ide_intr, hwif); |
440 | } | 440 | } |
441 | } | 441 | } |
442 | return rc; | 442 | return rc; |
443 | } | 443 | } |
444 | 444 | ||
445 | static inline void ide_unlock_host(struct ide_host *host) | 445 | static inline void ide_unlock_host(struct ide_host *host) |
446 | { | 446 | { |
447 | if (host->host_flags & IDE_HFLAG_SERIALIZE) { | 447 | if (host->host_flags & IDE_HFLAG_SERIALIZE) { |
448 | if (host->release_lock) | 448 | if (host->release_lock) |
449 | host->release_lock(); | 449 | host->release_lock(); |
450 | clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy); | 450 | clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy); |
451 | } | 451 | } |
452 | } | 452 | } |
453 | 453 | ||
454 | /* | 454 | /* |
455 | * Issue a new request to a device. | 455 | * Issue a new request to a device. |
456 | */ | 456 | */ |
457 | void do_ide_request(struct request_queue *q) | 457 | void do_ide_request(struct request_queue *q) |
458 | { | 458 | { |
459 | ide_drive_t *drive = q->queuedata; | 459 | ide_drive_t *drive = q->queuedata; |
460 | ide_hwif_t *hwif = drive->hwif; | 460 | ide_hwif_t *hwif = drive->hwif; |
461 | struct ide_host *host = hwif->host; | 461 | struct ide_host *host = hwif->host; |
462 | struct request *rq = NULL; | 462 | struct request *rq = NULL; |
463 | ide_startstop_t startstop; | 463 | ide_startstop_t startstop; |
464 | 464 | ||
465 | /* | 465 | /* |
466 | * drive is doing pre-flush, ordered write, post-flush sequence. even | 466 | * drive is doing pre-flush, ordered write, post-flush sequence. even |
467 | * though that is 3 requests, it must be seen as a single transaction. | 467 | * though that is 3 requests, it must be seen as a single transaction. |
468 | * we must not preempt this drive until that is complete | 468 | * we must not preempt this drive until that is complete |
469 | */ | 469 | */ |
470 | if (blk_queue_flushing(q)) | 470 | if (blk_queue_flushing(q)) |
471 | /* | 471 | /* |
472 | * small race where queue could get replugged during | 472 | * small race where queue could get replugged during |
473 | * the 3-request flush cycle, just yank the plug since | 473 | * the 3-request flush cycle, just yank the plug since |
474 | * we want it to finish asap | 474 | * we want it to finish asap |
475 | */ | 475 | */ |
476 | blk_remove_plug(q); | 476 | blk_remove_plug(q); |
477 | 477 | ||
478 | spin_unlock_irq(q->queue_lock); | 478 | spin_unlock_irq(q->queue_lock); |
479 | 479 | ||
480 | /* HLD do_request() callback might sleep, make sure it's okay */ | 480 | /* HLD do_request() callback might sleep, make sure it's okay */ |
481 | might_sleep(); | 481 | might_sleep(); |
482 | 482 | ||
483 | if (ide_lock_host(host, hwif)) | 483 | if (ide_lock_host(host, hwif)) |
484 | goto plug_device_2; | 484 | goto plug_device_2; |
485 | 485 | ||
486 | spin_lock_irq(&hwif->lock); | 486 | spin_lock_irq(&hwif->lock); |
487 | 487 | ||
488 | if (!ide_lock_port(hwif)) { | 488 | if (!ide_lock_port(hwif)) { |
489 | ide_hwif_t *prev_port; | 489 | ide_hwif_t *prev_port; |
490 | repeat: | 490 | repeat: |
491 | prev_port = hwif->host->cur_port; | 491 | prev_port = hwif->host->cur_port; |
492 | hwif->rq = NULL; | 492 | hwif->rq = NULL; |
493 | 493 | ||
494 | if (drive->dev_flags & IDE_DFLAG_SLEEPING && | 494 | if (drive->dev_flags & IDE_DFLAG_SLEEPING && |
495 | time_after(drive->sleep, jiffies)) { | 495 | time_after(drive->sleep, jiffies)) { |
496 | ide_unlock_port(hwif); | 496 | ide_unlock_port(hwif); |
497 | goto plug_device; | 497 | goto plug_device; |
498 | } | 498 | } |
499 | 499 | ||
500 | if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) && | 500 | if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) && |
501 | hwif != prev_port) { | 501 | hwif != prev_port) { |
502 | /* | 502 | /* |
503 | * set nIEN for previous port, drives in the | 503 | * set nIEN for previous port, drives in the |
504 | * quirk_list may not like intr setups/cleanups | 504 | * quirk_list may not like intr setups/cleanups |
505 | */ | 505 | */ |
506 | if (prev_port && prev_port->cur_dev->quirk_list == 0) | 506 | if (prev_port && prev_port->cur_dev->quirk_list == 0) |
507 | prev_port->tp_ops->write_devctl(prev_port, | 507 | prev_port->tp_ops->write_devctl(prev_port, |
508 | ATA_NIEN | | 508 | ATA_NIEN | |
509 | ATA_DEVCTL_OBS); | 509 | ATA_DEVCTL_OBS); |
510 | 510 | ||
511 | hwif->host->cur_port = hwif; | 511 | hwif->host->cur_port = hwif; |
512 | } | 512 | } |
513 | hwif->cur_dev = drive; | 513 | hwif->cur_dev = drive; |
514 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); | 514 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); |
515 | 515 | ||
516 | spin_unlock_irq(&hwif->lock); | 516 | spin_unlock_irq(&hwif->lock); |
517 | spin_lock_irq(q->queue_lock); | 517 | spin_lock_irq(q->queue_lock); |
518 | /* | 518 | /* |
519 | * we know that the queue isn't empty, but this can happen | 519 | * we know that the queue isn't empty, but this can happen |
520 | * if the q->prep_rq_fn() decides to kill a request | 520 | * if the q->prep_rq_fn() decides to kill a request |
521 | */ | 521 | */ |
522 | rq = elv_next_request(drive->queue); | 522 | rq = elv_next_request(drive->queue); |
523 | spin_unlock_irq(q->queue_lock); | 523 | spin_unlock_irq(q->queue_lock); |
524 | spin_lock_irq(&hwif->lock); | 524 | spin_lock_irq(&hwif->lock); |
525 | 525 | ||
526 | if (!rq) { | 526 | if (!rq) { |
527 | ide_unlock_port(hwif); | 527 | ide_unlock_port(hwif); |
528 | goto out; | 528 | goto out; |
529 | } | 529 | } |
530 | 530 | ||
531 | /* | 531 | /* |
532 | * Sanity: don't accept a request that isn't a PM request | 532 | * Sanity: don't accept a request that isn't a PM request |
533 | * if we are currently power managed. This is very important as | 533 | * if we are currently power managed. This is very important as |
534 | * blk_stop_queue() doesn't prevent the elv_next_request() | 534 | * blk_stop_queue() doesn't prevent the elv_next_request() |
535 | * above to return us whatever is in the queue. Since we call | 535 | * above to return us whatever is in the queue. Since we call |
536 | * ide_do_request() ourselves, we end up taking requests while | 536 | * ide_do_request() ourselves, we end up taking requests while |
537 | * the queue is blocked... | 537 | * the queue is blocked... |
538 | * | 538 | * |
539 | * We let requests forced at head of queue with ide-preempt | 539 | * We let requests forced at head of queue with ide-preempt |
540 | * though. I hope that doesn't happen too much, hopefully not | 540 | * though. I hope that doesn't happen too much, hopefully not |
541 | * unless the subdriver triggers such a thing in its own PM | 541 | * unless the subdriver triggers such a thing in its own PM |
542 | * state machine. | 542 | * state machine. |
543 | */ | 543 | */ |
544 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && | 544 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && |
545 | blk_pm_request(rq) == 0 && | 545 | blk_pm_request(rq) == 0 && |
546 | (rq->cmd_flags & REQ_PREEMPT) == 0) { | 546 | (rq->cmd_flags & REQ_PREEMPT) == 0) { |
547 | /* there should be no pending command at this point */ | 547 | /* there should be no pending command at this point */ |
548 | ide_unlock_port(hwif); | 548 | ide_unlock_port(hwif); |
549 | goto plug_device; | 549 | goto plug_device; |
550 | } | 550 | } |
551 | 551 | ||
552 | hwif->rq = rq; | 552 | hwif->rq = rq; |
553 | 553 | ||
554 | spin_unlock_irq(&hwif->lock); | 554 | spin_unlock_irq(&hwif->lock); |
555 | startstop = start_request(drive, rq); | 555 | startstop = start_request(drive, rq); |
556 | spin_lock_irq(&hwif->lock); | 556 | spin_lock_irq(&hwif->lock); |
557 | 557 | ||
558 | if (startstop == ide_stopped) | 558 | if (startstop == ide_stopped) |
559 | goto repeat; | 559 | goto repeat; |
560 | } else | 560 | } else |
561 | goto plug_device; | 561 | goto plug_device; |
562 | out: | 562 | out: |
563 | spin_unlock_irq(&hwif->lock); | 563 | spin_unlock_irq(&hwif->lock); |
564 | if (rq == NULL) | 564 | if (rq == NULL) |
565 | ide_unlock_host(host); | 565 | ide_unlock_host(host); |
566 | spin_lock_irq(q->queue_lock); | 566 | spin_lock_irq(q->queue_lock); |
567 | return; | 567 | return; |
568 | 568 | ||
569 | plug_device: | 569 | plug_device: |
570 | spin_unlock_irq(&hwif->lock); | 570 | spin_unlock_irq(&hwif->lock); |
571 | ide_unlock_host(host); | 571 | ide_unlock_host(host); |
572 | plug_device_2: | 572 | plug_device_2: |
573 | spin_lock_irq(q->queue_lock); | 573 | spin_lock_irq(q->queue_lock); |
574 | 574 | ||
575 | if (!elv_queue_empty(q)) | 575 | if (!elv_queue_empty(q)) |
576 | blk_plug_device(q); | 576 | blk_plug_device(q); |
577 | } | 577 | } |
578 | 578 | ||
579 | static void ide_plug_device(ide_drive_t *drive) | 579 | static void ide_plug_device(ide_drive_t *drive) |
580 | { | 580 | { |
581 | struct request_queue *q = drive->queue; | 581 | struct request_queue *q = drive->queue; |
582 | unsigned long flags; | 582 | unsigned long flags; |
583 | 583 | ||
584 | spin_lock_irqsave(q->queue_lock, flags); | 584 | spin_lock_irqsave(q->queue_lock, flags); |
585 | if (!elv_queue_empty(q)) | 585 | if (!elv_queue_empty(q)) |
586 | blk_plug_device(q); | 586 | blk_plug_device(q); |
587 | spin_unlock_irqrestore(q->queue_lock, flags); | 587 | spin_unlock_irqrestore(q->queue_lock, flags); |
588 | } | 588 | } |
589 | 589 | ||
590 | static int drive_is_ready(ide_drive_t *drive) | 590 | static int drive_is_ready(ide_drive_t *drive) |
591 | { | 591 | { |
592 | ide_hwif_t *hwif = drive->hwif; | 592 | ide_hwif_t *hwif = drive->hwif; |
593 | u8 stat = 0; | 593 | u8 stat = 0; |
594 | 594 | ||
595 | if (drive->waiting_for_dma) | 595 | if (drive->waiting_for_dma) |
596 | return hwif->dma_ops->dma_test_irq(drive); | 596 | return hwif->dma_ops->dma_test_irq(drive); |
597 | 597 | ||
598 | if (hwif->io_ports.ctl_addr && | 598 | if (hwif->io_ports.ctl_addr && |
599 | (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) | 599 | (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) |
600 | stat = hwif->tp_ops->read_altstatus(hwif); | 600 | stat = hwif->tp_ops->read_altstatus(hwif); |
601 | else | 601 | else |
602 | /* Note: this may clear a pending IRQ!! */ | 602 | /* Note: this may clear a pending IRQ!! */ |
603 | stat = hwif->tp_ops->read_status(hwif); | 603 | stat = hwif->tp_ops->read_status(hwif); |
604 | 604 | ||
605 | if (stat & ATA_BUSY) | 605 | if (stat & ATA_BUSY) |
606 | /* drive busy: definitely not interrupting */ | 606 | /* drive busy: definitely not interrupting */ |
607 | return 0; | 607 | return 0; |
608 | 608 | ||
609 | /* drive ready: *might* be interrupting */ | 609 | /* drive ready: *might* be interrupting */ |
610 | return 1; | 610 | return 1; |
611 | } | 611 | } |
612 | 612 | ||
613 | /** | 613 | /** |
614 | * ide_timer_expiry - handle lack of an IDE interrupt | 614 | * ide_timer_expiry - handle lack of an IDE interrupt |
615 | * @data: timer callback magic (hwif) | 615 | * @data: timer callback magic (hwif) |
616 | * | 616 | * |
617 | * An IDE command has timed out before the expected drive return | 617 | * An IDE command has timed out before the expected drive return |
618 | * occurred. At this point we attempt to clean up the current | 618 | * occurred. At this point we attempt to clean up the current |
619 | * mess. If the current handler includes an expiry handler then | 619 | * mess. If the current handler includes an expiry handler then |
620 | * we invoke the expiry handler, and providing it is happy the | 620 | * we invoke the expiry handler, and providing it is happy the |
621 | * work is done. If that fails we apply generic recovery rules | 621 | * work is done. If that fails we apply generic recovery rules |
622 | * invoking the handler and checking the drive DMA status. We | 622 | * invoking the handler and checking the drive DMA status. We |
623 | * have an excessively incestuous relationship with the DMA | 623 | * have an excessively incestuous relationship with the DMA |
624 | * logic that wants cleaning up. | 624 | * logic that wants cleaning up. |
625 | */ | 625 | */ |
626 | 626 | ||
627 | void ide_timer_expiry (unsigned long data) | 627 | void ide_timer_expiry (unsigned long data) |
628 | { | 628 | { |
629 | ide_hwif_t *hwif = (ide_hwif_t *)data; | 629 | ide_hwif_t *hwif = (ide_hwif_t *)data; |
630 | ide_drive_t *uninitialized_var(drive); | 630 | ide_drive_t *uninitialized_var(drive); |
631 | ide_handler_t *handler; | 631 | ide_handler_t *handler; |
632 | unsigned long flags; | 632 | unsigned long flags; |
633 | int wait = -1; | 633 | int wait = -1; |
634 | int plug_device = 0; | 634 | int plug_device = 0; |
635 | 635 | ||
636 | spin_lock_irqsave(&hwif->lock, flags); | 636 | spin_lock_irqsave(&hwif->lock, flags); |
637 | 637 | ||
638 | handler = hwif->handler; | 638 | handler = hwif->handler; |
639 | 639 | ||
640 | if (handler == NULL || hwif->req_gen != hwif->req_gen_timer) { | 640 | if (handler == NULL || hwif->req_gen != hwif->req_gen_timer) { |
641 | /* | 641 | /* |
642 | * Either a marginal timeout occurred | 642 | * Either a marginal timeout occurred |
643 | * (got the interrupt just as timer expired), | 643 | * (got the interrupt just as timer expired), |
644 | * or we were "sleeping" to give other devices a chance. | 644 | * or we were "sleeping" to give other devices a chance. |
645 | * Either way, we don't really want to complain about anything. | 645 | * Either way, we don't really want to complain about anything. |
646 | */ | 646 | */ |
647 | } else { | 647 | } else { |
648 | ide_expiry_t *expiry = hwif->expiry; | 648 | ide_expiry_t *expiry = hwif->expiry; |
649 | ide_startstop_t startstop = ide_stopped; | 649 | ide_startstop_t startstop = ide_stopped; |
650 | 650 | ||
651 | drive = hwif->cur_dev; | 651 | drive = hwif->cur_dev; |
652 | 652 | ||
653 | if (expiry) { | 653 | if (expiry) { |
654 | wait = expiry(drive); | 654 | wait = expiry(drive); |
655 | if (wait > 0) { /* continue */ | 655 | if (wait > 0) { /* continue */ |
656 | /* reset timer */ | 656 | /* reset timer */ |
657 | hwif->timer.expires = jiffies + wait; | 657 | hwif->timer.expires = jiffies + wait; |
658 | hwif->req_gen_timer = hwif->req_gen; | 658 | hwif->req_gen_timer = hwif->req_gen; |
659 | add_timer(&hwif->timer); | 659 | add_timer(&hwif->timer); |
660 | spin_unlock_irqrestore(&hwif->lock, flags); | 660 | spin_unlock_irqrestore(&hwif->lock, flags); |
661 | return; | 661 | return; |
662 | } | 662 | } |
663 | } | 663 | } |
664 | hwif->handler = NULL; | 664 | hwif->handler = NULL; |
665 | hwif->expiry = NULL; | 665 | hwif->expiry = NULL; |
666 | /* | 666 | /* |
667 | * We need to simulate a real interrupt when invoking | 667 | * We need to simulate a real interrupt when invoking |
668 | * the handler() function, which means we need to | 668 | * the handler() function, which means we need to |
669 | * globally mask the specific IRQ: | 669 | * globally mask the specific IRQ: |
670 | */ | 670 | */ |
671 | spin_unlock(&hwif->lock); | 671 | spin_unlock(&hwif->lock); |
672 | /* disable_irq_nosync ?? */ | 672 | /* disable_irq_nosync ?? */ |
673 | disable_irq(hwif->irq); | 673 | disable_irq(hwif->irq); |
674 | /* local CPU only, as if we were handling an interrupt */ | 674 | /* local CPU only, as if we were handling an interrupt */ |
675 | local_irq_disable(); | 675 | local_irq_disable(); |
676 | if (hwif->polling) { | 676 | if (hwif->polling) { |
677 | startstop = handler(drive); | 677 | startstop = handler(drive); |
678 | } else if (drive_is_ready(drive)) { | 678 | } else if (drive_is_ready(drive)) { |
679 | if (drive->waiting_for_dma) | 679 | if (drive->waiting_for_dma) |
680 | hwif->dma_ops->dma_lost_irq(drive); | 680 | hwif->dma_ops->dma_lost_irq(drive); |
681 | if (hwif->ack_intr) | 681 | if (hwif->ack_intr) |
682 | hwif->ack_intr(hwif); | 682 | hwif->ack_intr(hwif); |
683 | printk(KERN_WARNING "%s: lost interrupt\n", | 683 | printk(KERN_WARNING "%s: lost interrupt\n", |
684 | drive->name); | 684 | drive->name); |
685 | startstop = handler(drive); | 685 | startstop = handler(drive); |
686 | } else { | 686 | } else { |
687 | if (drive->waiting_for_dma) | 687 | if (drive->waiting_for_dma) |
688 | startstop = ide_dma_timeout_retry(drive, wait); | 688 | startstop = ide_dma_timeout_retry(drive, wait); |
689 | else | 689 | else |
690 | startstop = ide_error(drive, "irq timeout", | 690 | startstop = ide_error(drive, "irq timeout", |
691 | hwif->tp_ops->read_status(hwif)); | 691 | hwif->tp_ops->read_status(hwif)); |
692 | } | 692 | } |
693 | spin_lock_irq(&hwif->lock); | 693 | spin_lock_irq(&hwif->lock); |
694 | enable_irq(hwif->irq); | 694 | enable_irq(hwif->irq); |
695 | if (startstop == ide_stopped) { | 695 | if (startstop == ide_stopped) { |
696 | ide_unlock_port(hwif); | 696 | ide_unlock_port(hwif); |
697 | plug_device = 1; | 697 | plug_device = 1; |
698 | } | 698 | } |
699 | } | 699 | } |
700 | spin_unlock_irqrestore(&hwif->lock, flags); | 700 | spin_unlock_irqrestore(&hwif->lock, flags); |
701 | 701 | ||
702 | if (plug_device) { | 702 | if (plug_device) { |
703 | ide_unlock_host(hwif->host); | 703 | ide_unlock_host(hwif->host); |
704 | ide_plug_device(drive); | 704 | ide_plug_device(drive); |
705 | } | 705 | } |
706 | } | 706 | } |
707 | 707 | ||
708 | /** | 708 | /** |
709 | * unexpected_intr - handle an unexpected IDE interrupt | 709 | * unexpected_intr - handle an unexpected IDE interrupt |
710 | * @irq: interrupt line | 710 | * @irq: interrupt line |
711 | * @hwif: port being processed | 711 | * @hwif: port being processed |
712 | * | 712 | * |
713 | * There's nothing really useful we can do with an unexpected interrupt, | 713 | * There's nothing really useful we can do with an unexpected interrupt, |
714 | * other than reading the status register (to clear it), and logging it. | 714 | * other than reading the status register (to clear it), and logging it. |
715 | * There should be no way that an irq can happen before we're ready for it, | 715 | * There should be no way that an irq can happen before we're ready for it, |
716 | * so we needn't worry much about losing an "important" interrupt here. | 716 | * so we needn't worry much about losing an "important" interrupt here. |
717 | * | 717 | * |
718 | * On laptops (and "green" PCs), an unexpected interrupt occurs whenever | 718 | * On laptops (and "green" PCs), an unexpected interrupt occurs whenever |
719 | * the drive enters "idle", "standby", or "sleep" mode, so if the status | 719 | * the drive enters "idle", "standby", or "sleep" mode, so if the status |
720 | * looks "good", we just ignore the interrupt completely. | 720 | * looks "good", we just ignore the interrupt completely. |
721 | * | 721 | * |
722 | * This routine assumes __cli() is in effect when called. | 722 | * This routine assumes __cli() is in effect when called. |
723 | * | 723 | * |
724 | * If an unexpected interrupt happens on irq15 while we are handling irq14 | 724 | * If an unexpected interrupt happens on irq15 while we are handling irq14 |
725 | * and if the two interfaces are "serialized" (CMD640), then it looks like | 725 | * and if the two interfaces are "serialized" (CMD640), then it looks like |
726 | * we could screw up by interfering with a new request being set up for | 726 | * we could screw up by interfering with a new request being set up for |
727 | * irq15. | 727 | * irq15. |
728 | * | 728 | * |
729 | * In reality, this is a non-issue. The new command is not sent unless | 729 | * In reality, this is a non-issue. The new command is not sent unless |
730 | * the drive is ready to accept one, in which case we know the drive is | 730 | * the drive is ready to accept one, in which case we know the drive is |
731 | * not trying to interrupt us. And ide_set_handler() is always invoked | 731 | * not trying to interrupt us. And ide_set_handler() is always invoked |
732 | * before completing the issuance of any new drive command, so we will not | 732 | * before completing the issuance of any new drive command, so we will not |
733 | * be accidentally invoked as a result of any valid command completion | 733 | * be accidentally invoked as a result of any valid command completion |
734 | * interrupt. | 734 | * interrupt. |
735 | */ | 735 | */ |
736 | 736 | ||
737 | static void unexpected_intr(int irq, ide_hwif_t *hwif) | 737 | static void unexpected_intr(int irq, ide_hwif_t *hwif) |
738 | { | 738 | { |
739 | u8 stat = hwif->tp_ops->read_status(hwif); | 739 | u8 stat = hwif->tp_ops->read_status(hwif); |
740 | 740 | ||
741 | if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) { | 741 | if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) { |
742 | /* Try to not flood the console with msgs */ | 742 | /* Try to not flood the console with msgs */ |
743 | static unsigned long last_msgtime, count; | 743 | static unsigned long last_msgtime, count; |
744 | ++count; | 744 | ++count; |
745 | 745 | ||
746 | if (time_after(jiffies, last_msgtime + HZ)) { | 746 | if (time_after(jiffies, last_msgtime + HZ)) { |
747 | last_msgtime = jiffies; | 747 | last_msgtime = jiffies; |
748 | printk(KERN_ERR "%s: unexpected interrupt, " | 748 | printk(KERN_ERR "%s: unexpected interrupt, " |
749 | "status=0x%02x, count=%ld\n", | 749 | "status=0x%02x, count=%ld\n", |
750 | hwif->name, stat, count); | 750 | hwif->name, stat, count); |
751 | } | 751 | } |
752 | } | 752 | } |
753 | } | 753 | } |
754 | 754 | ||
755 | /** | 755 | /** |
756 | * ide_intr - default IDE interrupt handler | 756 | * ide_intr - default IDE interrupt handler |
757 | * @irq: interrupt number | 757 | * @irq: interrupt number |
758 | * @dev_id: hwif | 758 | * @dev_id: hwif |
759 | * @regs: unused weirdness from the kernel irq layer | 759 | * @regs: unused weirdness from the kernel irq layer |
760 | * | 760 | * |
761 | * This is the default IRQ handler for the IDE layer. You should | 761 | * This is the default IRQ handler for the IDE layer. You should |
762 | * not need to override it. If you do be aware it is subtle in | 762 | * not need to override it. If you do be aware it is subtle in |
763 | * places | 763 | * places |
764 | * | 764 | * |
765 | * hwif is the interface in the group currently performing | 765 | * hwif is the interface in the group currently performing |
766 | * a command. hwif->cur_dev is the drive and hwif->handler is | 766 | * a command. hwif->cur_dev is the drive and hwif->handler is |
767 | * the IRQ handler to call. As we issue a command the handlers | 767 | * the IRQ handler to call. As we issue a command the handlers |
768 | * step through multiple states, reassigning the handler to the | 768 | * step through multiple states, reassigning the handler to the |
769 | * next step in the process. Unlike a smart SCSI controller IDE | 769 | * next step in the process. Unlike a smart SCSI controller IDE |
770 | * expects the main processor to sequence the various transfer | 770 | * expects the main processor to sequence the various transfer |
771 | * stages. We also manage a poll timer to catch up with most | 771 | * stages. We also manage a poll timer to catch up with most |
772 | * timeout situations. There are still a few where the handlers | 772 | * timeout situations. There are still a few where the handlers |
773 | * don't ever decide to give up. | 773 | * don't ever decide to give up. |
774 | * | 774 | * |
775 | * The handler eventually returns ide_stopped to indicate the | 775 | * The handler eventually returns ide_stopped to indicate the |
776 | * request completed. At this point we issue the next request | 776 | * request completed. At this point we issue the next request |
777 | * on the port and the process begins again. | 777 | * on the port and the process begins again. |
778 | */ | 778 | */ |
779 | 779 | ||
780 | irqreturn_t ide_intr (int irq, void *dev_id) | 780 | irqreturn_t ide_intr (int irq, void *dev_id) |
781 | { | 781 | { |
782 | ide_hwif_t *hwif = (ide_hwif_t *)dev_id; | 782 | ide_hwif_t *hwif = (ide_hwif_t *)dev_id; |
783 | struct ide_host *host = hwif->host; | 783 | struct ide_host *host = hwif->host; |
784 | ide_drive_t *uninitialized_var(drive); | 784 | ide_drive_t *uninitialized_var(drive); |
785 | ide_handler_t *handler; | 785 | ide_handler_t *handler; |
786 | unsigned long flags; | 786 | unsigned long flags; |
787 | ide_startstop_t startstop; | 787 | ide_startstop_t startstop; |
788 | irqreturn_t irq_ret = IRQ_NONE; | 788 | irqreturn_t irq_ret = IRQ_NONE; |
789 | int plug_device = 0; | 789 | int plug_device = 0; |
790 | 790 | ||
791 | if (host->host_flags & IDE_HFLAG_SERIALIZE) { | 791 | if (host->host_flags & IDE_HFLAG_SERIALIZE) { |
792 | if (hwif != host->cur_port) | 792 | if (hwif != host->cur_port) |
793 | goto out_early; | 793 | goto out_early; |
794 | } | 794 | } |
795 | 795 | ||
796 | spin_lock_irqsave(&hwif->lock, flags); | 796 | spin_lock_irqsave(&hwif->lock, flags); |
797 | 797 | ||
798 | if (hwif->ack_intr && hwif->ack_intr(hwif) == 0) | 798 | if (hwif->ack_intr && hwif->ack_intr(hwif) == 0) |
799 | goto out; | 799 | goto out; |
800 | 800 | ||
801 | handler = hwif->handler; | 801 | handler = hwif->handler; |
802 | 802 | ||
803 | if (handler == NULL || hwif->polling) { | 803 | if (handler == NULL || hwif->polling) { |
804 | /* | 804 | /* |
805 | * Not expecting an interrupt from this drive. | 805 | * Not expecting an interrupt from this drive. |
806 | * That means this could be: | 806 | * That means this could be: |
807 | * (1) an interrupt from another PCI device | 807 | * (1) an interrupt from another PCI device |
808 | * sharing the same PCI INT# as us. | 808 | * sharing the same PCI INT# as us. |
809 | * or (2) a drive just entered sleep or standby mode, | 809 | * or (2) a drive just entered sleep or standby mode, |
810 | * and is interrupting to let us know. | 810 | * and is interrupting to let us know. |
811 | * or (3) a spurious interrupt of unknown origin. | 811 | * or (3) a spurious interrupt of unknown origin. |
812 | * | 812 | * |
813 | * For PCI, we cannot tell the difference, | 813 | * For PCI, we cannot tell the difference, |
814 | * so in that case we just ignore it and hope it goes away. | 814 | * so in that case we just ignore it and hope it goes away. |
815 | */ | 815 | */ |
816 | if ((host->irq_flags & IRQF_SHARED) == 0) { | 816 | if ((host->irq_flags & IRQF_SHARED) == 0) { |
817 | /* | 817 | /* |
818 | * Probably not a shared PCI interrupt, | 818 | * Probably not a shared PCI interrupt, |
819 | * so we can safely try to do something about it: | 819 | * so we can safely try to do something about it: |
820 | */ | 820 | */ |
821 | unexpected_intr(irq, hwif); | 821 | unexpected_intr(irq, hwif); |
822 | } else { | 822 | } else { |
823 | /* | 823 | /* |
824 | * Whack the status register, just in case | 824 | * Whack the status register, just in case |
825 | * we have a leftover pending IRQ. | 825 | * we have a leftover pending IRQ. |
826 | */ | 826 | */ |
827 | (void)hwif->tp_ops->read_status(hwif); | 827 | (void)hwif->tp_ops->read_status(hwif); |
828 | } | 828 | } |
829 | goto out; | 829 | goto out; |
830 | } | 830 | } |
831 | 831 | ||
832 | drive = hwif->cur_dev; | 832 | drive = hwif->cur_dev; |
833 | 833 | ||
834 | if (!drive_is_ready(drive)) | 834 | if (!drive_is_ready(drive)) |
835 | /* | 835 | /* |
836 | * This happens regularly when we share a PCI IRQ with | 836 | * This happens regularly when we share a PCI IRQ with |
837 | * another device. Unfortunately, it can also happen | 837 | * another device. Unfortunately, it can also happen |
838 | * with some buggy drives that trigger the IRQ before | 838 | * with some buggy drives that trigger the IRQ before |
839 | * their status register is up to date. Hopefully we have | 839 | * their status register is up to date. Hopefully we have |
840 | * enough advance overhead that the latter isn't a problem. | 840 | * enough advance overhead that the latter isn't a problem. |
841 | */ | 841 | */ |
842 | goto out; | 842 | goto out; |
843 | 843 | ||
844 | hwif->handler = NULL; | 844 | hwif->handler = NULL; |
845 | hwif->expiry = NULL; | 845 | hwif->expiry = NULL; |
846 | hwif->req_gen++; | 846 | hwif->req_gen++; |
847 | del_timer(&hwif->timer); | 847 | del_timer(&hwif->timer); |
848 | spin_unlock(&hwif->lock); | 848 | spin_unlock(&hwif->lock); |
849 | 849 | ||
850 | if (hwif->port_ops && hwif->port_ops->clear_irq) | 850 | if (hwif->port_ops && hwif->port_ops->clear_irq) |
851 | hwif->port_ops->clear_irq(drive); | 851 | hwif->port_ops->clear_irq(drive); |
852 | 852 | ||
853 | if (drive->dev_flags & IDE_DFLAG_UNMASK) | 853 | if (drive->dev_flags & IDE_DFLAG_UNMASK) |
854 | local_irq_enable_in_hardirq(); | 854 | local_irq_enable_in_hardirq(); |
855 | 855 | ||
856 | /* service this interrupt, may set handler for next interrupt */ | 856 | /* service this interrupt, may set handler for next interrupt */ |
857 | startstop = handler(drive); | 857 | startstop = handler(drive); |
858 | 858 | ||
859 | spin_lock_irq(&hwif->lock); | 859 | spin_lock_irq(&hwif->lock); |
860 | /* | 860 | /* |
861 | * Note that handler() may have set things up for another | 861 | * Note that handler() may have set things up for another |
862 | * interrupt to occur soon, but it cannot happen until | 862 | * interrupt to occur soon, but it cannot happen until |
863 | * we exit from this routine, because it will be the | 863 | * we exit from this routine, because it will be the |
864 | * same irq as is currently being serviced here, and Linux | 864 | * same irq as is currently being serviced here, and Linux |
865 | * won't allow another of the same (on any CPU) until we return. | 865 | * won't allow another of the same (on any CPU) until we return. |
866 | */ | 866 | */ |
867 | if (startstop == ide_stopped) { | 867 | if (startstop == ide_stopped) { |
868 | BUG_ON(hwif->handler); | 868 | BUG_ON(hwif->handler); |
869 | ide_unlock_port(hwif); | 869 | ide_unlock_port(hwif); |
870 | plug_device = 1; | 870 | plug_device = 1; |
871 | } | 871 | } |
872 | irq_ret = IRQ_HANDLED; | 872 | irq_ret = IRQ_HANDLED; |
873 | out: | 873 | out: |
874 | spin_unlock_irqrestore(&hwif->lock, flags); | 874 | spin_unlock_irqrestore(&hwif->lock, flags); |
875 | out_early: | 875 | out_early: |
876 | if (plug_device) { | 876 | if (plug_device) { |
877 | ide_unlock_host(hwif->host); | 877 | ide_unlock_host(hwif->host); |
878 | ide_plug_device(drive); | 878 | ide_plug_device(drive); |
879 | } | 879 | } |
880 | 880 | ||
881 | return irq_ret; | 881 | return irq_ret; |
882 | } | 882 | } |
883 | EXPORT_SYMBOL_GPL(ide_intr); | 883 | EXPORT_SYMBOL_GPL(ide_intr); |
884 | 884 | ||
885 | void ide_pad_transfer(ide_drive_t *drive, int write, int len) | 885 | void ide_pad_transfer(ide_drive_t *drive, int write, int len) |
886 | { | 886 | { |
887 | ide_hwif_t *hwif = drive->hwif; | 887 | ide_hwif_t *hwif = drive->hwif; |
888 | u8 buf[4] = { 0 }; | 888 | u8 buf[4] = { 0 }; |
889 | 889 | ||
890 | while (len > 0) { | 890 | while (len > 0) { |
891 | if (write) | 891 | if (write) |
892 | hwif->tp_ops->output_data(drive, NULL, buf, min(4, len)); | 892 | hwif->tp_ops->output_data(drive, NULL, buf, min(4, len)); |
893 | else | 893 | else |
894 | hwif->tp_ops->input_data(drive, NULL, buf, min(4, len)); | 894 | hwif->tp_ops->input_data(drive, NULL, buf, min(4, len)); |
895 | len -= 4; | 895 | len -= 4; |
896 | } | 896 | } |
897 | } | 897 | } |
898 | EXPORT_SYMBOL_GPL(ide_pad_transfer); | 898 | EXPORT_SYMBOL_GPL(ide_pad_transfer); |
899 | 899 |
drivers/ide/ide-tape.c
1 | /* | 1 | /* |
2 | * IDE ATAPI streaming tape driver. | 2 | * IDE ATAPI streaming tape driver. |
3 | * | 3 | * |
4 | * Copyright (C) 1995-1999 Gadi Oxman <gadio@netvision.net.il> | 4 | * Copyright (C) 1995-1999 Gadi Oxman <gadio@netvision.net.il> |
5 | * Copyright (C) 2003-2005 Bartlomiej Zolnierkiewicz | 5 | * Copyright (C) 2003-2005 Bartlomiej Zolnierkiewicz |
6 | * | 6 | * |
7 | * This driver was constructed as a student project in the software laboratory | 7 | * This driver was constructed as a student project in the software laboratory |
8 | * of the faculty of electrical engineering in the Technion - Israel's | 8 | * of the faculty of electrical engineering in the Technion - Israel's |
9 | * Institute Of Technology, with the guide of Avner Lottem and Dr. Ilana David. | 9 | * Institute Of Technology, with the guide of Avner Lottem and Dr. Ilana David. |
10 | * | 10 | * |
11 | * It is hereby placed under the terms of the GNU general public license. | 11 | * It is hereby placed under the terms of the GNU general public license. |
12 | * (See linux/COPYING). | 12 | * (See linux/COPYING). |
13 | * | 13 | * |
14 | * For a historical changelog see | 14 | * For a historical changelog see |
15 | * Documentation/ide/ChangeLog.ide-tape.1995-2002 | 15 | * Documentation/ide/ChangeLog.ide-tape.1995-2002 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define DRV_NAME "ide-tape" | 18 | #define DRV_NAME "ide-tape" |
19 | 19 | ||
20 | #define IDETAPE_VERSION "1.20" | 20 | #define IDETAPE_VERSION "1.20" |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/jiffies.h> | 30 | #include <linux/jiffies.h> |
31 | #include <linux/major.h> | 31 | #include <linux/major.h> |
32 | #include <linux/errno.h> | 32 | #include <linux/errno.h> |
33 | #include <linux/genhd.h> | 33 | #include <linux/genhd.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/ide.h> | 36 | #include <linux/ide.h> |
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
38 | #include <linux/completion.h> | 38 | #include <linux/completion.h> |
39 | #include <linux/bitops.h> | 39 | #include <linux/bitops.h> |
40 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
41 | #include <scsi/scsi.h> | 41 | #include <scsi/scsi.h> |
42 | 42 | ||
43 | #include <asm/byteorder.h> | 43 | #include <asm/byteorder.h> |
44 | #include <linux/irq.h> | 44 | #include <linux/irq.h> |
45 | #include <linux/uaccess.h> | 45 | #include <linux/uaccess.h> |
46 | #include <linux/io.h> | 46 | #include <linux/io.h> |
47 | #include <asm/unaligned.h> | 47 | #include <asm/unaligned.h> |
48 | #include <linux/mtio.h> | 48 | #include <linux/mtio.h> |
49 | 49 | ||
50 | enum { | 50 | enum { |
51 | /* output errors only */ | 51 | /* output errors only */ |
52 | DBG_ERR = (1 << 0), | 52 | DBG_ERR = (1 << 0), |
53 | /* output all sense key/asc */ | 53 | /* output all sense key/asc */ |
54 | DBG_SENSE = (1 << 1), | 54 | DBG_SENSE = (1 << 1), |
55 | /* info regarding all chrdev-related procedures */ | 55 | /* info regarding all chrdev-related procedures */ |
56 | DBG_CHRDEV = (1 << 2), | 56 | DBG_CHRDEV = (1 << 2), |
57 | /* all remaining procedures */ | 57 | /* all remaining procedures */ |
58 | DBG_PROCS = (1 << 3), | 58 | DBG_PROCS = (1 << 3), |
59 | }; | 59 | }; |
60 | 60 | ||
61 | /* define to see debug info */ | 61 | /* define to see debug info */ |
62 | #define IDETAPE_DEBUG_LOG 0 | 62 | #define IDETAPE_DEBUG_LOG 0 |
63 | 63 | ||
64 | #if IDETAPE_DEBUG_LOG | 64 | #if IDETAPE_DEBUG_LOG |
65 | #define debug_log(lvl, fmt, args...) \ | 65 | #define debug_log(lvl, fmt, args...) \ |
66 | { \ | 66 | { \ |
67 | if (tape->debug_mask & lvl) \ | 67 | if (tape->debug_mask & lvl) \ |
68 | printk(KERN_INFO "ide-tape: " fmt, ## args); \ | 68 | printk(KERN_INFO "ide-tape: " fmt, ## args); \ |
69 | } | 69 | } |
70 | #else | 70 | #else |
71 | #define debug_log(lvl, fmt, args...) do {} while (0) | 71 | #define debug_log(lvl, fmt, args...) do {} while (0) |
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | /**************************** Tunable parameters *****************************/ | 74 | /**************************** Tunable parameters *****************************/ |
75 | /* | 75 | /* |
76 | * After each failed packet command we issue a request sense command and retry | 76 | * After each failed packet command we issue a request sense command and retry |
77 | * the packet command IDETAPE_MAX_PC_RETRIES times. | 77 | * the packet command IDETAPE_MAX_PC_RETRIES times. |
78 | * | 78 | * |
79 | * Setting IDETAPE_MAX_PC_RETRIES to 0 will disable retries. | 79 | * Setting IDETAPE_MAX_PC_RETRIES to 0 will disable retries. |
80 | */ | 80 | */ |
81 | #define IDETAPE_MAX_PC_RETRIES 3 | 81 | #define IDETAPE_MAX_PC_RETRIES 3 |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * The following parameter is used to select the point in the internal tape fifo | 84 | * The following parameter is used to select the point in the internal tape fifo |
85 | * in which we will start to refill the buffer. Decreasing the following | 85 | * in which we will start to refill the buffer. Decreasing the following |
86 | * parameter will improve the system's latency and interactive response, while | 86 | * parameter will improve the system's latency and interactive response, while |
87 | * using a high value might improve system throughput. | 87 | * using a high value might improve system throughput. |
88 | */ | 88 | */ |
89 | #define IDETAPE_FIFO_THRESHOLD 2 | 89 | #define IDETAPE_FIFO_THRESHOLD 2 |
90 | 90 | ||
91 | /* | 91 | /* |
92 | * DSC polling parameters. | 92 | * DSC polling parameters. |
93 | * | 93 | * |
94 | * Polling for DSC (a single bit in the status register) is a very important | 94 | * Polling for DSC (a single bit in the status register) is a very important |
95 | * function in ide-tape. There are two cases in which we poll for DSC: | 95 | * function in ide-tape. There are two cases in which we poll for DSC: |
96 | * | 96 | * |
97 | * 1. Before a read/write packet command, to ensure that we can transfer data | 97 | * 1. Before a read/write packet command, to ensure that we can transfer data |
98 | * from/to the tape's data buffers, without causing an actual media access. | 98 | * from/to the tape's data buffers, without causing an actual media access. |
99 | * In case the tape is not ready yet, we take out our request from the device | 99 | * In case the tape is not ready yet, we take out our request from the device |
100 | * request queue, so that ide.c could service requests from the other device | 100 | * request queue, so that ide.c could service requests from the other device |
101 | * on the same interface in the meantime. | 101 | * on the same interface in the meantime. |
102 | * | 102 | * |
103 | * 2. After the successful initialization of a "media access packet command", | 103 | * 2. After the successful initialization of a "media access packet command", |
104 | * which is a command that can take a long time to complete (the interval can | 104 | * which is a command that can take a long time to complete (the interval can |
105 | * range from several seconds to even an hour). Again, we postpone our request | 105 | * range from several seconds to even an hour). Again, we postpone our request |
106 | * in the middle to free the bus for the other device. The polling frequency | 106 | * in the middle to free the bus for the other device. The polling frequency |
107 | * here should be lower than the read/write frequency since those media access | 107 | * here should be lower than the read/write frequency since those media access |
108 | * commands are slow. We start from a "fast" frequency - IDETAPE_DSC_MA_FAST | 108 | * commands are slow. We start from a "fast" frequency - IDETAPE_DSC_MA_FAST |
109 | * (1 second), and if we don't receive DSC after IDETAPE_DSC_MA_THRESHOLD | 109 | * (1 second), and if we don't receive DSC after IDETAPE_DSC_MA_THRESHOLD |
110 | * (5 min), we switch it to a lower frequency - IDETAPE_DSC_MA_SLOW (1 min). | 110 | * (5 min), we switch it to a lower frequency - IDETAPE_DSC_MA_SLOW (1 min). |
111 | * | 111 | * |
112 | * We also set a timeout for the timer, in case something goes wrong. The | 112 | * We also set a timeout for the timer, in case something goes wrong. The |
113 | * timeout should be longer then the maximum execution time of a tape operation. | 113 | * timeout should be longer then the maximum execution time of a tape operation. |
114 | */ | 114 | */ |
115 | 115 | ||
116 | /* DSC timings. */ | 116 | /* DSC timings. */ |
117 | #define IDETAPE_DSC_RW_MIN 5*HZ/100 /* 50 msec */ | 117 | #define IDETAPE_DSC_RW_MIN 5*HZ/100 /* 50 msec */ |
118 | #define IDETAPE_DSC_RW_MAX 40*HZ/100 /* 400 msec */ | 118 | #define IDETAPE_DSC_RW_MAX 40*HZ/100 /* 400 msec */ |
119 | #define IDETAPE_DSC_RW_TIMEOUT 2*60*HZ /* 2 minutes */ | 119 | #define IDETAPE_DSC_RW_TIMEOUT 2*60*HZ /* 2 minutes */ |
120 | #define IDETAPE_DSC_MA_FAST 2*HZ /* 2 seconds */ | 120 | #define IDETAPE_DSC_MA_FAST 2*HZ /* 2 seconds */ |
121 | #define IDETAPE_DSC_MA_THRESHOLD 5*60*HZ /* 5 minutes */ | 121 | #define IDETAPE_DSC_MA_THRESHOLD 5*60*HZ /* 5 minutes */ |
122 | #define IDETAPE_DSC_MA_SLOW 30*HZ /* 30 seconds */ | 122 | #define IDETAPE_DSC_MA_SLOW 30*HZ /* 30 seconds */ |
123 | #define IDETAPE_DSC_MA_TIMEOUT 2*60*60*HZ /* 2 hours */ | 123 | #define IDETAPE_DSC_MA_TIMEOUT 2*60*60*HZ /* 2 hours */ |
124 | 124 | ||
125 | /*************************** End of tunable parameters ***********************/ | 125 | /*************************** End of tunable parameters ***********************/ |
126 | 126 | ||
127 | /* tape directions */ | 127 | /* tape directions */ |
128 | enum { | 128 | enum { |
129 | IDETAPE_DIR_NONE = (1 << 0), | 129 | IDETAPE_DIR_NONE = (1 << 0), |
130 | IDETAPE_DIR_READ = (1 << 1), | 130 | IDETAPE_DIR_READ = (1 << 1), |
131 | IDETAPE_DIR_WRITE = (1 << 2), | 131 | IDETAPE_DIR_WRITE = (1 << 2), |
132 | }; | 132 | }; |
133 | 133 | ||
134 | /* Tape door status */ | 134 | /* Tape door status */ |
135 | #define DOOR_UNLOCKED 0 | 135 | #define DOOR_UNLOCKED 0 |
136 | #define DOOR_LOCKED 1 | 136 | #define DOOR_LOCKED 1 |
137 | #define DOOR_EXPLICITLY_LOCKED 2 | 137 | #define DOOR_EXPLICITLY_LOCKED 2 |
138 | 138 | ||
139 | /* Some defines for the SPACE command */ | 139 | /* Some defines for the SPACE command */ |
140 | #define IDETAPE_SPACE_OVER_FILEMARK 1 | 140 | #define IDETAPE_SPACE_OVER_FILEMARK 1 |
141 | #define IDETAPE_SPACE_TO_EOD 3 | 141 | #define IDETAPE_SPACE_TO_EOD 3 |
142 | 142 | ||
143 | /* Some defines for the LOAD UNLOAD command */ | 143 | /* Some defines for the LOAD UNLOAD command */ |
144 | #define IDETAPE_LU_LOAD_MASK 1 | 144 | #define IDETAPE_LU_LOAD_MASK 1 |
145 | #define IDETAPE_LU_RETENSION_MASK 2 | 145 | #define IDETAPE_LU_RETENSION_MASK 2 |
146 | #define IDETAPE_LU_EOT_MASK 4 | 146 | #define IDETAPE_LU_EOT_MASK 4 |
147 | 147 | ||
148 | /* Structures related to the SELECT SENSE / MODE SENSE packet commands. */ | 148 | /* Structures related to the SELECT SENSE / MODE SENSE packet commands. */ |
149 | #define IDETAPE_BLOCK_DESCRIPTOR 0 | 149 | #define IDETAPE_BLOCK_DESCRIPTOR 0 |
150 | #define IDETAPE_CAPABILITIES_PAGE 0x2a | 150 | #define IDETAPE_CAPABILITIES_PAGE 0x2a |
151 | 151 | ||
152 | /* | 152 | /* |
153 | * Most of our global data which we need to save even as we leave the driver due | 153 | * Most of our global data which we need to save even as we leave the driver due |
154 | * to an interrupt or a timer event is stored in the struct defined below. | 154 | * to an interrupt or a timer event is stored in the struct defined below. |
155 | */ | 155 | */ |
156 | typedef struct ide_tape_obj { | 156 | typedef struct ide_tape_obj { |
157 | ide_drive_t *drive; | 157 | ide_drive_t *drive; |
158 | struct ide_driver *driver; | 158 | struct ide_driver *driver; |
159 | struct gendisk *disk; | 159 | struct gendisk *disk; |
160 | struct device dev; | 160 | struct device dev; |
161 | 161 | ||
162 | /* used by REQ_IDETAPE_{READ,WRITE} requests */ | 162 | /* used by REQ_IDETAPE_{READ,WRITE} requests */ |
163 | struct ide_atapi_pc queued_pc; | 163 | struct ide_atapi_pc queued_pc; |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * DSC polling variables. | 166 | * DSC polling variables. |
167 | * | 167 | * |
168 | * While polling for DSC we use postponed_rq to postpone the current | 168 | * While polling for DSC we use postponed_rq to postpone the current |
169 | * request so that ide.c will be able to service pending requests on the | 169 | * request so that ide.c will be able to service pending requests on the |
170 | * other device. Note that at most we will have only one DSC (usually | 170 | * other device. Note that at most we will have only one DSC (usually |
171 | * data transfer) request in the device request queue. | 171 | * data transfer) request in the device request queue. |
172 | */ | 172 | */ |
173 | struct request *postponed_rq; | 173 | struct request *postponed_rq; |
174 | /* The time in which we started polling for DSC */ | 174 | /* The time in which we started polling for DSC */ |
175 | unsigned long dsc_polling_start; | 175 | unsigned long dsc_polling_start; |
176 | /* Timer used to poll for dsc */ | 176 | /* Timer used to poll for dsc */ |
177 | struct timer_list dsc_timer; | 177 | struct timer_list dsc_timer; |
178 | /* Read/Write dsc polling frequency */ | 178 | /* Read/Write dsc polling frequency */ |
179 | unsigned long best_dsc_rw_freq; | 179 | unsigned long best_dsc_rw_freq; |
180 | unsigned long dsc_poll_freq; | 180 | unsigned long dsc_poll_freq; |
181 | unsigned long dsc_timeout; | 181 | unsigned long dsc_timeout; |
182 | 182 | ||
183 | /* Read position information */ | 183 | /* Read position information */ |
184 | u8 partition; | 184 | u8 partition; |
185 | /* Current block */ | 185 | /* Current block */ |
186 | unsigned int first_frame; | 186 | unsigned int first_frame; |
187 | 187 | ||
188 | /* Last error information */ | 188 | /* Last error information */ |
189 | u8 sense_key, asc, ascq; | 189 | u8 sense_key, asc, ascq; |
190 | 190 | ||
191 | /* Character device operation */ | 191 | /* Character device operation */ |
192 | unsigned int minor; | 192 | unsigned int minor; |
193 | /* device name */ | 193 | /* device name */ |
194 | char name[4]; | 194 | char name[4]; |
195 | /* Current character device data transfer direction */ | 195 | /* Current character device data transfer direction */ |
196 | u8 chrdev_dir; | 196 | u8 chrdev_dir; |
197 | 197 | ||
198 | /* tape block size, usually 512 or 1024 bytes */ | 198 | /* tape block size, usually 512 or 1024 bytes */ |
199 | unsigned short blk_size; | 199 | unsigned short blk_size; |
200 | int user_bs_factor; | 200 | int user_bs_factor; |
201 | 201 | ||
202 | /* Copy of the tape's Capabilities and Mechanical Page */ | 202 | /* Copy of the tape's Capabilities and Mechanical Page */ |
203 | u8 caps[20]; | 203 | u8 caps[20]; |
204 | 204 | ||
205 | /* | 205 | /* |
206 | * Active data transfer request parameters. | 206 | * Active data transfer request parameters. |
207 | * | 207 | * |
208 | * At most, there is only one ide-tape originated data transfer request | 208 | * At most, there is only one ide-tape originated data transfer request |
209 | * in the device request queue. This allows ide.c to easily service | 209 | * in the device request queue. This allows ide.c to easily service |
210 | * requests from the other device when we postpone our active request. | 210 | * requests from the other device when we postpone our active request. |
211 | */ | 211 | */ |
212 | 212 | ||
213 | /* Data buffer size chosen based on the tape's recommendation */ | 213 | /* Data buffer size chosen based on the tape's recommendation */ |
214 | int buffer_size; | 214 | int buffer_size; |
215 | /* Staging buffer of buffer_size bytes */ | 215 | /* Staging buffer of buffer_size bytes */ |
216 | void *buf; | 216 | void *buf; |
217 | /* The read/write cursor */ | 217 | /* The read/write cursor */ |
218 | void *cur; | 218 | void *cur; |
219 | /* The number of valid bytes in buf */ | 219 | /* The number of valid bytes in buf */ |
220 | size_t valid; | 220 | size_t valid; |
221 | 221 | ||
222 | /* Measures average tape speed */ | 222 | /* Measures average tape speed */ |
223 | unsigned long avg_time; | 223 | unsigned long avg_time; |
224 | int avg_size; | 224 | int avg_size; |
225 | int avg_speed; | 225 | int avg_speed; |
226 | 226 | ||
227 | /* the door is currently locked */ | 227 | /* the door is currently locked */ |
228 | int door_locked; | 228 | int door_locked; |
229 | /* the tape hardware is write protected */ | 229 | /* the tape hardware is write protected */ |
230 | char drv_write_prot; | 230 | char drv_write_prot; |
231 | /* the tape is write protected (hardware or opened as read-only) */ | 231 | /* the tape is write protected (hardware or opened as read-only) */ |
232 | char write_prot; | 232 | char write_prot; |
233 | 233 | ||
234 | u32 debug_mask; | 234 | u32 debug_mask; |
235 | } idetape_tape_t; | 235 | } idetape_tape_t; |
236 | 236 | ||
237 | static DEFINE_MUTEX(idetape_ref_mutex); | 237 | static DEFINE_MUTEX(idetape_ref_mutex); |
238 | 238 | ||
239 | static struct class *idetape_sysfs_class; | 239 | static struct class *idetape_sysfs_class; |
240 | 240 | ||
241 | static void ide_tape_release(struct device *); | 241 | static void ide_tape_release(struct device *); |
242 | 242 | ||
243 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) | 243 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) |
244 | { | 244 | { |
245 | struct ide_tape_obj *tape = NULL; | 245 | struct ide_tape_obj *tape = NULL; |
246 | 246 | ||
247 | mutex_lock(&idetape_ref_mutex); | 247 | mutex_lock(&idetape_ref_mutex); |
248 | tape = ide_drv_g(disk, ide_tape_obj); | 248 | tape = ide_drv_g(disk, ide_tape_obj); |
249 | if (tape) { | 249 | if (tape) { |
250 | if (ide_device_get(tape->drive)) | 250 | if (ide_device_get(tape->drive)) |
251 | tape = NULL; | 251 | tape = NULL; |
252 | else | 252 | else |
253 | get_device(&tape->dev); | 253 | get_device(&tape->dev); |
254 | } | 254 | } |
255 | mutex_unlock(&idetape_ref_mutex); | 255 | mutex_unlock(&idetape_ref_mutex); |
256 | return tape; | 256 | return tape; |
257 | } | 257 | } |
258 | 258 | ||
259 | static void ide_tape_put(struct ide_tape_obj *tape) | 259 | static void ide_tape_put(struct ide_tape_obj *tape) |
260 | { | 260 | { |
261 | ide_drive_t *drive = tape->drive; | 261 | ide_drive_t *drive = tape->drive; |
262 | 262 | ||
263 | mutex_lock(&idetape_ref_mutex); | 263 | mutex_lock(&idetape_ref_mutex); |
264 | put_device(&tape->dev); | 264 | put_device(&tape->dev); |
265 | ide_device_put(drive); | 265 | ide_device_put(drive); |
266 | mutex_unlock(&idetape_ref_mutex); | 266 | mutex_unlock(&idetape_ref_mutex); |
267 | } | 267 | } |
268 | 268 | ||
269 | /* | 269 | /* |
270 | * The variables below are used for the character device interface. Additional | 270 | * The variables below are used for the character device interface. Additional |
271 | * state variables are defined in our ide_drive_t structure. | 271 | * state variables are defined in our ide_drive_t structure. |
272 | */ | 272 | */ |
273 | static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES]; | 273 | static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES]; |
274 | 274 | ||
275 | static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) | 275 | static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) |
276 | { | 276 | { |
277 | struct ide_tape_obj *tape = NULL; | 277 | struct ide_tape_obj *tape = NULL; |
278 | 278 | ||
279 | mutex_lock(&idetape_ref_mutex); | 279 | mutex_lock(&idetape_ref_mutex); |
280 | tape = idetape_devs[i]; | 280 | tape = idetape_devs[i]; |
281 | if (tape) | 281 | if (tape) |
282 | get_device(&tape->dev); | 282 | get_device(&tape->dev); |
283 | mutex_unlock(&idetape_ref_mutex); | 283 | mutex_unlock(&idetape_ref_mutex); |
284 | return tape; | 284 | return tape; |
285 | } | 285 | } |
286 | 286 | ||
287 | /* | 287 | /* |
288 | * called on each failed packet command retry to analyze the request sense. We | 288 | * called on each failed packet command retry to analyze the request sense. We |
289 | * currently do not utilize this information. | 289 | * currently do not utilize this information. |
290 | */ | 290 | */ |
291 | static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) | 291 | static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) |
292 | { | 292 | { |
293 | idetape_tape_t *tape = drive->driver_data; | 293 | idetape_tape_t *tape = drive->driver_data; |
294 | struct ide_atapi_pc *pc = drive->failed_pc; | 294 | struct ide_atapi_pc *pc = drive->failed_pc; |
295 | 295 | ||
296 | tape->sense_key = sense[2] & 0xF; | 296 | tape->sense_key = sense[2] & 0xF; |
297 | tape->asc = sense[12]; | 297 | tape->asc = sense[12]; |
298 | tape->ascq = sense[13]; | 298 | tape->ascq = sense[13]; |
299 | 299 | ||
300 | debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n", | 300 | debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n", |
301 | pc->c[0], tape->sense_key, tape->asc, tape->ascq); | 301 | pc->c[0], tape->sense_key, tape->asc, tape->ascq); |
302 | 302 | ||
303 | /* Correct pc->xferred by asking the tape. */ | 303 | /* Correct pc->xferred by asking the tape. */ |
304 | if (pc->flags & PC_FLAG_DMA_ERROR) | 304 | if (pc->flags & PC_FLAG_DMA_ERROR) |
305 | pc->xferred = pc->req_xfer - | 305 | pc->xferred = pc->req_xfer - |
306 | tape->blk_size * | 306 | tape->blk_size * |
307 | get_unaligned_be32(&sense[3]); | 307 | get_unaligned_be32(&sense[3]); |
308 | 308 | ||
309 | /* | 309 | /* |
310 | * If error was the result of a zero-length read or write command, | 310 | * If error was the result of a zero-length read or write command, |
311 | * with sense key=5, asc=0x22, ascq=0, let it slide. Some drives | 311 | * with sense key=5, asc=0x22, ascq=0, let it slide. Some drives |
312 | * (i.e. Seagate STT3401A Travan) don't support 0-length read/writes. | 312 | * (i.e. Seagate STT3401A Travan) don't support 0-length read/writes. |
313 | */ | 313 | */ |
314 | if ((pc->c[0] == READ_6 || pc->c[0] == WRITE_6) | 314 | if ((pc->c[0] == READ_6 || pc->c[0] == WRITE_6) |
315 | /* length == 0 */ | 315 | /* length == 0 */ |
316 | && pc->c[4] == 0 && pc->c[3] == 0 && pc->c[2] == 0) { | 316 | && pc->c[4] == 0 && pc->c[3] == 0 && pc->c[2] == 0) { |
317 | if (tape->sense_key == 5) { | 317 | if (tape->sense_key == 5) { |
318 | /* don't report an error, everything's ok */ | 318 | /* don't report an error, everything's ok */ |
319 | pc->error = 0; | 319 | pc->error = 0; |
320 | /* don't retry read/write */ | 320 | /* don't retry read/write */ |
321 | pc->flags |= PC_FLAG_ABORT; | 321 | pc->flags |= PC_FLAG_ABORT; |
322 | } | 322 | } |
323 | } | 323 | } |
324 | if (pc->c[0] == READ_6 && (sense[2] & 0x80)) { | 324 | if (pc->c[0] == READ_6 && (sense[2] & 0x80)) { |
325 | pc->error = IDE_DRV_ERROR_FILEMARK; | 325 | pc->error = IDE_DRV_ERROR_FILEMARK; |
326 | pc->flags |= PC_FLAG_ABORT; | 326 | pc->flags |= PC_FLAG_ABORT; |
327 | } | 327 | } |
328 | if (pc->c[0] == WRITE_6) { | 328 | if (pc->c[0] == WRITE_6) { |
329 | if ((sense[2] & 0x40) || (tape->sense_key == 0xd | 329 | if ((sense[2] & 0x40) || (tape->sense_key == 0xd |
330 | && tape->asc == 0x0 && tape->ascq == 0x2)) { | 330 | && tape->asc == 0x0 && tape->ascq == 0x2)) { |
331 | pc->error = IDE_DRV_ERROR_EOD; | 331 | pc->error = IDE_DRV_ERROR_EOD; |
332 | pc->flags |= PC_FLAG_ABORT; | 332 | pc->flags |= PC_FLAG_ABORT; |
333 | } | 333 | } |
334 | } | 334 | } |
335 | if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { | 335 | if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { |
336 | if (tape->sense_key == 8) { | 336 | if (tape->sense_key == 8) { |
337 | pc->error = IDE_DRV_ERROR_EOD; | 337 | pc->error = IDE_DRV_ERROR_EOD; |
338 | pc->flags |= PC_FLAG_ABORT; | 338 | pc->flags |= PC_FLAG_ABORT; |
339 | } | 339 | } |
340 | if (!(pc->flags & PC_FLAG_ABORT) && | 340 | if (!(pc->flags & PC_FLAG_ABORT) && |
341 | pc->xferred) | 341 | pc->xferred) |
342 | pc->retries = IDETAPE_MAX_PC_RETRIES + 1; | 342 | pc->retries = IDETAPE_MAX_PC_RETRIES + 1; |
343 | } | 343 | } |
344 | } | 344 | } |
345 | 345 | ||
346 | static void ide_tape_handle_dsc(ide_drive_t *); | 346 | static void ide_tape_handle_dsc(ide_drive_t *); |
347 | 347 | ||
348 | static int ide_tape_callback(ide_drive_t *drive, int dsc) | 348 | static int ide_tape_callback(ide_drive_t *drive, int dsc) |
349 | { | 349 | { |
350 | idetape_tape_t *tape = drive->driver_data; | 350 | idetape_tape_t *tape = drive->driver_data; |
351 | struct ide_atapi_pc *pc = drive->pc; | 351 | struct ide_atapi_pc *pc = drive->pc; |
352 | struct request *rq = drive->hwif->rq; | 352 | struct request *rq = drive->hwif->rq; |
353 | int uptodate = pc->error ? 0 : 1; | 353 | int uptodate = pc->error ? 0 : 1; |
354 | int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; | 354 | int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; |
355 | 355 | ||
356 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | 356 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
357 | 357 | ||
358 | if (dsc) | 358 | if (dsc) |
359 | ide_tape_handle_dsc(drive); | 359 | ide_tape_handle_dsc(drive); |
360 | 360 | ||
361 | if (drive->failed_pc == pc) | 361 | if (drive->failed_pc == pc) |
362 | drive->failed_pc = NULL; | 362 | drive->failed_pc = NULL; |
363 | 363 | ||
364 | if (pc->c[0] == REQUEST_SENSE) { | 364 | if (pc->c[0] == REQUEST_SENSE) { |
365 | if (uptodate) | 365 | if (uptodate) |
366 | idetape_analyze_error(drive, pc->buf); | 366 | idetape_analyze_error(drive, pc->buf); |
367 | else | 367 | else |
368 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " | 368 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " |
369 | "itself - Aborting request!\n"); | 369 | "itself - Aborting request!\n"); |
370 | } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { | 370 | } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { |
371 | int blocks = pc->xferred / tape->blk_size; | 371 | int blocks = pc->xferred / tape->blk_size; |
372 | 372 | ||
373 | tape->avg_size += blocks * tape->blk_size; | 373 | tape->avg_size += blocks * tape->blk_size; |
374 | 374 | ||
375 | if (time_after_eq(jiffies, tape->avg_time + HZ)) { | 375 | if (time_after_eq(jiffies, tape->avg_time + HZ)) { |
376 | tape->avg_speed = tape->avg_size * HZ / | 376 | tape->avg_speed = tape->avg_size * HZ / |
377 | (jiffies - tape->avg_time) / 1024; | 377 | (jiffies - tape->avg_time) / 1024; |
378 | tape->avg_size = 0; | 378 | tape->avg_size = 0; |
379 | tape->avg_time = jiffies; | 379 | tape->avg_time = jiffies; |
380 | } | 380 | } |
381 | 381 | ||
382 | tape->first_frame += blocks; | 382 | tape->first_frame += blocks; |
383 | rq->resid_len = rq->data_len - blocks * tape->blk_size; | 383 | rq->resid_len = blk_rq_bytes(rq) - blocks * tape->blk_size; |
384 | 384 | ||
385 | if (pc->error) { | 385 | if (pc->error) { |
386 | uptodate = 0; | 386 | uptodate = 0; |
387 | err = pc->error; | 387 | err = pc->error; |
388 | } | 388 | } |
389 | } else if (pc->c[0] == READ_POSITION && uptodate) { | 389 | } else if (pc->c[0] == READ_POSITION && uptodate) { |
390 | u8 *readpos = pc->buf; | 390 | u8 *readpos = pc->buf; |
391 | 391 | ||
392 | debug_log(DBG_SENSE, "BOP - %s\n", | 392 | debug_log(DBG_SENSE, "BOP - %s\n", |
393 | (readpos[0] & 0x80) ? "Yes" : "No"); | 393 | (readpos[0] & 0x80) ? "Yes" : "No"); |
394 | debug_log(DBG_SENSE, "EOP - %s\n", | 394 | debug_log(DBG_SENSE, "EOP - %s\n", |
395 | (readpos[0] & 0x40) ? "Yes" : "No"); | 395 | (readpos[0] & 0x40) ? "Yes" : "No"); |
396 | 396 | ||
397 | if (readpos[0] & 0x4) { | 397 | if (readpos[0] & 0x4) { |
398 | printk(KERN_INFO "ide-tape: Block location is unknown" | 398 | printk(KERN_INFO "ide-tape: Block location is unknown" |
399 | "to the tape\n"); | 399 | "to the tape\n"); |
400 | clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | 400 | clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); |
401 | uptodate = 0; | 401 | uptodate = 0; |
402 | err = IDE_DRV_ERROR_GENERAL; | 402 | err = IDE_DRV_ERROR_GENERAL; |
403 | } else { | 403 | } else { |
404 | debug_log(DBG_SENSE, "Block Location - %u\n", | 404 | debug_log(DBG_SENSE, "Block Location - %u\n", |
405 | be32_to_cpup((__be32 *)&readpos[4])); | 405 | be32_to_cpup((__be32 *)&readpos[4])); |
406 | 406 | ||
407 | tape->partition = readpos[1]; | 407 | tape->partition = readpos[1]; |
408 | tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]); | 408 | tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]); |
409 | set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | 409 | set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); |
410 | } | 410 | } |
411 | } | 411 | } |
412 | 412 | ||
413 | rq->errors = err; | 413 | rq->errors = err; |
414 | 414 | ||
415 | return uptodate; | 415 | return uptodate; |
416 | } | 416 | } |
417 | 417 | ||
418 | /* | 418 | /* |
419 | * Postpone the current request so that ide.c will be able to service requests | 419 | * Postpone the current request so that ide.c will be able to service requests |
420 | * from another device on the same port while we are polling for DSC. | 420 | * from another device on the same port while we are polling for DSC. |
421 | */ | 421 | */ |
422 | static void idetape_postpone_request(ide_drive_t *drive) | 422 | static void idetape_postpone_request(ide_drive_t *drive) |
423 | { | 423 | { |
424 | idetape_tape_t *tape = drive->driver_data; | 424 | idetape_tape_t *tape = drive->driver_data; |
425 | 425 | ||
426 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | 426 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
427 | 427 | ||
428 | tape->postponed_rq = drive->hwif->rq; | 428 | tape->postponed_rq = drive->hwif->rq; |
429 | 429 | ||
430 | ide_stall_queue(drive, tape->dsc_poll_freq); | 430 | ide_stall_queue(drive, tape->dsc_poll_freq); |
431 | } | 431 | } |
432 | 432 | ||
433 | static void ide_tape_handle_dsc(ide_drive_t *drive) | 433 | static void ide_tape_handle_dsc(ide_drive_t *drive) |
434 | { | 434 | { |
435 | idetape_tape_t *tape = drive->driver_data; | 435 | idetape_tape_t *tape = drive->driver_data; |
436 | 436 | ||
437 | /* Media access command */ | 437 | /* Media access command */ |
438 | tape->dsc_polling_start = jiffies; | 438 | tape->dsc_polling_start = jiffies; |
439 | tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST; | 439 | tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST; |
440 | tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; | 440 | tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; |
441 | /* Allow ide.c to handle other requests */ | 441 | /* Allow ide.c to handle other requests */ |
442 | idetape_postpone_request(drive); | 442 | idetape_postpone_request(drive); |
443 | } | 443 | } |
444 | 444 | ||
445 | /* | 445 | /* |
446 | * Packet Command Interface | 446 | * Packet Command Interface |
447 | * | 447 | * |
448 | * The current Packet Command is available in drive->pc, and will not change | 448 | * The current Packet Command is available in drive->pc, and will not change |
449 | * until we finish handling it. Each packet command is associated with a | 449 | * until we finish handling it. Each packet command is associated with a |
450 | * callback function that will be called when the command is finished. | 450 | * callback function that will be called when the command is finished. |
451 | * | 451 | * |
452 | * The handling will be done in three stages: | 452 | * The handling will be done in three stages: |
453 | * | 453 | * |
454 | * 1. ide_tape_issue_pc will send the packet command to the drive, and will set | 454 | * 1. ide_tape_issue_pc will send the packet command to the drive, and will set |
455 | * the interrupt handler to ide_pc_intr. | 455 | * the interrupt handler to ide_pc_intr. |
456 | * | 456 | * |
457 | * 2. On each interrupt, ide_pc_intr will be called. This step will be | 457 | * 2. On each interrupt, ide_pc_intr will be called. This step will be |
458 | * repeated until the device signals us that no more interrupts will be issued. | 458 | * repeated until the device signals us that no more interrupts will be issued. |
459 | * | 459 | * |
460 | * 3. ATAPI Tape media access commands have immediate status with a delayed | 460 | * 3. ATAPI Tape media access commands have immediate status with a delayed |
461 | * process. In case of a successful initiation of a media access packet command, | 461 | * process. In case of a successful initiation of a media access packet command, |
462 | * the DSC bit will be set when the actual execution of the command is finished. | 462 | * the DSC bit will be set when the actual execution of the command is finished. |
463 | * Since the tape drive will not issue an interrupt, we have to poll for this | 463 | * Since the tape drive will not issue an interrupt, we have to poll for this |
464 | * event. In this case, we define the request as "low priority request" by | 464 | * event. In this case, we define the request as "low priority request" by |
465 | * setting rq_status to IDETAPE_RQ_POSTPONED, set a timer to poll for DSC and | 465 | * setting rq_status to IDETAPE_RQ_POSTPONED, set a timer to poll for DSC and |
466 | * exit the driver. | 466 | * exit the driver. |
467 | * | 467 | * |
468 | * ide.c will then give higher priority to requests which originate from the | 468 | * ide.c will then give higher priority to requests which originate from the |
469 | * other device, until will change rq_status to RQ_ACTIVE. | 469 | * other device, until will change rq_status to RQ_ACTIVE. |
470 | * | 470 | * |
471 | * 4. When the packet command is finished, it will be checked for errors. | 471 | * 4. When the packet command is finished, it will be checked for errors. |
472 | * | 472 | * |
473 | * 5. In case an error was found, we queue a request sense packet command in | 473 | * 5. In case an error was found, we queue a request sense packet command in |
474 | * front of the request queue and retry the operation up to | 474 | * front of the request queue and retry the operation up to |
475 | * IDETAPE_MAX_PC_RETRIES times. | 475 | * IDETAPE_MAX_PC_RETRIES times. |
476 | * | 476 | * |
477 | * 6. In case no error was found, or we decided to give up and not to retry | 477 | * 6. In case no error was found, or we decided to give up and not to retry |
478 | * again, the callback function will be called and then we will handle the next | 478 | * again, the callback function will be called and then we will handle the next |
479 | * request. | 479 | * request. |
480 | */ | 480 | */ |
481 | 481 | ||
482 | static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, | 482 | static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, |
483 | struct ide_cmd *cmd, | 483 | struct ide_cmd *cmd, |
484 | struct ide_atapi_pc *pc) | 484 | struct ide_atapi_pc *pc) |
485 | { | 485 | { |
486 | idetape_tape_t *tape = drive->driver_data; | 486 | idetape_tape_t *tape = drive->driver_data; |
487 | 487 | ||
488 | if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) | 488 | if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) |
489 | drive->failed_pc = pc; | 489 | drive->failed_pc = pc; |
490 | 490 | ||
491 | /* Set the current packet command */ | 491 | /* Set the current packet command */ |
492 | drive->pc = pc; | 492 | drive->pc = pc; |
493 | 493 | ||
494 | if (pc->retries > IDETAPE_MAX_PC_RETRIES || | 494 | if (pc->retries > IDETAPE_MAX_PC_RETRIES || |
495 | (pc->flags & PC_FLAG_ABORT)) { | 495 | (pc->flags & PC_FLAG_ABORT)) { |
496 | unsigned int done = blk_rq_bytes(drive->hwif->rq); | 496 | unsigned int done = blk_rq_bytes(drive->hwif->rq); |
497 | 497 | ||
498 | /* | 498 | /* |
499 | * We will "abort" retrying a packet command in case legitimate | 499 | * We will "abort" retrying a packet command in case legitimate |
500 | * error code was received (crossing a filemark, or end of the | 500 | * error code was received (crossing a filemark, or end of the |
501 | * media, for example). | 501 | * media, for example). |
502 | */ | 502 | */ |
503 | if (!(pc->flags & PC_FLAG_ABORT)) { | 503 | if (!(pc->flags & PC_FLAG_ABORT)) { |
504 | if (!(pc->c[0] == TEST_UNIT_READY && | 504 | if (!(pc->c[0] == TEST_UNIT_READY && |
505 | tape->sense_key == 2 && tape->asc == 4 && | 505 | tape->sense_key == 2 && tape->asc == 4 && |
506 | (tape->ascq == 1 || tape->ascq == 8))) { | 506 | (tape->ascq == 1 || tape->ascq == 8))) { |
507 | printk(KERN_ERR "ide-tape: %s: I/O error, " | 507 | printk(KERN_ERR "ide-tape: %s: I/O error, " |
508 | "pc = %2x, key = %2x, " | 508 | "pc = %2x, key = %2x, " |
509 | "asc = %2x, ascq = %2x\n", | 509 | "asc = %2x, ascq = %2x\n", |
510 | tape->name, pc->c[0], | 510 | tape->name, pc->c[0], |
511 | tape->sense_key, tape->asc, | 511 | tape->sense_key, tape->asc, |
512 | tape->ascq); | 512 | tape->ascq); |
513 | } | 513 | } |
514 | /* Giving up */ | 514 | /* Giving up */ |
515 | pc->error = IDE_DRV_ERROR_GENERAL; | 515 | pc->error = IDE_DRV_ERROR_GENERAL; |
516 | } | 516 | } |
517 | 517 | ||
518 | drive->failed_pc = NULL; | 518 | drive->failed_pc = NULL; |
519 | drive->pc_callback(drive, 0); | 519 | drive->pc_callback(drive, 0); |
520 | ide_complete_rq(drive, -EIO, done); | 520 | ide_complete_rq(drive, -EIO, done); |
521 | return ide_stopped; | 521 | return ide_stopped; |
522 | } | 522 | } |
523 | debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); | 523 | debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); |
524 | 524 | ||
525 | pc->retries++; | 525 | pc->retries++; |
526 | 526 | ||
527 | return ide_issue_pc(drive, cmd); | 527 | return ide_issue_pc(drive, cmd); |
528 | } | 528 | } |
529 | 529 | ||
530 | /* A mode sense command is used to "sense" tape parameters. */ | 530 | /* A mode sense command is used to "sense" tape parameters. */ |
531 | static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) | 531 | static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code) |
532 | { | 532 | { |
533 | ide_init_pc(pc); | 533 | ide_init_pc(pc); |
534 | pc->c[0] = MODE_SENSE; | 534 | pc->c[0] = MODE_SENSE; |
535 | if (page_code != IDETAPE_BLOCK_DESCRIPTOR) | 535 | if (page_code != IDETAPE_BLOCK_DESCRIPTOR) |
536 | /* DBD = 1 - Don't return block descriptors */ | 536 | /* DBD = 1 - Don't return block descriptors */ |
537 | pc->c[1] = 8; | 537 | pc->c[1] = 8; |
538 | pc->c[2] = page_code; | 538 | pc->c[2] = page_code; |
539 | /* | 539 | /* |
540 | * Changed pc->c[3] to 0 (255 will at best return unused info). | 540 | * Changed pc->c[3] to 0 (255 will at best return unused info). |
541 | * | 541 | * |
542 | * For SCSI this byte is defined as subpage instead of high byte | 542 | * For SCSI this byte is defined as subpage instead of high byte |
543 | * of length and some IDE drives seem to interpret it this way | 543 | * of length and some IDE drives seem to interpret it this way |
544 | * and return an error when 255 is used. | 544 | * and return an error when 255 is used. |
545 | */ | 545 | */ |
546 | pc->c[3] = 0; | 546 | pc->c[3] = 0; |
547 | /* We will just discard data in that case */ | 547 | /* We will just discard data in that case */ |
548 | pc->c[4] = 255; | 548 | pc->c[4] = 255; |
549 | if (page_code == IDETAPE_BLOCK_DESCRIPTOR) | 549 | if (page_code == IDETAPE_BLOCK_DESCRIPTOR) |
550 | pc->req_xfer = 12; | 550 | pc->req_xfer = 12; |
551 | else if (page_code == IDETAPE_CAPABILITIES_PAGE) | 551 | else if (page_code == IDETAPE_CAPABILITIES_PAGE) |
552 | pc->req_xfer = 24; | 552 | pc->req_xfer = 24; |
553 | else | 553 | else |
554 | pc->req_xfer = 50; | 554 | pc->req_xfer = 50; |
555 | } | 555 | } |
556 | 556 | ||
557 | static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) | 557 | static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) |
558 | { | 558 | { |
559 | ide_hwif_t *hwif = drive->hwif; | 559 | ide_hwif_t *hwif = drive->hwif; |
560 | idetape_tape_t *tape = drive->driver_data; | 560 | idetape_tape_t *tape = drive->driver_data; |
561 | struct ide_atapi_pc *pc = drive->pc; | 561 | struct ide_atapi_pc *pc = drive->pc; |
562 | u8 stat; | 562 | u8 stat; |
563 | 563 | ||
564 | stat = hwif->tp_ops->read_status(hwif); | 564 | stat = hwif->tp_ops->read_status(hwif); |
565 | 565 | ||
566 | if (stat & ATA_DSC) { | 566 | if (stat & ATA_DSC) { |
567 | if (stat & ATA_ERR) { | 567 | if (stat & ATA_ERR) { |
568 | /* Error detected */ | 568 | /* Error detected */ |
569 | if (pc->c[0] != TEST_UNIT_READY) | 569 | if (pc->c[0] != TEST_UNIT_READY) |
570 | printk(KERN_ERR "ide-tape: %s: I/O error, ", | 570 | printk(KERN_ERR "ide-tape: %s: I/O error, ", |
571 | tape->name); | 571 | tape->name); |
572 | /* Retry operation */ | 572 | /* Retry operation */ |
573 | ide_retry_pc(drive); | 573 | ide_retry_pc(drive); |
574 | return ide_stopped; | 574 | return ide_stopped; |
575 | } | 575 | } |
576 | pc->error = 0; | 576 | pc->error = 0; |
577 | } else { | 577 | } else { |
578 | pc->error = IDE_DRV_ERROR_GENERAL; | 578 | pc->error = IDE_DRV_ERROR_GENERAL; |
579 | drive->failed_pc = NULL; | 579 | drive->failed_pc = NULL; |
580 | } | 580 | } |
581 | drive->pc_callback(drive, 0); | 581 | drive->pc_callback(drive, 0); |
582 | return ide_stopped; | 582 | return ide_stopped; |
583 | } | 583 | } |
584 | 584 | ||
585 | static void ide_tape_create_rw_cmd(idetape_tape_t *tape, | 585 | static void ide_tape_create_rw_cmd(idetape_tape_t *tape, |
586 | struct ide_atapi_pc *pc, struct request *rq, | 586 | struct ide_atapi_pc *pc, struct request *rq, |
587 | u8 opcode) | 587 | u8 opcode) |
588 | { | 588 | { |
589 | unsigned int length = blk_rq_sectors(rq); | 589 | unsigned int length = blk_rq_sectors(rq); |
590 | 590 | ||
591 | ide_init_pc(pc); | 591 | ide_init_pc(pc); |
592 | put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); | 592 | put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); |
593 | pc->c[1] = 1; | 593 | pc->c[1] = 1; |
594 | pc->buf = NULL; | 594 | pc->buf = NULL; |
595 | pc->buf_size = length * tape->blk_size; | 595 | pc->buf_size = length * tape->blk_size; |
596 | pc->req_xfer = pc->buf_size; | 596 | pc->req_xfer = pc->buf_size; |
597 | if (pc->req_xfer == tape->buffer_size) | 597 | if (pc->req_xfer == tape->buffer_size) |
598 | pc->flags |= PC_FLAG_DMA_OK; | 598 | pc->flags |= PC_FLAG_DMA_OK; |
599 | 599 | ||
600 | if (opcode == READ_6) | 600 | if (opcode == READ_6) |
601 | pc->c[0] = READ_6; | 601 | pc->c[0] = READ_6; |
602 | else if (opcode == WRITE_6) { | 602 | else if (opcode == WRITE_6) { |
603 | pc->c[0] = WRITE_6; | 603 | pc->c[0] = WRITE_6; |
604 | pc->flags |= PC_FLAG_WRITING; | 604 | pc->flags |= PC_FLAG_WRITING; |
605 | } | 605 | } |
606 | 606 | ||
607 | memcpy(rq->cmd, pc->c, 12); | 607 | memcpy(rq->cmd, pc->c, 12); |
608 | } | 608 | } |
609 | 609 | ||
610 | static ide_startstop_t idetape_do_request(ide_drive_t *drive, | 610 | static ide_startstop_t idetape_do_request(ide_drive_t *drive, |
611 | struct request *rq, sector_t block) | 611 | struct request *rq, sector_t block) |
612 | { | 612 | { |
613 | ide_hwif_t *hwif = drive->hwif; | 613 | ide_hwif_t *hwif = drive->hwif; |
614 | idetape_tape_t *tape = drive->driver_data; | 614 | idetape_tape_t *tape = drive->driver_data; |
615 | struct ide_atapi_pc *pc = NULL; | 615 | struct ide_atapi_pc *pc = NULL; |
616 | struct request *postponed_rq = tape->postponed_rq; | 616 | struct request *postponed_rq = tape->postponed_rq; |
617 | struct ide_cmd cmd; | 617 | struct ide_cmd cmd; |
618 | u8 stat; | 618 | u8 stat; |
619 | 619 | ||
620 | debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n" | 620 | debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n" |
621 | (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq)); | 621 | (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq)); |
622 | 622 | ||
623 | if (!(blk_special_request(rq) || blk_sense_request(rq))) { | 623 | if (!(blk_special_request(rq) || blk_sense_request(rq))) { |
624 | /* We do not support buffer cache originated requests. */ | 624 | /* We do not support buffer cache originated requests. */ |
625 | printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " | 625 | printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " |
626 | "request queue (%d)\n", drive->name, rq->cmd_type); | 626 | "request queue (%d)\n", drive->name, rq->cmd_type); |
627 | if (blk_fs_request(rq) == 0 && rq->errors == 0) | 627 | if (blk_fs_request(rq) == 0 && rq->errors == 0) |
628 | rq->errors = -EIO; | 628 | rq->errors = -EIO; |
629 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); | 629 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); |
630 | return ide_stopped; | 630 | return ide_stopped; |
631 | } | 631 | } |
632 | 632 | ||
633 | /* Retry a failed packet command */ | 633 | /* Retry a failed packet command */ |
634 | if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { | 634 | if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { |
635 | pc = drive->failed_pc; | 635 | pc = drive->failed_pc; |
636 | goto out; | 636 | goto out; |
637 | } | 637 | } |
638 | 638 | ||
639 | if (postponed_rq != NULL) | 639 | if (postponed_rq != NULL) |
640 | if (rq != postponed_rq) { | 640 | if (rq != postponed_rq) { |
641 | printk(KERN_ERR "ide-tape: ide-tape.c bug - " | 641 | printk(KERN_ERR "ide-tape: ide-tape.c bug - " |
642 | "Two DSC requests were queued\n"); | 642 | "Two DSC requests were queued\n"); |
643 | drive->failed_pc = NULL; | 643 | drive->failed_pc = NULL; |
644 | rq->errors = 0; | 644 | rq->errors = 0; |
645 | ide_complete_rq(drive, 0, blk_rq_bytes(rq)); | 645 | ide_complete_rq(drive, 0, blk_rq_bytes(rq)); |
646 | return ide_stopped; | 646 | return ide_stopped; |
647 | } | 647 | } |
648 | 648 | ||
649 | tape->postponed_rq = NULL; | 649 | tape->postponed_rq = NULL; |
650 | 650 | ||
651 | /* | 651 | /* |
652 | * If the tape is still busy, postpone our request and service | 652 | * If the tape is still busy, postpone our request and service |
653 | * the other device meanwhile. | 653 | * the other device meanwhile. |
654 | */ | 654 | */ |
655 | stat = hwif->tp_ops->read_status(hwif); | 655 | stat = hwif->tp_ops->read_status(hwif); |
656 | 656 | ||
657 | if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 && | 657 | if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 && |
658 | (rq->cmd[13] & REQ_IDETAPE_PC2) == 0) | 658 | (rq->cmd[13] & REQ_IDETAPE_PC2) == 0) |
659 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); | 659 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); |
660 | 660 | ||
661 | if (drive->dev_flags & IDE_DFLAG_POST_RESET) { | 661 | if (drive->dev_flags & IDE_DFLAG_POST_RESET) { |
662 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); | 662 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); |
663 | drive->dev_flags &= ~IDE_DFLAG_POST_RESET; | 663 | drive->dev_flags &= ~IDE_DFLAG_POST_RESET; |
664 | } | 664 | } |
665 | 665 | ||
666 | if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) && | 666 | if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) && |
667 | (stat & ATA_DSC) == 0) { | 667 | (stat & ATA_DSC) == 0) { |
668 | if (postponed_rq == NULL) { | 668 | if (postponed_rq == NULL) { |
669 | tape->dsc_polling_start = jiffies; | 669 | tape->dsc_polling_start = jiffies; |
670 | tape->dsc_poll_freq = tape->best_dsc_rw_freq; | 670 | tape->dsc_poll_freq = tape->best_dsc_rw_freq; |
671 | tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT; | 671 | tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT; |
672 | } else if (time_after(jiffies, tape->dsc_timeout)) { | 672 | } else if (time_after(jiffies, tape->dsc_timeout)) { |
673 | printk(KERN_ERR "ide-tape: %s: DSC timeout\n", | 673 | printk(KERN_ERR "ide-tape: %s: DSC timeout\n", |
674 | tape->name); | 674 | tape->name); |
675 | if (rq->cmd[13] & REQ_IDETAPE_PC2) { | 675 | if (rq->cmd[13] & REQ_IDETAPE_PC2) { |
676 | idetape_media_access_finished(drive); | 676 | idetape_media_access_finished(drive); |
677 | return ide_stopped; | 677 | return ide_stopped; |
678 | } else { | 678 | } else { |
679 | return ide_do_reset(drive); | 679 | return ide_do_reset(drive); |
680 | } | 680 | } |
681 | } else if (time_after(jiffies, | 681 | } else if (time_after(jiffies, |
682 | tape->dsc_polling_start + | 682 | tape->dsc_polling_start + |
683 | IDETAPE_DSC_MA_THRESHOLD)) | 683 | IDETAPE_DSC_MA_THRESHOLD)) |
684 | tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW; | 684 | tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW; |
685 | idetape_postpone_request(drive); | 685 | idetape_postpone_request(drive); |
686 | return ide_stopped; | 686 | return ide_stopped; |
687 | } | 687 | } |
688 | if (rq->cmd[13] & REQ_IDETAPE_READ) { | 688 | if (rq->cmd[13] & REQ_IDETAPE_READ) { |
689 | pc = &tape->queued_pc; | 689 | pc = &tape->queued_pc; |
690 | ide_tape_create_rw_cmd(tape, pc, rq, READ_6); | 690 | ide_tape_create_rw_cmd(tape, pc, rq, READ_6); |
691 | goto out; | 691 | goto out; |
692 | } | 692 | } |
693 | if (rq->cmd[13] & REQ_IDETAPE_WRITE) { | 693 | if (rq->cmd[13] & REQ_IDETAPE_WRITE) { |
694 | pc = &tape->queued_pc; | 694 | pc = &tape->queued_pc; |
695 | ide_tape_create_rw_cmd(tape, pc, rq, WRITE_6); | 695 | ide_tape_create_rw_cmd(tape, pc, rq, WRITE_6); |
696 | goto out; | 696 | goto out; |
697 | } | 697 | } |
698 | if (rq->cmd[13] & REQ_IDETAPE_PC1) { | 698 | if (rq->cmd[13] & REQ_IDETAPE_PC1) { |
699 | pc = (struct ide_atapi_pc *)rq->special; | 699 | pc = (struct ide_atapi_pc *)rq->special; |
700 | rq->cmd[13] &= ~(REQ_IDETAPE_PC1); | 700 | rq->cmd[13] &= ~(REQ_IDETAPE_PC1); |
701 | rq->cmd[13] |= REQ_IDETAPE_PC2; | 701 | rq->cmd[13] |= REQ_IDETAPE_PC2; |
702 | goto out; | 702 | goto out; |
703 | } | 703 | } |
704 | if (rq->cmd[13] & REQ_IDETAPE_PC2) { | 704 | if (rq->cmd[13] & REQ_IDETAPE_PC2) { |
705 | idetape_media_access_finished(drive); | 705 | idetape_media_access_finished(drive); |
706 | return ide_stopped; | 706 | return ide_stopped; |
707 | } | 707 | } |
708 | BUG(); | 708 | BUG(); |
709 | 709 | ||
710 | out: | 710 | out: |
711 | /* prepare sense request for this command */ | 711 | /* prepare sense request for this command */ |
712 | ide_prep_sense(drive, rq); | 712 | ide_prep_sense(drive, rq); |
713 | 713 | ||
714 | memset(&cmd, 0, sizeof(cmd)); | 714 | memset(&cmd, 0, sizeof(cmd)); |
715 | 715 | ||
716 | if (rq_data_dir(rq)) | 716 | if (rq_data_dir(rq)) |
717 | cmd.tf_flags |= IDE_TFLAG_WRITE; | 717 | cmd.tf_flags |= IDE_TFLAG_WRITE; |
718 | 718 | ||
719 | cmd.rq = rq; | 719 | cmd.rq = rq; |
720 | 720 | ||
721 | ide_init_sg_cmd(&cmd, pc->req_xfer); | 721 | ide_init_sg_cmd(&cmd, pc->req_xfer); |
722 | ide_map_sg(drive, &cmd); | 722 | ide_map_sg(drive, &cmd); |
723 | 723 | ||
724 | return ide_tape_issue_pc(drive, &cmd, pc); | 724 | return ide_tape_issue_pc(drive, &cmd, pc); |
725 | } | 725 | } |
726 | 726 | ||
727 | /* | 727 | /* |
728 | * Write a filemark if write_filemark=1. Flush the device buffers without | 728 | * Write a filemark if write_filemark=1. Flush the device buffers without |
729 | * writing a filemark otherwise. | 729 | * writing a filemark otherwise. |
730 | */ | 730 | */ |
731 | static void idetape_create_write_filemark_cmd(ide_drive_t *drive, | 731 | static void idetape_create_write_filemark_cmd(ide_drive_t *drive, |
732 | struct ide_atapi_pc *pc, int write_filemark) | 732 | struct ide_atapi_pc *pc, int write_filemark) |
733 | { | 733 | { |
734 | ide_init_pc(pc); | 734 | ide_init_pc(pc); |
735 | pc->c[0] = WRITE_FILEMARKS; | 735 | pc->c[0] = WRITE_FILEMARKS; |
736 | pc->c[4] = write_filemark; | 736 | pc->c[4] = write_filemark; |
737 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 737 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
738 | } | 738 | } |
739 | 739 | ||
740 | static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) | 740 | static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) |
741 | { | 741 | { |
742 | idetape_tape_t *tape = drive->driver_data; | 742 | idetape_tape_t *tape = drive->driver_data; |
743 | struct gendisk *disk = tape->disk; | 743 | struct gendisk *disk = tape->disk; |
744 | int load_attempted = 0; | 744 | int load_attempted = 0; |
745 | 745 | ||
746 | /* Wait for the tape to become ready */ | 746 | /* Wait for the tape to become ready */ |
747 | set_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags); | 747 | set_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags); |
748 | timeout += jiffies; | 748 | timeout += jiffies; |
749 | while (time_before(jiffies, timeout)) { | 749 | while (time_before(jiffies, timeout)) { |
750 | if (ide_do_test_unit_ready(drive, disk) == 0) | 750 | if (ide_do_test_unit_ready(drive, disk) == 0) |
751 | return 0; | 751 | return 0; |
752 | if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) | 752 | if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) |
753 | || (tape->asc == 0x3A)) { | 753 | || (tape->asc == 0x3A)) { |
754 | /* no media */ | 754 | /* no media */ |
755 | if (load_attempted) | 755 | if (load_attempted) |
756 | return -ENOMEDIUM; | 756 | return -ENOMEDIUM; |
757 | ide_do_start_stop(drive, disk, IDETAPE_LU_LOAD_MASK); | 757 | ide_do_start_stop(drive, disk, IDETAPE_LU_LOAD_MASK); |
758 | load_attempted = 1; | 758 | load_attempted = 1; |
759 | /* not about to be ready */ | 759 | /* not about to be ready */ |
760 | } else if (!(tape->sense_key == 2 && tape->asc == 4 && | 760 | } else if (!(tape->sense_key == 2 && tape->asc == 4 && |
761 | (tape->ascq == 1 || tape->ascq == 8))) | 761 | (tape->ascq == 1 || tape->ascq == 8))) |
762 | return -EIO; | 762 | return -EIO; |
763 | msleep(100); | 763 | msleep(100); |
764 | } | 764 | } |
765 | return -EIO; | 765 | return -EIO; |
766 | } | 766 | } |
767 | 767 | ||
768 | static int idetape_flush_tape_buffers(ide_drive_t *drive) | 768 | static int idetape_flush_tape_buffers(ide_drive_t *drive) |
769 | { | 769 | { |
770 | struct ide_tape_obj *tape = drive->driver_data; | 770 | struct ide_tape_obj *tape = drive->driver_data; |
771 | struct ide_atapi_pc pc; | 771 | struct ide_atapi_pc pc; |
772 | int rc; | 772 | int rc; |
773 | 773 | ||
774 | idetape_create_write_filemark_cmd(drive, &pc, 0); | 774 | idetape_create_write_filemark_cmd(drive, &pc, 0); |
775 | rc = ide_queue_pc_tail(drive, tape->disk, &pc); | 775 | rc = ide_queue_pc_tail(drive, tape->disk, &pc); |
776 | if (rc) | 776 | if (rc) |
777 | return rc; | 777 | return rc; |
778 | idetape_wait_ready(drive, 60 * 5 * HZ); | 778 | idetape_wait_ready(drive, 60 * 5 * HZ); |
779 | return 0; | 779 | return 0; |
780 | } | 780 | } |
781 | 781 | ||
782 | static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc) | 782 | static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc) |
783 | { | 783 | { |
784 | ide_init_pc(pc); | 784 | ide_init_pc(pc); |
785 | pc->c[0] = READ_POSITION; | 785 | pc->c[0] = READ_POSITION; |
786 | pc->req_xfer = 20; | 786 | pc->req_xfer = 20; |
787 | } | 787 | } |
788 | 788 | ||
789 | static int idetape_read_position(ide_drive_t *drive) | 789 | static int idetape_read_position(ide_drive_t *drive) |
790 | { | 790 | { |
791 | idetape_tape_t *tape = drive->driver_data; | 791 | idetape_tape_t *tape = drive->driver_data; |
792 | struct ide_atapi_pc pc; | 792 | struct ide_atapi_pc pc; |
793 | int position; | 793 | int position; |
794 | 794 | ||
795 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | 795 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
796 | 796 | ||
797 | idetape_create_read_position_cmd(&pc); | 797 | idetape_create_read_position_cmd(&pc); |
798 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) | 798 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) |
799 | return -1; | 799 | return -1; |
800 | position = tape->first_frame; | 800 | position = tape->first_frame; |
801 | return position; | 801 | return position; |
802 | } | 802 | } |
803 | 803 | ||
804 | static void idetape_create_locate_cmd(ide_drive_t *drive, | 804 | static void idetape_create_locate_cmd(ide_drive_t *drive, |
805 | struct ide_atapi_pc *pc, | 805 | struct ide_atapi_pc *pc, |
806 | unsigned int block, u8 partition, int skip) | 806 | unsigned int block, u8 partition, int skip) |
807 | { | 807 | { |
808 | ide_init_pc(pc); | 808 | ide_init_pc(pc); |
809 | pc->c[0] = POSITION_TO_ELEMENT; | 809 | pc->c[0] = POSITION_TO_ELEMENT; |
810 | pc->c[1] = 2; | 810 | pc->c[1] = 2; |
811 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]); | 811 | put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]); |
812 | pc->c[8] = partition; | 812 | pc->c[8] = partition; |
813 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 813 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
814 | } | 814 | } |
815 | 815 | ||
816 | static void __ide_tape_discard_merge_buffer(ide_drive_t *drive) | 816 | static void __ide_tape_discard_merge_buffer(ide_drive_t *drive) |
817 | { | 817 | { |
818 | idetape_tape_t *tape = drive->driver_data; | 818 | idetape_tape_t *tape = drive->driver_data; |
819 | 819 | ||
820 | if (tape->chrdev_dir != IDETAPE_DIR_READ) | 820 | if (tape->chrdev_dir != IDETAPE_DIR_READ) |
821 | return; | 821 | return; |
822 | 822 | ||
823 | clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags); | 823 | clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags); |
824 | tape->valid = 0; | 824 | tape->valid = 0; |
825 | if (tape->buf != NULL) { | 825 | if (tape->buf != NULL) { |
826 | kfree(tape->buf); | 826 | kfree(tape->buf); |
827 | tape->buf = NULL; | 827 | tape->buf = NULL; |
828 | } | 828 | } |
829 | 829 | ||
830 | tape->chrdev_dir = IDETAPE_DIR_NONE; | 830 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
831 | } | 831 | } |
832 | 832 | ||
833 | /* | 833 | /* |
834 | * Position the tape to the requested block using the LOCATE packet command. | 834 | * Position the tape to the requested block using the LOCATE packet command. |
835 | * A READ POSITION command is then issued to check where we are positioned. Like | 835 | * A READ POSITION command is then issued to check where we are positioned. Like |
836 | * all higher level operations, we queue the commands at the tail of the request | 836 | * all higher level operations, we queue the commands at the tail of the request |
837 | * queue and wait for their completion. | 837 | * queue and wait for their completion. |
838 | */ | 838 | */ |
839 | static int idetape_position_tape(ide_drive_t *drive, unsigned int block, | 839 | static int idetape_position_tape(ide_drive_t *drive, unsigned int block, |
840 | u8 partition, int skip) | 840 | u8 partition, int skip) |
841 | { | 841 | { |
842 | idetape_tape_t *tape = drive->driver_data; | 842 | idetape_tape_t *tape = drive->driver_data; |
843 | struct gendisk *disk = tape->disk; | 843 | struct gendisk *disk = tape->disk; |
844 | int retval; | 844 | int retval; |
845 | struct ide_atapi_pc pc; | 845 | struct ide_atapi_pc pc; |
846 | 846 | ||
847 | if (tape->chrdev_dir == IDETAPE_DIR_READ) | 847 | if (tape->chrdev_dir == IDETAPE_DIR_READ) |
848 | __ide_tape_discard_merge_buffer(drive); | 848 | __ide_tape_discard_merge_buffer(drive); |
849 | idetape_wait_ready(drive, 60 * 5 * HZ); | 849 | idetape_wait_ready(drive, 60 * 5 * HZ); |
850 | idetape_create_locate_cmd(drive, &pc, block, partition, skip); | 850 | idetape_create_locate_cmd(drive, &pc, block, partition, skip); |
851 | retval = ide_queue_pc_tail(drive, disk, &pc); | 851 | retval = ide_queue_pc_tail(drive, disk, &pc); |
852 | if (retval) | 852 | if (retval) |
853 | return (retval); | 853 | return (retval); |
854 | 854 | ||
855 | idetape_create_read_position_cmd(&pc); | 855 | idetape_create_read_position_cmd(&pc); |
856 | return ide_queue_pc_tail(drive, disk, &pc); | 856 | return ide_queue_pc_tail(drive, disk, &pc); |
857 | } | 857 | } |
858 | 858 | ||
859 | static void ide_tape_discard_merge_buffer(ide_drive_t *drive, | 859 | static void ide_tape_discard_merge_buffer(ide_drive_t *drive, |
860 | int restore_position) | 860 | int restore_position) |
861 | { | 861 | { |
862 | idetape_tape_t *tape = drive->driver_data; | 862 | idetape_tape_t *tape = drive->driver_data; |
863 | int seek, position; | 863 | int seek, position; |
864 | 864 | ||
865 | __ide_tape_discard_merge_buffer(drive); | 865 | __ide_tape_discard_merge_buffer(drive); |
866 | if (restore_position) { | 866 | if (restore_position) { |
867 | position = idetape_read_position(drive); | 867 | position = idetape_read_position(drive); |
868 | seek = position > 0 ? position : 0; | 868 | seek = position > 0 ? position : 0; |
869 | if (idetape_position_tape(drive, seek, 0, 0)) { | 869 | if (idetape_position_tape(drive, seek, 0, 0)) { |
870 | printk(KERN_INFO "ide-tape: %s: position_tape failed in" | 870 | printk(KERN_INFO "ide-tape: %s: position_tape failed in" |
871 | " %s\n", tape->name, __func__); | 871 | " %s\n", tape->name, __func__); |
872 | return; | 872 | return; |
873 | } | 873 | } |
874 | } | 874 | } |
875 | } | 875 | } |
876 | 876 | ||
877 | /* | 877 | /* |
878 | * Generate a read/write request for the block device interface and wait for it | 878 | * Generate a read/write request for the block device interface and wait for it |
879 | * to be serviced. | 879 | * to be serviced. |
880 | */ | 880 | */ |
881 | static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size) | 881 | static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size) |
882 | { | 882 | { |
883 | idetape_tape_t *tape = drive->driver_data; | 883 | idetape_tape_t *tape = drive->driver_data; |
884 | struct request *rq; | 884 | struct request *rq; |
885 | int ret; | 885 | int ret; |
886 | 886 | ||
887 | debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); | 887 | debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); |
888 | BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); | 888 | BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); |
889 | BUG_ON(size < 0 || size % tape->blk_size); | 889 | BUG_ON(size < 0 || size % tape->blk_size); |
890 | 890 | ||
891 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 891 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
892 | rq->cmd_type = REQ_TYPE_SPECIAL; | 892 | rq->cmd_type = REQ_TYPE_SPECIAL; |
893 | rq->cmd[13] = cmd; | 893 | rq->cmd[13] = cmd; |
894 | rq->rq_disk = tape->disk; | 894 | rq->rq_disk = tape->disk; |
895 | 895 | ||
896 | if (size) { | 896 | if (size) { |
897 | ret = blk_rq_map_kern(drive->queue, rq, tape->buf, size, | 897 | ret = blk_rq_map_kern(drive->queue, rq, tape->buf, size, |
898 | __GFP_WAIT); | 898 | __GFP_WAIT); |
899 | if (ret) | 899 | if (ret) |
900 | goto out_put; | 900 | goto out_put; |
901 | } | 901 | } |
902 | 902 | ||
903 | blk_execute_rq(drive->queue, tape->disk, rq, 0); | 903 | blk_execute_rq(drive->queue, tape->disk, rq, 0); |
904 | 904 | ||
905 | /* calculate the number of transferred bytes and update buffer state */ | 905 | /* calculate the number of transferred bytes and update buffer state */ |
906 | size -= rq->resid_len; | 906 | size -= rq->resid_len; |
907 | tape->cur = tape->buf; | 907 | tape->cur = tape->buf; |
908 | if (cmd == REQ_IDETAPE_READ) | 908 | if (cmd == REQ_IDETAPE_READ) |
909 | tape->valid = size; | 909 | tape->valid = size; |
910 | else | 910 | else |
911 | tape->valid = 0; | 911 | tape->valid = 0; |
912 | 912 | ||
913 | ret = size; | 913 | ret = size; |
914 | if (rq->errors == IDE_DRV_ERROR_GENERAL) | 914 | if (rq->errors == IDE_DRV_ERROR_GENERAL) |
915 | ret = -EIO; | 915 | ret = -EIO; |
916 | out_put: | 916 | out_put: |
917 | blk_put_request(rq); | 917 | blk_put_request(rq); |
918 | return ret; | 918 | return ret; |
919 | } | 919 | } |
920 | 920 | ||
921 | static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc) | 921 | static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc) |
922 | { | 922 | { |
923 | ide_init_pc(pc); | 923 | ide_init_pc(pc); |
924 | pc->c[0] = INQUIRY; | 924 | pc->c[0] = INQUIRY; |
925 | pc->c[4] = 254; | 925 | pc->c[4] = 254; |
926 | pc->req_xfer = 254; | 926 | pc->req_xfer = 254; |
927 | } | 927 | } |
928 | 928 | ||
929 | static void idetape_create_rewind_cmd(ide_drive_t *drive, | 929 | static void idetape_create_rewind_cmd(ide_drive_t *drive, |
930 | struct ide_atapi_pc *pc) | 930 | struct ide_atapi_pc *pc) |
931 | { | 931 | { |
932 | ide_init_pc(pc); | 932 | ide_init_pc(pc); |
933 | pc->c[0] = REZERO_UNIT; | 933 | pc->c[0] = REZERO_UNIT; |
934 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 934 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
935 | } | 935 | } |
936 | 936 | ||
937 | static void idetape_create_erase_cmd(struct ide_atapi_pc *pc) | 937 | static void idetape_create_erase_cmd(struct ide_atapi_pc *pc) |
938 | { | 938 | { |
939 | ide_init_pc(pc); | 939 | ide_init_pc(pc); |
940 | pc->c[0] = ERASE; | 940 | pc->c[0] = ERASE; |
941 | pc->c[1] = 1; | 941 | pc->c[1] = 1; |
942 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 942 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
943 | } | 943 | } |
944 | 944 | ||
945 | static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) | 945 | static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) |
946 | { | 946 | { |
947 | ide_init_pc(pc); | 947 | ide_init_pc(pc); |
948 | pc->c[0] = SPACE; | 948 | pc->c[0] = SPACE; |
949 | put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]); | 949 | put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]); |
950 | pc->c[1] = cmd; | 950 | pc->c[1] = cmd; |
951 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; | 951 | pc->flags |= PC_FLAG_WAIT_FOR_DSC; |
952 | } | 952 | } |
953 | 953 | ||
954 | static void ide_tape_flush_merge_buffer(ide_drive_t *drive) | 954 | static void ide_tape_flush_merge_buffer(ide_drive_t *drive) |
955 | { | 955 | { |
956 | idetape_tape_t *tape = drive->driver_data; | 956 | idetape_tape_t *tape = drive->driver_data; |
957 | 957 | ||
958 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { | 958 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { |
959 | printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" | 959 | printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" |
960 | " but we are not writing.\n"); | 960 | " but we are not writing.\n"); |
961 | return; | 961 | return; |
962 | } | 962 | } |
963 | if (tape->buf) { | 963 | if (tape->buf) { |
964 | size_t aligned = roundup(tape->valid, tape->blk_size); | 964 | size_t aligned = roundup(tape->valid, tape->blk_size); |
965 | 965 | ||
966 | memset(tape->cur, 0, aligned - tape->valid); | 966 | memset(tape->cur, 0, aligned - tape->valid); |
967 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, aligned); | 967 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, aligned); |
968 | kfree(tape->buf); | 968 | kfree(tape->buf); |
969 | tape->buf = NULL; | 969 | tape->buf = NULL; |
970 | } | 970 | } |
971 | tape->chrdev_dir = IDETAPE_DIR_NONE; | 971 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
972 | } | 972 | } |
973 | 973 | ||
974 | static int idetape_init_rw(ide_drive_t *drive, int dir) | 974 | static int idetape_init_rw(ide_drive_t *drive, int dir) |
975 | { | 975 | { |
976 | idetape_tape_t *tape = drive->driver_data; | 976 | idetape_tape_t *tape = drive->driver_data; |
977 | int rc; | 977 | int rc; |
978 | 978 | ||
979 | BUG_ON(dir != IDETAPE_DIR_READ && dir != IDETAPE_DIR_WRITE); | 979 | BUG_ON(dir != IDETAPE_DIR_READ && dir != IDETAPE_DIR_WRITE); |
980 | 980 | ||
981 | if (tape->chrdev_dir == dir) | 981 | if (tape->chrdev_dir == dir) |
982 | return 0; | 982 | return 0; |
983 | 983 | ||
984 | if (tape->chrdev_dir == IDETAPE_DIR_READ) | 984 | if (tape->chrdev_dir == IDETAPE_DIR_READ) |
985 | ide_tape_discard_merge_buffer(drive, 1); | 985 | ide_tape_discard_merge_buffer(drive, 1); |
986 | else if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { | 986 | else if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { |
987 | ide_tape_flush_merge_buffer(drive); | 987 | ide_tape_flush_merge_buffer(drive); |
988 | idetape_flush_tape_buffers(drive); | 988 | idetape_flush_tape_buffers(drive); |
989 | } | 989 | } |
990 | 990 | ||
991 | if (tape->buf || tape->valid) { | 991 | if (tape->buf || tape->valid) { |
992 | printk(KERN_ERR "ide-tape: valid should be 0 now\n"); | 992 | printk(KERN_ERR "ide-tape: valid should be 0 now\n"); |
993 | tape->valid = 0; | 993 | tape->valid = 0; |
994 | } | 994 | } |
995 | 995 | ||
996 | tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); | 996 | tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); |
997 | if (!tape->buf) | 997 | if (!tape->buf) |
998 | return -ENOMEM; | 998 | return -ENOMEM; |
999 | tape->chrdev_dir = dir; | 999 | tape->chrdev_dir = dir; |
1000 | tape->cur = tape->buf; | 1000 | tape->cur = tape->buf; |
1001 | 1001 | ||
1002 | /* | 1002 | /* |
1003 | * Issue a 0 rw command to ensure that DSC handshake is | 1003 | * Issue a 0 rw command to ensure that DSC handshake is |
1004 | * switched from completion mode to buffer available mode. No | 1004 | * switched from completion mode to buffer available mode. No |
1005 | * point in issuing this if DSC overlap isn't supported, some | 1005 | * point in issuing this if DSC overlap isn't supported, some |
1006 | * drives (Seagate STT3401A) will return an error. | 1006 | * drives (Seagate STT3401A) will return an error. |
1007 | */ | 1007 | */ |
1008 | if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { | 1008 | if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { |
1009 | int cmd = dir == IDETAPE_DIR_READ ? REQ_IDETAPE_READ | 1009 | int cmd = dir == IDETAPE_DIR_READ ? REQ_IDETAPE_READ |
1010 | : REQ_IDETAPE_WRITE; | 1010 | : REQ_IDETAPE_WRITE; |
1011 | 1011 | ||
1012 | rc = idetape_queue_rw_tail(drive, cmd, 0); | 1012 | rc = idetape_queue_rw_tail(drive, cmd, 0); |
1013 | if (rc < 0) { | 1013 | if (rc < 0) { |
1014 | kfree(tape->buf); | 1014 | kfree(tape->buf); |
1015 | tape->buf = NULL; | 1015 | tape->buf = NULL; |
1016 | tape->chrdev_dir = IDETAPE_DIR_NONE; | 1016 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
1017 | return rc; | 1017 | return rc; |
1018 | } | 1018 | } |
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | return 0; | 1021 | return 0; |
1022 | } | 1022 | } |
1023 | 1023 | ||
1024 | static void idetape_pad_zeros(ide_drive_t *drive, int bcount) | 1024 | static void idetape_pad_zeros(ide_drive_t *drive, int bcount) |
1025 | { | 1025 | { |
1026 | idetape_tape_t *tape = drive->driver_data; | 1026 | idetape_tape_t *tape = drive->driver_data; |
1027 | 1027 | ||
1028 | memset(tape->buf, 0, tape->buffer_size); | 1028 | memset(tape->buf, 0, tape->buffer_size); |
1029 | 1029 | ||
1030 | while (bcount) { | 1030 | while (bcount) { |
1031 | unsigned int count = min(tape->buffer_size, bcount); | 1031 | unsigned int count = min(tape->buffer_size, bcount); |
1032 | 1032 | ||
1033 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, count); | 1033 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, count); |
1034 | bcount -= count; | 1034 | bcount -= count; |
1035 | } | 1035 | } |
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | /* | 1038 | /* |
1039 | * Rewinds the tape to the Beginning Of the current Partition (BOP). We | 1039 | * Rewinds the tape to the Beginning Of the current Partition (BOP). We |
1040 | * currently support only one partition. | 1040 | * currently support only one partition. |
1041 | */ | 1041 | */ |
1042 | static int idetape_rewind_tape(ide_drive_t *drive) | 1042 | static int idetape_rewind_tape(ide_drive_t *drive) |
1043 | { | 1043 | { |
1044 | struct ide_tape_obj *tape = drive->driver_data; | 1044 | struct ide_tape_obj *tape = drive->driver_data; |
1045 | struct gendisk *disk = tape->disk; | 1045 | struct gendisk *disk = tape->disk; |
1046 | int retval; | 1046 | int retval; |
1047 | struct ide_atapi_pc pc; | 1047 | struct ide_atapi_pc pc; |
1048 | 1048 | ||
1049 | debug_log(DBG_SENSE, "Enter %s\n", __func__); | 1049 | debug_log(DBG_SENSE, "Enter %s\n", __func__); |
1050 | 1050 | ||
1051 | idetape_create_rewind_cmd(drive, &pc); | 1051 | idetape_create_rewind_cmd(drive, &pc); |
1052 | retval = ide_queue_pc_tail(drive, disk, &pc); | 1052 | retval = ide_queue_pc_tail(drive, disk, &pc); |
1053 | if (retval) | 1053 | if (retval) |
1054 | return retval; | 1054 | return retval; |
1055 | 1055 | ||
1056 | idetape_create_read_position_cmd(&pc); | 1056 | idetape_create_read_position_cmd(&pc); |
1057 | retval = ide_queue_pc_tail(drive, disk, &pc); | 1057 | retval = ide_queue_pc_tail(drive, disk, &pc); |
1058 | if (retval) | 1058 | if (retval) |
1059 | return retval; | 1059 | return retval; |
1060 | return 0; | 1060 | return 0; |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | /* mtio.h compatible commands should be issued to the chrdev interface. */ | 1063 | /* mtio.h compatible commands should be issued to the chrdev interface. */ |
1064 | static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, | 1064 | static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, |
1065 | unsigned long arg) | 1065 | unsigned long arg) |
1066 | { | 1066 | { |
1067 | idetape_tape_t *tape = drive->driver_data; | 1067 | idetape_tape_t *tape = drive->driver_data; |
1068 | void __user *argp = (void __user *)arg; | 1068 | void __user *argp = (void __user *)arg; |
1069 | 1069 | ||
1070 | struct idetape_config { | 1070 | struct idetape_config { |
1071 | int dsc_rw_frequency; | 1071 | int dsc_rw_frequency; |
1072 | int dsc_media_access_frequency; | 1072 | int dsc_media_access_frequency; |
1073 | int nr_stages; | 1073 | int nr_stages; |
1074 | } config; | 1074 | } config; |
1075 | 1075 | ||
1076 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | 1076 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
1077 | 1077 | ||
1078 | switch (cmd) { | 1078 | switch (cmd) { |
1079 | case 0x0340: | 1079 | case 0x0340: |
1080 | if (copy_from_user(&config, argp, sizeof(config))) | 1080 | if (copy_from_user(&config, argp, sizeof(config))) |
1081 | return -EFAULT; | 1081 | return -EFAULT; |
1082 | tape->best_dsc_rw_freq = config.dsc_rw_frequency; | 1082 | tape->best_dsc_rw_freq = config.dsc_rw_frequency; |
1083 | break; | 1083 | break; |
1084 | case 0x0350: | 1084 | case 0x0350: |
1085 | config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq; | 1085 | config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq; |
1086 | config.nr_stages = 1; | 1086 | config.nr_stages = 1; |
1087 | if (copy_to_user(argp, &config, sizeof(config))) | 1087 | if (copy_to_user(argp, &config, sizeof(config))) |
1088 | return -EFAULT; | 1088 | return -EFAULT; |
1089 | break; | 1089 | break; |
1090 | default: | 1090 | default: |
1091 | return -EIO; | 1091 | return -EIO; |
1092 | } | 1092 | } |
1093 | return 0; | 1093 | return 0; |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, | 1096 | static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, |
1097 | int mt_count) | 1097 | int mt_count) |
1098 | { | 1098 | { |
1099 | idetape_tape_t *tape = drive->driver_data; | 1099 | idetape_tape_t *tape = drive->driver_data; |
1100 | struct gendisk *disk = tape->disk; | 1100 | struct gendisk *disk = tape->disk; |
1101 | struct ide_atapi_pc pc; | 1101 | struct ide_atapi_pc pc; |
1102 | int retval, count = 0; | 1102 | int retval, count = 0; |
1103 | int sprev = !!(tape->caps[4] & 0x20); | 1103 | int sprev = !!(tape->caps[4] & 0x20); |
1104 | 1104 | ||
1105 | if (mt_count == 0) | 1105 | if (mt_count == 0) |
1106 | return 0; | 1106 | return 0; |
1107 | if (MTBSF == mt_op || MTBSFM == mt_op) { | 1107 | if (MTBSF == mt_op || MTBSFM == mt_op) { |
1108 | if (!sprev) | 1108 | if (!sprev) |
1109 | return -EIO; | 1109 | return -EIO; |
1110 | mt_count = -mt_count; | 1110 | mt_count = -mt_count; |
1111 | } | 1111 | } |
1112 | 1112 | ||
1113 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { | 1113 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { |
1114 | tape->valid = 0; | 1114 | tape->valid = 0; |
1115 | if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) | 1115 | if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) |
1116 | ++count; | 1116 | ++count; |
1117 | ide_tape_discard_merge_buffer(drive, 0); | 1117 | ide_tape_discard_merge_buffer(drive, 0); |
1118 | } | 1118 | } |
1119 | 1119 | ||
1120 | switch (mt_op) { | 1120 | switch (mt_op) { |
1121 | case MTFSF: | 1121 | case MTFSF: |
1122 | case MTBSF: | 1122 | case MTBSF: |
1123 | idetape_create_space_cmd(&pc, mt_count - count, | 1123 | idetape_create_space_cmd(&pc, mt_count - count, |
1124 | IDETAPE_SPACE_OVER_FILEMARK); | 1124 | IDETAPE_SPACE_OVER_FILEMARK); |
1125 | return ide_queue_pc_tail(drive, disk, &pc); | 1125 | return ide_queue_pc_tail(drive, disk, &pc); |
1126 | case MTFSFM: | 1126 | case MTFSFM: |
1127 | case MTBSFM: | 1127 | case MTBSFM: |
1128 | if (!sprev) | 1128 | if (!sprev) |
1129 | return -EIO; | 1129 | return -EIO; |
1130 | retval = idetape_space_over_filemarks(drive, MTFSF, | 1130 | retval = idetape_space_over_filemarks(drive, MTFSF, |
1131 | mt_count - count); | 1131 | mt_count - count); |
1132 | if (retval) | 1132 | if (retval) |
1133 | return retval; | 1133 | return retval; |
1134 | count = (MTBSFM == mt_op ? 1 : -1); | 1134 | count = (MTBSFM == mt_op ? 1 : -1); |
1135 | return idetape_space_over_filemarks(drive, MTFSF, count); | 1135 | return idetape_space_over_filemarks(drive, MTFSF, count); |
1136 | default: | 1136 | default: |
1137 | printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n", | 1137 | printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n", |
1138 | mt_op); | 1138 | mt_op); |
1139 | return -EIO; | 1139 | return -EIO; |
1140 | } | 1140 | } |
1141 | } | 1141 | } |
1142 | 1142 | ||
1143 | /* | 1143 | /* |
1144 | * Our character device read / write functions. | 1144 | * Our character device read / write functions. |
1145 | * | 1145 | * |
1146 | * The tape is optimized to maximize throughput when it is transferring an | 1146 | * The tape is optimized to maximize throughput when it is transferring an |
1147 | * integral number of the "continuous transfer limit", which is a parameter of | 1147 | * integral number of the "continuous transfer limit", which is a parameter of |
1148 | * the specific tape (26kB on my particular tape, 32kB for Onstream). | 1148 | * the specific tape (26kB on my particular tape, 32kB for Onstream). |
1149 | * | 1149 | * |
1150 | * As of version 1.3 of the driver, the character device provides an abstract | 1150 | * As of version 1.3 of the driver, the character device provides an abstract |
1151 | * continuous view of the media - any mix of block sizes (even 1 byte) on the | 1151 | * continuous view of the media - any mix of block sizes (even 1 byte) on the |
1152 | * same backup/restore procedure is supported. The driver will internally | 1152 | * same backup/restore procedure is supported. The driver will internally |
1153 | * convert the requests to the recommended transfer unit, so that an unmatch | 1153 | * convert the requests to the recommended transfer unit, so that an unmatch |
1154 | * between the user's block size to the recommended size will only result in a | 1154 | * between the user's block size to the recommended size will only result in a |
1155 | * (slightly) increased driver overhead, but will no longer hit performance. | 1155 | * (slightly) increased driver overhead, but will no longer hit performance. |
1156 | * This is not applicable to Onstream. | 1156 | * This is not applicable to Onstream. |
1157 | */ | 1157 | */ |
1158 | static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, | 1158 | static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, |
1159 | size_t count, loff_t *ppos) | 1159 | size_t count, loff_t *ppos) |
1160 | { | 1160 | { |
1161 | struct ide_tape_obj *tape = file->private_data; | 1161 | struct ide_tape_obj *tape = file->private_data; |
1162 | ide_drive_t *drive = tape->drive; | 1162 | ide_drive_t *drive = tape->drive; |
1163 | size_t done = 0; | 1163 | size_t done = 0; |
1164 | ssize_t ret = 0; | 1164 | ssize_t ret = 0; |
1165 | int rc; | 1165 | int rc; |
1166 | 1166 | ||
1167 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); | 1167 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); |
1168 | 1168 | ||
1169 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { | 1169 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { |
1170 | if (test_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags)) | 1170 | if (test_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags)) |
1171 | if (count > tape->blk_size && | 1171 | if (count > tape->blk_size && |
1172 | (count % tape->blk_size) == 0) | 1172 | (count % tape->blk_size) == 0) |
1173 | tape->user_bs_factor = count / tape->blk_size; | 1173 | tape->user_bs_factor = count / tape->blk_size; |
1174 | } | 1174 | } |
1175 | 1175 | ||
1176 | rc = idetape_init_rw(drive, IDETAPE_DIR_READ); | 1176 | rc = idetape_init_rw(drive, IDETAPE_DIR_READ); |
1177 | if (rc < 0) | 1177 | if (rc < 0) |
1178 | return rc; | 1178 | return rc; |
1179 | 1179 | ||
1180 | while (done < count) { | 1180 | while (done < count) { |
1181 | size_t todo; | 1181 | size_t todo; |
1182 | 1182 | ||
1183 | /* refill if staging buffer is empty */ | 1183 | /* refill if staging buffer is empty */ |
1184 | if (!tape->valid) { | 1184 | if (!tape->valid) { |
1185 | /* If we are at a filemark, nothing more to read */ | 1185 | /* If we are at a filemark, nothing more to read */ |
1186 | if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) | 1186 | if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) |
1187 | break; | 1187 | break; |
1188 | /* read */ | 1188 | /* read */ |
1189 | if (idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, | 1189 | if (idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, |
1190 | tape->buffer_size) <= 0) | 1190 | tape->buffer_size) <= 0) |
1191 | break; | 1191 | break; |
1192 | } | 1192 | } |
1193 | 1193 | ||
1194 | /* copy out */ | 1194 | /* copy out */ |
1195 | todo = min_t(size_t, count - done, tape->valid); | 1195 | todo = min_t(size_t, count - done, tape->valid); |
1196 | if (copy_to_user(buf + done, tape->cur, todo)) | 1196 | if (copy_to_user(buf + done, tape->cur, todo)) |
1197 | ret = -EFAULT; | 1197 | ret = -EFAULT; |
1198 | 1198 | ||
1199 | tape->cur += todo; | 1199 | tape->cur += todo; |
1200 | tape->valid -= todo; | 1200 | tape->valid -= todo; |
1201 | done += todo; | 1201 | done += todo; |
1202 | } | 1202 | } |
1203 | 1203 | ||
1204 | if (!done && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { | 1204 | if (!done && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { |
1205 | debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); | 1205 | debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); |
1206 | 1206 | ||
1207 | idetape_space_over_filemarks(drive, MTFSF, 1); | 1207 | idetape_space_over_filemarks(drive, MTFSF, 1); |
1208 | return 0; | 1208 | return 0; |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | return ret ? ret : done; | 1211 | return ret ? ret : done; |
1212 | } | 1212 | } |
1213 | 1213 | ||
1214 | static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, | 1214 | static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, |
1215 | size_t count, loff_t *ppos) | 1215 | size_t count, loff_t *ppos) |
1216 | { | 1216 | { |
1217 | struct ide_tape_obj *tape = file->private_data; | 1217 | struct ide_tape_obj *tape = file->private_data; |
1218 | ide_drive_t *drive = tape->drive; | 1218 | ide_drive_t *drive = tape->drive; |
1219 | size_t done = 0; | 1219 | size_t done = 0; |
1220 | ssize_t ret = 0; | 1220 | ssize_t ret = 0; |
1221 | int rc; | 1221 | int rc; |
1222 | 1222 | ||
1223 | /* The drive is write protected. */ | 1223 | /* The drive is write protected. */ |
1224 | if (tape->write_prot) | 1224 | if (tape->write_prot) |
1225 | return -EACCES; | 1225 | return -EACCES; |
1226 | 1226 | ||
1227 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); | 1227 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); |
1228 | 1228 | ||
1229 | /* Initialize write operation */ | 1229 | /* Initialize write operation */ |
1230 | rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); | 1230 | rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); |
1231 | if (rc < 0) | 1231 | if (rc < 0) |
1232 | return rc; | 1232 | return rc; |
1233 | 1233 | ||
1234 | while (done < count) { | 1234 | while (done < count) { |
1235 | size_t todo; | 1235 | size_t todo; |
1236 | 1236 | ||
1237 | /* flush if staging buffer is full */ | 1237 | /* flush if staging buffer is full */ |
1238 | if (tape->valid == tape->buffer_size && | 1238 | if (tape->valid == tape->buffer_size && |
1239 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, | 1239 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, |
1240 | tape->buffer_size) <= 0) | 1240 | tape->buffer_size) <= 0) |
1241 | return rc; | 1241 | return rc; |
1242 | 1242 | ||
1243 | /* copy in */ | 1243 | /* copy in */ |
1244 | todo = min_t(size_t, count - done, | 1244 | todo = min_t(size_t, count - done, |
1245 | tape->buffer_size - tape->valid); | 1245 | tape->buffer_size - tape->valid); |
1246 | if (copy_from_user(tape->cur, buf + done, todo)) | 1246 | if (copy_from_user(tape->cur, buf + done, todo)) |
1247 | ret = -EFAULT; | 1247 | ret = -EFAULT; |
1248 | 1248 | ||
1249 | tape->cur += todo; | 1249 | tape->cur += todo; |
1250 | tape->valid += todo; | 1250 | tape->valid += todo; |
1251 | done += todo; | 1251 | done += todo; |
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | return ret ? ret : done; | 1254 | return ret ? ret : done; |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | static int idetape_write_filemark(ide_drive_t *drive) | 1257 | static int idetape_write_filemark(ide_drive_t *drive) |
1258 | { | 1258 | { |
1259 | struct ide_tape_obj *tape = drive->driver_data; | 1259 | struct ide_tape_obj *tape = drive->driver_data; |
1260 | struct ide_atapi_pc pc; | 1260 | struct ide_atapi_pc pc; |
1261 | 1261 | ||
1262 | /* Write a filemark */ | 1262 | /* Write a filemark */ |
1263 | idetape_create_write_filemark_cmd(drive, &pc, 1); | 1263 | idetape_create_write_filemark_cmd(drive, &pc, 1); |
1264 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { | 1264 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { |
1265 | printk(KERN_ERR "ide-tape: Couldn't write a filemark\n"); | 1265 | printk(KERN_ERR "ide-tape: Couldn't write a filemark\n"); |
1266 | return -EIO; | 1266 | return -EIO; |
1267 | } | 1267 | } |
1268 | return 0; | 1268 | return 0; |
1269 | } | 1269 | } |
1270 | 1270 | ||
1271 | /* | 1271 | /* |
1272 | * Called from idetape_chrdev_ioctl when the general mtio MTIOCTOP ioctl is | 1272 | * Called from idetape_chrdev_ioctl when the general mtio MTIOCTOP ioctl is |
1273 | * requested. | 1273 | * requested. |
1274 | * | 1274 | * |
1275 | * Note: MTBSF and MTBSFM are not supported when the tape doesn't support | 1275 | * Note: MTBSF and MTBSFM are not supported when the tape doesn't support |
1276 | * spacing over filemarks in the reverse direction. In this case, MTFSFM is also | 1276 | * spacing over filemarks in the reverse direction. In this case, MTFSFM is also |
1277 | * usually not supported. | 1277 | * usually not supported. |
1278 | * | 1278 | * |
1279 | * The following commands are currently not supported: | 1279 | * The following commands are currently not supported: |
1280 | * | 1280 | * |
1281 | * MTFSS, MTBSS, MTWSM, MTSETDENSITY, MTSETDRVBUFFER, MT_ST_BOOLEANS, | 1281 | * MTFSS, MTBSS, MTWSM, MTSETDENSITY, MTSETDRVBUFFER, MT_ST_BOOLEANS, |
1282 | * MT_ST_WRITE_THRESHOLD. | 1282 | * MT_ST_WRITE_THRESHOLD. |
1283 | */ | 1283 | */ |
1284 | static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) | 1284 | static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) |
1285 | { | 1285 | { |
1286 | idetape_tape_t *tape = drive->driver_data; | 1286 | idetape_tape_t *tape = drive->driver_data; |
1287 | struct gendisk *disk = tape->disk; | 1287 | struct gendisk *disk = tape->disk; |
1288 | struct ide_atapi_pc pc; | 1288 | struct ide_atapi_pc pc; |
1289 | int i, retval; | 1289 | int i, retval; |
1290 | 1290 | ||
1291 | debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n", | 1291 | debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n", |
1292 | mt_op, mt_count); | 1292 | mt_op, mt_count); |
1293 | 1293 | ||
1294 | switch (mt_op) { | 1294 | switch (mt_op) { |
1295 | case MTFSF: | 1295 | case MTFSF: |
1296 | case MTFSFM: | 1296 | case MTFSFM: |
1297 | case MTBSF: | 1297 | case MTBSF: |
1298 | case MTBSFM: | 1298 | case MTBSFM: |
1299 | if (!mt_count) | 1299 | if (!mt_count) |
1300 | return 0; | 1300 | return 0; |
1301 | return idetape_space_over_filemarks(drive, mt_op, mt_count); | 1301 | return idetape_space_over_filemarks(drive, mt_op, mt_count); |
1302 | default: | 1302 | default: |
1303 | break; | 1303 | break; |
1304 | } | 1304 | } |
1305 | 1305 | ||
1306 | switch (mt_op) { | 1306 | switch (mt_op) { |
1307 | case MTWEOF: | 1307 | case MTWEOF: |
1308 | if (tape->write_prot) | 1308 | if (tape->write_prot) |
1309 | return -EACCES; | 1309 | return -EACCES; |
1310 | ide_tape_discard_merge_buffer(drive, 1); | 1310 | ide_tape_discard_merge_buffer(drive, 1); |
1311 | for (i = 0; i < mt_count; i++) { | 1311 | for (i = 0; i < mt_count; i++) { |
1312 | retval = idetape_write_filemark(drive); | 1312 | retval = idetape_write_filemark(drive); |
1313 | if (retval) | 1313 | if (retval) |
1314 | return retval; | 1314 | return retval; |
1315 | } | 1315 | } |
1316 | return 0; | 1316 | return 0; |
1317 | case MTREW: | 1317 | case MTREW: |
1318 | ide_tape_discard_merge_buffer(drive, 0); | 1318 | ide_tape_discard_merge_buffer(drive, 0); |
1319 | if (idetape_rewind_tape(drive)) | 1319 | if (idetape_rewind_tape(drive)) |
1320 | return -EIO; | 1320 | return -EIO; |
1321 | return 0; | 1321 | return 0; |
1322 | case MTLOAD: | 1322 | case MTLOAD: |
1323 | ide_tape_discard_merge_buffer(drive, 0); | 1323 | ide_tape_discard_merge_buffer(drive, 0); |
1324 | return ide_do_start_stop(drive, disk, IDETAPE_LU_LOAD_MASK); | 1324 | return ide_do_start_stop(drive, disk, IDETAPE_LU_LOAD_MASK); |
1325 | case MTUNLOAD: | 1325 | case MTUNLOAD: |
1326 | case MTOFFL: | 1326 | case MTOFFL: |
1327 | /* | 1327 | /* |
1328 | * If door is locked, attempt to unlock before | 1328 | * If door is locked, attempt to unlock before |
1329 | * attempting to eject. | 1329 | * attempting to eject. |
1330 | */ | 1330 | */ |
1331 | if (tape->door_locked) { | 1331 | if (tape->door_locked) { |
1332 | if (!ide_set_media_lock(drive, disk, 0)) | 1332 | if (!ide_set_media_lock(drive, disk, 0)) |
1333 | tape->door_locked = DOOR_UNLOCKED; | 1333 | tape->door_locked = DOOR_UNLOCKED; |
1334 | } | 1334 | } |
1335 | ide_tape_discard_merge_buffer(drive, 0); | 1335 | ide_tape_discard_merge_buffer(drive, 0); |
1336 | retval = ide_do_start_stop(drive, disk, !IDETAPE_LU_LOAD_MASK); | 1336 | retval = ide_do_start_stop(drive, disk, !IDETAPE_LU_LOAD_MASK); |
1337 | if (!retval) | 1337 | if (!retval) |
1338 | clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags); | 1338 | clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags); |
1339 | return retval; | 1339 | return retval; |
1340 | case MTNOP: | 1340 | case MTNOP: |
1341 | ide_tape_discard_merge_buffer(drive, 0); | 1341 | ide_tape_discard_merge_buffer(drive, 0); |
1342 | return idetape_flush_tape_buffers(drive); | 1342 | return idetape_flush_tape_buffers(drive); |
1343 | case MTRETEN: | 1343 | case MTRETEN: |
1344 | ide_tape_discard_merge_buffer(drive, 0); | 1344 | ide_tape_discard_merge_buffer(drive, 0); |
1345 | return ide_do_start_stop(drive, disk, | 1345 | return ide_do_start_stop(drive, disk, |
1346 | IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK); | 1346 | IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK); |
1347 | case MTEOM: | 1347 | case MTEOM: |
1348 | idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD); | 1348 | idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD); |
1349 | return ide_queue_pc_tail(drive, disk, &pc); | 1349 | return ide_queue_pc_tail(drive, disk, &pc); |
1350 | case MTERASE: | 1350 | case MTERASE: |
1351 | (void)idetape_rewind_tape(drive); | 1351 | (void)idetape_rewind_tape(drive); |
1352 | idetape_create_erase_cmd(&pc); | 1352 | idetape_create_erase_cmd(&pc); |
1353 | return ide_queue_pc_tail(drive, disk, &pc); | 1353 | return ide_queue_pc_tail(drive, disk, &pc); |
1354 | case MTSETBLK: | 1354 | case MTSETBLK: |
1355 | if (mt_count) { | 1355 | if (mt_count) { |
1356 | if (mt_count < tape->blk_size || | 1356 | if (mt_count < tape->blk_size || |
1357 | mt_count % tape->blk_size) | 1357 | mt_count % tape->blk_size) |
1358 | return -EIO; | 1358 | return -EIO; |
1359 | tape->user_bs_factor = mt_count / tape->blk_size; | 1359 | tape->user_bs_factor = mt_count / tape->blk_size; |
1360 | clear_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags); | 1360 | clear_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags); |
1361 | } else | 1361 | } else |
1362 | set_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags); | 1362 | set_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags); |
1363 | return 0; | 1363 | return 0; |
1364 | case MTSEEK: | 1364 | case MTSEEK: |
1365 | ide_tape_discard_merge_buffer(drive, 0); | 1365 | ide_tape_discard_merge_buffer(drive, 0); |
1366 | return idetape_position_tape(drive, | 1366 | return idetape_position_tape(drive, |
1367 | mt_count * tape->user_bs_factor, tape->partition, 0); | 1367 | mt_count * tape->user_bs_factor, tape->partition, 0); |
1368 | case MTSETPART: | 1368 | case MTSETPART: |
1369 | ide_tape_discard_merge_buffer(drive, 0); | 1369 | ide_tape_discard_merge_buffer(drive, 0); |
1370 | return idetape_position_tape(drive, 0, mt_count, 0); | 1370 | return idetape_position_tape(drive, 0, mt_count, 0); |
1371 | case MTFSR: | 1371 | case MTFSR: |
1372 | case MTBSR: | 1372 | case MTBSR: |
1373 | case MTLOCK: | 1373 | case MTLOCK: |
1374 | retval = ide_set_media_lock(drive, disk, 1); | 1374 | retval = ide_set_media_lock(drive, disk, 1); |
1375 | if (retval) | 1375 | if (retval) |
1376 | return retval; | 1376 | return retval; |
1377 | tape->door_locked = DOOR_EXPLICITLY_LOCKED; | 1377 | tape->door_locked = DOOR_EXPLICITLY_LOCKED; |
1378 | return 0; | 1378 | return 0; |
1379 | case MTUNLOCK: | 1379 | case MTUNLOCK: |
1380 | retval = ide_set_media_lock(drive, disk, 0); | 1380 | retval = ide_set_media_lock(drive, disk, 0); |
1381 | if (retval) | 1381 | if (retval) |
1382 | return retval; | 1382 | return retval; |
1383 | tape->door_locked = DOOR_UNLOCKED; | 1383 | tape->door_locked = DOOR_UNLOCKED; |
1384 | return 0; | 1384 | return 0; |
1385 | default: | 1385 | default: |
1386 | printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n", | 1386 | printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n", |
1387 | mt_op); | 1387 | mt_op); |
1388 | return -EIO; | 1388 | return -EIO; |
1389 | } | 1389 | } |
1390 | } | 1390 | } |
1391 | 1391 | ||
1392 | /* | 1392 | /* |
1393 | * Our character device ioctls. General mtio.h magnetic io commands are | 1393 | * Our character device ioctls. General mtio.h magnetic io commands are |
1394 | * supported here, and not in the corresponding block interface. Our own | 1394 | * supported here, and not in the corresponding block interface. Our own |
1395 | * ide-tape ioctls are supported on both interfaces. | 1395 | * ide-tape ioctls are supported on both interfaces. |
1396 | */ | 1396 | */ |
1397 | static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, | 1397 | static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, |
1398 | unsigned int cmd, unsigned long arg) | 1398 | unsigned int cmd, unsigned long arg) |
1399 | { | 1399 | { |
1400 | struct ide_tape_obj *tape = file->private_data; | 1400 | struct ide_tape_obj *tape = file->private_data; |
1401 | ide_drive_t *drive = tape->drive; | 1401 | ide_drive_t *drive = tape->drive; |
1402 | struct mtop mtop; | 1402 | struct mtop mtop; |
1403 | struct mtget mtget; | 1403 | struct mtget mtget; |
1404 | struct mtpos mtpos; | 1404 | struct mtpos mtpos; |
1405 | int block_offset = 0, position = tape->first_frame; | 1405 | int block_offset = 0, position = tape->first_frame; |
1406 | void __user *argp = (void __user *)arg; | 1406 | void __user *argp = (void __user *)arg; |
1407 | 1407 | ||
1408 | debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd); | 1408 | debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd); |
1409 | 1409 | ||
1410 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { | 1410 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { |
1411 | ide_tape_flush_merge_buffer(drive); | 1411 | ide_tape_flush_merge_buffer(drive); |
1412 | idetape_flush_tape_buffers(drive); | 1412 | idetape_flush_tape_buffers(drive); |
1413 | } | 1413 | } |
1414 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { | 1414 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { |
1415 | block_offset = tape->valid / | 1415 | block_offset = tape->valid / |
1416 | (tape->blk_size * tape->user_bs_factor); | 1416 | (tape->blk_size * tape->user_bs_factor); |
1417 | position = idetape_read_position(drive); | 1417 | position = idetape_read_position(drive); |
1418 | if (position < 0) | 1418 | if (position < 0) |
1419 | return -EIO; | 1419 | return -EIO; |
1420 | } | 1420 | } |
1421 | switch (cmd) { | 1421 | switch (cmd) { |
1422 | case MTIOCTOP: | 1422 | case MTIOCTOP: |
1423 | if (copy_from_user(&mtop, argp, sizeof(struct mtop))) | 1423 | if (copy_from_user(&mtop, argp, sizeof(struct mtop))) |
1424 | return -EFAULT; | 1424 | return -EFAULT; |
1425 | return idetape_mtioctop(drive, mtop.mt_op, mtop.mt_count); | 1425 | return idetape_mtioctop(drive, mtop.mt_op, mtop.mt_count); |
1426 | case MTIOCGET: | 1426 | case MTIOCGET: |
1427 | memset(&mtget, 0, sizeof(struct mtget)); | 1427 | memset(&mtget, 0, sizeof(struct mtget)); |
1428 | mtget.mt_type = MT_ISSCSI2; | 1428 | mtget.mt_type = MT_ISSCSI2; |
1429 | mtget.mt_blkno = position / tape->user_bs_factor - block_offset; | 1429 | mtget.mt_blkno = position / tape->user_bs_factor - block_offset; |
1430 | mtget.mt_dsreg = | 1430 | mtget.mt_dsreg = |
1431 | ((tape->blk_size * tape->user_bs_factor) | 1431 | ((tape->blk_size * tape->user_bs_factor) |
1432 | << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK; | 1432 | << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK; |
1433 | 1433 | ||
1434 | if (tape->drv_write_prot) | 1434 | if (tape->drv_write_prot) |
1435 | mtget.mt_gstat |= GMT_WR_PROT(0xffffffff); | 1435 | mtget.mt_gstat |= GMT_WR_PROT(0xffffffff); |
1436 | 1436 | ||
1437 | if (copy_to_user(argp, &mtget, sizeof(struct mtget))) | 1437 | if (copy_to_user(argp, &mtget, sizeof(struct mtget))) |
1438 | return -EFAULT; | 1438 | return -EFAULT; |
1439 | return 0; | 1439 | return 0; |
1440 | case MTIOCPOS: | 1440 | case MTIOCPOS: |
1441 | mtpos.mt_blkno = position / tape->user_bs_factor - block_offset; | 1441 | mtpos.mt_blkno = position / tape->user_bs_factor - block_offset; |
1442 | if (copy_to_user(argp, &mtpos, sizeof(struct mtpos))) | 1442 | if (copy_to_user(argp, &mtpos, sizeof(struct mtpos))) |
1443 | return -EFAULT; | 1443 | return -EFAULT; |
1444 | return 0; | 1444 | return 0; |
1445 | default: | 1445 | default: |
1446 | if (tape->chrdev_dir == IDETAPE_DIR_READ) | 1446 | if (tape->chrdev_dir == IDETAPE_DIR_READ) |
1447 | ide_tape_discard_merge_buffer(drive, 1); | 1447 | ide_tape_discard_merge_buffer(drive, 1); |
1448 | return idetape_blkdev_ioctl(drive, cmd, arg); | 1448 | return idetape_blkdev_ioctl(drive, cmd, arg); |
1449 | } | 1449 | } |
1450 | } | 1450 | } |
1451 | 1451 | ||
1452 | /* | 1452 | /* |
1453 | * Do a mode sense page 0 with block descriptor and if it succeeds set the tape | 1453 | * Do a mode sense page 0 with block descriptor and if it succeeds set the tape |
1454 | * block size with the reported value. | 1454 | * block size with the reported value. |
1455 | */ | 1455 | */ |
1456 | static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) | 1456 | static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) |
1457 | { | 1457 | { |
1458 | idetape_tape_t *tape = drive->driver_data; | 1458 | idetape_tape_t *tape = drive->driver_data; |
1459 | struct ide_atapi_pc pc; | 1459 | struct ide_atapi_pc pc; |
1460 | 1460 | ||
1461 | idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR); | 1461 | idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR); |
1462 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { | 1462 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { |
1463 | printk(KERN_ERR "ide-tape: Can't get block descriptor\n"); | 1463 | printk(KERN_ERR "ide-tape: Can't get block descriptor\n"); |
1464 | if (tape->blk_size == 0) { | 1464 | if (tape->blk_size == 0) { |
1465 | printk(KERN_WARNING "ide-tape: Cannot deal with zero " | 1465 | printk(KERN_WARNING "ide-tape: Cannot deal with zero " |
1466 | "block size, assuming 32k\n"); | 1466 | "block size, assuming 32k\n"); |
1467 | tape->blk_size = 32768; | 1467 | tape->blk_size = 32768; |
1468 | } | 1468 | } |
1469 | return; | 1469 | return; |
1470 | } | 1470 | } |
1471 | tape->blk_size = (pc.buf[4 + 5] << 16) + | 1471 | tape->blk_size = (pc.buf[4 + 5] << 16) + |
1472 | (pc.buf[4 + 6] << 8) + | 1472 | (pc.buf[4 + 6] << 8) + |
1473 | pc.buf[4 + 7]; | 1473 | pc.buf[4 + 7]; |
1474 | tape->drv_write_prot = (pc.buf[2] & 0x80) >> 7; | 1474 | tape->drv_write_prot = (pc.buf[2] & 0x80) >> 7; |
1475 | } | 1475 | } |
1476 | 1476 | ||
1477 | static int idetape_chrdev_open(struct inode *inode, struct file *filp) | 1477 | static int idetape_chrdev_open(struct inode *inode, struct file *filp) |
1478 | { | 1478 | { |
1479 | unsigned int minor = iminor(inode), i = minor & ~0xc0; | 1479 | unsigned int minor = iminor(inode), i = minor & ~0xc0; |
1480 | ide_drive_t *drive; | 1480 | ide_drive_t *drive; |
1481 | idetape_tape_t *tape; | 1481 | idetape_tape_t *tape; |
1482 | int retval; | 1482 | int retval; |
1483 | 1483 | ||
1484 | if (i >= MAX_HWIFS * MAX_DRIVES) | 1484 | if (i >= MAX_HWIFS * MAX_DRIVES) |
1485 | return -ENXIO; | 1485 | return -ENXIO; |
1486 | 1486 | ||
1487 | lock_kernel(); | 1487 | lock_kernel(); |
1488 | tape = ide_tape_chrdev_get(i); | 1488 | tape = ide_tape_chrdev_get(i); |
1489 | if (!tape) { | 1489 | if (!tape) { |
1490 | unlock_kernel(); | 1490 | unlock_kernel(); |
1491 | return -ENXIO; | 1491 | return -ENXIO; |
1492 | } | 1492 | } |
1493 | 1493 | ||
1494 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); | 1494 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); |
1495 | 1495 | ||
1496 | /* | 1496 | /* |
1497 | * We really want to do nonseekable_open(inode, filp); here, but some | 1497 | * We really want to do nonseekable_open(inode, filp); here, but some |
1498 | * versions of tar incorrectly call lseek on tapes and bail out if that | 1498 | * versions of tar incorrectly call lseek on tapes and bail out if that |
1499 | * fails. So we disallow pread() and pwrite(), but permit lseeks. | 1499 | * fails. So we disallow pread() and pwrite(), but permit lseeks. |
1500 | */ | 1500 | */ |
1501 | filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); | 1501 | filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); |
1502 | 1502 | ||
1503 | drive = tape->drive; | 1503 | drive = tape->drive; |
1504 | 1504 | ||
1505 | filp->private_data = tape; | 1505 | filp->private_data = tape; |
1506 | 1506 | ||
1507 | if (test_and_set_bit(IDE_AFLAG_BUSY, &drive->atapi_flags)) { | 1507 | if (test_and_set_bit(IDE_AFLAG_BUSY, &drive->atapi_flags)) { |
1508 | retval = -EBUSY; | 1508 | retval = -EBUSY; |
1509 | goto out_put_tape; | 1509 | goto out_put_tape; |
1510 | } | 1510 | } |
1511 | 1511 | ||
1512 | retval = idetape_wait_ready(drive, 60 * HZ); | 1512 | retval = idetape_wait_ready(drive, 60 * HZ); |
1513 | if (retval) { | 1513 | if (retval) { |
1514 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); | 1514 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); |
1515 | printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name); | 1515 | printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name); |
1516 | goto out_put_tape; | 1516 | goto out_put_tape; |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | idetape_read_position(drive); | 1519 | idetape_read_position(drive); |
1520 | if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags)) | 1520 | if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags)) |
1521 | (void)idetape_rewind_tape(drive); | 1521 | (void)idetape_rewind_tape(drive); |
1522 | 1522 | ||
1523 | /* Read block size and write protect status from drive. */ | 1523 | /* Read block size and write protect status from drive. */ |
1524 | ide_tape_get_bsize_from_bdesc(drive); | 1524 | ide_tape_get_bsize_from_bdesc(drive); |
1525 | 1525 | ||
1526 | /* Set write protect flag if device is opened as read-only. */ | 1526 | /* Set write protect flag if device is opened as read-only. */ |
1527 | if ((filp->f_flags & O_ACCMODE) == O_RDONLY) | 1527 | if ((filp->f_flags & O_ACCMODE) == O_RDONLY) |
1528 | tape->write_prot = 1; | 1528 | tape->write_prot = 1; |
1529 | else | 1529 | else |
1530 | tape->write_prot = tape->drv_write_prot; | 1530 | tape->write_prot = tape->drv_write_prot; |
1531 | 1531 | ||
1532 | /* Make sure drive isn't write protected if user wants to write. */ | 1532 | /* Make sure drive isn't write protected if user wants to write. */ |
1533 | if (tape->write_prot) { | 1533 | if (tape->write_prot) { |
1534 | if ((filp->f_flags & O_ACCMODE) == O_WRONLY || | 1534 | if ((filp->f_flags & O_ACCMODE) == O_WRONLY || |
1535 | (filp->f_flags & O_ACCMODE) == O_RDWR) { | 1535 | (filp->f_flags & O_ACCMODE) == O_RDWR) { |
1536 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); | 1536 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); |
1537 | retval = -EROFS; | 1537 | retval = -EROFS; |
1538 | goto out_put_tape; | 1538 | goto out_put_tape; |
1539 | } | 1539 | } |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | /* Lock the tape drive door so user can't eject. */ | 1542 | /* Lock the tape drive door so user can't eject. */ |
1543 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { | 1543 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { |
1544 | if (!ide_set_media_lock(drive, tape->disk, 1)) { | 1544 | if (!ide_set_media_lock(drive, tape->disk, 1)) { |
1545 | if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) | 1545 | if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) |
1546 | tape->door_locked = DOOR_LOCKED; | 1546 | tape->door_locked = DOOR_LOCKED; |
1547 | } | 1547 | } |
1548 | } | 1548 | } |
1549 | unlock_kernel(); | 1549 | unlock_kernel(); |
1550 | return 0; | 1550 | return 0; |
1551 | 1551 | ||
1552 | out_put_tape: | 1552 | out_put_tape: |
1553 | ide_tape_put(tape); | 1553 | ide_tape_put(tape); |
1554 | unlock_kernel(); | 1554 | unlock_kernel(); |
1555 | return retval; | 1555 | return retval; |
1556 | } | 1556 | } |
1557 | 1557 | ||
1558 | static void idetape_write_release(ide_drive_t *drive, unsigned int minor) | 1558 | static void idetape_write_release(ide_drive_t *drive, unsigned int minor) |
1559 | { | 1559 | { |
1560 | idetape_tape_t *tape = drive->driver_data; | 1560 | idetape_tape_t *tape = drive->driver_data; |
1561 | 1561 | ||
1562 | ide_tape_flush_merge_buffer(drive); | 1562 | ide_tape_flush_merge_buffer(drive); |
1563 | tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); | 1563 | tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); |
1564 | if (tape->buf != NULL) { | 1564 | if (tape->buf != NULL) { |
1565 | idetape_pad_zeros(drive, tape->blk_size * | 1565 | idetape_pad_zeros(drive, tape->blk_size * |
1566 | (tape->user_bs_factor - 1)); | 1566 | (tape->user_bs_factor - 1)); |
1567 | kfree(tape->buf); | 1567 | kfree(tape->buf); |
1568 | tape->buf = NULL; | 1568 | tape->buf = NULL; |
1569 | } | 1569 | } |
1570 | idetape_write_filemark(drive); | 1570 | idetape_write_filemark(drive); |
1571 | idetape_flush_tape_buffers(drive); | 1571 | idetape_flush_tape_buffers(drive); |
1572 | idetape_flush_tape_buffers(drive); | 1572 | idetape_flush_tape_buffers(drive); |
1573 | } | 1573 | } |
1574 | 1574 | ||
1575 | static int idetape_chrdev_release(struct inode *inode, struct file *filp) | 1575 | static int idetape_chrdev_release(struct inode *inode, struct file *filp) |
1576 | { | 1576 | { |
1577 | struct ide_tape_obj *tape = filp->private_data; | 1577 | struct ide_tape_obj *tape = filp->private_data; |
1578 | ide_drive_t *drive = tape->drive; | 1578 | ide_drive_t *drive = tape->drive; |
1579 | unsigned int minor = iminor(inode); | 1579 | unsigned int minor = iminor(inode); |
1580 | 1580 | ||
1581 | lock_kernel(); | 1581 | lock_kernel(); |
1582 | tape = drive->driver_data; | 1582 | tape = drive->driver_data; |
1583 | 1583 | ||
1584 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); | 1584 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); |
1585 | 1585 | ||
1586 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) | 1586 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) |
1587 | idetape_write_release(drive, minor); | 1587 | idetape_write_release(drive, minor); |
1588 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { | 1588 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { |
1589 | if (minor < 128) | 1589 | if (minor < 128) |
1590 | ide_tape_discard_merge_buffer(drive, 1); | 1590 | ide_tape_discard_merge_buffer(drive, 1); |
1591 | } | 1591 | } |
1592 | 1592 | ||
1593 | if (minor < 128 && test_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags)) | 1593 | if (minor < 128 && test_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags)) |
1594 | (void) idetape_rewind_tape(drive); | 1594 | (void) idetape_rewind_tape(drive); |
1595 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { | 1595 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { |
1596 | if (tape->door_locked == DOOR_LOCKED) { | 1596 | if (tape->door_locked == DOOR_LOCKED) { |
1597 | if (!ide_set_media_lock(drive, tape->disk, 0)) | 1597 | if (!ide_set_media_lock(drive, tape->disk, 0)) |
1598 | tape->door_locked = DOOR_UNLOCKED; | 1598 | tape->door_locked = DOOR_UNLOCKED; |
1599 | } | 1599 | } |
1600 | } | 1600 | } |
1601 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); | 1601 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); |
1602 | ide_tape_put(tape); | 1602 | ide_tape_put(tape); |
1603 | unlock_kernel(); | 1603 | unlock_kernel(); |
1604 | return 0; | 1604 | return 0; |
1605 | } | 1605 | } |
1606 | 1606 | ||
1607 | static void idetape_get_inquiry_results(ide_drive_t *drive) | 1607 | static void idetape_get_inquiry_results(ide_drive_t *drive) |
1608 | { | 1608 | { |
1609 | idetape_tape_t *tape = drive->driver_data; | 1609 | idetape_tape_t *tape = drive->driver_data; |
1610 | struct ide_atapi_pc pc; | 1610 | struct ide_atapi_pc pc; |
1611 | u8 pc_buf[256]; | 1611 | u8 pc_buf[256]; |
1612 | char fw_rev[4], vendor_id[8], product_id[16]; | 1612 | char fw_rev[4], vendor_id[8], product_id[16]; |
1613 | 1613 | ||
1614 | idetape_create_inquiry_cmd(&pc); | 1614 | idetape_create_inquiry_cmd(&pc); |
1615 | pc.buf = &pc_buf[0]; | 1615 | pc.buf = &pc_buf[0]; |
1616 | pc.buf_size = sizeof(pc_buf); | 1616 | pc.buf_size = sizeof(pc_buf); |
1617 | 1617 | ||
1618 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { | 1618 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { |
1619 | printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", | 1619 | printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", |
1620 | tape->name); | 1620 | tape->name); |
1621 | return; | 1621 | return; |
1622 | } | 1622 | } |
1623 | memcpy(vendor_id, &pc.buf[8], 8); | 1623 | memcpy(vendor_id, &pc.buf[8], 8); |
1624 | memcpy(product_id, &pc.buf[16], 16); | 1624 | memcpy(product_id, &pc.buf[16], 16); |
1625 | memcpy(fw_rev, &pc.buf[32], 4); | 1625 | memcpy(fw_rev, &pc.buf[32], 4); |
1626 | 1626 | ||
1627 | ide_fixstring(vendor_id, 8, 0); | 1627 | ide_fixstring(vendor_id, 8, 0); |
1628 | ide_fixstring(product_id, 16, 0); | 1628 | ide_fixstring(product_id, 16, 0); |
1629 | ide_fixstring(fw_rev, 4, 0); | 1629 | ide_fixstring(fw_rev, 4, 0); |
1630 | 1630 | ||
1631 | printk(KERN_INFO "ide-tape: %s <-> %s: %.8s %.16s rev %.4s\n", | 1631 | printk(KERN_INFO "ide-tape: %s <-> %s: %.8s %.16s rev %.4s\n", |
1632 | drive->name, tape->name, vendor_id, product_id, fw_rev); | 1632 | drive->name, tape->name, vendor_id, product_id, fw_rev); |
1633 | } | 1633 | } |
1634 | 1634 | ||
1635 | /* | 1635 | /* |
1636 | * Ask the tape about its various parameters. In particular, we will adjust our | 1636 | * Ask the tape about its various parameters. In particular, we will adjust our |
1637 | * data transfer buffer size to the recommended value as returned by the tape. | 1637 | * data transfer buffer size to the recommended value as returned by the tape. |
1638 | */ | 1638 | */ |
1639 | static void idetape_get_mode_sense_results(ide_drive_t *drive) | 1639 | static void idetape_get_mode_sense_results(ide_drive_t *drive) |
1640 | { | 1640 | { |
1641 | idetape_tape_t *tape = drive->driver_data; | 1641 | idetape_tape_t *tape = drive->driver_data; |
1642 | struct ide_atapi_pc pc; | 1642 | struct ide_atapi_pc pc; |
1643 | u8 *caps; | 1643 | u8 *caps; |
1644 | u8 speed, max_speed; | 1644 | u8 speed, max_speed; |
1645 | 1645 | ||
1646 | idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE); | 1646 | idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE); |
1647 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { | 1647 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { |
1648 | printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming" | 1648 | printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming" |
1649 | " some default values\n"); | 1649 | " some default values\n"); |
1650 | tape->blk_size = 512; | 1650 | tape->blk_size = 512; |
1651 | put_unaligned(52, (u16 *)&tape->caps[12]); | 1651 | put_unaligned(52, (u16 *)&tape->caps[12]); |
1652 | put_unaligned(540, (u16 *)&tape->caps[14]); | 1652 | put_unaligned(540, (u16 *)&tape->caps[14]); |
1653 | put_unaligned(6*52, (u16 *)&tape->caps[16]); | 1653 | put_unaligned(6*52, (u16 *)&tape->caps[16]); |
1654 | return; | 1654 | return; |
1655 | } | 1655 | } |
1656 | caps = pc.buf + 4 + pc.buf[3]; | 1656 | caps = pc.buf + 4 + pc.buf[3]; |
1657 | 1657 | ||
1658 | /* convert to host order and save for later use */ | 1658 | /* convert to host order and save for later use */ |
1659 | speed = be16_to_cpup((__be16 *)&caps[14]); | 1659 | speed = be16_to_cpup((__be16 *)&caps[14]); |
1660 | max_speed = be16_to_cpup((__be16 *)&caps[8]); | 1660 | max_speed = be16_to_cpup((__be16 *)&caps[8]); |
1661 | 1661 | ||
1662 | *(u16 *)&caps[8] = max_speed; | 1662 | *(u16 *)&caps[8] = max_speed; |
1663 | *(u16 *)&caps[12] = be16_to_cpup((__be16 *)&caps[12]); | 1663 | *(u16 *)&caps[12] = be16_to_cpup((__be16 *)&caps[12]); |
1664 | *(u16 *)&caps[14] = speed; | 1664 | *(u16 *)&caps[14] = speed; |
1665 | *(u16 *)&caps[16] = be16_to_cpup((__be16 *)&caps[16]); | 1665 | *(u16 *)&caps[16] = be16_to_cpup((__be16 *)&caps[16]); |
1666 | 1666 | ||
1667 | if (!speed) { | 1667 | if (!speed) { |
1668 | printk(KERN_INFO "ide-tape: %s: invalid tape speed " | 1668 | printk(KERN_INFO "ide-tape: %s: invalid tape speed " |
1669 | "(assuming 650KB/sec)\n", drive->name); | 1669 | "(assuming 650KB/sec)\n", drive->name); |
1670 | *(u16 *)&caps[14] = 650; | 1670 | *(u16 *)&caps[14] = 650; |
1671 | } | 1671 | } |
1672 | if (!max_speed) { | 1672 | if (!max_speed) { |
1673 | printk(KERN_INFO "ide-tape: %s: invalid max_speed " | 1673 | printk(KERN_INFO "ide-tape: %s: invalid max_speed " |
1674 | "(assuming 650KB/sec)\n", drive->name); | 1674 | "(assuming 650KB/sec)\n", drive->name); |
1675 | *(u16 *)&caps[8] = 650; | 1675 | *(u16 *)&caps[8] = 650; |
1676 | } | 1676 | } |
1677 | 1677 | ||
1678 | memcpy(&tape->caps, caps, 20); | 1678 | memcpy(&tape->caps, caps, 20); |
1679 | 1679 | ||
1680 | /* device lacks locking support according to capabilities page */ | 1680 | /* device lacks locking support according to capabilities page */ |
1681 | if ((caps[6] & 1) == 0) | 1681 | if ((caps[6] & 1) == 0) |
1682 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | 1682 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
1683 | 1683 | ||
1684 | if (caps[7] & 0x02) | 1684 | if (caps[7] & 0x02) |
1685 | tape->blk_size = 512; | 1685 | tape->blk_size = 512; |
1686 | else if (caps[7] & 0x04) | 1686 | else if (caps[7] & 0x04) |
1687 | tape->blk_size = 1024; | 1687 | tape->blk_size = 1024; |
1688 | } | 1688 | } |
1689 | 1689 | ||
1690 | #ifdef CONFIG_IDE_PROC_FS | 1690 | #ifdef CONFIG_IDE_PROC_FS |
1691 | #define ide_tape_devset_get(name, field) \ | 1691 | #define ide_tape_devset_get(name, field) \ |
1692 | static int get_##name(ide_drive_t *drive) \ | 1692 | static int get_##name(ide_drive_t *drive) \ |
1693 | { \ | 1693 | { \ |
1694 | idetape_tape_t *tape = drive->driver_data; \ | 1694 | idetape_tape_t *tape = drive->driver_data; \ |
1695 | return tape->field; \ | 1695 | return tape->field; \ |
1696 | } | 1696 | } |
1697 | 1697 | ||
1698 | #define ide_tape_devset_set(name, field) \ | 1698 | #define ide_tape_devset_set(name, field) \ |
1699 | static int set_##name(ide_drive_t *drive, int arg) \ | 1699 | static int set_##name(ide_drive_t *drive, int arg) \ |
1700 | { \ | 1700 | { \ |
1701 | idetape_tape_t *tape = drive->driver_data; \ | 1701 | idetape_tape_t *tape = drive->driver_data; \ |
1702 | tape->field = arg; \ | 1702 | tape->field = arg; \ |
1703 | return 0; \ | 1703 | return 0; \ |
1704 | } | 1704 | } |
1705 | 1705 | ||
1706 | #define ide_tape_devset_rw_field(_name, _field) \ | 1706 | #define ide_tape_devset_rw_field(_name, _field) \ |
1707 | ide_tape_devset_get(_name, _field) \ | 1707 | ide_tape_devset_get(_name, _field) \ |
1708 | ide_tape_devset_set(_name, _field) \ | 1708 | ide_tape_devset_set(_name, _field) \ |
1709 | IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name) | 1709 | IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name) |
1710 | 1710 | ||
1711 | #define ide_tape_devset_r_field(_name, _field) \ | 1711 | #define ide_tape_devset_r_field(_name, _field) \ |
1712 | ide_tape_devset_get(_name, _field) \ | 1712 | ide_tape_devset_get(_name, _field) \ |
1713 | IDE_DEVSET(_name, 0, get_##_name, NULL) | 1713 | IDE_DEVSET(_name, 0, get_##_name, NULL) |
1714 | 1714 | ||
1715 | static int mulf_tdsc(ide_drive_t *drive) { return 1000; } | 1715 | static int mulf_tdsc(ide_drive_t *drive) { return 1000; } |
1716 | static int divf_tdsc(ide_drive_t *drive) { return HZ; } | 1716 | static int divf_tdsc(ide_drive_t *drive) { return HZ; } |
1717 | static int divf_buffer(ide_drive_t *drive) { return 2; } | 1717 | static int divf_buffer(ide_drive_t *drive) { return 2; } |
1718 | static int divf_buffer_size(ide_drive_t *drive) { return 1024; } | 1718 | static int divf_buffer_size(ide_drive_t *drive) { return 1024; } |
1719 | 1719 | ||
1720 | ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); | 1720 | ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); |
1721 | 1721 | ||
1722 | ide_tape_devset_rw_field(debug_mask, debug_mask); | 1722 | ide_tape_devset_rw_field(debug_mask, debug_mask); |
1723 | ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq); | 1723 | ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq); |
1724 | 1724 | ||
1725 | ide_tape_devset_r_field(avg_speed, avg_speed); | 1725 | ide_tape_devset_r_field(avg_speed, avg_speed); |
1726 | ide_tape_devset_r_field(speed, caps[14]); | 1726 | ide_tape_devset_r_field(speed, caps[14]); |
1727 | ide_tape_devset_r_field(buffer, caps[16]); | 1727 | ide_tape_devset_r_field(buffer, caps[16]); |
1728 | ide_tape_devset_r_field(buffer_size, buffer_size); | 1728 | ide_tape_devset_r_field(buffer_size, buffer_size); |
1729 | 1729 | ||
1730 | static const struct ide_proc_devset idetape_settings[] = { | 1730 | static const struct ide_proc_devset idetape_settings[] = { |
1731 | __IDE_PROC_DEVSET(avg_speed, 0, 0xffff, NULL, NULL), | 1731 | __IDE_PROC_DEVSET(avg_speed, 0, 0xffff, NULL, NULL), |
1732 | __IDE_PROC_DEVSET(buffer, 0, 0xffff, NULL, divf_buffer), | 1732 | __IDE_PROC_DEVSET(buffer, 0, 0xffff, NULL, divf_buffer), |
1733 | __IDE_PROC_DEVSET(buffer_size, 0, 0xffff, NULL, divf_buffer_size), | 1733 | __IDE_PROC_DEVSET(buffer_size, 0, 0xffff, NULL, divf_buffer_size), |
1734 | __IDE_PROC_DEVSET(debug_mask, 0, 0xffff, NULL, NULL), | 1734 | __IDE_PROC_DEVSET(debug_mask, 0, 0xffff, NULL, NULL), |
1735 | __IDE_PROC_DEVSET(dsc_overlap, 0, 1, NULL, NULL), | 1735 | __IDE_PROC_DEVSET(dsc_overlap, 0, 1, NULL, NULL), |
1736 | __IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL), | 1736 | __IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL), |
1737 | __IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, | 1737 | __IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, |
1738 | mulf_tdsc, divf_tdsc), | 1738 | mulf_tdsc, divf_tdsc), |
1739 | { NULL }, | 1739 | { NULL }, |
1740 | }; | 1740 | }; |
1741 | #endif | 1741 | #endif |
1742 | 1742 | ||
1743 | /* | 1743 | /* |
1744 | * The function below is called to: | 1744 | * The function below is called to: |
1745 | * | 1745 | * |
1746 | * 1. Initialize our various state variables. | 1746 | * 1. Initialize our various state variables. |
1747 | * 2. Ask the tape for its capabilities. | 1747 | * 2. Ask the tape for its capabilities. |
1748 | * 3. Allocate a buffer which will be used for data transfer. The buffer size | 1748 | * 3. Allocate a buffer which will be used for data transfer. The buffer size |
1749 | * is chosen based on the recommendation which we received in step 2. | 1749 | * is chosen based on the recommendation which we received in step 2. |
1750 | * | 1750 | * |
1751 | * Note that at this point ide.c already assigned us an irq, so that we can | 1751 | * Note that at this point ide.c already assigned us an irq, so that we can |
1752 | * queue requests here and wait for their completion. | 1752 | * queue requests here and wait for their completion. |
1753 | */ | 1753 | */ |
1754 | static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) | 1754 | static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) |
1755 | { | 1755 | { |
1756 | unsigned long t; | 1756 | unsigned long t; |
1757 | int speed; | 1757 | int speed; |
1758 | int buffer_size; | 1758 | int buffer_size; |
1759 | u16 *ctl = (u16 *)&tape->caps[12]; | 1759 | u16 *ctl = (u16 *)&tape->caps[12]; |
1760 | 1760 | ||
1761 | drive->pc_callback = ide_tape_callback; | 1761 | drive->pc_callback = ide_tape_callback; |
1762 | 1762 | ||
1763 | drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; | 1763 | drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; |
1764 | 1764 | ||
1765 | if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { | 1765 | if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { |
1766 | printk(KERN_INFO "ide-tape: %s: disabling DSC overlap\n", | 1766 | printk(KERN_INFO "ide-tape: %s: disabling DSC overlap\n", |
1767 | tape->name); | 1767 | tape->name); |
1768 | drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; | 1768 | drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; |
1769 | } | 1769 | } |
1770 | 1770 | ||
1771 | /* Seagate Travan drives do not support DSC overlap. */ | 1771 | /* Seagate Travan drives do not support DSC overlap. */ |
1772 | if (strstr((char *)&drive->id[ATA_ID_PROD], "Seagate STT3401")) | 1772 | if (strstr((char *)&drive->id[ATA_ID_PROD], "Seagate STT3401")) |
1773 | drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; | 1773 | drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; |
1774 | 1774 | ||
1775 | tape->minor = minor; | 1775 | tape->minor = minor; |
1776 | tape->name[0] = 'h'; | 1776 | tape->name[0] = 'h'; |
1777 | tape->name[1] = 't'; | 1777 | tape->name[1] = 't'; |
1778 | tape->name[2] = '0' + minor; | 1778 | tape->name[2] = '0' + minor; |
1779 | tape->chrdev_dir = IDETAPE_DIR_NONE; | 1779 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
1780 | 1780 | ||
1781 | idetape_get_inquiry_results(drive); | 1781 | idetape_get_inquiry_results(drive); |
1782 | idetape_get_mode_sense_results(drive); | 1782 | idetape_get_mode_sense_results(drive); |
1783 | ide_tape_get_bsize_from_bdesc(drive); | 1783 | ide_tape_get_bsize_from_bdesc(drive); |
1784 | tape->user_bs_factor = 1; | 1784 | tape->user_bs_factor = 1; |
1785 | tape->buffer_size = *ctl * tape->blk_size; | 1785 | tape->buffer_size = *ctl * tape->blk_size; |
1786 | while (tape->buffer_size > 0xffff) { | 1786 | while (tape->buffer_size > 0xffff) { |
1787 | printk(KERN_NOTICE "ide-tape: decreasing stage size\n"); | 1787 | printk(KERN_NOTICE "ide-tape: decreasing stage size\n"); |
1788 | *ctl /= 2; | 1788 | *ctl /= 2; |
1789 | tape->buffer_size = *ctl * tape->blk_size; | 1789 | tape->buffer_size = *ctl * tape->blk_size; |
1790 | } | 1790 | } |
1791 | buffer_size = tape->buffer_size; | 1791 | buffer_size = tape->buffer_size; |
1792 | 1792 | ||
1793 | /* select the "best" DSC read/write polling freq */ | 1793 | /* select the "best" DSC read/write polling freq */ |
1794 | speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]); | 1794 | speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]); |
1795 | 1795 | ||
1796 | t = (IDETAPE_FIFO_THRESHOLD * tape->buffer_size * HZ) / (speed * 1000); | 1796 | t = (IDETAPE_FIFO_THRESHOLD * tape->buffer_size * HZ) / (speed * 1000); |
1797 | 1797 | ||
1798 | /* | 1798 | /* |
1799 | * Ensure that the number we got makes sense; limit it within | 1799 | * Ensure that the number we got makes sense; limit it within |
1800 | * IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX. | 1800 | * IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX. |
1801 | */ | 1801 | */ |
1802 | tape->best_dsc_rw_freq = clamp_t(unsigned long, t, IDETAPE_DSC_RW_MIN, | 1802 | tape->best_dsc_rw_freq = clamp_t(unsigned long, t, IDETAPE_DSC_RW_MIN, |
1803 | IDETAPE_DSC_RW_MAX); | 1803 | IDETAPE_DSC_RW_MAX); |
1804 | printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, " | 1804 | printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, " |
1805 | "%lums tDSC%s\n", | 1805 | "%lums tDSC%s\n", |
1806 | drive->name, tape->name, *(u16 *)&tape->caps[14], | 1806 | drive->name, tape->name, *(u16 *)&tape->caps[14], |
1807 | (*(u16 *)&tape->caps[16] * 512) / tape->buffer_size, | 1807 | (*(u16 *)&tape->caps[16] * 512) / tape->buffer_size, |
1808 | tape->buffer_size / 1024, | 1808 | tape->buffer_size / 1024, |
1809 | tape->best_dsc_rw_freq * 1000 / HZ, | 1809 | tape->best_dsc_rw_freq * 1000 / HZ, |
1810 | (drive->dev_flags & IDE_DFLAG_USING_DMA) ? ", DMA" : ""); | 1810 | (drive->dev_flags & IDE_DFLAG_USING_DMA) ? ", DMA" : ""); |
1811 | 1811 | ||
1812 | ide_proc_register_driver(drive, tape->driver); | 1812 | ide_proc_register_driver(drive, tape->driver); |
1813 | } | 1813 | } |
1814 | 1814 | ||
1815 | static void ide_tape_remove(ide_drive_t *drive) | 1815 | static void ide_tape_remove(ide_drive_t *drive) |
1816 | { | 1816 | { |
1817 | idetape_tape_t *tape = drive->driver_data; | 1817 | idetape_tape_t *tape = drive->driver_data; |
1818 | 1818 | ||
1819 | ide_proc_unregister_driver(drive, tape->driver); | 1819 | ide_proc_unregister_driver(drive, tape->driver); |
1820 | device_del(&tape->dev); | 1820 | device_del(&tape->dev); |
1821 | ide_unregister_region(tape->disk); | 1821 | ide_unregister_region(tape->disk); |
1822 | 1822 | ||
1823 | mutex_lock(&idetape_ref_mutex); | 1823 | mutex_lock(&idetape_ref_mutex); |
1824 | put_device(&tape->dev); | 1824 | put_device(&tape->dev); |
1825 | mutex_unlock(&idetape_ref_mutex); | 1825 | mutex_unlock(&idetape_ref_mutex); |
1826 | } | 1826 | } |
1827 | 1827 | ||
1828 | static void ide_tape_release(struct device *dev) | 1828 | static void ide_tape_release(struct device *dev) |
1829 | { | 1829 | { |
1830 | struct ide_tape_obj *tape = to_ide_drv(dev, ide_tape_obj); | 1830 | struct ide_tape_obj *tape = to_ide_drv(dev, ide_tape_obj); |
1831 | ide_drive_t *drive = tape->drive; | 1831 | ide_drive_t *drive = tape->drive; |
1832 | struct gendisk *g = tape->disk; | 1832 | struct gendisk *g = tape->disk; |
1833 | 1833 | ||
1834 | BUG_ON(tape->valid); | 1834 | BUG_ON(tape->valid); |
1835 | 1835 | ||
1836 | drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; | 1836 | drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; |
1837 | drive->driver_data = NULL; | 1837 | drive->driver_data = NULL; |
1838 | device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor)); | 1838 | device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor)); |
1839 | device_destroy(idetape_sysfs_class, | 1839 | device_destroy(idetape_sysfs_class, |
1840 | MKDEV(IDETAPE_MAJOR, tape->minor + 128)); | 1840 | MKDEV(IDETAPE_MAJOR, tape->minor + 128)); |
1841 | idetape_devs[tape->minor] = NULL; | 1841 | idetape_devs[tape->minor] = NULL; |
1842 | g->private_data = NULL; | 1842 | g->private_data = NULL; |
1843 | put_disk(g); | 1843 | put_disk(g); |
1844 | kfree(tape); | 1844 | kfree(tape); |
1845 | } | 1845 | } |
1846 | 1846 | ||
1847 | #ifdef CONFIG_IDE_PROC_FS | 1847 | #ifdef CONFIG_IDE_PROC_FS |
1848 | static int proc_idetape_read_name | 1848 | static int proc_idetape_read_name |
1849 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 1849 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
1850 | { | 1850 | { |
1851 | ide_drive_t *drive = (ide_drive_t *) data; | 1851 | ide_drive_t *drive = (ide_drive_t *) data; |
1852 | idetape_tape_t *tape = drive->driver_data; | 1852 | idetape_tape_t *tape = drive->driver_data; |
1853 | char *out = page; | 1853 | char *out = page; |
1854 | int len; | 1854 | int len; |
1855 | 1855 | ||
1856 | len = sprintf(out, "%s\n", tape->name); | 1856 | len = sprintf(out, "%s\n", tape->name); |
1857 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | 1857 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
1858 | } | 1858 | } |
1859 | 1859 | ||
1860 | static ide_proc_entry_t idetape_proc[] = { | 1860 | static ide_proc_entry_t idetape_proc[] = { |
1861 | { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, | 1861 | { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, |
1862 | { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL }, | 1862 | { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL }, |
1863 | { NULL, 0, NULL, NULL } | 1863 | { NULL, 0, NULL, NULL } |
1864 | }; | 1864 | }; |
1865 | 1865 | ||
1866 | static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive) | 1866 | static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive) |
1867 | { | 1867 | { |
1868 | return idetape_proc; | 1868 | return idetape_proc; |
1869 | } | 1869 | } |
1870 | 1870 | ||
1871 | static const struct ide_proc_devset *ide_tape_proc_devsets(ide_drive_t *drive) | 1871 | static const struct ide_proc_devset *ide_tape_proc_devsets(ide_drive_t *drive) |
1872 | { | 1872 | { |
1873 | return idetape_settings; | 1873 | return idetape_settings; |
1874 | } | 1874 | } |
1875 | #endif | 1875 | #endif |
1876 | 1876 | ||
1877 | static int ide_tape_probe(ide_drive_t *); | 1877 | static int ide_tape_probe(ide_drive_t *); |
1878 | 1878 | ||
1879 | static struct ide_driver idetape_driver = { | 1879 | static struct ide_driver idetape_driver = { |
1880 | .gen_driver = { | 1880 | .gen_driver = { |
1881 | .owner = THIS_MODULE, | 1881 | .owner = THIS_MODULE, |
1882 | .name = "ide-tape", | 1882 | .name = "ide-tape", |
1883 | .bus = &ide_bus_type, | 1883 | .bus = &ide_bus_type, |
1884 | }, | 1884 | }, |
1885 | .probe = ide_tape_probe, | 1885 | .probe = ide_tape_probe, |
1886 | .remove = ide_tape_remove, | 1886 | .remove = ide_tape_remove, |
1887 | .version = IDETAPE_VERSION, | 1887 | .version = IDETAPE_VERSION, |
1888 | .do_request = idetape_do_request, | 1888 | .do_request = idetape_do_request, |
1889 | #ifdef CONFIG_IDE_PROC_FS | 1889 | #ifdef CONFIG_IDE_PROC_FS |
1890 | .proc_entries = ide_tape_proc_entries, | 1890 | .proc_entries = ide_tape_proc_entries, |
1891 | .proc_devsets = ide_tape_proc_devsets, | 1891 | .proc_devsets = ide_tape_proc_devsets, |
1892 | #endif | 1892 | #endif |
1893 | }; | 1893 | }; |
1894 | 1894 | ||
1895 | /* Our character device supporting functions, passed to register_chrdev. */ | 1895 | /* Our character device supporting functions, passed to register_chrdev. */ |
1896 | static const struct file_operations idetape_fops = { | 1896 | static const struct file_operations idetape_fops = { |
1897 | .owner = THIS_MODULE, | 1897 | .owner = THIS_MODULE, |
1898 | .read = idetape_chrdev_read, | 1898 | .read = idetape_chrdev_read, |
1899 | .write = idetape_chrdev_write, | 1899 | .write = idetape_chrdev_write, |
1900 | .ioctl = idetape_chrdev_ioctl, | 1900 | .ioctl = idetape_chrdev_ioctl, |
1901 | .open = idetape_chrdev_open, | 1901 | .open = idetape_chrdev_open, |
1902 | .release = idetape_chrdev_release, | 1902 | .release = idetape_chrdev_release, |
1903 | }; | 1903 | }; |
1904 | 1904 | ||
1905 | static int idetape_open(struct block_device *bdev, fmode_t mode) | 1905 | static int idetape_open(struct block_device *bdev, fmode_t mode) |
1906 | { | 1906 | { |
1907 | struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk); | 1907 | struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk); |
1908 | 1908 | ||
1909 | if (!tape) | 1909 | if (!tape) |
1910 | return -ENXIO; | 1910 | return -ENXIO; |
1911 | 1911 | ||
1912 | return 0; | 1912 | return 0; |
1913 | } | 1913 | } |
1914 | 1914 | ||
1915 | static int idetape_release(struct gendisk *disk, fmode_t mode) | 1915 | static int idetape_release(struct gendisk *disk, fmode_t mode) |
1916 | { | 1916 | { |
1917 | struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj); | 1917 | struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj); |
1918 | 1918 | ||
1919 | ide_tape_put(tape); | 1919 | ide_tape_put(tape); |
1920 | return 0; | 1920 | return 0; |
1921 | } | 1921 | } |
1922 | 1922 | ||
1923 | static int idetape_ioctl(struct block_device *bdev, fmode_t mode, | 1923 | static int idetape_ioctl(struct block_device *bdev, fmode_t mode, |
1924 | unsigned int cmd, unsigned long arg) | 1924 | unsigned int cmd, unsigned long arg) |
1925 | { | 1925 | { |
1926 | struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj); | 1926 | struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj); |
1927 | ide_drive_t *drive = tape->drive; | 1927 | ide_drive_t *drive = tape->drive; |
1928 | int err = generic_ide_ioctl(drive, bdev, cmd, arg); | 1928 | int err = generic_ide_ioctl(drive, bdev, cmd, arg); |
1929 | if (err == -EINVAL) | 1929 | if (err == -EINVAL) |
1930 | err = idetape_blkdev_ioctl(drive, cmd, arg); | 1930 | err = idetape_blkdev_ioctl(drive, cmd, arg); |
1931 | return err; | 1931 | return err; |
1932 | } | 1932 | } |
1933 | 1933 | ||
1934 | static struct block_device_operations idetape_block_ops = { | 1934 | static struct block_device_operations idetape_block_ops = { |
1935 | .owner = THIS_MODULE, | 1935 | .owner = THIS_MODULE, |
1936 | .open = idetape_open, | 1936 | .open = idetape_open, |
1937 | .release = idetape_release, | 1937 | .release = idetape_release, |
1938 | .locked_ioctl = idetape_ioctl, | 1938 | .locked_ioctl = idetape_ioctl, |
1939 | }; | 1939 | }; |
1940 | 1940 | ||
1941 | static int ide_tape_probe(ide_drive_t *drive) | 1941 | static int ide_tape_probe(ide_drive_t *drive) |
1942 | { | 1942 | { |
1943 | idetape_tape_t *tape; | 1943 | idetape_tape_t *tape; |
1944 | struct gendisk *g; | 1944 | struct gendisk *g; |
1945 | int minor; | 1945 | int minor; |
1946 | 1946 | ||
1947 | if (!strstr("ide-tape", drive->driver_req)) | 1947 | if (!strstr("ide-tape", drive->driver_req)) |
1948 | goto failed; | 1948 | goto failed; |
1949 | 1949 | ||
1950 | if (drive->media != ide_tape) | 1950 | if (drive->media != ide_tape) |
1951 | goto failed; | 1951 | goto failed; |
1952 | 1952 | ||
1953 | if ((drive->dev_flags & IDE_DFLAG_ID_READ) && | 1953 | if ((drive->dev_flags & IDE_DFLAG_ID_READ) && |
1954 | ide_check_atapi_device(drive, DRV_NAME) == 0) { | 1954 | ide_check_atapi_device(drive, DRV_NAME) == 0) { |
1955 | printk(KERN_ERR "ide-tape: %s: not supported by this version of" | 1955 | printk(KERN_ERR "ide-tape: %s: not supported by this version of" |
1956 | " the driver\n", drive->name); | 1956 | " the driver\n", drive->name); |
1957 | goto failed; | 1957 | goto failed; |
1958 | } | 1958 | } |
1959 | tape = kzalloc(sizeof(idetape_tape_t), GFP_KERNEL); | 1959 | tape = kzalloc(sizeof(idetape_tape_t), GFP_KERNEL); |
1960 | if (tape == NULL) { | 1960 | if (tape == NULL) { |
1961 | printk(KERN_ERR "ide-tape: %s: Can't allocate a tape struct\n", | 1961 | printk(KERN_ERR "ide-tape: %s: Can't allocate a tape struct\n", |
1962 | drive->name); | 1962 | drive->name); |
1963 | goto failed; | 1963 | goto failed; |
1964 | } | 1964 | } |
1965 | 1965 | ||
1966 | g = alloc_disk(1 << PARTN_BITS); | 1966 | g = alloc_disk(1 << PARTN_BITS); |
1967 | if (!g) | 1967 | if (!g) |
1968 | goto out_free_tape; | 1968 | goto out_free_tape; |
1969 | 1969 | ||
1970 | ide_init_disk(g, drive); | 1970 | ide_init_disk(g, drive); |
1971 | 1971 | ||
1972 | tape->dev.parent = &drive->gendev; | 1972 | tape->dev.parent = &drive->gendev; |
1973 | tape->dev.release = ide_tape_release; | 1973 | tape->dev.release = ide_tape_release; |
1974 | dev_set_name(&tape->dev, dev_name(&drive->gendev)); | 1974 | dev_set_name(&tape->dev, dev_name(&drive->gendev)); |
1975 | 1975 | ||
1976 | if (device_register(&tape->dev)) | 1976 | if (device_register(&tape->dev)) |
1977 | goto out_free_disk; | 1977 | goto out_free_disk; |
1978 | 1978 | ||
1979 | tape->drive = drive; | 1979 | tape->drive = drive; |
1980 | tape->driver = &idetape_driver; | 1980 | tape->driver = &idetape_driver; |
1981 | tape->disk = g; | 1981 | tape->disk = g; |
1982 | 1982 | ||
1983 | g->private_data = &tape->driver; | 1983 | g->private_data = &tape->driver; |
1984 | 1984 | ||
1985 | drive->driver_data = tape; | 1985 | drive->driver_data = tape; |
1986 | 1986 | ||
1987 | mutex_lock(&idetape_ref_mutex); | 1987 | mutex_lock(&idetape_ref_mutex); |
1988 | for (minor = 0; idetape_devs[minor]; minor++) | 1988 | for (minor = 0; idetape_devs[minor]; minor++) |
1989 | ; | 1989 | ; |
1990 | idetape_devs[minor] = tape; | 1990 | idetape_devs[minor] = tape; |
1991 | mutex_unlock(&idetape_ref_mutex); | 1991 | mutex_unlock(&idetape_ref_mutex); |
1992 | 1992 | ||
1993 | idetape_setup(drive, tape, minor); | 1993 | idetape_setup(drive, tape, minor); |
1994 | 1994 | ||
1995 | device_create(idetape_sysfs_class, &drive->gendev, | 1995 | device_create(idetape_sysfs_class, &drive->gendev, |
1996 | MKDEV(IDETAPE_MAJOR, minor), NULL, "%s", tape->name); | 1996 | MKDEV(IDETAPE_MAJOR, minor), NULL, "%s", tape->name); |
1997 | device_create(idetape_sysfs_class, &drive->gendev, | 1997 | device_create(idetape_sysfs_class, &drive->gendev, |
1998 | MKDEV(IDETAPE_MAJOR, minor + 128), NULL, | 1998 | MKDEV(IDETAPE_MAJOR, minor + 128), NULL, |
1999 | "n%s", tape->name); | 1999 | "n%s", tape->name); |
2000 | 2000 | ||
2001 | g->fops = &idetape_block_ops; | 2001 | g->fops = &idetape_block_ops; |
2002 | ide_register_region(g); | 2002 | ide_register_region(g); |
2003 | 2003 | ||
2004 | return 0; | 2004 | return 0; |
2005 | 2005 | ||
2006 | out_free_disk: | 2006 | out_free_disk: |
2007 | put_disk(g); | 2007 | put_disk(g); |
2008 | out_free_tape: | 2008 | out_free_tape: |
2009 | kfree(tape); | 2009 | kfree(tape); |
2010 | failed: | 2010 | failed: |
2011 | return -ENODEV; | 2011 | return -ENODEV; |
2012 | } | 2012 | } |
2013 | 2013 | ||
2014 | static void __exit idetape_exit(void) | 2014 | static void __exit idetape_exit(void) |
2015 | { | 2015 | { |
2016 | driver_unregister(&idetape_driver.gen_driver); | 2016 | driver_unregister(&idetape_driver.gen_driver); |
2017 | class_destroy(idetape_sysfs_class); | 2017 | class_destroy(idetape_sysfs_class); |
2018 | unregister_chrdev(IDETAPE_MAJOR, "ht"); | 2018 | unregister_chrdev(IDETAPE_MAJOR, "ht"); |
2019 | } | 2019 | } |
2020 | 2020 | ||
2021 | static int __init idetape_init(void) | 2021 | static int __init idetape_init(void) |
2022 | { | 2022 | { |
2023 | int error = 1; | 2023 | int error = 1; |
2024 | idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape"); | 2024 | idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape"); |
2025 | if (IS_ERR(idetape_sysfs_class)) { | 2025 | if (IS_ERR(idetape_sysfs_class)) { |
2026 | idetape_sysfs_class = NULL; | 2026 | idetape_sysfs_class = NULL; |
2027 | printk(KERN_ERR "Unable to create sysfs class for ide tapes\n"); | 2027 | printk(KERN_ERR "Unable to create sysfs class for ide tapes\n"); |
2028 | error = -EBUSY; | 2028 | error = -EBUSY; |
2029 | goto out; | 2029 | goto out; |
2030 | } | 2030 | } |
2031 | 2031 | ||
2032 | if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) { | 2032 | if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) { |
2033 | printk(KERN_ERR "ide-tape: Failed to register chrdev" | 2033 | printk(KERN_ERR "ide-tape: Failed to register chrdev" |
2034 | " interface\n"); | 2034 | " interface\n"); |
2035 | error = -EBUSY; | 2035 | error = -EBUSY; |
2036 | goto out_free_class; | 2036 | goto out_free_class; |
2037 | } | 2037 | } |
2038 | 2038 | ||
2039 | error = driver_register(&idetape_driver.gen_driver); | 2039 | error = driver_register(&idetape_driver.gen_driver); |
2040 | if (error) | 2040 | if (error) |
2041 | goto out_free_driver; | 2041 | goto out_free_driver; |
2042 | 2042 | ||
2043 | return 0; | 2043 | return 0; |
2044 | 2044 | ||
2045 | out_free_driver: | 2045 | out_free_driver: |
2046 | driver_unregister(&idetape_driver.gen_driver); | 2046 | driver_unregister(&idetape_driver.gen_driver); |
2047 | out_free_class: | 2047 | out_free_class: |
2048 | class_destroy(idetape_sysfs_class); | 2048 | class_destroy(idetape_sysfs_class); |
2049 | out: | 2049 | out: |
2050 | return error; | 2050 | return error; |
2051 | } | 2051 | } |
2052 | 2052 | ||
2053 | MODULE_ALIAS("ide:*m-tape*"); | 2053 | MODULE_ALIAS("ide:*m-tape*"); |
2054 | module_init(idetape_init); | 2054 | module_init(idetape_init); |
2055 | module_exit(idetape_exit); | 2055 | module_exit(idetape_exit); |
2056 | MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR); | 2056 | MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR); |
2057 | MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); | 2057 | MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); |
2058 | MODULE_LICENSE("GPL"); | 2058 | MODULE_LICENSE("GPL"); |
2059 | 2059 |