ata-raid.h revision 131113
167071Ssos/*-
2111188Ssos * Copyright (c) 2000 - 2003 S�ren Schmidt <sos@FreeBSD.org>
367071Ssos * All rights reserved.
467071Ssos *
567071Ssos * Redistribution and use in source and binary forms, with or without
667071Ssos * modification, are permitted provided that the following conditions
767071Ssos * are met:
867071Ssos * 1. Redistributions of source code must retain the above copyright
967071Ssos *    notice, this list of conditions and the following disclaimer,
1067071Ssos *    without modification, immediately at the beginning of the file.
1167071Ssos * 2. Redistributions in binary form must reproduce the above copyright
1267071Ssos *    notice, this list of conditions and the following disclaimer in the
1367071Ssos *    documentation and/or other materials provided with the distribution.
1467071Ssos * 3. The name of the author may not be used to endorse or promote products
1567071Ssos *    derived from this software without specific prior written permission.
1667071Ssos *
1767071Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1867071Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1967071Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2067071Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2167071Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2267071Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2367071Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2467071Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2567071Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2667071Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2767071Ssos *
2867071Ssos * $FreeBSD: head/sys/dev/ata/ata-raid.h 131113 2004-06-25 21:21:59Z sos $
2967071Ssos */
3067071Ssos
3191816Ssos/* misc defines */
3291816Ssos#define MAX_ARRAYS	16
3391816Ssos#define MAX_DISKS	16
3491816Ssos#define AR_PROXIMITY	2048
3591816Ssos#define AR_READ		0x01
3691816Ssos#define AR_WRITE	0x02
3791816Ssos#define AR_WAIT		0x04
38111489Ssos#define AR_STRATEGY(x)	(x)->bio_disk->d_strategy((x))
39119404Ssos#define AD_SOFTC(x)	((struct ad_softc *)(x.device->softc))
4093276Ssos#define ATA_MAGIC	"FreeBSD ATA driver RAID "
4191816Ssos
4290215Ssosstruct ar_disk {
4390215Ssos    struct ata_device	*device;
4491593Ssos    u_int64_t		disk_sectors;	/* sectors on this disk */
4590215Ssos    off_t		last_lba;	/* last lba used */
4690215Ssos    int			flags;
4790215Ssos#define AR_DF_PRESENT		0x00000001
4890215Ssos#define AR_DF_ASSIGNED		0x00000002
4990215Ssos#define AR_DF_SPARE		0x00000004
5090215Ssos#define AR_DF_ONLINE		0x00000008
5190215Ssos};
5290215Ssos
5367071Ssosstruct ar_softc {
5490215Ssos    int			lun;
5590215Ssos    int32_t		magic_0;	/* ident for this array */
5690215Ssos    int32_t		magic_1;	/* ident for this array */
5790215Ssos    int			flags;
58131113Ssos#define AR_F_SPAN		0x00000001
59131113Ssos#define AR_F_RAID0		0x00000002
60131113Ssos#define AR_F_RAID1		0x00000004
61131113Ssos#define AR_F_RAID3		0x00000008
62131113Ssos#define AR_F_RAID5		0x00000010
63131113Ssos
64131113Ssos#define AR_F_READY		0x00000100
65131113Ssos#define AR_F_DEGRADED		0x00000200
66131113Ssos#define AR_F_REBUILDING		0x00000400
67131113Ssos#define AR_F_TOGGLE		0x00000800
68131113Ssos
69131113Ssos#define AR_F_FREEBSD_RAID	0x00010000
70131113Ssos#define AR_F_PROMISE_RAID	0x00020000
71131113Ssos#define AR_F_HIGHPOINT_RAID	0x00040000
72131113Ssos#define AR_F_ADAPTEC_RAID	0x00080000
73131113Ssos#define AR_F_LSI_RAID		0x00100000
74131113Ssos#define AR_F_INTEL_RAID		0x00200000
75131113Ssos#define AR_F_QTEC_RAID		0x00400000
76131113Ssos
7790215Ssos    int			total_disks;	/* number of disks in this array */
7890215Ssos    int			generation;	/* generation of this array */
7990566Ssos    struct ar_disk	disks[MAX_DISKS+1]; /* ptr to each disk in array */
8090215Ssos    int			width;		/* array width in disks */
8190215Ssos    u_int16_t		heads;
8290215Ssos    u_int16_t		sectors;
8390215Ssos    u_int32_t		cylinders;
8490215Ssos    u_int64_t		total_sectors;
8593276Ssos    int			interleave;	/* interleave in blocks */
8690215Ssos    int			reserved;	/* sectors that are NOT to be used */
8790215Ssos    int			offset;		/* offset from start of disk */
8890215Ssos    u_int64_t		lock_start;	/* start of locked area for rebuild */
8990215Ssos    u_int64_t		lock_end;	/* end of locked area for rebuild */
90125975Sphk    struct disk		*disk;		/* disklabel/slice stuff */
9192343Ssos    struct proc		*pid;		/* rebuilder process id */
9267071Ssos};
9367071Ssos
9467071Ssosstruct ar_buf {
9591816Ssos    struct bio		bp;		/* must be first element! */
9691914Ssos    struct bio		*org;
9790215Ssos    struct ar_buf	*mirror;
9890215Ssos    int			drive;
9990215Ssos    int			flags;
10090215Ssos#define AB_F_DONE		0x01
10167071Ssos};
10267071Ssos
103131113Ssos
10490215Ssos#define HPT_LBA			9
10590215Ssos
10667071Ssosstruct highpoint_raid_conf {
10767071Ssos    int8_t		filler1[32];
108131113Ssos    u_int32_t		magic;
10967071Ssos#define HPT_MAGIC_OK		0x5a7816f0
11067071Ssos#define HPT_MAGIC_BAD		0x5a7816fd
11167071Ssos
11267071Ssos    u_int32_t		magic_0;
11367071Ssos    u_int32_t		magic_1;
11467071Ssos    u_int32_t		order;
11593276Ssos#define HPT_O_RAID0		0x01
11691914Ssos#define HPT_O_RAID1		0x02
11793276Ssos#define HPT_O_OK		0x04
11867071Ssos
11990215Ssos    u_int8_t		array_width;
12090215Ssos    u_int8_t		stripe_shift;
12167071Ssos    u_int8_t		type;
12290215Ssos#define HPT_T_RAID0		0x00
12390215Ssos#define HPT_T_RAID1		0x01
12490215Ssos#define HPT_T_RAID01_RAID0	0x02
12567071Ssos#define HPT_T_SPAN		0x03
12667071Ssos#define HPT_T_RAID_3		0x04
12767071Ssos#define HPT_T_RAID_5		0x05
12867071Ssos#define HPT_T_SINGLEDISK	0x06
12990215Ssos#define HPT_T_RAID01_RAID1	0x07
13067071Ssos
13167071Ssos    u_int8_t		disk_number;
13290215Ssos    u_int32_t		total_sectors;
13367071Ssos    u_int32_t		disk_mode;
13467071Ssos    u_int32_t		boot_mode;
13567071Ssos    u_int8_t		boot_disk;
13667071Ssos    u_int8_t		boot_protect;
13767071Ssos    u_int8_t		error_log_entries;
13867071Ssos    u_int8_t		error_log_index;
13967071Ssos    struct {
14067071Ssos	u_int32_t	timestamp;
14167071Ssos	u_int8_t	reason;
14290215Ssos#define HPT_R_REMOVED		0xfe
14390215Ssos#define HPT_R_BROKEN		0xff
14467071Ssos
14567071Ssos	u_int8_t	disk;
14667071Ssos	u_int8_t	status;
14767071Ssos	u_int8_t	sectors;
14867071Ssos	u_int32_t	lba;
14967071Ssos    } errorlog[32];
15091861Ssos    int8_t		filler2[16];
15191914Ssos    u_int32_t		rebuild_lba;
15291861Ssos    u_int8_t		dummy_1;
15391861Ssos    u_int8_t		name_1[15];
15491861Ssos    u_int8_t		dummy_2;
15591861Ssos    u_int8_t		name_2[15];
15691861Ssos    int8_t		filler3[8];
157103870Salfred} __packed;
15867071Ssos
15990566Ssos
160131113Ssos#define LSI_LBA(adp)	(adp->total_secs - 1)
161131113Ssos
162131113Ssosstruct lsi_raid_conf {
163131113Ssos    u_int8_t		lsi_id[6];
164131113Ssos#define LSI_MAGIC	"$XIDE$"
165131113Ssos
166131113Ssos    u_int8_t		dummy_1;
167131113Ssos    u_int8_t		flags;
168131113Ssos    u_int8_t		version[2];
169131113Ssos    u_int8_t		config_entries;
170131113Ssos    u_int8_t		raid_count;
171131113Ssos    u_int8_t		total_disks;
172131113Ssos    u_int8_t		dummy_d;
173131113Ssos    u_int8_t		dummy_e;
174131113Ssos    u_int8_t		dummy_f;
175131113Ssos
176131113Ssos    union {
177131113Ssos	struct {
178131113Ssos	    u_int8_t	type;
179131113Ssos#define LSI_R_RAID0	0x01
180131113Ssos#define LSI_R_RAID1	0x02
181131113Ssos#define LSI_R_SPARE	0x08
182131113Ssos
183131113Ssos	    u_int8_t	dummy_1;
184131113Ssos	    u_int16_t	stripe_size;
185131113Ssos	    u_int8_t	raid_width;
186131113Ssos	    u_int8_t	disk_count;
187131113Ssos	    u_int8_t	config_offset;
188131113Ssos	    u_int8_t	dummy_7;
189131113Ssos	    u_int8_t	flags;
190131113Ssos#define LSI_R_DEGRADED	0x02
191131113Ssos
192131113Ssos	    u_int32_t	total_sectors;
193131113Ssos	    u_int8_t	filler[3];
194131113Ssos	} __packed raid;
195131113Ssos	struct {
196131113Ssos	    u_int8_t	device;
197131113Ssos#define LSI_D_MASTER	0x00
198131113Ssos#define LSI_D_SLAVE	0x01
199131113Ssos#define LSI_D_CHANNEL0	0x00
200131113Ssos#define LSI_D_CHANNEL1	0x10
201131113Ssos#define LSI_D_NONE	0xff
202131113Ssos
203131113Ssos	    u_int8_t	dummy_1;
204131113Ssos	    u_int32_t	disk_sectors;
205131113Ssos	    u_int8_t	disk_number;
206131113Ssos	    u_int8_t	raid_number;
207131113Ssos	    u_int8_t	flags;
208131113Ssos#define LSI_D_GONE	0x02
209131113Ssos
210131113Ssos	    u_int8_t	filler[7];
211131113Ssos	} __packed disk;
212131113Ssos    } configs[30];
213131113Ssos    u_int8_t		disk_number;
214131113Ssos    u_int8_t		raid_number;
215131113Ssos    u_int32_t		timestamp;
216131113Ssos    u_int8_t		filler[10];
217131113Ssos} __packed;
218131113Ssos
219131113Ssos
22090215Ssos#define PR_LBA(adp) \
22190215Ssos	(((adp->total_secs / (adp->heads * adp->sectors)) * \
22290215Ssos	  adp->heads * adp->sectors) - adp->sectors)
22390215Ssos
22467071Ssosstruct promise_raid_conf {
22567071Ssos    char		promise_id[24];
22667071Ssos#define PR_MAGIC	"Promise Technology, Inc."
22767071Ssos
22890215Ssos    u_int32_t		dummy_0;
22990566Ssos    u_int64_t		magic_0;
23094408Ssos#define PR_MAGIC0(x)	(x.device ? ((u_int64_t)x.device->channel->unit<<48) | \
23194408Ssos			((u_int64_t)(x.device->unit != 0) << 56) : 0)
23290215Ssos    u_int16_t		magic_1;
23390215Ssos    u_int32_t		magic_2;
23490215Ssos    u_int8_t		filler1[470];
23567071Ssos    struct {
236131113Ssos	u_int32_t	integrity;
23790215Ssos#define PR_I_VALID		0x00000080
23890215Ssos
23990215Ssos	u_int8_t	flags;
24090215Ssos#define PR_F_VALID		0x00000001
24190215Ssos#define PR_F_ONLINE		0x00000002
24290215Ssos#define PR_F_ASSIGNED		0x00000004
24390215Ssos#define PR_F_SPARE		0x00000008
24490215Ssos#define PR_F_DUPLICATE		0x00000010
24590215Ssos#define PR_F_REDIR		0x00000020
24690215Ssos#define PR_F_DOWN		0x00000040
24784485Ssos#define PR_F_READY		0x00000080
24867071Ssos
24990215Ssos	u_int8_t	disk_number;
25090215Ssos	u_int8_t	channel;
25190215Ssos	u_int8_t	device;
252103870Salfred	u_int64_t	magic_0 __packed;
253131113Ssos	u_int32_t	disk_offset;
25490215Ssos	u_int32_t	disk_sectors;
25590566Ssos	u_int32_t	rebuild_lba;
25690215Ssos	u_int16_t	generation;
25790215Ssos	u_int8_t	status;
25890215Ssos#define PR_S_VALID		0x01
25990215Ssos#define PR_S_ONLINE		0x02
26090215Ssos#define PR_S_INITED		0x04
26190215Ssos#define PR_S_READY		0x08
26290215Ssos#define PR_S_DEGRADED		0x10
26390215Ssos#define PR_S_MARKED		0x20
26490566Ssos#define PR_S_FUNCTIONAL		0x80
26567071Ssos
26690215Ssos	u_int8_t	type;
26790215Ssos#define PR_T_RAID0		0x00
26890215Ssos#define PR_T_RAID1		0x01
26990215Ssos#define PR_T_RAID3		0x02
27090215Ssos#define PR_T_RAID5		0x04
27190215Ssos#define PR_T_SPAN		0x08
27267071Ssos
273131113Ssos	u_int8_t	total_disks;
27490215Ssos	u_int8_t	stripe_shift;
27590215Ssos	u_int8_t	array_width;
27668183Ssos	u_int8_t	array_number;
27790215Ssos	u_int32_t	total_sectors;
27867071Ssos	u_int16_t	cylinders;
27967071Ssos	u_int8_t	heads;
28067071Ssos	u_int8_t	sectors;
281103870Salfred	int64_t		magic_1 __packed;
282131113Ssos	struct {
28390215Ssos	    u_int8_t	flags;
28490215Ssos	    u_int8_t	dummy_0;
28590215Ssos	    u_int8_t	channel;
28690215Ssos	    u_int8_t	device;
287103870Salfred	    u_int64_t	magic_0 __packed;
28867071Ssos	} disk[8];
28968183Ssos    } raid;
29068183Ssos    int32_t		filler2[346];
29190215Ssos    u_int32_t		checksum;
292103870Salfred} __packed;
29367071Ssos
29491593Ssosint ata_raiddisk_attach(struct ad_softc *);
29591593Ssosint ata_raiddisk_detach(struct ad_softc *);
29690566Ssosvoid ata_raid_attach(void);
29793276Ssosint ata_raid_create(struct raid_setup *);
29893276Ssosint ata_raid_delete(int);
299113245Ssosint ata_raid_status(int, struct raid_status *);
300114529Ssosint ata_raid_addspare(int, int);
30191593Ssosint ata_raid_rebuild(int);
302