UFS 2.0 spec defines that the command type in transfer descriptor
is always 0x1 instead of different values as shown in UFSHC1.0/1.1.

This patch will distingwish v1.0/v1.1 UFSHC and later UFSHC when
setting CT

Signed-off-by: Chuanxiao Dong <chuanxiao.d...@intel.com>
---
 drivers/scsi/ufs/ufshcd.c |   27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index ba27215..8635d5d 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -706,16 +706,19 @@ static void ufshcd_disable_intr(struct ufs_hba *hba, u32 
intrs)
 /**
  * ufshcd_prepare_req_desc_hdr() - Fills the requests header
  * descriptor according to request
+ * @hba: per adapter instance
  * @lrbp: pointer to local reference block
  * @upiu_flags: flags required in the header
  * @cmd_dir: requests data direction
  */
-static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp,
-               u32 *upiu_flags, enum dma_data_direction cmd_dir)
+static void ufshcd_prepare_req_desc_hdr(struct ufs_hba *hba,
+               struct ufshcd_lrb *lrbp, u32 *upiu_flags,
+               enum dma_data_direction cmd_dir)
 {
        struct utp_transfer_req_desc *req_desc = lrbp->utr_descriptor_ptr;
        u32 data_direction;
        u32 dword_0;
+       u8 cmd_type;
 
        if (cmd_dir == DMA_FROM_DEVICE) {
                data_direction = UTP_DEVICE_TO_HOST;
@@ -728,8 +731,20 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb 
*lrbp,
                *upiu_flags = UPIU_CMD_FLAGS_NONE;
        }
 
-       dword_0 = data_direction | (lrbp->command_type
-                               << UPIU_COMMAND_TYPE_OFFSET);
+       /*
+        * Per UFSHCI spec v1.0/v1.1, Command Type in UTP transfer
+        * request descriptor is not the same as v2.0 spec.
+        * In v2.0 spec, Command Type is always 1, the other values
+        * are reserved
+        */
+       if (hba->ufs_version == UFSHCI_VERSION_10 ||
+                       hba->ufs_version == UFSHCI_VERSION_11)
+               cmd_type = lrbp->command_type;
+       else
+               cmd_type = UTP_CMD_TYPE_UFS;
+
+       dword_0 = data_direction | (cmd_type << UPIU_COMMAND_TYPE_OFFSET);
+
        if (lrbp->intr_cmd)
                dword_0 |= UTP_REQ_DESC_INT_CMD;
 
@@ -834,7 +849,7 @@ static int ufshcd_compose_upiu(struct ufs_hba *hba, struct 
ufshcd_lrb *lrbp)
        switch (lrbp->command_type) {
        case UTP_CMD_TYPE_SCSI:
                if (likely(lrbp->cmd)) {
-                       ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags,
+                       ufshcd_prepare_req_desc_hdr(hba, lrbp, &upiu_flags,
                                        lrbp->cmd->sc_data_direction);
                        ufshcd_prepare_utp_scsi_cmd_upiu(lrbp, upiu_flags);
                } else {
@@ -842,7 +857,7 @@ static int ufshcd_compose_upiu(struct ufs_hba *hba, struct 
ufshcd_lrb *lrbp)
                }
                break;
        case UTP_CMD_TYPE_DEV_MANAGE:
-               ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE);
+               ufshcd_prepare_req_desc_hdr(hba, lrbp, &upiu_flags, DMA_NONE);
                if (hba->dev_cmd.type == DEV_CMD_TYPE_QUERY)
                        ufshcd_prepare_utp_query_req_upiu(
                                        hba, lrbp, upiu_flags);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to