sata_mv ncq Mask transient IRQs

The chips can handle many transient errors internally without a software IRQ.
We now mask/ignore those interrupts here.  This is necessary for NCQ, later on.

Signed-off-by: Mark Lord <mlord@pobox.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
Mark Lord 2008-01-26 18:30:37 -05:00 committed by Jeff Garzik
parent 3606a38069
commit 646a4da514
1 changed files with 28 additions and 8 deletions

View File

@ -170,7 +170,7 @@ enum {
PCIE_IRQ_CAUSE_OFS = 0x1900,
PCIE_IRQ_MASK_OFS = 0x1910,
PCIE_UNMASK_ALL_IRQS = 0x70a, /* assorted bits */
PCIE_UNMASK_ALL_IRQS = 0x40a, /* assorted bits */
HC_MAIN_IRQ_CAUSE_OFS = 0x1d60,
HC_MAIN_IRQ_MASK_OFS = 0x1d64,
@ -244,14 +244,33 @@ enum {
EDMA_ERR_CRPB_PAR = (1 << 10), /* CRPB parity error */
EDMA_ERR_INTRL_PAR = (1 << 11), /* internal parity error */
EDMA_ERR_IORDY = (1 << 12), /* IORdy timeout */
EDMA_ERR_LNK_CTRL_RX = (0xf << 13), /* link ctrl rx error */
EDMA_ERR_LNK_CTRL_RX_2 = (1 << 15),
EDMA_ERR_LNK_CTRL_RX_0 = (1 << 13), /* transient: CRC err */
EDMA_ERR_LNK_CTRL_RX_1 = (1 << 14), /* transient: FIFO err */
EDMA_ERR_LNK_CTRL_RX_2 = (1 << 15), /* fatal: caught SYNC */
EDMA_ERR_LNK_CTRL_RX_3 = (1 << 16), /* transient: FIS rx err */
EDMA_ERR_LNK_DATA_RX = (0xf << 17), /* link data rx error */
EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), /* link ctrl tx error */
EDMA_ERR_LNK_CTRL_TX_0 = (1 << 21), /* transient: CRC err */
EDMA_ERR_LNK_CTRL_TX_1 = (1 << 22), /* transient: FIFO err */
EDMA_ERR_LNK_CTRL_TX_2 = (1 << 23), /* transient: caught SYNC */
EDMA_ERR_LNK_CTRL_TX_3 = (1 << 24), /* transient: caught DMAT */
EDMA_ERR_LNK_CTRL_TX_4 = (1 << 25), /* transient: FIS collision */
EDMA_ERR_LNK_DATA_TX = (0x1f << 26), /* link data tx error */
EDMA_ERR_TRANS_PROTO = (1 << 31), /* transport protocol error */
EDMA_ERR_OVERRUN_5 = (1 << 5),
EDMA_ERR_UNDERRUN_5 = (1 << 6),
EDMA_ERR_IRQ_TRANSIENT = EDMA_ERR_LNK_CTRL_RX_0 |
EDMA_ERR_LNK_CTRL_RX_1 |
EDMA_ERR_LNK_CTRL_RX_3 |
EDMA_ERR_LNK_CTRL_TX,
EDMA_EH_FREEZE = EDMA_ERR_D_PAR |
EDMA_ERR_PRD_PAR |
EDMA_ERR_DEV_DCON |
@ -1716,18 +1735,19 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
struct ata_host *host = dev_instance;
unsigned int hc, handled = 0, n_hcs;
void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
u32 irq_stat;
u32 irq_stat, irq_mask;
spin_lock(&host->lock);
irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS);
irq_mask = readl(mmio + HC_MAIN_IRQ_MASK_OFS);
/* check the cases where we either have nothing pending or have read
* a bogus register value which can indicate HW removal or PCI fault
*/
if (!irq_stat || (0xffffffffU == irq_stat))
return IRQ_NONE;
if (!(irq_stat & irq_mask) || (0xffffffffU == irq_stat))
goto out_unlock;
n_hcs = mv_get_hc_count(host->ports[0]->flags);
spin_lock(&host->lock);
if (unlikely(irq_stat & PCI_ERR)) {
mv_pci_error(host, mmio);
@ -2428,8 +2448,8 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs);
writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
/* unmask all EDMA error interrupts */
writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS);
/* unmask all non-transient EDMA error interrupts */
writelfl(~EDMA_ERR_IRQ_TRANSIENT, port_mmio + EDMA_ERR_IRQ_MASK_OFS);
VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n",
readl(port_mmio + EDMA_CFG_OFS),