Re: tulip (pnic) errors in 2.6.5-rc1

From: Jeff Garzik
Date: Thu Mar 18 2004 - 04:55:05 EST


Mikael Pettersson wrote:
2.6.5-rc1 causes my Netgear FA310TX to
fill the kernel log with messages like:

There doesn't seem to be anything interesting in the tulip driver changes, but who knows. Does reverting the attached patch help?

Note the pci_dma_sync_xxx changes in the patch may be required to build, I'm not sure.

Jeff


===== drivers/scsi/libata-core.c 1.26 vs edited =====
--- 1.26/drivers/scsi/libata-core.c Mon Mar 15 11:43:58 2004
+++ edited/drivers/scsi/libata-core.c Thu Mar 18 03:36:13 2004
@@ -2263,9 +2263,12 @@
mb(); /* make sure PRD table writes are visible to controller */
writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);

- /* specify data direction */
- /* FIXME: redundant to later start-dma command? */
- writeb(rw ? 0 : ATA_DMA_WR, mmio + ATA_DMA_CMD);
+ /* specify data direction, triple-check start bit is clear */
+ dmactl = readb(mmio + ATA_DMA_CMD);
+ dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
+ if (!rw)
+ dmactl |= ATA_DMA_WR;
+ writeb(dmactl, mmio + ATA_DMA_CMD);

/* clear interrupt, error bits */
host_stat = readb(mmio + ATA_DMA_STATUS);
@@ -2275,7 +2278,6 @@
ap->ops->exec_command(ap, &qc->tf);

/* start host DMA transaction */
- dmactl = readb(mmio + ATA_DMA_CMD);
writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD);

/* Strictly, one may wish to issue a readb() here, to
@@ -2308,9 +2310,12 @@
/* load PRD table addr. */
outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);

- /* specify data direction */
- /* FIXME: redundant to later start-dma command? */
- outb(rw ? 0 : ATA_DMA_WR, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ /* specify data direction, triple-check start bit is clear */
+ dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
+ if (!rw)
+ dmactl |= ATA_DMA_WR;
+ outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);

/* clear interrupt, error bits */
host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
@@ -2321,7 +2326,6 @@
ap->ops->exec_command(ap, &qc->tf);

/* start host DMA transaction */
- dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
outb(dmactl | ATA_DMA_START,
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
}
@@ -2344,14 +2348,16 @@
void *mmio = (void *) ap->ioaddr.bmdma_addr;

/* clear start/stop bit */
- writeb(0, mmio + ATA_DMA_CMD);
+ writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
+ mmio + ATA_DMA_CMD);

/* ack intr, err bits */
writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
mmio + ATA_DMA_STATUS);
} else {
/* clear start/stop bit */
- outb(0, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
+ ap->ioaddr.bmdma_addr + ATA_DMA_CMD);

/* ack intr, err bits */
outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,