aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2007-02-16 20:40:21 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-02-16 20:40:21 -0500
commitf0dd8712eb8cc5687b4582fbc41cfbcd55bba0d2 (patch)
tree190bc6cf68e056ae72d895dc2c9074de2c0ed18f /drivers
parentfdb77da4ca68ae17a39d58c9d5c00479a7e124c0 (diff)
ide: clear bmdma status in ide_intr() for ICHx controllers (revised #4)
patch 1/2 (revised): - Fix drive->waiting_for_dma to work with CDB-intr devices. - Do the dma status clearing in ide_intr() and add a new hwif->ide_dma_clear_irq for Intel ICHx controllers. Revised per Alan, Sergei and Bart's advice. Patch against 2.6.20-rc6. Tested ok on my ICH4 and pdc20275 adapters. Please review/apply, thanks. Signed-off-by: Albert Lee <albertcc@tw.ibm.com> Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: "Adam W. Hawks" <awhawks@us.ibm.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ide/ide-cd.c8
-rw-r--r--drivers/ide/ide-io.c11
-rw-r--r--drivers/ide/ide.c1
-rw-r--r--drivers/ide/pci/piix.c63
4 files changed, 68 insertions, 15 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 5969cec58dc1..21f4ae2b7176 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -930,6 +930,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
930 HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); 930 HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
931 931
932 if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { 932 if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
933 /* waiting for CDB interrupt, not DMA yet. */
934 if (info->dma)
935 drive->waiting_for_dma = 0;
936
933 /* packet command */ 937 /* packet command */
934 ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry); 938 ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
935 return ide_started; 939 return ide_started;
@@ -972,6 +976,10 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
972 /* Check for errors. */ 976 /* Check for errors. */
973 if (cdrom_decode_status(drive, DRQ_STAT, NULL)) 977 if (cdrom_decode_status(drive, DRQ_STAT, NULL))
974 return ide_stopped; 978 return ide_stopped;
979
980 /* Ok, next interrupt will be DMA interrupt. */
981 if (info->dma)
982 drive->waiting_for_dma = 1;
975 } else { 983 } else {
976 /* Otherwise, we must wait for DRQ to get set. */ 984 /* Otherwise, we must wait for DRQ to get set. */
977 if (ide_wait_stat(&startstop, drive, DRQ_STAT, 985 if (ide_wait_stat(&startstop, drive, DRQ_STAT,
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 2614f41b5074..99d1c43f433e 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -1646,6 +1646,17 @@ irqreturn_t ide_intr (int irq, void *dev_id)
1646 del_timer(&hwgroup->timer); 1646 del_timer(&hwgroup->timer);
1647 spin_unlock(&ide_lock); 1647 spin_unlock(&ide_lock);
1648 1648
1649 /* Some controllers might set DMA INTR no matter DMA or PIO;
1650 * bmdma status might need to be cleared even for
1651 * PIO interrupts to prevent spurious/lost irq.
1652 */
1653 if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma))
1654 /* ide_dma_end() needs bmdma status for error checking.
1655 * So, skip clearing bmdma status here and leave it
1656 * to ide_dma_end() if this is dma interrupt.
1657 */
1658 hwif->ide_dma_clear_irq(drive);
1659
1649 if (drive->unmask) 1660 if (drive->unmask)
1650 local_irq_enable_in_hardirq(); 1661 local_irq_enable_in_hardirq();
1651 /* service this interrupt, may set handler for next interrupt */ 1662 /* service this interrupt, may set handler for next interrupt */
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index c750f6ce770a..65eb095469b5 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -509,6 +509,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
509 hwif->ide_dma_on = tmp_hwif->ide_dma_on; 509 hwif->ide_dma_on = tmp_hwif->ide_dma_on;
510 hwif->ide_dma_off_quietly = tmp_hwif->ide_dma_off_quietly; 510 hwif->ide_dma_off_quietly = tmp_hwif->ide_dma_off_quietly;
511 hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq; 511 hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq;
512 hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq;
512 hwif->ide_dma_host_on = tmp_hwif->ide_dma_host_on; 513 hwif->ide_dma_host_on = tmp_hwif->ide_dma_host_on;
513 hwif->ide_dma_host_off = tmp_hwif->ide_dma_host_off; 514 hwif->ide_dma_host_off = tmp_hwif->ide_dma_host_off;
514 hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq; 515 hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq;
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 52cfc2ac22c1..af65b0888bbb 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -410,17 +410,14 @@ fast_ata_pio:
410} 410}
411 411
412/** 412/**
413 * init_chipset_piix - set up the PIIX chipset 413 * piix_is_ichx - check if ICHx
414 * @dev: PCI device to set up 414 * @dev: PCI device to check
415 * @name: Name of the device
416 * 415 *
417 * Initialize the PCI device as required. For the PIIX this turns 416 * returns 1 if ICHx, 0 otherwise.
418 * out to be nice and simple
419 */ 417 */
420 418static int piix_is_ichx(struct pci_dev *dev)
421static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
422{ 419{
423 switch(dev->device) { 420 switch (dev->device) {
424 case PCI_DEVICE_ID_INTEL_82801EB_1: 421 case PCI_DEVICE_ID_INTEL_82801EB_1:
425 case PCI_DEVICE_ID_INTEL_82801AA_1: 422 case PCI_DEVICE_ID_INTEL_82801AA_1:
426 case PCI_DEVICE_ID_INTEL_82801AB_1: 423 case PCI_DEVICE_ID_INTEL_82801AB_1:
@@ -438,19 +435,51 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char
438 case PCI_DEVICE_ID_INTEL_ICH7_21: 435 case PCI_DEVICE_ID_INTEL_ICH7_21:
439 case PCI_DEVICE_ID_INTEL_ESB2_18: 436 case PCI_DEVICE_ID_INTEL_ESB2_18:
440 case PCI_DEVICE_ID_INTEL_ICH8_6: 437 case PCI_DEVICE_ID_INTEL_ICH8_6:
441 { 438 return 1;
442 unsigned int extra = 0;
443 pci_read_config_dword(dev, 0x54, &extra);
444 pci_write_config_dword(dev, 0x54, extra|0x400);
445 }
446 default:
447 break;
448 } 439 }
449 440
450 return 0; 441 return 0;
451} 442}
452 443
453/** 444/**
445 * init_chipset_piix - set up the PIIX chipset
446 * @dev: PCI device to set up
447 * @name: Name of the device
448 *
449 * Initialize the PCI device as required. For the PIIX this turns
450 * out to be nice and simple
451 */
452
453static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
454{
455 if (piix_is_ichx(dev)) {
456 unsigned int extra = 0;
457 pci_read_config_dword(dev, 0x54, &extra);
458 pci_write_config_dword(dev, 0x54, extra|0x400);
459 }
460
461 return 0;
462}
463
464/**
465 * piix_dma_clear_irq - clear BMDMA status
466 * @drive: IDE drive to clear
467 *
468 * Called from ide_intr() for PIO interrupts
469 * to clear BMDMA status as needed by ICHx
470 */
471static void piix_dma_clear_irq(ide_drive_t *drive)
472{
473 ide_hwif_t *hwif = HWIF(drive);
474 u8 dma_stat;
475
476 /* clear the INTR & ERROR bits */
477 dma_stat = hwif->INB(hwif->dma_status);
478 /* Should we force the bit as well ? */
479 hwif->OUTB(dma_stat, hwif->dma_status);
480}
481
482/**
454 * init_hwif_piix - fill in the hwif for the PIIX 483 * init_hwif_piix - fill in the hwif for the PIIX
455 * @hwif: IDE interface 484 * @hwif: IDE interface
456 * 485 *
@@ -486,6 +515,10 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
486 if (!hwif->dma_base) 515 if (!hwif->dma_base)
487 return; 516 return;
488 517
518 /* ICHx need to clear the bmdma status for all interrupts */
519 if (piix_is_ichx(hwif->pci_dev))
520 hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
521
489 hwif->atapi_dma = 1; 522 hwif->atapi_dma = 1;
490 hwif->ultra_mask = 0x3f; 523 hwif->ultra_mask = 0x3f;
491 hwif->mwdma_mask = 0x06; 524 hwif->mwdma_mask = 0x06;