aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2008-05-17 13:36:30 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-19 17:29:51 -0400
commit88e675e193159b9891c1c576de4348eaf490f5d0 (patch)
tree6af356c51ed75d862ac7aa731a9aeea49e340eb6 /drivers
parentc4de573b14d78ac83861d81d12977457d1e9cb6d (diff)
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: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/sata_mv.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index d0fd83635fa4..47dae7a2fbf4 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -908,6 +908,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
908 writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); 908 writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
909 909
910 mv_set_edma_ptrs(port_mmio, hpriv, pp); 910 mv_set_edma_ptrs(port_mmio, hpriv, pp);
911 mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ);
911 912
912 writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); 913 writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS);
913 pp->pp_flags |= MV_PP_FLAG_EDMA_EN; 914 pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
@@ -1360,6 +1361,7 @@ out_port_free_dma_mem:
1360static void mv_port_stop(struct ata_port *ap) 1361static void mv_port_stop(struct ata_port *ap)
1361{ 1362{
1362 mv_stop_edma(ap); 1363 mv_stop_edma(ap);
1364 mv_enable_port_irqs(ap, 0);
1363 mv_port_free_dma_mem(ap); 1365 mv_port_free_dma_mem(ap);
1364} 1366}
1365 1367
@@ -1601,6 +1603,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
1601 * shadow block, etc registers. 1603 * shadow block, etc registers.
1602 */ 1604 */
1603 mv_stop_edma(ap); 1605 mv_stop_edma(ap);
1606 mv_enable_port_irqs(ap, ERR_IRQ);
1604 mv_pmp_select(ap, qc->dev->link->pmp); 1607 mv_pmp_select(ap, qc->dev->link->pmp);
1605 return ata_sff_qc_issue(qc); 1608 return ata_sff_qc_issue(qc);
1606 } 1609 }
@@ -2800,7 +2803,7 @@ static void mv_eh_thaw(struct ata_port *ap)
2800 hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport); 2803 hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport);
2801 writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); 2804 writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
2802 2805
2803 mv_enable_port_irqs(ap, DONE_IRQ | ERR_IRQ); 2806 mv_enable_port_irqs(ap, ERR_IRQ);
2804} 2807}
2805 2808
2806/** 2809/**