]> err.no Git - linux-2.6/commitdiff
hpt366: clean up DMA timeout handling for HPT370
authorSergei Shtylyov <sshtylyov@ru.mvista.com>
Wed, 7 Feb 2007 17:18:13 +0000 (18:18 +0100)
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Wed, 7 Feb 2007 17:18:13 +0000 (18:18 +0100)
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 <sshtylyov@ru.mvista.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
drivers/ide/pci/hpt366.c

index 7317defd8210a5c8ae75dbc62fd02d2b3b6262f1..9ad1531b60349bc5d11742372ee9fa943f2a6b00 100644 (file)
@@ -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 <andre@linux-ide.org>
  * 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
  *             <source@mvista.com>
  */
 
@@ -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;