ata-raid.h revision 94408
150397Sobrien/*-
290075Sobrien * Copyright (c) 2000,2001,2002 S�ren Schmidt <sos@FreeBSD.org>
390075Sobrien * All rights reserved.
450397Sobrien *
550397Sobrien * Redistribution and use in source and binary forms, with or without
650397Sobrien * modification, are permitted provided that the following conditions
750397Sobrien * are met:
890075Sobrien * 1. Redistributions of source code must retain the above copyright
950397Sobrien *    notice, this list of conditions and the following disclaimer,
1090075Sobrien *    without modification, immediately at the beginning of the file.
1190075Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1290075Sobrien *    notice, this list of conditions and the following disclaimer in the
1390075Sobrien *    documentation and/or other materials provided with the distribution.
1450397Sobrien * 3. The name of the author may not be used to endorse or promote products
1590075Sobrien *    derived from this software without specific prior written permission.
1690075Sobrien *
1790075Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1890075Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1950397Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2050397Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2190075Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2290075Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2390075Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2450397Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2590075Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2690075Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2790075Sobrien *
2890075Sobrien * $FreeBSD: head/sys/dev/ata/ata-raid.h 94408 2002-04-11 08:52:32Z sos $
2990075Sobrien */
3090075Sobrien
3150397Sobrien/* misc defines */
3250397Sobrien#define MAX_ARRAYS	16
3350397Sobrien#define MAX_DISKS	16
3450397Sobrien#define AR_PROXIMITY	2048
3550397Sobrien#define AR_READ		0x01
3650397Sobrien#define AR_WRITE	0x02
3750397Sobrien#define AR_WAIT		0x04
3850397Sobrien#define AR_STRATEGY(x)	(x)->bio_dev->si_disk->d_devsw->d_strategy((x))
3950397Sobrien#define AD_SOFTC(x)	((struct ad_softc *)(x.device->driver))
4050397Sobrien#define ATA_MAGIC	"FreeBSD ATA driver RAID "
41117395Skan
4250397Sobrienstruct ar_disk {
4350397Sobrien    struct ata_device	*device;
4450397Sobrien    u_int64_t		disk_sectors;	/* sectors on this disk */
4550397Sobrien    off_t		last_lba;	/* last lba used */
4650397Sobrien    int			flags;
4790075Sobrien#define AR_DF_PRESENT		0x00000001
4850397Sobrien#define AR_DF_ASSIGNED		0x00000002
4950397Sobrien#define AR_DF_SPARE		0x00000004
5090075Sobrien#define AR_DF_ONLINE		0x00000008
5150397Sobrien};
5250397Sobrien
5350397Sobrienstruct ar_softc {
5490075Sobrien    int			lun;
5550397Sobrien    int32_t		magic_0;	/* ident for this array */
5690075Sobrien    int32_t		magic_1;	/* ident for this array */
5790075Sobrien    int			flags;
5890075Sobrien#define AR_F_RAID0		0x0001	/* STRIPE */
5990075Sobrien#define AR_F_RAID1		0x0002	/* MIRROR */
6090075Sobrien#define AR_F_SPAN		0x0004	/* SPAN */
6190075Sobrien#define AR_F_READY		0x0100
6290075Sobrien#define AR_F_DEGRADED		0x0200
6390075Sobrien#define AR_F_REBUILDING		0x0400
6490075Sobrien#define AR_F_PROMISE_RAID	0x1000
65117395Skan#define AR_F_HIGHPOINT_RAID	0x2000
6650397Sobrien#define AR_F_FREEBSD_RAID	0x4000
6790075Sobrien
6890075Sobrien    int			total_disks;	/* number of disks in this array */
6950397Sobrien    int			generation;	/* generation of this array */
7050397Sobrien    struct ar_disk	disks[MAX_DISKS+1]; /* ptr to each disk in array */
7190075Sobrien    int			width;		/* array width in disks */
7290075Sobrien    u_int16_t		heads;
7390075Sobrien    u_int16_t		sectors;
7490075Sobrien    u_int32_t		cylinders;
7590075Sobrien    u_int64_t		total_sectors;
7690075Sobrien    int			interleave;	/* interleave in blocks */
7790075Sobrien    int			reserved;	/* sectors that are NOT to be used */
7890075Sobrien    int			offset;		/* offset from start of disk */
7990075Sobrien    u_int64_t		lock_start;	/* start of locked area for rebuild */
8090075Sobrien    u_int64_t		lock_end;	/* end of locked area for rebuild */
8190075Sobrien    struct disk		disk;		/* disklabel/slice stuff */
8290075Sobrien    struct proc		*pid;		/* rebuilder process id */
8390075Sobrien    dev_t		dev;		/* device place holder */
8490075Sobrien};
8590075Sobrien
8690075Sobrienstruct ar_buf {
8790075Sobrien    struct bio		bp;		/* must be first element! */
8890075Sobrien    struct bio		*org;
8950397Sobrien    struct ar_buf	*mirror;
9050397Sobrien    int			drive;
9150397Sobrien    int			flags;
9250397Sobrien#define AB_F_DONE		0x01
9350397Sobrien};
9450397Sobrien
9550397Sobrien#define HPT_LBA			9
9690075Sobrien
9750397Sobrienstruct highpoint_raid_conf {
9890075Sobrien    int8_t		filler1[32];
9950397Sobrien    u_int32_t		magic;			/* 0x20 */
10050397Sobrien#define HPT_MAGIC_OK		0x5a7816f0
10190075Sobrien#define HPT_MAGIC_BAD		0x5a7816fd
10290075Sobrien
10350397Sobrien    u_int32_t		magic_0;
10450397Sobrien    u_int32_t		magic_1;
10550397Sobrien    u_int32_t		order;
10650397Sobrien#define HPT_O_RAID0		0x01
10790075Sobrien#define HPT_O_RAID1		0x02
10890075Sobrien#define HPT_O_OK		0x04
10990075Sobrien
11090075Sobrien    u_int8_t		array_width;
11190075Sobrien    u_int8_t		stripe_shift;
11290075Sobrien    u_int8_t		type;
11390075Sobrien#define HPT_T_RAID0		0x00
11490075Sobrien#define HPT_T_RAID1		0x01
11590075Sobrien#define HPT_T_RAID01_RAID0	0x02
11690075Sobrien#define HPT_T_SPAN		0x03
11790075Sobrien#define HPT_T_RAID_3		0x04
11890075Sobrien#define HPT_T_RAID_5		0x05
11990075Sobrien#define HPT_T_SINGLEDISK	0x06
120117395Skan#define HPT_T_RAID01_RAID1	0x07
121117395Skan
122117395Skan    u_int8_t		disk_number;
123117395Skan    u_int32_t		total_sectors;
124117395Skan    u_int32_t		disk_mode;
125117395Skan    u_int32_t		boot_mode;
126117395Skan    u_int8_t		boot_disk;
127117395Skan    u_int8_t		boot_protect;
128117395Skan    u_int8_t		error_log_entries;
129117395Skan    u_int8_t		error_log_index;
130117395Skan    struct {
131117395Skan	u_int32_t	timestamp;
132117395Skan	u_int8_t	reason;
133117395Skan#define HPT_R_REMOVED		0xfe
134117395Skan#define HPT_R_BROKEN		0xff
135117395Skan
13690075Sobrien	u_int8_t	disk;
137117395Skan	u_int8_t	status;
13890075Sobrien	u_int8_t	sectors;
13990075Sobrien	u_int32_t	lba;
14090075Sobrien    } errorlog[32];
14190075Sobrien    int8_t		filler2[16];
14290075Sobrien    u_int32_t		rebuild_lba;
143117395Skan    u_int8_t		dummy_1;
14490075Sobrien    u_int8_t		name_1[15];
14590075Sobrien    u_int8_t		dummy_2;
14690075Sobrien    u_int8_t		name_2[15];
14790075Sobrien    int8_t		filler3[8];
148117395Skan} __attribute__((packed));
149117395Skan
150117395Skan
151117395Skan#define PR_LBA(adp) \
152117395Skan	(((adp->total_secs / (adp->heads * adp->sectors)) * \
153117395Skan	  adp->heads * adp->sectors) - adp->sectors)
154117395Skan
155117395Skanstruct promise_raid_conf {
156117395Skan    char		promise_id[24];
157117395Skan#define PR_MAGIC	"Promise Technology, Inc."
158117395Skan
159117395Skan    u_int32_t		dummy_0;
160117395Skan    u_int64_t		magic_0;
161117395Skan#define PR_MAGIC0(x)	(x.device ? ((u_int64_t)x.device->channel->unit<<48) | \
162117395Skan			((u_int64_t)(x.device->unit != 0) << 56) : 0)
163117395Skan    u_int16_t		magic_1;
16450397Sobrien    u_int32_t		magic_2;
16550397Sobrien    u_int8_t		filler1[470];
16650397Sobrien    struct {
16750397Sobrien	u_int32_t	integrity;		/* 0x200 */
16850397Sobrien#define PR_I_VALID		0x00000080
16950397Sobrien
17050397Sobrien	u_int8_t	flags;
17150397Sobrien#define PR_F_VALID		0x00000001
17250397Sobrien#define PR_F_ONLINE		0x00000002
17350397Sobrien#define PR_F_ASSIGNED		0x00000004
17450397Sobrien#define PR_F_SPARE		0x00000008
17550397Sobrien#define PR_F_DUPLICATE		0x00000010
17650397Sobrien#define PR_F_REDIR		0x00000020
17750397Sobrien#define PR_F_DOWN		0x00000040
17850397Sobrien#define PR_F_READY		0x00000080
17950397Sobrien
18050397Sobrien	u_int8_t	disk_number;
18150397Sobrien	u_int8_t	channel;
18250397Sobrien	u_int8_t	device;
18350397Sobrien	u_int64_t	magic_0 __attribute__((packed));
18490075Sobrien	u_int32_t	disk_offset;		/* 0x210 */
18590075Sobrien	u_int32_t	disk_sectors;
18650397Sobrien	u_int32_t	rebuild_lba;
18750397Sobrien	u_int16_t	generation;
18850397Sobrien	u_int8_t	status;
18950397Sobrien#define PR_S_VALID		0x01
19050397Sobrien#define PR_S_ONLINE		0x02
19150397Sobrien#define PR_S_INITED		0x04
19250397Sobrien#define PR_S_READY		0x08
19350397Sobrien#define PR_S_DEGRADED		0x10
19450397Sobrien#define PR_S_MARKED		0x20
19550397Sobrien#define PR_S_FUNCTIONAL		0x80
19650397Sobrien
19750397Sobrien	u_int8_t	type;
19890075Sobrien#define PR_T_RAID0		0x00
19990075Sobrien#define PR_T_RAID1		0x01
20090075Sobrien#define PR_T_RAID3		0x02
20190075Sobrien#define PR_T_RAID5		0x04
20290075Sobrien#define PR_T_SPAN		0x08
20390075Sobrien
20490075Sobrien	u_int8_t	total_disks;		/* 0x220 */
20590075Sobrien	u_int8_t	stripe_shift;
20690075Sobrien	u_int8_t	array_width;
20790075Sobrien	u_int8_t	array_number;
20890075Sobrien	u_int32_t	total_sectors;
20990075Sobrien	u_int16_t	cylinders;
21090075Sobrien	u_int8_t	heads;
21150397Sobrien	u_int8_t	sectors;
21250397Sobrien	int64_t		magic_1 __attribute__((packed));
21390075Sobrien	struct {				/* 0x240 */
21450397Sobrien	    u_int8_t	flags;
21550397Sobrien	    u_int8_t	dummy_0;
21650397Sobrien	    u_int8_t	channel;
21750397Sobrien	    u_int8_t	device;
21850397Sobrien	    u_int64_t	magic_0 __attribute__((packed));
21990075Sobrien	} disk[8];
22090075Sobrien    } raid;
22190075Sobrien    int32_t		filler2[346];
22250397Sobrien    u_int32_t		checksum;
22390075Sobrien} __attribute__((packed));
224117395Skan
22590075Sobrienint ata_raiddisk_probe(struct ad_softc *);
22690075Sobrienint ata_raiddisk_attach(struct ad_softc *);
22750397Sobrienint ata_raiddisk_detach(struct ad_softc *);
22850397Sobrienvoid ata_raid_attach(void);
22950397Sobrienint ata_raid_create(struct raid_setup *);
23090075Sobrienint ata_raid_delete(int);
23150397Sobrienint ata_raid_status(int array, struct raid_status *);
23250397Sobrienint ata_raid_rebuild(int);
23390075Sobrien