aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2009-01-30 18:48:41 -0500
committerJeff Garzik <jgarzik@redhat.com>2009-03-24 22:02:38 -0400
commitf48765ccb48a62596b664aa88a2b0f943c12c0e1 (patch)
tree48894dfdc349b8c8010798f7725fbf30e5bdc629 /drivers/ata
parent00b81235aa0368f84c0e704bec4142cd8c516ad5 (diff)
sata_mv: restructure mv_qc_issue
Rearrange logic in mv_qc_issue() to handle protocols other than ATA_PROT_DMA, ATA_PROT_NCQ, and ATA_PROT_PIO. This is in preparation for later enabling ATAPI support. 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.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index fb3288bbd9fb..0c25f52249df 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)
1565 */ 1565 */
1566static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) 1566static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
1567{ 1567{
1568 static int limit_warnings = 10;
1568 struct ata_port *ap = qc->ap; 1569 struct ata_port *ap = qc->ap;
1569 void __iomem *port_mmio = mv_ap_base(ap); 1570 void __iomem *port_mmio = mv_ap_base(ap);
1570 struct mv_port_priv *pp = ap->private_data; 1571 struct mv_port_priv *pp = ap->private_data;
1571 u32 in_index; 1572 u32 in_index;
1573 unsigned int port_irqs = DONE_IRQ | ERR_IRQ;
1574
1575 switch (qc->tf.protocol) {
1576 case ATA_PROT_DMA:
1577 case ATA_PROT_NCQ:
1578 mv_start_edma(ap, port_mmio, pp, qc->tf.protocol);
1579 pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
1580 in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
1581
1582 /* Write the request in pointer to kick the EDMA to life */
1583 writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
1584 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
1585 return 0;
1572 1586
1573 if ((qc->tf.protocol != ATA_PROT_DMA) && 1587 case ATA_PROT_PIO:
1574 (qc->tf.protocol != ATA_PROT_NCQ)) {
1575 static int limit_warnings = 10;
1576 /* 1588 /*
1577 * Errata SATA#16, SATA#24: warn if multiple DRQs expected. 1589 * Errata SATA#16, SATA#24: warn if multiple DRQs expected.
1578 * 1590 *
@@ -1590,27 +1602,22 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
1590 ": attempting PIO w/multiple DRQ: " 1602 ": attempting PIO w/multiple DRQ: "
1591 "this may fail due to h/w errata\n"); 1603 "this may fail due to h/w errata\n");
1592 } 1604 }
1605 /* drop through */
1606 case ATAPI_PROT_PIO:
1607 port_irqs = ERR_IRQ; /* leave DONE_IRQ masked for PIO */
1608 /* drop through */
1609 default:
1593 /* 1610 /*
1594 * We're about to send a non-EDMA capable command to the 1611 * We're about to send a non-EDMA capable command to the
1595 * port. Turn off EDMA so there won't be problems accessing 1612 * port. Turn off EDMA so there won't be problems accessing
1596 * shadow block, etc registers. 1613 * shadow block, etc registers.
1597 */ 1614 */
1598 mv_stop_edma(ap); 1615 mv_stop_edma(ap);
1599 mv_enable_port_irqs(ap, ERR_IRQ); 1616 mv_edma_cfg(ap, 0, 0);
1617 mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs);
1600 mv_pmp_select(ap, qc->dev->link->pmp); 1618 mv_pmp_select(ap, qc->dev->link->pmp);
1601 return ata_sff_qc_issue(qc); 1619 return ata_sff_qc_issue(qc);
1602 } 1620 }
1603
1604 mv_start_edma(ap, port_mmio, pp, qc->tf.protocol);
1605
1606 pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
1607 in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
1608
1609 /* and write the request in pointer to kick the EDMA to life */
1610 writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
1611 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
1612
1613 return 0;
1614} 1621}
1615 1622
1616static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) 1623static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)