Annotation of sys/dev/softraidvar.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: softraidvar.h,v 1.32 2007/06/06 23:06:02 deraadt Exp $ */
2: /*
3: * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: #include <dev/biovar.h>
19:
20: #include <sys/buf.h>
21: #include <sys/queue.h>
22: #include <sys/rwlock.h>
23:
24: #include <scsi/scsi_all.h>
25: #include <scsi/scsi_disk.h>
26: #include <scsi/scsiconf.h>
27:
28: #define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
29:
30: /* #define SR_DEBUG */
31: #ifdef SR_DEBUG
32: extern u_int32_t sr_debug;
33: #define DPRINTF(x...) do { if (sr_debug) printf(x); } while(0)
34: #define DNPRINTF(n,x...) do { if (sr_debug & n) printf(x); } while(0)
35: #define SR_D_CMD 0x0001
36: #define SR_D_INTR 0x0002
37: #define SR_D_MISC 0x0004
38: #define SR_D_IOCTL 0x0008
39: #define SR_D_CCB 0x0010
40: #define SR_D_WU 0x0020
41: #define SR_D_META 0x0040
42: #define SR_D_DIS 0x0080
43: #define SR_D_STATE 0x0100
44: #else
45: #define DPRINTF(x...)
46: #define DNPRINTF(n,x...)
47: #endif
48:
49: #define SR_MAXFER MAXPHYS
50: #define SR_MAX_LD 1
51: #define SR_MAX_CMDS 16
52: #define SR_MAX_STATES 7
53:
54: /* forward define to prevent dependency goo */
55: struct sr_softc;
56:
57: #define SR_UUID_MAX 4
58: struct sr_uuid {
59: u_int32_t sui_id[SR_UUID_MAX];
60: } __packed;
61:
62: struct sr_ccb {
63: struct buf ccb_buf; /* MUST BE FIRST!! */
64:
65: struct sr_workunit *ccb_wu;
66: struct sr_discipline *ccb_dis;
67:
68: int ccb_target;
69: int ccb_state;
70: #define SR_CCB_FREE 0
71: #define SR_CCB_INPROGRESS 1
72: #define SR_CCB_OK 2
73: #define SR_CCB_FAILED 3
74:
75: TAILQ_ENTRY(sr_ccb) ccb_link;
76: } __packed;
77:
78: TAILQ_HEAD(sr_ccb_list, sr_ccb);
79:
80: struct sr_workunit {
81: struct scsi_xfer *swu_xs;
82: struct sr_discipline *swu_dis;
83:
84: int swu_state;
85: #define SR_WU_FREE 0
86: #define SR_WU_INPROGRESS 1
87: #define SR_WU_OK 2
88: #define SR_WU_FAILED 3
89: #define SR_WU_PARTIALLYFAILED 4
90: #define SR_WU_DEFERRED 5
91: #define SR_WU_PENDING 6
92: #define SR_WU_RESTART 7
93: #define SR_WU_REQUEUE 8
94:
95: int swu_fake; /* faked wu */
96: /* workunit io range */
97: daddr64_t swu_blk_start;
98: daddr64_t swu_blk_end;
99:
100: /* in flight totals */
101: u_int32_t swu_ios_complete;
102: u_int32_t swu_ios_failed;
103: u_int32_t swu_ios_succeeded;
104:
105: /* number of ios that makes up the whole work unit */
106: u_int32_t swu_io_count;
107:
108: /* colliding wu */
109: struct sr_workunit *swu_collider;
110:
111: /* all ios that make up this workunit */
112: struct sr_ccb_list swu_ccb;
113:
114: TAILQ_ENTRY(sr_workunit) swu_link;
115: };
116:
117: TAILQ_HEAD(sr_wu_list, sr_workunit);
118:
119: /* RAID 1 */
120: #define SR_RAID1_NOWU 16
121: struct sr_raid1 {
122: u_int32_t sr1_counter;
123: };
124:
125: /* RAID C */
126: #define SR_RAIDC_NOWU 16
127: struct sr_raidc {
128: u_int64_t src_sid;
129: char src_key[64];
130: };
131:
132: #define SR_META_SIZE 32 /* save space at chunk beginning */
133: #define SR_META_OFFSET 16 /* skip 8192 bytes at chunk beginning */
134: #define SR_META_VERSION 1 /* bump when sr_metadata changes */
135: struct sr_metadata {
136: /* do not change order of ssd_magic, ssd_version & ssd_checksum */
137: u_int64_t ssd_magic; /* magic id */
138: #define SR_MAGIC 0x4d4152436372616dLLU
139: u_int8_t ssd_version; /* meta data version */
140: u_int8_t ssd_pad1[3];
141: u_int32_t ssd_flags; /* flags */
142:
143: /* meta-data */
144: u_int32_t ssd_checksum; /* xor of the structure */
145: u_int32_t ssd_size; /* sizeof(sr_metadata) */
146: u_int32_t ssd_ondisk; /* on disk version counter */
147: u_int32_t ssd_pad2;
148: struct sr_uuid ssd_uuid; /* unique identifier */
149:
150: /* virtual disk data */
151: u_int32_t ssd_vd_ver; /* vd structure version */
152: u_int32_t ssd_vd_size; /* vd structure size */
153: u_int32_t ssd_vd_volid; /* volume id */
154: u_int32_t ssd_vd_chk; /* vd structure xor */
155:
156: /* chunk data */
157: u_int32_t ssd_chunk_ver; /* chunk structure version */
158: u_int32_t ssd_chunk_no; /* number of chunks */
159: u_int32_t ssd_chunk_size; /* chunk structure size */
160: u_int32_t ssd_chunk_id; /* chunk identifier */
161: u_int32_t ssd_chunk_chk; /* chunk structure xor */
162: u_int32_t ssd_pad3;
163:
164: /* optional metadata */
165: u_int32_t ssd_opt_ver; /* optinal meta version */
166: u_int32_t ssd_opt_no; /* nr of optional md elements */
167: u_int32_t ssd_opt_size; /* sizeof optional metadata */
168: u_int32_t ssd_opt_chk; /* optional metadata xor */
169: } __packed;
170:
171: struct sr_metadata_list {
172: struct sr_metadata *sml_metadata;
173: dev_t sml_mm;
174: int sml_used;
175:
176: SLIST_ENTRY(sr_metadata_list) sml_link;
177: };
178:
179: SLIST_HEAD(sr_metadata_list_head, sr_metadata_list);
180:
181: #define SR_OPT_VERSION 1 /* bump when sr_opt_meta changes */
182: struct sr_opt_meta {
183: u_int32_t som_type;
184: u_int32_t som_pad;
185: #define SR_OPT_INVALID 0x00
186: #define SR_OPT_CRYPTO 0x01
187: union {
188: struct sr_raidc smm_crypto;
189: } som_meta;
190: };
191:
192: #define SR_CHUNK_VERSION 1 /* bump when sr_chunk_meta changes */
193: struct sr_chunk_meta {
194: u_int32_t scm_volid; /* vd we belong to */
195: u_int32_t scm_chunk_id; /* chunk id */
196: u_int32_t scm_status; /* use bio bioc_disk status */
197: u_int32_t scm_pad1;
198: char scm_devname[32];/* /dev/XXXXX */
199: int64_t scm_size; /* size of partition */
200: int64_t scm_coerced_size; /* coerced size of part */
201: struct sr_uuid scm_uuid; /* unique identifier */
202: } __packed;
203:
204: struct sr_chunk {
205: struct sr_chunk_meta src_meta; /* chunk meta data */
206:
207: /* runtime data */
208: dev_t src_dev_mm; /* major/minor */
209:
210: /* helper members before metadata makes it onto the chunk */
211: int src_meta_ondisk;/* set when meta is on disk */
212: char src_devname[32];
213: int64_t src_size;
214:
215: SLIST_ENTRY(sr_chunk) src_link;
216: };
217:
218: SLIST_HEAD(sr_chunk_head, sr_chunk);
219:
220: #define SR_VOL_VERSION 1 /* bump when sr_vol_meta changes */
221: struct sr_vol_meta {
222: u_int32_t svm_volid; /* volume id */
223: u_int32_t svm_status; /* use bioc_vol status */
224: u_int32_t svm_flags; /* flags */
225: #define SR_VOL_DIRTY 0x01
226: u_int32_t svm_level; /* raid level */
227: int64_t svm_size; /* virtual disk size */
228: char svm_devname[32];/* /dev/XXXXX */
229: char svm_vendor[8]; /* scsi vendor */
230: char svm_product[16];/* scsi product */
231: char svm_revision[4];/* scsi revision */
232: u_int32_t svm_no_chunk; /* number of chunks */
233: struct sr_uuid svm_uuid; /* volume unique identifier */
234: } __packed;
235:
236: struct sr_volume {
237: struct sr_vol_meta sv_meta; /* meta data */
238:
239: /* runtime data */
240: struct sr_chunk_head sv_chunk_list; /* linked list of all chunks */
241: struct sr_chunk **sv_chunks; /* array to same chunks */
242:
243: /* sensors */
244: struct ksensor sv_sensor;
245: struct ksensordev sv_sensordev;
246: int sv_sensor_valid;
247: };
248:
249: struct sr_discipline {
250: struct sr_softc *sd_sc; /* link back to sr softc */
251: u_int8_t sd_type; /* type of discipline */
252: #define SR_MD_RAID0 0
253: #define SR_MD_RAID1 1
254: #define SR_MD_RAID5 2
255: #define SR_MD_CACHE 3
256: #define SR_MD_RAIDC 4
257: char sd_name[10]; /* human readable dis name */
258: u_int8_t sd_scsibus; /* scsibus discipline uses */
259: struct scsi_link sd_link; /* link to midlayer */
260:
261: union {
262: struct sr_raid1 mdd_raid1;
263: struct sr_raidc mdd_raidc;
264: } sd_dis_specific;/* dis specific members */
265: #define mds sd_dis_specific
266:
267: /* discipline metadata */
268: struct sr_metadata *sd_meta; /* in memory copy of metadata */
269: u_int32_t sd_meta_flags;
270:
271: int sd_sync;
272: int sd_must_flush;
273:
274: struct device *sd_scsibus_dev;
275: void (*sd_shutdownhook)(void *);
276:
277: /* discipline volume */
278: struct sr_volume sd_vol; /* volume associated */
279:
280: /* discipline resources */
281: struct sr_ccb *sd_ccb;
282: struct sr_ccb_list sd_ccb_freeq;
283: u_int32_t sd_max_ccb_per_wu;
284:
285: struct sr_workunit *sd_wu; /* all workunits */
286: u_int32_t sd_max_wu;
287:
288: struct sr_wu_list sd_wu_freeq; /* free wu queue */
289: struct sr_wu_list sd_wu_pendq; /* pending wu queue */
290: struct sr_wu_list sd_wu_defq; /* deferred wu queue */
291:
292: /* discipline stats */
293: int sd_wu_pending;
294: u_int64_t sd_wu_collisions;
295:
296: /* discipline functions */
297: int (*sd_alloc_resources)(struct sr_discipline *);
298: int (*sd_assemble_volume)(void *);
299: int (*sd_bringup_volume)(void *);
300: int (*sd_shutdown_volume)(void *);
301: int (*sd_free_resources)(struct sr_discipline *);
302: int (*sd_quiesce_io)(struct sr_discipline *);
303: void (*sd_set_chunk_state)(struct sr_discipline *,
304: int, int);
305: void (*sd_set_vol_state)(struct sr_discipline *);
306:
307: /* SCSI emulation */
308: struct scsi_sense_data sd_scsi_sense;
309: int (*sd_scsi_rw)(struct sr_workunit *);
310: int (*sd_scsi_sync)(struct sr_workunit *);
311: int (*sd_scsi_tur)(struct sr_workunit *);
312: int (*sd_scsi_start_stop)(struct sr_workunit *);
313: int (*sd_scsi_inquiry)(struct sr_workunit *);
314: int (*sd_scsi_read_cap)(struct sr_workunit *);
315: int (*sd_scsi_req_sense)(struct sr_workunit *);
316: };
317:
318: struct sr_softc {
319: struct device sc_dev;
320:
321: int (*sc_ioctl)(struct device *, u_long, caddr_t);
322:
323: struct rwlock sc_lock;
324:
325: int sc_sensors_running;
326: /*
327: * during scsibus attach this is the discipline that is in use
328: * this variable is protected by sc_lock and splhigh
329: */
330: struct sr_discipline *sc_attach_dis;
331:
332: /*
333: * XXX expensive, alternative would be nice but has to be cheap
334: * since the scsibus lookup happens on each IO
335: */
336: #define SR_MAXSCSIBUS 256
337: struct sr_discipline *sc_dis[SR_MAXSCSIBUS]; /* scsibus is u_int8_t */
338: };
CVSweb