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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23  *
24  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
25  */
26 
27 #ifndef	_SBD_IMPL_H
28 #define	_SBD_IMPL_H
29 
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 struct register_lu_cmd;
35 struct modify_lu_cmd;
36 struct sbd_lu_attr;
37 struct sbd_it_data;
38 
39 #define	ATOMIC8_GET(val) (		\
40 			(atomic_add_8_nv(&(val), 0)))
41 #define	ATOMIC32_GET(val) (		\
42 			(atomic_add_32_nv(&(val), 0)))
43 
44 /*
45  * sms endianess
46  */
47 #define	SMS_BIG_ENDIAN			0x00
48 #define	SMS_LITTLE_ENDIAN		0xFF
49 
50 #ifdef	_BIG_ENDIAN
51 #define	SMS_DATA_ORDER	SMS_BIG_ENDIAN
52 #else
53 #define	SMS_DATA_ORDER	SMS_LITTLE_ENDIAN
54 #endif
55 
56 /* Test if one of the BitOrder definitions exists */
57 #ifdef _BIT_FIELDS_LTOH
58 #elif defined(_BIT_FIELDS_HTOL)
59 #else
60 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
61 #endif
62 
63 #define	SBD_V0_MAGIC	0x53554e4d4943524f
64 #define	SBD_MAGIC	0x53554e5342444c55
65 
66 typedef struct sbd_v0_meta_start {
67 	uint64_t		sm_magic;	/* SBD_MAGIC */
68 	uint64_t		sm_meta_size;	/* Includes everything */
69 } sbd_v0_meta_start_t;
70 
71 typedef struct sbd_meta_start {
72 	uint64_t		sm_magic;
73 	uint64_t		sm_meta_size;
74 	uint64_t		sm_meta_size_used;
75 	uint64_t		sm_rsvd1;	/* Defaults to zero */
76 	uint64_t		sm_rsvd2;
77 	uint16_t		sm_ver_major;
78 	uint16_t		sm_ver_minor;
79 	uint16_t		sm_ver_subminor;
80 	uint8_t			sm_flags;	/* None at this moment */
81 	uint8_t			sm_chksum;
82 } sbd_meta_start_t;
83 
84 typedef struct sm_v0_section_hdr {
85 	uint64_t	sms_offset;	/* Offset of this section */
86 	uint64_t	sms_size;	/* Includes the header and padding */
87 	uint16_t	sms_id;		/* Section identifier */
88 	uint16_t	sms_padding;	/* For alignment */
89 	uint32_t	sms_seqno;	/* For multiple sections with same ID */
90 	uint8_t		sms_hdr_data_order; /* 0x00 or 0xff */
91 	uint8_t		sms_payload_data_order;
92 	uint16_t	rsvd2;
93 	uint32_t	rsvd3;		/* 8 byte align */
94 } sm_v0_section_hdr_t;
95 
96 /*
97  * sbd_it_flags
98  */
99 #define	SBD_IT_HAS_SCSI2_RESERVATION	0x0001
100 #define	SBD_IT_PGR_REGISTERED		0x0002
101 #define	SBD_IT_PGR_EXCLUSIVE_RSV_HOLDER	0x0004
102 #define	SBD_IT_PGR_CHECK_FLAG		0x0008
103 
104 /*
105  * PGR flags
106  */
107 #define	SBD_PGR_APTPL			0x01
108 #define	SBD_PGR_RSVD_ONE		0x02
109 #define	SBD_PGR_RSVD_ALL_REGISTRANTS	0x04
110 #define	SBD_PGR_ALL_KEYS_HAS_IT		0x08
111 
112 #define	SBD_PGR_RSVD(pgr)	(((pgr)->pgr_flags) & (SBD_PGR_RSVD_ONE | \
113 					SBD_PGR_RSVD_ALL_REGISTRANTS))
114 #define	SBD_PGR_RSVD_NONE(pgr)	(!(SBD_PGR_RSVD(pgr)))
115 
116 /*
117  * PGR key flags
118  */
119 #define	SBD_PGR_KEY_ALL_TG_PT		0x01
120 #define	SBD_PGR_KEY_TPT_ID_FLAG		0x02
121 
122 typedef struct sbd_pgr_key_info {
123 	uint64_t	pgr_key;
124 	uint16_t	pgr_key_lpt_len;
125 	uint16_t	pgr_key_rpt_len;
126 	uint8_t		pgr_key_flags;
127 	uint8_t		pgr_key_it[1];	/* order:- initiator info followed by */
128 					/* scsi_devid_desc of local port */
129 } sbd_pgr_key_info_t;
130 
131 typedef struct sbd_pgr_info {
132 	sm_section_hdr_t	pgr_sms_header;
133 	uint32_t		pgr_rsvholder_indx;
134 	uint32_t		pgr_numkeys;
135 	uint8_t			pgr_flags;
136 	uint8_t			pgr_data_order;
137 #ifdef _BIT_FIELDS_LTOH
138 	uint8_t			pgr_rsv_type:4,
139 				pgr_rsv_scope:4;
140 #else
141 	uint8_t			pgr_rsv_scope:4,
142 				pgr_rsv_type:4;
143 #endif
144 	uint8_t			rsvd[5];	/* 8 byte boundary */
145 
146 } sbd_pgr_info_t;
147 
148 typedef struct sbd_pgr_key {
149 	uint64_t		pgr_key;
150 	uint16_t		pgr_key_lpt_len;
151 	uint16_t		pgr_key_rpt_len;
152 	uint8_t			pgr_key_flags;
153 	struct scsi_devid_desc	*pgr_key_lpt_id;
154 	struct scsi_transport_id *pgr_key_rpt_id;
155 	struct sbd_it_data	*pgr_key_it;
156 	struct sbd_pgr_key	*pgr_key_next;
157 	struct sbd_pgr_key	*pgr_key_prev;
158 } sbd_pgr_key_t;
159 
160 typedef struct sbd_pgr {
161 	sbd_pgr_key_t		*pgr_keylist;
162 	sbd_pgr_key_t		*pgr_rsvholder;
163 	uint32_t		pgr_PRgeneration; /* PGR PRgeneration value */
164 	uint8_t			pgr_flags;	/* PGR flags (eg: APTPL)  */
165 	uint8_t			pgr_rsv_type:4,
166 				pgr_rsv_scope:4;
167 	krwlock_t		pgr_lock; /* Lock order pgr_lock, sl_lock */
168 } sbd_pgr_t;
169 
170 
171 typedef struct sbd_v0_lu_info {
172 	sm_v0_section_hdr_t	sli_sms_header;
173 	uint64_t		sli_total_store_size;
174 	uint64_t		sli_total_meta_size;
175 	uint64_t		rsvd0;
176 	uint64_t		sli_lu_data_offset;
177 	uint64_t		sli_lu_data_size;
178 	uint64_t		rsvd1;
179 	uint32_t		sli_flags;
180 	uint16_t		sli_blocksize;
181 	uint16_t		rsvd2;
182 	uint8_t			sli_lu_devid[20];
183 	uint32_t		rsvd3;
184 } sbd_v0_lu_info_t;
185 
186 typedef struct sbd_lu_info {
187 	sm_section_hdr_t	sli_sms_header;
188 	uint64_t		sli_total_store_size;
189 	uint64_t		sli_total_meta_size;
190 	uint64_t		sli_lu_data_offset;
191 	uint64_t		sli_lu_data_size;
192 	uint32_t		sli_flags;
193 	uint16_t		sli_blocksize;
194 	uint8_t			sli_data_order;
195 	uint8_t			rsvd1;
196 	uint8_t			sli_lu_devid[20];
197 	uint32_t		rsvd2;
198 } sbd_lu_info_t;
199 
200 /*
201  * sl_flags
202  */
203 #define	SBD_LU_HAS_SCSI2_RESERVATION	0x0001
204 
205 typedef struct sbd_cmd {
206 	uint8_t		flags;
207 	uint8_t		nbufs;
208 	uint16_t	cmd_type;	/* Type of command */
209 	uint32_t	trans_data_len;	/* Length of transient data buf */
210 	uint64_t	addr;		/* current */
211 	uint32_t	len;		/* len left */
212 	uint32_t	current_ro;	/* running relative offset */
213 	uint8_t		*trans_data;	/* Any transient data */
214 	ats_state_t	*ats_state;
215 	uint32_t	rsvd;
216 } sbd_cmd_t;
217 
218 /*
219  * flags for sbd_cmd
220  *
221  * SBD_SCSI_CMD_ACTIVE means that a command is running.  This is the time
222  *      between the function sbd_new_task is called and either the command
223  *      completion is sent (stmf_scsilib_send_status) or an abort is
224  *      issued
225  *
226  * SBD_SCSI_CMD_ABORT_REQUESTED is when a command is being aborted.  It may
227  *      be set prior to the task being dispatched or anywhere in the process
228  *      of the command.
229  *
230  * SBD_SCSI_CMD_XFER_FAIL is set when a command data buffer transfer was
231  *      errored.  Usually it leads to an abort.
232  *
233  * SBD_SCSI_CMD_SYNC_WRITE synchronous write being done.
234  *
235  * SBD_SCSI_CMD_TRANS_DATA means that a buffer has been allocated to
236  *      be used for the transfer of data.
237  */
238 #define	SBD_SCSI_CMD_ACTIVE		0x01
239 #define	SBD_SCSI_CMD_ABORT_REQUESTED	0x02
240 #define	SBD_SCSI_CMD_XFER_FAIL		0x04
241 #define	SBD_SCSI_CMD_SYNC_WRITE		0x08
242 #define	SBD_SCSI_CMD_TRANS_DATA		0x10
243 #define	SBD_SCSI_CMD_ATS_RELATED	0x20
244 
245 /*
246  * cmd types
247  */
248 #define	SBD_CMD_SCSI_READ	0x01
249 #define	SBD_CMD_SCSI_WRITE	0x02
250 #define	SBD_CMD_SMALL_READ	0x03
251 #define	SBD_CMD_SMALL_WRITE	0x04
252 #define	SBD_CMD_SCSI_PR_OUT	0x05
253 
254 typedef struct sbd_it_data {
255 	struct sbd_it_data	*sbd_it_next;
256 	uint64_t		sbd_it_session_id;
257 	uint8_t			sbd_it_lun[8];
258 	uint8_t			sbd_it_ua_conditions;
259 	uint8_t			sbd_it_flags;
260 	sbd_pgr_key_t		*pgr_key_ptr;
261 } sbd_it_data_t;
262 
263 typedef struct sbd_create_standby_lu {
264 	uint32_t	stlu_meta_fname_size;
265 	uint32_t	stlu_rsvd;
266 	uint8_t		stlu_guid[16];
267 	char		stlu_meta_fname[8];
268 } sbd_create_standby_lu_t;
269 
270 /*
271  * Different UA conditions
272  */
273 #define	SBD_UA_POR			    0x01
274 #define	SBD_UA_CAPACITY_CHANGED		    0x02
275 #define	SBD_UA_MODE_PARAMETERS_CHANGED	    0x04
276 #define	SBD_UA_ACCESS_STATE_TRANSITION	    0x08
277 #define	SBD_UA_REGISTRATIONS_PREEMPTED	    0x10
278 #define	SBD_UA_RESERVATIONS_PREEMPTED	    0x20
279 #define	SBD_UA_RESERVATIONS_RELEASED	    0x40
280 #define	SBD_UA_ASYMMETRIC_ACCESS_CHANGED    0x80
281 
282 /*
283  * sbd_it_flags
284  */
285 #define	SBD_IT_HAS_SCSI2_RESERVATION	0x0001
286 
287 /*
288  * dbuf private data needed for direct zvol data transfers
289  *
290  * To further isolate the zvol knowledge, the object handles
291  * needed to call into zfs are declared void * here.
292  */
293 
294 typedef struct sbd_zvol_io {
295 	uint64_t	zvio_offset;	/* offset into volume */
296 	int		zvio_flags;	/* flags */
297 	void		*zvio_dbp;	/* array of dmu buffers */
298 	void		*zvio_abp;	/* array of arc buffers */
299 	uio_t		*zvio_uio;	/* for copy operations */
300 } sbd_zvol_io_t;
301 
302 #define	ZVIO_DEFAULT	0
303 #define	ZVIO_COMMIT	1
304 #define	ZVIO_ABORT	2
305 #define	ZVIO_SYNC	4
306 #define	ZVIO_ASYNC	8
307 
308 /*
309  * zvol data path functions
310  */
311 int sbd_zvol_get_volume_params(sbd_lu_t *sl);
312 uint32_t sbd_zvol_numsegs(sbd_lu_t *sl, uint64_t off, uint32_t len);
313 int sbd_zvol_alloc_read_bufs(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
314 void sbd_zvol_rele_read_bufs(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
315 int sbd_zvol_alloc_write_bufs(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
316 void sbd_zvol_rele_write_bufs_abort(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
317 int sbd_zvol_rele_write_bufs(sbd_lu_t *sl, stmf_data_buf_t *dbuf);
318 int sbd_zvol_copy_read(sbd_lu_t *sl, uio_t *uio);
319 int sbd_zvol_copy_write(sbd_lu_t *sl, uio_t *uio, int flags);
320 
321 stmf_status_t sbd_task_alloc(struct scsi_task *task);
322 void sbd_new_task(struct scsi_task *task, struct stmf_data_buf *initial_dbuf);
323 void sbd_dbuf_xfer_done(struct scsi_task *task, struct stmf_data_buf *dbuf);
324 void sbd_send_status_done(struct scsi_task *task);
325 void sbd_task_free(struct scsi_task *task);
326 stmf_status_t sbd_abort(struct stmf_lu *lu, int abort_cmd, void *arg,
327 							uint32_t flags);
328 void sbd_task_poll(struct scsi_task *task);
329 void sbd_dbuf_free(struct scsi_task *task, struct stmf_data_buf *dbuf);
330 void sbd_ctl(struct stmf_lu *lu, int cmd, void *arg);
331 stmf_status_t sbd_info(uint32_t cmd, stmf_lu_t *lu, void *arg,
332 				uint8_t *buf, uint32_t *bufsizep);
333 uint8_t sbd_get_lbasize_shift(stmf_lu_t *lu);
334 int sbd_is_valid_lu(stmf_lu_t *lu);
335 
336 #ifdef	__cplusplus
337 }
338 #endif
339 
340 #endif /* _SBD_IMPL_H */
341