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 */