diff options
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 98 |
1 files changed, 4 insertions, 94 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index cad057d25a29..6f8f544392a8 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -354,7 +354,6 @@ void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | |||
354 | 354 | ||
355 | void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | 355 | void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) |
356 | { | 356 | { |
357 | ide_hwif_t *hwif = HWIF(drive); | ||
358 | unsigned long flags; | 357 | unsigned long flags; |
359 | struct request *rq; | 358 | struct request *rq; |
360 | 359 | ||
@@ -362,19 +361,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
362 | rq = HWGROUP(drive)->rq; | 361 | rq = HWGROUP(drive)->rq; |
363 | spin_unlock_irqrestore(&ide_lock, flags); | 362 | spin_unlock_irqrestore(&ide_lock, flags); |
364 | 363 | ||
365 | if (rq->cmd_type == REQ_TYPE_ATA_CMD) { | 364 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
366 | u8 *args = (u8 *) rq->buffer; | ||
367 | if (rq->errors == 0) | ||
368 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | ||
369 | |||
370 | if (args) { | ||
371 | args[0] = stat; | ||
372 | args[1] = err; | ||
373 | /* be sure we're looking at the low order bits */ | ||
374 | hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG); | ||
375 | args[2] = hwif->INB(IDE_NSECTOR_REG); | ||
376 | } | ||
377 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | ||
378 | ide_task_t *args = (ide_task_t *) rq->special; | 365 | ide_task_t *args = (ide_task_t *) rq->special; |
379 | if (rq->errors == 0) | 366 | if (rq->errors == 0) |
380 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | 367 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); |
@@ -624,48 +611,6 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) | |||
624 | return __ide_abort(drive, rq); | 611 | return __ide_abort(drive, rq); |
625 | } | 612 | } |
626 | 613 | ||
627 | /** | ||
628 | * drive_cmd_intr - drive command completion interrupt | ||
629 | * @drive: drive the completion interrupt occurred on | ||
630 | * | ||
631 | * drive_cmd_intr() is invoked on completion of a special DRIVE_CMD. | ||
632 | * We do any necessary data reading and then wait for the drive to | ||
633 | * go non busy. At that point we may read the error data and complete | ||
634 | * the request | ||
635 | */ | ||
636 | |||
637 | static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) | ||
638 | { | ||
639 | struct request *rq = HWGROUP(drive)->rq; | ||
640 | ide_hwif_t *hwif = HWIF(drive); | ||
641 | u8 *args = (u8 *)rq->buffer, pio_in = (args && args[3]) ? 1 : 0, stat; | ||
642 | |||
643 | if (pio_in) { | ||
644 | u8 io_32bit = drive->io_32bit; | ||
645 | stat = hwif->INB(IDE_STATUS_REG); | ||
646 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { | ||
647 | if (stat & (ERR_STAT | DRQ_STAT)) | ||
648 | return ide_error(drive, __FUNCTION__, stat); | ||
649 | ide_set_handler(drive, &drive_cmd_intr, WAIT_WORSTCASE, | ||
650 | NULL); | ||
651 | return ide_started; | ||
652 | } | ||
653 | drive->io_32bit = 0; | ||
654 | hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS); | ||
655 | drive->io_32bit = io_32bit; | ||
656 | stat = wait_drive_not_busy(drive); | ||
657 | } else { | ||
658 | local_irq_enable_in_hardirq(); | ||
659 | stat = hwif->INB(IDE_STATUS_REG); | ||
660 | } | ||
661 | |||
662 | if (!OK_STAT(stat, (pio_in ? 0 : READY_STAT), BAD_STAT)) | ||
663 | return ide_error(drive, __FUNCTION__, stat); | ||
664 | /* calls ide_end_drive_cmd */ | ||
665 | ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG)); | ||
666 | return ide_stopped; | ||
667 | } | ||
668 | |||
669 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 614 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
670 | { | 615 | { |
671 | tf->nsect = drive->sect; | 616 | tf->nsect = drive->sect; |
@@ -851,16 +796,9 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
851 | struct request *rq) | 796 | struct request *rq) |
852 | { | 797 | { |
853 | ide_hwif_t *hwif = HWIF(drive); | 798 | ide_hwif_t *hwif = HWIF(drive); |
854 | u8 *args = rq->buffer; | 799 | ide_task_t *task = rq->special; |
855 | ide_task_t ltask; | ||
856 | struct ide_taskfile *tf = <ask.tf; | ||
857 | |||
858 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | ||
859 | ide_task_t *task = rq->special; | ||
860 | |||
861 | if (task == NULL) | ||
862 | goto done; | ||
863 | 800 | ||
801 | if (task) { | ||
864 | hwif->data_phase = task->data_phase; | 802 | hwif->data_phase = task->data_phase; |
865 | 803 | ||
866 | switch (hwif->data_phase) { | 804 | switch (hwif->data_phase) { |
@@ -877,33 +815,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
877 | return do_rw_taskfile(drive, task); | 815 | return do_rw_taskfile(drive, task); |
878 | } | 816 | } |
879 | 817 | ||
880 | if (args == NULL) | ||
881 | goto done; | ||
882 | |||
883 | memset(<ask, 0, sizeof(ltask)); | ||
884 | if (rq->cmd_type == REQ_TYPE_ATA_CMD) { | ||
885 | #ifdef DEBUG | ||
886 | printk("%s: DRIVE_CMD\n", drive->name); | ||
887 | #endif | ||
888 | tf->feature = args[2]; | ||
889 | if (args[0] == WIN_SMART) { | ||
890 | tf->nsect = args[3]; | ||
891 | tf->lbal = args[1]; | ||
892 | tf->lbam = 0x4f; | ||
893 | tf->lbah = 0xc2; | ||
894 | ltask.tf_flags = IDE_TFLAG_OUT_TF; | ||
895 | } else { | ||
896 | tf->nsect = args[1]; | ||
897 | ltask.tf_flags = IDE_TFLAG_OUT_FEATURE | | ||
898 | IDE_TFLAG_OUT_NSECT; | ||
899 | } | ||
900 | } | ||
901 | tf->command = args[0]; | ||
902 | ide_tf_load(drive, <ask); | ||
903 | ide_execute_command(drive, args[0], &drive_cmd_intr, WAIT_WORSTCASE, NULL); | ||
904 | return ide_started; | ||
905 | |||
906 | done: | ||
907 | /* | 818 | /* |
908 | * NULL is actually a valid way of waiting for | 819 | * NULL is actually a valid way of waiting for |
909 | * all current requests to be flushed from the queue. | 820 | * all current requests to be flushed from the queue. |
@@ -1007,8 +918,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
1007 | if (drive->current_speed == 0xff) | 918 | if (drive->current_speed == 0xff) |
1008 | ide_config_drive_speed(drive, drive->desired_speed); | 919 | ide_config_drive_speed(drive, drive->desired_speed); |
1009 | 920 | ||
1010 | if (rq->cmd_type == REQ_TYPE_ATA_CMD || | 921 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) |
1011 | rq->cmd_type == REQ_TYPE_ATA_TASKFILE) | ||
1012 | return execute_drive_cmd(drive, rq); | 922 | return execute_drive_cmd(drive, rq); |
1013 | else if (blk_pm_request(rq)) { | 923 | else if (blk_pm_request(rq)) { |
1014 | struct request_pm_state *pm = rq->data; | 924 | struct request_pm_state *pm = rq->data; |