libata: implement protocol tests
authorTejun Heo <htejun@gmail.com>
Tue, 27 Nov 2007 10:28:53 +0000 (19:28 +0900)
committerJeff Garzik <jeff@garzik.org>
Wed, 23 Jan 2008 10:24:10 +0000 (05:24 -0500)
Implement protocol tests - ata_is_atapi(), ata_is_nodata(),
ata_is_pio(), ata_is_dma(), ata_is_ncq() and ata_is_data() and use
them to replace is_atapi_taskfile() and hard coded protocol tests.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/sata_fsl.c
drivers/ata/sata_sil.c
drivers/ata/sata_sil24.c
drivers/scsi/libsas/sas_ata.c
include/linux/ata.h

index ef5e6b6e6e6968953a57b96a0201028bd7e55fb2..5eee91c73c90b984f6f86bbaa01196204ed7e11a 100644 (file)
@@ -1511,7 +1511,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        struct ahci_port_priv *pp = ap->private_data;
-       int is_atapi = is_atapi_taskfile(&qc->tf);
+       int is_atapi = ata_is_atapi(qc->tf.protocol);
        void *cmd_tbl;
        u32 opts;
        const u32 cmd_fis_len = 5; /* five dwords */
index bb9e025522ba1285f4a5c9c7362c0f2676b1f743..8c7af2c8e8d40e36587740ed998fb4ce780a6a85 100644 (file)
@@ -5358,7 +5358,7 @@ static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *q
                    (qc->tf.flags & ATA_TFLAG_WRITE))
                    return 1;
 
-               if (is_atapi_taskfile(&qc->tf) &&
+               if (ata_is_atapi(qc->tf.protocol) &&
                    !(qc->dev->flags & ATA_DFLAG_CDB_INTR))
                        return 1;
        }
@@ -5955,30 +5955,6 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active,
        return nr_done;
 }
 
-static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-
-       switch (qc->tf.protocol) {
-       case ATA_PROT_NCQ:
-       case ATA_PROT_DMA:
-       case ATA_PROT_ATAPI_DMA:
-               return 1;
-
-       case ATA_PROT_ATAPI:
-       case ATA_PROT_PIO:
-               if (ap->flags & ATA_FLAG_PIO_DMA)
-                       return 1;
-
-               /* fall through */
-
-       default:
-               return 0;
-       }
-
-       /* never reached */
-}
-
 /**
  *     ata_qc_issue - issue taskfile to device
  *     @qc: command to issue to device
@@ -5995,6 +5971,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        struct ata_link *link = qc->dev->link;
+       u8 prot = qc->tf.protocol;
 
        /* Make sure only one non-NCQ command is outstanding.  The
         * check is skipped for old EH because it reuses active qc to
@@ -6002,7 +5979,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
         */
        WARN_ON(ap->ops->error_handler && ata_tag_valid(link->active_tag));
 
-       if (qc->tf.protocol == ATA_PROT_NCQ) {
+       if (prot == ATA_PROT_NCQ) {
                WARN_ON(link->sactive & (1 << qc->tag));
 
                if (!link->sactive)
@@ -6018,7 +5995,8 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
        qc->flags |= ATA_QCFLAG_ACTIVE;
        ap->qc_active |= 1 << qc->tag;
 
-       if (ata_should_dma_map(qc)) {
+       if (ata_is_dma(prot) || (ata_is_pio(prot) &&
+                                (ap->flags & ATA_FLAG_PIO_DMA))) {
                if (qc->flags & ATA_QCFLAG_SG) {
                        if (ata_sg_setup(qc))
                                goto sg_err;
@@ -6217,8 +6195,8 @@ inline unsigned int ata_host_intr(struct ata_port *ap,
                 */
 
                /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
-                * The flag was turned on only for atapi devices.
-                * No need to check is_atapi_taskfile(&qc->tf) again.
+                * The flag was turned on only for atapi devices.  No
+                * need to check ata_is_atapi(qc->tf.protocol) again.
                 */
                if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
                        goto idle_irq;
index d015b4adcfe098402fd9e8b307a829f580e36636..a3c33f16542780ab91df8f8d5bb0dde6612132f1 100644 (file)
@@ -417,7 +417,7 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc)
        }
 
        /* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */
-       if (is_atapi_taskfile(&qc->tf)) {
+       if (ata_is_atapi(qc->tf.protocol)) {
                desc_info |= ATAPI_CMD;
                memset((void *)&cd->acmd, 0, 32);
                memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len);
index f5119bf40c24f0e9e65219208e2fd65a47137e1f..0b8191b52f97b8e3b1d032eca7a01e6d7069e898 100644 (file)
@@ -416,15 +416,14 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
                 */
 
                /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
-                * The flag was turned on only for atapi devices.
-                * No need to check is_atapi_taskfile(&qc->tf) again.
+                * The flag was turned on only for atapi devices.  No
+                * need to check ata_is_atapi(qc->tf.protocol) again.
                 */
                if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
                        goto err_hsm;
                break;
        case HSM_ST_LAST:
-               if (qc->tf.protocol == ATA_PROT_DMA ||
-                   qc->tf.protocol == ATA_PROT_ATAPI_DMA) {
+               if (ata_is_dma(qc->tf.protocol)) {
                        /* clear DMA-Start bit */
                        ap->ops->bmdma_stop(qc);
 
@@ -451,8 +450,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
        /* kick HSM in the ass */
        ata_hsm_move(ap, qc, status, 0);
 
-       if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
-                                      qc->tf.protocol == ATA_PROT_ATAPI_DMA))
+       if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol))
                ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2);
 
        return;
index 864c1c1b851138805c9aa11968d8a1567b7ab305..fdd3ceac329b045ebbc9ab9e9576e1a250f9cdfd 100644 (file)
@@ -852,9 +852,7 @@ static int sil24_qc_defer(struct ata_queued_cmd *qc)
         *   set.
         *
         */
-       int is_excl = (prot == ATA_PROT_ATAPI ||
-                      prot == ATA_PROT_ATAPI_NODATA ||
-                      prot == ATA_PROT_ATAPI_DMA ||
+       int is_excl = (ata_is_atapi(prot) ||
                       (qc->flags & ATA_QCFLAG_RESULT_TF));
 
        if (unlikely(ap->excl_link)) {
@@ -885,35 +883,21 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
 
        cb = &pp->cmd_block[sil24_tag(qc->tag)];
 
-       switch (qc->tf.protocol) {
-       case ATA_PROT_PIO:
-       case ATA_PROT_DMA:
-       case ATA_PROT_NCQ:
-       case ATA_PROT_NODATA:
+       if (!ata_is_atapi(qc->tf.protocol)) {
                prb = &cb->ata.prb;
                sge = cb->ata.sge;
-               break;
-
-       case ATA_PROT_ATAPI:
-       case ATA_PROT_ATAPI_DMA:
-       case ATA_PROT_ATAPI_NODATA:
+       } else {
                prb = &cb->atapi.prb;
                sge = cb->atapi.sge;
                memset(cb->atapi.cdb, 0, 32);
                memcpy(cb->atapi.cdb, qc->cdb, qc->dev->cdb_len);
 
-               if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {
+               if (ata_is_data(qc->tf.protocol)) {
                        if (qc->tf.flags & ATA_TFLAG_WRITE)
                                ctrl = PRB_CTRL_PACKET_WRITE;
                        else
                                ctrl = PRB_CTRL_PACKET_READ;
                }
-               break;
-
-       default:
-               prb = NULL;     /* shut up, gcc */
-               sge = NULL;
-               BUG();
        }
 
        prb->ctrl = cpu_to_le16(ctrl);
index 0829b55c64d23c90cf70b025a566447eed8635f0..831294de1d8d0598157944973c72a9fe19bfd325 100644 (file)
@@ -176,7 +176,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
 
        ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis);
        task->uldd_task = qc;
-       if (is_atapi_taskfile(&qc->tf)) {
+       if (ata_is_atapi(qc->tf.protocol)) {
                memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
                task->total_xfer_len = qc->nbytes + qc->pad_len;
                task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
index 3fbe6d7784abfc05f3ee5f8cecce66be2f28aae3..43fecf62773afa034a00cf46b4290edd3784f0bc 100644 (file)
@@ -324,6 +324,13 @@ enum {
        ATA_TFLAG_LBA           = (1 << 4), /* enable LBA */
        ATA_TFLAG_FUA           = (1 << 5), /* enable FUA */
        ATA_TFLAG_POLLING       = (1 << 6), /* set nIEN to 1 and use polling */
+
+       /* protocol flags */
+       ATA_PROT_FLAG_PIO       = (1 << 0), /* is PIO */
+       ATA_PROT_FLAG_DMA       = (1 << 1), /* is DMA */
+       ATA_PROT_FLAG_DATA      = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA,
+       ATA_PROT_FLAG_NCQ       = (1 << 2), /* is NCQ */
+       ATA_PROT_FLAG_ATAPI     = (1 << 3), /* is ATAPI */
 };
 
 enum ata_tf_protocols {
@@ -373,6 +380,63 @@ struct ata_taskfile {
        u8                      command;        /* IO operation */
 };
 
+/*
+ * protocol tests
+ */
+static inline unsigned int ata_prot_flags(u8 prot)
+{
+       switch (prot) {
+       case ATA_PROT_NODATA:
+               return 0;
+       case ATA_PROT_PIO:
+               return ATA_PROT_FLAG_PIO;
+       case ATA_PROT_DMA:
+               return ATA_PROT_FLAG_DMA;
+       case ATA_PROT_NCQ:
+               return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ;
+       case ATA_PROT_ATAPI_NODATA:
+               return ATA_PROT_FLAG_ATAPI;
+       case ATA_PROT_ATAPI:
+               return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO;
+       case ATA_PROT_ATAPI_DMA:
+               return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA;
+       }
+       return 0;
+}
+
+static inline int ata_is_atapi(u8 prot)
+{
+       return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI;
+}
+
+static inline int ata_is_nodata(u8 prot)
+{
+       return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA);
+}
+
+static inline int ata_is_pio(u8 prot)
+{
+       return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO;
+}
+
+static inline int ata_is_dma(u8 prot)
+{
+       return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA;
+}
+
+static inline int ata_is_ncq(u8 prot)
+{
+       return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ;
+}
+
+static inline int ata_is_data(u8 prot)
+{
+       return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA;
+}
+
+/*
+ * id tests
+ */
 #define ata_id_is_ata(id)      (((id)[0] & (1 << 15)) == 0)
 #define ata_id_has_lba(id)     ((id)[49] & (1 << 9))
 #define ata_id_has_dma(id)     ((id)[49] & (1 << 8))
@@ -594,13 +658,6 @@ static inline int atapi_command_packet_set(const u16 *dev_id)
        return (dev_id[0] >> 8) & 0x1f;
 }
 
-static inline int is_atapi_taskfile(const struct ata_taskfile *tf)
-{
-       return (tf->protocol == ATA_PROT_ATAPI) ||
-              (tf->protocol == ATA_PROT_ATAPI_NODATA) ||
-              (tf->protocol == ATA_PROT_ATAPI_DMA);
-}
-
 static inline int is_multi_taskfile(struct ata_taskfile *tf)
 {
        return (tf->command == ATA_CMD_READ_MULTI) ||