From: Sergei Shtylyov Date: Wed, 7 Feb 2007 17:18:13 +0000 (+0100) Subject: hpt366: clean up DMA timeout handling for HPT370 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=4bf63de27e9fd9c0926ba3bb773de076b324a955;p=linux-beck.git hpt366: clean up DMA timeout handling for HPT370 Clean up DMA timeout handling for HPT370: - hpt370_lostirq_timeout() cleared the DMA status which made __ide_dma_end() called afterwards return the incorrect result, and the DMA engine was reset both before and after stopping DMA while the HighPoint drivers only do it after (which seems logical) -- fix this and also rename the function; - get rid of the needless mutual recursion in hpt370_ide_dma_end() and hpt370_ide_dma_timeout(); - get rid of hpt370_lostirq_timeout() since hwif->ide_dma_end() called from the driver's interrupt handler later does all its work. Signed-off-by: Sergei Shtylyov Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 7317defd8210..9ad1531b6034 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 0.51 Jun 04, 2006 + * linux/drivers/ide/pci/hpt366.c Version 0.52 Jun 07, 2006 * * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -90,6 +90,7 @@ * there; make HPT36x speedproc handler look the same way as the HPT37x one * - fix the tuneproc handler to always set the PIO mode requested, not the * best possible one + * - clean up DMA timeout handling for HPT370 * */ @@ -680,7 +681,7 @@ static int hpt366_ide_dma_lostirq(ide_drive_t *drive) return __ide_dma_lostirq(drive); } -static void hpt370_clear_engine (ide_drive_t *drive) +static void hpt370_clear_engine(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); @@ -688,6 +689,22 @@ static void hpt370_clear_engine (ide_drive_t *drive) udelay(10); } +static void hpt370_irq_timeout(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + u16 bfifo = 0; + u8 dma_cmd; + + pci_read_config_word(hwif->pci_dev, hwif->select_data + 2, &bfifo); + printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff); + + /* get DMA command mode */ + dma_cmd = hwif->INB(hwif->dma_command); + /* stop DMA */ + hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command); + hpt370_clear_engine(drive); +} + static void hpt370_ide_dma_start(ide_drive_t *drive) { #ifdef HPT_RESET_STATE_ENGINE @@ -696,55 +713,27 @@ static void hpt370_ide_dma_start(ide_drive_t *drive) ide_dma_start(drive); } -static int hpt370_ide_dma_end (ide_drive_t *drive) +static int hpt370_ide_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = hwif->INB(hwif->dma_status); + u8 dma_stat = hwif->INB(hwif->dma_status); if (dma_stat & 0x01) { /* wait a little */ udelay(20); dma_stat = hwif->INB(hwif->dma_status); + if (dma_stat & 0x01) + hpt370_irq_timeout(drive); } - if ((dma_stat & 0x01) != 0) - /* fallthrough */ - (void) HWIF(drive)->ide_dma_timeout(drive); - return __ide_dma_end(drive); } -static void hpt370_lostirq_timeout (ide_drive_t *drive) +static int hpt370_ide_dma_timeout(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - u8 bfifo = 0; - u8 dma_stat = 0, dma_cmd = 0; - - pci_read_config_byte(HWIF(drive)->pci_dev, hwif->select_data + 2, &bfifo); - printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo); - hpt370_clear_engine(drive); - /* get dma command mode */ - dma_cmd = hwif->INB(hwif->dma_command); - /* stop dma */ - hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command); - dma_stat = hwif->INB(hwif->dma_status); - /* clear errors */ - hwif->OUTB(dma_stat | 0x6, hwif->dma_status); -} - -static int hpt370_ide_dma_timeout (ide_drive_t *drive) -{ - hpt370_lostirq_timeout(drive); - hpt370_clear_engine(drive); + hpt370_irq_timeout(drive); return __ide_dma_timeout(drive); } -static int hpt370_ide_dma_lostirq (ide_drive_t *drive) -{ - hpt370_lostirq_timeout(drive); - hpt370_clear_engine(drive); - return __ide_dma_lostirq(drive); -} - /* returns 1 if DMA IRQ issued, 0 otherwise */ static int hpt374_ide_dma_test_irq(ide_drive_t *drive) { @@ -1226,7 +1215,6 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) hwif->dma_start = &hpt370_ide_dma_start; hwif->ide_dma_end = &hpt370_ide_dma_end; hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; - hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq; } else hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;