diff options
author | Akira Iguchi | 2007-03-03 17:48:55 +0100 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz | 2007-03-03 17:48:55 +0100 |
commit | 06a9952b8379c48df972023f648014a82582c23a (patch) | |
tree | 54502af21dff2a7a2ec7f7ffe70208e849fd9fad /drivers/ide | |
parent | 846c11abc7934a523a665a3b702358e6f2998e3e (diff) |
scc_pata: bugfix for checking DMA IRQ status
On Tuesday 27 February 2007, Akira Iguchi wrote:
>
> But since I sent the first patch, I found a bug for checking DMA IRQ status.
> (http://www.spinics.net/lists/linux-ide/msg06903.html)
> Then I sent the fixed patch for libata only. So my drivers/ide patch
> still has same bug and I want to fix it, too.
>
> The following patch fixes this bug. Please apply this patch.
From: Akira Iguchi <akira2.iguchi@toshiba.co.jp>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ppc/scc_pata.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/ide/ppc/scc_pata.c b/drivers/ide/ppc/scc_pata.c index de64b022478b..f84bf791f72e 100644 --- a/drivers/ide/ppc/scc_pata.c +++ b/drivers/ide/ppc/scc_pata.c @@ -509,6 +509,32 @@ static int scc_ide_dma_end(ide_drive_t * drive) return __ide_dma_end(drive); } +/* returns 1 if dma irq issued, 0 otherwise */ +static int scc_dma_test_irq(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + u8 dma_stat = hwif->INB(hwif->dma_status); + + /* return 1 if INTR asserted */ + if ((dma_stat & 4) == 4) + return 1; + + /* Workaround for PTERADD: emulate DMA_INTR when + * - IDE_STATUS[ERR] = 1 + * - INT_STATUS[INTRQ] = 1 + * - DMA_STATUS[IORACTA] = 1 + */ + if (in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT && + in_be32((void __iomem *)(hwif->dma_base + 0x014)) & INTSTS_INTRQ && + dma_stat & 1) + return 1; + + if (!drive->waiting_for_dma) + printk(KERN_WARNING "%s: (%s) called while not waiting\n", + drive->name, __FUNCTION__); + return 0; +} + /** * setup_mmio_scc - map CTRL/BMID region * @dev: PCI device we are configuring @@ -712,6 +738,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) hwif->speedproc = scc_tune_chipset; hwif->tuneproc = scc_tuneproc; hwif->ide_dma_check = scc_config_drive_for_dma; + hwif->ide_dma_test_irq = scc_dma_test_irq; hwif->drives[0].autotune = IDE_TUNE_AUTO; hwif->drives[1].autotune = IDE_TUNE_AUTO; |