diff options
-rw-r--r-- | drivers/ide/ide-io.c | 15 | ||||
-rw-r--r-- | drivers/ide/pci/piix.c | 39 | ||||
-rw-r--r-- | include/linux/ide.h | 4 |
3 files changed, 29 insertions, 29 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ec709269c066..d0579f1abddd 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -1418,23 +1418,16 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1418 | del_timer(&hwgroup->timer); | 1418 | del_timer(&hwgroup->timer); |
1419 | spin_unlock(&ide_lock); | 1419 | spin_unlock(&ide_lock); |
1420 | 1420 | ||
1421 | /* Some controllers might set DMA INTR no matter DMA or PIO; | 1421 | if (hwif->port_ops && hwif->port_ops->clear_irq) |
1422 | * bmdma status might need to be cleared even for | 1422 | hwif->port_ops->clear_irq(drive); |
1423 | * PIO interrupts to prevent spurious/lost irq. | ||
1424 | */ | ||
1425 | if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma)) | ||
1426 | /* ide_dma_end() needs bmdma status for error checking. | ||
1427 | * So, skip clearing bmdma status here and leave it | ||
1428 | * to ide_dma_end() if this is dma interrupt. | ||
1429 | */ | ||
1430 | hwif->ide_dma_clear_irq(drive); | ||
1431 | 1423 | ||
1432 | if (drive->dev_flags & IDE_DFLAG_UNMASK) | 1424 | if (drive->dev_flags & IDE_DFLAG_UNMASK) |
1433 | local_irq_enable_in_hardirq(); | 1425 | local_irq_enable_in_hardirq(); |
1426 | |||
1434 | /* service this interrupt, may set handler for next interrupt */ | 1427 | /* service this interrupt, may set handler for next interrupt */ |
1435 | startstop = handler(drive); | 1428 | startstop = handler(drive); |
1436 | spin_lock_irq(&ide_lock); | ||
1437 | 1429 | ||
1430 | spin_lock_irq(&ide_lock); | ||
1438 | /* | 1431 | /* |
1439 | * Note that handler() may have set things up for another | 1432 | * Note that handler() may have set things up for another |
1440 | * interrupt to occur soon, but it cannot happen until | 1433 | * interrupt to occur soon, but it cannot happen until |
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, \ |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 14d489c2e5a9..37a4344f3842 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -704,6 +704,7 @@ extern const struct ide_tp_ops default_tp_ops; | |||
704 | * @resetproc: routine to reset controller after a disk reset | 704 | * @resetproc: routine to reset controller after a disk reset |
705 | * @maskproc: special host masking for drive selection | 705 | * @maskproc: special host masking for drive selection |
706 | * @quirkproc: check host's drive quirk list | 706 | * @quirkproc: check host's drive quirk list |
707 | * @clear_irq: clear IRQ | ||
707 | * | 708 | * |
708 | * @mdma_filter: filter MDMA modes | 709 | * @mdma_filter: filter MDMA modes |
709 | * @udma_filter: filter UDMA modes | 710 | * @udma_filter: filter UDMA modes |
@@ -720,6 +721,7 @@ struct ide_port_ops { | |||
720 | void (*resetproc)(ide_drive_t *); | 721 | void (*resetproc)(ide_drive_t *); |
721 | void (*maskproc)(ide_drive_t *, int); | 722 | void (*maskproc)(ide_drive_t *, int); |
722 | void (*quirkproc)(ide_drive_t *); | 723 | void (*quirkproc)(ide_drive_t *); |
724 | void (*clear_irq)(ide_drive_t *); | ||
723 | 725 | ||
724 | u8 (*mdma_filter)(ide_drive_t *); | 726 | u8 (*mdma_filter)(ide_drive_t *); |
725 | u8 (*udma_filter)(ide_drive_t *); | 727 | u8 (*udma_filter)(ide_drive_t *); |
@@ -782,8 +784,6 @@ typedef struct hwif_s { | |||
782 | const struct ide_port_ops *port_ops; | 784 | const struct ide_port_ops *port_ops; |
783 | const struct ide_dma_ops *dma_ops; | 785 | const struct ide_dma_ops *dma_ops; |
784 | 786 | ||
785 | void (*ide_dma_clear_irq)(ide_drive_t *drive); | ||
786 | |||
787 | /* dma physical region descriptor table (cpu view) */ | 787 | /* dma physical region descriptor table (cpu view) */ |
788 | unsigned int *dmatable_cpu; | 788 | unsigned int *dmatable_cpu; |
789 | /* dma physical region descriptor table (dma view) */ | 789 | /* dma physical region descriptor table (dma view) */ |