1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte /*
2240c3e8ffSJohn Forte  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23*61dfa509SRick McNeal  *
24*61dfa509SRick McNeal  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
25a49dc893SSaso Kiselkov  * Copyright (c) 2013 by Delphix. All rights reserved.
26fcf3ce44SJohn Forte  */
27fcf3ce44SJohn Forte #ifndef _STMF_IMPL_H
28fcf3ce44SJohn Forte #define	_STMF_IMPL_H
29fcf3ce44SJohn Forte 
30fcf3ce44SJohn Forte #include <sys/stmf_defines.h>
31fcf3ce44SJohn Forte #include <sys/stmf_ioctl.h>
32fcf3ce44SJohn Forte 
33fcf3ce44SJohn Forte #ifdef	__cplusplus
34fcf3ce44SJohn Forte extern "C" {
35fcf3ce44SJohn Forte #endif
36fcf3ce44SJohn Forte 
37fcf3ce44SJohn Forte typedef	uint32_t stmf_event_handle_t;
38fcf3ce44SJohn Forte #define	STMF_MAX_NUM_EVENTS		(sizeof (stmf_event_handle_t) * 8)
39fcf3ce44SJohn Forte #define	STMF_EVENT_ADD(h, e)		(atomic_or_32(&(h), \
40fcf3ce44SJohn Forte 						((uint32_t)1) << (e)))
41fcf3ce44SJohn Forte #define	STMF_EVENT_REMOVE(h, e)		(atomic_and_32(&(h), \
42fcf3ce44SJohn Forte 						~(((uint32_t)1) << (e))))
43fcf3ce44SJohn Forte #define	STMF_EVENT_ENABLED(h, e)	(((h) & ((uint32_t)1) << (e)) != 0)
44fcf3ce44SJohn Forte #define	STMF_EVENT_CLEAR_ALL(h)		((h) = 0)
45fcf3ce44SJohn Forte #define	STMF_EVENT_ALLOC_HANDLE(h)	((h) = 0)
46fcf3ce44SJohn Forte #define	STMF_EVENT_FREE_HANDLE(h)	((h) = 0)
47fcf3ce44SJohn Forte 
48034d83c4Stim szeto #define	STMF_TGT_NAME_LEN		256
49034d83c4Stim szeto #define	STMF_GUID_INPUT			32
50034d83c4Stim szeto 
51034d83c4Stim szeto #define	STMF_UPDATE_KSTAT_IO(kip, dbuf)					\
52034d83c4Stim szeto 	if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {			\
53034d83c4Stim szeto 		kip->reads++;						\
54034d83c4Stim szeto 		kip->nread += dbuf->db_data_size;			\
55034d83c4Stim szeto 	} else {							\
56034d83c4Stim szeto 		kip->writes++;						\
57034d83c4Stim szeto 		kip->nwritten += dbuf->db_data_size;			\
58034d83c4Stim szeto 	}
59034d83c4Stim szeto 
60fcf3ce44SJohn Forte struct stmf_i_scsi_task;
61fcf3ce44SJohn Forte struct stmf_itl_data;
62fcf3ce44SJohn Forte 
63fcf3ce44SJohn Forte typedef struct stmf_i_lu_provider {
64fcf3ce44SJohn Forte 	stmf_lu_provider_t	*ilp_lp;
65fcf3ce44SJohn Forte 	uint32_t		ilp_alloc_size;
66fcf3ce44SJohn Forte 	uint32_t		ilp_nlus;	/* # LUNs being exported */
67fcf3ce44SJohn Forte 	uint32_t		ilp_cb_in_progress:1,
68fcf3ce44SJohn Forte 				ilp_rsvd:31;
69fcf3ce44SJohn Forte 	struct stmf_i_lu_provider *ilp_next;
70fcf3ce44SJohn Forte 	struct stmf_pp_data	*ilp_ppd;
71fcf3ce44SJohn Forte } stmf_i_lu_provider_t;
72fcf3ce44SJohn Forte 
73fcf3ce44SJohn Forte typedef struct stmf_i_lu {
74fcf3ce44SJohn Forte 	stmf_lu_t	*ilu_lu;
75fcf3ce44SJohn Forte 	uint32_t	ilu_alloc_size;
76fcf3ce44SJohn Forte 	uint32_t	ilu_flags;
77fcf3ce44SJohn Forte 	uint32_t	ilu_ref_cnt;
78fcf3ce44SJohn Forte 	uint8_t		ilu_state;
79fcf3ce44SJohn Forte 	uint8_t		ilu_prev_state;
8045039663SJohn Forte 	uint8_t		ilu_access;
8145039663SJohn Forte 	uint8_t		ilu_alua;
82fcf3ce44SJohn Forte 	stmf_event_handle_t ilu_event_hdl;
83fcf3ce44SJohn Forte 	struct stmf_i_lu *ilu_next;
84fcf3ce44SJohn Forte 	struct stmf_i_lu *ilu_prev;
85fcf3ce44SJohn Forte 	char		*ilu_alias;
86034d83c4Stim szeto 	char		ilu_ascii_hex_guid[STMF_GUID_INPUT + 1];
87fcf3ce44SJohn Forte 	kmutex_t	ilu_task_lock;
88fcf3ce44SJohn Forte 	uint32_t	ilu_task_cntr1;
89fcf3ce44SJohn Forte 	uint32_t	ilu_task_cntr2;
90fcf3ce44SJohn Forte 	uint32_t	*ilu_cur_task_cntr;
91fcf3ce44SJohn Forte 	uint32_t	ilu_ntasks;	 /* # of tasks in the ilu_task list */
92fcf3ce44SJohn Forte 	uint32_t	ilu_ntasks_free;	/* # of tasks that are free */
93fcf3ce44SJohn Forte 	uint32_t	ilu_ntasks_min_free; /* # minimal free tasks */
94*61dfa509SRick McNeal 	uint32_t	ilu_additional_ref;
9545039663SJohn Forte 	uint32_t	ilu_proxy_registered;
9645039663SJohn Forte 	uint64_t	ilu_reg_msgid;
97fcf3ce44SJohn Forte 	struct stmf_i_scsi_task	*ilu_tasks;
98fcf3ce44SJohn Forte 	struct stmf_i_scsi_task *ilu_free_tasks;
99fcf3ce44SJohn Forte 	struct stmf_itl_data	*ilu_itl_list;
100034d83c4Stim szeto 	kstat_t		*ilu_kstat_info;
101034d83c4Stim szeto 	kstat_t		*ilu_kstat_io;
102034d83c4Stim szeto 	kmutex_t	ilu_kstat_lock;
103a49dc893SSaso Kiselkov 	kcondvar_t	ilu_offline_pending_cv;
104fcf3ce44SJohn Forte 
105fcf3ce44SJohn Forte 	/* point to the luid entry in stmf_state.stmf_luid_list */
106fcf3ce44SJohn Forte 	void		*ilu_luid;
107fcf3ce44SJohn Forte } stmf_i_lu_t;
108fcf3ce44SJohn Forte 
109fcf3ce44SJohn Forte /*
110fcf3ce44SJohn Forte  * ilu_flags
111fcf3ce44SJohn Forte  */
112fcf3ce44SJohn Forte #define	ILU_STALL_DEREGISTER		0x0001
113fcf3ce44SJohn Forte #define	ILU_RESET_ACTIVE		0x0002
114fcf3ce44SJohn Forte 
115fcf3ce44SJohn Forte typedef struct stmf_i_port_provider {
116fcf3ce44SJohn Forte 	stmf_port_provider_t	*ipp_pp;
117fcf3ce44SJohn Forte 	uint32_t		ipp_alloc_size;
118fcf3ce44SJohn Forte 	uint32_t		ipp_npps;
119fcf3ce44SJohn Forte 	uint32_t		ipp_cb_in_progress:1,
120fcf3ce44SJohn Forte 				ipp_rsvd:31;
121fcf3ce44SJohn Forte 	struct stmf_i_port_provider *ipp_next;
122fcf3ce44SJohn Forte 	struct stmf_pp_data	*ipp_ppd;
123fcf3ce44SJohn Forte } stmf_i_port_provider_t;
124fcf3ce44SJohn Forte 
125427fcaf8Stim szeto #define	MAX_ILPORT			0x10000
126427fcaf8Stim szeto 
127fcf3ce44SJohn Forte typedef struct stmf_i_local_port {
128fcf3ce44SJohn Forte 	stmf_local_port_t	*ilport_lport;
129fcf3ce44SJohn Forte 	uint32_t		ilport_alloc_size;
130fcf3ce44SJohn Forte 	uint32_t		ilport_nsessions;
131fcf3ce44SJohn Forte 	struct stmf_i_scsi_session *ilport_ss_list;
132fcf3ce44SJohn Forte 	krwlock_t		ilport_lock;
133fcf3ce44SJohn Forte 	struct stmf_i_local_port *ilport_next;
134fcf3ce44SJohn Forte 	struct stmf_i_local_port *ilport_prev;
135fcf3ce44SJohn Forte 	uint8_t			ilport_state;
136fcf3ce44SJohn Forte 	uint8_t			ilport_prev_state;
13745039663SJohn Forte 	uint8_t			ilport_standby;
13845039663SJohn Forte 	uint8_t			ilport_alua;
139fcf3ce44SJohn Forte 	uint16_t		ilport_rtpid; /* relative tpid */
14045039663SJohn Forte 	uint16_t		ilport_proxy_registered;
14145039663SJohn Forte 	uint64_t		ilport_reg_msgid;
14245039663SJohn Forte 	uint8_t			ilport_no_standby_lu;
14340c3e8ffSJohn Forte 	uint32_t		ilport_unexpected_comp;
144fcf3ce44SJohn Forte 	stmf_event_handle_t	ilport_event_hdl;
145fcf3ce44SJohn Forte 	clock_t			ilport_last_online_clock;
146fcf3ce44SJohn Forte 	clock_t			ilport_avg_interval;
147fcf3ce44SJohn Forte 	uint32_t		ilport_online_times;
148fcf3ce44SJohn Forte 	uint32_t		ilport_flags;
149034d83c4Stim szeto 	kstat_t			*ilport_kstat_info;
150034d83c4Stim szeto 	kstat_t			*ilport_kstat_io;
151034d83c4Stim szeto 	kmutex_t		ilport_kstat_lock;
152034d83c4Stim szeto 	char			ilport_kstat_tgt_name[STMF_TGT_NAME_LEN];
153fcf3ce44SJohn Forte 	/* which target group this port belongs to in stmf_state.stmf_tg_list */
154fcf3ce44SJohn Forte 	void			*ilport_tg;
155427fcaf8Stim szeto 	id_t			ilport_instance;
156fcf3ce44SJohn Forte 	/* XXX Need something to track all the remote ports also */
157fcf3ce44SJohn Forte } stmf_i_local_port_t;
158fcf3ce44SJohn Forte 
159fcf3ce44SJohn Forte #define	STMF_AVG_ONLINE_INTERVAL	(30 * drv_usectohz(1000000))
160fcf3ce44SJohn Forte 
161427fcaf8Stim szeto #define	MAX_IRPORT			0x10000
162427fcaf8Stim szeto 
163427fcaf8Stim szeto typedef struct stmf_i_remote_port {
164427fcaf8Stim szeto 	struct scsi_devid_desc	*irport_id;
165427fcaf8Stim szeto 	kmutex_t		irport_mutex;
166427fcaf8Stim szeto 	int			irport_refcnt;
167427fcaf8Stim szeto 	id_t			irport_instance;
168427fcaf8Stim szeto 	avl_node_t		irport_ln;
169*61dfa509SRick McNeal 	/* number of active read tasks */
170*61dfa509SRick McNeal 	uint32_t		irport_nread_tasks;
171*61dfa509SRick McNeal 	/* number of active write tasks */
172*61dfa509SRick McNeal 	uint32_t		irport_nwrite_tasks;
173*61dfa509SRick McNeal 	hrtime_t		irport_rdstart_timestamp;
174*61dfa509SRick McNeal 	hrtime_t		irport_rddone_timestamp;
175*61dfa509SRick McNeal 	hrtime_t		irport_wrstart_timestamp;
176*61dfa509SRick McNeal 	hrtime_t		irport_wrdone_timestamp;
177*61dfa509SRick McNeal 	kstat_t			*irport_kstat_info;
178*61dfa509SRick McNeal 	kstat_t			*irport_kstat_io;
179*61dfa509SRick McNeal 	kstat_t			*irport_kstat_estat;	/* extended stats */
180*61dfa509SRick McNeal 	boolean_t		irport_info_dirty;
181427fcaf8Stim szeto } stmf_i_remote_port_t;
182427fcaf8Stim szeto 
183fcf3ce44SJohn Forte /*
184fcf3ce44SJohn Forte  * ilport flags
185fcf3ce44SJohn Forte  */
186fcf3ce44SJohn Forte #define	ILPORT_FORCED_OFFLINE		0x01
187fcf3ce44SJohn Forte #define	ILPORT_SS_GOT_INITIAL_LUNS	0x02
188fcf3ce44SJohn Forte 
189fcf3ce44SJohn Forte typedef struct stmf_i_scsi_session {
190fcf3ce44SJohn Forte 	stmf_scsi_session_t	*iss_ss;
191fcf3ce44SJohn Forte 	uint32_t		iss_alloc_size;
192fcf3ce44SJohn Forte 	uint32_t		iss_flags;
193427fcaf8Stim szeto 	stmf_i_remote_port_t	*iss_irport;
194fcf3ce44SJohn Forte 	struct stmf_i_scsi_session *iss_next;
195fcf3ce44SJohn Forte 	/*
196fcf3ce44SJohn Forte 	 * Ideally we should maintain 2 maps. One would indicate a new map
197fcf3ce44SJohn Forte 	 * which will become available only upon receipt of a REPORT LUN
198fcf3ce44SJohn Forte 	 * cmd.
199fcf3ce44SJohn Forte 	 */
200fcf3ce44SJohn Forte 	struct stmf_lun_map	*iss_sm;
201fcf3ce44SJohn Forte 	/*
202fcf3ce44SJohn Forte 	 * which host group the host of this session belongs to in
203fcf3ce44SJohn Forte 	 * stmf_state.stmf_hg_list
204fcf3ce44SJohn Forte 	 */
205fcf3ce44SJohn Forte 	void			*iss_hg;
206fcf3ce44SJohn Forte 	krwlock_t		*iss_lockp;
207fcf3ce44SJohn Forte 	time_t			iss_creation_time;
208fcf3ce44SJohn Forte } stmf_i_scsi_session_t;
209fcf3ce44SJohn Forte 
210fcf3ce44SJohn Forte /*
211fcf3ce44SJohn Forte  * iss flags
212fcf3ce44SJohn Forte  */
213fcf3ce44SJohn Forte #define	ISS_LUN_INVENTORY_CHANGED		0x0001
214fcf3ce44SJohn Forte #define	ISS_RESET_ACTIVE			0x0002
215fcf3ce44SJohn Forte #define	ISS_BEING_CREATED			0x0004
216fcf3ce44SJohn Forte #define	ISS_GOT_INITIAL_LUNS			0x0008
217fcf3ce44SJohn Forte #define	ISS_EVENT_ACTIVE			0x0010
218716c1805SNattuvetty Bhavyan #define	ISS_NULL_TPTID				0x0020
219fcf3ce44SJohn Forte 
220fcf3ce44SJohn Forte #define	ITASK_MAX_NCMDS			14
221fcf3ce44SJohn Forte #define	ITASK_DEFAULT_POLL_TIMEOUT	0
22240c3e8ffSJohn Forte 
22340c3e8ffSJohn Forte #define	ITASK_TASK_AUDIT_DEPTH		32 /* Must be a power of 2 */
22440c3e8ffSJohn Forte 
22540c3e8ffSJohn Forte typedef enum {
22640c3e8ffSJohn Forte 	TE_UNDEFINED,
22740c3e8ffSJohn Forte 	TE_TASK_START,
22840c3e8ffSJohn Forte 	TE_XFER_START,
22940c3e8ffSJohn Forte 	TE_XFER_DONE,
23040c3e8ffSJohn Forte 	TE_SEND_STATUS,
23140c3e8ffSJohn Forte 	TE_SEND_STATUS_DONE,
23240c3e8ffSJohn Forte 	TE_TASK_FREE,
23340c3e8ffSJohn Forte 	TE_TASK_ABORT,
23440c3e8ffSJohn Forte 	TE_TASK_LPORT_ABORTED,
23540c3e8ffSJohn Forte 	TE_TASK_LU_ABORTED,
23640c3e8ffSJohn Forte 	TE_PROCESS_CMD
23740c3e8ffSJohn Forte } task_audit_event_t;
23840c3e8ffSJohn Forte 
23940c3e8ffSJohn Forte #define	CMD_OR_IOF_NA	0xffffffff
24040c3e8ffSJohn Forte 
24140c3e8ffSJohn Forte typedef struct stmf_task_audit_rec {
24240c3e8ffSJohn Forte 	task_audit_event_t	ta_event;
24340c3e8ffSJohn Forte 	uint32_t		ta_cmd_or_iof;
24440c3e8ffSJohn Forte 	uint32_t		ta_itask_flags;
24540c3e8ffSJohn Forte 	stmf_data_buf_t		*ta_dbuf;
24640c3e8ffSJohn Forte 	timespec_t		ta_timestamp;
24740c3e8ffSJohn Forte } stmf_task_audit_rec_t;
24840c3e8ffSJohn Forte 
249fcf3ce44SJohn Forte struct stmf_worker;
250fcf3ce44SJohn Forte typedef struct stmf_i_scsi_task {
251fcf3ce44SJohn Forte 	scsi_task_t		*itask_task;
252fcf3ce44SJohn Forte 	uint32_t		itask_alloc_size;
253fcf3ce44SJohn Forte 	uint32_t		itask_flags;
254*61dfa509SRick McNeal 	kmutex_t		itask_mutex; /* protects flags and lists */
25545039663SJohn Forte 	uint64_t		itask_proxy_msg_id;
25645039663SJohn Forte 	stmf_data_buf_t		*itask_proxy_dbuf;
257fcf3ce44SJohn Forte 	struct stmf_worker	*itask_worker;
258fcf3ce44SJohn Forte 	uint32_t		*itask_ilu_task_cntr;
259fcf3ce44SJohn Forte 	struct stmf_i_scsi_task	*itask_worker_next;
260fcf3ce44SJohn Forte 	struct stmf_i_scsi_task	*itask_lu_next;
261fcf3ce44SJohn Forte 	struct stmf_i_scsi_task	*itask_lu_prev;
262fcf3ce44SJohn Forte 	struct stmf_i_scsi_task	*itask_lu_free_next;
263fcf3ce44SJohn Forte 	struct stmf_itl_data	*itask_itl_datap;
264fcf3ce44SJohn Forte 	clock_t			itask_start_time;	/* abort and normal */
265fcf3ce44SJohn Forte 	/* For now we only support 4 parallel buffers. Should be enough. */
266fcf3ce44SJohn Forte 	stmf_data_buf_t		*itask_dbufs[4];
267fcf3ce44SJohn Forte 	clock_t			itask_poll_timeout;
268fcf3ce44SJohn Forte 	uint8_t			itask_cmd_stack[ITASK_MAX_NCMDS];
269fcf3ce44SJohn Forte 	uint8_t			itask_ncmds;
270fcf3ce44SJohn Forte 	uint8_t			itask_allocated_buf_map;
271fcf3ce44SJohn Forte 	uint16_t		itask_cdb_buf_size;
272427fcaf8Stim szeto 
273427fcaf8Stim szeto 	/* Task profile data */
274427fcaf8Stim szeto 	hrtime_t		itask_start_timestamp;
275427fcaf8Stim szeto 	hrtime_t		itask_done_timestamp;
276*61dfa509SRick McNeal 	hrtime_t		itask_xfer_done_timestamp;
277427fcaf8Stim szeto 	hrtime_t		itask_waitq_enter_timestamp;
278427fcaf8Stim szeto 	hrtime_t		itask_waitq_time;
279427fcaf8Stim szeto 	hrtime_t		itask_lu_read_time;
280427fcaf8Stim szeto 	hrtime_t		itask_lu_write_time;
281427fcaf8Stim szeto 	hrtime_t		itask_lport_read_time;
282427fcaf8Stim szeto 	hrtime_t		itask_lport_write_time;
283427fcaf8Stim szeto 	uint64_t		itask_read_xfer;
284427fcaf8Stim szeto 	uint64_t		itask_write_xfer;
28540c3e8ffSJohn Forte 	kmutex_t		itask_audit_mutex;
28640c3e8ffSJohn Forte 	uint8_t			itask_audit_index;
28740c3e8ffSJohn Forte 	stmf_task_audit_rec_t	itask_audit_records[ITASK_TASK_AUDIT_DEPTH];
288fcf3ce44SJohn Forte } stmf_i_scsi_task_t;
289fcf3ce44SJohn Forte 
290fcf3ce44SJohn Forte #define	ITASK_DEFAULT_ABORT_TIMEOUT	5
291fcf3ce44SJohn Forte 
292*61dfa509SRick McNeal /*
293*61dfa509SRick McNeal  * Common code to encode an itask onto the worker_task queue is placed
294*61dfa509SRick McNeal  * in this macro to simplify future maintenace activity.
295*61dfa509SRick McNeal  */
296*61dfa509SRick McNeal #define	STMF_ENQUEUE_ITASK(w, i) \
297*61dfa509SRick McNeal 	ASSERT((itask->itask_flags & ITASK_IN_FREE_LIST) == 0); \
298*61dfa509SRick McNeal 	ASSERT(mutex_owned(&itask->itask_mutex)); \
299*61dfa509SRick McNeal 	ASSERT(mutex_owned(&w->worker_lock)); \
300*61dfa509SRick McNeal 	i->itask_worker_next = NULL; \
301*61dfa509SRick McNeal 	if (w->worker_task_tail) { \
302*61dfa509SRick McNeal 		w->worker_task_tail->itask_worker_next = i; \
303*61dfa509SRick McNeal 	} else { \
304*61dfa509SRick McNeal 		w->worker_task_head = i; \
305*61dfa509SRick McNeal 	} \
306*61dfa509SRick McNeal 	w->worker_task_tail = i; \
307*61dfa509SRick McNeal 	if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) { \
308*61dfa509SRick McNeal 		w->worker_max_qdepth_pu = w->worker_queue_depth; \
309*61dfa509SRick McNeal 	} \
310*61dfa509SRick McNeal 	atomic_inc_32(&w->worker_ref_count); \
311*61dfa509SRick McNeal 	atomic_or_32(&itask->itask_flags, ITASK_IN_WORKER_QUEUE); \
312*61dfa509SRick McNeal 	i->itask_waitq_enter_timestamp = gethrtime(); \
313*61dfa509SRick McNeal 	if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0) \
314*61dfa509SRick McNeal 		cv_signal(&w->worker_cv);
315*61dfa509SRick McNeal 
316*61dfa509SRick McNeal #define	STMF_DEQUEUE_ITASK(w, itask) \
317*61dfa509SRick McNeal 	ASSERT(mutex_owned(&w->worker_lock)); \
318*61dfa509SRick McNeal 	if ((itask = w->worker_task_head) != NULL) { \
319*61dfa509SRick McNeal 		w->worker_task_head = itask->itask_worker_next; \
320*61dfa509SRick McNeal 		if (w->worker_task_head == NULL) { \
321*61dfa509SRick McNeal 			w->worker_task_tail = NULL; \
322*61dfa509SRick McNeal 		} \
323*61dfa509SRick McNeal 	} else { \
324*61dfa509SRick McNeal 		w->worker_task_tail = NULL; \
325*61dfa509SRick McNeal 	}
326*61dfa509SRick McNeal 
327fcf3ce44SJohn Forte /*
328fcf3ce44SJohn Forte  * itask_flags
329fcf3ce44SJohn Forte  */
330fcf3ce44SJohn Forte #define	ITASK_IN_FREE_LIST		0x0001
331fcf3ce44SJohn Forte #define	ITASK_IN_TRANSITION		0x0002
332fcf3ce44SJohn Forte #define	ITASK_IN_WORKER_QUEUE		0x0004
333fcf3ce44SJohn Forte #define	ITASK_BEING_ABORTED		0x0008
334fcf3ce44SJohn Forte #define	ITASK_BEING_COMPLETED		0x0010
335fcf3ce44SJohn Forte #define	ITASK_KNOWN_TO_TGT_PORT		0x0020
336fcf3ce44SJohn Forte #define	ITASK_KNOWN_TO_LU		0x0040
337fcf3ce44SJohn Forte #define	ITASK_LU_ABORT_CALLED		0x0080
338fcf3ce44SJohn Forte #define	ITASK_TGT_PORT_ABORT_CALLED	0x0100
339fcf3ce44SJohn Forte #define	ITASK_DEFAULT_HANDLING		0x0200
340fcf3ce44SJohn Forte #define	ITASK_CAUSING_LU_RESET		0x0400
341fcf3ce44SJohn Forte #define	ITASK_CAUSING_TARGET_RESET	0x0800
342554c2b16Stim szeto #define	ITASK_KSTAT_IN_RUNQ		0x1000
34345039663SJohn Forte #define	ITASK_PROXY_TASK		0x2000
344fcf3ce44SJohn Forte 
345fcf3ce44SJohn Forte /*
346fcf3ce44SJohn Forte  * itask cmds.
347fcf3ce44SJohn Forte  */
348fcf3ce44SJohn Forte #define	ITASK_CMD_MASK			0x1F
349fcf3ce44SJohn Forte #define	ITASK_CMD_BUF_NDX(cmd)		(((uint8_t)(cmd)) >> 5)
350fcf3ce44SJohn Forte #define	ITASK_CMD_NEW_TASK		0x1
351fcf3ce44SJohn Forte #define	ITASK_CMD_DATA_XFER_DONE	0x2
352fcf3ce44SJohn Forte #define	ITASK_CMD_STATUS_DONE		0x3
353fcf3ce44SJohn Forte #define	ITASK_CMD_ABORT			0x4
354fcf3ce44SJohn Forte #define	ITASK_CMD_SEND_STATUS		0x5
355fcf3ce44SJohn Forte #define	ITASK_CMD_POLL			0x10
356fcf3ce44SJohn Forte #define	ITASK_CMD_POLL_LU		(ITASK_CMD_POLL | 1)
357fcf3ce44SJohn Forte #define	ITASK_CMD_POLL_LPORT		(ITASK_CMD_POLL | 2)
358fcf3ce44SJohn Forte 
359fcf3ce44SJohn Forte /*
360fcf3ce44SJohn Forte  * struct maintained on a per itl basis when the lu registers ITL handle.
361fcf3ce44SJohn Forte  */
362fcf3ce44SJohn Forte typedef struct stmf_itl_data {
363fcf3ce44SJohn Forte 	uint32_t			itl_counter;
364fcf3ce44SJohn Forte 	uint8_t				itl_flags;
365fcf3ce44SJohn Forte 	uint8_t				itl_hdlrm_reason;
366fcf3ce44SJohn Forte 	uint16_t			itl_lun;
367fcf3ce44SJohn Forte 	void				*itl_handle;
368427fcaf8Stim szeto 	struct stmf_i_lu		*itl_ilu;
369fcf3ce44SJohn Forte 	struct stmf_i_scsi_session	*itl_session;
370fcf3ce44SJohn Forte 	struct stmf_itl_data		*itl_next;
371fcf3ce44SJohn Forte } stmf_itl_data_t;
372fcf3ce44SJohn Forte 
373fcf3ce44SJohn Forte /*
374fcf3ce44SJohn Forte  * itl flags
375fcf3ce44SJohn Forte  */
376fcf3ce44SJohn Forte #define	STMF_ITL_BEING_TERMINATED	0x01
377fcf3ce44SJohn Forte 
378fcf3ce44SJohn Forte /*
379fcf3ce44SJohn Forte  * data structures to maintain provider private data.
380fcf3ce44SJohn Forte  */
381fcf3ce44SJohn Forte typedef struct stmf_pp_data {
382fcf3ce44SJohn Forte 	struct stmf_pp_data	*ppd_next;
383fcf3ce44SJohn Forte 	void			*ppd_provider;
384fcf3ce44SJohn Forte 	nvlist_t		*ppd_nv;
385fcf3ce44SJohn Forte 	uint32_t		ppd_lu_provider:1,
386fcf3ce44SJohn Forte 				ppd_port_provider:1,
387fcf3ce44SJohn Forte 				ppd_rsvd:30;
388fcf3ce44SJohn Forte 	uint32_t		ppd_alloc_size;
3898fe96085Stim szeto 	uint64_t		ppd_token;
390fcf3ce44SJohn Forte 	char			ppd_name[8];
391fcf3ce44SJohn Forte } stmf_pp_data_t;
392fcf3ce44SJohn Forte 
393fcf3ce44SJohn Forte typedef struct stmf_worker {
394fcf3ce44SJohn Forte 	kthread_t		*worker_tid;
395fcf3ce44SJohn Forte 	stmf_i_scsi_task_t	*worker_task_head;
396fcf3ce44SJohn Forte 	stmf_i_scsi_task_t	*worker_task_tail;
397fcf3ce44SJohn Forte 	stmf_i_scsi_task_t	*worker_wait_head;
398fcf3ce44SJohn Forte 	stmf_i_scsi_task_t	*worker_wait_tail;
399fcf3ce44SJohn Forte 	kmutex_t		worker_lock;
400fcf3ce44SJohn Forte 	kcondvar_t		worker_cv;
401fcf3ce44SJohn Forte 	uint32_t		worker_flags;
402fcf3ce44SJohn Forte 	uint32_t		worker_queue_depth;	/* ntasks cur queued */
403fcf3ce44SJohn Forte 	uint32_t		worker_max_qdepth_pu;	/* maxqd / unit time */
404fcf3ce44SJohn Forte 	uint32_t		worker_max_sys_qdepth_pu; /* for all workers */
405fcf3ce44SJohn Forte 	uint32_t		worker_ref_count;	/* # IOs referencing */
406427fcaf8Stim szeto 	hrtime_t		worker_signal_timestamp;
407fcf3ce44SJohn Forte } stmf_worker_t;
408fcf3ce44SJohn Forte 
409fcf3ce44SJohn Forte /*
410fcf3ce44SJohn Forte  * worker flags
411fcf3ce44SJohn Forte  */
412fcf3ce44SJohn Forte #define	STMF_WORKER_STARTED		1
413fcf3ce44SJohn Forte #define	STMF_WORKER_ACTIVE		2
414fcf3ce44SJohn Forte #define	STMF_WORKER_TERMINATE		4
415fcf3ce44SJohn Forte 
416fcf3ce44SJohn Forte /*
417fcf3ce44SJohn Forte  * data struct for managing transfers.
418fcf3ce44SJohn Forte  */
419fcf3ce44SJohn Forte typedef struct stmf_xfer_data {
420fcf3ce44SJohn Forte 	uint32_t	alloc_size;	/* Including this struct */
421fcf3ce44SJohn Forte 	uint32_t	size_done;
422fcf3ce44SJohn Forte 	uint32_t	size_left;
423fcf3ce44SJohn Forte 	uint8_t		buf[4];
424fcf3ce44SJohn Forte } stmf_xfer_data_t;
425fcf3ce44SJohn Forte 
426fcf3ce44SJohn Forte /*
427fcf3ce44SJohn Forte  * Define frequently used macros
428fcf3ce44SJohn Forte  */
429fcf3ce44SJohn Forte #define	TASK_TO_ITASK(x_task)	\
430fcf3ce44SJohn Forte 	((stmf_i_scsi_task_t *)(x_task)->task_stmf_private)
431fcf3ce44SJohn Forte 
432fcf3ce44SJohn Forte void stmf_dlun_init();
433fcf3ce44SJohn Forte stmf_status_t stmf_dlun_fini();
434fcf3ce44SJohn Forte void stmf_worker_init();
435fcf3ce44SJohn Forte stmf_status_t stmf_worker_fini();
436fcf3ce44SJohn Forte void stmf_task_free(scsi_task_t *task);
437fcf3ce44SJohn Forte void stmf_do_task_abort(scsi_task_t *task);
438fcf3ce44SJohn Forte void stmf_do_itl_dereg(stmf_lu_t *lu, stmf_itl_data_t *itl,
439fcf3ce44SJohn Forte 		uint8_t hdlrm_reason);
440fcf3ce44SJohn Forte void stmf_generate_lu_event(stmf_i_lu_t *ilu, int eventid,
441fcf3ce44SJohn Forte 				void *arg, uint32_t flags);
442fcf3ce44SJohn Forte void stmf_generate_lport_event(stmf_i_local_port_t *ilport, int eventid,
443fcf3ce44SJohn Forte 						void *arg, uint32_t flags);
444fcf3ce44SJohn Forte 
445fcf3ce44SJohn Forte #ifdef	__cplusplus
446fcf3ce44SJohn Forte }
447fcf3ce44SJohn Forte #endif
448fcf3ce44SJohn Forte 
449fcf3ce44SJohn Forte #endif /* _STMF_IMPL_H */
450