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