diff options
Diffstat (limited to 'drivers/ide/ide-atapi.c')
-rw-r--r-- | drivers/ide/ide-atapi.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index b558663418d8..2521677e1f48 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
@@ -468,12 +468,22 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) | |||
468 | return ireason; | 468 | return ireason; |
469 | } | 469 | } |
470 | 470 | ||
471 | ide_startstop_t ide_transfer_pc(ide_drive_t *drive, unsigned int timeout, | 471 | static int ide_delayed_transfer_pc(ide_drive_t *drive) |
472 | ide_expiry_t *expiry) | 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 | |||
480 | static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) | ||
473 | { | 481 | { |
474 | struct ide_atapi_pc *pc = drive->pc; | 482 | struct ide_atapi_pc *pc = drive->pc; |
475 | ide_hwif_t *hwif = drive->hwif; | 483 | ide_hwif_t *hwif = drive->hwif; |
476 | struct request *rq = hwif->hwgroup->rq; | 484 | struct request *rq = hwif->hwgroup->rq; |
485 | ide_expiry_t *expiry; | ||
486 | unsigned int timeout; | ||
477 | ide_startstop_t startstop; | 487 | ide_startstop_t startstop; |
478 | u8 ireason; | 488 | u8 ireason; |
479 | 489 | ||
@@ -493,6 +503,25 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, unsigned int timeout, | |||
493 | return ide_do_reset(drive); | 503 | return ide_do_reset(drive); |
494 | } | 504 | } |
495 | 505 | ||
506 | /* | ||
507 | * If necessary schedule the packet transfer to occur 'timeout' | ||
508 | * miliseconds later in ide_delayed_transfer_pc() after the device | ||
509 | * says it's ready for a packet. | ||
510 | */ | ||
511 | if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { | ||
512 | timeout = drive->pc_delay; | ||
513 | expiry = &ide_delayed_transfer_pc; | ||
514 | } else { | ||
515 | if (drive->scsi) { | ||
516 | timeout = ide_scsi_get_timeout(pc); | ||
517 | expiry = ide_scsi_expiry; | ||
518 | } else { | ||
519 | timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD | ||
520 | : WAIT_TAPE_CMD; | ||
521 | expiry = NULL; | ||
522 | } | ||
523 | } | ||
524 | |||
496 | /* Set the interrupt routine */ | 525 | /* Set the interrupt routine */ |
497 | ide_set_handler(drive, ide_pc_intr, timeout, expiry); | 526 | ide_set_handler(drive, ide_pc_intr, timeout, expiry); |
498 | 527 | ||
@@ -508,10 +537,8 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, unsigned int timeout, | |||
508 | 537 | ||
509 | return ide_started; | 538 | return ide_started; |
510 | } | 539 | } |
511 | EXPORT_SYMBOL_GPL(ide_transfer_pc); | ||
512 | 540 | ||
513 | ide_startstop_t ide_issue_pc(ide_drive_t *drive, | 541 | ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, |
514 | ide_handler_t *handler, unsigned int timeout, | ||
515 | ide_expiry_t *expiry) | 542 | ide_expiry_t *expiry) |
516 | { | 543 | { |
517 | struct ide_atapi_pc *pc = drive->pc; | 544 | struct ide_atapi_pc *pc = drive->pc; |
@@ -550,12 +577,12 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, | |||
550 | 577 | ||
551 | /* Issue the packet command */ | 578 | /* Issue the packet command */ |
552 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { | 579 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { |
553 | ide_execute_command(drive, ATA_CMD_PACKET, handler, | 580 | ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, |
554 | timeout, NULL); | 581 | timeout, NULL); |
555 | return ide_started; | 582 | return ide_started; |
556 | } else { | 583 | } else { |
557 | ide_execute_pkt_cmd(drive); | 584 | ide_execute_pkt_cmd(drive); |
558 | return (*handler)(drive); | 585 | return ide_transfer_pc(drive); |
559 | } | 586 | } |
560 | } | 587 | } |
561 | EXPORT_SYMBOL_GPL(ide_issue_pc); | 588 | EXPORT_SYMBOL_GPL(ide_issue_pc); |