sata_mv: restructure mv_qc_issue
authorMark Lord <liml@rtr.ca>
Fri, 30 Jan 2009 23:48:41 +0000 (18:48 -0500)
committerJeff Garzik <jgarzik@redhat.com>
Wed, 25 Mar 2009 02:02:38 +0000 (22:02 -0400)
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>
drivers/ata/sata_mv.c

index fb3288b..0c25f52 100644 (file)
@@ -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)