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.c183
1 files changed, 135 insertions, 48 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 608c5bade929..2e305714c209 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -124,8 +124,8 @@ EXPORT_SYMBOL_GPL(ide_init_pc);
124 * the current request, so that it will be processed immediately, on the next 124 * the current request, so that it will be processed immediately, on the next
125 * pass through the driver. 125 * pass through the driver.
126 */ 126 */
127void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, 127static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
128 struct ide_atapi_pc *pc, struct request *rq) 128 struct ide_atapi_pc *pc, struct request *rq)
129{ 129{
130 blk_rq_init(NULL, rq); 130 blk_rq_init(NULL, rq);
131 rq->cmd_type = REQ_TYPE_SPECIAL; 131 rq->cmd_type = REQ_TYPE_SPECIAL;
@@ -137,7 +137,6 @@ void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
137 rq->cmd[13] = REQ_IDETAPE_PC1; 137 rq->cmd[13] = REQ_IDETAPE_PC1;
138 ide_do_drive_cmd(drive, rq); 138 ide_do_drive_cmd(drive, rq);
139} 139}
140EXPORT_SYMBOL_GPL(ide_queue_pc_head);
141 140
142/* 141/*
143 * Add a special packet command request to the tail of the request queue, 142 * Add a special packet command request to the tail of the request queue,
@@ -203,25 +202,80 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
203} 202}
204EXPORT_SYMBOL_GPL(ide_set_media_lock); 203EXPORT_SYMBOL_GPL(ide_set_media_lock);
205 204
206/* TODO: unify the code thus making some arguments go away */ 205void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc)
207ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
208 ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
209 void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
210 void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
211 int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
212{ 206{
207 ide_init_pc(pc);
208 pc->c[0] = REQUEST_SENSE;
209 if (drive->media == ide_floppy) {
210 pc->c[4] = 255;
211 pc->req_xfer = 18;
212 } else {
213 pc->c[4] = 20;
214 pc->req_xfer = 20;
215 }
216}
217EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);
218
219/*
220 * Called when an error was detected during the last packet command.
221 * We queue a request sense packet command in the head of the request list.
222 */
223void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk)
224{
225 struct request *rq = &drive->request_sense_rq;
226 struct ide_atapi_pc *pc = &drive->request_sense_pc;
227
228 (void)ide_read_error(drive);
229 ide_create_request_sense_cmd(drive, pc);
230 if (drive->media == ide_tape)
231 set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
232 ide_queue_pc_head(drive, disk, pc, rq);
233}
234EXPORT_SYMBOL_GPL(ide_retry_pc);
235
236int ide_scsi_expiry(ide_drive_t *drive)
237{
238 struct ide_atapi_pc *pc = drive->pc;
239
240 debug_log("%s called for %lu at %lu\n", __func__,
241 pc->scsi_cmd->serial_number, jiffies);
242
243 pc->flags |= PC_FLAG_TIMEDOUT;
244
245 return 0; /* we do not want the IDE subsystem to retry */
246}
247EXPORT_SYMBOL_GPL(ide_scsi_expiry);
248
249/*
250 * This is the usual interrupt handler which will be called during a packet
251 * command. We will transfer some of the data (as requested by the drive)
252 * and will re-point interrupt handler to us.
253 */
254static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
255{
256 struct ide_atapi_pc *pc = drive->pc;
213 ide_hwif_t *hwif = drive->hwif; 257 ide_hwif_t *hwif = drive->hwif;
214 struct request *rq = hwif->hwgroup->rq; 258 struct request *rq = hwif->hwgroup->rq;
215 const struct ide_tp_ops *tp_ops = hwif->tp_ops; 259 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
216 xfer_func_t *xferfunc; 260 xfer_func_t *xferfunc;
217 unsigned int temp; 261 ide_expiry_t *expiry;
262 unsigned int timeout, temp;
218 u16 bcount; 263 u16 bcount;
219 u8 stat, ireason, scsi = drive->scsi; 264 u8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0;
220 265
221 debug_log("Enter %s - interrupt handler\n", __func__); 266 debug_log("Enter %s - interrupt handler\n", __func__);
222 267
268 if (scsi) {
269 timeout = ide_scsi_get_timeout(pc);
270 expiry = ide_scsi_expiry;
271 } else {
272 timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
273 : WAIT_TAPE_CMD;
274 expiry = NULL;
275 }
276
223 if (pc->flags & PC_FLAG_TIMEDOUT) { 277 if (pc->flags & PC_FLAG_TIMEDOUT) {
224 drive->pc_callback(drive); 278 drive->pc_callback(drive, 0);
225 return ide_stopped; 279 return ide_stopped;
226 } 280 }
227 281
@@ -238,8 +292,8 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
238 pc->flags |= PC_FLAG_DMA_ERROR; 292 pc->flags |= PC_FLAG_DMA_ERROR;
239 } else { 293 } else {
240 pc->xferred = pc->req_xfer; 294 pc->xferred = pc->req_xfer;
241 if (update_buffers) 295 if (drive->pc_update_buffers)
242 update_buffers(drive, pc); 296 drive->pc_update_buffers(drive, pc);
243 } 297 }
244 debug_log("%s: DMA finished\n", drive->name); 298 debug_log("%s: DMA finished\n", drive->name);
245 } 299 }
@@ -276,21 +330,19 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
276 debug_log("[cmd %x]: check condition\n", rq->cmd[0]); 330 debug_log("[cmd %x]: check condition\n", rq->cmd[0]);
277 331
278 /* Retry operation */ 332 /* Retry operation */
279 retry_pc(drive); 333 ide_retry_pc(drive, rq->rq_disk);
280 334
281 /* queued, but not started */ 335 /* queued, but not started */
282 return ide_stopped; 336 return ide_stopped;
283 } 337 }
284cmd_finished: 338cmd_finished:
285 pc->error = 0; 339 pc->error = 0;
286 if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && 340
287 (stat & ATA_DSC) == 0) { 341 if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
288 dsc_handle(drive); 342 dsc = 1;
289 return ide_stopped;
290 }
291 343
292 /* Command finished - Call the callback function */ 344 /* Command finished - Call the callback function */
293 drive->pc_callback(drive); 345 drive->pc_callback(drive, dsc);
294 346
295 return ide_stopped; 347 return ide_stopped;
296 } 348 }
@@ -336,7 +388,8 @@ cmd_finished:
336 temp = 0; 388 temp = 0;
337 if (temp) { 389 if (temp) {
338 if (pc->sg) 390 if (pc->sg)
339 io_buffers(drive, pc, temp, 0); 391 drive->pc_io_buffers(drive, pc,
392 temp, 0);
340 else 393 else
341 tp_ops->input_data(drive, NULL, 394 tp_ops->input_data(drive, NULL,
342 pc->cur_pos, temp); 395 pc->cur_pos, temp);
@@ -348,9 +401,7 @@ cmd_finished:
348 pc->xferred += temp; 401 pc->xferred += temp;
349 pc->cur_pos += temp; 402 pc->cur_pos += temp;
350 ide_pad_transfer(drive, 0, bcount - temp); 403 ide_pad_transfer(drive, 0, bcount - temp);
351 ide_set_handler(drive, handler, timeout, 404 goto next_irq;
352 expiry);
353 return ide_started;
354 } 405 }
355 debug_log("The device wants to send us more data than " 406 debug_log("The device wants to send us more data than "
356 "expected - allowing transfer\n"); 407 "expected - allowing transfer\n");
@@ -362,7 +413,7 @@ cmd_finished:
362 if ((drive->media == ide_floppy && !scsi && !pc->buf) || 413 if ((drive->media == ide_floppy && !scsi && !pc->buf) ||
363 (drive->media == ide_tape && !scsi && pc->bh) || 414 (drive->media == ide_tape && !scsi && pc->bh) ||
364 (scsi && pc->sg)) { 415 (scsi && pc->sg)) {
365 int done = io_buffers(drive, pc, bcount, 416 int done = drive->pc_io_buffers(drive, pc, bcount,
366 !!(pc->flags & PC_FLAG_WRITING)); 417 !!(pc->flags & PC_FLAG_WRITING));
367 418
368 /* FIXME: don't do partial completions */ 419 /* FIXME: don't do partial completions */
@@ -377,12 +428,11 @@ cmd_finished:
377 428
378 debug_log("[cmd %x] transferred %d bytes on that intr.\n", 429 debug_log("[cmd %x] transferred %d bytes on that intr.\n",
379 rq->cmd[0], bcount); 430 rq->cmd[0], bcount);
380 431next_irq:
381 /* And set the interrupt handler again */ 432 /* And set the interrupt handler again */
382 ide_set_handler(drive, handler, timeout, expiry); 433 ide_set_handler(drive, ide_pc_intr, timeout, expiry);
383 return ide_started; 434 return ide_started;
384} 435}
385EXPORT_SYMBOL_GPL(ide_pc_intr);
386 436
387static u8 ide_read_ireason(ide_drive_t *drive) 437static u8 ide_read_ireason(ide_drive_t *drive)
388{ 438{
@@ -418,12 +468,22 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
418 return ireason; 468 return ireason;
419} 469}
420 470
421ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, 471static int ide_delayed_transfer_pc(ide_drive_t *drive)
422 ide_handler_t *handler, unsigned int timeout,
423 ide_expiry_t *expiry)
424{ 472{
473 /* Send the actual packet */
474 drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12);
475
476 /* Timeout for the packet command */
477 return WAIT_FLOPPY_CMD;
478}
479
480static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
481{
482 struct ide_atapi_pc *pc = drive->pc;
425 ide_hwif_t *hwif = drive->hwif; 483 ide_hwif_t *hwif = drive->hwif;
426 struct request *rq = hwif->hwgroup->rq; 484 struct request *rq = hwif->hwgroup->rq;
485 ide_expiry_t *expiry;
486 unsigned int timeout;
427 ide_startstop_t startstop; 487 ide_startstop_t startstop;
428 u8 ireason; 488 u8 ireason;
429 489
@@ -434,7 +494,8 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
434 } 494 }
435 495
436 ireason = ide_read_ireason(drive); 496 ireason = ide_read_ireason(drive);
437 if (drive->media == ide_tape && !drive->scsi) 497 if (drive->media == ide_tape &&
498 (drive->dev_flags & IDE_DFLAG_SCSI) == 0)
438 ireason = ide_wait_ireason(drive, ireason); 499 ireason = ide_wait_ireason(drive, ireason);
439 500
440 if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { 501 if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {
@@ -443,8 +504,27 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
443 return ide_do_reset(drive); 504 return ide_do_reset(drive);
444 } 505 }
445 506
507 /*
508 * If necessary schedule the packet transfer to occur 'timeout'
509 * miliseconds later in ide_delayed_transfer_pc() after the device
510 * says it's ready for a packet.
511 */
512 if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
513 timeout = drive->pc_delay;
514 expiry = &ide_delayed_transfer_pc;
515 } else {
516 if (drive->dev_flags & IDE_DFLAG_SCSI) {
517 timeout = ide_scsi_get_timeout(pc);
518 expiry = ide_scsi_expiry;
519 } else {
520 timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
521 : WAIT_TAPE_CMD;
522 expiry = NULL;
523 }
524 }
525
446 /* Set the interrupt routine */ 526 /* Set the interrupt routine */
447 ide_set_handler(drive, handler, timeout, expiry); 527 ide_set_handler(drive, ide_pc_intr, timeout, expiry);
448 528
449 /* Begin DMA, if necessary */ 529 /* Begin DMA, if necessary */
450 if (pc->flags & PC_FLAG_DMA_OK) { 530 if (pc->flags & PC_FLAG_DMA_OK) {
@@ -458,22 +538,22 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
458 538
459 return ide_started; 539 return ide_started;
460} 540}
461EXPORT_SYMBOL_GPL(ide_transfer_pc);
462 541
463ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, 542ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,
464 ide_handler_t *handler, unsigned int timeout,
465 ide_expiry_t *expiry) 543 ide_expiry_t *expiry)
466{ 544{
545 struct ide_atapi_pc *pc = drive->pc;
467 ide_hwif_t *hwif = drive->hwif; 546 ide_hwif_t *hwif = drive->hwif;
547 u32 tf_flags;
468 u16 bcount; 548 u16 bcount;
469 u8 dma = 0; 549 u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI);
470 550
471 /* We haven't transferred any data yet */ 551 /* We haven't transferred any data yet */
472 pc->xferred = 0; 552 pc->xferred = 0;
473 pc->cur_pos = pc->buf; 553 pc->cur_pos = pc->buf;
474 554
475 /* Request to transfer the entire buffer at once */ 555 /* Request to transfer the entire buffer at once */
476 if (drive->media == ide_tape && !drive->scsi) 556 if (drive->media == ide_tape && scsi == 0)
477 bcount = pc->req_xfer; 557 bcount = pc->req_xfer;
478 else 558 else
479 bcount = min(pc->req_xfer, 63 * 1024); 559 bcount = min(pc->req_xfer, 63 * 1024);
@@ -483,28 +563,35 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
483 ide_dma_off(drive); 563 ide_dma_off(drive);
484 } 564 }
485 565
486 if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) { 566 if ((pc->flags & PC_FLAG_DMA_OK) &&
487 if (drive->scsi) 567 (drive->dev_flags & IDE_DFLAG_USING_DMA)) {
568 if (scsi)
488 hwif->sg_mapped = 1; 569 hwif->sg_mapped = 1;
489 dma = !hwif->dma_ops->dma_setup(drive); 570 drive->dma = !hwif->dma_ops->dma_setup(drive);
490 if (drive->scsi) 571 if (scsi)
491 hwif->sg_mapped = 0; 572 hwif->sg_mapped = 0;
492 } 573 }
493 574
494 if (!dma) 575 if (!drive->dma)
495 pc->flags &= ~PC_FLAG_DMA_OK; 576 pc->flags &= ~PC_FLAG_DMA_OK;
496 577
497 ide_pktcmd_tf_load(drive, drive->scsi ? 0 : IDE_TFLAG_OUT_DEVICE, 578 if (scsi)
498 bcount, dma); 579 tf_flags = 0;
580 else if (drive->media == ide_cdrom || drive->media == ide_optical)
581 tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
582 else
583 tf_flags = IDE_TFLAG_OUT_DEVICE;
584
585 ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);
499 586
500 /* Issue the packet command */ 587 /* Issue the packet command */
501 if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { 588 if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
502 ide_execute_command(drive, ATA_CMD_PACKET, handler, 589 ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
503 timeout, NULL); 590 timeout, NULL);
504 return ide_started; 591 return ide_started;
505 } else { 592 } else {
506 ide_execute_pkt_cmd(drive); 593 ide_execute_pkt_cmd(drive);
507 return (*handler)(drive); 594 return ide_transfer_pc(drive);
508 } 595 }
509} 596}
510EXPORT_SYMBOL_GPL(ide_issue_pc); 597EXPORT_SYMBOL_GPL(ide_issue_pc);