diff options
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 116 |
1 files changed, 13 insertions, 103 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2711b5a6962d..6f8f544392a8 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -75,7 +75,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
75 | */ | 75 | */ |
76 | if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { | 76 | if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) { |
77 | drive->state = 0; | 77 | drive->state = 0; |
78 | HWGROUP(drive)->hwif->ide_dma_on(drive); | 78 | ide_dma_on(drive); |
79 | } | 79 | } |
80 | 80 | ||
81 | if (!end_that_request_chunk(rq, uptodate, nr_bytes)) { | 81 | if (!end_that_request_chunk(rq, uptodate, nr_bytes)) { |
@@ -219,7 +219,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
219 | * we could be smarter and check for current xfer_speed | 219 | * we could be smarter and check for current xfer_speed |
220 | * in struct drive etc... | 220 | * in struct drive etc... |
221 | */ | 221 | */ |
222 | if (drive->hwif->ide_dma_on == NULL) | 222 | if (drive->hwif->dma_host_set == NULL) |
223 | break; | 223 | break; |
224 | /* | 224 | /* |
225 | * TODO: respect ->using_dma setting | 225 | * TODO: respect ->using_dma setting |
@@ -231,7 +231,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
231 | return ide_stopped; | 231 | return ide_stopped; |
232 | 232 | ||
233 | out_do_tf: | 233 | out_do_tf: |
234 | args->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | 234 | args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
235 | args->data_phase = TASKFILE_NO_DATA; | 235 | args->data_phase = TASKFILE_NO_DATA; |
236 | return do_rw_taskfile(drive, args); | 236 | return do_rw_taskfile(drive, args); |
237 | } | 237 | } |
@@ -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,17 +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 | args[2] = hwif->INB(IDE_NSECTOR_REG); | ||
374 | } | ||
375 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | ||
376 | ide_task_t *args = (ide_task_t *) rq->special; | 365 | ide_task_t *args = (ide_task_t *) rq->special; |
377 | if (rq->errors == 0) | 366 | if (rq->errors == 0) |
378 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | 367 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); |
@@ -383,10 +372,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
383 | tf->error = err; | 372 | tf->error = err; |
384 | tf->status = stat; | 373 | tf->status = stat; |
385 | 374 | ||
386 | args->tf_flags |= (IDE_TFLAG_IN_TF|IDE_TFLAG_IN_DEVICE); | ||
387 | if (args->tf_flags & IDE_TFLAG_LBA48) | ||
388 | args->tf_flags |= IDE_TFLAG_IN_HOB; | ||
389 | |||
390 | ide_tf_read(drive, args); | 375 | ide_tf_read(drive, args); |
391 | } | 376 | } |
392 | } else if (blk_pm_request(rq)) { | 377 | } else if (blk_pm_request(rq)) { |
@@ -626,42 +611,6 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) | |||
626 | return __ide_abort(drive, rq); | 611 | return __ide_abort(drive, rq); |
627 | } | 612 | } |
628 | 613 | ||
629 | /** | ||
630 | * drive_cmd_intr - drive command completion interrupt | ||
631 | * @drive: drive the completion interrupt occurred on | ||
632 | * | ||
633 | * drive_cmd_intr() is invoked on completion of a special DRIVE_CMD. | ||
634 | * We do any necessary data reading and then wait for the drive to | ||
635 | * go non busy. At that point we may read the error data and complete | ||
636 | * the request | ||
637 | */ | ||
638 | |||
639 | static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) | ||
640 | { | ||
641 | struct request *rq = HWGROUP(drive)->rq; | ||
642 | ide_hwif_t *hwif = HWIF(drive); | ||
643 | u8 *args = (u8 *) rq->buffer; | ||
644 | u8 stat = hwif->INB(IDE_STATUS_REG); | ||
645 | int retries = 10; | ||
646 | |||
647 | local_irq_enable_in_hardirq(); | ||
648 | if (rq->cmd_type == REQ_TYPE_ATA_CMD && | ||
649 | (stat & DRQ_STAT) && args && args[3]) { | ||
650 | u8 io_32bit = drive->io_32bit; | ||
651 | drive->io_32bit = 0; | ||
652 | hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS); | ||
653 | drive->io_32bit = io_32bit; | ||
654 | while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--) | ||
655 | udelay(100); | ||
656 | } | ||
657 | |||
658 | if (!OK_STAT(stat, READY_STAT, BAD_STAT)) | ||
659 | return ide_error(drive, "drive_cmd", stat); | ||
660 | /* calls ide_end_drive_cmd */ | ||
661 | ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG)); | ||
662 | return ide_stopped; | ||
663 | } | ||
664 | |||
665 | 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) |
666 | { | 615 | { |
667 | tf->nsect = drive->sect; | 616 | tf->nsect = drive->sect; |
@@ -710,7 +659,7 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) | |||
710 | return ide_stopped; | 659 | return ide_stopped; |
711 | } | 660 | } |
712 | 661 | ||
713 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | | 662 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE | |
714 | IDE_TFLAG_CUSTOM_HANDLER; | 663 | IDE_TFLAG_CUSTOM_HANDLER; |
715 | 664 | ||
716 | do_rw_taskfile(drive, &args); | 665 | do_rw_taskfile(drive, &args); |
@@ -787,7 +736,7 @@ static ide_startstop_t do_special (ide_drive_t *drive) | |||
787 | 736 | ||
788 | if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { | 737 | if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { |
789 | if (keep_dma) | 738 | if (keep_dma) |
790 | hwif->ide_dma_on(drive); | 739 | ide_dma_on(drive); |
791 | } | 740 | } |
792 | } | 741 | } |
793 | 742 | ||
@@ -847,16 +796,9 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
847 | struct request *rq) | 796 | struct request *rq) |
848 | { | 797 | { |
849 | ide_hwif_t *hwif = HWIF(drive); | 798 | ide_hwif_t *hwif = HWIF(drive); |
850 | u8 *args = rq->buffer; | 799 | ide_task_t *task = rq->special; |
851 | ide_task_t ltask; | ||
852 | struct ide_taskfile *tf = <ask.tf; | ||
853 | |||
854 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | ||
855 | ide_task_t *task = rq->special; | ||
856 | |||
857 | if (task == NULL) | ||
858 | goto done; | ||
859 | 800 | ||
801 | if (task) { | ||
860 | hwif->data_phase = task->data_phase; | 802 | hwif->data_phase = task->data_phase; |
861 | 803 | ||
862 | switch (hwif->data_phase) { | 804 | switch (hwif->data_phase) { |
@@ -873,33 +815,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
873 | return do_rw_taskfile(drive, task); | 815 | return do_rw_taskfile(drive, task); |
874 | } | 816 | } |
875 | 817 | ||
876 | if (args == NULL) | ||
877 | goto done; | ||
878 | |||
879 | memset(<ask, 0, sizeof(ltask)); | ||
880 | if (rq->cmd_type == REQ_TYPE_ATA_CMD) { | ||
881 | #ifdef DEBUG | ||
882 | printk("%s: DRIVE_CMD\n", drive->name); | ||
883 | #endif | ||
884 | tf->feature = args[2]; | ||
885 | if (args[0] == WIN_SMART) { | ||
886 | tf->nsect = args[3]; | ||
887 | tf->lbal = args[1]; | ||
888 | tf->lbam = 0x4f; | ||
889 | tf->lbah = 0xc2; | ||
890 | ltask.tf_flags = IDE_TFLAG_OUT_TF; | ||
891 | } else { | ||
892 | tf->nsect = args[1]; | ||
893 | ltask.tf_flags = IDE_TFLAG_OUT_FEATURE | | ||
894 | IDE_TFLAG_OUT_NSECT; | ||
895 | } | ||
896 | } | ||
897 | tf->command = args[0]; | ||
898 | ide_tf_load(drive, <ask); | ||
899 | ide_execute_command(drive, args[0], &drive_cmd_intr, WAIT_WORSTCASE, NULL); | ||
900 | return ide_started; | ||
901 | |||
902 | done: | ||
903 | /* | 818 | /* |
904 | * NULL is actually a valid way of waiting for | 819 | * NULL is actually a valid way of waiting for |
905 | * all current requests to be flushed from the queue. | 820 | * all current requests to be flushed from the queue. |
@@ -939,8 +854,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) | |||
939 | if (rc) | 854 | if (rc) |
940 | printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); | 855 | printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); |
941 | SELECT_DRIVE(drive); | 856 | SELECT_DRIVE(drive); |
942 | if (IDE_CONTROL_REG) | 857 | ide_set_irq(drive, 1); |
943 | HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); | ||
944 | rc = ide_wait_not_busy(HWIF(drive), 100000); | 858 | rc = ide_wait_not_busy(HWIF(drive), 100000); |
945 | if (rc) | 859 | if (rc) |
946 | printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); | 860 | printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); |
@@ -1004,8 +918,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
1004 | if (drive->current_speed == 0xff) | 918 | if (drive->current_speed == 0xff) |
1005 | ide_config_drive_speed(drive, drive->desired_speed); | 919 | ide_config_drive_speed(drive, drive->desired_speed); |
1006 | 920 | ||
1007 | if (rq->cmd_type == REQ_TYPE_ATA_CMD || | 921 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) |
1008 | rq->cmd_type == REQ_TYPE_ATA_TASKFILE) | ||
1009 | return execute_drive_cmd(drive, rq); | 922 | return execute_drive_cmd(drive, rq); |
1010 | else if (blk_pm_request(rq)) { | 923 | else if (blk_pm_request(rq)) { |
1011 | struct request_pm_state *pm = rq->data; | 924 | struct request_pm_state *pm = rq->data; |
@@ -1213,15 +1126,13 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
1213 | } | 1126 | } |
1214 | again: | 1127 | again: |
1215 | hwif = HWIF(drive); | 1128 | hwif = HWIF(drive); |
1216 | if (hwgroup->hwif->sharing_irq && | 1129 | if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif) { |
1217 | hwif != hwgroup->hwif && | ||
1218 | hwif->io_ports[IDE_CONTROL_OFFSET]) { | ||
1219 | /* | 1130 | /* |
1220 | * set nIEN for previous hwif, drives in the | 1131 | * set nIEN for previous hwif, drives in the |
1221 | * quirk_list may not like intr setups/cleanups | 1132 | * quirk_list may not like intr setups/cleanups |
1222 | */ | 1133 | */ |
1223 | if (drive->quirk_list != 1) | 1134 | if (drive->quirk_list != 1) |
1224 | hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); | 1135 | ide_set_irq(drive, 0); |
1225 | } | 1136 | } |
1226 | hwgroup->hwif = hwif; | 1137 | hwgroup->hwif = hwif; |
1227 | hwgroup->drive = drive; | 1138 | hwgroup->drive = drive; |
@@ -1334,7 +1245,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
1334 | */ | 1245 | */ |
1335 | drive->retry_pio++; | 1246 | drive->retry_pio++; |
1336 | drive->state = DMA_PIO_RETRY; | 1247 | drive->state = DMA_PIO_RETRY; |
1337 | hwif->dma_off_quietly(drive); | 1248 | ide_dma_off_quietly(drive); |
1338 | 1249 | ||
1339 | /* | 1250 | /* |
1340 | * un-busy drive etc (hwgroup->busy is cleared on return) and | 1251 | * un-busy drive etc (hwgroup->busy is cleared on return) and |
@@ -1679,7 +1590,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1679 | void ide_init_drive_cmd (struct request *rq) | 1590 | void ide_init_drive_cmd (struct request *rq) |
1680 | { | 1591 | { |
1681 | memset(rq, 0, sizeof(*rq)); | 1592 | memset(rq, 0, sizeof(*rq)); |
1682 | rq->cmd_type = REQ_TYPE_ATA_CMD; | ||
1683 | rq->ref_count = 1; | 1593 | rq->ref_count = 1; |
1684 | } | 1594 | } |
1685 | 1595 | ||