History

scsi: ufs: Simplify response header parsing

Make the code that parses UTP transfer request headers easier to read by using u8 instead of __be32 where appropriate.

Bart Van Assche committed 3 years ago

Commit 617bfaa1 parent 67a2a893 files · +115 −108Browse files

Unified · Split

3 files
  1. drivers/ufs/core/ufshcd.c +60 −93
  2. include/uapi/scsi/scsi_bsg_ufs.h +49 −3
  3. include/ufs/ufs.h +6 −12
drivers/ufs/core/ufshcd.c+60−93
@@ -882,35 +882,7 @@ static inline u32 ufshcd_get_dme_attr_val(struct ufs_hba *hba) · 881 unmodified lines
882882 static inline enum upiu_response_transaction
883883 ufshcd_get_req_rsp(struct utp_upiu_rsp *ucd_rsp_ptr)
884884 {
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;
914886 }
915887
916888 /**
@@ -924,8 +896,7 @@ ufshcd_get_rsp_upiu_data_seg_len(struct utp_upiu_rsp *ucd_rsp_ptr) · 7 unmodified lines
924896 */
925897 static inline bool ufshcd_is_exception_event(struct utp_upiu_rsp *ucd_rsp_ptr)
926898 {
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;
929900 }
930901
931902 /**
@@ -2224,10 +2195,11 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag, · 1292 unmodified lines
22242195 static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp)
22252196 {
22262197 u8 *const sense_buffer = lrbp->cmd->sense_buffer;
2198+ u16 resp_len;
22272199 int len;
22282200
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) {
22312203 int len_to_copy;
22322204
22332205 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
22622234 u16 buf_len;
22632235
22642236 /* 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);
22672239 buf_len = be16_to_cpu(
22682240 hba->dev_cmd.query.request.upiu_req.length);
22692241 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
26362608 struct utp_upiu_req *ucd_req_ptr = lrbp->ucd_req_ptr;
26372609 unsigned short cdb_len;
26382610
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+ };
26482618
26492619 ucd_req_ptr->sc.exp_data_transfer_len = cpu_to_be32(cmd->sdb.length);
26502620
@@ -2669,18 +2639,19 @@ static void ufshcd_prepare_utp_query_req_upiu(struct ufs_hba *hba, · 18 unmodified lines
26692639 u16 len = be16_to_cpu(query->request.upiu_req.length);
26702640
26712641 /* 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+ };
26842655
26852656 /* Copy the Query Request buffer as is */
26862657 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
26992670
27002671 memset(ucd_req_ptr, 0, sizeof(struct utp_upiu_req));
27012672
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+ };
27082677
27092678 memset(lrbp->ucd_rsp_ptr, 0, sizeof(struct utp_upiu_rsp));
27102679 }
@@ -3008,13 +2977,6 @@ static int ufshcd_clear_cmd(struct ufs_hba *hba, u32 task_tag) · 297 unmodified lines
30082977 mask, ~mask, 1000, 1000);
30092978 }
30102979
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−
30182980 /**
30192981 * ufshcd_dev_cmd_completion() - handles device management command responses
30202982 * @hba: per adapter instance
@@ -3039,11 +3001,13 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) · 18 unmodified lines
30393001 __func__, resp);
30403002 }
30413003 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)
30453008 err = ufshcd_copy_query_response(hba, lrbp);
30463009 break;
3010+ }
30473011 case UPIU_TRANSACTION_REJECT_UPIU:
30483012 /* TODO: handle Reject UPIU Response */
30493013 err = -EPERM;
@@ -5244,7 +5208,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, · 2194 unmodified lines
52445208 u8 upiu_flags;
52455209 u32 resid;
52465210
5247− upiu_flags = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_0) >> 16;
5211+ upiu_flags = lrbp->ucd_rsp_ptr->header.flags;
52485212 resid = be32_to_cpu(lrbp->ucd_rsp_ptr->sr.residual_transfer_count);
52495213 /*
52505214 * 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
52575221 ocs = ufshcd_get_tr_ocs(lrbp, cqe);
52585222
52595223 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)
52625226 ocs = OCS_SUCCESS;
52635227 }
52645228
@@ -5267,17 +5231,11 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, · 2 unmodified lines
52675231 hba->ufs_stats.last_hibern8_exit_tstamp = ktime_set(0, 0);
52685232 switch (ufshcd_get_req_rsp(lrbp->ucd_rsp_ptr)) {
52695233 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−
52765234 /*
52775235 * get the result based on SCSI status response
52785236 * to notify the SCSI midlayer of the command status
52795237 */
5280− scsi_status = result & MASK_SCSI_STATUS;
5238+ scsi_status = lrbp->ucd_rsp_ptr->header.status;
52815239 result = ufshcd_scsi_cmd_status(lrbp, scsi_status);
52825240
52835241 /*
@@ -6967,7 +6925,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, · 1683 unmodified lines
69676925 WARN_ONCE(task_tag < 0 || task_tag >= hba->nutmrs, "Invalid tag %d\n",
69686926 task_tag);
69696927 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;
69716929
69726930 memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq));
69736931 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
70346992 treq.header.ocs = OCS_INVALID_COMMAND_STATUS;
70356993
70366994 /* 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;
70406998
70416999 /*
70427000 * 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
71107068 lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE;
71117069
71127070 /* 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;
71147072
71157073 ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE, 0);
71167074
@@ -7143,8 +7101,8 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, · 26 unmodified lines
71437101 memcpy(rsp_upiu, lrbp->ucd_rsp_ptr, sizeof(*rsp_upiu));
71447102 if (desc_buff && desc_op == UPIU_QUERY_OPCODE_READ_DESC) {
71457103 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);
71487106
71497107 if (*buff_len >= resp_len) {
71507108 memcpy(desc_buff, descp, resp_len);
@@ -7192,7 +7150,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, · 41 unmodified lines
71927150 enum dev_cmd_type cmd_type = DEV_CMD_TYPE_QUERY;
71937151 struct utp_task_req_desc treq = { };
71947152 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;
71967154
71977155 switch (msgcode) {
71987156 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
72847242 ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, dir, 2);
72857243
72867244 /* 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;
72887248
72897249 /* copy the UPIU(contains CDB) request as it is */
72907250 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
73067266 /* Just copy the upiu response as it is */
73077267 memcpy(rsp_upiu, lrbp->ucd_rsp_ptr, sizeof(*rsp_upiu));
73087268 /* 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;
73107271
7311− ehs_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2) >> 24;
7272+ ehs_len = lrbp->ucd_rsp_ptr->header.ehs_length;
73127273 /*
73137274 * Since the bLength in EHS indicates the total size of the EHS Header and EHS Data
73147275 * 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
1059410555 BUILD_BUG_ON(((__le32 *)&(struct request_desc_header){
1059510556 .dunu = cpu_to_le32(0xbadcafe)})[3] !=
1059610557 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);
1059710564 }
1059810565
1059910566 /*
include/uapi/scsi/scsi_bsg_ufs.h+49−3
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #ifndef SCSI_BSG_UFS_H
99 #define SCSI_BSG_UFS_H
1010
11+#include <asm/byteorder.h>
1112 #include <linux/types.h>
1213 /*
1314 * This file intended to be included by both kernel and user space
@@ -40,11 +41,56 @@ enum ufs_rpmb_op_type { · 26 unmodified lines
4041 * @dword_0: UPIU header DW-0
4142 * @dword_1: UPIU header DW-1
4243 * @dword_2: UPIU header DW-2
44+ *
45+ * @transaction_code: Type of request or response. See also enum
46+ * upiu_request_transaction and enum upiu_response_transaction.
47+ * @flags: UPIU flags. The meaning of individual flags depends on the
48+ * transaction code.
49+ * @lun: Logical unit number.
50+ * @task_tag: Task tag.
51+ * @iid: Initiator ID.
52+ * @command_set_type: 0 for SCSI command set; 1 for UFS specific.
53+ * @tm_function: Task management function in case of a task management request
54+ * UPIU.
55+ * @query_function: Query function in case of a query request UPIU.
56+ * @response: 0 for success; 1 for failure.
57+ * @status: SCSI status if this is the header of a response to a SCSI command.
58+ * @ehs_length: EHS length in units of 32 bytes.
59+ * @device_information:
60+ * @data_segment_length: data segment length.
4361 */
4462 struct utp_upiu_header {
45− __be32 dword_0;
46− __be32 dword_1;
47− __be32 dword_2;
63+ union {
64+ struct {
65+ __be32 dword_0;
66+ __be32 dword_1;
67+ __be32 dword_2;
68+ };
69+ struct {
70+ __u8 transaction_code;
71+ __u8 flags;
72+ __u8 lun;
73+ __u8 task_tag;
74+#if defined(__BIG_ENDIAN)
75+ __u8 iid: 4;
76+ __u8 command_set_type: 4;
77+#elif defined(__LITTLE_ENDIAN)
78+ __u8 command_set_type: 4;
79+ __u8 iid: 4;
80+#else
81+#error
82+#endif
83+ union {
84+ __u8 tm_function;
85+ __u8 query_function;
86+ };
87+ __u8 response;
88+ __u8 status;
89+ __u8 ehs_length;
90+ __u8 device_information;
91+ __be16 data_segment_length;
92+ };
93+ };
4894 };
4995
5096 /**
include/ufs/ufs.h+6−12
@@ -15,6 +15,12 @@ · 14 unmodified lines
1515 #include <linux/types.h>
1616 #include <uapi/scsi/scsi_bsg_ufs.h>
1717
18+/*
19+ * Using static_assert() is not allowed in UAPI header files. Hence the check
20+ * in this header file of the size of struct utp_upiu_header.
21+ */
22+static_assert(sizeof(struct utp_upiu_header) == 12);
23+
1824 #define GENERAL_UPIU_REQUEST_SIZE (sizeof(struct utp_upiu_req))
1925 #define QUERY_DESC_MAX_SIZE 255
2026 #define QUERY_DESC_MIN_SIZE 2
@@ -23,11 +29,6 @@ · 2 unmodified lines
2329 (sizeof(struct utp_upiu_header)))
2430 #define UFS_SENSE_SIZE 18
2531
26−static inline __be32 upiu_header_dword(u8 byte3, u8 byte2, u8 byte1, u8 byte0)
27−{
28− return cpu_to_be32(byte3 << 24 | byte2 << 16 | byte1 << 8 | byte0);
29−}
30−
3132 /*
3233 * UFS device may have standard LUs and LUN id could be from 0x00 to
3334 * 0x7F. Standard LUs use "Peripheral Device Addressing Format".
@@ -477,14 +478,7 @@ enum { · 443 unmodified lines
477478 #define UPIU_RSP_CODE_OFFSET 8
478479
479480 enum {
480− MASK_SCSI_STATUS = 0xFF,
481− MASK_TASK_RESPONSE = 0xFF00,
482− MASK_RSP_UPIU_RESULT = 0xFFFF,
483− MASK_QUERY_DATA_SEG_LEN = 0xFFFF,
484− MASK_RSP_UPIU_DATA_SEG_LEN = 0xFFFF,
485− MASK_RSP_EXCEPTION_EVENT = 0x10000,
486481 MASK_TM_SERVICE_RESP = 0xFF,
487− MASK_TM_FUNC = 0xFF,
488482 };
489483
490484 /* Task management service response */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t