Commit 42ed893d authored by Mark Lord's avatar Mark Lord Committed by Jeff Garzik

[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: default avatarMark Lord <mlord@pobox.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent c01e8a23
...@@ -1809,7 +1809,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) ...@@ -1809,7 +1809,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
void __iomem *port_mmio = mv_ap_base(ap); void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data; struct mv_port_priv *pp = ap->private_data;
u32 in_index; u32 in_index;
unsigned int port_irqs = DONE_IRQ | ERR_IRQ; unsigned int port_irqs;
switch (qc->tf.protocol) { switch (qc->tf.protocol) {
case ATA_PROT_DMA: case ATA_PROT_DMA:
...@@ -1842,20 +1842,28 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) ...@@ -1842,20 +1842,28 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
"this may fail due to h/w errata\n"); "this may fail due to h/w errata\n");
} }
/* drop through */ /* drop through */
case ATA_PROT_NODATA:
case ATAPI_PROT_PIO: case ATAPI_PROT_PIO:
port_irqs = ERR_IRQ; /* leave DONE_IRQ masked for PIO */ case ATAPI_PROT_NODATA:
/* drop through */ if (ap->flags & ATA_FLAG_PIO_POLLING)
default: qc->tf.flags |= ATA_TFLAG_POLLING;
/* break;
* We're about to send a non-EDMA capable command to the
* port. Turn off EDMA so there won't be problems accessing
* shadow block, etc registers.
*/
mv_stop_edma(ap);
mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs);
mv_pmp_select(ap, qc->dev->link->pmp);
return ata_sff_qc_issue(qc);
} }
if (qc->tf.flags & ATA_TFLAG_POLLING)
port_irqs = ERR_IRQ; /* mask device interrupt when polling */
else
port_irqs = ERR_IRQ | DONE_IRQ; /* unmask all interrupts */
/*
* We're about to send a non-EDMA capable command to the
* port. Turn off EDMA so there won't be problems accessing
* shadow block, etc registers.
*/
mv_stop_edma(ap);
mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs);
mv_pmp_select(ap, qc->dev->link->pmp);
return ata_sff_qc_issue(qc);
} }
static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
......
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