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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 #ifndef _STMF_IMPL_H
25 #define	_STMF_IMPL_H
26 
27 #include <sys/stmf_defines.h>
28 #include <sys/stmf_ioctl.h>
29 
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 typedef	uint32_t stmf_event_handle_t;
35 #define	STMF_MAX_NUM_EVENTS		(sizeof (stmf_event_handle_t) * 8)
36 #define	STMF_EVENT_ADD(h, e)		(atomic_or_32(&(h), \
37 						((uint32_t)1) << (e)))
38 #define	STMF_EVENT_REMOVE(h, e)		(atomic_and_32(&(h), \
39 						~(((uint32_t)1) << (e))))
40 #define	STMF_EVENT_ENABLED(h, e)	(((h) & ((uint32_t)1) << (e)) != 0)
41 #define	STMF_EVENT_CLEAR_ALL(h)		((h) = 0)
42 #define	STMF_EVENT_ALLOC_HANDLE(h)	((h) = 0)
43 #define	STMF_EVENT_FREE_HANDLE(h)	((h) = 0)
44 
45 #define	STMF_TGT_NAME_LEN		256
46 #define	STMF_GUID_INPUT			32
47 
48 #define	STMF_UPDATE_KSTAT_IO(kip, dbuf)					\
49 	if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {			\
50 		kip->reads++;						\
51 		kip->nread += dbuf->db_data_size;			\
52 	} else {							\
53 		kip->writes++;						\
54 		kip->nwritten += dbuf->db_data_size;			\
55 	}
56 
57 struct stmf_i_scsi_task;
58 struct stmf_itl_data;
59 
60 typedef struct stmf_i_lu_provider {
61 	stmf_lu_provider_t	*ilp_lp;
62 	uint32_t		ilp_alloc_size;
63 	uint32_t		ilp_nlus;	/* # LUNs being exported */
64 	uint32_t		ilp_cb_in_progress:1,
65 				ilp_rsvd:31;
66 	struct stmf_i_lu_provider *ilp_next;
67 	struct stmf_pp_data	*ilp_ppd;
68 } stmf_i_lu_provider_t;
69 
70 typedef struct stmf_i_lu {
71 	stmf_lu_t	*ilu_lu;
72 	uint32_t	ilu_alloc_size;
73 	uint32_t	ilu_flags;
74 	uint32_t	ilu_ref_cnt;
75 	uint8_t		ilu_state;
76 	uint8_t		ilu_prev_state;
77 	uint8_t		ilu_access;
78 	uint8_t		ilu_alua;
79 	stmf_event_handle_t ilu_event_hdl;
80 	struct stmf_i_lu *ilu_next;
81 	struct stmf_i_lu *ilu_prev;
82 	char		*ilu_alias;
83 	char		ilu_ascii_hex_guid[STMF_GUID_INPUT + 1];
84 	kmutex_t	ilu_task_lock;
85 	uint32_t	ilu_task_cntr1;
86 	uint32_t	ilu_task_cntr2;
87 	uint32_t	*ilu_cur_task_cntr;
88 	uint32_t	ilu_ntasks;	 /* # of tasks in the ilu_task list */
89 	uint32_t	ilu_ntasks_free;	/* # of tasks that are free */
90 	uint32_t	ilu_ntasks_min_free; /* # minimal free tasks */
91 	uint32_t	rsvd1;
92 	uint32_t	ilu_proxy_registered;
93 	uint64_t	ilu_reg_msgid;
94 	struct stmf_i_scsi_task	*ilu_tasks;
95 	struct stmf_i_scsi_task *ilu_free_tasks;
96 	struct stmf_itl_data	*ilu_itl_list;
97 	kstat_t		*ilu_kstat_info;
98 	kstat_t		*ilu_kstat_io;
99 	kmutex_t	ilu_kstat_lock;
100 
101 	/* point to the luid entry in stmf_state.stmf_luid_list */
102 	void		*ilu_luid;
103 } stmf_i_lu_t;
104 
105 /*
106  * ilu_flags
107  */
108 #define	ILU_STALL_DEREGISTER		0x0001
109 #define	ILU_RESET_ACTIVE		0x0002
110 
111 typedef struct stmf_i_port_provider {
112 	stmf_port_provider_t	*ipp_pp;
113 	uint32_t		ipp_alloc_size;
114 	uint32_t		ipp_npps;
115 	uint32_t		ipp_cb_in_progress:1,
116 				ipp_rsvd:31;
117 	struct stmf_i_port_provider *ipp_next;
118 	struct stmf_pp_data	*ipp_ppd;
119 } stmf_i_port_provider_t;
120 
121 #define	MAX_ILPORT			0x10000
122 
123 typedef struct stmf_i_local_port {
124 	stmf_local_port_t	*ilport_lport;
125 	uint32_t		ilport_alloc_size;
126 	uint32_t		ilport_nsessions;
127 	struct stmf_i_scsi_session *ilport_ss_list;
128 	krwlock_t		ilport_lock;
129 	struct stmf_i_local_port *ilport_next;
130 	struct stmf_i_local_port *ilport_prev;
131 	uint8_t			ilport_state;
132 	uint8_t			ilport_prev_state;
133 	uint8_t			ilport_standby;
134 	uint8_t			ilport_alua;
135 	uint16_t		ilport_rtpid; /* relative tpid */
136 	uint16_t		ilport_proxy_registered;
137 	uint64_t		ilport_reg_msgid;
138 	uint8_t			ilport_no_standby_lu;
139 	uint32_t		ilport_unexpected_comp;
140 	stmf_event_handle_t	ilport_event_hdl;
141 	clock_t			ilport_last_online_clock;
142 	clock_t			ilport_avg_interval;
143 	uint32_t		ilport_online_times;
144 	uint32_t		ilport_flags;
145 	kstat_t			*ilport_kstat_info;
146 	kstat_t			*ilport_kstat_io;
147 	kmutex_t		ilport_kstat_lock;
148 	char			ilport_kstat_tgt_name[STMF_TGT_NAME_LEN];
149 	/* which target group this port belongs to in stmf_state.stmf_tg_list */
150 	void			*ilport_tg;
151 	id_t			ilport_instance;
152 	/* XXX Need something to track all the remote ports also */
153 } stmf_i_local_port_t;
154 
155 #define	STMF_AVG_ONLINE_INTERVAL	(30 * drv_usectohz(1000000))
156 
157 #define	MAX_IRPORT			0x10000
158 
159 typedef struct stmf_i_remote_port {
160 	struct scsi_devid_desc	*irport_id;
161 	kmutex_t		irport_mutex;
162 	int			irport_refcnt;
163 	id_t			irport_instance;
164 	avl_node_t		irport_ln;
165 } stmf_i_remote_port_t;
166 
167 typedef struct stmf_i_itl_kstat {
168 	char			iitl_kstat_nm[KSTAT_STRLEN];
169 	char			iitl_kstat_lport[STMF_TGT_NAME_LEN];
170 	char			iitl_kstat_guid[STMF_GUID_INPUT + 1];
171 	char			*iitl_kstat_strbuf;
172 	int			iitl_kstat_strbuflen;
173 	kstat_t			*iitl_kstat_info;
174 	kstat_t			*iitl_kstat_taskq;
175 	kstat_t			*iitl_kstat_lu_xfer;
176 	kstat_t			*iitl_kstat_lport_xfer;
177 	avl_node_t		iitl_kstat_ln;
178 } stmf_i_itl_kstat_t;
179 
180 /*
181  * ilport flags
182  */
183 #define	ILPORT_FORCED_OFFLINE		0x01
184 #define	ILPORT_SS_GOT_INITIAL_LUNS	0x02
185 
186 typedef struct stmf_i_scsi_session {
187 	stmf_scsi_session_t	*iss_ss;
188 	uint32_t		iss_alloc_size;
189 	uint32_t		iss_flags;
190 	stmf_i_remote_port_t	*iss_irport;
191 	struct stmf_i_scsi_session *iss_next;
192 	/*
193 	 * Ideally we should maintain 2 maps. One would indicate a new map
194 	 * which will become available only upon receipt of a REPORT LUN
195 	 * cmd.
196 	 */
197 	struct stmf_lun_map	*iss_sm;
198 	/*
199 	 * which host group the host of this session belongs to in
200 	 * stmf_state.stmf_hg_list
201 	 */
202 	void			*iss_hg;
203 	krwlock_t		*iss_lockp;
204 	time_t			iss_creation_time;
205 } stmf_i_scsi_session_t;
206 
207 /*
208  * iss flags
209  */
210 #define	ISS_LUN_INVENTORY_CHANGED		0x0001
211 #define	ISS_RESET_ACTIVE			0x0002
212 #define	ISS_BEING_CREATED			0x0004
213 #define	ISS_GOT_INITIAL_LUNS			0x0008
214 #define	ISS_EVENT_ACTIVE			0x0010
215 
216 #define	ITASK_MAX_NCMDS			14
217 #define	ITASK_DEFAULT_POLL_TIMEOUT	0
218 
219 #define	ITASK_TASK_AUDIT_DEPTH		32 /* Must be a power of 2 */
220 
221 typedef enum {
222 	TE_UNDEFINED,
223 	TE_TASK_START,
224 	TE_XFER_START,
225 	TE_XFER_DONE,
226 	TE_SEND_STATUS,
227 	TE_SEND_STATUS_DONE,
228 	TE_TASK_FREE,
229 	TE_TASK_ABORT,
230 	TE_TASK_LPORT_ABORTED,
231 	TE_TASK_LU_ABORTED,
232 	TE_PROCESS_CMD
233 } task_audit_event_t;
234 
235 #define	CMD_OR_IOF_NA	0xffffffff
236 
237 typedef struct stmf_task_audit_rec {
238 	task_audit_event_t	ta_event;
239 	uint32_t		ta_cmd_or_iof;
240 	uint32_t		ta_itask_flags;
241 	stmf_data_buf_t		*ta_dbuf;
242 	timespec_t		ta_timestamp;
243 } stmf_task_audit_rec_t;
244 
245 struct stmf_worker;
246 typedef struct stmf_i_scsi_task {
247 	scsi_task_t		*itask_task;
248 	uint32_t		itask_alloc_size;
249 	uint32_t		itask_flags;
250 	uint64_t		itask_proxy_msg_id;
251 	stmf_data_buf_t		*itask_proxy_dbuf;
252 	struct stmf_worker	*itask_worker;
253 	uint32_t		*itask_ilu_task_cntr;
254 	struct stmf_i_scsi_task	*itask_worker_next;
255 	struct stmf_i_scsi_task	*itask_lu_next;
256 	struct stmf_i_scsi_task	*itask_lu_prev;
257 	struct stmf_i_scsi_task	*itask_lu_free_next;
258 	struct stmf_i_scsi_task	*itask_abort_next;
259 	struct stmf_itl_data	*itask_itl_datap;
260 	clock_t			itask_start_time;	/* abort and normal */
261 	/* For now we only support 4 parallel buffers. Should be enough. */
262 	stmf_data_buf_t		*itask_dbufs[4];
263 	clock_t			itask_poll_timeout;
264 	uint8_t			itask_cmd_stack[ITASK_MAX_NCMDS];
265 	uint8_t			itask_ncmds;
266 	uint8_t			itask_allocated_buf_map;
267 	uint16_t		itask_cdb_buf_size;
268 
269 	/* Task profile data */
270 	hrtime_t		itask_start_timestamp;
271 	hrtime_t		itask_done_timestamp;
272 	hrtime_t		itask_waitq_enter_timestamp;
273 	hrtime_t		itask_waitq_time;
274 	hrtime_t		itask_lu_read_time;
275 	hrtime_t		itask_lu_write_time;
276 	hrtime_t		itask_lport_read_time;
277 	hrtime_t		itask_lport_write_time;
278 	uint64_t		itask_read_xfer;
279 	uint64_t		itask_write_xfer;
280 	kmutex_t		itask_audit_mutex;
281 	uint8_t			itask_audit_index;
282 	stmf_task_audit_rec_t	itask_audit_records[ITASK_TASK_AUDIT_DEPTH];
283 } stmf_i_scsi_task_t;
284 
285 #define	ITASK_DEFAULT_ABORT_TIMEOUT	5
286 
287 /*
288  * itask_flags
289  */
290 #define	ITASK_IN_FREE_LIST		0x0001
291 #define	ITASK_IN_TRANSITION		0x0002
292 #define	ITASK_IN_WORKER_QUEUE		0x0004
293 #define	ITASK_BEING_ABORTED		0x0008
294 #define	ITASK_BEING_COMPLETED		0x0010
295 #define	ITASK_KNOWN_TO_TGT_PORT		0x0020
296 #define	ITASK_KNOWN_TO_LU		0x0040
297 #define	ITASK_LU_ABORT_CALLED		0x0080
298 #define	ITASK_TGT_PORT_ABORT_CALLED	0x0100
299 #define	ITASK_DEFAULT_HANDLING		0x0200
300 #define	ITASK_CAUSING_LU_RESET		0x0400
301 #define	ITASK_CAUSING_TARGET_RESET	0x0800
302 #define	ITASK_KSTAT_IN_RUNQ		0x1000
303 #define	ITASK_PROXY_TASK		0x2000
304 
305 /*
306  * itask cmds.
307  */
308 #define	ITASK_CMD_MASK			0x1F
309 #define	ITASK_CMD_BUF_NDX(cmd)		(((uint8_t)(cmd)) >> 5)
310 #define	ITASK_CMD_NEW_TASK		0x1
311 #define	ITASK_CMD_DATA_XFER_DONE	0x2
312 #define	ITASK_CMD_STATUS_DONE		0x3
313 #define	ITASK_CMD_ABORT			0x4
314 #define	ITASK_CMD_SEND_STATUS		0x5
315 #define	ITASK_CMD_POLL			0x10
316 #define	ITASK_CMD_POLL_LU		(ITASK_CMD_POLL | 1)
317 #define	ITASK_CMD_POLL_LPORT		(ITASK_CMD_POLL | 2)
318 
319 /*
320  * struct maintained on a per itl basis when the lu registers ITL handle.
321  */
322 typedef struct stmf_itl_data {
323 	uint32_t			itl_counter;
324 	uint8_t				itl_flags;
325 	uint8_t				itl_hdlrm_reason;
326 	uint16_t			itl_lun;
327 	char				*itl_kstat_strbuf;
328 	int				itl_kstat_strbuflen;
329 	kstat_t				*itl_kstat_info;
330 	kstat_t				*itl_kstat_taskq;
331 	kstat_t				*itl_kstat_lu_xfer;
332 	kstat_t				*itl_kstat_lport_xfer;
333 	void				*itl_handle;
334 	struct stmf_i_lu		*itl_ilu;
335 	struct stmf_i_scsi_session	*itl_session;
336 	struct stmf_itl_data		*itl_next;
337 } stmf_itl_data_t;
338 
339 /*
340  * itl flags
341  */
342 #define	STMF_ITL_BEING_TERMINATED	0x01
343 
344 /*
345  * data structures to maintain provider private data.
346  */
347 typedef struct stmf_pp_data {
348 	struct stmf_pp_data	*ppd_next;
349 	void			*ppd_provider;
350 	nvlist_t		*ppd_nv;
351 	uint32_t		ppd_lu_provider:1,
352 				ppd_port_provider:1,
353 				ppd_rsvd:30;
354 	uint32_t		ppd_alloc_size;
355 	uint64_t		ppd_token;
356 	char			ppd_name[8];
357 } stmf_pp_data_t;
358 
359 typedef struct stmf_worker {
360 	kthread_t		*worker_tid;
361 	stmf_i_scsi_task_t	*worker_task_head;
362 	stmf_i_scsi_task_t	*worker_task_tail;
363 	stmf_i_scsi_task_t	*worker_wait_head;
364 	stmf_i_scsi_task_t	*worker_wait_tail;
365 	kmutex_t		worker_lock;
366 	kcondvar_t		worker_cv;
367 	uint32_t		worker_flags;
368 	uint32_t		worker_queue_depth;	/* ntasks cur queued */
369 	uint32_t		worker_max_qdepth_pu;	/* maxqd / unit time */
370 	uint32_t		worker_max_sys_qdepth_pu; /* for all workers */
371 	uint32_t		worker_ref_count;	/* # IOs referencing */
372 	hrtime_t		worker_signal_timestamp;
373 } stmf_worker_t;
374 
375 /*
376  * worker flags
377  */
378 #define	STMF_WORKER_STARTED		1
379 #define	STMF_WORKER_ACTIVE		2
380 #define	STMF_WORKER_TERMINATE		4
381 
382 /*
383  * data struct for managing transfers.
384  */
385 typedef struct stmf_xfer_data {
386 	uint32_t	alloc_size;	/* Including this struct */
387 	uint32_t	size_done;
388 	uint32_t	size_left;
389 	uint8_t		buf[4];
390 } stmf_xfer_data_t;
391 
392 /*
393  * Define frequently used macros
394  */
395 #define	TASK_TO_ITASK(x_task)	\
396 	((stmf_i_scsi_task_t *)(x_task)->task_stmf_private)
397 
398 void stmf_dlun_init();
399 stmf_status_t stmf_dlun_fini();
400 void stmf_worker_init();
401 stmf_status_t stmf_worker_fini();
402 void stmf_task_free(scsi_task_t *task);
403 void stmf_do_task_abort(scsi_task_t *task);
404 void stmf_do_itl_dereg(stmf_lu_t *lu, stmf_itl_data_t *itl,
405 		uint8_t hdlrm_reason);
406 void stmf_generate_lu_event(stmf_i_lu_t *ilu, int eventid,
407 				void *arg, uint32_t flags);
408 void stmf_generate_lport_event(stmf_i_local_port_t *ilport, int eventid,
409 						void *arg, uint32_t flags);
410 
411 #ifdef	__cplusplus
412 }
413 #endif
414 
415 #endif /* _STMF_IMPL_H */
416