diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index e106954e13f9..41ec53f329fa 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -135,6 +135,23 @@ static u8 ide_read_sff_dma_status(ide_hwif_t *hwif) | |||
135 | return inb(hwif->dma_base + ATA_DMA_STATUS); | 135 | return inb(hwif->dma_base + ATA_DMA_STATUS); |
136 | } | 136 | } |
137 | 137 | ||
138 | static void ide_set_irq(ide_hwif_t *hwif, int on) | ||
139 | { | ||
140 | u8 ctl = ATA_DEVCTL_OBS; | ||
141 | |||
142 | if (on == 4) { /* hack for SRST */ | ||
143 | ctl |= 4; | ||
144 | on &= ~4; | ||
145 | } | ||
146 | |||
147 | ctl |= on ? 0 : 2; | ||
148 | |||
149 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
150 | writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); | ||
151 | else | ||
152 | outb(ctl, hwif->io_ports.ctl_addr); | ||
153 | } | ||
154 | |||
138 | static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | 155 | static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) |
139 | { | 156 | { |
140 | ide_hwif_t *hwif = drive->hwif; | 157 | ide_hwif_t *hwif = drive->hwif; |
@@ -360,6 +377,8 @@ void default_hwif_transport(ide_hwif_t *hwif) | |||
360 | hwif->read_altstatus = ide_read_altstatus; | 377 | hwif->read_altstatus = ide_read_altstatus; |
361 | hwif->read_sff_dma_status = ide_read_sff_dma_status; | 378 | hwif->read_sff_dma_status = ide_read_sff_dma_status; |
362 | 379 | ||
380 | hwif->set_irq = ide_set_irq; | ||
381 | |||
363 | hwif->tf_load = ide_tf_load; | 382 | hwif->tf_load = ide_tf_load; |
364 | hwif->tf_read = ide_tf_read; | 383 | hwif->tf_read = ide_tf_read; |
365 | 384 | ||
@@ -722,7 +741,7 @@ int ide_driveid_update(ide_drive_t *drive) | |||
722 | */ | 741 | */ |
723 | 742 | ||
724 | SELECT_MASK(drive, 1); | 743 | SELECT_MASK(drive, 1); |
725 | ide_set_irq(drive, 0); | 744 | hwif->set_irq(hwif, 0); |
726 | msleep(50); | 745 | msleep(50); |
727 | hwif->exec_command(hwif, WIN_IDENTIFY); | 746 | hwif->exec_command(hwif, WIN_IDENTIFY); |
728 | timeout = jiffies + WAIT_WORSTCASE; | 747 | timeout = jiffies + WAIT_WORSTCASE; |
@@ -808,12 +827,12 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
808 | SELECT_DRIVE(drive); | 827 | SELECT_DRIVE(drive); |
809 | SELECT_MASK(drive, 0); | 828 | SELECT_MASK(drive, 0); |
810 | udelay(1); | 829 | udelay(1); |
811 | ide_set_irq(drive, 0); | 830 | hwif->set_irq(hwif, 0); |
812 | hwif->OUTB(speed, io_ports->nsect_addr); | 831 | hwif->OUTB(speed, io_ports->nsect_addr); |
813 | hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr); | 832 | hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr); |
814 | hwif->exec_command(hwif, WIN_SETFEATURES); | 833 | hwif->exec_command(hwif, WIN_SETFEATURES); |
815 | if (drive->quirk_list == 2) | 834 | if (drive->quirk_list == 2) |
816 | ide_set_irq(drive, 1); | 835 | hwif->set_irq(hwif, 1); |
817 | 836 | ||
818 | error = __ide_wait_stat(drive, drive->ready_stat, | 837 | error = __ide_wait_stat(drive, drive->ready_stat, |
819 | BUSY_STAT|DRQ_STAT|ERR_STAT, | 838 | BUSY_STAT|DRQ_STAT|ERR_STAT, |
@@ -1129,7 +1148,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1129 | ide_hwgroup_t *hwgroup; | 1148 | ide_hwgroup_t *hwgroup; |
1130 | struct ide_io_ports *io_ports; | 1149 | struct ide_io_ports *io_ports; |
1131 | const struct ide_port_ops *port_ops; | 1150 | const struct ide_port_ops *port_ops; |
1132 | u8 ctl; | ||
1133 | 1151 | ||
1134 | spin_lock_irqsave(&ide_lock, flags); | 1152 | spin_lock_irqsave(&ide_lock, flags); |
1135 | hwif = HWIF(drive); | 1153 | hwif = HWIF(drive); |
@@ -1174,16 +1192,15 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1174 | * immediate interrupt due to the edge transition it produces. | 1192 | * immediate interrupt due to the edge transition it produces. |
1175 | * This single interrupt gives us a "fast poll" for drives that | 1193 | * This single interrupt gives us a "fast poll" for drives that |
1176 | * recover from reset very quickly, saving us the first 50ms wait time. | 1194 | * recover from reset very quickly, saving us the first 50ms wait time. |
1195 | * | ||
1196 | * TODO: add ->softreset method and stop abusing ->set_irq | ||
1177 | */ | 1197 | */ |
1178 | /* set SRST and nIEN */ | 1198 | /* set SRST and nIEN */ |
1179 | hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | 6, io_ports->ctl_addr); | 1199 | hwif->set_irq(hwif, 4); |
1180 | /* more than enough time */ | 1200 | /* more than enough time */ |
1181 | udelay(10); | 1201 | udelay(10); |
1182 | if (drive->quirk_list == 2) | 1202 | /* clear SRST, leave nIEN (unless device is on the quirk list) */ |
1183 | ctl = ATA_DEVCTL_OBS; /* clear SRST and nIEN */ | 1203 | hwif->set_irq(hwif, drive->quirk_list == 2); |
1184 | else | ||
1185 | ctl = ATA_DEVCTL_OBS | 2; /* clear SRST, leave nIEN */ | ||
1186 | hwif->OUTBSYNC(hwif, ctl, io_ports->ctl_addr); | ||
1187 | /* more than enough time */ | 1204 | /* more than enough time */ |
1188 | udelay(10); | 1205 | udelay(10); |
1189 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | 1206 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; |