xref: /illumos-gate/usr/src/uts/common/io/comstar/port/srpt/srpt_impl.h (revision 9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829)
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