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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 #ifndef _SYS_PPPT_IC_IF_H 26 #define _SYS_PPPT_IC_IF_H 27 28 #include <sys/stmf_defines.h> 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 /* 35 * ALUA messaging and interconnect API. 36 */ 37 38 /* 39 * Message type. 40 */ 41 typedef enum { 42 STMF_ICM_REGISTER_PROXY_PORT = 0, 43 STMF_ICM_DEREGISTER_PROXY_PORT, 44 STMF_ICM_REGISTER_LUN, 45 STMF_ICM_DEREGISTER_LUN, 46 STMF_ICM_SCSI_CMD, 47 STMF_ICM_SCSI_DATA, 48 STMF_ICM_SCSI_DATA_XFER_DONE, 49 STMF_ICM_SCSI_STATUS, 50 STMF_ICM_R2T, 51 STMF_ICM_STATUS, 52 STMF_ICM_SESSION_CREATE, 53 STMF_ICM_SESSION_DESTROY, 54 STMF_ICM_ECHO_REQUEST, 55 STMF_ICM_ECHO_REPLY, 56 STMF_ICM_LUN_ACTIVE, 57 STMF_ICM_MAX_MSG_TYPE 58 } stmf_ic_msg_type_t; 59 60 /* 61 * Message id: uniquely identifies a message. 62 * This need not be a sequence number since we don't depend on 63 * messages being delivered in sequence. 64 */ 65 typedef uint64_t stmf_ic_msgid_t; 66 67 /* 68 * IC message. This is a container for the various specific message types. 69 * 70 * Note that the message contains a pointer to an nvlist. This pointer 71 * is valid only in the case of messages which are unmarshaled from 72 * nvlists. In that case, it's important to retain a pointer to the nvlist, 73 * since the message and the nvlist share data in the case of strings 74 * and array elements, and data in the message may be invalid if used 75 * after the nvlist is freed. 76 */ 77 typedef struct stmf_ic_msg { 78 stmf_ic_msg_type_t icm_msg_type; 79 stmf_ic_msgid_t icm_msgid; 80 nvlist_t *icm_nvlist; /* nvlist associated with the msg */ 81 void *icm_msg; /* ptr to the specific msg */ 82 } stmf_ic_msg_t; 83 84 /* 85 * Register port message. 86 */ 87 typedef struct { 88 scsi_devid_desc_t *icrp_port_id; 89 uint16_t icrp_relative_port_id; 90 /* opaque callback data */ 91 uint16_t icrp_cb_arg_len; 92 uint8_t *icrp_cb_arg; 93 } stmf_ic_reg_port_msg_t; 94 95 /* 96 * Deregister port message. 97 */ 98 typedef struct { 99 scsi_devid_desc_t *icdp_port_id; 100 /* opaque callback data */ 101 uint16_t icdp_cb_arg_len; 102 uint8_t *icdp_cb_arg; 103 } stmf_ic_dereg_port_msg_t; 104 105 /* 106 * Register/deregister lun message. 107 */ 108 typedef struct { 109 uint8_t icrl_lun_id[16]; 110 char *icrl_lu_provider_name; 111 /* opaque callback data */ 112 uint16_t icrl_cb_arg_len; 113 uint8_t *icrl_cb_arg; 114 } stmf_ic_reg_dereg_lun_msg_t; 115 116 /* 117 * SCSI cmd msg. 118 */ 119 typedef struct { 120 stmf_ic_msgid_t icsc_task_msgid; 121 scsi_devid_desc_t *icsc_ini_devid; 122 scsi_devid_desc_t *icsc_tgt_devid; 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_ic_session_create_destroy_msg_t; 201 202 /* 203 * Echo request/reply message 204 */ 205 typedef struct { 206 uint8_t *icerr_data; 207 uint32_t icerr_datalen; 208 } stmf_ic_echo_request_reply_msg_t; 209 210 typedef enum { 211 STMF_IC_MSG_SUCCESS = 0, 212 STMF_IC_MSG_IC_DOWN, 213 STMF_IC_MSG_TIMED_OUT, 214 STMF_IC_MSG_INTERNAL_ERROR 215 } stmf_ic_msg_status_t; 216 217 /* 218 * Function prototypes. 219 * 220 * Note: Functions which are exported to other modules must have a function 221 * typedef and a prototype; the function type definition is used by 222 * the other module to import the symbol using ddi_modsym(). 223 */ 224 225 void stmf_ic_ioctl_cmd(void *ibuf, uint32_t ibuf_size); 226 227 /* Allocate a register port message */ 228 typedef 229 stmf_ic_msg_t *(*stmf_ic_reg_port_msg_alloc_func_t)( 230 scsi_devid_desc_t *port_id, 231 uint16_t relative_port_id, 232 uint16_t cb_arg_len, 233 uint8_t *cb_arg, 234 stmf_ic_msgid_t msgid); 235 236 stmf_ic_msg_t *stmf_ic_reg_port_msg_alloc( 237 scsi_devid_desc_t *port_id, 238 uint16_t relative_port_id, 239 uint16_t cb_arg_len, 240 uint8_t *cb_arg, 241 stmf_ic_msgid_t msgid); 242 243 /* Allocate a deregister port message */ 244 typedef 245 stmf_ic_msg_t *(*stmf_ic_dereg_port_msg_alloc_func_t)( 246 scsi_devid_desc_t *port_id, 247 uint16_t cb_arg_len, 248 uint8_t *cb_arg, 249 stmf_ic_msgid_t msgid); 250 251 stmf_ic_msg_t *stmf_ic_dereg_port_msg_alloc( 252 scsi_devid_desc_t *port_id, 253 uint16_t cb_arg_len, 254 uint8_t *cb_arg, 255 stmf_ic_msgid_t msgid); 256 257 258 /* Allocate a register lun message */ 259 typedef 260 stmf_ic_msg_t *(*stmf_ic_reg_lun_msg_alloc_func_t)( 261 uint8_t *icrl_lun_id, /* should be 16 bytes */ 262 char *lu_provider_name, 263 uint16_t cb_arg_len, 264 uint8_t *cb_arg, 265 stmf_ic_msgid_t msgid); 266 267 stmf_ic_msg_t *stmf_ic_reg_lun_msg_alloc( 268 uint8_t *icrl_lun_id, /* should be 16 bytes */ 269 char *lu_provider_name, 270 uint16_t cb_arg_len, 271 uint8_t *cb_arg, 272 stmf_ic_msgid_t msgid); 273 274 /* Allocate a lun active message */ 275 typedef 276 stmf_ic_msg_t *(*stmf_ic_lun_active_msg_alloc_func_t)( 277 uint8_t *icrl_lun_id, /* should be 16 bytes */ 278 char *lu_provider_name, 279 uint16_t cb_arg_len, 280 uint8_t *cb_arg, 281 stmf_ic_msgid_t msgid); 282 283 stmf_ic_msg_t *stmf_ic_lun_active_msg_alloc( 284 uint8_t *icrl_lun_id, /* should be 16 bytes */ 285 char *lu_provider_name, 286 uint16_t cb_arg_len, 287 uint8_t *cb_arg, 288 stmf_ic_msgid_t msgid); 289 290 /* Allocate a deregister lun message */ 291 typedef 292 stmf_ic_msg_t *(*stmf_ic_dereg_lun_msg_alloc_func_t)( 293 uint8_t *icrl_lun_id, /* should be 16 bytes */ 294 char *lu_provider_name, 295 uint16_t cb_arg_len, 296 uint8_t *cb_arg, 297 stmf_ic_msgid_t msgid); 298 299 stmf_ic_msg_t *stmf_ic_dereg_lun_msg_alloc( 300 uint8_t *icrl_lun_id, /* should be 16 bytes */ 301 char *lu_provider_name, 302 uint16_t cb_arg_len, 303 uint8_t *cb_arg, 304 stmf_ic_msgid_t msgid); 305 306 /* Allocate a scsi cmd message */ 307 typedef 308 stmf_ic_msg_t *(*stmf_ic_scsi_cmd_msg_alloc_func_t)( 309 stmf_ic_msgid_t task_msgid, 310 scsi_task_t *scsi_task, 311 uint32_t immed_data_len, 312 uint8_t *immed_data, 313 stmf_ic_msgid_t msgid); 314 315 stmf_ic_msg_t *stmf_ic_scsi_cmd_msg_alloc( 316 stmf_ic_msgid_t task_msgid, 317 scsi_task_t *scsi_task, 318 uint32_t immed_data_len, 319 uint8_t *immed_data, 320 stmf_ic_msgid_t msgid); 321 322 /* Allocate a scsi data message */ 323 typedef 324 stmf_ic_msg_t *(*stmf_ic_scsi_data_msg_alloc_func_t)( 325 stmf_ic_msgid_t task_msgid, 326 uint64_t session_id, 327 uint8_t *lun_id, 328 uint64_t data_len, 329 uint8_t *data, 330 stmf_ic_msgid_t msgid); 331 332 stmf_ic_msg_t *stmf_ic_scsi_data_msg_alloc( 333 stmf_ic_msgid_t task_msgid, 334 uint64_t session_id, 335 uint8_t *lun_id, 336 uint64_t data_len, 337 uint8_t *data, 338 stmf_ic_msgid_t msgid); 339 340 /* Allocate a scsi transfer done message */ 341 typedef 342 stmf_ic_msg_t *(*stmf_ic_scsi_data_xfer_done_msg_alloc_func_t)( 343 stmf_ic_msgid_t task_msgid, 344 uint64_t session_id, 345 stmf_status_t status, 346 stmf_ic_msgid_t msgid); 347 348 stmf_ic_msg_t *stmf_ic_scsi_data_xfer_done_msg_alloc( 349 stmf_ic_msgid_t task_msgid, 350 uint64_t session_id, 351 stmf_status_t status, 352 stmf_ic_msgid_t msgid); 353 354 355 /* Allocate a scsi status message */ 356 stmf_ic_msg_t *stmf_ic_scsi_status_msg_alloc( 357 stmf_ic_msgid_t task_msgid, 358 uint64_t session_id, 359 uint8_t *lun_id, 360 uint8_t response, /* was command processed? */ 361 uint8_t status, 362 uint8_t flags, 363 uint32_t resid, 364 uint8_t sense_len, 365 uint8_t *sense, 366 stmf_ic_msgid_t msgid); /* must match corresponding scsi cmd msgid */ 367 368 369 /* Allocate a scsi ready to transfer (r2t) message */ 370 stmf_ic_msg_t *stmf_ic_r2t_msg_alloc( 371 stmf_ic_msgid_t task_msgid, 372 uint64_t session_id, 373 uint32_t offset, 374 uint32_t length, 375 stmf_ic_msgid_t msgid); /* must match corresponding scsi cmd msgid */ 376 377 /* Allocate a status message */ 378 stmf_ic_msg_t *stmf_ic_status_msg_alloc( 379 stmf_status_t status, 380 stmf_ic_msg_type_t msg_type, /* msg type reporting status on */ 381 stmf_ic_msgid_t msgid); /* id of msg reporting status on */ 382 383 /* Allocate a session create message */ 384 typedef 385 stmf_ic_msg_t *(*stmf_ic_session_create_msg_alloc_func_t)( 386 stmf_scsi_session_t *session, 387 stmf_ic_msgid_t msgid); 388 389 stmf_ic_msg_t *stmf_ic_session_create_msg_alloc( 390 stmf_scsi_session_t *session, 391 stmf_ic_msgid_t msgid); 392 393 /* Allocate a session destroy message */ 394 typedef 395 stmf_ic_msg_t *(*stmf_ic_session_destroy_msg_alloc_func_t)( 396 stmf_scsi_session_t *session, 397 stmf_ic_msgid_t msgid); 398 399 stmf_ic_msg_t *stmf_ic_session_destroy_msg_alloc( 400 stmf_scsi_session_t *session, 401 stmf_ic_msgid_t msgid); 402 403 /* Allocate an echo request message */ 404 stmf_ic_msg_t *stmf_ic_echo_request_msg_alloc( 405 uint32_t data_len, 406 uint8_t *data, 407 stmf_ic_msgid_t msgid); 408 409 /* Allocate an echo reply message */ 410 stmf_ic_msg_t *stmf_ic_echo_reply_msg_alloc( 411 uint32_t data_len, 412 uint8_t *data, 413 stmf_ic_msgid_t msgid); 414 415 /* 416 * Free a msg. 417 */ 418 typedef void (*stmf_ic_msg_free_func_t)(stmf_ic_msg_t *msg); 419 void stmf_ic_msg_free(stmf_ic_msg_t *msg); 420 421 /* 422 * Send a message out over the interconnect, in the process marshalling 423 * the arguments. 424 * 425 * After being sent, the message is freed by tx_msg(). 426 */ 427 typedef stmf_ic_msg_status_t (*stmf_ic_tx_msg_func_t)(stmf_ic_msg_t *msg); 428 stmf_ic_msg_status_t stmf_ic_tx_msg(stmf_ic_msg_t *msg); 429 430 /* 431 * This is a low-level upcall which is called when a message has 432 * been received on the interconnect. 433 */ 434 void stmf_ic_rx_msg(char *buf, size_t len); 435 436 stmf_status_t stmf_msg_rx(stmf_ic_msg_t *msg); 437 438 #ifdef __cplusplus 439 } 440 #endif 441 442 #endif /* _SYS_PPPT_IC_IF_H */ 443