Commit 88e675e1 authored by Mark Lord's avatar Mark Lord Committed by Jeff Garzik

sata_mv: fix pmp drives not found

Part three of simplifying/fixing handling of the main_irq_mask register
to resolve unexpected interrupt issues observed in 2.6.26-rc*.

Partially fix a reported bug whereby we sometimes miss seeing drives on
a port-multiplier, as reported by Gwendal Grignou <gwendal@google.com>.

The problem was that we were receiving unexpected interrupts
during EH from POLLed commands while accessing port-multiplier registers.
These unexpected interrupts can be prevented by masking the DONE_IRQ bit
for the port whenever not operating in EDMA mode.

Also fix port_stop() to mask all port interrupts.
Signed-off-by: default avatarMark Lord <mlord@pobox.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent c4de573b
...@@ -908,6 +908,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, ...@@ -908,6 +908,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
mv_set_edma_ptrs(port_mmio, hpriv, pp); mv_set_edma_ptrs(port_mmio, hpriv, pp);
mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ);
writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS);
pp->pp_flags |= MV_PP_FLAG_EDMA_EN; pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
...@@ -1360,6 +1361,7 @@ static int mv_port_start(struct ata_port *ap) ...@@ -1360,6 +1361,7 @@ static int mv_port_start(struct ata_port *ap)
static void mv_port_stop(struct ata_port *ap) static void mv_port_stop(struct ata_port *ap)
{ {
mv_stop_edma(ap); mv_stop_edma(ap);
mv_enable_port_irqs(ap, 0);
mv_port_free_dma_mem(ap); mv_port_free_dma_mem(ap);
} }
...@@ -1601,6 +1603,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) ...@@ -1601,6 +1603,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
* shadow block, etc registers. * shadow block, etc registers.
*/ */
mv_stop_edma(ap); mv_stop_edma(ap);
mv_enable_port_irqs(ap, ERR_IRQ);
mv_pmp_select(ap, qc->dev->link->pmp); mv_pmp_select(ap, qc->dev->link->pmp);
return ata_sff_qc_issue(qc); return ata_sff_qc_issue(qc);
} }
...@@ -2800,7 +2803,7 @@ static void mv_eh_thaw(struct ata_port *ap) ...@@ -2800,7 +2803,7 @@ static void mv_eh_thaw(struct ata_port *ap)
hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport); hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport);
writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
mv_enable_port_irqs(ap, DONE_IRQ | ERR_IRQ); mv_enable_port_irqs(ap, ERR_IRQ);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment