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