aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-atapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-atapi.c')
-rw-r--r--drivers/ide/ide-atapi.c168
1 files changed, 105 insertions, 63 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 7201b176d75b..afe5a4323879 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -80,34 +80,6 @@ void ide_init_pc(struct ide_atapi_pc *pc)
80EXPORT_SYMBOL_GPL(ide_init_pc); 80EXPORT_SYMBOL_GPL(ide_init_pc);
81 81
82/* 82/*
83 * Generate a new packet command request in front of the request queue, before
84 * the current request, so that it will be processed immediately, on the next
85 * pass through the driver.
86 */
87static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
88 struct ide_atapi_pc *pc, struct request *rq)
89{
90 blk_rq_init(NULL, rq);
91 rq->cmd_type = REQ_TYPE_SPECIAL;
92 rq->cmd_flags |= REQ_PREEMPT;
93 rq->buffer = (char *)pc;
94 rq->rq_disk = disk;
95
96 if (pc->req_xfer) {
97 rq->data = pc->buf;
98 rq->data_len = pc->req_xfer;
99 }
100
101 memcpy(rq->cmd, pc->c, 12);
102 if (drive->media == ide_tape)
103 rq->cmd[13] = REQ_IDETAPE_PC1;
104
105 drive->hwif->rq = NULL;
106
107 elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
108}
109
110/*
111 * 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,
112 * and wait for it to be serviced. 84 * and wait for it to be serviced.
113 */ 85 */
@@ -119,19 +91,21 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
119 91
120 rq = blk_get_request(drive->queue, READ, __GFP_WAIT); 92 rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
121 rq->cmd_type = REQ_TYPE_SPECIAL; 93 rq->cmd_type = REQ_TYPE_SPECIAL;
122 rq->buffer = (char *)pc; 94 rq->special = (char *)pc;
123 95
124 if (pc->req_xfer) { 96 if (pc->req_xfer) {
125 rq->data = pc->buf; 97 error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer,
126 rq->data_len = pc->req_xfer; 98 GFP_NOIO);
99 if (error)
100 goto put_req;
127 } 101 }
128 102
129 memcpy(rq->cmd, pc->c, 12); 103 memcpy(rq->cmd, pc->c, 12);
130 if (drive->media == ide_tape) 104 if (drive->media == ide_tape)
131 rq->cmd[13] = REQ_IDETAPE_PC1; 105 rq->cmd[13] = REQ_IDETAPE_PC1;
132 error = blk_execute_rq(drive->queue, disk, rq, 0); 106 error = blk_execute_rq(drive->queue, disk, rq, 0);
107put_req:
133 blk_put_request(rq); 108 blk_put_request(rq);
134
135 return error; 109 return error;
136} 110}
137EXPORT_SYMBOL_GPL(ide_queue_pc_tail); 111EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
@@ -191,20 +165,103 @@ void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc)
191} 165}
192EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd); 166EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);
193 167
168void ide_prep_sense(ide_drive_t *drive, struct request *rq)
169{
170 struct request_sense *sense = &drive->sense_data;
171 struct request *sense_rq = &drive->sense_rq;
172 unsigned int cmd_len, sense_len;
173 int err;
174
175 debug_log("%s: enter\n", __func__);
176
177 switch (drive->media) {
178 case ide_floppy:
179 cmd_len = 255;
180 sense_len = 18;
181 break;
182 case ide_tape:
183 cmd_len = 20;
184 sense_len = 20;
185 break;
186 default:
187 cmd_len = 18;
188 sense_len = 18;
189 }
190
191 BUG_ON(sense_len > sizeof(*sense));
192
193 if (blk_sense_request(rq) || drive->sense_rq_armed)
194 return;
195
196 memset(sense, 0, sizeof(*sense));
197
198 blk_rq_init(rq->q, sense_rq);
199
200 err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len,
201 GFP_NOIO);
202 if (unlikely(err)) {
203 if (printk_ratelimit())
204 printk(KERN_WARNING "%s: failed to map sense buffer\n",
205 drive->name);
206 return;
207 }
208
209 sense_rq->rq_disk = rq->rq_disk;
210 sense_rq->cmd[0] = GPCMD_REQUEST_SENSE;
211 sense_rq->cmd[4] = cmd_len;
212 sense_rq->cmd_type = REQ_TYPE_SENSE;
213 sense_rq->cmd_flags |= REQ_PREEMPT;
214
215 if (drive->media == ide_tape)
216 sense_rq->cmd[13] = REQ_IDETAPE_PC1;
217
218 drive->sense_rq_armed = true;
219}
220EXPORT_SYMBOL_GPL(ide_prep_sense);
221
222int ide_queue_sense_rq(ide_drive_t *drive, void *special)
223{
224 /* deferred failure from ide_prep_sense() */
225 if (!drive->sense_rq_armed) {
226 printk(KERN_WARNING "%s: failed queue sense request\n",
227 drive->name);
228 return -ENOMEM;
229 }
230
231 drive->sense_rq.special = special;
232 drive->sense_rq_armed = false;
233
234 drive->hwif->rq = NULL;
235
236 elv_add_request(drive->queue, &drive->sense_rq,
237 ELEVATOR_INSERT_FRONT, 0);
238 return 0;
239}
240EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
241
194/* 242/*
195 * Called when an error was detected during the last packet command. 243 * Called when an error was detected during the last packet command.
196 * We queue a request sense packet command in the head of the request list. 244 * We queue a request sense packet command at the head of the request
245 * queue.
197 */ 246 */
198void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) 247void ide_retry_pc(ide_drive_t *drive)
199{ 248{
200 struct request *rq = &drive->request_sense_rq; 249 struct request *sense_rq = &drive->sense_rq;
201 struct ide_atapi_pc *pc = &drive->request_sense_pc; 250 struct ide_atapi_pc *pc = &drive->request_sense_pc;
202 251
203 (void)ide_read_error(drive); 252 (void)ide_read_error(drive);
204 ide_create_request_sense_cmd(drive, pc); 253
254 /* init pc from sense_rq */
255 ide_init_pc(pc);
256 memcpy(pc->c, sense_rq->cmd, 12);
257 pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */
258 pc->req_xfer = sense_rq->data_len;
259
205 if (drive->media == ide_tape) 260 if (drive->media == ide_tape)
206 set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); 261 set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
207 ide_queue_pc_head(drive, disk, pc, rq); 262
263 if (ide_queue_sense_rq(drive, pc))
264 ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq));
208} 265}
209EXPORT_SYMBOL_GPL(ide_retry_pc); 266EXPORT_SYMBOL_GPL(ide_retry_pc);
210 267
@@ -276,7 +333,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
276 struct ide_cmd *cmd = &hwif->cmd; 333 struct ide_cmd *cmd = &hwif->cmd;
277 struct request *rq = hwif->rq; 334 struct request *rq = hwif->rq;
278 const struct ide_tp_ops *tp_ops = hwif->tp_ops; 335 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
279 xfer_func_t *xferfunc;
280 unsigned int timeout, done; 336 unsigned int timeout, done;
281 u16 bcount; 337 u16 bcount;
282 u8 stat, ireason, dsc = 0; 338 u8 stat, ireason, dsc = 0;
@@ -303,11 +359,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
303 drive->name, rq_data_dir(pc->rq) 359 drive->name, rq_data_dir(pc->rq)
304 ? "write" : "read"); 360 ? "write" : "read");
305 pc->flags |= PC_FLAG_DMA_ERROR; 361 pc->flags |= PC_FLAG_DMA_ERROR;
306 } else { 362 } else
307 pc->xferred = pc->req_xfer; 363 pc->xferred = pc->req_xfer;
308 if (drive->pc_update_buffers)
309 drive->pc_update_buffers(drive, pc);
310 }
311 debug_log("%s: DMA finished\n", drive->name); 364 debug_log("%s: DMA finished\n", drive->name);
312 } 365 }
313 366
@@ -343,7 +396,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
343 debug_log("[cmd %x]: check condition\n", rq->cmd[0]); 396 debug_log("[cmd %x]: check condition\n", rq->cmd[0]);
344 397
345 /* Retry operation */ 398 /* Retry operation */
346 ide_retry_pc(drive, rq->rq_disk); 399 ide_retry_pc(drive);
347 400
348 /* queued, but not started */ 401 /* queued, but not started */
349 return ide_stopped; 402 return ide_stopped;
@@ -353,6 +406,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
353 if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) 406 if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
354 dsc = 1; 407 dsc = 1;
355 408
409 /*
410 * ->pc_callback() might change rq->data_len for
411 * residual count, cache total length.
412 */
413 done = blk_rq_bytes(rq);
414
356 /* Command finished - Call the callback function */ 415 /* Command finished - Call the callback function */
357 uptodate = drive->pc_callback(drive, dsc); 416 uptodate = drive->pc_callback(drive, dsc);
358 417
@@ -361,7 +420,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
361 420
362 if (blk_special_request(rq)) { 421 if (blk_special_request(rq)) {
363 rq->errors = 0; 422 rq->errors = 0;
364 done = blk_rq_bytes(rq);
365 error = 0; 423 error = 0;
366 } else { 424 } else {
367 425
@@ -370,11 +428,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
370 rq->errors = -EIO; 428 rq->errors = -EIO;
371 } 429 }
372 430
373 if (drive->media == ide_tape)
374 done = ide_rq_bytes(rq); /* FIXME */
375 else
376 done = blk_rq_bytes(rq);
377
378 error = uptodate ? 0 : -EIO; 431 error = uptodate ? 0 : -EIO;
379 } 432 }
380 433
@@ -407,21 +460,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
407 return ide_do_reset(drive); 460 return ide_do_reset(drive);
408 } 461 }
409 462
410 xferfunc = write ? tp_ops->output_data : tp_ops->input_data; 463 done = min_t(unsigned int, bcount, cmd->nleft);
411 464 ide_pio_bytes(drive, cmd, write, done);
412 if (drive->media == ide_floppy && pc->buf == NULL) {
413 done = min_t(unsigned int, bcount, cmd->nleft);
414 ide_pio_bytes(drive, cmd, write, done);
415 } else if (drive->media == ide_tape && pc->bh) {
416 done = drive->pc_io_buffers(drive, pc, bcount, write);
417 } else {
418 done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred);
419 xferfunc(drive, NULL, pc->cur_pos, done);
420 }
421 465
422 /* Update the current position */ 466 /* Update transferred byte count */
423 pc->xferred += done; 467 pc->xferred += done;
424 pc->cur_pos += done;
425 468
426 bcount -= done; 469 bcount -= done;
427 470
@@ -599,7 +642,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
599 642
600 /* We haven't transferred any data yet */ 643 /* We haven't transferred any data yet */
601 pc->xferred = 0; 644 pc->xferred = 0;
602 pc->cur_pos = pc->buf;
603 645
604 valid_tf = IDE_VALID_DEVICE; 646 valid_tf = IDE_VALID_DEVICE;
605 bcount = ((drive->media == ide_tape) ? 647 bcount = ((drive->media == ide_tape) ?