aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r--drivers/ide/ide-io.c116
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
233out_do_tf: 233out_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
355void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) 355void 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
639static 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
665static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) 614static 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 = &ltask.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(&ltask, 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, &ltask);
899 ide_execute_command(drive, args[0], &drive_cmd_intr, WAIT_WORSTCASE, NULL);
900 return ide_started;
901
902done:
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)
1679void ide_init_drive_cmd (struct request *rq) 1590void 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