Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bf63de2 authored by Sergei Shtylyov's avatar Sergei Shtylyov Committed by Bartlomiej Zolnierkiewicz
Browse files

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: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 26ccb802
Loading
Loading
Loading
Loading
+25 −37
Original line number Diff line number Diff line
/*
 * 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>
 */

@@ -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
@@ -705,46 +722,18 @@ static int hpt370_ide_dma_end (ide_drive_t *drive)
		/* 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)
{
	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;