From: Mark Lord <liml@rtr.ca>
Date: Sat, 17 May 2008 17:36:30 +0000 (-0400)
Subject: sata_mv: fix pmp drives not found
X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=88e675e193159b9891c1c576de4348eaf490f5d0;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git

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>
---

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,
 			writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
 
 		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);
 		pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
@@ -1360,6 +1361,7 @@ out_port_free_dma_mem:
 static void mv_port_stop(struct ata_port *ap)
 {
 	mv_stop_edma(ap);
+	mv_enable_port_irqs(ap, 0);
 	mv_port_free_dma_mem(ap);
 }
 
@@ -1601,6 +1603,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
 		 * shadow block, etc registers.
 		 */
 		mv_stop_edma(ap);
+		mv_enable_port_irqs(ap, ERR_IRQ);
 		mv_pmp_select(ap, qc->dev->link->pmp);
 		return ata_sff_qc_issue(qc);
 	}
@@ -2800,7 +2803,7 @@ static void mv_eh_thaw(struct ata_port *ap)
 	hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport);
 	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);
 }
 
 /**