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 } srpt_target_port_t; 302 303 /* 304 * SRP Target hardware device. A SRP Target hardware device 305 * is an IB HCA. All ports of the HCA comprise a single 306 * I/O Controller that is registered with the IB Device 307 * Managment Agent. 308 */ 309 typedef struct srpt_ioc_s { 310 list_node_t ioc_node; 311 312 krwlock_t ioc_rwlock; 313 ibt_hca_hdl_t ioc_ibt_hdl; 314 ibt_hca_attr_t ioc_attr; 315 ib_guid_t ioc_guid; 316 317 /* 318 * By default each HCA is a single SRP.T10 service based on 319 * the HCA GUID. We have implemented the target here as a 320 * pointer to facilitate moving to a list of targets if 321 * appropriate down the road. 322 */ 323 srpt_target_port_t *ioc_tgt_port; 324 325 326 /* 327 * Each HCA registers a single I/O Controller with the 328 * IB Device Management Agent. 329 */ 330 ibdma_hdl_t ioc_ibdma_hdl; 331 ib_dm_ioc_ctrl_profile_t ioc_profile; 332 ib_dm_srv_t ioc_svc; 333 334 ibt_pd_hdl_t ioc_pd_hdl; 335 ibt_srq_sizes_t ioc_srq_attr; 336 ibt_srq_hdl_t ioc_srq_hdl; 337 338 /* 339 * The I/O Controller pool of IU resources allocated 340 * at controller creation. 341 */ 342 uint32_t ioc_num_iu_entries; 343 srpt_iu_t *ioc_iu_pool; 344 ibt_mr_hdl_t ioc_iu_mr_hdl; 345 void *ioc_iu_bufs; /* iu buffer space */ 346 347 /* 348 * Each I/O Controller has it's own data buffer 349 * vmem arena. Pool is created at controller creation, 350 * and expanded as required. This keeps IB memory 351 * registrations to a minimum in the data path. 352 */ 353 struct srpt_vmem_pool_s *ioc_dbuf_pool; 354 stmf_dbuf_store_t *ioc_stmf_ds; 355 } srpt_ioc_t; 356 357 /* 358 * Memory regions 359 */ 360 typedef struct srpt_mr_s { 361 ibt_mr_hdl_t mr_hdl; 362 ib_vaddr_t mr_va; 363 ib_memlen_t mr_len; 364 ibt_lkey_t mr_lkey; 365 ibt_rkey_t mr_rkey; 366 avl_node_t mr_avl; 367 } srpt_mr_t; 368 369 /* 370 * SRP Target vmem arena definition 371 */ 372 typedef struct srpt_vmem_pool_s { 373 srpt_ioc_t *svp_ioc; 374 ib_memlen_t svp_chunksize; 375 vmem_t *svp_vmem; 376 uint64_t svp_total_size; 377 uint64_t svp_max_size; 378 avl_tree_t svp_mr_list; 379 krwlock_t svp_lock; 380 ibt_mr_flags_t svp_flags; 381 } srpt_vmem_pool_t; 382 383 /* 384 * SRP port provider data buffer, allocated and freed 385 * via calls to the IOC datastore. 386 */ 387 typedef struct srpt_ds_dbuf_s { 388 stmf_data_buf_t *db_stmf_buf; 389 srpt_ioc_t *db_ioc; 390 ibt_mr_hdl_t db_mr_hdl; 391 ibt_wr_ds_t db_sge; 392 srpt_iu_t *db_iu; 393 } srpt_ds_dbuf_t; 394 395 /* 396 * SRP Target service state 397 */ 398 typedef enum { 399 SRPT_SVC_DISABLED, 400 SRPT_SVC_ENABLED 401 } srpt_svc_state_t; 402 403 typedef struct { 404 ddi_modhandle_t ibdmah; 405 ibdma_hdl_t (*ibdma_register)(ib_guid_t, 406 ib_dm_ioc_ctrl_profile_t *, ib_dm_srv_t *); 407 ibdma_status_t (*ibdma_unregister)(ibdma_hdl_t); 408 ibdma_status_t (*ibdma_update)(ibdma_hdl_t, 409 ib_dm_ioc_ctrl_profile_t *, ib_dm_srv_t *); 410 } srpt_ibdma_ops_t; 411 412 /* 413 * SRP Target protocol driver context data structure, maintaining 414 * the global state of the protocol. 415 */ 416 typedef struct srpt_ctxt_s { 417 dev_info_t *sc_dip; 418 krwlock_t sc_rwlock; 419 srpt_svc_state_t sc_svc_state; 420 421 ibt_clnt_hdl_t sc_ibt_hdl; 422 423 /* 424 * SRP Target I/O Controllers. Each IBT HCA represents an 425 * I/O Controller. Must hold rwlock as a writer to update. 426 */ 427 list_t sc_ioc_list; 428 uint_t sc_num_iocs; 429 430 /* Back-end COMSTAR port provider interface. */ 431 stmf_port_provider_t *sc_pp; 432 433 /* IBDMA entry points */ 434 srpt_ibdma_ops_t sc_ibdma_ops; 435 } srpt_ctxt_t; 436 437 typedef struct srpt_iu_data_s { 438 union { 439 uint8_t srp_op; 440 srp_cmd_req_t srp_cmd; 441 srp_tsk_mgmt_t srp_tsk_mgmt; 442 srp_i_logout_t srp_i_logout; 443 srp_rsp_t srp_rsp; 444 } rx_iu; 445 } srpt_iu_data_t; 446 447 extern srpt_ctxt_t *srpt_ctxt; 448 449 /* 450 * For Non recoverable or Major Errors 451 */ 452 #define SRPT_LOG_L0 0 453 454 /* 455 * For additional information on Non recoverable errors and 456 * warnings/informational message for sys-admin types. 457 */ 458 #define SRPT_LOG_L1 1 459 460 /* 461 * debug only 462 * for more verbose trace than L1, for e.g. recoverable errors, 463 * or intersting trace 464 */ 465 #define SRPT_LOG_L2 2 466 467 /* 468 * debug only 469 * for more verbose trace than L2, for e.g. printing function entries.... 470 */ 471 #define SRPT_LOG_L3 3 472 473 /* 474 * debug only 475 * for more verbose trace than L3, for e.g. printing minor function entries... 476 */ 477 #define SRPT_LOG_L4 4 478 479 /* 480 * srpt_errlevel can be set in the debugger to enable additional logging. 481 * You can also add set srpt:srpt_errlevel={0,1,2,3,4} in /etc/system. 482 * The default log level is L1. 483 */ 484 #define SRPT_LOG_DEFAULT_LEVEL SRPT_LOG_L1 485 486 extern uint_t srpt_errlevel; 487 488 489 #define SRPT_DPRINTF_L0(...) cmn_err(CE_WARN, __VA_ARGS__) 490 #define SRPT_DPRINTF_L1(...) cmn_err(CE_NOTE, __VA_ARGS__) 491 #define SRPT_DPRINTF_L2(...) if (srpt_errlevel >= SRPT_LOG_L2) { \ 492 cmn_err(CE_NOTE, __VA_ARGS__);\ 493 } 494 #ifdef DEBUG 495 #define SRPT_DPRINTF_L3(...) if (srpt_errlevel >= SRPT_LOG_L3) { \ 496 cmn_err(CE_NOTE, __VA_ARGS__);\ 497 } 498 #define SRPT_DPRINTF_L4(...) if (srpt_errlevel >= SRPT_LOG_L4) { \ 499 cmn_err(CE_NOTE, __VA_ARGS__);\ 500 } 501 #else 502 #define SRPT_DPRINTF_L3 0 && 503 #define SRPT_DPRINTF_L4 0 && 504 #endif 505 506 #ifdef __cplusplus 507 } 508 #endif 509 510 #endif /* _SRPT_IMPL_H_ */ 511