1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _SRP_H
28 #define	_SRP_H
29 
30 /*
31  * General SCSI RDMA Protocol generic defines
32  */
33 
34 #ifdef	__cplusplus
35 extern "C" {
36 #endif
37 
38 /*
39  * The following defines and structures are based on revision 16A of
40  * the T10 Project 1415-D SRP Protocol specification.
41  */
42 
43 /* Protocol revsion information */
44 enum {
45 	SRP_PROTOCOL		= 0x0108,
46 	SRP_PROTOCOL_VERSION	= 0x0001,
47 	SRP_REV_16A_IO_CLASS	= 0x0100,
48 	SRP_REV_10_IO_CLASS	= 0xFF00,	/* Old targets */
49 	SRP_IO_SUBCLASS		= 0x690E
50 };
51 
52 /* SRP memory descriptors; direct and indirect formats */
53 typedef struct srp_direct_desc_s {
54 	uint64_t	dd_vaddr;
55 	uint32_t	dd_hdl;
56 	uint32_t	dd_len;
57 } srp_direct_desc_t;
58 
59 #pragma pack(1)
60 typedef struct srp_indirect_desc_s {
61 	srp_direct_desc_t	id_table;
62 	uint32_t		id_len;
63 	srp_direct_desc_t	id_desc[1];
64 } srp_indirect_desc_t;
65 #pragma pack()
66 enum {
67 	SRP_DIRECT_BUFR_DESC	= 1 << 1,
68 	SRP_INDIRECT_BUFR_DESC	= 1 << 2
69 };
70 
71 /* General constants */
72 enum {
73 	SRP_CDB_SIZE		= 16,
74 	SRP_LUN_SIZE		= 8,
75 	SRP_PORT_ID_LEN		= 16,
76 	SRP_MIN_IU_SIZE		= 64
77 };
78 
79 /* SRP IU types */
80 enum {
81 	SRP_IU_LOGIN_REQ	= 0x00,
82 	SRP_IU_TASK_MGMT	= 0x01,
83 	SRP_IU_CMD		= 0x02,
84 	SRP_IU_I_LOGOUT		= 0x03,
85 	SRP_IU_LOGIN_RSP	= 0xC0,
86 	SRP_IU_RSP		= 0xC1,
87 	SRP_IU_LOGIN_REJ	= 0xC2,
88 	SRP_IU_T_LOGOUT		= 0x80,
89 	SRP_IU_CRED_REQ		= 0x81,
90 	SRP_IU_AER_REQ		= 0x82,
91 	SRP_IU_CRED_RSP		= 0x41,
92 	SRP_IU_AER_RSP		= 0x42
93 };
94 
95 /* SRP Initiator Login IU, 64 bytes */
96 enum {
97 	SRP_LOGIN_MULTI_CH_SINGLE		= 0,
98 	SRP_LOGIN_MULTI_CH_MULTIPLE		= 1,
99 	SRP_LOGIN_MULTI_CH_MASK			= 0x03,
100 	SRP_LOGIN_AESOL_NOTIFICATION		= 1 << 6,
101 	SRP_LOGIN_CRSOL_NOTIFICATION		= 1 << 5,
102 	SRP_LOGIN_LOSOL_NOTIFICATION		= 1 << 4
103 };
104 
105 typedef struct srp_login_req_s {
106 	uint8_t		lreq_type;
107 	uint8_t		lreq_rsvd[7];
108 	uint64_t	lreq_tag;
109 	uint32_t	lreq_req_it_iu_len;
110 	uint8_t		lreq_rsvd2[4];
111 	uint16_t	lreq_buf_format;
112 	uint8_t		lreq_req_flags;
113 	uint8_t		lreq_rsvd3[5];
114 	uint8_t		lreq_initiator_port_id[SRP_PORT_ID_LEN];
115 	uint8_t		lreq_target_port_id[SRP_PORT_ID_LEN];
116 } srp_login_req_t;
117 
118 /* SRP Task Management IU, 64 bytes. */
119 enum {
120 	SRP_TSK_MGMT_SUCCESSFUL_COMP_SOLNT	= 1 << 1,
121 	SRP_TSK_MGMT_UNSUCCESSFUL_COMP_SOLNT	= 1 << 2
122 };
123 
124 enum {
125 	SRP_TSK_ATTR_QTYPE_SIMPLE	= 0,
126 	SRP_TSK_ATTR_QTYPE_HEAD_OF_Q	= 1,
127 	SRP_TSK_ATTR_QTYPE_ORDERED	= 2,
128 	SRP_TSK_ATTR_QTYPE_ACA_Q_TAG	= 4
129 };
130 
131 enum {
132 	SRP_TSK_MGMT_ABORT_TASK		= 1,
133 	SRP_TSK_MGMT_ABORT_TASK_SET	= 2,
134 	SRP_TSK_MGMT_CLEAR_TASK_SET	= 4,
135 	SRP_TSK_MGMT_LUN_RESET		= 8,
136 	SRP_TSK_MGMT_CLEAR_ACA		= 0x40
137 };
138 
139 typedef struct srp_tsk_mgmt_s {
140 	uint8_t		tm_type;
141 	uint8_t		tm_not_flags;
142 	uint8_t		tm_rsvd[6];
143 	uint64_t	tm_tag;
144 	uint8_t		tm_rsvd2[4];
145 	uint8_t		tm_lun[8];
146 	uint8_t		tm_rsvd3[2];
147 	uint8_t		tm_function;
148 	uint8_t		tm_rsvd4;
149 	uint64_t	tm_task_tag;
150 	uint8_t		tm_rsvd5[8];
151 } srp_tsk_mgmt_t;
152 
153 /* SRP Command Request IU, 48 bytes minimum */
154 enum {
155 	SRP_DATA_DESC_NONE		= 0,
156 	SRP_DATA_DESC_DIRECT		= 1,
157 	SRP_DATA_DESC_INDIRECT		= 2
158 };
159 
160 #pragma pack(1)
161 typedef struct srp_cmd_req_s {
162 	uint8_t		cr_type;
163 	uint8_t		cr_not_flags;
164 	uint8_t		cr_rsvd[3];
165 	uint8_t		cr_buf_fmt;
166 	uint8_t		cr_docnt;
167 	uint8_t		cr_dicnt;
168 	uint64_t	cr_tag;
169 	uint8_t		cr_rsvd2[4];
170 	uint8_t		cr_lun[8];
171 	uint8_t		cr_rsvd3;
172 	uint8_t		cr_task_attr;
173 	uint8_t		cr_rsvd4;
174 	uint8_t		cr_add_cdb_len;
175 	uint8_t		cr_cdb[SRP_CDB_SIZE];
176 	uint8_t		cr_add_data;
177 } srp_cmd_req_t;
178 #pragma pack()
179 
180 /* SRP Initiator Logout IU, 16 bytes */
181 typedef struct srp_i_logout_s {
182 	uint8_t		il_type;
183 	uint8_t		il_rsvd[7];
184 	uint64_t	il_tag;
185 } srp_i_logout_t;
186 
187 /* SRP Login Response IU, 52 bytes */
188 enum {
189 	SRP_MULTI_CH_RESULT_NO_EXISTING		= 0,
190 	SRP_MULTI_CH_RESULT_TERM_EXISTING	= 1,
191 	SRP_MULTI_CH_RESULT_EXISTING_EXISTS  	= 1 << 1,
192 	SRP_SOLNT_SUPPORTED			= 1 << 4
193 };
194 
195 #define	SRP_LOGIN_RSP_SIZE	52
196 
197 typedef struct srp_login_rsp_s {
198 	uint8_t		lrsp_type;
199 	uint8_t		lrsp_rsvd[3];
200 	uint32_t	lrsp_req_limit_delta;
201 	uint64_t	lrsp_tag;
202 	uint32_t	lrsp_max_it_iu_len;
203 	uint32_t	lrsp_max_ti_iu_len;
204 	uint16_t	lrsp_sup_buf_format;
205 	uint8_t		lrsp_rsp_flags;
206 	uint8_t		lrsp_rsvd2[25];
207 } srp_login_rsp_t;
208 
209 /* SRP Response IU, 36 byte minimum */
210 enum {
211 	SRP_RSP_SOLICITED_NOTIFICATION = 1
212 };
213 
214 enum {
215 	SRP_RSP_VALID		= 1,
216 	SRP_RSP_SNS_VALID	= 1 << 1,
217 	SRP_RSP_DO_OVER		= 1 << 2,
218 	SRP_RSP_DO_UNDER	= 1 << 3,
219 	SRP_RSP_DI_OVER		= 1 << 4,
220 	SRP_RSP_DI_UNDER	= 1 << 5
221 };
222 
223 /* Additional response data used for task mgmt responses */
224 enum {
225 	SRP_TM_SUCCESS		= 0,
226 	SRP_TM_REQ_INVALID	= 2,
227 	SRP_TM_NOT_SUPPORTED	= 4,
228 	SRP_TM_FAILED		= 5
229 };
230 
231 typedef struct srp_rsp_data_s {
232 	uint8_t		rd_rsvd[3];
233 	uint8_t		rd_rsp_status;
234 } srp_rsp_data_t;
235 
236 #define	SRP_RSP_SIZE		36
237 
238 typedef struct srp_rsp_s {
239 	uint8_t		rsp_type;
240 	uint8_t		rsp_sol_not;
241 	uint8_t		rsp_rsvd[2];
242 	uint32_t	rsp_req_limit_delta;
243 	uint64_t	rsp_tag;
244 	uint8_t		rsp_rsvd2[2];
245 	uint8_t		rsp_flags;
246 	uint8_t		rsp_status;
247 	uint32_t	rsp_do_resid_cnt;
248 	uint32_t	rsp_di_resid_cnt;
249 	uint32_t	rsp_sense_data_len;
250 	uint32_t	rsp_data_len;
251 } srp_rsp_t;
252 
253 /* SRP Login Reject IU, 32 bytes */
254 enum {
255 	SRP_LOGIN_REJ_NO_REASON				= 0x00010000,
256 	SRP_LOGIN_REJ_INSUFFICIENT_CH_RESOURCES		= 0x00010001,
257 	SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE	= 0x00010002,
258 	SRP_LOGIN_REJ_UNABLE_TO_ASSOCIATE_I_T_NEXUS	= 0x00010003,
259 	SRP_LOGIN_REJ_REQ_BUF_FORMAT_NOT_SUPPORTED	= 0x00010004,
260 	SRP_LOGIN_REJ_MULTI_CH_NOT_SUPPORTED		= 0x00010005,
261 	SRP_LOGIN_REJ_INIT_CH_LIMIT			= 0x00010006
262 };
263 
264 typedef struct srp_login_rej_s {
265 	uint8_t		lrej_type;
266 	uint8_t		lrej_rsvd[3];
267 	uint32_t	lrej_reason;
268 	uint64_t	lrej_tag;
269 	uint8_t		lrej_rsvd2[8];
270 	uint16_t	lrej_sup_buf_format;
271 	uint8_t		lrej_rsvd3[6];
272 } srp_login_rej_t;
273 
274 /* SRP Target Logout IU, 16 bytes */
275 enum {
276 	SRP_T_LOGOUT_NO_REASON			= 0,
277 	SRP_T_LOGOUT_INACTIVE			= 1,
278 	SRP_T_LOGOUT_INVALID_IU_TYPE		= 2,
279 	SRP_T_LOGOUT_UNEXPECTED_INITIATOR_RSP	= 3,
280 	SRP_T_LOGOUT_MULTI_CHANNEL_ACTION	= 4,
281 	SRP_T_LOGOUT_UNSUPPORTED_DO_FORMAT	= 6,
282 	SRP_T_LOGOUT_UNSUPPORTED_DI_FORMAT	= 7,
283 	SRP_T_LOGOUT_INVALID_IU_LENGTH		= 8
284 };
285 
286 typedef struct srp_t_logout_s {
287 	uint8_t		tl_type;
288 	uint8_t		tl_sol_not;
289 	uint8_t		tl_rsvd[2];
290 	uint32_t	tl_reason;
291 	uint64_t	tl_tag;
292 } srp_t_logout_t;
293 
294 #ifdef	__cplusplus
295 }
296 #endif
297 
298 #endif /* _SRP_H */
299