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