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