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