diff options
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 72 |
1 files changed, 22 insertions, 50 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 28057747c1f8..661b75a89d4d 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -504,55 +504,6 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat) | |||
504 | 504 | ||
505 | EXPORT_SYMBOL_GPL(ide_error); | 505 | EXPORT_SYMBOL_GPL(ide_error); |
506 | 506 | ||
507 | ide_startstop_t __ide_abort(ide_drive_t *drive, struct request *rq) | ||
508 | { | ||
509 | if (drive->media != ide_disk) | ||
510 | rq->errors |= ERROR_RESET; | ||
511 | |||
512 | ide_kill_rq(drive, rq); | ||
513 | |||
514 | return ide_stopped; | ||
515 | } | ||
516 | |||
517 | EXPORT_SYMBOL_GPL(__ide_abort); | ||
518 | |||
519 | /** | ||
520 | * ide_abort - abort pending IDE operations | ||
521 | * @drive: drive the error occurred on | ||
522 | * @msg: message to report | ||
523 | * | ||
524 | * ide_abort kills and cleans up when we are about to do a | ||
525 | * host initiated reset on active commands. Longer term we | ||
526 | * want handlers to have sensible abort handling themselves | ||
527 | * | ||
528 | * This differs fundamentally from ide_error because in | ||
529 | * this case the command is doing just fine when we | ||
530 | * blow it away. | ||
531 | */ | ||
532 | |||
533 | ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) | ||
534 | { | ||
535 | struct request *rq; | ||
536 | |||
537 | if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) | ||
538 | return ide_stopped; | ||
539 | |||
540 | /* retry only "normal" I/O: */ | ||
541 | if (!blk_fs_request(rq)) { | ||
542 | rq->errors = 1; | ||
543 | ide_end_drive_cmd(drive, BUSY_STAT, 0); | ||
544 | return ide_stopped; | ||
545 | } | ||
546 | |||
547 | if (rq->rq_disk) { | ||
548 | ide_driver_t *drv; | ||
549 | |||
550 | drv = *(ide_driver_t **)rq->rq_disk->private_data; | ||
551 | return drv->abort(drive, rq); | ||
552 | } else | ||
553 | return __ide_abort(drive, rq); | ||
554 | } | ||
555 | |||
556 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 507 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
557 | { | 508 | { |
558 | tf->nsect = drive->sect; | 509 | tf->nsect = drive->sect; |
@@ -766,6 +717,18 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
766 | return ide_stopped; | 717 | return ide_stopped; |
767 | } | 718 | } |
768 | 719 | ||
720 | static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) | ||
721 | { | ||
722 | switch (rq->cmd[0]) { | ||
723 | case REQ_DRIVE_RESET: | ||
724 | return ide_do_reset(drive); | ||
725 | default: | ||
726 | blk_dump_rq_flags(rq, "ide_special_rq - bad request"); | ||
727 | ide_end_request(drive, 0, 0); | ||
728 | return ide_stopped; | ||
729 | } | ||
730 | } | ||
731 | |||
769 | static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) | 732 | static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) |
770 | { | 733 | { |
771 | struct request_pm_state *pm = rq->data; | 734 | struct request_pm_state *pm = rq->data; |
@@ -869,7 +832,16 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
869 | pm->pm_step == ide_pm_state_completed) | 832 | pm->pm_step == ide_pm_state_completed) |
870 | ide_complete_pm_request(drive, rq); | 833 | ide_complete_pm_request(drive, rq); |
871 | return startstop; | 834 | return startstop; |
872 | } | 835 | } else if (!rq->rq_disk && blk_special_request(rq)) |
836 | /* | ||
837 | * TODO: Once all ULDs have been modified to | ||
838 | * check for specific op codes rather than | ||
839 | * blindly accepting any special request, the | ||
840 | * check for ->rq_disk above may be replaced | ||
841 | * by a more suitable mechanism or even | ||
842 | * dropped entirely. | ||
843 | */ | ||
844 | return ide_special_rq(drive, rq); | ||
873 | 845 | ||
874 | drv = *(ide_driver_t **)rq->rq_disk->private_data; | 846 | drv = *(ide_driver_t **)rq->rq_disk->private_data; |
875 | return drv->do_request(drive, rq, block); | 847 | return drv->do_request(drive, rq, block); |