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 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 #ifndef _SYS_PPPT_IC_IF_H 25 #define _SYS_PPPT_IC_IF_H 26 27 #include <sys/stmf_defines.h> 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /* 34 * ALUA messaging and interconnect API. 35 */ 36 37 /* 38 * Message type. 39 */ 40 typedef enum { 41 STMF_ICM_REGISTER_PROXY_PORT = 0, 42 STMF_ICM_DEREGISTER_PROXY_PORT, 43 STMF_ICM_REGISTER_LUN, 44 STMF_ICM_DEREGISTER_LUN, 45 STMF_ICM_SCSI_CMD, 46 STMF_ICM_SCSI_DATA, 47 STMF_ICM_SCSI_DATA_XFER_DONE, 48 STMF_ICM_SCSI_STATUS, 49 STMF_ICM_R2T, 50 STMF_ICM_STATUS, 51 STMF_ICM_SESSION_CREATE, 52 STMF_ICM_SESSION_DESTROY, 53 STMF_ICM_ECHO_REQUEST, 54 STMF_ICM_ECHO_REPLY, 55 STMF_ICM_LUN_ACTIVE, 56 STMF_ICM_MAX_MSG_TYPE 57 } stmf_ic_msg_type_t; 58 59 /* 60 * Message id: uniquely identifies a message. 61 * This need not be a sequence number since we don't depend on 62 * messages being delivered in sequence. 63 */ 64 typedef uint64_t stmf_ic_msgid_t; 65 66 /* 67 * IC message. This is a container for the various specific message types. 68 * 69 * Note that the message contains a pointer to an nvlist. This pointer 70 * is valid only in the case of messages which are unmarshaled from 71 * nvlists. In that case, it's important to retain a pointer to the nvlist, 72 * since the message and the nvlist share data in the case of strings 73 * and array elements, and data in the message may be invalid if used 74 * after the nvlist is freed. 75 */ 76 typedef struct stmf_ic_msg { 77 stmf_ic_msg_type_t icm_msg_type; 78 stmf_ic_msgid_t icm_msgid; 79 nvlist_t *icm_nvlist; /* nvlist associated with the msg */ 80 void *icm_msg; /* ptr to the specific msg */ 81 } stmf_ic_msg_t; 82 83 /* 84 * Register port message. 85 */ 86 typedef struct { 87 scsi_devid_desc_t *icrp_port_id; 88 uint16_t icrp_relative_port_id; 89 /* opaque callback data */ 90 uint16_t icrp_cb_arg_len; 91 uint8_t *icrp_cb_arg; 92 } stmf_ic_reg_port_msg_t; 93 94 /* 95 * Deregister port message. 96 */ 97 typedef struct { 98 scsi_devid_desc_t *icdp_port_id; 99 /* opaque callback data */ 100 uint16_t icdp_cb_arg_len; 101 uint8_t *icdp_cb_arg; 102 } stmf_ic_dereg_port_msg_t; 103 104 /* 105 * Register/deregister lun message. 106 */ 107 typedef struct { 108 uint8_t icrl_lun_id[16]; 109 char *icrl_lu_provider_name; 110 /* opaque callback data */ 111 uint16_t icrl_cb_arg_len; 112 uint8_t *icrl_cb_arg; 113 } stmf_ic_reg_dereg_lun_msg_t; 114 115 /* 116 * SCSI cmd msg. 117 */ 118 typedef struct { 119 stmf_ic_msgid_t icsc_task_msgid; 120 scsi_devid_desc_t *icsc_ini_devid; 121 scsi_devid_desc_t *icsc_tgt_devid; 122 stmf_remote_port_t *icsc_rport; 123 uint8_t icsc_lun_id[16]; 124 /* 125 * fields from scsi_task_t 126 */ 127 uint64_t icsc_session_id; 128 uint8_t icsc_task_lun_no[8]; 129 uint32_t icsc_task_expected_xfer_length; 130 uint16_t icsc_task_cdb_length; 131 uint8_t *icsc_task_cdb; 132 uint8_t icsc_task_flags; /* See def. for task flags */ 133 uint8_t icsc_task_priority; /* As per SAM-3 */ 134 uint8_t icsc_task_mgmt_function; /* if is a TM req */ 135 uint32_t icsc_immed_data_len; 136 uint8_t *icsc_immed_data; 137 } stmf_ic_scsi_cmd_msg_t; 138 139 /* 140 * SCSI data message. 141 */ 142 typedef struct { 143 stmf_ic_msgid_t icsd_task_msgid; /* matches msgid of cmd */ 144 uint64_t icsd_session_id; 145 uint8_t icsd_lun_id[16]; 146 uint64_t icsd_data_len; 147 uint8_t *icsd_data; 148 } stmf_ic_scsi_data_msg_t; 149 150 /* 151 * SCSI data xfer done msg 152 */ 153 typedef struct { 154 stmf_ic_msgid_t icsx_task_msgid; /* matches msgid of cmd */ 155 uint64_t icsx_session_id; 156 stmf_status_t icsx_status; 157 } stmf_ic_scsi_data_xfer_done_msg_t; 158 159 /* 160 * SCSI status msg. 161 */ 162 typedef struct { 163 stmf_ic_msgid_t icss_task_msgid; /* matches msgid of cmd */ 164 uint64_t icss_session_id; 165 uint8_t icss_lun_id[16]; 166 uint8_t icss_response; /* was command processed? */ 167 uint8_t icss_status; 168 uint8_t icss_flags; /* TASK_SCTRL_OVER, TASK_SCTRL_UNDER */ 169 uint32_t icss_resid; 170 uint8_t icss_sense_len; 171 uint8_t *icss_sense; 172 } stmf_ic_scsi_status_msg_t; 173 174 /* 175 * Ready to transfer (r2t) msg. 176 */ 177 typedef struct { 178 stmf_ic_msgid_t icrt_task_msgid; /* matches msgid of cmd */ 179 uint64_t icrt_session_id; 180 uint32_t icrt_offset; 181 uint32_t icrt_length; 182 } stmf_ic_r2t_msg_t; 183 184 /* 185 * Status message: sent in response to messages other than SCSI messages. 186 */ 187 typedef struct { 188 stmf_ic_msg_type_t ics_msg_type; /* msg type rpting status on */ 189 stmf_ic_msgid_t ics_msgid; /* msgid reporting status on */ 190 stmf_status_t ics_status; 191 } stmf_ic_status_msg_t; 192 193 /* 194 * Session create/destroy message. 195 */ 196 typedef struct { 197 uint64_t icscd_session_id; 198 scsi_devid_desc_t *icscd_ini_devid; 199 scsi_devid_desc_t *icscd_tgt_devid; 200 stmf_remote_port_t *icscd_rport; 201 } stmf_ic_session_create_destroy_msg_t; 202 203 /* 204 * Echo request/reply message 205 */ 206 typedef struct { 207 uint8_t *icerr_data; 208 uint32_t icerr_datalen; 209 } stmf_ic_echo_request_reply_msg_t; 210 211 typedef enum { 212 STMF_IC_MSG_SUCCESS = 0, 213 STMF_IC_MSG_IC_DOWN, 214 STMF_IC_MSG_TIMED_OUT, 215 STMF_IC_MSG_INTERNAL_ERROR 216 } stmf_ic_msg_status_t; 217 218 /* 219 * Function prototypes. 220 * 221 * Note: Functions which are exported to other modules must have a function 222 * typedef and a prototype; the function type definition is used by 223 * the other module to import the symbol using ddi_modsym(). 224 */ 225 226 void stmf_ic_ioctl_cmd(void *ibuf, uint32_t ibuf_size); 227 228 /* Allocate a register port message */ 229 typedef 230 stmf_ic_msg_t *(*stmf_ic_reg_port_msg_alloc_func_t)( 231 scsi_devid_desc_t *port_id, 232 uint16_t relative_port_id, 233 uint16_t cb_arg_len, 234 uint8_t *cb_arg, 235 stmf_ic_msgid_t msgid); 236 237 stmf_ic_msg_t *stmf_ic_reg_port_msg_alloc( 238 scsi_devid_desc_t *port_id, 239 uint16_t relative_port_id, 240 uint16_t cb_arg_len, 241 uint8_t *cb_arg, 242 stmf_ic_msgid_t msgid); 243 244 /* Allocate a deregister port message */ 245 typedef 246 stmf_ic_msg_t *(*stmf_ic_dereg_port_msg_alloc_func_t)( 247 scsi_devid_desc_t *port_id, 248 uint16_t cb_arg_len, 249 uint8_t *cb_arg, 250 stmf_ic_msgid_t msgid); 251 252 stmf_ic_msg_t *stmf_ic_dereg_port_msg_alloc( 253 scsi_devid_desc_t *port_id, 254 uint16_t cb_arg_len, 255 uint8_t *cb_arg, 256 stmf_ic_msgid_t msgid); 257 258 259 /* Allocate a register lun message */ 260 typedef 261 stmf_ic_msg_t *(*stmf_ic_reg_lun_msg_alloc_func_t)( 262 uint8_t *icrl_lun_id, /* should be 16 bytes */ 263 char *lu_provider_name, 264 uint16_t cb_arg_len, 265 uint8_t *cb_arg, 266 stmf_ic_msgid_t msgid); 267 268 stmf_ic_msg_t *stmf_ic_reg_lun_msg_alloc( 269 uint8_t *icrl_lun_id, /* should be 16 bytes */ 270 char *lu_provider_name, 271 uint16_t cb_arg_len, 272 uint8_t *cb_arg, 273 stmf_ic_msgid_t msgid); 274 275 /* Allocate a lun active message */ 276 typedef 277 stmf_ic_msg_t *(*stmf_ic_lun_active_msg_alloc_func_t)( 278 uint8_t *icrl_lun_id, /* should be 16 bytes */ 279 char *lu_provider_name, 280 uint16_t cb_arg_len, 281 uint8_t *cb_arg, 282 stmf_ic_msgid_t msgid); 283 284 stmf_ic_msg_t *stmf_ic_lun_active_msg_alloc( 285 uint8_t *icrl_lun_id, /* should be 16 bytes */ 286 char *lu_provider_name, 287 uint16_t cb_arg_len, 288 uint8_t *cb_arg, 289 stmf_ic_msgid_t msgid); 290 291 /* Allocate a deregister lun message */ 292 typedef 293 stmf_ic_msg_t *(*stmf_ic_dereg_lun_msg_alloc_func_t)( 294 uint8_t *icrl_lun_id, /* should be 16 bytes */ 295 char *lu_provider_name, 296 uint16_t cb_arg_len, 297 uint8_t *cb_arg, 298 stmf_ic_msgid_t msgid); 299 300 stmf_ic_msg_t *stmf_ic_dereg_lun_msg_alloc( 301 uint8_t *icrl_lun_id, /* should be 16 bytes */ 302 char *lu_provider_name, 303 uint16_t cb_arg_len, 304 uint8_t *cb_arg, 305 stmf_ic_msgid_t msgid); 306 307 /* Allocate a scsi cmd message */ 308 typedef 309 stmf_ic_msg_t *(*stmf_ic_scsi_cmd_msg_alloc_func_t)( 310 stmf_ic_msgid_t task_msgid, 311 scsi_task_t *scsi_task, 312 uint32_t immed_data_len, 313 uint8_t *immed_data, 314 stmf_ic_msgid_t msgid); 315 316 stmf_ic_msg_t *stmf_ic_scsi_cmd_msg_alloc( 317 stmf_ic_msgid_t task_msgid, 318 scsi_task_t *scsi_task, 319 uint32_t immed_data_len, 320 uint8_t *immed_data, 321 stmf_ic_msgid_t msgid); 322 323 /* Allocate a scsi data message */ 324 typedef 325 stmf_ic_msg_t *(*stmf_ic_scsi_data_msg_alloc_func_t)( 326 stmf_ic_msgid_t task_msgid, 327 uint64_t session_id, 328 uint8_t *lun_id, 329 uint64_t data_len, 330 uint8_t *data, 331 stmf_ic_msgid_t msgid); 332 333 stmf_ic_msg_t *stmf_ic_scsi_data_msg_alloc( 334 stmf_ic_msgid_t task_msgid, 335 uint64_t session_id, 336 uint8_t *lun_id, 337 uint64_t data_len, 338 uint8_t *data, 339 stmf_ic_msgid_t msgid); 340 341 /* Allocate a scsi transfer done message */ 342 typedef 343 stmf_ic_msg_t *(*stmf_ic_scsi_data_xfer_done_msg_alloc_func_t)( 344 stmf_ic_msgid_t task_msgid, 345 uint64_t session_id, 346 stmf_status_t status, 347 stmf_ic_msgid_t msgid); 348 349 stmf_ic_msg_t *stmf_ic_scsi_data_xfer_done_msg_alloc( 350 stmf_ic_msgid_t task_msgid, 351 uint64_t session_id, 352 stmf_status_t status, 353 stmf_ic_msgid_t msgid); 354 355 356 /* Allocate a scsi status message */ 357 stmf_ic_msg_t *stmf_ic_scsi_status_msg_alloc( 358 stmf_ic_msgid_t task_msgid, 359 uint64_t session_id, 360 uint8_t *lun_id, 361 uint8_t response, /* was command processed? */ 362 uint8_t status, 363 uint8_t flags, 364 uint32_t resid, 365 uint8_t sense_len, 366 uint8_t *sense, 367 stmf_ic_msgid_t msgid); /* must match corresponding scsi cmd msgid */ 368 369 370 /* Allocate a scsi ready to transfer (r2t) message */ 371 stmf_ic_msg_t *stmf_ic_r2t_msg_alloc( 372 stmf_ic_msgid_t task_msgid, 373 uint64_t session_id, 374 uint32_t offset, 375 uint32_t length, 376 stmf_ic_msgid_t msgid); /* must match corresponding scsi cmd msgid */ 377 378 /* Allocate a status message */ 379 stmf_ic_msg_t *stmf_ic_status_msg_alloc( 380 stmf_status_t status, 381 stmf_ic_msg_type_t msg_type, /* msg type reporting status on */ 382 stmf_ic_msgid_t msgid); /* id of msg reporting status on */ 383 384 /* Allocate a session create message */ 385 typedef 386 stmf_ic_msg_t *(*stmf_ic_session_create_msg_alloc_func_t)( 387 stmf_scsi_session_t *session, 388 stmf_ic_msgid_t msgid); 389 390 stmf_ic_msg_t *stmf_ic_session_create_msg_alloc( 391 stmf_scsi_session_t *session, 392 stmf_ic_msgid_t msgid); 393 394 /* Allocate a session destroy message */ 395 typedef 396 stmf_ic_msg_t *(*stmf_ic_session_destroy_msg_alloc_func_t)( 397 stmf_scsi_session_t *session, 398 stmf_ic_msgid_t msgid); 399 400 stmf_ic_msg_t *stmf_ic_session_destroy_msg_alloc( 401 stmf_scsi_session_t *session, 402 stmf_ic_msgid_t msgid); 403 404 /* Allocate an echo request message */ 405 stmf_ic_msg_t *stmf_ic_echo_request_msg_alloc( 406 uint32_t data_len, 407 uint8_t *data, 408 stmf_ic_msgid_t msgid); 409 410 /* Allocate an echo reply message */ 411 stmf_ic_msg_t *stmf_ic_echo_reply_msg_alloc( 412 uint32_t data_len, 413 uint8_t *data, 414 stmf_ic_msgid_t msgid); 415 416 /* 417 * Free a msg. 418 */ 419 typedef void (*stmf_ic_msg_free_func_t)(stmf_ic_msg_t *msg); 420 void stmf_ic_msg_free(stmf_ic_msg_t *msg); 421 422 /* 423 * Send a message out over the interconnect, in the process marshalling 424 * the arguments. 425 * 426 * After being sent, the message is freed by tx_msg(). 427 */ 428 typedef stmf_ic_msg_status_t (*stmf_ic_tx_msg_func_t)(stmf_ic_msg_t *msg); 429 stmf_ic_msg_status_t stmf_ic_tx_msg(stmf_ic_msg_t *msg); 430 431 /* 432 * This is a low-level upcall which is called when a message has 433 * been received on the interconnect. 434 */ 435 void stmf_ic_rx_msg(char *buf, size_t len); 436 437 stmf_status_t stmf_msg_rx(stmf_ic_msg_t *msg); 438 439 #ifdef __cplusplus 440 } 441 #endif 442 443 #endif /* _SYS_PPPT_IC_IF_H */ 444