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