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) */ |
