summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/ata-raid.h
blob: 7a3e7a998d588fe710fdaebbbee428c53cbfd2cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/*-
 * Copyright (c) 2000 - 2003 Søren Schmidt <sos@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer,
 *    without modification, immediately at the beginning of the file.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD$
 */

/* misc defines */
#define MAX_ARRAYS	16
#define MAX_DISKS	16
#define AR_PROXIMITY	2048
#define AR_READ		0x01
#define AR_WRITE	0x02
#define AR_WAIT		0x04
#define AR_STRATEGY(x)	(x)->bio_disk->d_strategy((x))
#define AD_SOFTC(x)	((struct ad_softc *)(x.device->softc))
#define ATA_MAGIC	"FreeBSD ATA driver RAID "

struct ar_disk {
    struct ata_device	*device;
    u_int64_t		disk_sectors;	/* sectors on this disk */
    off_t		last_lba;	/* last lba used */
    int			flags;
#define AR_DF_PRESENT		0x00000001
#define AR_DF_ASSIGNED		0x00000002
#define AR_DF_SPARE		0x00000004
#define AR_DF_ONLINE		0x00000008
};

struct ar_softc {
    int			lun;
    int32_t		magic_0;	/* ident for this array */
    int32_t		magic_1;	/* ident for this array */
    int			flags;
#define AR_F_SPAN		0x00000001
#define AR_F_RAID0		0x00000002
#define AR_F_RAID1		0x00000004
#define AR_F_RAID3		0x00000008
#define AR_F_RAID5		0x00000010	

#define AR_F_READY		0x00000100
#define AR_F_DEGRADED		0x00000200
#define AR_F_REBUILDING		0x00000400
#define AR_F_TOGGLE		0x00000800

#define AR_F_FREEBSD_RAID	0x00010000
#define AR_F_PROMISE_RAID	0x00020000
#define AR_F_HIGHPOINT_RAID	0x00040000
#define AR_F_ADAPTEC_RAID	0x00080000
#define AR_F_LSI_RAID		0x00100000
#define AR_F_INTEL_RAID		0x00200000
#define AR_F_QTEC_RAID		0x00400000

    int			total_disks;	/* number of disks in this array */
    int			generation;	/* generation of this array */
    struct ar_disk	disks[MAX_DISKS+1]; /* ptr to each disk in array */
    int			width;		/* array width in disks */
    u_int16_t		heads;
    u_int16_t		sectors;
    u_int32_t		cylinders;
    u_int64_t		total_sectors;
    int			interleave;	/* interleave in blocks */
    int			reserved;	/* sectors that are NOT to be used */
    int			offset;		/* offset from start of disk */
    u_int64_t		lock_start;	/* start of locked area for rebuild */
    u_int64_t		lock_end;	/* end of locked area for rebuild */
    struct disk		*disk;		/* disklabel/slice stuff */
    struct proc		*pid;		/* rebuilder process id */
};

struct ar_buf {
    struct bio		bp;		/* must be first element! */
    struct bio		*org;
    struct ar_buf	*mirror;
    int			drive;
    int			flags;
#define AB_F_DONE		0x01
};


#define HPT_LBA			9

struct highpoint_raid_conf {
    int8_t		filler1[32];
    u_int32_t		magic;
#define HPT_MAGIC_OK		0x5a7816f0
#define HPT_MAGIC_BAD		0x5a7816fd

    u_int32_t		magic_0;
    u_int32_t		magic_1;
    u_int32_t		order;
#define HPT_O_RAID0		0x01
#define HPT_O_RAID1		0x02
#define HPT_O_OK		0x04

    u_int8_t		array_width;
    u_int8_t		stripe_shift;
    u_int8_t		type;
#define HPT_T_RAID0		0x00
#define HPT_T_RAID1		0x01
#define HPT_T_RAID01_RAID0	0x02
#define HPT_T_SPAN		0x03
#define HPT_T_RAID_3		0x04
#define HPT_T_RAID_5		0x05
#define HPT_T_SINGLEDISK	0x06
#define HPT_T_RAID01_RAID1	0x07

    u_int8_t		disk_number;
    u_int32_t		total_sectors;
    u_int32_t		disk_mode;
    u_int32_t		boot_mode;
    u_int8_t		boot_disk;
    u_int8_t		boot_protect;
    u_int8_t		error_log_entries;
    u_int8_t		error_log_index;
    struct {
	u_int32_t	timestamp;
	u_int8_t	reason;
#define HPT_R_REMOVED		0xfe
#define HPT_R_BROKEN		0xff
	
	u_int8_t	disk;
	u_int8_t	status;
	u_int8_t	sectors;
	u_int32_t	lba;
    } errorlog[32];
    int8_t		filler2[16];
    u_int32_t		rebuild_lba;
    u_int8_t		dummy_1;
    u_int8_t		name_1[15];
    u_int8_t		dummy_2;
    u_int8_t		name_2[15];
    int8_t		filler3[8];
} __packed;


#define LSI_LBA(adp)	(adp->total_secs - 1)

struct lsi_raid_conf {
    u_int8_t		lsi_id[6];
#define LSI_MAGIC	"$XIDE$"

    u_int8_t		dummy_1;
    u_int8_t		flags;
    u_int8_t		version[2];
    u_int8_t		config_entries;
    u_int8_t		raid_count;
    u_int8_t		total_disks;
    u_int8_t		dummy_d;
    u_int8_t		dummy_e;
    u_int8_t		dummy_f;

    union {
	struct {
	    u_int8_t	type;
#define LSI_R_RAID0	0x01
#define LSI_R_RAID1	0x02
#define LSI_R_SPARE	0x08

	    u_int8_t	dummy_1;
	    u_int16_t	stripe_size;
	    u_int8_t	raid_width;
	    u_int8_t	disk_count;
	    u_int8_t	config_offset;
	    u_int8_t	dummy_7;
	    u_int8_t	flags;
#define LSI_R_DEGRADED	0x02

	    u_int32_t	total_sectors;
	    u_int8_t	filler[3];
	} __packed raid;
	struct {
	    u_int8_t	device;
#define LSI_D_MASTER	0x00
#define LSI_D_SLAVE	0x01
#define LSI_D_CHANNEL0	0x00
#define LSI_D_CHANNEL1	0x10
#define LSI_D_NONE	0xff

	    u_int8_t	dummy_1;
	    u_int32_t	disk_sectors;
	    u_int8_t	disk_number;
	    u_int8_t	raid_number;
	    u_int8_t	flags;
#define LSI_D_GONE	0x02

	    u_int8_t	filler[7];
	} __packed disk;
    } configs[30];
    u_int8_t		disk_number;
    u_int8_t		raid_number;
    u_int32_t		timestamp;
    u_int8_t		filler[10];
} __packed;


#define PR_LBA(adp) \
	(((adp->total_secs / (adp->heads * adp->sectors)) * \
	  adp->heads * adp->sectors) - adp->sectors)

struct promise_raid_conf {
    char		promise_id[24];
#define PR_MAGIC	"Promise Technology, Inc."

    u_int32_t		dummy_0;
    u_int64_t		magic_0;
#define PR_MAGIC0(x)	(x.device ? ((u_int64_t)x.device->channel->unit<<48) | \
			((u_int64_t)(x.device->unit != 0) << 56) : 0)
    u_int16_t		magic_1;
    u_int32_t		magic_2;
    u_int8_t		filler1[470];
    struct {
	u_int32_t	integrity;
#define PR_I_VALID		0x00000080

	u_int8_t	flags;
#define PR_F_VALID		0x00000001
#define PR_F_ONLINE		0x00000002
#define PR_F_ASSIGNED		0x00000004
#define PR_F_SPARE		0x00000008
#define PR_F_DUPLICATE		0x00000010
#define PR_F_REDIR		0x00000020
#define PR_F_DOWN		0x00000040
#define PR_F_READY		0x00000080

	u_int8_t	disk_number;
	u_int8_t	channel;
	u_int8_t	device;
	u_int64_t	magic_0 __packed;
	u_int32_t	disk_offset;
	u_int32_t	disk_sectors;
	u_int32_t	rebuild_lba;
	u_int16_t	generation;
	u_int8_t	status;
#define PR_S_VALID		0x01
#define PR_S_ONLINE		0x02
#define PR_S_INITED		0x04
#define PR_S_READY		0x08
#define PR_S_DEGRADED		0x10
#define PR_S_MARKED		0x20
#define PR_S_FUNCTIONAL		0x80

	u_int8_t	type;
#define PR_T_RAID0		0x00
#define PR_T_RAID1		0x01
#define PR_T_RAID3		0x02
#define PR_T_RAID5		0x04
#define PR_T_SPAN		0x08

	u_int8_t	total_disks;
	u_int8_t	stripe_shift;
	u_int8_t	array_width;
	u_int8_t	array_number;
	u_int32_t	total_sectors;
	u_int16_t	cylinders;
	u_int8_t	heads;
	u_int8_t	sectors;
	int64_t		magic_1 __packed;
	struct {
	    u_int8_t	flags;
	    u_int8_t	dummy_0;
	    u_int8_t	channel;
	    u_int8_t	device;
	    u_int64_t	magic_0 __packed;
	} disk[8];
    } raid;
    int32_t		filler2[346];
    u_int32_t		checksum;
} __packed;

int ata_raiddisk_attach(struct ad_softc *);
int ata_raiddisk_detach(struct ad_softc *);
void ata_raid_attach(void);
int ata_raid_create(struct raid_setup *);
int ata_raid_delete(int);
int ata_raid_status(int, struct raid_status *);
int ata_raid_addspare(int, int);
int ata_raid_rebuild(int);
OpenPOWER on IntegriCloud