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 _SRPT_IMPL_H_ 28 #define _SRPT_IMPL_H_ 29 30 /* 31 * Prototypes and data structures for the SRP Target Port Provider. 32 */ 33 34 #include <sys/types.h> 35 #include <sys/ddi.h> 36 #include <sys/ib/ibtl/ibti.h> 37 #include <sys/modctl.h> 38 39 #include <stmf.h> 40 #include <stmf_ioctl.h> 41 #include <portif.h> 42 43 #include <sys/ib/mgt/ibdma/ibdma.h> 44 45 #ifdef __cplusplus 46 extern "C" { 47 #endif 48 49 /* Format the session identifier */ 50 #define ALIAS_STR(s, a, b) \ 51 ((void) snprintf((s), sizeof ((s)), "%016llx:%016llx", \ 52 (u_longlong_t)(a), (u_longlong_t)(b))) 53 54 /* Format the EUI name */ 55 #define EUI_STR(s, a) \ 56 ((void) snprintf((s), sizeof ((s)), "eui.%016llX", (u_longlong_t)(a))) 57 58 /* 59 * We should/could consider making some of these values tunables. 60 * Specifically, SEND_MSG_SIZE and SEND_MSG_DEPTH. 61 */ 62 enum { 63 SRPT_DEFAULT_IOC_SRQ_SIZE = 4096, 64 SRPT_DEFAULT_SEND_MSG_DEPTH = 128, 65 SRPT_DEFAULT_SEND_MSG_SIZE = 960, /* must be multiple of 64 */ 66 SRPT_DEFAULT_MAX_RDMA_SIZE = 65536, 67 SRPT_MIN_T_I_IU_LEN = 52, 68 SRPT_EUI_ID_LEN = 20, 69 SRPT_RECV_WC_POLL_SIZE = 16, 70 SRPT_SEND_WC_POLL_SIZE = 16, 71 SRPT_MAX_OUT_IO_PER_CMD = 16, 72 SRPT_FENCE_SEND = 1, 73 SRPT_NO_FENCE_SEND = 0 74 }; 75 76 struct srpt_target_port_s; 77 78 #define SRPT_ALIAS_LEN (SRP_PORT_ID_LEN * 2 + 2) 79 80 /* 81 * SRP Session - represents a SCSI I_T_Nexus. 82 * 83 * Sessions map 1 or more initiator logins to a specific I/O 84 * Controller SCSI Target Port. Targets create sessions 85 * at initiator login and release when no longer referenced 86 * by a login. 87 */ 88 typedef struct srpt_session_s { 89 krwlock_t ss_rwlock; 90 list_node_t ss_node; 91 92 /* 93 * ADVANCED FEATURE, NOT YET SUPPORTED. 94 * In multi-channel mode, multiple RDMA communication 95 * channels may reference the same SCSI session. When 96 * a channel releases its reference to the SCSI session, 97 * it should have no tasks associated with the session. 98 * 99 * If multi-channel is implemented, add a channel list 100 * to this object instead of tracking it on the target. 101 * 102 * Will also need a session state & mode. Mode is to 103 * track if the session is MULTI or SINGLE channel. 104 */ 105 106 stmf_scsi_session_t *ss_ss; 107 struct srpt_target_port_s *ss_tgt; 108 list_t ss_task_list; 109 110 /* 111 * SRP Initiator and target identifiers are 128-bit. 112 * 113 * The specification defines the initiator to be 64-bits of 114 * ID extension and 64 bits of GUID, but these are really 115 * just a recommendation. Generally the extension is used 116 * to create unique I_T_Nexus from the same initiator and 117 * target. Initiators are inconsistent on the GUID they 118 * use, some use the HCA Node, some the HCA port. 119 * 120 * The specification defines the target to be 64-bits of 121 * service ID followed by 64-bits of I/O Controller GUID. 122 * In the case where there is a single default target 123 * service, they will be the same (our default). 124 */ 125 uint8_t ss_i_id[SRP_PORT_ID_LEN]; 126 uint8_t ss_t_id[SRP_PORT_ID_LEN]; 127 128 /* So we can see the full 128-bit initiator login from stmfadm */ 129 char ss_i_alias[SRPT_ALIAS_LEN]; 130 uint8_t ss_hw_port; 131 132 char ss_t_alias[SRPT_ALIAS_LEN]; 133 char ss_i_name[SRPT_EUI_ID_LEN + 1]; 134 char ss_t_name[SRPT_EUI_ID_LEN + 1]; 135 char ss_i_gid[SRPT_ALIAS_LEN]; 136 char ss_t_gid[SRPT_ALIAS_LEN]; 137 } srpt_session_t; 138 139 /* 140 * Send work request types. 141 */ 142 typedef enum srpt_swqe_type_e { 143 SRPT_SWQE_TYPE_DATA = 1, 144 SRPT_SWQE_TYPE_RESP 145 } srpt_swqe_type_t; 146 147 typedef struct srpt_swqe_s { 148 srpt_swqe_type_t sw_type; 149 void *sw_addr; 150 ibt_wrid_t sw_next; 151 } srpt_swqe_t; 152 153 /* 154 * SRP Channel - the RDMA communications channel associated with 155 * a specific SRP login. 156 */ 157 typedef enum srpt_channel_state_e { 158 SRPT_CHANNEL_CONNECTING = 0, 159 SRPT_CHANNEL_CONNECTED, 160 SRPT_CHANNEL_DISCONNECTING 161 } srpt_channel_state_t; 162 163 typedef struct srpt_channel_s { 164 krwlock_t ch_rwlock; 165 166 kmutex_t ch_reflock; 167 uint_t ch_refcnt; 168 kcondvar_t ch_cv_complete; 169 uint_t ch_cv_waiters; 170 171 list_node_t ch_stp_node; 172 srpt_channel_state_t ch_state; 173 ibt_cq_hdl_t ch_scq_hdl; 174 ibt_cq_hdl_t ch_rcq_hdl; 175 ibt_channel_hdl_t ch_chan_hdl; 176 ibt_chan_sizes_t ch_sizes; 177 178 uint32_t ch_req_lim_delta; 179 uint32_t ch_ti_iu_len; 180 struct srpt_target_port_s *ch_tgt; 181 srpt_session_t *ch_session; 182 183 /* 184 * Map IB send WQE request IDs to the 185 * apporpriate operation type (for errors). 186 */ 187 kmutex_t ch_swqe_lock; 188 srpt_swqe_t *ch_swqe; 189 uint32_t ch_num_swqe; 190 uint32_t ch_head; 191 uint32_t ch_tail; 192 uint32_t ch_swqe_posted; 193 } srpt_channel_t; 194 195 /* 196 * SRP Information Unit (IU). Each IU structure contains 197 * the buffer for the IU itself (received over the RC 198 * channel), and all of the context required by the target 199 * to process this request represented by the IU. 200 * Available IU structures are managed on the I/O Controller 201 * shared receive queue. 202 */ 203 enum { 204 SRPT_IU_STMF_ABORTING = 1 << 0, /* STMF called abort */ 205 SRPT_IU_SRP_ABORTING = 1 << 1, /* SRP initiator aborting */ 206 SRPT_IU_ABORTED = 1 << 2, /* Task has been aborted */ 207 SRPT_IU_RESP_SENT = 1 << 3 /* Response queued */ 208 }; 209 210 typedef struct srpt_iu_s { 211 /* 212 * The buffer for the IU itself. When unused (a 213 * reference count of zero), this buffer is posted 214 * on the I/O Controllers SRPT SRQ. 215 */ 216 void *iu_buf; 217 ibt_wr_ds_t iu_sge; 218 struct srpt_ioc_s *iu_ioc; 219 uint_t iu_pool_ndx; 220 kmutex_t iu_lock; 221 222 /* 223 * The following are reset for each IU request 224 * processed by this buffer. 225 */ 226 list_node_t iu_ss_task_node; 227 srpt_channel_t *iu_ch; 228 229 uint_t iu_num_rdescs; 230 srp_direct_desc_t *iu_rdescs; 231 uint_t iu_tot_xfer_len; 232 233 uint64_t iu_tag; 234 uint_t iu_flags; 235 uint32_t iu_sq_posted_cnt; 236 scsi_task_t *iu_stmf_task; 237 } srpt_iu_t; 238 239 /* 240 * SRP SCSI Target Port. By default each HCA creates a single 241 * SCSI Target Port based on the associated I/O Controller 242 * (HCA) node GUID and made available through each physical 243 * hardware port of the I/O Controller. 244 */ 245 typedef enum srpt_target_state_e { 246 SRPT_TGT_STATE_OFFLINE = 0, 247 SRPT_TGT_STATE_ONLINING, 248 SRPT_TGT_STATE_ONLINE, 249 SRPT_TGT_STATE_OFFLINING 250 } srpt_target_state_t; 251 252 typedef struct srpt_hw_port_s { 253 ibt_sbind_hdl_t hwp_bind_hdl; 254 ib_gid_t hwp_gid; 255 } srpt_hw_port_t; 256 257 typedef struct srpt_target_port_s { 258 stmf_local_port_t *tp_lport; 259 struct srpt_ioc_s *tp_ioc; 260 261 kmutex_t tp_lock; 262 srpt_target_state_t tp_state; 263 kcondvar_t tp_offline_complete; 264 uint_t tp_drv_disabled; 265 266 /* 267 * We are using a simple list for channels right now, we 268 * probably should switch this over to the AVL 269 * implementation eventually (but lookups are not done 270 * in the data path so this is not urgent). 271 */ 272 kmutex_t tp_ch_list_lock; 273 list_t tp_ch_list; 274 275 /* 276 * A list of active sessions. Session lifetime is 277 * determined by having active channels, but track 278 * them here for easier determination to when a 279 * target can truly be offlined, and as a step toward 280 * being session-focused rather than channel-focused. 281 * If we ever truly support multi-channel, move the 282 * channels to be part of the session object. 283 * 284 * Sessions should remain on this list until they 285 * are deregistered from STMF. This allows the target 286 * to properly track when it can consider itself 'offline'. 287 */ 288 kmutex_t tp_sess_list_lock; 289 kcondvar_t tp_sess_complete; 290 list_t tp_sess_list; 291 292 uint_t tp_srp_enabled; 293 ibt_srv_hdl_t tp_ibt_svc_hdl; 294 ibt_srv_desc_t tp_ibt_svc_desc; 295 ib_svc_id_t tp_ibt_svc_id; 296 scsi_devid_desc_t *tp_scsi_devid; 297 uint8_t tp_srp_port_id[SRP_PORT_ID_LEN]; 298 299 uint_t tp_nports; 300 srpt_hw_port_t *tp_hw_port; 301 /* 302 * track the number of active ports so we can offline the target if 303 * none 304 */ 305 uint32_t tp_num_active_ports; 306 /* state STMF wants the target in. We may be offline due to no ports */ 307 srpt_target_state_t tp_requested_state; 308 } srpt_target_port_t; 309 310 /* 311 * SRP Target hardware device. A SRP Target hardware device 312 * is an IB HCA. All ports of the HCA comprise a single 313 * I/O Controller that is registered with the IB Device 314 * Managment Agent. 315 */ 316 typedef struct srpt_ioc_s { 317 list_node_t ioc_node; 318 319 krwlock_t ioc_rwlock; 320 ibt_hca_hdl_t ioc_ibt_hdl; 321 ibt_hca_attr_t ioc_attr; 322 ib_guid_t ioc_guid; 323 324 /* 325 * By default each HCA is a single SRP.T10 service based on 326 * the HCA GUID. We have implemented the target here as a 327 * pointer to facilitate moving to a list of targets if 328 * appropriate down the road. 329 */ 330 srpt_target_port_t *ioc_tgt_port; 331 332 333 /* 334 * Each HCA registers a single I/O Controller with the 335 * IB Device Management Agent. 336 */ 337 ibdma_hdl_t ioc_ibdma_hdl; 338 ib_dm_ioc_ctrl_profile_t ioc_profile; 339 ib_dm_srv_t ioc_svc; 340 341 ibt_pd_hdl_t ioc_pd_hdl; 342 ibt_srq_sizes_t ioc_srq_attr; 343 ibt_srq_hdl_t ioc_srq_hdl; 344 345 /* 346 * The I/O Controller pool of IU resources allocated 347 * at controller creation. 348 */ 349 uint32_t ioc_num_iu_entries; 350 srpt_iu_t *ioc_iu_pool; 351 ibt_mr_hdl_t ioc_iu_mr_hdl; 352 void *ioc_iu_bufs; /* iu buffer space */ 353 354 /* 355 * Each I/O Controller has it's own data buffer 356 * vmem arena. Pool is created at controller creation, 357 * and expanded as required. This keeps IB memory 358 * registrations to a minimum in the data path. 359 */ 360 struct srpt_vmem_pool_s *ioc_dbuf_pool; 361 stmf_dbuf_store_t *ioc_stmf_ds; 362 } srpt_ioc_t; 363 364 /* 365 * Memory regions 366 */ 367 typedef struct srpt_mr_s { 368 ibt_mr_hdl_t mr_hdl; 369 ib_vaddr_t mr_va; 370 ib_memlen_t mr_len; 371 ibt_lkey_t mr_lkey; 372 ibt_rkey_t mr_rkey; 373 avl_node_t mr_avl; 374 } srpt_mr_t; 375 376 /* 377 * SRP Target vmem arena definition 378 */ 379 typedef struct srpt_vmem_pool_s { 380 srpt_ioc_t *svp_ioc; 381 ib_memlen_t svp_chunksize; 382 vmem_t *svp_vmem; 383 uint64_t svp_total_size; 384 uint64_t svp_max_size; 385 avl_tree_t svp_mr_list; 386 krwlock_t svp_lock; 387 ibt_mr_flags_t svp_flags; 388 } srpt_vmem_pool_t; 389 390 /* 391 * SRP port provider data buffer, allocated and freed 392 * via calls to the IOC datastore. 393 */ 394 typedef struct srpt_ds_dbuf_s { 395 stmf_data_buf_t *db_stmf_buf; 396 srpt_ioc_t *db_ioc; 397 ibt_mr_hdl_t db_mr_hdl; 398 ibt_wr_ds_t db_sge; 399 srpt_iu_t *db_iu; 400 } srpt_ds_dbuf_t; 401 402 /* 403 * SRP Target service state 404 */ 405 typedef enum { 406 SRPT_SVC_DISABLED, 407 SRPT_SVC_ENABLED 408 } srpt_svc_state_t; 409 410 typedef struct { 411 ddi_modhandle_t ibdmah; 412 ibdma_hdl_t (*ibdma_register)(ib_guid_t, 413 ib_dm_ioc_ctrl_profile_t *, ib_dm_srv_t *); 414 ibdma_status_t (*ibdma_unregister)(ibdma_hdl_t); 415 ibdma_status_t (*ibdma_update)(ibdma_hdl_t, 416 ib_dm_ioc_ctrl_profile_t *, ib_dm_srv_t *); 417 } srpt_ibdma_ops_t; 418 419 /* 420 * SRP Target protocol driver context data structure, maintaining 421 * the global state of the protocol. 422 */ 423 typedef struct srpt_ctxt_s { 424 dev_info_t *sc_dip; 425 krwlock_t sc_rwlock; 426 srpt_svc_state_t sc_svc_state; 427 428 ibt_clnt_hdl_t sc_ibt_hdl; 429 430 /* 431 * SRP Target I/O Controllers. Each IBT HCA represents an 432 * I/O Controller. Must hold rwlock as a writer to update. 433 */ 434 list_t sc_ioc_list; 435 uint_t sc_num_iocs; 436 437 /* Back-end COMSTAR port provider interface. */ 438 stmf_port_provider_t *sc_pp; 439 440 /* IBDMA entry points */ 441 srpt_ibdma_ops_t sc_ibdma_ops; 442 } srpt_ctxt_t; 443 444 typedef struct srpt_iu_data_s { 445 union { 446 uint8_t srp_op; 447 srp_cmd_req_t srp_cmd; 448 srp_tsk_mgmt_t srp_tsk_mgmt; 449 srp_i_logout_t srp_i_logout; 450 srp_rsp_t srp_rsp; 451 } rx_iu; 452 } srpt_iu_data_t; 453 454 extern srpt_ctxt_t *srpt_ctxt; 455 456 /* 457 * For Non recoverable or Major Errors 458 */ 459 #define SRPT_LOG_L0 0 460 461 /* 462 * For additional information on Non recoverable errors and 463 * warnings/informational message for sys-admin types. 464 */ 465 #define SRPT_LOG_L1 1 466 467 /* 468 * debug only 469 * for more verbose trace than L1, for e.g. recoverable errors, 470 * or intersting trace 471 */ 472 #define SRPT_LOG_L2 2 473 474 /* 475 * debug only 476 * for more verbose trace than L2, for e.g. printing function entries.... 477 */ 478 #define SRPT_LOG_L3 3 479 480 /* 481 * debug only 482 * for more verbose trace than L3, for e.g. printing minor function entries... 483 */ 484 #define SRPT_LOG_L4 4 485 486 /* 487 * srpt_errlevel can be set in the debugger to enable additional logging. 488 * You can also add set srpt:srpt_errlevel={0,1,2,3,4} in /etc/system. 489 * The default log level is L1. 490 */ 491 #define SRPT_LOG_DEFAULT_LEVEL SRPT_LOG_L1 492 493 extern uint_t srpt_errlevel; 494 495 496 #define SRPT_DPRINTF_L0(...) cmn_err(CE_WARN, __VA_ARGS__) 497 #define SRPT_DPRINTF_L1(...) cmn_err(CE_NOTE, __VA_ARGS__) 498 #define SRPT_DPRINTF_L2(...) if (srpt_errlevel >= SRPT_LOG_L2) { \ 499 cmn_err(CE_NOTE, __VA_ARGS__);\ 500 } 501 #ifdef DEBUG 502 #define SRPT_DPRINTF_L3(...) if (srpt_errlevel >= SRPT_LOG_L3) { \ 503 cmn_err(CE_NOTE, __VA_ARGS__);\ 504 } 505 #define SRPT_DPRINTF_L4(...) if (srpt_errlevel >= SRPT_LOG_L4) { \ 506 cmn_err(CE_NOTE, __VA_ARGS__);\ 507 } 508 #else 509 #define SRPT_DPRINTF_L3 0 && 510 #define SRPT_DPRINTF_L4 0 && 511 #endif 512 513 #ifdef __cplusplus 514 } 515 #endif 516 517 #endif /* _SRPT_IMPL_H_ */ 518