diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 230 |
1 files changed, 156 insertions, 74 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 44aaec256a30..07da5fb9eaff 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -42,18 +42,6 @@ static void ide_outb (u8 val, unsigned long port) | |||
42 | outb(val, port); | 42 | outb(val, port); |
43 | } | 43 | } |
44 | 44 | ||
45 | static void ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port) | ||
46 | { | ||
47 | outb(addr, port); | ||
48 | } | ||
49 | |||
50 | void default_hwif_iops (ide_hwif_t *hwif) | ||
51 | { | ||
52 | hwif->OUTB = ide_outb; | ||
53 | hwif->OUTBSYNC = ide_outbsync; | ||
54 | hwif->INB = ide_inb; | ||
55 | } | ||
56 | |||
57 | /* | 45 | /* |
58 | * MMIO operations, typically used for SATA controllers | 46 | * MMIO operations, typically used for SATA controllers |
59 | */ | 47 | */ |
@@ -68,31 +56,19 @@ static void ide_mm_outb (u8 value, unsigned long port) | |||
68 | writeb(value, (void __iomem *) port); | 56 | writeb(value, (void __iomem *) port); |
69 | } | 57 | } |
70 | 58 | ||
71 | static void ide_mm_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port) | ||
72 | { | ||
73 | writeb(value, (void __iomem *) port); | ||
74 | } | ||
75 | |||
76 | void default_hwif_mmiops (ide_hwif_t *hwif) | ||
77 | { | ||
78 | hwif->OUTB = ide_mm_outb; | ||
79 | /* Most systems will need to override OUTBSYNC, alas however | ||
80 | this one is controller specific! */ | ||
81 | hwif->OUTBSYNC = ide_mm_outbsync; | ||
82 | hwif->INB = ide_mm_inb; | ||
83 | } | ||
84 | |||
85 | EXPORT_SYMBOL(default_hwif_mmiops); | ||
86 | |||
87 | void SELECT_DRIVE (ide_drive_t *drive) | 59 | void SELECT_DRIVE (ide_drive_t *drive) |
88 | { | 60 | { |
89 | ide_hwif_t *hwif = drive->hwif; | 61 | ide_hwif_t *hwif = drive->hwif; |
90 | const struct ide_port_ops *port_ops = hwif->port_ops; | 62 | const struct ide_port_ops *port_ops = hwif->port_ops; |
63 | ide_task_t task; | ||
91 | 64 | ||
92 | if (port_ops && port_ops->selectproc) | 65 | if (port_ops && port_ops->selectproc) |
93 | port_ops->selectproc(drive); | 66 | port_ops->selectproc(drive); |
94 | 67 | ||
95 | hwif->OUTB(drive->select.all, hwif->io_ports.device_addr); | 68 | memset(&task, 0, sizeof(task)); |
69 | task.tf_flags = IDE_TFLAG_OUT_DEVICE; | ||
70 | |||
71 | drive->hwif->tp_ops->tf_load(drive, &task); | ||
96 | } | 72 | } |
97 | 73 | ||
98 | void SELECT_MASK(ide_drive_t *drive, int mask) | 74 | void SELECT_MASK(ide_drive_t *drive, int mask) |
@@ -103,7 +79,61 @@ void SELECT_MASK(ide_drive_t *drive, int mask) | |||
103 | port_ops->maskproc(drive, mask); | 79 | port_ops->maskproc(drive, mask); |
104 | } | 80 | } |
105 | 81 | ||
106 | static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | 82 | void ide_exec_command(ide_hwif_t *hwif, u8 cmd) |
83 | { | ||
84 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
85 | writeb(cmd, (void __iomem *)hwif->io_ports.command_addr); | ||
86 | else | ||
87 | outb(cmd, hwif->io_ports.command_addr); | ||
88 | } | ||
89 | EXPORT_SYMBOL_GPL(ide_exec_command); | ||
90 | |||
91 | u8 ide_read_status(ide_hwif_t *hwif) | ||
92 | { | ||
93 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
94 | return readb((void __iomem *)hwif->io_ports.status_addr); | ||
95 | else | ||
96 | return inb(hwif->io_ports.status_addr); | ||
97 | } | ||
98 | EXPORT_SYMBOL_GPL(ide_read_status); | ||
99 | |||
100 | u8 ide_read_altstatus(ide_hwif_t *hwif) | ||
101 | { | ||
102 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
103 | return readb((void __iomem *)hwif->io_ports.ctl_addr); | ||
104 | else | ||
105 | return inb(hwif->io_ports.ctl_addr); | ||
106 | } | ||
107 | EXPORT_SYMBOL_GPL(ide_read_altstatus); | ||
108 | |||
109 | u8 ide_read_sff_dma_status(ide_hwif_t *hwif) | ||
110 | { | ||
111 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
112 | return readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | ||
113 | else | ||
114 | return inb(hwif->dma_base + ATA_DMA_STATUS); | ||
115 | } | ||
116 | EXPORT_SYMBOL_GPL(ide_read_sff_dma_status); | ||
117 | |||
118 | void ide_set_irq(ide_hwif_t *hwif, int on) | ||
119 | { | ||
120 | u8 ctl = ATA_DEVCTL_OBS; | ||
121 | |||
122 | if (on == 4) { /* hack for SRST */ | ||
123 | ctl |= 4; | ||
124 | on &= ~4; | ||
125 | } | ||
126 | |||
127 | ctl |= on ? 0 : 2; | ||
128 | |||
129 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
130 | writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); | ||
131 | else | ||
132 | outb(ctl, hwif->io_ports.ctl_addr); | ||
133 | } | ||
134 | EXPORT_SYMBOL_GPL(ide_set_irq); | ||
135 | |||
136 | void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | ||
107 | { | 137 | { |
108 | ide_hwif_t *hwif = drive->hwif; | 138 | ide_hwif_t *hwif = drive->hwif; |
109 | struct ide_io_ports *io_ports = &hwif->io_ports; | 139 | struct ide_io_ports *io_ports = &hwif->io_ports; |
@@ -155,8 +185,9 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | |||
155 | tf_outb((tf->device & HIHI) | drive->select.all, | 185 | tf_outb((tf->device & HIHI) | drive->select.all, |
156 | io_ports->device_addr); | 186 | io_ports->device_addr); |
157 | } | 187 | } |
188 | EXPORT_SYMBOL_GPL(ide_tf_load); | ||
158 | 189 | ||
159 | static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | 190 | void ide_tf_read(ide_drive_t *drive, ide_task_t *task) |
160 | { | 191 | { |
161 | ide_hwif_t *hwif = drive->hwif; | 192 | ide_hwif_t *hwif = drive->hwif; |
162 | struct ide_io_ports *io_ports = &hwif->io_ports; | 193 | struct ide_io_ports *io_ports = &hwif->io_ports; |
@@ -188,6 +219,8 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | |||
188 | /* be sure we're looking at the low order bits */ | 219 | /* be sure we're looking at the low order bits */ |
189 | tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); | 220 | tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); |
190 | 221 | ||
222 | if (task->tf_flags & IDE_TFLAG_IN_FEATURE) | ||
223 | tf->feature = tf_inb(io_ports->feature_addr); | ||
191 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) | 224 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) |
192 | tf->nsect = tf_inb(io_ports->nsect_addr); | 225 | tf->nsect = tf_inb(io_ports->nsect_addr); |
193 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) | 226 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) |
@@ -214,6 +247,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | |||
214 | tf->hob_lbah = tf_inb(io_ports->lbah_addr); | 247 | tf->hob_lbah = tf_inb(io_ports->lbah_addr); |
215 | } | 248 | } |
216 | } | 249 | } |
250 | EXPORT_SYMBOL_GPL(ide_tf_read); | ||
217 | 251 | ||
218 | /* | 252 | /* |
219 | * Some localbus EIDE interfaces require a special access sequence | 253 | * Some localbus EIDE interfaces require a special access sequence |
@@ -236,8 +270,8 @@ static void ata_vlb_sync(unsigned long port) | |||
236 | * so if an odd len is specified, be sure that there's at least one | 270 | * so if an odd len is specified, be sure that there's at least one |
237 | * extra byte allocated for the buffer. | 271 | * extra byte allocated for the buffer. |
238 | */ | 272 | */ |
239 | static void ata_input_data(ide_drive_t *drive, struct request *rq, | 273 | void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, |
240 | void *buf, unsigned int len) | 274 | unsigned int len) |
241 | { | 275 | { |
242 | ide_hwif_t *hwif = drive->hwif; | 276 | ide_hwif_t *hwif = drive->hwif; |
243 | struct ide_io_ports *io_ports = &hwif->io_ports; | 277 | struct ide_io_ports *io_ports = &hwif->io_ports; |
@@ -277,12 +311,13 @@ static void ata_input_data(ide_drive_t *drive, struct request *rq, | |||
277 | insw(data_addr, buf, len / 2); | 311 | insw(data_addr, buf, len / 2); |
278 | } | 312 | } |
279 | } | 313 | } |
314 | EXPORT_SYMBOL_GPL(ide_input_data); | ||
280 | 315 | ||
281 | /* | 316 | /* |
282 | * This is used for most PIO data transfers *to* the IDE interface | 317 | * This is used for most PIO data transfers *to* the IDE interface |
283 | */ | 318 | */ |
284 | static void ata_output_data(ide_drive_t *drive, struct request *rq, | 319 | void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf, |
285 | void *buf, unsigned int len) | 320 | unsigned int len) |
286 | { | 321 | { |
287 | ide_hwif_t *hwif = drive->hwif; | 322 | ide_hwif_t *hwif = drive->hwif; |
288 | struct ide_io_ports *io_ports = &hwif->io_ports; | 323 | struct ide_io_ports *io_ports = &hwif->io_ports; |
@@ -320,15 +355,50 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq, | |||
320 | outsw(data_addr, buf, len / 2); | 355 | outsw(data_addr, buf, len / 2); |
321 | } | 356 | } |
322 | } | 357 | } |
358 | EXPORT_SYMBOL_GPL(ide_output_data); | ||
359 | |||
360 | u8 ide_read_error(ide_drive_t *drive) | ||
361 | { | ||
362 | ide_task_t task; | ||
363 | |||
364 | memset(&task, 0, sizeof(task)); | ||
365 | task.tf_flags = IDE_TFLAG_IN_FEATURE; | ||
366 | |||
367 | drive->hwif->tp_ops->tf_read(drive, &task); | ||
368 | |||
369 | return task.tf.error; | ||
370 | } | ||
371 | EXPORT_SYMBOL_GPL(ide_read_error); | ||
323 | 372 | ||
324 | void default_hwif_transport(ide_hwif_t *hwif) | 373 | void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) |
325 | { | 374 | { |
326 | hwif->tf_load = ide_tf_load; | 375 | ide_task_t task; |
327 | hwif->tf_read = ide_tf_read; | 376 | |
377 | memset(&task, 0, sizeof(task)); | ||
378 | task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | | ||
379 | IDE_TFLAG_IN_NSECT; | ||
328 | 380 | ||
329 | hwif->input_data = ata_input_data; | 381 | drive->hwif->tp_ops->tf_read(drive, &task); |
330 | hwif->output_data = ata_output_data; | 382 | |
383 | *bcount = (task.tf.lbah << 8) | task.tf.lbam; | ||
384 | *ireason = task.tf.nsect & 3; | ||
331 | } | 385 | } |
386 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); | ||
387 | |||
388 | const struct ide_tp_ops default_tp_ops = { | ||
389 | .exec_command = ide_exec_command, | ||
390 | .read_status = ide_read_status, | ||
391 | .read_altstatus = ide_read_altstatus, | ||
392 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
393 | |||
394 | .set_irq = ide_set_irq, | ||
395 | |||
396 | .tf_load = ide_tf_load, | ||
397 | .tf_read = ide_tf_read, | ||
398 | |||
399 | .input_data = ide_input_data, | ||
400 | .output_data = ide_output_data, | ||
401 | }; | ||
332 | 402 | ||
333 | void ide_fix_driveid (struct hd_driveid *id) | 403 | void ide_fix_driveid (struct hd_driveid *id) |
334 | { | 404 | { |
@@ -483,10 +553,10 @@ int drive_is_ready (ide_drive_t *drive) | |||
483 | * about possible isa-pnp and pci-pnp issues yet. | 553 | * about possible isa-pnp and pci-pnp issues yet. |
484 | */ | 554 | */ |
485 | if (hwif->io_ports.ctl_addr) | 555 | if (hwif->io_ports.ctl_addr) |
486 | stat = ide_read_altstatus(drive); | 556 | stat = hwif->tp_ops->read_altstatus(hwif); |
487 | else | 557 | else |
488 | /* Note: this may clear a pending IRQ!! */ | 558 | /* Note: this may clear a pending IRQ!! */ |
489 | stat = ide_read_status(drive); | 559 | stat = hwif->tp_ops->read_status(hwif); |
490 | 560 | ||
491 | if (stat & BUSY_STAT) | 561 | if (stat & BUSY_STAT) |
492 | /* drive busy: definitely not interrupting */ | 562 | /* drive busy: definitely not interrupting */ |
@@ -511,24 +581,26 @@ EXPORT_SYMBOL(drive_is_ready); | |||
511 | */ | 581 | */ |
512 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) | 582 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) |
513 | { | 583 | { |
584 | ide_hwif_t *hwif = drive->hwif; | ||
585 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
514 | unsigned long flags; | 586 | unsigned long flags; |
515 | int i; | 587 | int i; |
516 | u8 stat; | 588 | u8 stat; |
517 | 589 | ||
518 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ | 590 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ |
519 | stat = ide_read_status(drive); | 591 | stat = tp_ops->read_status(hwif); |
520 | 592 | ||
521 | if (stat & BUSY_STAT) { | 593 | if (stat & BUSY_STAT) { |
522 | local_irq_set(flags); | 594 | local_irq_set(flags); |
523 | timeout += jiffies; | 595 | timeout += jiffies; |
524 | while ((stat = ide_read_status(drive)) & BUSY_STAT) { | 596 | while ((stat = tp_ops->read_status(hwif)) & BUSY_STAT) { |
525 | if (time_after(jiffies, timeout)) { | 597 | if (time_after(jiffies, timeout)) { |
526 | /* | 598 | /* |
527 | * One last read after the timeout in case | 599 | * One last read after the timeout in case |
528 | * heavy interrupt load made us not make any | 600 | * heavy interrupt load made us not make any |
529 | * progress during the timeout.. | 601 | * progress during the timeout.. |
530 | */ | 602 | */ |
531 | stat = ide_read_status(drive); | 603 | stat = tp_ops->read_status(hwif); |
532 | if (!(stat & BUSY_STAT)) | 604 | if (!(stat & BUSY_STAT)) |
533 | break; | 605 | break; |
534 | 606 | ||
@@ -548,7 +620,7 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti | |||
548 | */ | 620 | */ |
549 | for (i = 0; i < 10; i++) { | 621 | for (i = 0; i < 10; i++) { |
550 | udelay(1); | 622 | udelay(1); |
551 | stat = ide_read_status(drive); | 623 | stat = tp_ops->read_status(hwif); |
552 | 624 | ||
553 | if (OK_STAT(stat, good, bad)) { | 625 | if (OK_STAT(stat, good, bad)) { |
554 | *rstat = stat; | 626 | *rstat = stat; |
@@ -674,6 +746,7 @@ no_80w: | |||
674 | int ide_driveid_update(ide_drive_t *drive) | 746 | int ide_driveid_update(ide_drive_t *drive) |
675 | { | 747 | { |
676 | ide_hwif_t *hwif = drive->hwif; | 748 | ide_hwif_t *hwif = drive->hwif; |
749 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
677 | struct hd_driveid *id; | 750 | struct hd_driveid *id; |
678 | unsigned long timeout, flags; | 751 | unsigned long timeout, flags; |
679 | u8 stat; | 752 | u8 stat; |
@@ -684,9 +757,9 @@ int ide_driveid_update(ide_drive_t *drive) | |||
684 | */ | 757 | */ |
685 | 758 | ||
686 | SELECT_MASK(drive, 1); | 759 | SELECT_MASK(drive, 1); |
687 | ide_set_irq(drive, 0); | 760 | tp_ops->set_irq(hwif, 0); |
688 | msleep(50); | 761 | msleep(50); |
689 | hwif->OUTBSYNC(hwif, WIN_IDENTIFY, hwif->io_ports.command_addr); | 762 | tp_ops->exec_command(hwif, WIN_IDENTIFY); |
690 | timeout = jiffies + WAIT_WORSTCASE; | 763 | timeout = jiffies + WAIT_WORSTCASE; |
691 | do { | 764 | do { |
692 | if (time_after(jiffies, timeout)) { | 765 | if (time_after(jiffies, timeout)) { |
@@ -695,11 +768,11 @@ int ide_driveid_update(ide_drive_t *drive) | |||
695 | } | 768 | } |
696 | 769 | ||
697 | msleep(50); /* give drive a breather */ | 770 | msleep(50); /* give drive a breather */ |
698 | stat = ide_read_altstatus(drive); | 771 | stat = tp_ops->read_altstatus(hwif); |
699 | } while (stat & BUSY_STAT); | 772 | } while (stat & BUSY_STAT); |
700 | 773 | ||
701 | msleep(50); /* wait for IRQ and DRQ_STAT */ | 774 | msleep(50); /* wait for IRQ and DRQ_STAT */ |
702 | stat = ide_read_status(drive); | 775 | stat = tp_ops->read_status(hwif); |
703 | 776 | ||
704 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { | 777 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { |
705 | SELECT_MASK(drive, 0); | 778 | SELECT_MASK(drive, 0); |
@@ -713,8 +786,8 @@ int ide_driveid_update(ide_drive_t *drive) | |||
713 | local_irq_restore(flags); | 786 | local_irq_restore(flags); |
714 | return 0; | 787 | return 0; |
715 | } | 788 | } |
716 | hwif->input_data(drive, NULL, id, SECTOR_SIZE); | 789 | tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); |
717 | (void)ide_read_status(drive); /* clear drive IRQ */ | 790 | (void)tp_ops->read_status(hwif); /* clear drive IRQ */ |
718 | local_irq_enable(); | 791 | local_irq_enable(); |
719 | local_irq_restore(flags); | 792 | local_irq_restore(flags); |
720 | ide_fix_driveid(id); | 793 | ide_fix_driveid(id); |
@@ -735,9 +808,10 @@ int ide_driveid_update(ide_drive_t *drive) | |||
735 | int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | 808 | int ide_config_drive_speed(ide_drive_t *drive, u8 speed) |
736 | { | 809 | { |
737 | ide_hwif_t *hwif = drive->hwif; | 810 | ide_hwif_t *hwif = drive->hwif; |
738 | struct ide_io_ports *io_ports = &hwif->io_ports; | 811 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
739 | int error = 0; | 812 | int error = 0; |
740 | u8 stat; | 813 | u8 stat; |
814 | ide_task_t task; | ||
741 | 815 | ||
742 | #ifdef CONFIG_BLK_DEV_IDEDMA | 816 | #ifdef CONFIG_BLK_DEV_IDEDMA |
743 | if (hwif->dma_ops) /* check if host supports DMA */ | 817 | if (hwif->dma_ops) /* check if host supports DMA */ |
@@ -770,12 +844,19 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
770 | SELECT_DRIVE(drive); | 844 | SELECT_DRIVE(drive); |
771 | SELECT_MASK(drive, 0); | 845 | SELECT_MASK(drive, 0); |
772 | udelay(1); | 846 | udelay(1); |
773 | ide_set_irq(drive, 0); | 847 | tp_ops->set_irq(hwif, 0); |
774 | hwif->OUTB(speed, io_ports->nsect_addr); | 848 | |
775 | hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr); | 849 | memset(&task, 0, sizeof(task)); |
776 | hwif->OUTBSYNC(hwif, WIN_SETFEATURES, io_ports->command_addr); | 850 | task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT; |
851 | task.tf.feature = SETFEATURES_XFER; | ||
852 | task.tf.nsect = speed; | ||
853 | |||
854 | tp_ops->tf_load(drive, &task); | ||
855 | |||
856 | tp_ops->exec_command(hwif, WIN_SETFEATURES); | ||
857 | |||
777 | if (drive->quirk_list == 2) | 858 | if (drive->quirk_list == 2) |
778 | ide_set_irq(drive, 1); | 859 | tp_ops->set_irq(hwif, 1); |
779 | 860 | ||
780 | error = __ide_wait_stat(drive, drive->ready_stat, | 861 | error = __ide_wait_stat(drive, drive->ready_stat, |
781 | BUSY_STAT|DRQ_STAT|ERR_STAT, | 862 | BUSY_STAT|DRQ_STAT|ERR_STAT, |
@@ -796,8 +877,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
796 | 877 | ||
797 | skip: | 878 | skip: |
798 | #ifdef CONFIG_BLK_DEV_IDEDMA | 879 | #ifdef CONFIG_BLK_DEV_IDEDMA |
799 | if ((speed >= XFER_SW_DMA_0 || (hwif->host_flags & IDE_HFLAG_VDMA)) && | 880 | if (speed >= XFER_SW_DMA_0 && drive->using_dma) |
800 | drive->using_dma) | ||
801 | hwif->dma_ops->dma_host_set(drive, 1); | 881 | hwif->dma_ops->dma_host_set(drive, 1); |
802 | else if (hwif->dma_ops) /* check if host supports DMA */ | 882 | else if (hwif->dma_ops) /* check if host supports DMA */ |
803 | ide_dma_off_quietly(drive); | 883 | ide_dma_off_quietly(drive); |
@@ -881,7 +961,7 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, | |||
881 | 961 | ||
882 | spin_lock_irqsave(&ide_lock, flags); | 962 | spin_lock_irqsave(&ide_lock, flags); |
883 | __ide_set_handler(drive, handler, timeout, expiry); | 963 | __ide_set_handler(drive, handler, timeout, expiry); |
884 | hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr); | 964 | hwif->tp_ops->exec_command(hwif, cmd); |
885 | /* | 965 | /* |
886 | * Drive takes 400nS to respond, we must avoid the IRQ being | 966 | * Drive takes 400nS to respond, we must avoid the IRQ being |
887 | * serviced before that. | 967 | * serviced before that. |
@@ -899,7 +979,7 @@ void ide_execute_pkt_cmd(ide_drive_t *drive) | |||
899 | unsigned long flags; | 979 | unsigned long flags; |
900 | 980 | ||
901 | spin_lock_irqsave(&ide_lock, flags); | 981 | spin_lock_irqsave(&ide_lock, flags); |
902 | hwif->OUTBSYNC(hwif, WIN_PACKETCMD, hwif->io_ports.command_addr); | 982 | hwif->tp_ops->exec_command(hwif, WIN_PACKETCMD); |
903 | ndelay(400); | 983 | ndelay(400); |
904 | spin_unlock_irqrestore(&ide_lock, flags); | 984 | spin_unlock_irqrestore(&ide_lock, flags); |
905 | } | 985 | } |
@@ -924,12 +1004,13 @@ static ide_startstop_t do_reset1 (ide_drive_t *, int); | |||
924 | */ | 1004 | */ |
925 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | 1005 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) |
926 | { | 1006 | { |
927 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | 1007 | ide_hwif_t *hwif = drive->hwif; |
1008 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | ||
928 | u8 stat; | 1009 | u8 stat; |
929 | 1010 | ||
930 | SELECT_DRIVE(drive); | 1011 | SELECT_DRIVE(drive); |
931 | udelay (10); | 1012 | udelay (10); |
932 | stat = ide_read_status(drive); | 1013 | stat = hwif->tp_ops->read_status(hwif); |
933 | 1014 | ||
934 | if (OK_STAT(stat, 0, BUSY_STAT)) | 1015 | if (OK_STAT(stat, 0, BUSY_STAT)) |
935 | printk("%s: ATAPI reset complete\n", drive->name); | 1016 | printk("%s: ATAPI reset complete\n", drive->name); |
@@ -975,7 +1056,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
975 | } | 1056 | } |
976 | } | 1057 | } |
977 | 1058 | ||
978 | tmp = ide_read_status(drive); | 1059 | tmp = hwif->tp_ops->read_status(hwif); |
979 | 1060 | ||
980 | if (!OK_STAT(tmp, 0, BUSY_STAT)) { | 1061 | if (!OK_STAT(tmp, 0, BUSY_STAT)) { |
981 | if (time_before(jiffies, hwgroup->poll_timeout)) { | 1062 | if (time_before(jiffies, hwgroup->poll_timeout)) { |
@@ -1089,8 +1170,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1089 | ide_hwif_t *hwif; | 1170 | ide_hwif_t *hwif; |
1090 | ide_hwgroup_t *hwgroup; | 1171 | ide_hwgroup_t *hwgroup; |
1091 | struct ide_io_ports *io_ports; | 1172 | struct ide_io_ports *io_ports; |
1173 | const struct ide_tp_ops *tp_ops; | ||
1092 | const struct ide_port_ops *port_ops; | 1174 | const struct ide_port_ops *port_ops; |
1093 | u8 ctl; | ||
1094 | 1175 | ||
1095 | spin_lock_irqsave(&ide_lock, flags); | 1176 | spin_lock_irqsave(&ide_lock, flags); |
1096 | hwif = HWIF(drive); | 1177 | hwif = HWIF(drive); |
@@ -1098,6 +1179,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1098 | 1179 | ||
1099 | io_ports = &hwif->io_ports; | 1180 | io_ports = &hwif->io_ports; |
1100 | 1181 | ||
1182 | tp_ops = hwif->tp_ops; | ||
1183 | |||
1101 | /* We must not reset with running handlers */ | 1184 | /* We must not reset with running handlers */ |
1102 | BUG_ON(hwgroup->handler != NULL); | 1185 | BUG_ON(hwgroup->handler != NULL); |
1103 | 1186 | ||
@@ -1106,7 +1189,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1106 | pre_reset(drive); | 1189 | pre_reset(drive); |
1107 | SELECT_DRIVE(drive); | 1190 | SELECT_DRIVE(drive); |
1108 | udelay (20); | 1191 | udelay (20); |
1109 | hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr); | 1192 | tp_ops->exec_command(hwif, WIN_SRST); |
1110 | ndelay(400); | 1193 | ndelay(400); |
1111 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | 1194 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; |
1112 | hwgroup->polling = 1; | 1195 | hwgroup->polling = 1; |
@@ -1135,16 +1218,15 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1135 | * immediate interrupt due to the edge transition it produces. | 1218 | * immediate interrupt due to the edge transition it produces. |
1136 | * This single interrupt gives us a "fast poll" for drives that | 1219 | * This single interrupt gives us a "fast poll" for drives that |
1137 | * recover from reset very quickly, saving us the first 50ms wait time. | 1220 | * recover from reset very quickly, saving us the first 50ms wait time. |
1221 | * | ||
1222 | * TODO: add ->softreset method and stop abusing ->set_irq | ||
1138 | */ | 1223 | */ |
1139 | /* set SRST and nIEN */ | 1224 | /* set SRST and nIEN */ |
1140 | hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | 6, io_ports->ctl_addr); | 1225 | tp_ops->set_irq(hwif, 4); |
1141 | /* more than enough time */ | 1226 | /* more than enough time */ |
1142 | udelay(10); | 1227 | udelay(10); |
1143 | if (drive->quirk_list == 2) | 1228 | /* clear SRST, leave nIEN (unless device is on the quirk list) */ |
1144 | ctl = ATA_DEVCTL_OBS; /* clear SRST and nIEN */ | 1229 | tp_ops->set_irq(hwif, drive->quirk_list == 2); |
1145 | else | ||
1146 | ctl = ATA_DEVCTL_OBS | 2; /* clear SRST, leave nIEN */ | ||
1147 | hwif->OUTBSYNC(hwif, ctl, io_ports->ctl_addr); | ||
1148 | /* more than enough time */ | 1230 | /* more than enough time */ |
1149 | udelay(10); | 1231 | udelay(10); |
1150 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | 1232 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; |
@@ -1189,7 +1271,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) | |||
1189 | * about locking issues (2.5 work ?). | 1271 | * about locking issues (2.5 work ?). |
1190 | */ | 1272 | */ |
1191 | mdelay(1); | 1273 | mdelay(1); |
1192 | stat = hwif->INB(hwif->io_ports.status_addr); | 1274 | stat = hwif->tp_ops->read_status(hwif); |
1193 | if ((stat & BUSY_STAT) == 0) | 1275 | if ((stat & BUSY_STAT) == 0) |
1194 | return 0; | 1276 | return 0; |
1195 | /* | 1277 | /* |