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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2013 by Delphix. All rights reserved.
26 */
27
28 #ifndef _STMF_H
29 #define _STMF_H
30
31 #include <sys/stmf_defines.h>
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 typedef enum stmf_struct_id {
38 STMF_STRUCT_LU_PROVIDER = 1,
39 STMF_STRUCT_PORT_PROVIDER,
40 STMF_STRUCT_STMF_LOCAL_PORT,
41 STMF_STRUCT_STMF_LU,
42 STMF_STRUCT_SCSI_SESSION,
43 STMF_STRUCT_SCSI_TASK,
44 STMF_STRUCT_DATA_BUF,
45 STMF_STRUCT_DBUF_STORE,
46 STMF_MAX_STRUCT_IDS
47 } stmf_struct_id_t;
48
49 /*
50 * Provider callback commands
51 */
52 #define STMF_PROVIDER_DATA_UPDATED 0x01
53
54 /*
55 * Provider callback flags
56 */
57 #define STMF_PCB_STMF_ONLINING 0x0001
58 #define STMF_PCB_PREG_COMPLETE 0x0002
59
60 typedef void *data_seg_handle_t;
61 #define STMF_MAX_LU_CACHE_NTASKS 16
62
63 #define STMF_NO_HANDLE 0xffffffff
64
65 #define COMPANY_ID_NONE 0xFFFFFFFF
66 #define COMPANY_ID_SUN 0x00144F
67
68 /*
69 * The scatter/gather list buffer format is used in 2 different
70 * contexts within stmf:
71 * 1) supplied by the port provider that the LU provider uses to exchange
72 * data with the backing store.
73 * 2) supplied by the LU provider that the port provider uses exchange
74 * data with the host initiator.
75 * The second format is optionally supported by the port provided as
76 * indicated by the command task flags.
77 */
78
79 typedef struct stmf_sglist_ent {
80 uint32_t seg_length;
81 uint8_t *seg_addr;
82 } stmf_sglist_ent_t;
83
84 typedef struct stmf_data_buf {
85 void *db_stmf_private;
86 void *db_port_private;
87 void *db_lu_private;
88 uint32_t db_buf_size; /* Total size of this buffer */
89 uint32_t db_data_size; /* Intended xfer size of this buffer */
90 uint32_t db_relative_offset;
91 uint16_t db_sglist_length;
92 uint16_t db_flags; /* Direction, auto status etc */
93 stmf_status_t db_xfer_status;
94 uint8_t db_handle; /* To track parallel buffers */
95 hrtime_t db_xfer_start_timestamp;
96 stmf_sglist_ent_t db_sglist[1]; /* PP scatter/gather list */
97 } stmf_data_buf_t;
98
99 /*
100 * db_flags
101 */
102 #define DB_DIRECTION_TO_RPORT 0x0001
103 #define DB_DIRECTION_FROM_RPORT 0x0002
104 #define DB_SEND_STATUS_GOOD 0x0004
105 #define DB_STATUS_GOOD_SENT 0x0008
106 #define DB_DONT_CACHE 0x0010
107 #define DB_DONT_REUSE 0x0020
108 #define DB_LU_DATA_BUF 0x0040
109 #define DB_LPORT_XFER_ACTIVE 0x8000
110
111 typedef struct scsi_task {
112 void *task_stmf_private;
113 void *task_port_private;
114
115 void *task_lu_private;
116 struct stmf_scsi_session *task_session;
117 struct stmf_local_port *task_lport;
118 struct stmf_lu *task_lu;
119 void *task_lu_itl_handle; /* Assigned by LU */
120
121 /* CMD information from initiator */
122 uint8_t task_lun_no[8];
123 uint8_t task_flags; /* See def. for task flags */
124 uint8_t task_priority; /* As per SAM-3 */
125 uint8_t task_mgmt_function; /* If this is a TM request */
126 uint8_t task_max_nbufs;
127 uint8_t task_cur_nbufs;
128 uint8_t task_csn_size; /* cmd seq no size in bits */
129 uint16_t task_additional_flags;
130 uint32_t task_cmd_seq_no;
131 uint32_t task_expected_xfer_length;
132 uint32_t task_timeout; /* In seconds */
133 uint16_t task_ext_id;
134 uint16_t task_cdb_length;
135 uint8_t *task_cdb;
136
137 /* Fields to manage data phase */
138 uint32_t task_cmd_xfer_length; /* xfer len based on CDB */
139 uint32_t task_nbytes_transferred;
140 uint32_t task_max_xfer_len; /* largest xfer allowed */
141 uint32_t task_1st_xfer_len; /* 1st xfer hint */
142 uint32_t task_copy_threshold; /* copy reduction threshold */
143
144
145 /* Status Phase */
146 stmf_status_t task_completion_status;
147 uint32_t task_resid;
148 uint8_t task_status_ctrl; /* See def. for status ctrl */
149 uint8_t task_scsi_status;
150 uint16_t task_sense_length;
151 uint8_t *task_sense_data;
152
153 /* Misc. task data */
154 void *task_extended_cmd;
155
156 } scsi_task_t;
157
158 /*
159 * Maximum expected transfer length. Can also be used when the transfer
160 * length is unknown when the task is allocated (e.g. SAS)
161 */
162
163 #define TASK_MAX_XFER_LENGTH 0xFFFFFFFF
164
165 /*
166 * task_flags definitions.
167 */
168 /*
169 * If TF_INITIAL_BURST is set, the dbuf passed with new_task() contains
170 * data from initial burst. Otherwise its just a buffer which the port
171 * passed to the LU.
172 */
173 #define TF_INITIAL_BURST 0x80
174 /* Both READ_DATA and WRITE_DATA can be set for bidirectional xfers */
175 #define TF_READ_DATA 0x40
176 #define TF_WRITE_DATA 0x20
177 #define TF_ATTR_MASK 0x07
178 #define TF_ATTR_UNTAGGED 0x0
179 #define TF_ATTR_SIMPLE_QUEUE 0x1
180 #define TF_ATTR_ORDERED_QUEUE 0x2
181 #define TF_ATTR_HEAD_OF_QUEUE 0x3
182 #define TF_ATTR_ACA 0x4
183
184 /*
185 * Task Management flags.
186 */
187 #define TM_NONE 0x00
188 #define TM_ABORT_TASK 0x01
189 #define TM_ABORT_TASK_SET 0x02
190 #define TM_CLEAR_ACA 0x03
191 #define TM_CLEAR_TASK_SET 0x04
192 #define TM_LUN_RESET 0x05
193 #define TM_TARGET_WARM_RESET 0x06
194 #define TM_TARGET_COLD_RESET 0x07
195 #define TM_TASK_REASSIGN 0x08
196 #define TM_TARGET_RESET 0x09
197 #define TM_QUERY_TASK 0x0A
198
199 /*
200 * additional flags
201 */
202 #define TASK_AF_ENABLE_COMP_CONF 0x01
203 #define TASK_AF_PORT_LOAD_HIGH 0x02
204 #define TASK_AF_NO_EXPECTED_XFER_LENGTH 0x04
205 /*
206 * PP sets this flag if it can process dbufs created by the LU.
207 */
208 #define TASK_AF_ACCEPT_LU_DBUF 0x08
209
210 /*
211 * Indicating a PPPT task
212 */
213 #define TASK_AF_PPPT_TASK 0x10
214
215 /*
216 * scsi_task_t extension identifiers
217 */
218 #define STMF_TASK_EXT_NONE 0
219
220 /*
221 * max_nbufs
222 */
223 #define STMF_BUFS_MAX 255
224
225 /*
226 * Task status ctrl
227 */
228 #define TASK_SCTRL_OVER 1
229 #define TASK_SCTRL_UNDER 2
230
231 /*
232 * The flags used by I/O flow.
233 */
234 #define STMF_IOF_LU_DONE 0x0001
235 #define STMF_IOF_LPORT_DONE 0x0002
236 #define STMF_IOF_STATS_ONLY 0x0004
237
238 /*
239 * struct allocation flags
240 */
241 #define AF_FORCE_NOSLEEP 0x0001
242 #define AF_DONTZERO 0x0002
243
244 typedef struct stmf_state_change_info {
245 uint64_t st_rflags; /* Reason behind this change */
246 char *st_additional_info;
247 } stmf_state_change_info_t;
248
249 typedef struct stmf_change_status {
250 stmf_status_t st_completion_status;
251 char *st_additional_info;
252 } stmf_change_status_t;
253
254 /*
255 * conditions causing or affecting the change.
256 */
257 #define STMF_RFLAG_USER_REQUEST 0x0001
258 #define STMF_RFLAG_FATAL_ERROR 0x0002
259 #define STMF_RFLAG_STAY_OFFLINED 0x0004
260 #define STMF_RFLAG_RESET 0x0008
261 #define STMF_RFLAG_COLLECT_DEBUG_DUMP 0x0010
262 #define STMF_RFLAG_LU_ABORT 0x0020
263 #define STMF_RFLAG_LPORT_ABORT 0x0040
264
265 #define STMF_CHANGE_INFO_LEN 160
266
267 /*
268 * cmds to stmf_abort entry point
269 */
270 #define STMF_QUEUE_TASK_ABORT 1
271 #define STMF_REQUEUE_TASK_ABORT_LPORT 2
272 #define STMF_REQUEUE_TASK_ABORT_LU 3
273 #define STMF_QUEUE_ABORT_LU 4
274
275 /*
276 * cmds to be used by stmf ctl
277 */
278 #define STMF_CMD_LU_OP 0x0100
279 #define STMF_CMD_LPORT_OP 0x0200
280 #define STMF_CMD_MASK 0x00ff
281 #define STMF_CMD_ONLINE 0x0001
282 #define STMF_CMD_OFFLINE 0x0002
283 #define STMF_CMD_GET_STATUS 0x0003
284 #define STMF_CMD_ONLINE_COMPLETE 0x0004
285 #define STMF_CMD_OFFLINE_COMPLETE 0x0005
286 #define STMF_ACK_ONLINE_COMPLETE 0x0006
287 #define STMF_ACK_OFFLINE_COMPLETE 0x0007
288
289 #define STMF_CMD_LU_ONLINE (STMF_CMD_LU_OP | STMF_CMD_ONLINE)
290 #define STMF_CMD_LU_OFFLINE (STMF_CMD_LU_OP | STMF_CMD_OFFLINE)
291 #define STMF_CMD_LPORT_ONLINE (STMF_CMD_LPORT_OP | STMF_CMD_ONLINE)
292 #define STMF_CMD_LPORT_OFFLINE (STMF_CMD_LPORT_OP | STMF_CMD_OFFLINE)
293 #define STMF_CMD_GET_LU_STATUS (STMF_CMD_LU_OP | STMF_CMD_GET_STATUS)
294 #define STMF_CMD_GET_LPORT_STATUS \
295 (STMF_CMD_LPORT_OP | STMF_CMD_GET_STATUS)
296 #define STMF_CMD_LU_ONLINE_COMPLETE \
297 (STMF_CMD_LU_OP | STMF_CMD_ONLINE_COMPLETE)
298 #define STMF_CMD_LPORT_ONLINE_COMPLETE \
299 (STMF_CMD_LPORT_OP | STMF_CMD_ONLINE_COMPLETE)
300 #define STMF_ACK_LU_ONLINE_COMPLETE \
301 (STMF_CMD_LU_OP | STMF_ACK_ONLINE_COMPLETE)
302 #define STMF_ACK_LPORT_ONLINE_COMPLETE \
303 (STMF_CMD_LPORT_OP | STMF_ACK_ONLINE_COMPLETE)
304 #define STMF_CMD_LU_OFFLINE_COMPLETE \
305 (STMF_CMD_LU_OP | STMF_CMD_OFFLINE_COMPLETE)
306 #define STMF_CMD_LPORT_OFFLINE_COMPLETE \
307 (STMF_CMD_LPORT_OP | STMF_CMD_OFFLINE_COMPLETE)
308 #define STMF_ACK_LU_OFFLINE_COMPLETE \
309 (STMF_CMD_LU_OP | STMF_ACK_OFFLINE_COMPLETE)
310 #define STMF_ACK_LPORT_OFFLINE_COMPLETE \
311 (STMF_CMD_LPORT_OP | STMF_ACK_OFFLINE_COMPLETE)
312 /*
313 * For LPORTs and LUs to create their own ctl cmds which dont
314 * conflict with stmf ctl cmds.
315 */
316 #define STMF_LPORT_CTL_CMDS 0x1000
317 #define STMF_LU_CTL_CMDS 0x2000
318
319 /*
320 * Commands for various info routines.
321 */
322 /* Command classifiers */
323 #define SI_LPORT 0x1000000
324 #define SI_STMF 0x2000000
325 #define SI_LU 0x4000000
326 #define SI_LPORT_FC 0x0000000
327 #define SI_LPORT_ISCSI 0x0010000
328 #define SI_LPORT_SAS 0x0020000
329 #define SI_STMF_LU 0x0010000
330 #define SI_STMF_LPORT 0x0020000
331
332 #define SI_GET_CLASS(v) ((v) & 0xFF000000)
333 #define SI_GET_SUBCLASS(v) ((v) & 0x00FF0000)
334
335 /* Commands for LPORT info routines */
336 /* XXX - Implement these. */
337 #if 0
338 #define SI_LPORT_FC_PORTINFO (SI_LPORT | SI_LPORT_FC | 1)
339 #define SI_RPORT_FC_PORTINFO (SI_LPORT | SI_LPORT_FC | 2)
340 #endif
341
342 /*
343 * Events
344 */
345 #define STMF_EVENT_ALL ((int)-1)
346 #define LPORT_EVENT_INITIAL_LUN_MAPPED 0
347
348 /*
349 * This needs to go into common/ddi/sunddi.h
350 */
351 #define DDI_NT_STMF "ddi_scsi_target:framework"
352 #define DDI_NT_STMF_LP "ddi_scsi_target:lu_provider"
353 #define DDI_NT_STMF_PP "ddi_scsi_target:port_provider"
354
355 /*
356 * VPD page bits.
357 */
358 #define STMF_VPD_LU_ID 0x01
359 #define STMF_VPD_TARGET_ID 0x02
360 #define STMF_VPD_TP_GROUP 0x04
361 #define STMF_VPD_RELATIVE_TP_ID 0x08
362
363 /*
364 * Common macros to simplify coding
365 */
366 #define STMF_SEC2TICK(x_sec) (drv_usectohz((x_sec) * 1000000))
367
368 void stmf_trace(caddr_t ident, const char *fmt, ...);
369 void *stmf_alloc(stmf_struct_id_t sid, int additional_size, int alloc_flags);
370 void stmf_free(void *struct_ptr);
371 struct scsi_task *stmf_task_alloc(struct stmf_local_port *lport,
372 struct stmf_scsi_session *ss, uint8_t *lun, uint16_t cdb_length,
373 uint16_t ext_id);
374 void stmf_post_task(scsi_task_t *task, stmf_data_buf_t *dbuf);
375 stmf_data_buf_t *stmf_alloc_dbuf(scsi_task_t *task, uint32_t size,
376 uint32_t *pminsize, uint32_t flags);
377 void stmf_free_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf);
378 stmf_status_t stmf_setup_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf,
379 uint32_t flags);
380 void stmf_teardown_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf);
381 stmf_status_t stmf_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf,
382 uint32_t ioflags);
383 stmf_status_t stmf_send_scsi_status(scsi_task_t *task, uint32_t ioflags);
384 void stmf_data_xfer_done(scsi_task_t *task, stmf_data_buf_t *dbuf,
385 uint32_t iof);
386 void stmf_send_status_done(scsi_task_t *task, stmf_status_t s, uint32_t iof);
387 void stmf_task_lu_done(scsi_task_t *task);
388 void stmf_abort(int abort_cmd, scsi_task_t *task, stmf_status_t s, void *arg);
389 void stmf_task_lu_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof);
390 void stmf_task_lport_aborted_unlocked(scsi_task_t *task, stmf_status_t s,
391 uint32_t iof);
392 stmf_status_t stmf_task_poll_lu(scsi_task_t *task, uint32_t timeout);
393 stmf_status_t stmf_task_poll_lport(scsi_task_t *task, uint32_t timeout);
394 stmf_status_t stmf_ctl(int cmd, void *obj, void *arg);
395 stmf_status_t stmf_register_itl_handle(struct stmf_lu *lu, uint8_t *lun,
396 struct stmf_scsi_session *ss, uint64_t session_id, void *itl_handle);
397 stmf_status_t stmf_deregister_all_lu_itl_handles(struct stmf_lu *lu);
398 stmf_status_t stmf_get_itl_handle(struct stmf_lu *lu, uint8_t *lun,
399 struct stmf_scsi_session *ss, uint64_t session_id, void **itl_handle_retp);
400 stmf_data_buf_t *stmf_handle_to_buf(scsi_task_t *task, uint8_t h);
401 stmf_status_t stmf_lu_add_event(struct stmf_lu *lu, int eventid);
402 stmf_status_t stmf_lu_remove_event(struct stmf_lu *lu, int eventid);
403 stmf_status_t stmf_lport_add_event(struct stmf_local_port *lport, int eventid);
404 stmf_status_t stmf_lport_remove_event(struct stmf_local_port *lport,
405 int eventid);
406 void stmf_wwn_to_devid_desc(struct scsi_devid_desc *sdid, uint8_t *wwn,
407 uint8_t protocol_id);
408 stmf_status_t stmf_scsilib_uniq_lu_id(uint32_t company_id,
409 struct scsi_devid_desc *lu_id);
410 stmf_status_t stmf_scsilib_uniq_lu_id2(uint32_t company_id, uint32_t host_id,
411 struct scsi_devid_desc *lu_id);
412 void stmf_scsilib_send_status(scsi_task_t *task, uint8_t st, uint32_t saa);
413 uint32_t stmf_scsilib_prepare_vpd_page83(scsi_task_t *task, uint8_t *page,
414 uint32_t page_len, uint8_t byte0, uint32_t vpd_mask);
415 uint16_t stmf_scsilib_get_lport_rtid(struct scsi_devid_desc *devid);
416 struct scsi_devid_desc *stmf_scsilib_get_devid_desc(uint16_t rtpid);
417 void stmf_scsilib_handle_report_tpgs(scsi_task_t *task, stmf_data_buf_t *dbuf);
418 void stmf_scsilib_handle_task_mgmt(scsi_task_t *task);
419
420 struct stmf_remote_port *stmf_scsilib_devid_to_remote_port(
421 struct scsi_devid_desc *);
422 boolean_t stmf_scsilib_tptid_validate(struct scsi_transport_id *,
423 uint32_t, uint16_t *);
424 boolean_t stmf_scsilib_tptid_compare(struct scsi_transport_id *,
425 struct scsi_transport_id *);
426 struct stmf_remote_port *stmf_remote_port_alloc(uint16_t);
427 void stmf_remote_port_free(struct stmf_remote_port *);
428 struct stmf_lu *stmf_check_and_hold_lu(struct scsi_task *task, uint8_t *guid);
429 void stmf_release_lu(struct stmf_lu *lu);
430 int stmf_is_task_being_aborted(struct scsi_task *task);
431 #ifdef __cplusplus
432 }
433 #endif
434
435 #endif /* _STMF_H */