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