aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorMark Lord <mlord@pobox.com>2009-02-25 15:15:39 -0500
committerJeff Garzik <jgarzik@redhat.com>2009-03-24 22:02:40 -0400
commit42ed893d8011264f9945c2f54055b47c298ac53e (patch)
tree1923c308e4b103960b9fefb24c51e50a91739a4e /drivers/ata
parentc01e8a23128c746f23088db836bd4c820f3eb0b4 (diff)
[libata] sata_mv: Tighten up interrupt masking in mv_qc_issue()
so that it doesn't miss any protocols. Handle future cases where a qc is specially marked for polled issue or where a particular chip version prefers interrupts over polling for PIO. This mimics the polling decision logic from ata_sff_qc_issue(). Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_mv.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 3bfe721ba766..b74af945a2fe 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1809,7 +1809,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
1809 void __iomem *port_mmio = mv_ap_base(ap); 1809 void __iomem *port_mmio = mv_ap_base(ap);
1810 struct mv_port_priv *pp = ap->private_data; 1810 struct mv_port_priv *pp = ap->private_data;
1811 u32 in_index; 1811 u32 in_index;
1812 unsigned int port_irqs = DONE_IRQ | ERR_IRQ; 1812 unsigned int port_irqs;
1813 1813
1814 switch (qc->tf.protocol) { 1814 switch (qc->tf.protocol) {
1815 case ATA_PROT_DMA: 1815 case ATA_PROT_DMA:
@@ -1842,20 +1842,28 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
1842 "this may fail due to h/w errata\n"); 1842 "this may fail due to h/w errata\n");
1843 } 1843 }
1844 /* drop through */ 1844 /* drop through */
1845 case ATA_PROT_NODATA:
1845 case ATAPI_PROT_PIO: 1846 case ATAPI_PROT_PIO:
1846 port_irqs = ERR_IRQ; /* leave DONE_IRQ masked for PIO */ 1847 case ATAPI_PROT_NODATA:
1847 /* drop through */ 1848 if (ap->flags & ATA_FLAG_PIO_POLLING)
1848 default: 1849 qc->tf.flags |= ATA_TFLAG_POLLING;
1849 /* 1850 break;
1850 * We're about to send a non-EDMA capable command to the
1851 * port. Turn off EDMA so there won't be problems accessing
1852 * shadow block, etc registers.
1853 */
1854 mv_stop_edma(ap);
1855 mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs);
1856 mv_pmp_select(ap, qc->dev->link->pmp);
1857 return ata_sff_qc_issue(qc);
1858 } 1851 }
1852
1853 if (qc->tf.flags & ATA_TFLAG_POLLING)
1854 port_irqs = ERR_IRQ; /* mask device interrupt when polling */
1855 else
1856 port_irqs = ERR_IRQ | DONE_IRQ; /* unmask all interrupts */
1857
1858 /*
1859 * We're about to send a non-EDMA capable command to the
1860 * port. Turn off EDMA so there won't be problems accessing
1861 * shadow block, etc registers.
1862 */
1863 mv_stop_edma(ap);
1864 mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs);
1865 mv_pmp_select(ap, qc->dev->link->pmp);
1866 return ata_sff_qc_issue(qc);
1859} 1867}
1860 1868
1861static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) 1869static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)