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, \ |
