xref: /openbsd-src/sys/dev/softraidvar.h (revision 5b6e6e1ea65e59c9bb2428cf35ca60d8cdd2673a)
1*5b6e6e1eSkn /* $OpenBSD: softraidvar.h,v 1.176 2022/12/19 15:27:06 kn Exp $ */
27195049bSmarco /*
3989b6914Sgrunk  * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
47fe2bdbeSckuethe  * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
57195049bSmarco  *
67195049bSmarco  * Permission to use, copy, modify, and distribute this software for any
77195049bSmarco  * purpose with or without fee is hereby granted, provided that the above
87195049bSmarco  * copyright notice and this permission notice appear in all copies.
97195049bSmarco  *
107195049bSmarco  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
117195049bSmarco  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
127195049bSmarco  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
137195049bSmarco  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
147195049bSmarco  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
157195049bSmarco  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
167195049bSmarco  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
177195049bSmarco  */
187195049bSmarco 
19f18dcc9cStedu #ifndef SOFTRAIDVAR_H
20f18dcc9cStedu #define SOFTRAIDVAR_H
21f18dcc9cStedu 
22bccb2f38Skrw #define SR_META_VERSION		6	/* bump when sr_metadata changes */
23f6e5141fSjsing #define SR_META_SIZE		64	/* save space at chunk beginning */
24f6e5141fSjsing #define SR_META_OFFSET		16	/* skip 8192 bytes at chunk beginning */
25f6e5141fSjsing 
26f6e5141fSjsing #define SR_BOOT_OFFSET		(SR_META_OFFSET + SR_META_SIZE)
27f6e5141fSjsing #define SR_BOOT_LOADER_SIZE	320	/* Size of boot loader storage. */
28f6e5141fSjsing #define SR_BOOT_LOADER_OFFSET	SR_BOOT_OFFSET
29f6e5141fSjsing #define SR_BOOT_BLOCKS_SIZE	128	/* Size of boot block storage. */
30f6e5141fSjsing #define SR_BOOT_BLOCKS_OFFSET	(SR_BOOT_LOADER_OFFSET + SR_BOOT_LOADER_SIZE)
31f6e5141fSjsing #define SR_BOOT_SIZE		(SR_BOOT_LOADER_SIZE + SR_BOOT_BLOCKS_SIZE)
32f6e5141fSjsing 
33e7d4f752Sderaadt #define SR_CRYPTO_MAXKEYBYTES	32	/* max bytes in a key (AES-XTS-256) */
34e7d4f752Sderaadt #define SR_CRYPTO_MAXKEYS	32	/* max keys per volume */
35e7d4f752Sderaadt #define SR_CRYPTO_KEYBITS	512	/* AES-XTS with 2 * 256 bit keys */
36e7d4f752Sderaadt #define SR_CRYPTO_KEYBYTES	(SR_CRYPTO_KEYBITS >> 3)
37e7d4f752Sderaadt #define SR_CRYPTO_KDFHINTBYTES	256	/* size of opaque KDF hint */
38e7d4f752Sderaadt #define SR_CRYPTO_CHECKBYTES	64	/* size of generic key chksum struct */
39e7d4f752Sderaadt #define SR_CRYPTO_KEY_BLKSHIFT	30	/* 0.5TB per key */
404fe5a5deSjsing #define SR_CRYPTO_KEY_BLKSIZE	(1ULL << SR_CRYPTO_KEY_BLKSHIFT)
414fe5a5deSjsing #define SR_CRYPTO_MAXSIZE	(SR_CRYPTO_KEY_BLKSIZE * SR_CRYPTO_MAXKEYS)
42e7d4f752Sderaadt 
4345d888eeSjsing /*
4445d888eeSjsing  * sr_crypto_genkdf is a generic hint for the KDF performed in userland and
4545d888eeSjsing  * is not interpreted by the kernel.
4645d888eeSjsing  */
47e7d4f752Sderaadt struct sr_crypto_genkdf {
48e7d4f752Sderaadt 	u_int32_t	len;
49e7d4f752Sderaadt 	u_int32_t	type;
50e7d4f752Sderaadt #define SR_CRYPTOKDFT_INVALID		0
51ea67ad9aSjsing #define SR_CRYPTOKDFT_PKCS5_PBKDF2	1
52e7d4f752Sderaadt #define SR_CRYPTOKDFT_KEYDISK		2
533487a6b1Sjsing #define SR_CRYPTOKDFT_BCRYPT_PBKDF	3
54e7d4f752Sderaadt };
55e7d4f752Sderaadt 
5645d888eeSjsing /*
573487a6b1Sjsing  * sr_crypto_pbkdf is a hint for a PBKDF performed in userland and is not
583487a6b1Sjsing  * interpreted by the kernel.
5945d888eeSjsing  */
603487a6b1Sjsing struct sr_crypto_pbkdf {
613487a6b1Sjsing 	struct sr_crypto_genkdf generic;
62e7d4f752Sderaadt 	u_int32_t	rounds;
63e7d4f752Sderaadt 	u_int8_t	salt[128];
64e7d4f752Sderaadt };
65e7d4f752Sderaadt 
66e7d4f752Sderaadt /*
6745d888eeSjsing  * sr_crypto_kdfinfo is used to copy masking keys and KDF hints from/to
6845d888eeSjsing  * userland. The embedded hint structures are not interpreted by the kernel.
69e7d4f752Sderaadt  */
70e7d4f752Sderaadt struct sr_crypto_kdfinfo {
71e7d4f752Sderaadt 	u_int32_t	len;
72e7d4f752Sderaadt 	u_int32_t	flags;
73e7d4f752Sderaadt #define SR_CRYPTOKDF_INVALID	(0)
74e7d4f752Sderaadt #define SR_CRYPTOKDF_KEY	(1<<0)
75e7d4f752Sderaadt #define SR_CRYPTOKDF_HINT	(1<<1)
76e7d4f752Sderaadt 	u_int8_t	maskkey[SR_CRYPTO_MAXKEYBYTES];
77e7d4f752Sderaadt 	union {
78e7d4f752Sderaadt 		struct sr_crypto_genkdf	generic;
793487a6b1Sjsing 		struct sr_crypto_pbkdf	pbkdf;
80e7d4f752Sderaadt 	}		_kdfhint;
81e7d4f752Sderaadt #define genkdf		_kdfhint.generic
823487a6b1Sjsing #define pbkdf		_kdfhint.pbkdf
83e7d4f752Sderaadt };
84e7d4f752Sderaadt 
85e7d4f752Sderaadt #define SR_IOCTL_GET_KDFHINT		0x01	/* Get KDF hint. */
864b1a56afSjsg #define SR_IOCTL_CHANGE_PASSPHRASE	0x02	/* Change passphrase. */
87e7d4f752Sderaadt 
88e7d4f752Sderaadt struct sr_crypto_kdfpair {
893487a6b1Sjsing 	struct sr_crypto_kdfinfo *kdfinfo1;
90e7d4f752Sderaadt 	u_int32_t	kdfsize1;
913487a6b1Sjsing 	struct sr_crypto_kdfinfo *kdfinfo2;
92e7d4f752Sderaadt 	u_int32_t	kdfsize2;
93e7d4f752Sderaadt };
94e7d4f752Sderaadt 
95e7d4f752Sderaadt #if defined(_KERNEL) || defined(_STANDALONE)
96e7d4f752Sderaadt 
97e7d4f752Sderaadt #include <crypto/md5.h>
98e7d4f752Sderaadt 
99e7d4f752Sderaadt #define SR_META_V3_SIZE		64
100e7d4f752Sderaadt #define SR_META_V3_OFFSET	16
101e7d4f752Sderaadt #define SR_META_V3_DATA_OFFSET	(SR_META_V3_OFFSET + SR_META_V3_SIZE)
102e7d4f752Sderaadt 
103e7d4f752Sderaadt #define SR_META_F_NATIVE	0	/* Native metadata format. */
104e7d4f752Sderaadt #define SR_META_F_INVALID	-1
105e7d4f752Sderaadt 
106f6e5141fSjsing #define SR_HEADER_SIZE		(SR_META_SIZE + SR_BOOT_SIZE)
107f6e5141fSjsing #define SR_DATA_OFFSET		(SR_META_OFFSET + SR_HEADER_SIZE)
108c8c45af3Sdjm 
1091e4909a2Sjsing #define SR_HOTSPARE_LEVEL	0xffffffff
1101e4909a2Sjsing #define SR_HOTSPARE_VOLID	0xffffffff
1110054cd36Sjsing #define SR_KEYDISK_LEVEL	0xfffffffe
1120054cd36Sjsing #define SR_KEYDISK_VOLID	0xfffffffe
1131e4909a2Sjsing 
114f6e5141fSjsing #define SR_UUID_MAX		16
115f6e5141fSjsing struct sr_uuid {
116f6e5141fSjsing 	u_int8_t		sui_id[SR_UUID_MAX];
117f6e5141fSjsing } __packed;
1180054cd36Sjsing 
119f4a5ffb3Sjsing struct sr_disk {
120f4a5ffb3Sjsing 	dev_t			sdk_devno;
121f4a5ffb3Sjsing 	SLIST_ENTRY(sr_disk)	sdk_link;
122f4a5ffb3Sjsing };
123f4a5ffb3Sjsing SLIST_HEAD(sr_disk_head, sr_disk);
124f4a5ffb3Sjsing 
125c8c45af3Sdjm struct sr_metadata {
126080cddd5Smarco 	struct sr_meta_invariant {
127080cddd5Smarco 		/* do not change order of ssd_magic, ssd_version */
128c8c45af3Sdjm 		u_int64_t	ssd_magic;	/* magic id */
129c8c45af3Sdjm #define	SR_MAGIC		0x4d4152436372616dLLU
130080cddd5Smarco 		u_int32_t	ssd_version;	/* meta data version */
131e5ea34d9Sjsing 		u_int32_t	ssd_vol_flags;	/* volume specific flags. */
132c8c45af3Sdjm 		struct sr_uuid	ssd_uuid;	/* unique identifier */
133c8c45af3Sdjm 
134080cddd5Smarco 		/* chunks */
135c8c45af3Sdjm 		u_int32_t	ssd_chunk_no;	/* number of chunks */
136c8c45af3Sdjm 		u_int32_t	ssd_chunk_id;	/* chunk identifier */
137c8c45af3Sdjm 
138080cddd5Smarco 		/* optional */
139eed14ba3Smarco 		u_int32_t	ssd_opt_no;	/* nr of optional md elements */
140bccb2f38Skrw 		u_int32_t	ssd_secsize;
141080cddd5Smarco 
142080cddd5Smarco 		/* volume metadata */
143080cddd5Smarco 		u_int32_t	ssd_volid;	/* volume id */
144080cddd5Smarco 		u_int32_t	ssd_level;	/* raid level */
145080cddd5Smarco 		int64_t		ssd_size;	/* virt disk size in blocks */
146080cddd5Smarco 		char		ssd_vendor[8];	/* scsi vendor */
147080cddd5Smarco 		char		ssd_product[16];/* scsi product */
148080cddd5Smarco 		char		ssd_revision[4];/* scsi revision */
149080cddd5Smarco 		/* optional volume members */
150080cddd5Smarco 		u_int32_t	ssd_strip_size;	/* strip size */
151080cddd5Smarco 	} _sdd_invariant;
152080cddd5Smarco #define ssdi			_sdd_invariant
153080cddd5Smarco 	/* MD5 of invariant metadata */
154080cddd5Smarco 	u_int8_t		ssd_checksum[MD5_DIGEST_LENGTH];
155080cddd5Smarco 	char			ssd_devname[32];/* /dev/XXXXX */
156080cddd5Smarco 	u_int32_t		ssd_meta_flags;
157080cddd5Smarco #define	SR_META_DIRTY		0x1
158d9ec6765Skrw 	u_int32_t		ssd_data_blkno;
159080cddd5Smarco 	u_int64_t		ssd_ondisk;	/* on disk version counter */
160eed14ba3Smarco 	int64_t			ssd_rebuild;	/* last block of rebuild */
161c8c45af3Sdjm } __packed;
162c8c45af3Sdjm 
163080cddd5Smarco struct sr_meta_chunk {
164080cddd5Smarco 	struct sr_meta_chunk_invariant {
165c8c45af3Sdjm 		u_int32_t	scm_volid;	/* vd we belong to */
166c8c45af3Sdjm 		u_int32_t	scm_chunk_id;	/* chunk id */
167c8c45af3Sdjm 		char		scm_devname[32];/* /dev/XXXXX */
168c8c45af3Sdjm 		int64_t		scm_size;	/* size of partition in blocks*/
169c8c45af3Sdjm 		int64_t		scm_coerced_size; /* coerced sz of part in blk*/
170c8c45af3Sdjm 		struct sr_uuid	scm_uuid;	/* unique identifier */
171080cddd5Smarco 	} _scm_invariant;
172080cddd5Smarco #define scmi			_scm_invariant
173080cddd5Smarco 	/* MD5 of invariant chunk metadata */
174080cddd5Smarco 	u_int8_t		scm_checksum[MD5_DIGEST_LENGTH];
175080cddd5Smarco 	u_int32_t		scm_status;	/* use bio bioc_disk status */
176c8c45af3Sdjm } __packed;
177c8c45af3Sdjm 
178080cddd5Smarco /*
179080cddd5Smarco  * Check that HMAC-SHA1_k(decrypted scm_key) == sch_mac, where
180080cddd5Smarco  * k = SHA1(masking key)
181080cddd5Smarco  */
182080cddd5Smarco struct sr_crypto_chk_hmac_sha1 {
183080cddd5Smarco 	u_int8_t	sch_mac[20];
184080cddd5Smarco } __packed;
185080cddd5Smarco 
186ee4e3de1Sjsing #define SR_OPT_INVALID		0x00
187ee4e3de1Sjsing #define SR_OPT_CRYPTO		0x01
188ee4e3de1Sjsing #define SR_OPT_BOOT		0x02
189ee4e3de1Sjsing #define SR_OPT_KEYDISK		0x03
190ee4e3de1Sjsing 
191ee4e3de1Sjsing struct sr_meta_opt_hdr {
192ee4e3de1Sjsing 	u_int32_t	som_type;	/* optional metadata type. */
193ee4e3de1Sjsing 	u_int32_t	som_length;	/* optional metadata length. */
194ee4e3de1Sjsing 	u_int8_t	som_checksum[MD5_DIGEST_LENGTH];
195ee4e3de1Sjsing } __packed;
196ee4e3de1Sjsing 
197080cddd5Smarco struct sr_meta_crypto {
198ee4e3de1Sjsing 	struct sr_meta_opt_hdr	scm_hdr;
199080cddd5Smarco 	u_int32_t		scm_alg;	/* vol crypto algorithm */
200080cddd5Smarco #define SR_CRYPTOA_AES_XTS_128	1
201080cddd5Smarco #define SR_CRYPTOA_AES_XTS_256	2
202080cddd5Smarco 	u_int32_t		scm_flags;	/* key & kdfhint valid */
203080cddd5Smarco #define SR_CRYPTOF_INVALID	(0)
204080cddd5Smarco #define SR_CRYPTOF_KEY		(1<<0)
205080cddd5Smarco #define SR_CRYPTOF_KDFHINT	(1<<1)
206080cddd5Smarco 	u_int32_t		scm_mask_alg;	/* disk key masking crypt alg */
207080cddd5Smarco #define SR_CRYPTOM_AES_ECB_256	1
208080cddd5Smarco 	u_int32_t		scm_pad1;
209080cddd5Smarco 	u_int8_t		scm_reserved[64];
210080cddd5Smarco 
211080cddd5Smarco 	/* symmetric keys used for disk encryption */
212080cddd5Smarco 	u_int8_t		scm_key[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES];
213080cddd5Smarco 	/* hint to kdf algorithm (opaque to kernel) */
214080cddd5Smarco 	u_int8_t		scm_kdfhint[SR_CRYPTO_KDFHINTBYTES];
215080cddd5Smarco 
216080cddd5Smarco 	u_int32_t		scm_check_alg;	/* key chksum algorithm */
217080cddd5Smarco #define SR_CRYPTOC_HMAC_SHA1		1
218080cddd5Smarco 	u_int32_t		scm_pad2;
219080cddd5Smarco 	union {
220080cddd5Smarco 		struct sr_crypto_chk_hmac_sha1	chk_hmac_sha1;
221080cddd5Smarco 		u_int8_t			chk_reserved2[64];
222080cddd5Smarco 	}			_scm_chk;
223080cddd5Smarco #define	chk_hmac_sha1	_scm_chk.chk_hmac_sha1
224080cddd5Smarco } __packed;
225080cddd5Smarco 
2268fdeb3fdSjsing #define SR_MAX_BOOT_DISKS 16
227f6e5141fSjsing struct sr_meta_boot {
228ee4e3de1Sjsing 	struct sr_meta_opt_hdr	sbm_hdr;
229f6e5141fSjsing 	u_int32_t		sbm_bootblk_size;
230f6e5141fSjsing 	u_int32_t		sbm_bootldr_size;
2318fdeb3fdSjsing 	u_char			sbm_root_duid[8];
2328fdeb3fdSjsing 	u_char			sbm_boot_duid[SR_MAX_BOOT_DISKS][8];
233f6e5141fSjsing } __packed;
234f6e5141fSjsing 
235b36cc235Sjsing struct sr_meta_keydisk {
236ee4e3de1Sjsing 	struct sr_meta_opt_hdr	skm_hdr;
237b36cc235Sjsing 	u_int8_t		skm_maskkey[SR_CRYPTO_MAXKEYBYTES];
238b36cc235Sjsing } __packed;
239b36cc235Sjsing 
240ee4e3de1Sjsing #define SR_OLD_META_OPT_SIZE	2480
241ee4e3de1Sjsing #define SR_OLD_META_OPT_OFFSET	8
242ee4e3de1Sjsing #define SR_OLD_META_OPT_MD5	(SR_OLD_META_OPT_SIZE - MD5_DIGEST_LENGTH)
243080cddd5Smarco 
244c907def9Sjsing struct sr_meta_opt_item {
245ee4e3de1Sjsing 	struct sr_meta_opt_hdr	*omi_som;
246c907def9Sjsing 	SLIST_ENTRY(sr_meta_opt_item) omi_link;
247c907def9Sjsing };
248c907def9Sjsing 
249c907def9Sjsing SLIST_HEAD(sr_meta_opt_head, sr_meta_opt_item);
250c907def9Sjsing 
251074ca811Sjsing struct sr_boot_chunk {
252074ca811Sjsing 	struct sr_metadata *sbc_metadata;
253b7072a3fSjsing 	dev_t		sbc_mm;			/* Device major/minor. */
254074ca811Sjsing 
255074ca811Sjsing 	u_int32_t	sbc_chunk_id;		/* Chunk ID. */
256074ca811Sjsing 	u_int32_t	sbc_state;		/* Chunk state. */
257074ca811Sjsing 	u_int32_t	sbc_disk;		/* Disk number. */
258074ca811Sjsing 	int		sbc_part;		/* Partition number. */
259074ca811Sjsing 	u_int64_t	sbc_ondisk;		/* Ondisk version. */
260074ca811Sjsing 
261074ca811Sjsing 	void		*sbc_diskinfo;		/* MD disk information. */
262074ca811Sjsing 
263074ca811Sjsing 	SLIST_ENTRY(sr_boot_chunk) sbc_link;
264074ca811Sjsing };
265074ca811Sjsing 
266074ca811Sjsing SLIST_HEAD(sr_boot_chunk_head, sr_boot_chunk);
267074ca811Sjsing 
268074ca811Sjsing struct sr_boot_volume {
269074ca811Sjsing 	struct sr_uuid	sbv_uuid;		/* Volume UUID. */
270074ca811Sjsing 	u_int32_t	sbv_level;		/* RAID Level. */
271074ca811Sjsing 	u_int32_t	sbv_volid;		/* Volume ID. */
272074ca811Sjsing 	u_int32_t	sbv_chunk_no;		/* Number of chunks. */
273074ca811Sjsing 	u_int32_t	sbv_flags;		/* Volume specific flags. */
274074ca811Sjsing 	u_int32_t	sbv_state;		/* Volume state. */
275074ca811Sjsing 	int64_t		sbv_size;		/* Virtual disk size. */
276f252f90fSyasuoka 	u_int32_t	sbv_secsize;		/* Sector size */
277d9ec6765Skrw 	u_int32_t	sbv_data_blkno;		/* Data offset. */
278074ca811Sjsing 	u_int64_t	sbv_ondisk;		/* Ondisk version. */
279074ca811Sjsing 
280074ca811Sjsing 	u_int32_t	sbv_chunks_found;	/* Number of chunks found. */
281074ca811Sjsing 	u_int32_t	sbv_unit;		/* Disk unit number. */
282074ca811Sjsing 	char		sbv_part;		/* Partition opened. */
283074ca811Sjsing 	void		*sbv_diskinfo;		/* MD disk information. */
284074ca811Sjsing 
28570197c51Sjsing 	u_int8_t	*sbv_keys;		/* Disk keys for volume. */
28670197c51Sjsing 	u_int8_t	*sbv_maskkey;		/* Mask key for disk keys. */
28770197c51Sjsing 
288074ca811Sjsing 	struct sr_boot_chunk_head sbv_chunks;	/* List of chunks. */
28970197c51Sjsing 	struct sr_meta_opt_head sbv_meta_opt;	/* List of optional metadata. */
290074ca811Sjsing 
291074ca811Sjsing 	SLIST_ENTRY(sr_boot_volume)	sbv_link;
292074ca811Sjsing };
293074ca811Sjsing 
294074ca811Sjsing SLIST_HEAD(sr_boot_volume_head, sr_boot_volume);
2951576da7bStedu 
296e7d4f752Sderaadt #endif /* _KERNEL | _STANDALONE */
297e7d4f752Sderaadt 
298c8c45af3Sdjm #ifdef _KERNEL
299e7d4f752Sderaadt 
3007195049bSmarco #include <dev/biovar.h>
3017195049bSmarco 
3027195049bSmarco #include <sys/buf.h>
3037195049bSmarco #include <sys/queue.h>
3047195049bSmarco #include <sys/rwlock.h>
3051f300c94Sjsing #include <sys/task.h>
3067195049bSmarco 
3077195049bSmarco #include <scsi/scsi_all.h>
3087195049bSmarco #include <scsi/scsi_disk.h>
3097195049bSmarco #include <scsi/scsiconf.h>
3107195049bSmarco 
3117195049bSmarco #define DEVNAME(_s)     ((_s)->sc_dev.dv_xname)
3127195049bSmarco 
3132360bd90Smarco /* #define SR_DEBUG */
3147195049bSmarco #ifdef SR_DEBUG
3157195049bSmarco extern u_int32_t		sr_debug;
3167195049bSmarco #define DNPRINTF(n,x...)	do { if (sr_debug & n) printf(x); } while(0)
3177195049bSmarco #define	SR_D_CMD		0x0001
3187195049bSmarco #define	SR_D_INTR		0x0002
3197195049bSmarco #define	SR_D_MISC		0x0004
3207195049bSmarco #define	SR_D_IOCTL		0x0008
3217195049bSmarco #define	SR_D_CCB		0x0010
3227195049bSmarco #define	SR_D_WU			0x0020
3237195049bSmarco #define	SR_D_META		0x0040
3247195049bSmarco #define	SR_D_DIS		0x0080
325e665884eSmarco #define	SR_D_STATE		0x0100
326d3808055Sjsing #define	SR_D_REBUILD		0x0200
3277195049bSmarco #else
3287195049bSmarco #define DNPRINTF(n,x...)
3297195049bSmarco #endif
3307195049bSmarco 
3311baf7721Smatthew #define	SR_MAX_LD		256
3327195049bSmarco #define	SR_MAX_CMDS		16
3333d417dfdSmarco #define	SR_MAX_STATES		7
334080cddd5Smarco #define SR_VM_IGNORE_DIRTY	1
335fe9ba17fSmarco #define SR_REBUILD_IO_SIZE	128 /* blocks */
3367195049bSmarco 
337b7072a3fSjsing extern struct sr_uuid	sr_bootuuid;
338b7072a3fSjsing extern u_int8_t		sr_bootkey[SR_CRYPTO_MAXKEYBYTES];
339b7072a3fSjsing 
3407195049bSmarco /* forward define to prevent dependency goo */
3417195049bSmarco struct sr_softc;
3427195049bSmarco 
3437195049bSmarco struct sr_ccb {
3447195049bSmarco 	struct buf		ccb_buf;	/* MUST BE FIRST!! */
3457195049bSmarco 
3467195049bSmarco 	struct sr_workunit	*ccb_wu;
3477195049bSmarco 	struct sr_discipline	*ccb_dis;
3487195049bSmarco 
34965c38a59Smarco 	int			ccb_target;
3507195049bSmarco 	int			ccb_state;
3517195049bSmarco #define SR_CCB_FREE		0
3527195049bSmarco #define SR_CCB_INPROGRESS	1
3537195049bSmarco #define SR_CCB_OK		2
3547195049bSmarco #define SR_CCB_FAILED		3
3557195049bSmarco 
356b8c2831aSjsing 	int			ccb_flags;
35791dbade8Sjordan #define SR_CCBF_FREEBUF		(1<<0)		/* free ccb_buf.b_data */
35891dbade8Sjordan 
3592cfeccc5Smarco 	void			*ccb_opaque; /* discipline usable pointer */
3602cfeccc5Smarco 
3617195049bSmarco 	TAILQ_ENTRY(sr_ccb)	ccb_link;
3629a5bbe9dSmarco };
3637195049bSmarco 
3647195049bSmarco TAILQ_HEAD(sr_ccb_list, sr_ccb);
3657195049bSmarco 
3667195049bSmarco struct sr_workunit {
3677195049bSmarco 	struct scsi_xfer	*swu_xs;
3687195049bSmarco 	struct sr_discipline	*swu_dis;
3697195049bSmarco 
3707195049bSmarco 	int			swu_state;
3717195049bSmarco #define SR_WU_FREE		0
3727195049bSmarco #define SR_WU_INPROGRESS	1
3737195049bSmarco #define SR_WU_OK		2
3747195049bSmarco #define SR_WU_FAILED		3
3757195049bSmarco #define SR_WU_PARTIALLYFAILED	4
37606ef7550Smarco #define SR_WU_DEFERRED		5
37706ef7550Smarco #define SR_WU_PENDING		6
37830ad50a2Smarco #define SR_WU_RESTART		7
37930ad50a2Smarco #define SR_WU_REQUEUE		8
38097ec8a20Sjsing #define SR_WU_CONSTRUCT		9
38106ef7550Smarco 
382fe9ba17fSmarco 	int			swu_flags;	/* additional hints */
383b0eaba70Smarco #define SR_WUF_REBUILD		(1<<0)		/* rebuild io */
38451e9de4cSjsing #define SR_WUF_REBUILDIOCOMP	(1<<1)		/* rebuild io complete */
385f3b9c4eeSjordan #define SR_WUF_FAIL		(1<<2)		/* RAID6: failure */
386f3b9c4eeSjordan #define SR_WUF_FAILIOCOMP	(1<<3)
38751e9de4cSjsing #define SR_WUF_WAKEUP		(1<<4)		/* Wakeup on I/O completion. */
38819d58073Sjsing #define SR_WUF_DISCIPLINE	(1<<5)		/* Discipline specific I/O. */
3892b887710Sjsing #define SR_WUF_FAKE		(1<<6)		/* Faked workunit. */
390fe9ba17fSmarco 
39106ef7550Smarco 	/* workunit io range */
3921abdbfdeSderaadt 	daddr_t			swu_blk_start;
3931abdbfdeSderaadt 	daddr_t			swu_blk_end;
3947195049bSmarco 
39598b789a9Sjsing 	/* number of ios that makes up the whole work unit */
39698b789a9Sjsing 	u_int32_t		swu_io_count;
39798b789a9Sjsing 
3987195049bSmarco 	/* in flight totals */
3997195049bSmarco 	u_int32_t		swu_ios_complete;
4007195049bSmarco 	u_int32_t		swu_ios_failed;
4017195049bSmarco 	u_int32_t		swu_ios_succeeded;
4027195049bSmarco 
40306ef7550Smarco 	/* colliding wu */
40406ef7550Smarco 	struct sr_workunit	*swu_collider;
40506ef7550Smarco 
40606ef7550Smarco 	/* all ios that make up this workunit */
40706ef7550Smarco 	struct sr_ccb_list	swu_ccb;
4087195049bSmarco 
4097af3f0fdSmarco 	/* task memory */
4101f300c94Sjsing 	struct task		swu_task;
4117af3f0fdSmarco 	int			swu_cb_active;	/* in callback */
4127af3f0fdSmarco 
41398b789a9Sjsing 	TAILQ_ENTRY(sr_workunit) swu_link;	/* Link in processing queue. */
41498b789a9Sjsing 	TAILQ_ENTRY(sr_workunit) swu_next;	/* Next work unit in chain. */
4157195049bSmarco };
4167195049bSmarco 
4177195049bSmarco TAILQ_HEAD(sr_wu_list, sr_workunit);
4187195049bSmarco 
41984e48fabSmarco /* RAID 0 */
42084e48fabSmarco #define SR_RAID0_NOWU		16
42184e48fabSmarco struct sr_raid0 {
422a7791af9Smarco 	int32_t			sr0_strip_bits;
42384e48fabSmarco };
42484e48fabSmarco 
425bcca2540Smarco /* RAID 1 */
426bcca2540Smarco #define SR_RAID1_NOWU		16
427bcca2540Smarco struct sr_raid1 {
428bcca2540Smarco 	u_int32_t		sr1_counter;
429bcca2540Smarco };
430bcca2540Smarco 
431f8000896Sjsing /* RAID 5 */
432f8000896Sjsing #define SR_RAID5_NOWU		16
433f8000896Sjsing struct sr_raid5 {
434f8000896Sjsing 	int32_t			sr5_strip_bits;
435c390bdbdSmarco };
436c390bdbdSmarco 
437f3b9c4eeSjordan /* RAID 6 */
438f3b9c4eeSjordan #define SR_RAID6_NOWU		16
439f3b9c4eeSjordan struct sr_raid6 {
440f3b9c4eeSjordan 	int32_t			sr6_strip_bits;
441f3b9c4eeSjordan };
442f3b9c4eeSjordan 
4438c887097Smarco /* CRYPTO */
444117fae6fSoga TAILQ_HEAD(sr_crypto_wu_head, sr_crypto_wu);
4453f700ba0Smarco #define SR_CRYPTO_NOWU		16
446117fae6fSoga 
44701de20b5Sstsp /*
44801de20b5Sstsp  * The per-I/O data that we need to preallocate. We cannot afford to allow I/O
44901de20b5Sstsp  * to start failing when memory pressure kicks in. We can store this in the WU
45001de20b5Sstsp  * because we assert that only one ccb per WU will ever be active during crypto.
45101de20b5Sstsp  */
45201de20b5Sstsp struct sr_crypto_wu {
45301de20b5Sstsp 	struct sr_workunit		 cr_wu;		/* Must be first. */
45401de20b5Sstsp 	struct uio			 cr_uio;
45501de20b5Sstsp 	struct iovec			 cr_iov;
45601de20b5Sstsp 	struct cryptop	 		*cr_crp;
45701de20b5Sstsp 	void				*cr_dmabuf;
45801de20b5Sstsp };
45901de20b5Sstsp 
460f18dcc9cStedu struct sr_crypto {
461c907def9Sjsing 	struct sr_meta_crypto	*scr_meta;
4620054cd36Sjsing 	struct sr_chunk		*key_disk;
4638c887097Smarco 
4646d198fe3Sjsing 	int			scr_alg;
4656d198fe3Sjsing 	int			scr_klen;
4666d198fe3Sjsing 
467080cddd5Smarco 	/* XXX only keep scr_sid over time */
4681a9d6c4eShshoexer 	u_int8_t		scr_key[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES];
469c8c45af3Sdjm 	u_int8_t		scr_maskkey[SR_CRYPTO_MAXKEYBYTES];
47075b43c32Sdjm 	u_int64_t		scr_sid[SR_CRYPTO_MAXKEYS];
471bcca2540Smarco };
4727195049bSmarco 
4732b5fc845Sjsing #define SR_CONCAT_NOWU		16
4742b5fc845Sjsing struct sr_concat {
4752b5fc845Sjsing };
4762b5fc845Sjsing 
47701de20b5Sstsp /* RAID 1C */
47801de20b5Sstsp #define SR_RAID1C_NOWU		16
479eb0e73bdSstsp struct sr_raid1c {
480eb0e73bdSstsp 	struct sr_crypto	sr1c_crypto;
481eb0e73bdSstsp 	struct sr_raid1		sr1c_raid1;
482eb0e73bdSstsp };
48301de20b5Sstsp 
4847195049bSmarco struct sr_chunk {
485080cddd5Smarco 	struct sr_meta_chunk	src_meta;	/* chunk meta data */
4867195049bSmarco 
4877195049bSmarco 	/* runtime data */
4887195049bSmarco 	dev_t			src_dev_mm;	/* major/minor */
4894b7d3c47Smarco 	struct vnode		*src_vn;	/* vnode */
4907195049bSmarco 
49197d19cbbSmarco 	/* helper members before metadata makes it onto the chunk  */
49297d19cbbSmarco 	int			src_meta_ondisk;/* set when meta is on disk */
49397d19cbbSmarco 	char			src_devname[32];
4948fdeb3fdSjsing 	u_char			src_duid[8];	/* Chunk disklabel UID. */
495496b32c3Smarco 	int64_t			src_size;	/* in blocks */
496bccb2f38Skrw 	u_int32_t		src_secsize;
49797d19cbbSmarco 
4987195049bSmarco 	SLIST_ENTRY(sr_chunk)	src_link;
4997195049bSmarco };
5007195049bSmarco 
5017195049bSmarco SLIST_HEAD(sr_chunk_head, sr_chunk);
5027195049bSmarco 
5037195049bSmarco struct sr_volume {
5047195049bSmarco 	/* runtime data */
5057195049bSmarco 	struct sr_chunk_head	sv_chunk_list;	/* linked list of all chunks */
5067195049bSmarco 	struct sr_chunk		**sv_chunks;	/* array to same chunks */
50752a49d95Sjsing 	int64_t			sv_chunk_minsz; /* Size of smallest chunk. */
50852a49d95Sjsing 	int64_t			sv_chunk_maxsz; /* Size of largest chunk. */
509b80f645dSmarco 
510b80f645dSmarco 	/* sensors */
511b80f645dSmarco 	struct ksensor		sv_sensor;
51213b6ba62Sjsing 	int			sv_sensor_attached;
5137195049bSmarco };
5147195049bSmarco 
5157195049bSmarco struct sr_discipline {
5167195049bSmarco 	struct sr_softc		*sd_sc;		/* link back to sr softc */
5172d9211fdSbluhm 	size_t			sd_wu_size;	/* alloc and free size */
5187195049bSmarco 	u_int8_t		sd_type;	/* type of discipline */
5197195049bSmarco #define	SR_MD_RAID0		0
5207195049bSmarco #define	SR_MD_RAID1		1
5217195049bSmarco #define	SR_MD_RAID5		2
5227195049bSmarco #define	SR_MD_CACHE		3
5233f700ba0Smarco #define	SR_MD_CRYPTO		4
524a8232f4aStedu 	/* AOE was 5 and 6. */
5250db2cd39Sjsing 	/* SR_MD_RAID4 was 7. */
526f3b9c4eeSjordan #define	SR_MD_RAID6		8
5272b5fc845Sjsing #define	SR_MD_CONCAT		9
52801de20b5Sstsp #define	SR_MD_RAID1C		10
529556bc6c4Skn 	char			sd_name[10];	/* human readable discipline name */
5301baf7721Smatthew 	u_int16_t		sd_target;	/* scsibus target discipline uses */
5317195049bSmarco 
532ac774743Sjsing 	u_int32_t		sd_capabilities;
5332b5fc845Sjsing #define SR_CAP_SYSTEM_DISK	0x00000001	/* Attaches as a system disk. */
5342b5fc845Sjsing #define SR_CAP_AUTO_ASSEMBLE	0x00000002	/* Can auto assemble. */
5352b5fc845Sjsing #define SR_CAP_REBUILD		0x00000004	/* Supports rebuild. */
5362b5fc845Sjsing #define SR_CAP_NON_COERCED	0x00000008	/* Uses non-coerced size. */
5374848162aSjsing #define SR_CAP_REDUNDANT	0x00000010	/* Redundant copies of data. */
538ac774743Sjsing 
5397195049bSmarco 	union {
54084e48fabSmarco 	    struct sr_raid0	mdd_raid0;
5417195049bSmarco 	    struct sr_raid1	mdd_raid1;
542f8000896Sjsing 	    struct sr_raid5	mdd_raid5;
543f3b9c4eeSjordan 	    struct sr_raid6	mdd_raid6;
5442b5fc845Sjsing 	    struct sr_concat	mdd_concat;
5452b5fc845Sjsing #ifdef CRYPTO
546f18dcc9cStedu 	    struct sr_crypto	mdd_crypto;
547eb0e73bdSstsp 	    struct sr_raid1c	mdd_raid1c;
5482b5fc845Sjsing #endif /* CRYPTO */
5497195049bSmarco 	}			sd_dis_specific;/* dis specific members */
5507195049bSmarco #define mds			sd_dis_specific
5517195049bSmarco 
5521f300c94Sjsing 	struct taskq		*sd_taskq;
5537af3f0fdSmarco 
554dcd22300Smarco 	/* discipline metadata */
555dcd22300Smarco 	struct sr_metadata	*sd_meta;	/* in memory copy of metadata */
556080cddd5Smarco 	void			*sd_meta_foreign; /* non native metadata */
557e8a57fdeSmarco 	u_int32_t		sd_meta_flags;
558080cddd5Smarco 	int			sd_meta_type;	/* metadata functions */
559c907def9Sjsing 	struct sr_meta_opt_head sd_meta_opt; /* optional metadata. */
5600580dc1dSmarco 
5619b9d9f36Smarco 	int			sd_sync;
562585d81f0Smarco 	int			sd_must_flush;
563585d81f0Smarco 
564c7c3e8aaSmarco 	int			sd_deleted;
565c7c3e8aaSmarco 
5667195049bSmarco 	/* discipline volume */
5677195049bSmarco 	struct sr_volume	sd_vol;		/* volume associated */
568080cddd5Smarco 	int			sd_vol_status;	/* runtime vol status */
5697195049bSmarco 	/* discipline resources */
5707195049bSmarco 	struct sr_ccb		*sd_ccb;
5717195049bSmarco 	struct sr_ccb_list	sd_ccb_freeq;
5727195049bSmarco 	u_int32_t		sd_max_ccb_per_wu;
5737195049bSmarco 
57498b789a9Sjsing 	struct sr_wu_list	sd_wu;		/* all workunits */
5757195049bSmarco 	u_int32_t		sd_max_wu;
5761f35e705Smarco 	int			sd_reb_active;	/* rebuild in progress */
5778989bbe9Sjsing 	int			sd_reb_abort;	/* abort rebuild */
5789b1bb5e7Smarco 	int			sd_ready;	/* fully operational */
5797195049bSmarco 
58006ef7550Smarco 	struct sr_wu_list	sd_wu_freeq;	/* free wu queue */
58106ef7550Smarco 	struct sr_wu_list	sd_wu_pendq;	/* pending wu queue */
58206ef7550Smarco 	struct sr_wu_list	sd_wu_defq;	/* deferred wu queue */
583e13e110eSkrw 
584e13e110eSkrw 	struct mutex		sd_wu_mtx;
585e13e110eSkrw 	struct scsi_iopool	sd_iopool;
58606ef7550Smarco 
58718e03cc6Smarco 	/* discipline stats */
58818e03cc6Smarco 	int			sd_wu_pending;
58918e03cc6Smarco 	u_int64_t		sd_wu_collisions;
59018e03cc6Smarco 
5917195049bSmarco 	/* discipline functions */
5929847360bSjsing 	int			(*sd_create)(struct sr_discipline *,
5939847360bSjsing 				    struct bioc_createraid *, int, int64_t);
5949847360bSjsing 	int			(*sd_assemble)(struct sr_discipline *,
5957c003ea3Sjsing 				    struct bioc_createraid *, int, void *);
5967195049bSmarco 	int			(*sd_alloc_resources)(struct sr_discipline *);
597820ef724Sjsing 	void			(*sd_free_resources)(struct sr_discipline *);
598d9594f12Sjsing 	int			(*sd_ioctl_handler)(struct sr_discipline *,
599da289b8bSjsing 				    struct bioc_discipline *);
600787a479aSmarco 	int			(*sd_start_discipline)(struct sr_discipline *);
601e665884eSmarco 	void			(*sd_set_chunk_state)(struct sr_discipline *,
602e665884eSmarco 				    int, int);
603e665884eSmarco 	void			(*sd_set_vol_state)(struct sr_discipline *);
60419e286b0Smarco 	int			(*sd_openings)(struct sr_discipline *);
605573449ddSjsing 	int			(*sd_meta_opt_handler)(struct sr_discipline *,
606ee4e3de1Sjsing 				    struct sr_meta_opt_hdr *);
6075d8df638Sjsing 	void			(*sd_rebuild)(struct sr_discipline *);
6087195049bSmarco 
6097195049bSmarco 	/* SCSI emulation */
6107195049bSmarco 	struct scsi_sense_data	sd_scsi_sense;
6117195049bSmarco 	int			(*sd_scsi_rw)(struct sr_workunit *);
612148cc3e1Sjsing 	void			(*sd_scsi_intr)(struct buf *);
61338cf722eSjsing 	int			(*sd_scsi_wu_done)(struct sr_workunit *);
614d01dc9afSjsing 	void			(*sd_scsi_done)(struct sr_workunit *);
6157195049bSmarco 	int			(*sd_scsi_sync)(struct sr_workunit *);
6167195049bSmarco 	int			(*sd_scsi_tur)(struct sr_workunit *);
6177195049bSmarco 	int			(*sd_scsi_start_stop)(struct sr_workunit *);
6187195049bSmarco 	int			(*sd_scsi_inquiry)(struct sr_workunit *);
6197195049bSmarco 	int			(*sd_scsi_read_cap)(struct sr_workunit *);
6207195049bSmarco 	int			(*sd_scsi_req_sense)(struct sr_workunit *);
621fe9ba17fSmarco 
622fe9ba17fSmarco 	/* background operation */
623fe9ba17fSmarco 	struct proc		*sd_background_proc;
624dd2d4a89Sjsing 
625e328a933Sjsing 	/* Tasks. */
626e328a933Sjsing 	struct task		sd_meta_save_task;
6273b545d8fSblambert 	struct task		sd_hotspare_rebuild_task;
628e328a933Sjsing 
629dd2d4a89Sjsing 	TAILQ_ENTRY(sr_discipline) sd_link;
6307195049bSmarco };
6317195049bSmarco 
632dd2d4a89Sjsing TAILQ_HEAD(sr_discipline_list, sr_discipline);
633dd2d4a89Sjsing 
6347195049bSmarco struct sr_softc {
6357195049bSmarco 	struct device		sc_dev;
6367195049bSmarco 
6377195049bSmarco 	struct rwlock		sc_lock;
638b80f645dSmarco 
639313b4264Sjsing 	struct bio_status	sc_status;	/* Status and messages. */
640313b4264Sjsing 
6411e4909a2Sjsing 	struct sr_chunk_head	sc_hotspare_list;	/* List of hotspares. */
6421e4909a2Sjsing 	struct rwlock		sc_hs_lock;	/* Lock for hotspares list. */
6431e4909a2Sjsing 	int			sc_hotspare_no; /* Number of hotspares. */
6441e4909a2Sjsing 
64513b6ba62Sjsing 	struct ksensordev	sc_sensordev;
6461d7cd2d4Sjsing 	struct sensor_task	*sc_sensor_task;
64713b6ba62Sjsing 
6481baf7721Smatthew 	struct scsibus_softc	*sc_scsibus;
649b80f645dSmarco 
650dd2d4a89Sjsing 	/* The target lookup has to be cheap since it happens for each I/O. */
651f7b72a91Sjsing 	struct sr_discipline	*sc_targets[SR_MAX_LD];
652dd2d4a89Sjsing 	struct sr_discipline_list sc_dis_list;
6537195049bSmarco };
654f18dcc9cStedu 
6559b1bb5e7Smarco /* hotplug */
6569b1bb5e7Smarco void			sr_hotplug_register(struct sr_discipline *, void *);
6579b1bb5e7Smarco void			sr_hotplug_unregister(struct sr_discipline *, void *);
6589b1bb5e7Smarco 
6591e4909a2Sjsing /* Hotspare and rebuild. */
660e4195480Sdlg void			sr_hotspare_rebuild_callback(void *);
6611e4909a2Sjsing 
662f18dcc9cStedu /* work units & ccbs */
663080cddd5Smarco int			sr_ccb_alloc(struct sr_discipline *);
664080cddd5Smarco void			sr_ccb_free(struct sr_discipline *);
665080cddd5Smarco struct sr_ccb		*sr_ccb_get(struct sr_discipline *);
666080cddd5Smarco void			sr_ccb_put(struct sr_ccb *);
6671abdbfdeSderaadt struct sr_ccb		*sr_ccb_rw(struct sr_discipline *, int, daddr_t,
668c804f705Skrw 			    long, u_int8_t *, int, int);
6698868790bSjsing void			sr_ccb_done(struct sr_ccb *);
6702d9211fdSbluhm int			sr_wu_alloc(struct sr_discipline *);
671080cddd5Smarco void			sr_wu_free(struct sr_discipline *);
672e13e110eSkrw void			*sr_wu_get(void *);
673e13e110eSkrw void			sr_wu_put(void *, void *);
674cbf13d71Sjsing void			sr_wu_init(struct sr_discipline *,
675cbf13d71Sjsing 			    struct sr_workunit *);
676de0f89e8Sjsing void			sr_wu_enqueue_ccb(struct sr_workunit *,
6776ffa9fd1Sjsing 			    struct sr_ccb *);
678de0f89e8Sjsing void			sr_wu_release_ccbs(struct sr_workunit *);
679d01dc9afSjsing void			sr_wu_done(struct sr_workunit *);
680f18dcc9cStedu 
681f09486a6Smarco /* misc functions */
682313b4264Sjsing void			sr_info(struct sr_softc *, const char *, ...);
683313b4264Sjsing void			sr_warn(struct sr_softc *, const char *, ...);
684313b4264Sjsing void			sr_error(struct sr_softc *, const char *, ...);
685f09486a6Smarco int32_t			sr_validate_stripsize(u_int32_t);
6860054cd36Sjsing int			sr_meta_read(struct sr_discipline *);
6870054cd36Sjsing int			sr_meta_native_read(struct sr_discipline *, dev_t,
6880054cd36Sjsing 			    struct sr_metadata *, void *);
6890054cd36Sjsing int			sr_meta_validate(struct sr_discipline *, dev_t,
6900054cd36Sjsing 			    struct sr_metadata *, void *);
691e4195480Sdlg void			sr_meta_save_callback(void *);
692c6446370Sjsing int			sr_meta_save(struct sr_discipline *, u_int32_t);
6930054cd36Sjsing void			sr_meta_getdevname(struct sr_softc *, dev_t, char *,
6940054cd36Sjsing 			    int);
695573449ddSjsing void			sr_meta_opt_load(struct sr_softc *,
696573449ddSjsing 			    struct sr_metadata *, struct sr_meta_opt_head *);
697c804f705Skrw void			*sr_block_get(struct sr_discipline *, long);
6984c26ac15Sjsing void			sr_block_put(struct sr_discipline *, void *, int);
699c6446370Sjsing void			sr_checksum(struct sr_softc *, void *, void *,
700c6446370Sjsing 			    u_int32_t);
7011abdbfdeSderaadt int			sr_validate_io(struct sr_workunit *, daddr_t *,
7024ce7339fSmarco 			    char *);
70360781f8cSjsing void			sr_schedule_wu(struct sr_workunit *);
7043864d2ceSmarco void			sr_scsi_done(struct sr_discipline *,
7053864d2ceSmarco 			    struct scsi_xfer *);
7067bf8e677Sjsing struct sr_workunit	*sr_scsi_wu_get(struct sr_discipline *, int);
7077bf8e677Sjsing void			sr_scsi_wu_put(struct sr_discipline *,
7087bf8e677Sjsing 			    struct sr_workunit *);
7090054cd36Sjsing int			sr_chunk_in_use(struct sr_softc *, dev_t);
71038301a9fSjsing int			sr_rebuild_percent(struct sr_discipline *);
711f09486a6Smarco 
712f18dcc9cStedu /* discipline functions */
713f18dcc9cStedu int			sr_raid_inquiry(struct sr_workunit *);
714f18dcc9cStedu int			sr_raid_read_cap(struct sr_workunit *);
715f18dcc9cStedu int			sr_raid_tur(struct sr_workunit *);
716f18dcc9cStedu int			sr_raid_request_sense( struct sr_workunit *);
717f18dcc9cStedu int			sr_raid_start_stop(struct sr_workunit *);
718f18dcc9cStedu int			sr_raid_sync(struct sr_workunit *);
71971dbe7f2Sjsing void			sr_raid_intr(struct buf *);
720f18dcc9cStedu void			sr_raid_startwu(struct sr_workunit *);
7214eafb073Sjsing void			sr_raid_recreate_wu(struct sr_workunit *);
722f18dcc9cStedu 
723edc270aeSjsing /* Discipline specific initialisation. */
724edc270aeSjsing void			sr_raid0_discipline_init(struct sr_discipline *);
725edc270aeSjsing void			sr_raid1_discipline_init(struct sr_discipline *);
726f8000896Sjsing void			sr_raid5_discipline_init(struct sr_discipline *);
727f3b9c4eeSjordan void			sr_raid6_discipline_init(struct sr_discipline *);
728edc270aeSjsing void			sr_crypto_discipline_init(struct sr_discipline *);
7292b5fc845Sjsing void			sr_concat_discipline_init(struct sr_discipline *);
73001de20b5Sstsp void			sr_raid1c_discipline_init(struct sr_discipline *);
73184e48fabSmarco 
732edc270aeSjsing /* Crypto discipline hooks. */
733f05efa1dShshoexer int			sr_crypto_get_kdf(struct bioc_createraid *,
734eb0e73bdSstsp 			    struct sr_discipline *, struct sr_crypto *);
735eb0e73bdSstsp int			sr_crypto_create_keys(struct sr_discipline *,
736eb0e73bdSstsp 			    struct sr_crypto *);
737eb0e73bdSstsp struct sr_chunk *	sr_crypto_create_key_disk(struct sr_discipline *,
738eb0e73bdSstsp 			    struct sr_crypto *, dev_t);
739eb0e73bdSstsp struct sr_chunk *	sr_crypto_read_key_disk(struct sr_discipline *,
740eb0e73bdSstsp 			    struct sr_crypto *, dev_t);
7418c887097Smarco 
7427b90f98fSmlarkin /* Hibernate I/O function */
7437b90f98fSmlarkin int			sr_hibernate_io(dev_t dev, daddr_t blkno, vaddr_t addr,
7447b90f98fSmlarkin 			    size_t size, int op, void *page);
7457b90f98fSmlarkin 
7468c887097Smarco #ifdef SR_DEBUG
747f5040c40Sjsing void			sr_dump_block(void *, int);
7488c887097Smarco void			sr_dump_mem(u_int8_t *, int);
7498c887097Smarco #endif
750f18dcc9cStedu 
751c8c45af3Sdjm #endif /* _KERNEL */
752c8c45af3Sdjm 
75384e48fabSmarco #endif /* SOFTRAIDVAR_H */
754