diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/sata_mv.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index fb3288bbd9f..0c25f52249d 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1565,14 +1565,26 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) */ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) { + static int limit_warnings = 10; struct ata_port *ap = qc->ap; void __iomem *port_mmio = mv_ap_base(ap); struct mv_port_priv *pp = ap->private_data; u32 in_index; + unsigned int port_irqs = DONE_IRQ | ERR_IRQ; + + switch (qc->tf.protocol) { + case ATA_PROT_DMA: + case ATA_PROT_NCQ: + mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); + pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; + in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT; + + /* Write the request in pointer to kick the EDMA to life */ + writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index, + port_mmio + EDMA_REQ_Q_IN_PTR_OFS); + return 0; - if ((qc->tf.protocol != ATA_PROT_DMA) && - (qc->tf.protocol != ATA_PROT_NCQ)) { - static int limit_warnings = 10; + case ATA_PROT_PIO: /* * Errata SATA#16, SATA#24: warn if multiple DRQs expected. * @@ -1590,27 +1602,22 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) ": attempting PIO w/multiple DRQ: " "this may fail due to h/w errata\n"); } + /* drop through */ + case ATAPI_PROT_PIO: + port_irqs = ERR_IRQ; /* leave DONE_IRQ masked for PIO */ + /* drop through */ + default: /* * 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_enable_port_irqs(ap, ERR_IRQ); + mv_edma_cfg(ap, 0, 0); + 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); } - - mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); - - pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; - in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT; - - /* and write the request in pointer to kick the EDMA to life */ - writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index, - port_mmio + EDMA_REQ_Q_IN_PTR_OFS); - - return 0; } static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) |