diff options
Diffstat (limited to 'drivers/ide/pci/piix.c')
-rw-r--r-- | drivers/ide/pci/piix.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index a909684ee61b..56feb939f82a 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c | |||
@@ -215,17 +215,26 @@ static unsigned int init_chipset_ich(struct pci_dev *dev) | |||
215 | } | 215 | } |
216 | 216 | ||
217 | /** | 217 | /** |
218 | * piix_dma_clear_irq - clear BMDMA status | 218 | * ich_clear_irq - clear BMDMA status |
219 | * @drive: IDE drive to clear | 219 | * @drive: IDE drive |
220 | * | 220 | * |
221 | * Called from ide_intr() for PIO interrupts | 221 | * ICHx contollers set DMA INTR no matter DMA or PIO. |
222 | * to clear BMDMA status as needed by ICHx | 222 | * BMDMA status might need to be cleared even for |
223 | * PIO interrupts to prevent spurious/lost IRQ. | ||
223 | */ | 224 | */ |
224 | static void piix_dma_clear_irq(ide_drive_t *drive) | 225 | static void ich_clear_irq(ide_drive_t *drive) |
225 | { | 226 | { |
226 | ide_hwif_t *hwif = HWIF(drive); | 227 | ide_hwif_t *hwif = HWIF(drive); |
227 | u8 dma_stat; | 228 | u8 dma_stat; |
228 | 229 | ||
230 | /* | ||
231 | * ide_dma_end() needs BMDMA status for error checking. | ||
232 | * So, skip clearing BMDMA status here and leave it | ||
233 | * to ide_dma_end() if this is DMA interrupt. | ||
234 | */ | ||
235 | if (drive->waiting_for_dma || hwif->dma_base == 0) | ||
236 | return; | ||
237 | |||
229 | /* clear the INTR & ERROR bits */ | 238 | /* clear the INTR & ERROR bits */ |
230 | dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); | 239 | dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); |
231 | /* Should we force the bit as well ? */ | 240 | /* Should we force the bit as well ? */ |
@@ -293,21 +302,19 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) | |||
293 | hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0; | 302 | hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0; |
294 | } | 303 | } |
295 | 304 | ||
296 | static void __devinit init_hwif_ich(ide_hwif_t *hwif) | ||
297 | { | ||
298 | init_hwif_piix(hwif); | ||
299 | |||
300 | /* ICHx need to clear the BMDMA status for all interrupts */ | ||
301 | if (hwif->dma_base) | ||
302 | hwif->ide_dma_clear_irq = &piix_dma_clear_irq; | ||
303 | } | ||
304 | |||
305 | static const struct ide_port_ops piix_port_ops = { | 305 | static const struct ide_port_ops piix_port_ops = { |
306 | .set_pio_mode = piix_set_pio_mode, | 306 | .set_pio_mode = piix_set_pio_mode, |
307 | .set_dma_mode = piix_set_dma_mode, | 307 | .set_dma_mode = piix_set_dma_mode, |
308 | .cable_detect = piix_cable_detect, | 308 | .cable_detect = piix_cable_detect, |
309 | }; | 309 | }; |
310 | 310 | ||
311 | static const struct ide_port_ops ich_port_ops = { | ||
312 | .set_pio_mode = piix_set_pio_mode, | ||
313 | .set_dma_mode = piix_set_dma_mode, | ||
314 | .clear_irq = ich_clear_irq, | ||
315 | .cable_detect = piix_cable_detect, | ||
316 | }; | ||
317 | |||
311 | #ifndef CONFIG_IA64 | 318 | #ifndef CONFIG_IA64 |
312 | #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS | 319 | #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS |
313 | #else | 320 | #else |
@@ -331,9 +338,9 @@ static const struct ide_port_ops piix_port_ops = { | |||
331 | { \ | 338 | { \ |
332 | .name = DRV_NAME, \ | 339 | .name = DRV_NAME, \ |
333 | .init_chipset = init_chipset_ich, \ | 340 | .init_chipset = init_chipset_ich, \ |
334 | .init_hwif = init_hwif_ich, \ | 341 | .init_hwif = init_hwif_piix, \ |
335 | .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ | 342 | .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ |
336 | .port_ops = &piix_port_ops, \ | 343 | .port_ops = &ich_port_ops, \ |
337 | .host_flags = IDE_HFLAGS_PIIX, \ | 344 | .host_flags = IDE_HFLAGS_PIIX, \ |
338 | .pio_mask = ATA_PIO4, \ | 345 | .pio_mask = ATA_PIO4, \ |
339 | .swdma_mask = ATA_SWDMA2_ONLY, \ | 346 | .swdma_mask = ATA_SWDMA2_ONLY, \ |