[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>
This commit is contained in:
parent
c01e8a2312
commit
42ed893d80
1 changed files with 21 additions and 13 deletions
|
@ -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)
|
||||||
"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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue