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) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright 2013, 2015 Nexenta Systems, Inc. All rights reserved.
24  */
25 #ifndef _PPPT_H
26 #define	_PPPT_H
27 
28 #include <sys/pppt_ic_if.h>
29 
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 #define	PPPT_GLOBAL_LOCK() mutex_enter(&pppt_global.global_lock)
35 #define	PPPT_GLOBAL_UNLOCK() mutex_exit(&pppt_global.global_lock)
36 
37 extern int pppt_logging;
38 
39 #define	PPPT_LOG if (pppt_logging) cmn_err
40 
41 #define	TGT_DEREG_RETRY_SECONDS	1
42 
43 typedef enum {
44 	PPPT_STATUS_SUCCESS = 0,
45 	PPPT_STATUS_FAIL,
46 	PPPT_STATUS_ABORTED,
47 	PPPT_STATUS_DONE
48 } pppt_status_t;
49 
50 #define	PPPT_MODNAME "pppt"
51 
52 #define	TGT_STATE_LIST() \
53 	item(TS_UNDEFINED) \
54 	item(TS_CREATED) \
55 	item(TS_ONLINING) \
56 	item(TS_ONLINE) \
57 	item(TS_STMF_ONLINE) \
58 	item(TS_DELETING_NEED_OFFLINE) \
59 	item(TS_OFFLINING) \
60 	item(TS_OFFLINE) \
61 	item(TS_STMF_OFFLINE) \
62 	item(TS_DELETING_STMF_DEREG) \
63 	item(TS_DELETING_STMF_DEREG_FAIL) \
64 	item(TS_DELETING) \
65 	item(TS_MAX_STATE)
66 
67 /* Target states and events, update pppt_ts_name table whenever modified */
68 typedef enum {
69 #define	item(a) a,
70 	TGT_STATE_LIST()
71 #undef	item
72 } pppt_tgt_state_t;
73 
74 #ifdef PPPT_TGT_SM_STRINGS
75 static const char *pppt_ts_name[TS_MAX_STATE + 1] = {
76 #define	item(a) #a,
77 	TGT_STATE_LIST()
78 #undef	item
79 };
80 #endif
81 
82 #define	TGT_EVENT_LIST() \
83 	item(TE_UNDEFINED) \
84 	item(TE_STMF_ONLINE_REQ) \
85 	item(TE_ONLINE_SUCCESS) \
86 	item(TE_ONLINE_FAIL) \
87 	item(TE_STMF_ONLINE_COMPLETE_ACK) \
88 	item(TE_STMF_OFFLINE_REQ) \
89 	item(TE_OFFLINE_COMPLETE) \
90 	item(TE_STMF_OFFLINE_COMPLETE_ACK) \
91 	item(TE_DELETE) \
92 	item(TE_STMF_DEREG_SUCCESS) \
93 	item(TE_STMF_DEREG_FAIL) \
94 	item(TE_STMF_DEREG_RETRY) \
95 	item(TE_WAIT_REF_COMPLETE) /* XXX */ \
96 	item(TE_MAX_EVENT)
97 
98 typedef enum {
99 #define	item(a) a,
100 	TGT_EVENT_LIST()
101 #undef	item
102 } pppt_tgt_event_t;
103 
104 #ifdef PPPT_TGT_SM_STRINGS
105 static const char *pppt_te_name[TE_MAX_EVENT + 1] = {
106 #define	item(a) #a,
107 	TGT_EVENT_LIST()
108 #undef	item
109 };
110 #endif
111 
112 typedef struct pppt_tgt_s {
113 	kmutex_t		target_mutex;
114 	kcondvar_t		target_cv;
115 	avl_node_t		target_global_ln;
116 	scsi_devid_desc_t	*target_devid;
117 	stmf_local_port_t	*target_stmf_lport;
118 	avl_tree_t		target_sess_list;
119 
120 	/* Target state */
121 	boolean_t		target_sm_busy;
122 	boolean_t		target_deleting;
123 	pppt_tgt_state_t	target_state;
124 	pppt_tgt_state_t	target_last_state;
125 	int			target_refcount;
126 	list_t			target_events;
127 } pppt_tgt_t;
128 
129 typedef struct {
130 	struct pppt_tgt_s	*ps_target;
131 	uint64_t		ps_session_id;
132 	int			ps_refcnt;
133 	kmutex_t		ps_mutex;
134 	kcondvar_t		ps_cv;
135 	boolean_t		ps_closed;
136 	avl_node_t		ps_global_ln;
137 	avl_node_t		ps_target_ln;
138 	avl_tree_t		ps_task_list;
139 	stmf_scsi_session_t	*ps_stmf_sess;
140 } pppt_sess_t;
141 
142 typedef struct {
143 	stmf_data_buf_t		*pbuf_stmf_buf;
144 	boolean_t		pbuf_is_immed;
145 	stmf_ic_msg_t		*pbuf_immed_msg;
146 } pppt_buf_t;
147 
148 typedef enum {
149 	PTS_INIT = 0,
150 	PTS_ACTIVE,
151 	PTS_DONE,
152 	PTS_SENT_STATUS,
153 	PTS_ABORTED
154 } pppt_task_state_t;
155 
156 typedef struct {
157 	pppt_sess_t		*pt_sess;
158 	avl_node_t		pt_sess_ln;
159 	int			pt_refcnt;
160 	kmutex_t		pt_mutex;
161 	stmf_ic_msgid_t		pt_task_id;
162 	uint8_t			pt_lun_id[16];
163 	pppt_task_state_t	pt_state;
164 	scsi_task_t		*pt_stmf_task;
165 	pppt_buf_t		*pt_immed_data;
166 	pppt_buf_t		*pt_read_buf;
167 	stmf_ic_msgid_t		pt_read_xfer_msgid;
168 } pppt_task_t;
169 
170 /*
171  * Error statistics
172  */
173 typedef struct {
174 	uint64_t		es_tgt_reg_svc_disabled;
175 	uint64_t		es_tgt_reg_duplicate;
176 	uint64_t		es_tgt_reg_create_fail;
177 	uint64_t		es_tgt_dereg_svc_disabled;
178 	uint64_t		es_tgt_dereg_not_found;
179 	uint64_t		es_sess_destroy_no_session;
180 	uint64_t		es_sess_lookup_no_session;
181 	uint64_t		es_sess_lookup_ident_mismatch;
182 	uint64_t		es_sess_lookup_bad_tgt_state;
183 	uint64_t		es_scmd_ptask_alloc_fail;
184 	uint64_t		es_scmd_sess_create_fail;
185 	uint64_t		es_scmd_stask_alloc_fail;
186 	uint64_t		es_scmd_dup_task_count;
187 } pppt_error_stats_t;
188 
189 #define	PPPT_INC_STAT(stat_field) \
190 	atomic_inc_64(&pppt_global.global_error_stats.stat_field);
191 
192 /*
193  * State values for the iscsit service
194  */
195 typedef enum {
196 	PSS_UNDEFINED = 0,
197 	PSS_DETACHED,
198 	PSS_DISABLED,
199 	PSS_ENABLING,
200 	PSS_ENABLED,
201 	PSS_BUSY,
202 	PSS_DISABLING
203 } pppt_service_state_t;
204 
205 
206 typedef struct {
207 	pppt_service_state_t	global_svc_state;
208 	dev_info_t		*global_dip;
209 	stmf_port_provider_t	*global_pp;
210 	stmf_dbuf_store_t	*global_dbuf_store;
211 	taskq_t			*global_dispatch_taskq;
212 	taskq_t			*global_sess_taskq;
213 	avl_tree_t		global_sess_list;
214 	avl_tree_t		global_target_list;
215 	kmutex_t		global_lock;
216 	door_handle_t		global_door;
217 	kmutex_t		global_door_lock;
218 	pppt_error_stats_t	global_error_stats;
219 } pppt_global_t;
220 
221 extern pppt_global_t pppt_global;
222 
223 stmf_status_t pppt_lport_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf,
224     uint32_t ioflags);
225 
226 void pppt_xfer_read_complete(pppt_task_t *pppt_task, stmf_status_t status);
227 
228 stmf_status_t pppt_lport_send_status(scsi_task_t *task, uint32_t ioflags);
229 
230 void pppt_lport_task_free(scsi_task_t *task);
231 
232 stmf_status_t pppt_lport_abort(stmf_local_port_t *lport, int abort_cmd,
233     void *arg, uint32_t flags);
234 
235 void pppt_lport_ctl(stmf_local_port_t *lport, int cmd, void *arg);
236 
237 pppt_sess_t *pppt_sess_lookup_locked(uint64_t session_id,
238     scsi_devid_desc_t *lport_devid,
239     stmf_remote_port_t *rport);
240 
241 pppt_sess_t *pppt_sess_lookup_by_id_locked(uint64_t session_id);
242 
243 pppt_sess_t *pppt_sess_lookup_create(scsi_devid_desc_t *lport_devid,
244     scsi_devid_desc_t *rport_devid, stmf_remote_port_t *rport,
245     uint64_t session_id, stmf_status_t *statusp);
246 
247 void pppt_sess_rele(pppt_sess_t *sks);
248 
249 void pppt_sess_rele_locked(pppt_sess_t *sks);
250 
251 void pppt_sess_close_locked(pppt_sess_t *ps);
252 
253 int pppt_sess_avl_compare_by_id(const void *void_sess1,
254     const void *void_sess2);
255 
256 int pppt_sess_avl_compare_by_name(const void *void_sess1,
257     const void *void_sess2);
258 
259 pppt_task_t *pppt_task_alloc(void);
260 
261 void pppt_task_free(pppt_task_t *ptask);
262 
263 pppt_status_t pppt_task_start(pppt_task_t *ptask);
264 
265 pppt_status_t pppt_task_done(pppt_task_t *ptask);
266 
267 pppt_task_t *pppt_task_lookup(stmf_ic_msgid_t msgid);
268 
269 void pppt_msg_rx(stmf_ic_msg_t *msg);
270 
271 void pppt_msg_tx_status(stmf_ic_msg_t *orig_msg, stmf_status_t status);
272 
273 pppt_tgt_t *pppt_tgt_lookup(scsi_devid_desc_t *tgt_devid);
274 
275 pppt_tgt_t *pppt_tgt_lookup_locked(scsi_devid_desc_t *tgt_devid);
276 
277 pppt_tgt_t *pppt_tgt_create(stmf_ic_reg_port_msg_t *reg_port,
278     stmf_status_t *errcode);
279 
280 void pppt_tgt_async_delete(pppt_tgt_t *tgt);
281 
282 void pppt_tgt_destroy(pppt_tgt_t *tgt);
283 
284 int pppt_tgt_avl_compare(const void *void_tgt1, const void *void_tgt2);
285 
286 void pppt_tgt_sm_ctl(stmf_local_port_t *lport, int cmd, void *arg);
287 
288 pppt_status_t pppt_task_hold(pppt_task_t *);
289 
290 #ifdef	__cplusplus
291 }
292 #endif
293 
294 #endif	/* _PPPT_H */
295