srpt_impl.h revision 11113:d133d86fdfbf
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
46extern "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 */
62enum {
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
76struct 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 */
88typedef 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 */
142typedef enum srpt_swqe_type_e {
143	SRPT_SWQE_TYPE_DATA = 1,
144	SRPT_SWQE_TYPE_RESP
145} srpt_swqe_type_t;
146
147typedef 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 */
157typedef enum srpt_channel_state_e {
158	SRPT_CHANNEL_CONNECTING = 0,
159	SRPT_CHANNEL_CONNECTED,
160	SRPT_CHANNEL_DISCONNECTING
161} srpt_channel_state_t;
162
163typedef 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 */
203enum {
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
210typedef 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 */
245typedef 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
252typedef 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
257typedef 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 */
316typedef 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 */
367typedef 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 */
379typedef 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 */
394typedef 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 */
405typedef enum {
406	SRPT_SVC_DISABLED,
407	SRPT_SVC_ENABLED
408} srpt_svc_state_t;
409
410typedef 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 */
423typedef 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
444typedef 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
454extern 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
493extern 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