| @@ -882,35 +882,7 @@ static inline u32 ufshcd_get_dme_attr_val(struct ufs_hba *hba) · 881 unmodified lines |
| 882 | 882 | static inline enum upiu_response_transaction |
| 883 | 883 | ufshcd_get_req_rsp(struct utp_upiu_rsp *ucd_rsp_ptr) |
| 884 | 884 | { |
| 885 | | − return be32_to_cpu(ucd_rsp_ptr->header.dword_0) >> 24; |
| 886 | | −} |
| 887 | | − |
| 888 | | −/** |
| 889 | | − * ufshcd_get_rsp_upiu_result - Get the result from response UPIU |
| 890 | | − * @ucd_rsp_ptr: pointer to response UPIU |
| 891 | | − * |
| 892 | | − * This function gets the response status and scsi_status from response UPIU |
| 893 | | − * |
| 894 | | − * Return: the response result code. |
| 895 | | − */ |
| 896 | | −static inline int |
| 897 | | −ufshcd_get_rsp_upiu_result(struct utp_upiu_rsp *ucd_rsp_ptr) |
| 898 | | −{ |
| 899 | | − return be32_to_cpu(ucd_rsp_ptr->header.dword_1) & MASK_RSP_UPIU_RESULT; |
| 900 | | −} |
| 901 | | − |
| 902 | | −/* |
| 903 | | − * ufshcd_get_rsp_upiu_data_seg_len - Get the data segment length |
| 904 | | − * from response UPIU |
| 905 | | − * @ucd_rsp_ptr: pointer to response UPIU |
| 906 | | − * |
| 907 | | − * Return: the data segment length. |
| 908 | | − */ |
| 909 | | −static inline unsigned int |
| 910 | | −ufshcd_get_rsp_upiu_data_seg_len(struct utp_upiu_rsp *ucd_rsp_ptr) |
| 911 | | −{ |
| 912 | | − return be32_to_cpu(ucd_rsp_ptr->header.dword_2) & |
| 913 | | − MASK_RSP_UPIU_DATA_SEG_LEN; |
| 885 | + return ucd_rsp_ptr->header.transaction_code; |
| 914 | 886 | } |
| 915 | 887 | |
| 916 | 888 | /** |
| @@ -924,8 +896,7 @@ ufshcd_get_rsp_upiu_data_seg_len(struct utp_upiu_rsp *ucd_rsp_ptr) · 7 unmodified lines |
| 924 | 896 | */ |
| 925 | 897 | static inline bool ufshcd_is_exception_event(struct utp_upiu_rsp *ucd_rsp_ptr) |
| 926 | 898 | { |
| 927 | | − return be32_to_cpu(ucd_rsp_ptr->header.dword_2) & |
| 928 | | − MASK_RSP_EXCEPTION_EVENT; |
| 899 | + return ucd_rsp_ptr->header.device_information & 1; |
| 929 | 900 | } |
| 930 | 901 | |
| 931 | 902 | /** |
| @@ -2224,10 +2195,11 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag, · 1292 unmodified lines |
| 2224 | 2195 | static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp) |
| 2225 | 2196 | { |
| 2226 | 2197 | u8 *const sense_buffer = lrbp->cmd->sense_buffer; |
| 2198 | + u16 resp_len; |
| 2227 | 2199 | int len; |
| 2228 | 2200 | |
| 2229 | | − if (sense_buffer && |
| 2230 | | − ufshcd_get_rsp_upiu_data_seg_len(lrbp->ucd_rsp_ptr)) { |
| 2201 | + resp_len = be16_to_cpu(lrbp->ucd_rsp_ptr->header.data_segment_length); |
| 2202 | + if (sense_buffer && resp_len) { |
| 2231 | 2203 | int len_to_copy; |
| 2232 | 2204 | |
| 2233 | 2205 | len = be16_to_cpu(lrbp->ucd_rsp_ptr->sr.sense_data_len); |
| @@ -2262,8 +2234,8 @@ int ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) · 28 unmodified lines |
| 2262 | 2234 | u16 buf_len; |
| 2263 | 2235 | |
| 2264 | 2236 | /* data segment length */ |
| 2265 | | − resp_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2) & |
| 2266 | | − MASK_QUERY_DATA_SEG_LEN; |
| 2237 | + resp_len = be16_to_cpu(lrbp->ucd_rsp_ptr->header |
| 2238 | + .data_segment_length); |
| 2267 | 2239 | buf_len = be16_to_cpu( |
| 2268 | 2240 | hba->dev_cmd.query.request.upiu_req.length); |
| 2269 | 2241 | if (likely(buf_len >= resp_len)) { |
| @@ -2636,15 +2608,13 @@ void ufshcd_prepare_utp_scsi_cmd_upiu(struct ufshcd_lrb *lrbp, u8 upiu_flags) · 366 unmodified lines |
| 2636 | 2608 | struct utp_upiu_req *ucd_req_ptr = lrbp->ucd_req_ptr; |
| 2637 | 2609 | unsigned short cdb_len; |
| 2638 | 2610 | |
| 2639 | | − /* command descriptor fields */ |
| 2640 | | − ucd_req_ptr->header.dword_0 = upiu_header_dword( |
| 2641 | | − UPIU_TRANSACTION_COMMAND, upiu_flags, |
| 2642 | | − lrbp->lun, lrbp->task_tag); |
| 2643 | | − ucd_req_ptr->header.dword_1 = upiu_header_dword( |
| 2644 | | − UPIU_COMMAND_SET_TYPE_SCSI, 0, 0, 0); |
| 2645 | | − |
| 2646 | | − /* Total EHS length and Data segment length will be zero */ |
| 2647 | | − ucd_req_ptr->header.dword_2 = 0; |
| 2611 | + ucd_req_ptr->header = (struct utp_upiu_header){ |
| 2612 | + .transaction_code = UPIU_TRANSACTION_COMMAND, |
| 2613 | + .flags = upiu_flags, |
| 2614 | + .lun = lrbp->lun, |
| 2615 | + .task_tag = lrbp->task_tag, |
| 2616 | + .command_set_type = UPIU_COMMAND_SET_TYPE_SCSI, |
| 2617 | + }; |
| 2648 | 2618 | |
| 2649 | 2619 | ucd_req_ptr->sc.exp_data_transfer_len = cpu_to_be32(cmd->sdb.length); |
| 2650 | 2620 | |
| @@ -2669,18 +2639,19 @@ static void ufshcd_prepare_utp_query_req_upiu(struct ufs_hba *hba, · 18 unmodified lines |
| 2669 | 2639 | u16 len = be16_to_cpu(query->request.upiu_req.length); |
| 2670 | 2640 | |
| 2671 | 2641 | /* Query request header */ |
| 2672 | | − ucd_req_ptr->header.dword_0 = upiu_header_dword( |
| 2673 | | − UPIU_TRANSACTION_QUERY_REQ, upiu_flags, |
| 2674 | | − lrbp->lun, lrbp->task_tag); |
| 2675 | | − ucd_req_ptr->header.dword_1 = upiu_header_dword( |
| 2676 | | − 0, query->request.query_func, 0, 0); |
| 2677 | | − |
| 2678 | | − /* Data segment length only need for WRITE_DESC */ |
| 2679 | | − if (query->request.upiu_req.opcode == UPIU_QUERY_OPCODE_WRITE_DESC) |
| 2680 | | − ucd_req_ptr->header.dword_2 = |
| 2681 | | − upiu_header_dword(0, 0, len >> 8, (u8)len); |
| 2682 | | − else |
| 2683 | | − ucd_req_ptr->header.dword_2 = 0; |
| 2642 | + ucd_req_ptr->header = (struct utp_upiu_header){ |
| 2643 | + .transaction_code = UPIU_TRANSACTION_QUERY_REQ, |
| 2644 | + .flags = upiu_flags, |
| 2645 | + .lun = lrbp->lun, |
| 2646 | + .task_tag = lrbp->task_tag, |
| 2647 | + .query_function = query->request.query_func, |
| 2648 | + /* Data segment length only need for WRITE_DESC */ |
| 2649 | + .data_segment_length = |
| 2650 | + query->request.upiu_req.opcode == |
| 2651 | + UPIU_QUERY_OPCODE_WRITE_DESC ? |
| 2652 | + cpu_to_be16(len) : |
| 2653 | + 0, |
| 2654 | + }; |
| 2684 | 2655 | |
| 2685 | 2656 | /* Copy the Query Request buffer as is */ |
| 2686 | 2657 | memcpy(&ucd_req_ptr->qr, &query->request.upiu_req, |
| @@ -2699,12 +2670,10 @@ static inline void ufshcd_prepare_utp_nop_upiu(struct ufshcd_lrb *lrbp) · 12 unmodified lines |
| 2699 | 2670 | |
| 2700 | 2671 | memset(ucd_req_ptr, 0, sizeof(struct utp_upiu_req)); |
| 2701 | 2672 | |
| 2702 | | − /* command descriptor fields */ |
| 2703 | | − ucd_req_ptr->header.dword_0 = upiu_header_dword( |
| 2704 | | − UPIU_TRANSACTION_NOP_OUT, 0, 0, lrbp->task_tag); |
| 2705 | | − /* clear rest of the fields of basic header */ |
| 2706 | | − ucd_req_ptr->header.dword_1 = 0; |
| 2707 | | − ucd_req_ptr->header.dword_2 = 0; |
| 2673 | + ucd_req_ptr->header = (struct utp_upiu_header){ |
| 2674 | + .transaction_code = UPIU_TRANSACTION_NOP_OUT, |
| 2675 | + .task_tag = lrbp->task_tag, |
| 2676 | + }; |
| 2708 | 2677 | |
| 2709 | 2678 | memset(lrbp->ucd_rsp_ptr, 0, sizeof(struct utp_upiu_rsp)); |
| 2710 | 2679 | } |
| @@ -3008,13 +2977,6 @@ static int ufshcd_clear_cmd(struct ufs_hba *hba, u32 task_tag) · 297 unmodified lines |
| 3008 | 2977 | mask, ~mask, 1000, 1000); |
| 3009 | 2978 | } |
| 3010 | 2979 | |
| 3011 | | −static int |
| 3012 | | −ufshcd_check_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) |
| 3013 | | −{ |
| 3014 | | − return ufshcd_get_rsp_upiu_result(lrbp->ucd_rsp_ptr) >> |
| 3015 | | − UPIU_RSP_CODE_OFFSET; |
| 3016 | | −} |
| 3017 | | − |
| 3018 | 2980 | /** |
| 3019 | 2981 | * ufshcd_dev_cmd_completion() - handles device management command responses |
| 3020 | 2982 | * @hba: per adapter instance |
| @@ -3039,11 +3001,13 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) · 18 unmodified lines |
| 3039 | 3001 | __func__, resp); |
| 3040 | 3002 | } |
| 3041 | 3003 | break; |
| 3042 | | − case UPIU_TRANSACTION_QUERY_RSP: |
| 3043 | | − err = ufshcd_check_query_response(hba, lrbp); |
| 3044 | | − if (!err) |
| 3004 | + case UPIU_TRANSACTION_QUERY_RSP: { |
| 3005 | + u8 response = lrbp->ucd_rsp_ptr->header.response; |
| 3006 | + |
| 3007 | + if (response == 0) |
| 3045 | 3008 | err = ufshcd_copy_query_response(hba, lrbp); |
| 3046 | 3009 | break; |
| 3010 | + } |
| 3047 | 3011 | case UPIU_TRANSACTION_REJECT_UPIU: |
| 3048 | 3012 | /* TODO: handle Reject UPIU Response */ |
| 3049 | 3013 | err = -EPERM; |
| @@ -5244,7 +5208,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, · 2194 unmodified lines |
| 5244 | 5208 | u8 upiu_flags; |
| 5245 | 5209 | u32 resid; |
| 5246 | 5210 | |
| 5247 | | − upiu_flags = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_0) >> 16; |
| 5211 | + upiu_flags = lrbp->ucd_rsp_ptr->header.flags; |
| 5248 | 5212 | resid = be32_to_cpu(lrbp->ucd_rsp_ptr->sr.residual_transfer_count); |
| 5249 | 5213 | /* |
| 5250 | 5214 | * Test !overflow instead of underflow to support UFS devices that do |
| @@ -5257,8 +5221,8 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, · 6 unmodified lines |
| 5257 | 5221 | ocs = ufshcd_get_tr_ocs(lrbp, cqe); |
| 5258 | 5222 | |
| 5259 | 5223 | if (hba->quirks & UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR) { |
| 5260 | | − if (be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_1) & |
| 5261 | | − MASK_RSP_UPIU_RESULT) |
| 5224 | + if (lrbp->ucd_rsp_ptr->header.response || |
| 5225 | + lrbp->ucd_rsp_ptr->header.status) |
| 5262 | 5226 | ocs = OCS_SUCCESS; |
| 5263 | 5227 | } |
| 5264 | 5228 | |
| @@ -5267,17 +5231,11 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, · 2 unmodified lines |
| 5267 | 5231 | hba->ufs_stats.last_hibern8_exit_tstamp = ktime_set(0, 0); |
| 5268 | 5232 | switch (ufshcd_get_req_rsp(lrbp->ucd_rsp_ptr)) { |
| 5269 | 5233 | case UPIU_TRANSACTION_RESPONSE: |
| 5270 | | − /* |
| 5271 | | − * get the response UPIU result to extract |
| 5272 | | − * the SCSI command status |
| 5273 | | − */ |
| 5274 | | − result = ufshcd_get_rsp_upiu_result(lrbp->ucd_rsp_ptr); |
| 5275 | | − |
| 5276 | 5234 | /* |
| 5277 | 5235 | * get the result based on SCSI status response |
| 5278 | 5236 | * to notify the SCSI midlayer of the command status |
| 5279 | 5237 | */ |
| 5280 | | − scsi_status = result & MASK_SCSI_STATUS; |
| 5238 | + scsi_status = lrbp->ucd_rsp_ptr->header.status; |
| 5281 | 5239 | result = ufshcd_scsi_cmd_status(lrbp, scsi_status); |
| 5282 | 5240 | |
| 5283 | 5241 | /* |
| @@ -6967,7 +6925,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, · 1683 unmodified lines |
| 6967 | 6925 | WARN_ONCE(task_tag < 0 || task_tag >= hba->nutmrs, "Invalid tag %d\n", |
| 6968 | 6926 | task_tag); |
| 6969 | 6927 | hba->tmf_rqs[req->tag] = req; |
| 6970 | | − treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag); |
| 6928 | + treq->upiu_req.req_header.task_tag = task_tag; |
| 6971 | 6929 | |
| 6972 | 6930 | memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq)); |
| 6973 | 6931 | ufshcd_vops_setup_task_mgmt(hba, task_tag, tm_function); |
| @@ -7034,9 +6992,9 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id, · 60 unmodified lines |
| 7034 | 6992 | treq.header.ocs = OCS_INVALID_COMMAND_STATUS; |
| 7035 | 6993 | |
| 7036 | 6994 | /* Configure task request UPIU */ |
| 7037 | | − treq.upiu_req.req_header.dword_0 = cpu_to_be32(lun_id << 8) | |
| 7038 | | − cpu_to_be32(UPIU_TRANSACTION_TASK_REQ << 24); |
| 7039 | | − treq.upiu_req.req_header.dword_1 = cpu_to_be32(tm_function << 16); |
| 6995 | + treq.upiu_req.req_header.transaction_code = UPIU_TRANSACTION_TASK_REQ; |
| 6996 | + treq.upiu_req.req_header.lun = lun_id; |
| 6997 | + treq.upiu_req.req_header.tm_function = tm_function; |
| 7040 | 6998 | |
| 7041 | 6999 | /* |
| 7042 | 7000 | * The host shall provide the same value for LUN field in the basic |
| @@ -7110,7 +7068,7 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, · 67 unmodified lines |
| 7110 | 7068 | lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; |
| 7111 | 7069 | |
| 7112 | 7070 | /* update the task tag in the request upiu */ |
| 7113 | | − req_upiu->header.dword_0 |= cpu_to_be32(tag); |
| 7071 | + req_upiu->header.task_tag = tag; |
| 7114 | 7072 | |
| 7115 | 7073 | ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE, 0); |
| 7116 | 7074 | |
| @@ -7143,8 +7101,8 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, · 26 unmodified lines |
| 7143 | 7101 | memcpy(rsp_upiu, lrbp->ucd_rsp_ptr, sizeof(*rsp_upiu)); |
| 7144 | 7102 | if (desc_buff && desc_op == UPIU_QUERY_OPCODE_READ_DESC) { |
| 7145 | 7103 | u8 *descp = (u8 *)lrbp->ucd_rsp_ptr + sizeof(*rsp_upiu); |
| 7146 | | − u16 resp_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2) & |
| 7147 | | − MASK_QUERY_DATA_SEG_LEN; |
| 7104 | + u16 resp_len = be16_to_cpu(lrbp->ucd_rsp_ptr->header |
| 7105 | + .data_segment_length); |
| 7148 | 7106 | |
| 7149 | 7107 | if (*buff_len >= resp_len) { |
| 7150 | 7108 | memcpy(desc_buff, descp, resp_len); |
| @@ -7192,7 +7150,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, · 41 unmodified lines |
| 7192 | 7150 | enum dev_cmd_type cmd_type = DEV_CMD_TYPE_QUERY; |
| 7193 | 7151 | struct utp_task_req_desc treq = { }; |
| 7194 | 7152 | enum utp_ocs ocs_value; |
| 7195 | | − u8 tm_f = be32_to_cpu(req_upiu->header.dword_1) >> 16 & MASK_TM_FUNC; |
| 7153 | + u8 tm_f = req_upiu->header.tm_function; |
| 7196 | 7154 | |
| 7197 | 7155 | switch (msgcode) { |
| 7198 | 7156 | case UPIU_TRANSACTION_NOP_OUT: |
| @@ -7284,7 +7242,9 @@ int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *r · 85 unmodified lines |
| 7284 | 7242 | ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, dir, 2); |
| 7285 | 7243 | |
| 7286 | 7244 | /* update the task tag and LUN in the request upiu */ |
| 7287 | | − req_upiu->header.dword_0 |= cpu_to_be32(upiu_flags << 16 | UFS_UPIU_RPMB_WLUN << 8 | tag); |
| 7245 | + req_upiu->header.flags = upiu_flags; |
| 7246 | + req_upiu->header.lun = UFS_UPIU_RPMB_WLUN; |
| 7247 | + req_upiu->header.task_tag = tag; |
| 7288 | 7248 | |
| 7289 | 7249 | /* copy the UPIU(contains CDB) request as it is */ |
| 7290 | 7250 | memcpy(lrbp->ucd_req_ptr, req_upiu, sizeof(*lrbp->ucd_req_ptr)); |
| @@ -7306,9 +7266,10 @@ int ufshcd_advanced_rpmb_req_handler(struct ufs_hba *hba, struct utp_upiu_req *r · 15 unmodified lines |
| 7306 | 7266 | /* Just copy the upiu response as it is */ |
| 7307 | 7267 | memcpy(rsp_upiu, lrbp->ucd_rsp_ptr, sizeof(*rsp_upiu)); |
| 7308 | 7268 | /* Get the response UPIU result */ |
| 7309 | | − result = ufshcd_get_rsp_upiu_result(lrbp->ucd_rsp_ptr); |
| 7269 | + result = (lrbp->ucd_rsp_ptr->header.response << 8) | |
| 7270 | + lrbp->ucd_rsp_ptr->header.status; |
| 7310 | 7271 | |
| 7311 | | − ehs_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2) >> 24; |
| 7272 | + ehs_len = lrbp->ucd_rsp_ptr->header.ehs_length; |
| 7312 | 7273 | /* |
| 7313 | 7274 | * Since the bLength in EHS indicates the total size of the EHS Header and EHS Data |
| 7314 | 7275 | * in 32 Byte units, the value of the bLength Request/Response for Advanced RPMB |
| @@ -10594,6 +10555,12 @@ static void ufshcd_check_header_layout(void) · 3279 unmodified lines |
| 10594 | 10555 | BUILD_BUG_ON(((__le32 *)&(struct request_desc_header){ |
| 10595 | 10556 | .dunu = cpu_to_le32(0xbadcafe)})[3] != |
| 10596 | 10557 | cpu_to_le32(0xbadcafe)); |
| 10558 | + |
| 10559 | + BUILD_BUG_ON(((u8 *)&(struct utp_upiu_header){ |
| 10560 | + .iid = 0xf })[4] != 0xf0); |
| 10561 | + |
| 10562 | + BUILD_BUG_ON(((u8 *)&(struct utp_upiu_header){ |
| 10563 | + .command_set_type = 0xf })[4] != 0xf); |
| 10597 | 10564 | } |
| 10598 | 10565 | |
| 10599 | 10566 | /* |