1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ |
2 | /* |
3 | * UFS Transport SGIO v4 BSG Message Support |
4 | * |
5 | * Copyright (C) 2011-2013 Samsung India Software Operations |
6 | * Copyright (C) 2018 Western Digital Corporation |
7 | */ |
8 | #ifndef SCSI_BSG_UFS_H |
9 | #define SCSI_BSG_UFS_H |
10 | |
11 | #include <asm/byteorder.h> |
12 | #include <linux/types.h> |
13 | /* |
14 | * This file intended to be included by both kernel and user space |
15 | */ |
16 | |
17 | #define UFS_CDB_SIZE 16 |
18 | /* uic commands are 4DW long, per UFSHCI V2.1 paragraph 5.6.1 */ |
19 | #define UIC_CMD_SIZE (sizeof(__u32) * 4) |
20 | |
21 | enum ufs_bsg_msg_code { |
22 | UPIU_TRANSACTION_UIC_CMD = 0x1F, |
23 | UPIU_TRANSACTION_ARPMB_CMD, |
24 | }; |
25 | |
26 | /* UFS RPMB Request Message Types */ |
27 | enum ufs_rpmb_op_type { |
28 | UFS_RPMB_WRITE_KEY = 0x01, |
29 | UFS_RPMB_READ_CNT = 0x02, |
30 | UFS_RPMB_WRITE = 0x03, |
31 | UFS_RPMB_READ = 0x04, |
32 | UFS_RPMB_READ_RESP = 0x05, |
33 | UFS_RPMB_SEC_CONF_WRITE = 0x06, |
34 | UFS_RPMB_SEC_CONF_READ = 0x07, |
35 | UFS_RPMB_PURGE_ENABLE = 0x08, |
36 | UFS_RPMB_PURGE_STATUS_READ = 0x09, |
37 | }; |
38 | |
39 | /** |
40 | * struct utp_upiu_header - UPIU header structure |
41 | * @dword_0: UPIU header DW-0 |
42 | * @dword_1: UPIU header DW-1 |
43 | * @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. |
61 | */ |
62 | struct { |
63 | union { |
64 | struct { |
65 | __be32 ; |
66 | __be32 ; |
67 | __be32 ; |
68 | }; |
69 | struct { |
70 | __u8 ; |
71 | __u8 ; |
72 | __u8 ; |
73 | __u8 ; |
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 : 4; |
80 | #else |
81 | #error |
82 | #endif |
83 | union { |
84 | __u8 ; |
85 | __u8 ; |
86 | } __attribute__((packed)); |
87 | __u8 ; |
88 | __u8 ; |
89 | __u8 ; |
90 | __u8 ; |
91 | __be16 ; |
92 | }; |
93 | }; |
94 | }; |
95 | |
96 | /** |
97 | * struct utp_upiu_query - upiu request buffer structure for |
98 | * query request. |
99 | * @opcode: command to perform B-0 |
100 | * @idn: a value that indicates the particular type of data B-1 |
101 | * @index: Index to further identify data B-2 |
102 | * @selector: Index to further identify data B-3 |
103 | * @reserved_osf: spec reserved field B-4,5 |
104 | * @length: number of descriptor bytes to read/write B-6,7 |
105 | * @value: Attribute value to be written DW-5 |
106 | * @reserved: spec reserved DW-6,7 |
107 | */ |
108 | struct utp_upiu_query { |
109 | __u8 opcode; |
110 | __u8 idn; |
111 | __u8 index; |
112 | __u8 selector; |
113 | __be16 reserved_osf; |
114 | __be16 length; |
115 | __be32 value; |
116 | __be32 reserved[2]; |
117 | }; |
118 | |
119 | /** |
120 | * struct utp_upiu_query_v4_0 - upiu request buffer structure for |
121 | * query request >= UFS 4.0 spec. |
122 | * @opcode: command to perform B-0 |
123 | * @idn: a value that indicates the particular type of data B-1 |
124 | * @index: Index to further identify data B-2 |
125 | * @selector: Index to further identify data B-3 |
126 | * @osf4: spec field B-5 |
127 | * @osf5: spec field B 6,7 |
128 | * @osf6: spec field DW 8,9 |
129 | * @osf7: spec field DW 10,11 |
130 | */ |
131 | struct utp_upiu_query_v4_0 { |
132 | __u8 opcode; |
133 | __u8 idn; |
134 | __u8 index; |
135 | __u8 selector; |
136 | __u8 osf3; |
137 | __u8 osf4; |
138 | __be16 osf5; |
139 | __be32 osf6; |
140 | __be32 osf7; |
141 | __be32 reserved; |
142 | }; |
143 | |
144 | /** |
145 | * struct utp_upiu_cmd - Command UPIU structure |
146 | * @data_transfer_len: Data Transfer Length DW-3 |
147 | * @cdb: Command Descriptor Block CDB DW-4 to DW-7 |
148 | */ |
149 | struct utp_upiu_cmd { |
150 | __be32 exp_data_transfer_len; |
151 | __u8 cdb[UFS_CDB_SIZE]; |
152 | }; |
153 | |
154 | /** |
155 | * struct utp_upiu_req - general upiu request structure |
156 | * @header:UPIU header structure DW-0 to DW-2 |
157 | * @sc: fields structure for scsi command DW-3 to DW-7 |
158 | * @qr: fields structure for query request DW-3 to DW-7 |
159 | * @uc: use utp_upiu_query to host the 4 dwords of uic command |
160 | */ |
161 | struct utp_upiu_req { |
162 | struct utp_upiu_header ; |
163 | union { |
164 | struct utp_upiu_cmd sc; |
165 | struct utp_upiu_query qr; |
166 | struct utp_upiu_query uc; |
167 | }; |
168 | }; |
169 | |
170 | struct ufs_arpmb_meta { |
171 | __be16 req_resp_type; |
172 | __u8 nonce[16]; |
173 | __be32 write_counter; |
174 | __be16 addr_lun; |
175 | __be16 block_count; |
176 | __be16 result; |
177 | } __attribute__((__packed__)); |
178 | |
179 | struct ufs_ehs { |
180 | __u8 length; |
181 | __u8 ehs_type; |
182 | __be16 ehssub_type; |
183 | struct ufs_arpmb_meta meta; |
184 | __u8 mac_key[32]; |
185 | } __attribute__((__packed__)); |
186 | |
187 | /* request (CDB) structure of the sg_io_v4 */ |
188 | struct ufs_bsg_request { |
189 | __u32 msgcode; |
190 | struct utp_upiu_req upiu_req; |
191 | }; |
192 | |
193 | /* response (request sense data) structure of the sg_io_v4 */ |
194 | struct ufs_bsg_reply { |
195 | /* |
196 | * The completion result. Result exists in two forms: |
197 | * if negative, it is an -Exxx system errno value. There will |
198 | * be no further reply information supplied. |
199 | * else, it's the 4-byte scsi error result, with driver, host, |
200 | * msg and status fields. The per-msgcode reply structure |
201 | * will contain valid data. |
202 | */ |
203 | int result; |
204 | |
205 | /* If there was reply_payload, how much was received? */ |
206 | __u32 reply_payload_rcv_len; |
207 | |
208 | struct utp_upiu_req upiu_rsp; |
209 | }; |
210 | |
211 | struct ufs_rpmb_request { |
212 | struct ufs_bsg_request bsg_request; |
213 | struct ufs_ehs ehs_req; |
214 | }; |
215 | |
216 | struct ufs_rpmb_reply { |
217 | struct ufs_bsg_reply bsg_reply; |
218 | struct ufs_ehs ehs_rsp; |
219 | }; |
220 | #endif /* UFS_BSG_H */ |
221 | |