libata-sff: separate out BMDMA qc_issue
Tejun Heo [Mon, 10 May 2010 19:41:42 +0000 (21:41 +0200)]
Separate out ata_bmdma_qc_issue() from ata_sff_qc_issue() such that
ata_sff_qc_issue() only deals with non-BMDMA SFF protocols (PIO and
nodata) while ata_bmdma_qc_issue() deals with the BMDMA protocols and
uses ata_sff_qc_issue() for non-DMA commands.  All the users are
updated accordingly.

Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

drivers/ata/libata-sff.c
drivers/ata/pata_acpi.c
drivers/ata/pata_cs5530.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_it821x.c
drivers/ata/pata_oldpiix.c
drivers/ata/pata_radisys.c
drivers/ata/pata_sc1200.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
include/linux/libata.h

index 6f52b59..19ddf92 100644 (file)
@@ -1379,15 +1379,11 @@ fsm_start:
 }
 
 /**
- *     ata_sff_qc_issue - issue taskfile to device in proto-dependent manner
+ *     ata_sff_qc_issue - issue taskfile to a SFF controller
  *     @qc: command to issue to device
  *
- *     Using various libata functions and hooks, this function
- *     starts an ATA command.  ATA commands are grouped into
- *     classes called "protocols", and issuing each type of protocol
- *     is slightly different.
- *
- *     May be used as the qc_issue() entry in ata_port_operations.
+ *     This function issues a PIO or NODATA command to a SFF
+ *     controller.
  *
  *     LOCKING:
  *     spin_lock_irqsave(host lock)
@@ -1402,23 +1398,8 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
        /* Use polling pio if the LLD doesn't handle
         * interrupt driven pio and atapi CDB interrupt.
         */
-       if (ap->flags & ATA_FLAG_PIO_POLLING) {
-               switch (qc->tf.protocol) {
-               case ATA_PROT_PIO:
-               case ATA_PROT_NODATA:
-               case ATAPI_PROT_PIO:
-               case ATAPI_PROT_NODATA:
-                       qc->tf.flags |= ATA_TFLAG_POLLING;
-                       break;
-               case ATAPI_PROT_DMA:
-                       if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
-                               /* see ata_dma_blacklisted() */
-                               BUG();
-                       break;
-               default:
-                       break;
-               }
-       }
+       if (ap->flags & ATA_FLAG_PIO_POLLING)
+               qc->tf.flags |= ATA_TFLAG_POLLING;
 
        /* select the device */
        ata_dev_select(ap, qc->dev->devno, 1, 0);
@@ -1437,15 +1418,6 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
 
                break;
 
-       case ATA_PROT_DMA:
-               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
-
-               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
-               ap->ops->bmdma_setup(qc);           /* set up bmdma */
-               ap->ops->bmdma_start(qc);           /* initiate bmdma */
-               ap->hsm_task_state = HSM_ST_LAST;
-               break;
-
        case ATA_PROT_PIO:
                if (qc->tf.flags & ATA_TFLAG_POLLING)
                        ata_qc_set_polling(qc);
@@ -1490,18 +1462,6 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
                        ata_sff_queue_pio_task(ap, 0);
                break;
 
-       case ATAPI_PROT_DMA:
-               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
-
-               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
-               ap->ops->bmdma_setup(qc);           /* set up bmdma */
-               ap->hsm_task_state = HSM_ST_FIRST;
-
-               /* send cdb by polling if no cdb interrupt */
-               if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
-                       ata_sff_queue_pio_task(ap, 0);
-               break;
-
        default:
                WARN_ON_ONCE(1);
                return AC_ERR_SYSTEM;
@@ -2618,6 +2578,7 @@ const struct ata_port_operations ata_bmdma_port_ops = {
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
 
        .qc_prep                = ata_bmdma_qc_prep,
+       .qc_issue               = ata_bmdma_qc_issue,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
@@ -2782,6 +2743,67 @@ void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc)
 EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep);
 
 /**
+ *     ata_bmdma_qc_issue - issue taskfile to a BMDMA controller
+ *     @qc: command to issue to device
+ *
+ *     This function issues a PIO, NODATA or DMA command to a
+ *     SFF/BMDMA controller.  PIO and NODATA are handled by
+ *     ata_sff_qc_issue().
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ *
+ *     RETURNS:
+ *     Zero on success, AC_ERR_* mask on failure
+ */
+unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+
+       /* see ata_dma_blacklisted() */
+       BUG_ON((ap->flags & ATA_FLAG_PIO_POLLING) &&
+              qc->tf.protocol == ATAPI_PROT_DMA);
+
+       /* defer PIO handling to sff_qc_issue */
+       if (!ata_is_dma(qc->tf.protocol))
+               return ata_sff_qc_issue(qc);
+
+       /* select the device */
+       ata_dev_select(ap, qc->dev->devno, 1, 0);
+
+       /* start the command */
+       switch (qc->tf.protocol) {
+       case ATA_PROT_DMA:
+               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
+
+               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
+               ap->ops->bmdma_setup(qc);           /* set up bmdma */
+               ap->ops->bmdma_start(qc);           /* initiate bmdma */
+               ap->hsm_task_state = HSM_ST_LAST;
+               break;
+
+       case ATAPI_PROT_DMA:
+               WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
+
+               ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
+               ap->ops->bmdma_setup(qc);           /* set up bmdma */
+               ap->hsm_task_state = HSM_ST_FIRST;
+
+               /* send cdb by polling if no cdb interrupt */
+               if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
+                       ata_sff_queue_pio_task(ap, 0);
+               break;
+
+       default:
+               WARN_ON(1);
+               return AC_ERR_SYSTEM;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue);
+
+/**
  *     ata_bmdma_error_handler - Stock error handler for BMDMA controller
  *     @ap: port to handle error for
  *
index 1a5a309..066b9f3 100644 (file)
@@ -172,7 +172,7 @@ static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
        struct pata_acpi *acpi = ap->private_data;
 
        if (acpi->gtm.flags & 0x10)
-               return ata_sff_qc_issue(qc);
+               return ata_bmdma_qc_issue(qc);
 
        if (adev != acpi->last) {
                pacpi_set_piomode(ap, adev);
@@ -180,7 +180,7 @@ static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
                        pacpi_set_dmamode(ap, adev);
                acpi->last = adev;
        }
-       return ata_sff_qc_issue(qc);
+       return ata_bmdma_qc_issue(qc);
 }
 
 /**
index 4b9a66f..e809a42 100644 (file)
@@ -156,7 +156,7 @@ static unsigned int cs5530_qc_issue(struct ata_queued_cmd *qc)
                        cs5530_set_dmamode(ap, adev);
        }
 
-       return ata_sff_qc_issue(qc);
+       return ata_bmdma_qc_issue(qc);
 }
 
 static struct scsi_host_template cs5530_sht = {
index 01457b2..8b95aeb 100644 (file)
@@ -320,7 +320,7 @@ static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc)
 
                hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23);
        }
-       return ata_sff_qc_issue(qc);
+       return ata_bmdma_qc_issue(qc);
 }
 
 static struct scsi_host_template hpt3x2n_sht = {
index 8d73438..2bd2b00 100644 (file)
@@ -430,7 +430,7 @@ static unsigned int it821x_smart_qc_issue(struct ata_queued_cmd *qc)
                case 0xFC:      /* Internal 'report rebuild state' */
                /* Arguably should just no-op this one */
                case ATA_CMD_SET_FEATURES:
-                       return ata_sff_qc_issue(qc);
+                       return ata_bmdma_qc_issue(qc);
        }
        printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command);
        return AC_ERR_DEV;
@@ -448,7 +448,7 @@ static unsigned int it821x_smart_qc_issue(struct ata_queued_cmd *qc)
 static unsigned int it821x_passthru_qc_issue(struct ata_queued_cmd *qc)
 {
        it821x_passthru_dev_select(qc->ap, qc->dev->devno);
-       return ata_sff_qc_issue(qc);
+       return ata_bmdma_qc_issue(qc);
 }
 
 /**
index 5f6aba7..988ef26 100644 (file)
@@ -200,7 +200,7 @@ static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc)
                if (ata_dma_enabled(adev))
                        oldpiix_set_dmamode(ap, adev);
        }
-       return ata_sff_qc_issue(qc);
+       return ata_bmdma_qc_issue(qc);
 }
 
 
index fc96022..a5fa388 100644 (file)
@@ -179,7 +179,7 @@ static unsigned int radisys_qc_issue(struct ata_queued_cmd *qc)
                                radisys_set_piomode(ap, adev);
                }
        }
-       return ata_sff_qc_issue(qc);
+       return ata_bmdma_qc_issue(qc);
 }
 
 
index 599e648..6b5b63a 100644 (file)
@@ -174,7 +174,7 @@ static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc)
                        sc1200_set_dmamode(ap, adev);
        }
 
-       return ata_sff_qc_issue(qc);
+       return ata_bmdma_qc_issue(qc);
 }
 
 /**
index fb0d2c1..f3471bc 100644 (file)
@@ -2358,7 +2358,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
                if (IS_GEN_II(hpriv))
                        return mv_qc_issue_fis(qc);
        }
-       return ata_sff_qc_issue(qc);
+       return ata_bmdma_qc_issue(qc);
 }
 
 static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
index 4863a62..baa8f0d 100644 (file)
@@ -1468,7 +1468,7 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
                BUG_ON(!(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) &&
                        (qc->flags & ATA_QCFLAG_DMAMAP));
                nv_adma_register_mode(qc->ap);
-               return ata_sff_qc_issue(qc);
+               return ata_bmdma_qc_issue(qc);
        } else
                nv_adma_mode(qc->ap);
 
@@ -2088,7 +2088,7 @@ static unsigned int nv_swncq_qc_issue(struct ata_queued_cmd *qc)
        struct nv_swncq_port_priv *pp = ap->private_data;
 
        if (qc->tf.protocol != ATA_PROT_NCQ)
-               return ata_sff_qc_issue(qc);
+               return ata_bmdma_qc_issue(qc);
 
        DPRINTK("Enter\n");
 
index d973972..ee84e7e 100644 (file)
@@ -1626,6 +1626,7 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev,
 #endif /* CONFIG_PCI */
 
 extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc);
+extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc);
 extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc);
 extern void ata_bmdma_error_handler(struct ata_port *ap);
 extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);