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
35extern "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 */
44enum {
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 */
53typedef 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)
60typedef 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()
66enum {
67	SRP_DIRECT_BUFR_DESC	= 1 << 1,
68	SRP_INDIRECT_BUFR_DESC	= 1 << 2
69};
70
71/* General constants */
72enum {
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 */
80enum {
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 */
96enum {
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
105typedef 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. */
119enum {
120	SRP_TSK_MGMT_SUCCESSFUL_COMP_SOLNT	= 1 << 1,
121	SRP_TSK_MGMT_UNSUCCESSFUL_COMP_SOLNT	= 1 << 2
122};
123
124enum {
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
131enum {
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
139typedef 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 */
154enum {
155	SRP_DATA_DESC_NONE		= 0,
156	SRP_DATA_DESC_DIRECT		= 1,
157	SRP_DATA_DESC_INDIRECT		= 2
158};
159
160#pragma pack(1)
161typedef 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 */
181typedef 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 */
188enum {
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
197typedef 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 */
210enum {
211	SRP_RSP_SOLICITED_NOTIFICATION = 1
212};
213
214enum {
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 */
224enum {
225	SRP_TM_SUCCESS		= 0,
226	SRP_TM_REQ_INVALID	= 2,
227	SRP_TM_NOT_SUPPORTED	= 4,
228	SRP_TM_FAILED		= 5
229};
230
231typedef 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
238typedef 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 */
254enum {
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
264typedef 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 */
275enum {
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
286typedef 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