forked from Minki/linux
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:
parent
3606a38069
commit
646a4da514
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user