]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/dev/ata/ata-raid.c
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.git] / 6 / sys / dev / ata / ata-raid.c
1 /*-
2  * Copyright (c) 2000 - 2006 Søren Schmidt <sos@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification, immediately at the beginning of the file.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include "opt_ata.h"
31 #include <sys/param.h>
32 #include <sys/systm.h> 
33 #include <sys/ata.h> 
34 #include <sys/kernel.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/endian.h>
38 #include <sys/bio.h>
39 #include <sys/bus.h>
40 #include <sys/conf.h>
41 #include <sys/disk.h>
42 #include <sys/cons.h>
43 #include <sys/sema.h>
44 #include <sys/taskqueue.h>
45 #include <vm/uma.h>
46 #include <machine/bus.h>
47 #include <sys/rman.h>
48 #include <dev/pci/pcivar.h>
49 #include <geom/geom_disk.h>
50 #include <dev/ata/ata-all.h>
51 #include <dev/ata/ata-disk.h>
52 #include <dev/ata/ata-raid.h>
53 #include <dev/ata/ata-pci.h>
54 #include <ata_if.h>
55
56 /* prototypes */
57 static void ata_raid_done(struct ata_request *request);
58 static void ata_raid_config_changed(struct ar_softc *rdp, int writeback);
59 static int ata_raid_status_old(struct ata_ioc_raid_config *config);
60 static int ata_raid_status(struct ata_ioc_raid_status *status);
61 static int ata_raid_create(struct ata_ioc_raid_config *config);
62 static int ata_raid_delete(int array);
63 static int ata_raid_addspare(struct ata_ioc_raid_config *config);
64 static int ata_raid_rebuild(int array);
65 static int ata_raid_read_metadata(device_t subdisk);
66 static int ata_raid_write_metadata(struct ar_softc *rdp);
67 static int ata_raid_wipe_metadata(struct ar_softc *rdp);
68 static int ata_raid_adaptec_read_meta(device_t dev, struct ar_softc **raidp);
69 static int ata_raid_hptv2_read_meta(device_t dev, struct ar_softc **raidp);
70 static int ata_raid_hptv2_write_meta(struct ar_softc *rdp);
71 static int ata_raid_hptv3_read_meta(device_t dev, struct ar_softc **raidp);
72 static int ata_raid_intel_read_meta(device_t dev, struct ar_softc **raidp);
73 static int ata_raid_intel_write_meta(struct ar_softc *rdp);
74 static int ata_raid_ite_read_meta(device_t dev, struct ar_softc **raidp);
75 static int ata_raid_jmicron_read_meta(device_t dev, struct ar_softc **raidp);
76 static int ata_raid_jmicron_write_meta(struct ar_softc *rdp);
77 static int ata_raid_lsiv2_read_meta(device_t dev, struct ar_softc **raidp);
78 static int ata_raid_lsiv3_read_meta(device_t dev, struct ar_softc **raidp);
79 static int ata_raid_nvidia_read_meta(device_t dev, struct ar_softc **raidp);
80 static int ata_raid_promise_read_meta(device_t dev, struct ar_softc **raidp, int native);
81 static int ata_raid_promise_write_meta(struct ar_softc *rdp);
82 static int ata_raid_sii_read_meta(device_t dev, struct ar_softc **raidp);
83 static int ata_raid_sis_read_meta(device_t dev, struct ar_softc **raidp);
84 static int ata_raid_sis_write_meta(struct ar_softc *rdp);
85 static int ata_raid_via_read_meta(device_t dev, struct ar_softc **raidp);
86 static int ata_raid_via_write_meta(struct ar_softc *rdp);
87 static struct ata_request *ata_raid_init_request(struct ar_softc *rdp, struct bio *bio);
88 static int ata_raid_send_request(struct ata_request *request);
89 static int ata_raid_rw(device_t dev, u_int64_t lba, void *data, u_int bcount, int flags);
90 static char * ata_raid_format(struct ar_softc *rdp);
91 static char * ata_raid_type(struct ar_softc *rdp);
92 static char * ata_raid_flags(struct ar_softc *rdp);
93
94 /* debugging only */
95 static void ata_raid_print_meta(struct ar_softc *meta);
96 static void ata_raid_adaptec_print_meta(struct adaptec_raid_conf *meta);
97 static void ata_raid_hptv2_print_meta(struct hptv2_raid_conf *meta);
98 static void ata_raid_hptv3_print_meta(struct hptv3_raid_conf *meta);
99 static void ata_raid_intel_print_meta(struct intel_raid_conf *meta);
100 static void ata_raid_ite_print_meta(struct ite_raid_conf *meta);
101 static void ata_raid_jmicron_print_meta(struct jmicron_raid_conf *meta);
102 static void ata_raid_lsiv2_print_meta(struct lsiv2_raid_conf *meta);
103 static void ata_raid_lsiv3_print_meta(struct lsiv3_raid_conf *meta);
104 static void ata_raid_nvidia_print_meta(struct nvidia_raid_conf *meta);
105 static void ata_raid_promise_print_meta(struct promise_raid_conf *meta);
106 static void ata_raid_sii_print_meta(struct sii_raid_conf *meta);
107 static void ata_raid_sis_print_meta(struct sis_raid_conf *meta);
108 static void ata_raid_via_print_meta(struct via_raid_conf *meta);
109
110 /* internal vars */   
111 static struct ar_softc *ata_raid_arrays[MAX_ARRAYS];
112 static MALLOC_DEFINE(M_AR, "ar_driver", "ATA PseudoRAID driver");
113 static devclass_t ata_raid_sub_devclass;
114 static int testing = 0;
115
116 /* device structures */
117 static disk_strategy_t ata_raid_strategy;
118 static dumper_t ata_raid_dump;
119
120 static void
121 ata_raid_attach(struct ar_softc *rdp, int writeback)
122 {
123     char buffer[32];
124     int disk;
125
126     mtx_init(&rdp->lock, "ATA PseudoRAID metadata lock", NULL, MTX_DEF);
127     ata_raid_config_changed(rdp, writeback);
128
129     /* sanitize arrays total_size % (width * interleave) == 0 */
130     if (rdp->type == AR_T_RAID0 || rdp->type == AR_T_RAID01 ||
131         rdp->type == AR_T_RAID5) {
132         rdp->total_sectors = (rdp->total_sectors/(rdp->interleave*rdp->width))*
133                              (rdp->interleave * rdp->width);
134         sprintf(buffer, " (stripe %d KB)",
135                 (rdp->interleave * DEV_BSIZE) / 1024);
136     }
137     else
138         buffer[0] = '\0';
139     rdp->disk = disk_alloc();
140     rdp->disk->d_strategy = ata_raid_strategy;
141     rdp->disk->d_dump = ata_raid_dump;
142     rdp->disk->d_name = "ar";
143     rdp->disk->d_sectorsize = DEV_BSIZE;
144     rdp->disk->d_mediasize = (off_t)rdp->total_sectors * DEV_BSIZE;
145     rdp->disk->d_fwsectors = rdp->sectors;
146     rdp->disk->d_fwheads = rdp->heads;
147     rdp->disk->d_maxsize = 128 * DEV_BSIZE;
148     rdp->disk->d_drv1 = rdp;
149     rdp->disk->d_unit = rdp->lun;
150     disk_create(rdp->disk, DISK_VERSION);
151
152     printf("ar%d: %juMB <%s %s%s> status: %s\n", rdp->lun,
153            rdp->total_sectors / ((1024L * 1024L) / DEV_BSIZE),
154            ata_raid_format(rdp), ata_raid_type(rdp),
155            buffer, ata_raid_flags(rdp));
156
157     if (testing || bootverbose)
158         printf("ar%d: %ju sectors [%dC/%dH/%dS] <%s> subdisks defined as:\n",
159                rdp->lun, rdp->total_sectors,
160                rdp->cylinders, rdp->heads, rdp->sectors, rdp->name);
161
162     for (disk = 0; disk < rdp->total_disks; disk++) {
163         printf("ar%d: disk%d ", rdp->lun, disk);
164         if (rdp->disks[disk].dev) {
165             if (rdp->disks[disk].flags & AR_DF_PRESENT) {
166                 /* status of this disk in the array */
167                 if (rdp->disks[disk].flags & AR_DF_ONLINE)
168                     printf("READY ");
169                 else if (rdp->disks[disk].flags & AR_DF_SPARE)
170                     printf("SPARE ");
171                 else
172                     printf("FREE  ");
173
174                 /* what type of disk is this in the array */
175                 switch (rdp->type) {
176                 case AR_T_RAID1:
177                 case AR_T_RAID01:
178                     if (disk < rdp->width)
179                         printf("(master) ");
180                     else
181                         printf("(mirror) ");
182                 }
183                 
184                 /* which physical disk is used */
185                 printf("using %s at ata%d-%s\n",
186                        device_get_nameunit(rdp->disks[disk].dev),
187                        device_get_unit(device_get_parent(rdp->disks[disk].dev)),
188                        (((struct ata_device *)
189                          device_get_softc(rdp->disks[disk].dev))->unit == 
190                          ATA_MASTER) ? "master" : "slave");
191             }
192             else if (rdp->disks[disk].flags & AR_DF_ASSIGNED)
193                 printf("DOWN\n");
194             else
195                 printf("INVALID no RAID config on this subdisk\n");
196         }
197         else
198             printf("DOWN no device found for this subdisk\n");
199     }
200 }
201
202 static int
203 ata_raid_ioctl(u_long cmd, caddr_t data)
204 {
205     struct ata_ioc_raid_status *status = (struct ata_ioc_raid_status *)data;
206     struct ata_ioc_raid_config *config = (struct ata_ioc_raid_config *)data;
207     int *lun = (int *)data;
208     int error = EOPNOTSUPP;
209
210     switch (cmd) {
211     case IOCATARAIDSTATUS_OLD:
212         error = ata_raid_status_old(config);
213         break;
214
215     case IOCATARAIDSTATUS:
216         error = ata_raid_status(status);
217         break;
218                         
219     case IOCATARAIDCREATE:
220         error = ata_raid_create(config);
221         break;
222          
223     case IOCATARAIDDELETE:
224         error = ata_raid_delete(*lun);
225         break;
226      
227     case IOCATARAIDADDSPARE:
228         error = ata_raid_addspare(config);
229         break;
230                             
231     case IOCATARAIDREBUILD:
232         error = ata_raid_rebuild(*lun);
233         break;
234     }
235     return error;
236 }
237
238 static void
239 ata_raid_strategy(struct bio *bp)
240 {
241     struct ar_softc *rdp = bp->bio_disk->d_drv1;
242     struct ata_request *request;
243     caddr_t data;
244     u_int64_t blkno, lba, blk = 0;
245     int count, chunk, drv, par = 0, change = 0;
246
247     if (!(rdp->status & AR_S_READY) ||
248         (bp->bio_cmd != BIO_READ && bp->bio_cmd != BIO_WRITE)) {
249         biofinish(bp, NULL, EIO);
250         return;
251     }
252
253     bp->bio_resid = bp->bio_bcount;
254     for (count = howmany(bp->bio_bcount, DEV_BSIZE),
255          blkno = bp->bio_pblkno, data = bp->bio_data;
256          count > 0; 
257          count -= chunk, blkno += chunk, data += (chunk * DEV_BSIZE)) {
258
259         switch (rdp->type) {
260         case AR_T_RAID1:
261             drv = 0;
262             lba = blkno;
263             chunk = count;
264             break;
265         
266         case AR_T_JBOD:
267         case AR_T_SPAN:
268             drv = 0;
269             lba = blkno;
270             while (lba >= rdp->disks[drv].sectors)
271                 lba -= rdp->disks[drv++].sectors;
272             chunk = min(rdp->disks[drv].sectors - lba, count);
273             break;
274         
275         case AR_T_RAID0:
276         case AR_T_RAID01:
277             chunk = blkno % rdp->interleave;
278             drv = (blkno / rdp->interleave) % rdp->width;
279             lba = (((blkno/rdp->interleave)/rdp->width)*rdp->interleave)+chunk;
280             chunk = min(count, rdp->interleave - chunk);
281             break;
282
283         case AR_T_RAID5:
284             drv = (blkno / rdp->interleave) % (rdp->width - 1);
285             par = rdp->width - 1 - 
286                   (blkno / (rdp->interleave * (rdp->width - 1))) % rdp->width;
287             if (drv >= par)
288                 drv++;
289             lba = ((blkno/rdp->interleave)/(rdp->width-1))*(rdp->interleave) +
290                   ((blkno%(rdp->interleave*(rdp->width-1)))%rdp->interleave);
291             chunk = min(count, rdp->interleave - (lba % rdp->interleave));
292             break;
293
294         default:
295             printf("ar%d: unknown array type in ata_raid_strategy\n", rdp->lun);
296             biofinish(bp, NULL, EIO);
297             return;
298         }
299          
300         /* offset on all but "first on HPTv2" */
301         if (!(drv == 0 && rdp->format == AR_F_HPTV2_RAID))
302             lba += rdp->offset_sectors;
303
304         if (!(request = ata_raid_init_request(rdp, bp))) {
305             biofinish(bp, NULL, EIO);
306             return;
307         }
308         request->data = data;
309         request->bytecount = chunk * DEV_BSIZE;
310         request->u.ata.lba = lba;
311         request->u.ata.count = request->bytecount / DEV_BSIZE;
312             
313         switch (rdp->type) {
314         case AR_T_JBOD:
315         case AR_T_SPAN:
316         case AR_T_RAID0:
317             if (((rdp->disks[drv].flags & (AR_DF_PRESENT|AR_DF_ONLINE)) ==
318                  (AR_DF_PRESENT|AR_DF_ONLINE) && !rdp->disks[drv].dev)) {
319                 rdp->disks[drv].flags &= ~AR_DF_ONLINE;
320                 ata_raid_config_changed(rdp, 1);
321                 ata_free_request(request);
322                 biofinish(bp, NULL, EIO);
323                 return;
324             }
325             request->this = drv;
326             request->dev = rdp->disks[request->this].dev;
327             ata_raid_send_request(request);
328             break;
329
330         case AR_T_RAID1:
331         case AR_T_RAID01:
332             if ((rdp->disks[drv].flags &
333                  (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) &&
334                 !rdp->disks[drv].dev) {
335                 rdp->disks[drv].flags &= ~AR_DF_ONLINE;
336                 change = 1;
337             }
338             if ((rdp->disks[drv + rdp->width].flags &
339                  (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) &&
340                 !rdp->disks[drv + rdp->width].dev) {
341                 rdp->disks[drv + rdp->width].flags &= ~AR_DF_ONLINE;
342                 change = 1;
343             }
344             if (change)
345                 ata_raid_config_changed(rdp, 1);
346             if (!(rdp->status & AR_S_READY)) {
347                 ata_free_request(request);
348                 biofinish(bp, NULL, EIO);
349                 return;
350             }
351
352             if (rdp->status & AR_S_REBUILDING)
353                 blk = ((lba / rdp->interleave) * rdp->width) * rdp->interleave +
354                       (rdp->interleave * (drv % rdp->width)) +
355                       lba % rdp->interleave;;
356
357             if (bp->bio_cmd == BIO_READ) {
358                 int src_online =
359                     (rdp->disks[drv].flags & AR_DF_ONLINE);
360                 int mir_online =
361                     (rdp->disks[drv+rdp->width].flags & AR_DF_ONLINE);
362
363                 /* if mirror gone or close to last access on source */
364                 if (!mir_online || 
365                     ((src_online) &&
366                      bp->bio_pblkno >=
367                         (rdp->disks[drv].last_lba - AR_PROXIMITY) &&
368                      bp->bio_pblkno <=
369                         (rdp->disks[drv].last_lba + AR_PROXIMITY))) {
370                     rdp->toggle = 0;
371                 } 
372                 /* if source gone or close to last access on mirror */
373                 else if (!src_online ||
374                          ((mir_online) &&
375                           bp->bio_pblkno >=
376                           (rdp->disks[drv+rdp->width].last_lba-AR_PROXIMITY) &&
377                           bp->bio_pblkno <=
378                           (rdp->disks[drv+rdp->width].last_lba+AR_PROXIMITY))) {
379                     drv += rdp->width;
380                     rdp->toggle = 1;
381                 }
382                 /* not close to any previous access, toggle */
383                 else {
384                     if (rdp->toggle)
385                         rdp->toggle = 0;
386                     else {
387                         drv += rdp->width;
388                         rdp->toggle = 1;
389                     }
390                 }
391
392                 if ((rdp->status & AR_S_REBUILDING) &&
393                     (blk <= rdp->rebuild_lba) &&
394                     ((blk + chunk) > rdp->rebuild_lba)) {
395                     struct ata_composite *composite;
396                     struct ata_request *rebuild;
397                     int this;
398
399                     /* figure out what part to rebuild */
400                     if (drv < rdp->width)
401                         this = drv + rdp->width;
402                     else
403                         this = drv - rdp->width;
404
405                     /* do we have a spare to rebuild on ? */
406                     if (rdp->disks[this].flags & AR_DF_SPARE) {
407                         if ((composite = ata_alloc_composite())) {
408                             if ((rebuild = ata_alloc_request())) {
409                                 rdp->rebuild_lba = blk + chunk;
410                                 bcopy(request, rebuild,
411                                       sizeof(struct ata_request));
412                                 rebuild->this = this;
413                                 rebuild->dev = rdp->disks[this].dev;
414                                 rebuild->flags &= ~ATA_R_READ;
415                                 rebuild->flags |= ATA_R_WRITE;
416                                 mtx_init(&composite->lock,
417                                          "ATA PseudoRAID rebuild lock",
418                                          NULL, MTX_DEF);
419                                 composite->residual = request->bytecount;
420                                 composite->rd_needed |= (1 << drv);
421                                 composite->wr_depend |= (1 << drv);
422                                 composite->wr_needed |= (1 << this);
423                                 composite->request[drv] = request;
424                                 composite->request[this] = rebuild;
425                                 request->composite = composite;
426                                 rebuild->composite = composite;
427                                 ata_raid_send_request(rebuild);
428                             }
429                             else {
430                                 ata_free_composite(composite);
431                                 printf("DOH! ata_alloc_request failed!\n");
432                             }
433                         }
434                         else {
435                             printf("DOH! ata_alloc_composite failed!\n");
436                         }
437                     }
438                     else if (rdp->disks[this].flags & AR_DF_ONLINE) {
439                         /*
440                          * if we got here we are a chunk of a RAID01 that 
441                          * does not need a rebuild, but we need to increment
442                          * the rebuild_lba address to get the rebuild to
443                          * move to the next chunk correctly
444                          */
445                         rdp->rebuild_lba = blk + chunk;
446                     }
447                     else
448                         printf("DOH! we didn't find the rebuild part\n");
449                 }
450             }
451             if (bp->bio_cmd == BIO_WRITE) {
452                 if ((rdp->disks[drv+rdp->width].flags & AR_DF_ONLINE) ||
453                     ((rdp->status & AR_S_REBUILDING) &&
454                      (rdp->disks[drv+rdp->width].flags & AR_DF_SPARE) &&
455                      ((blk < rdp->rebuild_lba) ||
456                       ((blk <= rdp->rebuild_lba) &&
457                        ((blk + chunk) > rdp->rebuild_lba))))) {
458                     if ((rdp->disks[drv].flags & AR_DF_ONLINE) ||
459                         ((rdp->status & AR_S_REBUILDING) &&
460                          (rdp->disks[drv].flags & AR_DF_SPARE) &&
461                          ((blk < rdp->rebuild_lba) ||
462                           ((blk <= rdp->rebuild_lba) &&
463                            ((blk + chunk) > rdp->rebuild_lba))))) {
464                         struct ata_request *mirror;
465                         struct ata_composite *composite;
466                         int this = drv + rdp->width;
467
468                         if ((composite = ata_alloc_composite())) {
469                             if ((mirror = ata_alloc_request())) {
470                                 if ((blk <= rdp->rebuild_lba) &&
471                                     ((blk + chunk) > rdp->rebuild_lba))
472                                     rdp->rebuild_lba = blk + chunk;
473                                 bcopy(request, mirror,
474                                       sizeof(struct ata_request));
475                                 mirror->this = this;
476                                 mirror->dev = rdp->disks[this].dev;
477                                 mtx_init(&composite->lock,
478                                          "ATA PseudoRAID mirror lock",
479                                          NULL, MTX_DEF);
480                                 composite->residual = request->bytecount;
481                                 composite->wr_needed |= (1 << drv);
482                                 composite->wr_needed |= (1 << this);
483                                 composite->request[drv] = request;
484                                 composite->request[this] = mirror;
485                                 request->composite = composite;
486                                 mirror->composite = composite;
487                                 ata_raid_send_request(mirror);
488                                 rdp->disks[this].last_lba =
489                                     bp->bio_pblkno + chunk;
490                             }
491                             else {
492                                 ata_free_composite(composite);
493                                 printf("DOH! ata_alloc_request failed!\n");
494                             }
495                         }
496                         else {
497                             printf("DOH! ata_alloc_composite failed!\n");
498                         }
499                     }
500                     else
501                         drv += rdp->width;
502                 }
503             }
504             request->this = drv;
505             request->dev = rdp->disks[request->this].dev;
506             ata_raid_send_request(request);
507             rdp->disks[request->this].last_lba = bp->bio_pblkno + chunk;
508             break;
509
510         case AR_T_RAID5:
511             if (((rdp->disks[drv].flags & (AR_DF_PRESENT|AR_DF_ONLINE)) ==
512                  (AR_DF_PRESENT|AR_DF_ONLINE) && !rdp->disks[drv].dev)) {
513                 rdp->disks[drv].flags &= ~AR_DF_ONLINE;
514                 change = 1;
515             }
516             if (((rdp->disks[par].flags & (AR_DF_PRESENT|AR_DF_ONLINE)) ==
517                  (AR_DF_PRESENT|AR_DF_ONLINE) && !rdp->disks[par].dev)) {
518                 rdp->disks[par].flags &= ~AR_DF_ONLINE;
519                 change = 1;
520             }
521             if (change)
522                 ata_raid_config_changed(rdp, 1);
523             if (!(rdp->status & AR_S_READY)) {
524                 ata_free_request(request);
525                 biofinish(bp, NULL, EIO);
526                 return;
527             }
528             if (rdp->status & AR_S_DEGRADED) {
529                 /* do the XOR game if possible */
530             }
531             else {
532                 request->this = drv;
533                 request->dev = rdp->disks[request->this].dev;
534                 if (bp->bio_cmd == BIO_READ) {
535                     ata_raid_send_request(request);
536                 }
537                 if (bp->bio_cmd == BIO_WRITE) { 
538                     ata_raid_send_request(request);
539                     // sikre at læs-modify-skriv til hver disk er atomarisk.
540                     // par kopi af request
541                     // læse orgdata fra drv
542                     // skriv nydata til drv
543                     // læse parorgdata fra par
544                     // skriv orgdata xor parorgdata xor nydata til par
545                 }
546             }
547             break;
548
549         default:
550             printf("ar%d: unknown array type in ata_raid_strategy\n", rdp->lun);
551         }
552     }
553 }
554
555 static void
556 ata_raid_done(struct ata_request *request)
557 {
558     struct ar_softc *rdp = request->driver;
559     struct ata_composite *composite = NULL;
560     struct bio *bp = request->bio;
561     int i, mirror, finished = 0;
562
563     switch (rdp->type) {
564     case AR_T_JBOD:
565     case AR_T_SPAN:
566     case AR_T_RAID0:
567         if (request->result) {
568             rdp->disks[request->this].flags &= ~AR_DF_ONLINE;
569             ata_raid_config_changed(rdp, 1);
570             bp->bio_error = request->result;
571             finished = 1;
572         }
573         else {
574             bp->bio_resid -= request->donecount;
575             if (!bp->bio_resid)
576                 finished = 1;
577         }
578         break;
579
580     case AR_T_RAID1:
581     case AR_T_RAID01:
582         if (request->this < rdp->width)
583             mirror = request->this + rdp->width;
584         else
585             mirror = request->this - rdp->width;
586         if (request->result) {
587             rdp->disks[request->this].flags &= ~AR_DF_ONLINE;
588             ata_raid_config_changed(rdp, 1);
589         }
590         if (rdp->status & AR_S_READY) {
591             u_int64_t blk = 0;
592
593             if (rdp->status & AR_S_REBUILDING) 
594                 blk = ((request->u.ata.lba / rdp->interleave) * rdp->width) *
595                       rdp->interleave + (rdp->interleave * 
596                       (request->this % rdp->width)) +
597                       request->u.ata.lba % rdp->interleave;
598
599             if (bp->bio_cmd == BIO_READ) {
600
601                 /* is this a rebuild composite */
602                 if ((composite = request->composite)) {
603                     mtx_lock(&composite->lock);
604                 
605                     /* handle the read part of a rebuild composite */
606                     if (request->flags & ATA_R_READ) {
607
608                         /* if read failed array is now broken */
609                         if (request->result) {
610                             rdp->disks[request->this].flags &= ~AR_DF_ONLINE;
611                             ata_raid_config_changed(rdp, 1);
612                             bp->bio_error = request->result;
613                             rdp->rebuild_lba = blk;
614                             finished = 1;
615                         }
616
617                         /* good data, update how far we've gotten */
618                         else {
619                             bp->bio_resid -= request->donecount;
620                             composite->residual -= request->donecount;
621                             if (!composite->residual) {
622                                 if (composite->wr_done & (1 << mirror))
623                                     finished = 1;
624                             }
625                         }
626                     }
627
628                     /* handle the write part of a rebuild composite */
629                     else if (request->flags & ATA_R_WRITE) {
630                         if (composite->rd_done & (1 << mirror)) {
631                             if (request->result) {
632                                 printf("DOH! rebuild failed\n"); /* XXX SOS */
633                                 rdp->rebuild_lba = blk;
634                             }
635                             if (!composite->residual)
636                                 finished = 1;
637                         }
638                     }
639                     mtx_unlock(&composite->lock);
640                 }
641
642                 /* if read failed retry on the mirror */
643                 else if (request->result) {
644                     request->dev = rdp->disks[mirror].dev;
645                     request->flags &= ~ATA_R_TIMEOUT;
646                     ata_raid_send_request(request);
647                     return;
648                 }
649
650                 /* we have good data */
651                 else {
652                     bp->bio_resid -= request->donecount;
653                     if (!bp->bio_resid)
654                         finished = 1;
655                 }
656             }
657             else if (bp->bio_cmd == BIO_WRITE) {
658                 /* do we have a mirror or rebuild to deal with ? */
659                 if ((composite = request->composite)) {
660                     mtx_lock(&composite->lock);
661                     if (composite->wr_done & (1 << mirror)) {
662                         if (request->result) {
663                             if (composite->request[mirror]->result) {
664                                 printf("DOH! all disks failed and got here\n");
665                                 bp->bio_error = EIO;
666                             }
667                             if (rdp->status & AR_S_REBUILDING) {
668                                 rdp->rebuild_lba = blk;
669                                 printf("DOH! rebuild failed\n"); /* XXX SOS */
670                             }
671                             bp->bio_resid -=
672                                 composite->request[mirror]->donecount;
673                             composite->residual -=
674                                 composite->request[mirror]->donecount;
675                         }
676                         else {
677                             bp->bio_resid -= request->donecount;
678                             composite->residual -= request->donecount;
679                         }
680                         if (!composite->residual)
681                             finished = 1;
682                     }
683                     mtx_unlock(&composite->lock);
684                 }
685                 /* no mirror we are done */
686                 else {
687                     bp->bio_resid -= request->donecount;
688                     if (!bp->bio_resid)
689                         finished = 1;
690                 }
691             }
692         }
693         else 
694             biofinish(bp, NULL, request->result);
695         break;
696
697     case AR_T_RAID5:
698         if (request->result) {
699             rdp->disks[request->this].flags &= ~AR_DF_ONLINE;
700             ata_raid_config_changed(rdp, 1);
701             if (rdp->status & AR_S_READY) {
702                 if (bp->bio_cmd == BIO_READ) {
703                     /* do the XOR game to recover data */
704                 }
705                 if (bp->bio_cmd == BIO_WRITE) {
706                     /* if the parity failed we're OK sortof */
707                     /* otherwise wee need to do the XOR long dance */
708                 }
709                 finished = 1;
710             }
711             else
712                 biofinish(bp, NULL, request->result);
713         }
714         else {
715             // did we have an XOR game going ??
716             bp->bio_resid -= request->donecount;
717             if (!bp->bio_resid)
718                 finished = 1;
719         }
720         break;
721
722     default:
723         printf("ar%d: unknown array type in ata_raid_done\n", rdp->lun);
724     }
725
726     if (finished) {
727         if ((rdp->status & AR_S_REBUILDING) && 
728             rdp->rebuild_lba >= rdp->total_sectors) {
729             int disk;
730
731             for (disk = 0; disk < rdp->total_disks; disk++) {
732                 if ((rdp->disks[disk].flags &
733                      (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_SPARE)) ==
734                     (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_SPARE)) {
735                     rdp->disks[disk].flags &= ~AR_DF_SPARE;
736                     rdp->disks[disk].flags |= AR_DF_ONLINE;
737                 }
738             }
739             rdp->status &= ~AR_S_REBUILDING;
740             ata_raid_config_changed(rdp, 1);
741         }
742         if (!bp->bio_resid)
743             biodone(bp);
744     }
745                  
746     if (composite) {
747         if (finished) {
748             /* we are done with this composite, free all resources */
749             for (i = 0; i < 32; i++) {
750                 if (composite->rd_needed & (1 << i) ||
751                     composite->wr_needed & (1 << i)) {
752                     ata_free_request(composite->request[i]);
753                 }
754             }
755             mtx_destroy(&composite->lock);
756             ata_free_composite(composite);
757         }
758     }
759     else
760         ata_free_request(request);
761 }
762
763 static int
764 ata_raid_dump(void *arg, void *virtual, vm_offset_t physical,
765               off_t offset, size_t length)
766 {
767     struct disk *dp = arg;
768     struct ar_softc *rdp = dp->d_drv1;
769     struct bio bp;
770
771     /* length zero is special and really means flush buffers to media */
772     if (!length) {
773         int disk, error;
774
775         for (disk = 0, error = 0; disk < rdp->total_disks; disk++) 
776             if (rdp->disks[disk].dev)
777                 error |= ata_controlcmd(rdp->disks[disk].dev,
778                                         ATA_FLUSHCACHE, 0, 0, 0);
779         return (error ? EIO : 0);
780     }
781
782     bzero(&bp, sizeof(struct bio));
783     bp.bio_disk = dp;
784     bp.bio_pblkno = offset / DEV_BSIZE;
785     bp.bio_bcount = length;
786     bp.bio_data = virtual;
787     bp.bio_cmd = BIO_WRITE;
788     ata_raid_strategy(&bp);
789     return bp.bio_error;
790 }
791
792 static void
793 ata_raid_config_changed(struct ar_softc *rdp, int writeback)
794 {
795     int disk, count, status;
796
797     mtx_lock(&rdp->lock);
798     /* set default all working mode */
799     status = rdp->status;
800     rdp->status &= ~AR_S_DEGRADED;
801     rdp->status |= AR_S_READY;
802
803     /* make sure all lost drives are accounted for */
804     for (disk = 0; disk < rdp->total_disks; disk++) {
805         if (!(rdp->disks[disk].flags & AR_DF_PRESENT))
806             rdp->disks[disk].flags &= ~AR_DF_ONLINE;
807     }
808
809     /* depending on RAID type figure out our health status */
810     switch (rdp->type) {
811     case AR_T_JBOD:
812     case AR_T_SPAN:
813     case AR_T_RAID0:
814         for (disk = 0; disk < rdp->total_disks; disk++) 
815             if (!(rdp->disks[disk].flags & AR_DF_ONLINE))
816                 rdp->status &= ~AR_S_READY; 
817         break;
818
819     case AR_T_RAID1:
820     case AR_T_RAID01:
821         for (disk = 0; disk < rdp->width; disk++) {
822             if (!(rdp->disks[disk].flags & AR_DF_ONLINE) &&
823                 !(rdp->disks[disk + rdp->width].flags & AR_DF_ONLINE)) {
824                 rdp->status &= ~AR_S_READY;
825             }
826             else if (((rdp->disks[disk].flags & AR_DF_ONLINE) &&
827                       !(rdp->disks[disk + rdp->width].flags & AR_DF_ONLINE)) ||
828                      (!(rdp->disks[disk].flags & AR_DF_ONLINE) &&
829                       (rdp->disks [disk + rdp->width].flags & AR_DF_ONLINE))) {
830                 rdp->status |= AR_S_DEGRADED;
831             }
832         }
833         break;
834
835     case AR_T_RAID5:
836         for (count = 0, disk = 0; disk < rdp->total_disks; disk++) {
837             if (!(rdp->disks[disk].flags & AR_DF_ONLINE))
838                 count++;
839         }
840         if (count) {
841             if (count > 1)
842                 rdp->status &= ~AR_S_READY;
843             else
844                 rdp->status |= AR_S_DEGRADED;
845         }
846         break;
847     default:
848         rdp->status &= ~AR_S_READY;
849     }
850
851     if (rdp->status != status) {
852         if (!(rdp->status & AR_S_READY)) {
853             printf("ar%d: FAILURE - %s array broken\n",
854                    rdp->lun, ata_raid_type(rdp));
855         }
856         else if (rdp->status & AR_S_DEGRADED) {
857             if (rdp->type & (AR_T_RAID1 | AR_T_RAID01))
858                 printf("ar%d: WARNING - mirror", rdp->lun);
859             else
860                 printf("ar%d: WARNING - parity", rdp->lun);
861             printf(" protection lost. %s array in DEGRADED mode\n",
862                    ata_raid_type(rdp));
863         }
864     }
865     mtx_unlock(&rdp->lock);
866     if (writeback)
867         ata_raid_write_metadata(rdp);
868
869 }
870
871 static int
872 ata_raid_status_old(struct ata_ioc_raid_config *config)
873 {
874     struct ata_ioc_raid_status status;
875     int error, i;
876
877     status.lun = config->lun;
878     error = ata_raid_status(&status);
879     if (error)
880         return error;
881
882     config->type = status.type;
883     config->total_disks = status.total_disks;
884     config->interleave = status.interleave;
885     config->status = status.status;
886     config->progress = status.progress;
887
888     for (i = 0; i < config->total_disks; i++)
889         config->disks[i] = status.disks[i].lun;
890     return (0);
891 }
892
893 static int
894 ata_raid_status(struct ata_ioc_raid_status *status)
895 {
896     struct ar_softc *rdp;
897     int i;
898         
899     if (!(rdp = ata_raid_arrays[status->lun]))
900         return ENXIO;
901         
902     status->type = rdp->type;
903     status->total_disks = rdp->total_disks;
904     for (i = 0; i < rdp->total_disks; i++ ) {
905         status->disks[i].state = 0;
906         if ((rdp->disks[i].flags & AR_DF_PRESENT) && rdp->disks[i].dev) {
907             status->disks[i].lun = device_get_unit(rdp->disks[i].dev);
908             if (rdp->disks[i].flags & AR_DF_PRESENT)
909                 status->disks[i].state |= AR_DISK_PRESENT;
910             if (rdp->disks[i].flags & AR_DF_ONLINE)
911                 status->disks[i].state |= AR_DISK_ONLINE;
912             if (rdp->disks[i].flags & AR_DF_SPARE)
913                 status->disks[i].state |= AR_DISK_SPARE;
914         } else
915             status->disks[i].lun = -1;
916     }
917     status->interleave = rdp->interleave;
918     status->status = rdp->status;
919     status->progress = 100 * rdp->rebuild_lba / rdp->total_sectors;
920     return 0;
921 }
922
923 static int
924 ata_raid_create(struct ata_ioc_raid_config *config)
925 {
926     struct ar_softc *rdp;
927     device_t subdisk;
928     int array, disk;
929     int ctlr = 0, disk_size = 0, total_disks = 0;
930
931     for (array = 0; array < MAX_ARRAYS; array++) {
932         if (!ata_raid_arrays[array])
933             break;
934     }
935     if (array >= MAX_ARRAYS)
936         return ENOSPC;
937
938     if (!(rdp = (struct ar_softc*)malloc(sizeof(struct ar_softc), M_AR,
939                                          M_NOWAIT | M_ZERO))) {
940         printf("ar%d: no memory for metadata storage\n", array);
941         return ENOMEM;
942     }
943
944     for (disk = 0; disk < config->total_disks; disk++) {
945         if ((subdisk = devclass_get_device(ata_raid_sub_devclass,
946                                            config->disks[disk]))) {
947             struct ata_raid_subdisk *ars = device_get_softc(subdisk);
948
949             /* is device already assigned to another array ? */
950             if (ars->raid[rdp->volume]) {
951                 config->disks[disk] = -1;
952                 free(rdp, M_AR);
953                 return EBUSY;
954             }
955             rdp->disks[disk].dev = device_get_parent(subdisk);
956
957             switch (pci_get_vendor(GRANDPARENT(rdp->disks[disk].dev))) {
958             case ATA_HIGHPOINT_ID:
959                 /* 
960                  * we need some way to decide if it should be v2 or v3
961                  * for now just use v2 since the v3 BIOS knows how to 
962                  * handle that as well.
963                  */
964                 ctlr = AR_F_HPTV2_RAID;
965                 rdp->disks[disk].sectors = HPTV3_LBA(rdp->disks[disk].dev);
966                 break;
967
968             case ATA_INTEL_ID:
969                 ctlr = AR_F_INTEL_RAID;
970                 rdp->disks[disk].sectors = INTEL_LBA(rdp->disks[disk].dev);
971                 break;
972
973             case ATA_ITE_ID:
974                 ctlr = AR_F_ITE_RAID;
975                 rdp->disks[disk].sectors = ITE_LBA(rdp->disks[disk].dev);
976                 break;
977
978             case ATA_JMICRON_ID:
979                 ctlr = AR_F_JMICRON_RAID;
980                 rdp->disks[disk].sectors = JMICRON_LBA(rdp->disks[disk].dev);
981                 break;
982
983             case 0:     /* XXX SOS cover up for bug in our PCI code */
984             case ATA_PROMISE_ID:        
985                 ctlr = AR_F_PROMISE_RAID;
986                 rdp->disks[disk].sectors = PROMISE_LBA(rdp->disks[disk].dev);
987                 break;
988
989             case ATA_SIS_ID:        
990                 ctlr = AR_F_SIS_RAID;
991                 rdp->disks[disk].sectors = SIS_LBA(rdp->disks[disk].dev);
992                 break;
993
994             case ATA_ATI_ID:        
995             case ATA_VIA_ID:        
996                 ctlr = AR_F_VIA_RAID;
997                 rdp->disks[disk].sectors = VIA_LBA(rdp->disks[disk].dev);
998                 break;
999
1000             default:
1001                 /* XXX SOS
1002                  * right, so here we are, we have an ATA chip and we want
1003                  * to create a RAID and store the metadata.
1004                  * we need to find a way to tell what kind of metadata this
1005                  * hardware's BIOS might be using (good ideas are welcomed)
1006                  * for now we just use our own native FreeBSD format.
1007                  * the only way to get support for the BIOS format is to
1008                  * setup the RAID from there, in that case we pickup the
1009                  * metadata format from the disks (if we support it).
1010                  */
1011                 printf("WARNING!! - not able to determine metadata format\n"
1012                        "WARNING!! - Using FreeBSD PseudoRAID metadata\n"
1013                        "If that is not what you want, use the BIOS to "
1014                        "create the array\n");
1015                 ctlr = AR_F_FREEBSD_RAID;
1016                 rdp->disks[disk].sectors = PROMISE_LBA(rdp->disks[disk].dev);
1017                 break;
1018             }
1019
1020             /* we need all disks to be of the same format */
1021             if ((rdp->format & AR_F_FORMAT_MASK) &&
1022                 (rdp->format & AR_F_FORMAT_MASK) != (ctlr & AR_F_FORMAT_MASK)) {
1023                 free(rdp, M_AR);
1024                 return EXDEV;
1025             }
1026             else
1027                 rdp->format = ctlr;
1028             
1029             /* use the smallest disk of the lots size */
1030             /* gigabyte boundry ??? XXX SOS */
1031             if (disk_size)
1032                 disk_size = min(rdp->disks[disk].sectors, disk_size);
1033             else
1034                 disk_size = rdp->disks[disk].sectors;
1035             rdp->disks[disk].flags = 
1036                 (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE);
1037
1038             total_disks++;
1039         }
1040         else {
1041             config->disks[disk] = -1;
1042             free(rdp, M_AR);
1043             return ENXIO;
1044         }
1045     }
1046
1047     if (total_disks != config->total_disks) {
1048         free(rdp, M_AR);
1049         return ENODEV;
1050     }
1051
1052     switch (config->type) {
1053     case AR_T_JBOD:
1054     case AR_T_SPAN:
1055     case AR_T_RAID0:
1056         break;
1057
1058     case AR_T_RAID1:
1059         if (total_disks != 2) {
1060             free(rdp, M_AR);
1061             return EPERM;
1062         }
1063         break;
1064
1065     case AR_T_RAID01:
1066         if (total_disks % 2 != 0) {
1067             free(rdp, M_AR);
1068             return EPERM;
1069         }
1070         break;
1071
1072     case AR_T_RAID5:
1073         if (total_disks < 3) {
1074             free(rdp, M_AR);
1075             return EPERM;
1076         }
1077         break;
1078
1079     default:
1080         free(rdp, M_AR);
1081         return EOPNOTSUPP;
1082     }
1083     rdp->type = config->type;
1084     rdp->lun = array;
1085     if (rdp->type == AR_T_RAID0 || rdp->type == AR_T_RAID01 ||
1086         rdp->type == AR_T_RAID5) {
1087         int bit = 0;
1088
1089         while (config->interleave >>= 1)
1090             bit++;
1091         rdp->interleave = 1 << bit;
1092     }
1093     rdp->offset_sectors = 0;
1094
1095     /* values that depend on metadata format */
1096     switch (rdp->format) {
1097     case AR_F_ADAPTEC_RAID:
1098         rdp->interleave = min(max(32, rdp->interleave), 128); /*+*/
1099         break;
1100
1101     case AR_F_HPTV2_RAID:
1102         rdp->interleave = min(max(8, rdp->interleave), 128); /*+*/
1103         rdp->offset_sectors = HPTV2_LBA(x) + 1;
1104         break;
1105
1106     case AR_F_HPTV3_RAID:
1107         rdp->interleave = min(max(32, rdp->interleave), 4096); /*+*/
1108         break;
1109
1110     case AR_F_INTEL_RAID:
1111         rdp->interleave = min(max(8, rdp->interleave), 256); /*+*/
1112         break;
1113
1114     case AR_F_ITE_RAID:
1115         rdp->interleave = min(max(2, rdp->interleave), 128); /*+*/
1116         break;
1117
1118     case AR_F_JMICRON_RAID:
1119         rdp->interleave = min(max(8, rdp->interleave), 256); /*+*/
1120         break;
1121
1122     case AR_F_LSIV2_RAID:
1123         rdp->interleave = min(max(2, rdp->interleave), 4096);
1124         break;
1125
1126     case AR_F_LSIV3_RAID:
1127         rdp->interleave = min(max(2, rdp->interleave), 256);
1128         break;
1129
1130     case AR_F_PROMISE_RAID:
1131         rdp->interleave = min(max(2, rdp->interleave), 2048); /*+*/
1132         break;
1133
1134     case AR_F_SII_RAID:
1135         rdp->interleave = min(max(8, rdp->interleave), 256); /*+*/
1136         break;
1137
1138     case AR_F_SIS_RAID:
1139         rdp->interleave = min(max(32, rdp->interleave), 512); /*+*/
1140         break;
1141
1142     case AR_F_VIA_RAID:
1143         rdp->interleave = min(max(8, rdp->interleave), 128); /*+*/
1144         break;
1145     }
1146
1147     rdp->total_disks = total_disks;
1148     rdp->width = total_disks / (rdp->type & (AR_RAID1 | AR_T_RAID01) ? 2 : 1);
1149     rdp->total_sectors = disk_size * (rdp->width - (rdp->type == AR_RAID5));
1150     rdp->heads = 255;
1151     rdp->sectors = 63;
1152     rdp->cylinders = rdp->total_sectors / (255 * 63);
1153     rdp->rebuild_lba = 0;
1154     rdp->status |= AR_S_READY;
1155
1156     /* we are committed to this array, grap the subdisks */
1157     for (disk = 0; disk < config->total_disks; disk++) {
1158         if ((subdisk = devclass_get_device(ata_raid_sub_devclass,
1159                                            config->disks[disk]))) {
1160             struct ata_raid_subdisk *ars = device_get_softc(subdisk);
1161
1162             ars->raid[rdp->volume] = rdp;
1163             ars->disk_number[rdp->volume] = disk;
1164         }
1165     }
1166     ata_raid_attach(rdp, 1);
1167     ata_raid_arrays[array] = rdp;
1168     config->lun = array;
1169     return 0;
1170 }
1171
1172 static int
1173 ata_raid_delete(int array)
1174 {
1175     struct ar_softc *rdp;    
1176     device_t subdisk;
1177     int disk;
1178
1179     if (!(rdp = ata_raid_arrays[array]))
1180         return ENXIO;
1181  
1182     rdp->status &= ~AR_S_READY;
1183     if (rdp->disk)
1184         disk_destroy(rdp->disk);
1185
1186     for (disk = 0; disk < rdp->total_disks; disk++) {
1187         if ((rdp->disks[disk].flags & AR_DF_PRESENT) && rdp->disks[disk].dev) {
1188             if ((subdisk = devclass_get_device(ata_raid_sub_devclass,
1189                      device_get_unit(rdp->disks[disk].dev)))) {
1190                 struct ata_raid_subdisk *ars = device_get_softc(subdisk);
1191
1192                 if (ars->raid[rdp->volume] != rdp)           /* XXX SOS */
1193                     device_printf(subdisk, "DOH! this disk doesn't belong\n");
1194                 if (ars->disk_number[rdp->volume] != disk)   /* XXX SOS */
1195                     device_printf(subdisk, "DOH! this disk number is wrong\n");
1196                 ars->raid[rdp->volume] = NULL;
1197                 ars->disk_number[rdp->volume] = -1;
1198             }
1199             rdp->disks[disk].flags = 0;
1200         }
1201     }
1202     ata_raid_wipe_metadata(rdp);
1203     ata_raid_arrays[array] = NULL;
1204     free(rdp, M_AR);
1205     return 0;
1206 }
1207
1208 static int
1209 ata_raid_addspare(struct ata_ioc_raid_config *config)
1210 {
1211     struct ar_softc *rdp;    
1212     device_t subdisk;
1213     int disk;
1214
1215     if (!(rdp = ata_raid_arrays[config->lun]))
1216         return ENXIO;
1217     if (!(rdp->status & AR_S_DEGRADED) || !(rdp->status & AR_S_READY))
1218         return ENXIO;
1219     if (rdp->status & AR_S_REBUILDING)
1220         return EBUSY; 
1221     switch (rdp->type) {
1222     case AR_T_RAID1:
1223     case AR_T_RAID01:
1224     case AR_T_RAID5:
1225         for (disk = 0; disk < rdp->total_disks; disk++ ) {
1226
1227             if (((rdp->disks[disk].flags & (AR_DF_PRESENT | AR_DF_ONLINE)) ==
1228                  (AR_DF_PRESENT | AR_DF_ONLINE)) && rdp->disks[disk].dev)
1229                 continue;
1230
1231             if ((subdisk = devclass_get_device(ata_raid_sub_devclass,
1232                                                config->disks[0] ))) {
1233                 struct ata_raid_subdisk *ars = device_get_softc(subdisk);
1234
1235                 if (ars->raid[rdp->volume]) 
1236                     return EBUSY;
1237     
1238                 /* XXX SOS validate size etc etc */
1239                 ars->raid[rdp->volume] = rdp;
1240                 ars->disk_number[rdp->volume] = disk;
1241                 rdp->disks[disk].dev = device_get_parent(subdisk);
1242                 rdp->disks[disk].flags =
1243                     (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_SPARE);
1244
1245                 device_printf(rdp->disks[disk].dev,
1246                               "inserted into ar%d disk%d as spare\n",
1247                               rdp->lun, disk);
1248                 ata_raid_config_changed(rdp, 1);
1249                 return 0;
1250             }
1251         }
1252         return ENXIO;
1253
1254     default:
1255         return EPERM;
1256     }
1257 }
1258  
1259 static int
1260 ata_raid_rebuild(int array)
1261 {
1262     struct ar_softc *rdp;    
1263     int disk, count;
1264
1265     if (!(rdp = ata_raid_arrays[array]))
1266         return ENXIO;
1267     /* XXX SOS we should lock the rdp softc here */
1268     if (!(rdp->status & AR_S_DEGRADED) || !(rdp->status & AR_S_READY))
1269         return ENXIO;
1270     if (rdp->status & AR_S_REBUILDING)
1271         return EBUSY; 
1272
1273     switch (rdp->type) {
1274     case AR_T_RAID1:
1275     case AR_T_RAID01:
1276     case AR_T_RAID5:
1277         for (count = 0, disk = 0; disk < rdp->total_disks; disk++ ) {
1278             if (((rdp->disks[disk].flags &
1279                   (AR_DF_PRESENT|AR_DF_ASSIGNED|AR_DF_ONLINE|AR_DF_SPARE)) ==
1280                  (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_SPARE)) &&
1281                 rdp->disks[disk].dev) {
1282                 count++;
1283             }
1284         }
1285
1286         if (count) {
1287             rdp->rebuild_lba = 0;
1288             rdp->status |= AR_S_REBUILDING;
1289             return 0;
1290         }
1291         return EIO;
1292
1293     default:
1294         return EPERM;
1295     }
1296 }
1297
1298 static int
1299 ata_raid_read_metadata(device_t subdisk)
1300 {
1301     devclass_t pci_devclass = devclass_find("pci");
1302     devclass_t devclass=device_get_devclass(GRANDPARENT(GRANDPARENT(subdisk)));
1303
1304     /* prioritize vendor native metadata layout if possible */
1305     if (devclass == pci_devclass) {
1306         switch (pci_get_vendor(GRANDPARENT(device_get_parent(subdisk)))) {
1307         case ATA_HIGHPOINT_ID: 
1308             if (ata_raid_hptv3_read_meta(subdisk, ata_raid_arrays))
1309                 return 0;
1310             if (ata_raid_hptv2_read_meta(subdisk, ata_raid_arrays))
1311                 return 0;
1312             break;
1313
1314         case ATA_INTEL_ID:
1315             if (ata_raid_intel_read_meta(subdisk, ata_raid_arrays))
1316                 return 0;
1317             break;
1318
1319         case ATA_ITE_ID:
1320             if (ata_raid_ite_read_meta(subdisk, ata_raid_arrays))
1321                 return 0;
1322             break;
1323
1324         case ATA_JMICRON_ID:
1325             if (ata_raid_jmicron_read_meta(subdisk, ata_raid_arrays))
1326                 return 0;
1327             break;
1328
1329         case ATA_NVIDIA_ID:
1330             if (ata_raid_nvidia_read_meta(subdisk, ata_raid_arrays))
1331                 return 0;
1332             break;
1333
1334         case 0:         /* XXX SOS cover up for bug in our PCI code */
1335         case ATA_PROMISE_ID: 
1336             if (ata_raid_promise_read_meta(subdisk, ata_raid_arrays, 0))
1337                 return 0;
1338             break;
1339
1340         case ATA_ATI_ID:
1341         case ATA_SILICON_IMAGE_ID:
1342             if (ata_raid_sii_read_meta(subdisk, ata_raid_arrays))
1343                 return 0;
1344             break;
1345
1346         case ATA_SIS_ID:
1347             if (ata_raid_sis_read_meta(subdisk, ata_raid_arrays))
1348                 return 0;
1349             break;
1350
1351         case ATA_VIA_ID:
1352             if (ata_raid_via_read_meta(subdisk, ata_raid_arrays))
1353                 return 0;
1354             break;
1355         }
1356     }
1357     
1358     /* handle controllers that have multiple layout possibilities */
1359     /* NOTE: the order of these are not insignificant */
1360
1361     /* Adaptec HostRAID */
1362     if (ata_raid_adaptec_read_meta(subdisk, ata_raid_arrays))
1363         return 0;
1364
1365     /* LSILogic v3 and v2 */
1366     if (ata_raid_lsiv3_read_meta(subdisk, ata_raid_arrays))
1367         return 0;
1368     if (ata_raid_lsiv2_read_meta(subdisk, ata_raid_arrays))
1369         return 0;
1370
1371     /* if none of the above matched, try FreeBSD native format */
1372     return ata_raid_promise_read_meta(subdisk, ata_raid_arrays, 1);
1373 }
1374
1375 static int
1376 ata_raid_write_metadata(struct ar_softc *rdp)
1377 {
1378     switch (rdp->format) {
1379     case AR_F_FREEBSD_RAID:
1380     case AR_F_PROMISE_RAID: 
1381         return ata_raid_promise_write_meta(rdp);
1382
1383     case AR_F_HPTV3_RAID:
1384     case AR_F_HPTV2_RAID:
1385         /*
1386          * always write HPT v2 metadata, the v3 BIOS knows it as well.
1387          * this is handy since we cannot know what version BIOS is on there
1388          */
1389         return ata_raid_hptv2_write_meta(rdp);
1390
1391     case AR_F_INTEL_RAID:
1392         return ata_raid_intel_write_meta(rdp);
1393
1394     case AR_F_JMICRON_RAID:
1395         return ata_raid_jmicron_write_meta(rdp);
1396
1397     case AR_F_SIS_RAID:
1398         return ata_raid_sis_write_meta(rdp);
1399
1400     case AR_F_VIA_RAID:
1401         return ata_raid_via_write_meta(rdp);
1402 #if 0
1403     case AR_F_HPTV3_RAID:
1404         return ata_raid_hptv3_write_meta(rdp);
1405
1406     case AR_F_ADAPTEC_RAID:
1407         return ata_raid_adaptec_write_meta(rdp);
1408
1409     case AR_F_ITE_RAID:
1410         return ata_raid_ite_write_meta(rdp);
1411
1412     case AR_F_LSIV2_RAID:
1413         return ata_raid_lsiv2_write_meta(rdp);
1414
1415     case AR_F_LSIV3_RAID:
1416         return ata_raid_lsiv3_write_meta(rdp);
1417
1418     case AR_F_NVIDIA_RAID:
1419         return ata_raid_nvidia_write_meta(rdp);
1420
1421     case AR_F_SII_RAID:
1422         return ata_raid_sii_write_meta(rdp);
1423
1424 #endif
1425     default:
1426         printf("ar%d: writing of %s metadata is NOT supported yet\n",
1427                rdp->lun, ata_raid_format(rdp));
1428     }
1429     return -1;
1430 }
1431
1432 static int
1433 ata_raid_wipe_metadata(struct ar_softc *rdp)
1434 {
1435     int disk, error = 0;
1436     u_int64_t lba;
1437     u_int32_t size;
1438     u_int8_t *meta;
1439
1440     for (disk = 0; disk < rdp->total_disks; disk++) {
1441         if (rdp->disks[disk].dev) {
1442             switch (rdp->format) {
1443             case AR_F_ADAPTEC_RAID:
1444                 lba = ADP_LBA(rdp->disks[disk].dev);
1445                 size = sizeof(struct adaptec_raid_conf);
1446                 break;
1447
1448             case AR_F_HPTV2_RAID:
1449                 lba = HPTV2_LBA(rdp->disks[disk].dev);
1450                 size = sizeof(struct hptv2_raid_conf);
1451                 break;
1452                 
1453             case AR_F_HPTV3_RAID:
1454                 lba = HPTV3_LBA(rdp->disks[disk].dev);
1455                 size = sizeof(struct hptv3_raid_conf);
1456                 break;
1457
1458             case AR_F_INTEL_RAID:
1459                 lba = INTEL_LBA(rdp->disks[disk].dev);
1460                 size = 3 * 512;         /* XXX SOS */
1461                 break;
1462
1463             case AR_F_ITE_RAID:
1464                 lba = ITE_LBA(rdp->disks[disk].dev);
1465                 size = sizeof(struct ite_raid_conf);
1466                 break;
1467
1468             case AR_F_JMICRON_RAID:
1469                 lba = JMICRON_LBA(rdp->disks[disk].dev);
1470                 size = sizeof(struct jmicron_raid_conf);
1471                 break;
1472
1473             case AR_F_LSIV2_RAID:
1474                 lba = LSIV2_LBA(rdp->disks[disk].dev);
1475                 size = sizeof(struct lsiv2_raid_conf);
1476                 break;
1477
1478             case AR_F_LSIV3_RAID:
1479                 lba = LSIV3_LBA(rdp->disks[disk].dev);
1480                 size = sizeof(struct lsiv3_raid_conf);
1481                 break;
1482
1483             case AR_F_NVIDIA_RAID:
1484                 lba = NVIDIA_LBA(rdp->disks[disk].dev);
1485                 size = sizeof(struct nvidia_raid_conf);
1486                 break;
1487
1488             case AR_F_FREEBSD_RAID:
1489             case AR_F_PROMISE_RAID: 
1490                 lba = PROMISE_LBA(rdp->disks[disk].dev);
1491                 size = sizeof(struct promise_raid_conf);
1492                 break;
1493
1494             case AR_F_SII_RAID:
1495                 lba = SII_LBA(rdp->disks[disk].dev);
1496                 size = sizeof(struct sii_raid_conf);
1497                 break;
1498
1499             case AR_F_SIS_RAID:
1500                 lba = SIS_LBA(rdp->disks[disk].dev);
1501                 size = sizeof(struct sis_raid_conf);
1502                 break;
1503
1504             case AR_F_VIA_RAID:
1505                 lba = VIA_LBA(rdp->disks[disk].dev);
1506                 size = sizeof(struct via_raid_conf);
1507                 break;
1508
1509             default:
1510                 printf("ar%d: wiping of %s metadata is NOT supported yet\n",
1511                        rdp->lun, ata_raid_format(rdp));
1512                 return ENXIO;
1513             }
1514             if (!(meta = malloc(size, M_AR, M_NOWAIT | M_ZERO)))
1515                 return ENOMEM;
1516             if (ata_raid_rw(rdp->disks[disk].dev, lba, meta, size,
1517                             ATA_R_WRITE | ATA_R_DIRECT)) {
1518                 device_printf(rdp->disks[disk].dev, "wipe metadata failed\n");
1519                 error = EIO;
1520             }
1521             free(meta, M_AR);
1522         }
1523     }
1524     return error;
1525 }
1526
1527 /* Adaptec HostRAID Metadata */
1528 static int
1529 ata_raid_adaptec_read_meta(device_t dev, struct ar_softc **raidp)
1530 {
1531     struct ata_raid_subdisk *ars = device_get_softc(dev);
1532     device_t parent = device_get_parent(dev);
1533     struct adaptec_raid_conf *meta;
1534     struct ar_softc *raid;
1535     int array, disk, retval = 0; 
1536
1537     if (!(meta = (struct adaptec_raid_conf *)
1538           malloc(sizeof(struct adaptec_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
1539         return ENOMEM;
1540
1541     if (ata_raid_rw(parent, ADP_LBA(parent),
1542                     meta, sizeof(struct adaptec_raid_conf), ATA_R_READ)) {
1543         if (testing || bootverbose)
1544             device_printf(parent, "Adaptec read metadata failed\n");
1545         goto adaptec_out;
1546     }
1547
1548     /* check if this is a Adaptec RAID struct */
1549     if (meta->magic_0 != ADP_MAGIC_0 || meta->magic_3 != ADP_MAGIC_3) {
1550         if (testing || bootverbose)
1551             device_printf(parent, "Adaptec check1 failed\n");
1552         goto adaptec_out;
1553     }
1554
1555     if (testing || bootverbose)
1556         ata_raid_adaptec_print_meta(meta);
1557
1558     /* now convert Adaptec metadata into our generic form */
1559     for (array = 0; array < MAX_ARRAYS; array++) {
1560         if (!raidp[array]) {
1561             raidp[array] = 
1562                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
1563                                           M_NOWAIT | M_ZERO);
1564             if (!raidp[array]) {
1565                 device_printf(parent, "failed to allocate metadata storage\n");
1566                 goto adaptec_out;
1567             }
1568         }
1569         raid = raidp[array];
1570         if (raid->format && (raid->format != AR_F_ADAPTEC_RAID))
1571             continue;
1572
1573         if (raid->magic_0 && raid->magic_0 != meta->configs[0].magic_0)
1574             continue;
1575
1576         if (!meta->generation || be32toh(meta->generation) > raid->generation) {
1577             switch (meta->configs[0].type) {
1578             case ADP_T_RAID0:
1579                 raid->magic_0 = meta->configs[0].magic_0;
1580                 raid->type = AR_T_RAID0;
1581                 raid->interleave = 1 << (meta->configs[0].stripe_shift >> 1);
1582                 raid->width = be16toh(meta->configs[0].total_disks);
1583                 break;
1584             
1585             case ADP_T_RAID1:
1586                 raid->magic_0 = meta->configs[0].magic_0;
1587                 raid->type = AR_T_RAID1;
1588                 raid->width = be16toh(meta->configs[0].total_disks) / 2;
1589                 break;
1590
1591             default:
1592                 device_printf(parent, "Adaptec unknown RAID type 0x%02x\n",
1593                               meta->configs[0].type);
1594                 free(raidp[array], M_AR);
1595                 raidp[array] = NULL;
1596                 goto adaptec_out;
1597             }
1598
1599             raid->format = AR_F_ADAPTEC_RAID;
1600             raid->generation = be32toh(meta->generation);
1601             raid->total_disks = be16toh(meta->configs[0].total_disks);
1602             raid->total_sectors = be32toh(meta->configs[0].sectors);
1603             raid->heads = 255;
1604             raid->sectors = 63;
1605             raid->cylinders = raid->total_sectors / (63 * 255);
1606             raid->offset_sectors = 0;
1607             raid->rebuild_lba = 0;
1608             raid->lun = array;
1609             strncpy(raid->name, meta->configs[0].name,
1610                     min(sizeof(raid->name), sizeof(meta->configs[0].name)));
1611
1612             /* clear out any old info */
1613             if (raid->generation) {
1614                 for (disk = 0; disk < raid->total_disks; disk++) {
1615                     raid->disks[disk].dev = NULL;
1616                     raid->disks[disk].flags = 0;
1617                 }
1618             }
1619         }
1620         if (be32toh(meta->generation) >= raid->generation) {
1621             struct ata_device *atadev = device_get_softc(parent);
1622             struct ata_channel *ch = device_get_softc(GRANDPARENT(dev));
1623             int disk_number = (ch->unit << !(ch->flags & ATA_NO_SLAVE)) +
1624                               ATA_DEV(atadev->unit);
1625
1626             raid->disks[disk_number].dev = parent;
1627             raid->disks[disk_number].sectors = 
1628                 be32toh(meta->configs[disk_number + 1].sectors);
1629             raid->disks[disk_number].flags =
1630                 (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED);
1631             ars->raid[raid->volume] = raid;
1632             ars->disk_number[raid->volume] = disk_number;
1633             retval = 1;
1634         }
1635         break;
1636     }
1637
1638 adaptec_out:
1639     free(meta, M_AR);
1640     return retval;
1641 }
1642
1643 /* Highpoint V2 RocketRAID Metadata */
1644 static int
1645 ata_raid_hptv2_read_meta(device_t dev, struct ar_softc **raidp)
1646 {
1647     struct ata_raid_subdisk *ars = device_get_softc(dev);
1648     device_t parent = device_get_parent(dev);
1649     struct hptv2_raid_conf *meta;
1650     struct ar_softc *raid = NULL;
1651     int array, disk_number = 0, retval = 0;
1652
1653     if (!(meta = (struct hptv2_raid_conf *)
1654           malloc(sizeof(struct hptv2_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
1655         return ENOMEM;
1656
1657     if (ata_raid_rw(parent, HPTV2_LBA(parent),
1658                     meta, sizeof(struct hptv2_raid_conf), ATA_R_READ)) {
1659         if (testing || bootverbose)
1660             device_printf(parent, "HighPoint (v2) read metadata failed\n");
1661         goto hptv2_out;
1662     }
1663
1664     /* check if this is a HighPoint v2 RAID struct */
1665     if (meta->magic != HPTV2_MAGIC_OK && meta->magic != HPTV2_MAGIC_BAD) {
1666         if (testing || bootverbose)
1667             device_printf(parent, "HighPoint (v2) check1 failed\n");
1668         goto hptv2_out;
1669     }
1670
1671     /* is this disk defined, or an old leftover/spare ? */
1672     if (!meta->magic_0) {
1673         if (testing || bootverbose)
1674             device_printf(parent, "HighPoint (v2) check2 failed\n");
1675         goto hptv2_out;
1676     }
1677
1678     if (testing || bootverbose)
1679         ata_raid_hptv2_print_meta(meta);
1680
1681     /* now convert HighPoint (v2) metadata into our generic form */
1682     for (array = 0; array < MAX_ARRAYS; array++) {
1683         if (!raidp[array]) {
1684             raidp[array] = 
1685                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
1686                                           M_NOWAIT | M_ZERO);
1687             if (!raidp[array]) {
1688                 device_printf(parent, "failed to allocate metadata storage\n");
1689                 goto hptv2_out;
1690             }
1691         }
1692         raid = raidp[array];
1693         if (raid->format && (raid->format != AR_F_HPTV2_RAID))
1694             continue;
1695
1696         switch (meta->type) {
1697         case HPTV2_T_RAID0:
1698             if ((meta->order & (HPTV2_O_RAID0|HPTV2_O_OK)) ==
1699                 (HPTV2_O_RAID0|HPTV2_O_OK))
1700                 goto highpoint_raid1;
1701             if (meta->order & (HPTV2_O_RAID0 | HPTV2_O_RAID1))
1702                 goto highpoint_raid01;
1703             if (raid->magic_0 && raid->magic_0 != meta->magic_0)
1704                 continue;
1705             raid->magic_0 = meta->magic_0;
1706             raid->type = AR_T_RAID0;
1707             raid->interleave = 1 << meta->stripe_shift;
1708             disk_number = meta->disk_number;
1709             if (!(meta->order & HPTV2_O_OK))
1710                 meta->magic = 0;        /* mark bad */
1711             break;
1712
1713         case HPTV2_T_RAID1:
1714 highpoint_raid1:
1715             if (raid->magic_0 && raid->magic_0 != meta->magic_0)
1716                 continue;
1717             raid->magic_0 = meta->magic_0;
1718             raid->type = AR_T_RAID1;
1719             disk_number = (meta->disk_number > 0);
1720             break;
1721
1722         case HPTV2_T_RAID01_RAID0:
1723 highpoint_raid01:
1724             if (meta->order & HPTV2_O_RAID0) {
1725                 if ((raid->magic_0 && raid->magic_0 != meta->magic_0) ||
1726                     (raid->magic_1 && raid->magic_1 != meta->magic_1))
1727                     continue;
1728                 raid->magic_0 = meta->magic_0;
1729                 raid->magic_1 = meta->magic_1;
1730                 raid->type = AR_T_RAID01;
1731                 raid->interleave = 1 << meta->stripe_shift;
1732                 disk_number = meta->disk_number;
1733             }
1734             else {
1735                 if (raid->magic_1 && raid->magic_1 != meta->magic_1)
1736                     continue;
1737                 raid->magic_1 = meta->magic_1;
1738                 raid->type = AR_T_RAID01;
1739                 raid->interleave = 1 << meta->stripe_shift;
1740                 disk_number = meta->disk_number + meta->array_width;
1741                 if (!(meta->order & HPTV2_O_RAID1))
1742                     meta->magic = 0;    /* mark bad */
1743             }
1744             break;
1745
1746         case HPTV2_T_SPAN:
1747             if (raid->magic_0 && raid->magic_0 != meta->magic_0)
1748                 continue;
1749             raid->magic_0 = meta->magic_0;
1750             raid->type = AR_T_SPAN;
1751             disk_number = meta->disk_number;
1752             break;
1753
1754         default:
1755             device_printf(parent, "Highpoint (v2) unknown RAID type 0x%02x\n",
1756                           meta->type);
1757             free(raidp[array], M_AR);
1758             raidp[array] = NULL;
1759             goto hptv2_out;
1760         }
1761
1762         raid->format |= AR_F_HPTV2_RAID;
1763         raid->disks[disk_number].dev = parent;
1764         raid->disks[disk_number].flags = (AR_DF_PRESENT | AR_DF_ASSIGNED);
1765         raid->lun = array;
1766         strncpy(raid->name, meta->name_1,
1767                 min(sizeof(raid->name), sizeof(meta->name_1)));
1768         if (meta->magic == HPTV2_MAGIC_OK) {
1769             raid->disks[disk_number].flags |= AR_DF_ONLINE;
1770             raid->width = meta->array_width;
1771             raid->total_sectors = meta->total_sectors;
1772             raid->heads = 255;
1773             raid->sectors = 63;
1774             raid->cylinders = raid->total_sectors / (63 * 255);
1775             raid->offset_sectors = HPTV2_LBA(parent) + 1;
1776             raid->rebuild_lba = meta->rebuild_lba;
1777             raid->disks[disk_number].sectors =
1778                 raid->total_sectors / raid->width;
1779         }
1780         else
1781             raid->disks[disk_number].flags &= ~AR_DF_ONLINE;
1782
1783         if ((raid->type & AR_T_RAID0) && (raid->total_disks < raid->width))
1784             raid->total_disks = raid->width;
1785         if (disk_number >= raid->total_disks)
1786             raid->total_disks = disk_number + 1;
1787         ars->raid[raid->volume] = raid;
1788         ars->disk_number[raid->volume] = disk_number;
1789         retval = 1;
1790         break;
1791     }
1792
1793 hptv2_out:
1794     free(meta, M_AR);
1795     return retval;
1796 }
1797
1798 static int
1799 ata_raid_hptv2_write_meta(struct ar_softc *rdp)
1800 {
1801     struct hptv2_raid_conf *meta;
1802     struct timeval timestamp;
1803     int disk, error = 0;
1804
1805     if (!(meta = (struct hptv2_raid_conf *)
1806           malloc(sizeof(struct hptv2_raid_conf), M_AR, M_NOWAIT | M_ZERO))) {
1807         printf("ar%d: failed to allocate metadata storage\n", rdp->lun);
1808         return ENOMEM;
1809     }
1810
1811     microtime(&timestamp);
1812     rdp->magic_0 = timestamp.tv_sec + 2;
1813     rdp->magic_1 = timestamp.tv_sec;
1814    
1815     for (disk = 0; disk < rdp->total_disks; disk++) {
1816         if ((rdp->disks[disk].flags & (AR_DF_PRESENT | AR_DF_ONLINE)) ==
1817             (AR_DF_PRESENT | AR_DF_ONLINE))
1818             meta->magic = HPTV2_MAGIC_OK;
1819         if (rdp->disks[disk].flags & AR_DF_ASSIGNED) {
1820             meta->magic_0 = rdp->magic_0;
1821             if (strlen(rdp->name))
1822                 strncpy(meta->name_1, rdp->name, sizeof(meta->name_1));
1823             else
1824                 strcpy(meta->name_1, "FreeBSD");
1825         }
1826         meta->disk_number = disk;
1827
1828         switch (rdp->type) {
1829         case AR_T_RAID0:
1830             meta->type = HPTV2_T_RAID0;
1831             strcpy(meta->name_2, "RAID 0");
1832             if (rdp->disks[disk].flags & AR_DF_ONLINE)
1833                 meta->order = HPTV2_O_OK;
1834             break;
1835
1836         case AR_T_RAID1:
1837             meta->type = HPTV2_T_RAID0;
1838             strcpy(meta->name_2, "RAID 1");
1839             meta->disk_number = (disk < rdp->width) ? disk : disk + 5;
1840             meta->order = HPTV2_O_RAID0 | HPTV2_O_OK;
1841             break;
1842
1843         case AR_T_RAID01:
1844             meta->type = HPTV2_T_RAID01_RAID0;
1845             strcpy(meta->name_2, "RAID 0+1");
1846             if (rdp->disks[disk].flags & AR_DF_ONLINE) {
1847                 if (disk < rdp->width) {
1848                     meta->order = (HPTV2_O_RAID0 | HPTV2_O_RAID1);
1849                     meta->magic_0 = rdp->magic_0 - 1;
1850                 }
1851                 else {
1852                     meta->order = HPTV2_O_RAID1;
1853                     meta->disk_number -= rdp->width;
1854                 }
1855             }
1856             else
1857                 meta->magic_0 = rdp->magic_0 - 1;
1858             meta->magic_1 = rdp->magic_1;
1859             break;
1860
1861         case AR_T_SPAN:
1862             meta->type = HPTV2_T_SPAN;
1863             strcpy(meta->name_2, "SPAN");
1864             break;
1865         default:
1866             free(meta, M_AR);
1867             return ENODEV;
1868         }
1869
1870         meta->array_width = rdp->width;
1871         meta->stripe_shift = (rdp->width > 1) ? (ffs(rdp->interleave)-1) : 0;
1872         meta->total_sectors = rdp->total_sectors;
1873         meta->rebuild_lba = rdp->rebuild_lba;
1874         if (testing || bootverbose)
1875             ata_raid_hptv2_print_meta(meta);
1876         if (rdp->disks[disk].dev) {
1877             if (ata_raid_rw(rdp->disks[disk].dev,
1878                             HPTV2_LBA(rdp->disks[disk].dev), meta,
1879                             sizeof(struct promise_raid_conf),
1880                             ATA_R_WRITE | ATA_R_DIRECT)) {
1881                 device_printf(rdp->disks[disk].dev, "write metadata failed\n");
1882                 error = EIO;
1883             }
1884         }
1885     }
1886     free(meta, M_AR);
1887     return error;
1888 }
1889
1890 /* Highpoint V3 RocketRAID Metadata */
1891 static int
1892 ata_raid_hptv3_read_meta(device_t dev, struct ar_softc **raidp)
1893 {
1894     struct ata_raid_subdisk *ars = device_get_softc(dev);
1895     device_t parent = device_get_parent(dev);
1896     struct hptv3_raid_conf *meta;
1897     struct ar_softc *raid = NULL;
1898     int array, disk_number, retval = 0;
1899
1900     if (!(meta = (struct hptv3_raid_conf *)
1901           malloc(sizeof(struct hptv3_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
1902         return ENOMEM;
1903
1904     if (ata_raid_rw(parent, HPTV3_LBA(parent),
1905                     meta, sizeof(struct hptv3_raid_conf), ATA_R_READ)) {
1906         if (testing || bootverbose)
1907             device_printf(parent, "HighPoint (v3) read metadata failed\n");
1908         goto hptv3_out;
1909     }
1910
1911     /* check if this is a HighPoint v3 RAID struct */
1912     if (meta->magic != HPTV3_MAGIC) {
1913         if (testing || bootverbose)
1914             device_printf(parent, "HighPoint (v3) check1 failed\n");
1915         goto hptv3_out;
1916     }
1917
1918     /* check if there are any config_entries */
1919     if (meta->config_entries < 1) {
1920         if (testing || bootverbose)
1921             device_printf(parent, "HighPoint (v3) check2 failed\n");
1922         goto hptv3_out;
1923     }
1924
1925     if (testing || bootverbose)
1926         ata_raid_hptv3_print_meta(meta);
1927
1928     /* now convert HighPoint (v3) metadata into our generic form */
1929     for (array = 0; array < MAX_ARRAYS; array++) {
1930         if (!raidp[array]) {
1931             raidp[array] = 
1932                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
1933                                           M_NOWAIT | M_ZERO);
1934             if (!raidp[array]) {
1935                 device_printf(parent, "failed to allocate metadata storage\n");
1936                 goto hptv3_out;
1937             }
1938         }
1939         raid = raidp[array];
1940         if (raid->format && (raid->format != AR_F_HPTV3_RAID))
1941             continue;
1942
1943         if ((raid->format & AR_F_HPTV3_RAID) && raid->magic_0 != meta->magic_0)
1944             continue;
1945         
1946         switch (meta->configs[0].type) {
1947         case HPTV3_T_RAID0:
1948             raid->type = AR_T_RAID0;
1949             raid->width = meta->configs[0].total_disks;
1950             disk_number = meta->configs[0].disk_number;
1951             break;
1952
1953         case HPTV3_T_RAID1:
1954             raid->type = AR_T_RAID1;
1955             raid->width = meta->configs[0].total_disks / 2;
1956             disk_number = meta->configs[0].disk_number;
1957             break;
1958
1959         case HPTV3_T_RAID5:
1960             raid->type = AR_T_RAID5;
1961             raid->width = meta->configs[0].total_disks;
1962             disk_number = meta->configs[0].disk_number;
1963             break;
1964
1965         case HPTV3_T_SPAN:
1966             raid->type = AR_T_SPAN;
1967             raid->width = meta->configs[0].total_disks;
1968             disk_number = meta->configs[0].disk_number;
1969             break;
1970
1971         default:
1972             device_printf(parent, "Highpoint (v3) unknown RAID type 0x%02x\n",
1973                           meta->configs[0].type);
1974             free(raidp[array], M_AR);
1975             raidp[array] = NULL;
1976             goto hptv3_out;
1977         }
1978         if (meta->config_entries == 2) {
1979             switch (meta->configs[1].type) {
1980             case HPTV3_T_RAID1:
1981                 if (raid->type == AR_T_RAID0) {
1982                     raid->type = AR_T_RAID01;
1983                     disk_number = meta->configs[1].disk_number +
1984                                   (meta->configs[0].disk_number << 1);
1985                     break;
1986                 }
1987             default:
1988                 device_printf(parent, "Highpoint (v3) unknown level 2 0x%02x\n",
1989                               meta->configs[1].type);
1990                 free(raidp[array], M_AR);
1991                 raidp[array] = NULL;
1992                 goto hptv3_out;
1993             }
1994         }
1995
1996         raid->magic_0 = meta->magic_0;
1997         raid->format = AR_F_HPTV3_RAID;
1998         raid->generation = meta->timestamp;
1999         raid->interleave = 1 << meta->configs[0].stripe_shift;
2000         raid->total_disks = meta->configs[0].total_disks +
2001             meta->configs[1].total_disks;
2002         raid->total_sectors = meta->configs[0].total_sectors +
2003             ((u_int64_t)meta->configs_high[0].total_sectors << 32);
2004         raid->heads = 255;
2005         raid->sectors = 63;
2006         raid->cylinders = raid->total_sectors / (63 * 255);
2007         raid->offset_sectors = 0;
2008         raid->rebuild_lba = meta->configs[0].rebuild_lba +
2009             ((u_int64_t)meta->configs_high[0].rebuild_lba << 32);
2010         raid->lun = array;
2011         strncpy(raid->name, meta->name,
2012                 min(sizeof(raid->name), sizeof(meta->name)));
2013         raid->disks[disk_number].sectors = raid->total_sectors /
2014             (raid->type == AR_T_RAID5 ? raid->width - 1 : raid->width);
2015         raid->disks[disk_number].dev = parent;
2016         raid->disks[disk_number].flags = 
2017             (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE);
2018         ars->raid[raid->volume] = raid;
2019         ars->disk_number[raid->volume] = disk_number;
2020         retval = 1;
2021         break;
2022     }
2023
2024 hptv3_out:
2025     free(meta, M_AR);
2026     return retval;
2027 }
2028
2029 /* Intel MatrixRAID Metadata */
2030 static int
2031 ata_raid_intel_read_meta(device_t dev, struct ar_softc **raidp)
2032 {
2033     struct ata_raid_subdisk *ars = device_get_softc(dev);
2034     device_t parent = device_get_parent(dev);
2035     struct intel_raid_conf *meta;
2036     struct intel_raid_mapping *map;
2037     struct ar_softc *raid = NULL;
2038     u_int32_t checksum, *ptr;
2039     int array, count, disk, volume = 1, retval = 0;
2040     char *tmp;
2041
2042     if (!(meta = (struct intel_raid_conf *)
2043           malloc(1536, M_AR, M_NOWAIT | M_ZERO)))
2044         return ENOMEM;
2045
2046     if (ata_raid_rw(parent, INTEL_LBA(parent), meta, 1024, ATA_R_READ)) {
2047         if (testing || bootverbose)
2048             device_printf(parent, "Intel read metadata failed\n");
2049         goto intel_out;
2050     }
2051     tmp = (char *)meta;
2052     bcopy(tmp, tmp+1024, 512);
2053     bcopy(tmp+512, tmp, 1024);
2054     bzero(tmp+1024, 512);
2055
2056     /* check if this is a Intel RAID struct */
2057     if (strncmp(meta->intel_id, INTEL_MAGIC, strlen(INTEL_MAGIC))) {
2058         if (testing || bootverbose)
2059             device_printf(parent, "Intel check1 failed\n");
2060         goto intel_out;
2061     }
2062
2063     for (checksum = 0, ptr = (u_int32_t *)meta, count = 0;
2064          count < (meta->config_size / sizeof(u_int32_t)); count++) {
2065         checksum += *ptr++;
2066     }
2067     checksum -= meta->checksum;
2068     if (checksum != meta->checksum) {  
2069         if (testing || bootverbose)
2070             device_printf(parent, "Intel check2 failed\n");          
2071         goto intel_out;
2072     }
2073
2074     if (testing || bootverbose)
2075         ata_raid_intel_print_meta(meta);
2076
2077     map = (struct intel_raid_mapping *)&meta->disk[meta->total_disks];
2078
2079     /* now convert Intel metadata into our generic form */
2080     for (array = 0; array < MAX_ARRAYS; array++) {
2081         if (!raidp[array]) {
2082             raidp[array] = 
2083                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
2084                                           M_NOWAIT | M_ZERO);
2085             if (!raidp[array]) {
2086                 device_printf(parent, "failed to allocate metadata storage\n");
2087                 goto intel_out;
2088             }
2089         }
2090         raid = raidp[array];
2091         if (raid->format && (raid->format != AR_F_INTEL_RAID))
2092             continue;
2093
2094         if ((raid->format & AR_F_INTEL_RAID) &&
2095             (raid->magic_0 != meta->config_id))
2096             continue;
2097
2098         /*
2099          * update our knowledge about the array config based on generation
2100          * NOTE: there can be multiple volumes on a disk set
2101          */
2102         if (!meta->generation || meta->generation > raid->generation) {
2103             switch (map->type) {
2104             case INTEL_T_RAID0:
2105                 raid->type = AR_T_RAID0;
2106                 raid->width = map->total_disks;
2107                 break;
2108
2109             case INTEL_T_RAID1:
2110                 if (map->total_disks == 4)
2111                     raid->type = AR_T_RAID01;
2112                 else
2113                     raid->type = AR_T_RAID1;
2114                 raid->width = map->total_disks / 2;
2115                 break;
2116
2117             case INTEL_T_RAID5:
2118                 raid->type = AR_T_RAID5;
2119                 raid->width = map->total_disks;
2120                 break;
2121
2122             default:
2123                 device_printf(parent, "Intel unknown RAID type 0x%02x\n",
2124                               map->type);
2125                 free(raidp[array], M_AR);
2126                 raidp[array] = NULL;
2127                 goto intel_out;
2128             }
2129
2130             switch (map->status) {
2131             case INTEL_S_READY:
2132                 raid->status = AR_S_READY;
2133                 break;
2134             case INTEL_S_DEGRADED:
2135                 raid->status |= AR_S_DEGRADED;
2136                 break;
2137             case INTEL_S_DISABLED:
2138             case INTEL_S_FAILURE:
2139                 raid->status = 0;
2140             }
2141
2142             raid->magic_0 = meta->config_id;
2143             raid->format = AR_F_INTEL_RAID;
2144             raid->generation = meta->generation;
2145             raid->interleave = map->stripe_sectors;
2146             raid->total_disks = map->total_disks;
2147             raid->total_sectors = map->total_sectors;
2148             raid->heads = 255;
2149             raid->sectors = 63;
2150             raid->cylinders = raid->total_sectors / (63 * 255);
2151             raid->offset_sectors = map->offset;         
2152             raid->rebuild_lba = 0;
2153             raid->lun = array;
2154             raid->volume = volume - 1;
2155             strncpy(raid->name, map->name,
2156                     min(sizeof(raid->name), sizeof(map->name)));
2157
2158             /* clear out any old info */
2159             for (disk = 0; disk < raid->total_disks; disk++) {
2160                 raid->disks[disk].dev = NULL;
2161                 bcopy(meta->disk[map->disk_idx[disk]].serial,
2162                       raid->disks[disk].serial,
2163                       sizeof(raid->disks[disk].serial));
2164                 raid->disks[disk].sectors =
2165                     meta->disk[map->disk_idx[disk]].sectors;
2166                 raid->disks[disk].flags = 0;
2167                 if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_ONLINE)
2168                     raid->disks[disk].flags |= AR_DF_ONLINE;
2169                 if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_ASSIGNED)
2170                     raid->disks[disk].flags |= AR_DF_ASSIGNED;
2171                 if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_SPARE) {
2172                     raid->disks[disk].flags &= ~(AR_DF_ONLINE | AR_DF_ASSIGNED);
2173                     raid->disks[disk].flags |= AR_DF_SPARE;
2174                 }
2175                 if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_DOWN)
2176                     raid->disks[disk].flags &= ~AR_DF_ONLINE;
2177             }
2178         }
2179         if (meta->generation >= raid->generation) {
2180             for (disk = 0; disk < raid->total_disks; disk++) {
2181                 struct ata_device *atadev = device_get_softc(parent);
2182
2183                 if (!strncmp(raid->disks[disk].serial, atadev->param.serial,
2184                     sizeof(raid->disks[disk].serial))) {
2185                     raid->disks[disk].dev = parent;
2186                     raid->disks[disk].flags |= (AR_DF_PRESENT | AR_DF_ONLINE);
2187                     ars->raid[raid->volume] = raid;
2188                     ars->disk_number[raid->volume] = disk;
2189                     retval = 1;
2190                 }
2191             }
2192         }
2193         else
2194             goto intel_out;
2195
2196         if (retval) {
2197             if (volume < meta->total_volumes) {
2198                 map = (struct intel_raid_mapping *)
2199                       &map->disk_idx[map->total_disks];
2200                 volume++;
2201                 retval = 0;
2202                 continue;
2203             }
2204             break;
2205         }
2206         else {
2207             free(raidp[array], M_AR);
2208             raidp[array] = NULL;
2209             if (volume == 2)
2210                 retval = 1;
2211         }
2212     }
2213
2214 intel_out:
2215     free(meta, M_AR);
2216     return retval;
2217 }
2218
2219 static int
2220 ata_raid_intel_write_meta(struct ar_softc *rdp)
2221 {
2222     struct intel_raid_conf *meta;
2223     struct intel_raid_mapping *map;
2224     struct timeval timestamp;
2225     u_int32_t checksum, *ptr;
2226     int count, disk, error = 0;
2227     char *tmp;
2228
2229     if (!(meta = (struct intel_raid_conf *)
2230           malloc(1536, M_AR, M_NOWAIT | M_ZERO))) {
2231         printf("ar%d: failed to allocate metadata storage\n", rdp->lun);
2232         return ENOMEM;
2233     }
2234
2235     rdp->generation++;
2236     microtime(&timestamp);
2237
2238     bcopy(INTEL_MAGIC, meta->intel_id, sizeof(meta->intel_id));
2239     bcopy(INTEL_VERSION_1100, meta->version, sizeof(meta->version));
2240     meta->config_id = timestamp.tv_sec;
2241     meta->generation = rdp->generation;
2242     meta->total_disks = rdp->total_disks;
2243     meta->total_volumes = 1;                                    /* XXX SOS */
2244     for (disk = 0; disk < rdp->total_disks; disk++) {
2245         if (rdp->disks[disk].dev) {
2246             struct ata_channel *ch =
2247                 device_get_softc(device_get_parent(rdp->disks[disk].dev));
2248             struct ata_device *atadev =
2249                 device_get_softc(rdp->disks[disk].dev);
2250
2251             bcopy(atadev->param.serial, meta->disk[disk].serial,
2252                   sizeof(rdp->disks[disk].serial));
2253             meta->disk[disk].sectors = rdp->disks[disk].sectors;
2254             meta->disk[disk].id = (ch->unit << 16) | ATA_DEV(atadev->unit);
2255         }
2256         else
2257             meta->disk[disk].sectors = rdp->total_sectors / rdp->width;
2258         meta->disk[disk].flags = 0;
2259         if (rdp->disks[disk].flags & AR_DF_SPARE)
2260             meta->disk[disk].flags  |= INTEL_F_SPARE;
2261         else {
2262             if (rdp->disks[disk].flags & AR_DF_ONLINE)
2263                 meta->disk[disk].flags |= INTEL_F_ONLINE;
2264             else
2265                 meta->disk[disk].flags |= INTEL_F_DOWN;
2266             if (rdp->disks[disk].flags & AR_DF_ASSIGNED)
2267                 meta->disk[disk].flags  |= INTEL_F_ASSIGNED;
2268         }
2269     }
2270     map = (struct intel_raid_mapping *)&meta->disk[meta->total_disks];
2271
2272     bcopy(rdp->name, map->name, sizeof(rdp->name));
2273     map->total_sectors = rdp->total_sectors;
2274     map->state = 12;                                            /* XXX SOS */
2275     map->offset = rdp->offset_sectors;
2276     map->stripe_count = rdp->total_sectors / (rdp->interleave*rdp->total_disks);
2277     map->stripe_sectors =  rdp->interleave;
2278     map->disk_sectors = rdp->total_sectors / rdp->width;
2279     map->status = INTEL_S_READY;                                /* XXX SOS */
2280     switch (rdp->type) {
2281     case AR_T_RAID0:
2282         map->type = INTEL_T_RAID0;
2283         break;
2284     case AR_T_RAID1:
2285         map->type = INTEL_T_RAID1;
2286         break;
2287     case AR_T_RAID01:
2288         map->type = INTEL_T_RAID1;
2289         break;
2290     case AR_T_RAID5:
2291         map->type = INTEL_T_RAID5;
2292         break;
2293     default:
2294         free(meta, M_AR);
2295         return ENODEV;
2296     }
2297     map->total_disks = rdp->total_disks;
2298     map->magic[0] = 0x02;
2299     map->magic[1] = 0xff;
2300     map->magic[2] = 0x01;
2301     for (disk = 0; disk < rdp->total_disks; disk++)
2302         map->disk_idx[disk] = disk;
2303
2304     meta->config_size = (char *)&map->disk_idx[disk] - (char *)meta;
2305     for (checksum = 0, ptr = (u_int32_t *)meta, count = 0;
2306          count < (meta->config_size / sizeof(u_int32_t)); count++) {
2307         checksum += *ptr++;
2308     }
2309     meta->checksum = checksum;
2310
2311     if (testing || bootverbose)
2312         ata_raid_intel_print_meta(meta);
2313
2314     tmp = (char *)meta;
2315     bcopy(tmp, tmp+1024, 512);
2316     bcopy(tmp+512, tmp, 1024);
2317     bzero(tmp+1024, 512);
2318
2319     for (disk = 0; disk < rdp->total_disks; disk++) {
2320         if (rdp->disks[disk].dev) {
2321             if (ata_raid_rw(rdp->disks[disk].dev,
2322                             INTEL_LBA(rdp->disks[disk].dev),
2323                             meta, 1024, ATA_R_WRITE | ATA_R_DIRECT)) {
2324                 device_printf(rdp->disks[disk].dev, "write metadata failed\n");
2325                 error = EIO;
2326             }
2327         }
2328     }
2329     free(meta, M_AR);
2330     return error;
2331 }
2332
2333
2334 /* Integrated Technology Express Metadata */
2335 static int
2336 ata_raid_ite_read_meta(device_t dev, struct ar_softc **raidp)
2337 {
2338     struct ata_raid_subdisk *ars = device_get_softc(dev);
2339     device_t parent = device_get_parent(dev);
2340     struct ite_raid_conf *meta;
2341     struct ar_softc *raid = NULL;
2342     int array, disk_number, count, retval = 0;
2343     u_int16_t *ptr;
2344
2345     if (!(meta = (struct ite_raid_conf *)
2346           malloc(sizeof(struct ite_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
2347         return ENOMEM;
2348
2349     if (ata_raid_rw(parent, ITE_LBA(parent),
2350                     meta, sizeof(struct ite_raid_conf), ATA_R_READ)) {
2351         if (testing || bootverbose)
2352             device_printf(parent, "ITE read metadata failed\n");
2353         goto ite_out;
2354     }
2355
2356     /* check if this is a ITE RAID struct */
2357     for (ptr = (u_int16_t *)meta->ite_id, count = 0;
2358          count < sizeof(meta->ite_id)/sizeof(uint16_t); count++)
2359         ptr[count] = be16toh(ptr[count]);
2360
2361     if (strncmp(meta->ite_id, ITE_MAGIC, strlen(ITE_MAGIC))) {
2362         if (testing || bootverbose)
2363             device_printf(parent, "ITE check1 failed\n");
2364         goto ite_out;
2365     }
2366
2367     if (testing || bootverbose)
2368         ata_raid_ite_print_meta(meta);
2369
2370     /* now convert ITE metadata into our generic form */
2371     for (array = 0; array < MAX_ARRAYS; array++) {
2372         if ((raid = raidp[array])) {
2373             if (raid->format != AR_F_ITE_RAID)
2374                 continue;
2375             if (raid->magic_0 != *((u_int64_t *)meta->timestamp_0))
2376                 continue;
2377         }
2378
2379         /* if we dont have a disks timestamp the RAID is invalidated */
2380         if (*((u_int64_t *)meta->timestamp_1) == 0)
2381             goto ite_out;
2382
2383         if (!raid) {
2384             raidp[array] = (struct ar_softc *)malloc(sizeof(struct ar_softc),
2385                                                      M_AR, M_NOWAIT | M_ZERO);
2386             if (!(raid = raidp[array])) {
2387                 device_printf(parent, "failed to allocate metadata storage\n");
2388                 goto ite_out;
2389             }
2390         }
2391
2392         switch (meta->type) {
2393         case ITE_T_RAID0:
2394             raid->type = AR_T_RAID0;
2395             raid->width = meta->array_width;
2396             raid->total_disks = meta->array_width;
2397             disk_number = meta->disk_number;
2398             break;
2399
2400         case ITE_T_RAID1:
2401             raid->type = AR_T_RAID1;
2402             raid->width = 1;
2403             raid->total_disks = 2;
2404             disk_number = meta->disk_number;
2405             break;
2406
2407         case ITE_T_RAID01:
2408             raid->type = AR_T_RAID01;
2409             raid->width = meta->array_width;
2410             raid->total_disks = 4;
2411             disk_number = ((meta->disk_number & 0x02) >> 1) |
2412                           ((meta->disk_number & 0x01) << 1);
2413             break;
2414
2415         case ITE_T_SPAN:
2416             raid->type = AR_T_SPAN;
2417             raid->width = 1;
2418             raid->total_disks = meta->array_width;
2419             disk_number = meta->disk_number;
2420             break;
2421
2422         default:
2423             device_printf(parent, "ITE unknown RAID type 0x%02x\n", meta->type);
2424             free(raidp[array], M_AR);
2425             raidp[array] = NULL;
2426             goto ite_out;
2427         }
2428
2429         raid->magic_0 = *((u_int64_t *)meta->timestamp_0);
2430         raid->format = AR_F_ITE_RAID;
2431         raid->generation = 0;
2432         raid->interleave = meta->stripe_sectors;
2433         raid->total_sectors = meta->total_sectors;
2434         raid->heads = 255;
2435         raid->sectors = 63;
2436         raid->cylinders = raid->total_sectors / (63 * 255);
2437         raid->offset_sectors = 0;
2438         raid->rebuild_lba = 0;
2439         raid->lun = array;
2440
2441         raid->disks[disk_number].dev = parent;
2442         raid->disks[disk_number].sectors = raid->total_sectors / raid->width;
2443         raid->disks[disk_number].flags = 
2444             (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE);
2445         ars->raid[raid->volume] = raid;
2446         ars->disk_number[raid->volume] = disk_number;
2447         retval = 1;
2448         break;
2449     }
2450 ite_out:
2451     free(meta, M_AR);
2452     return retval;
2453 }
2454
2455 /* JMicron Technology Corp Metadata */
2456 static int
2457 ata_raid_jmicron_read_meta(device_t dev, struct ar_softc **raidp)
2458 {
2459     struct ata_raid_subdisk *ars = device_get_softc(dev);
2460     device_t parent = device_get_parent(dev);
2461     struct jmicron_raid_conf *meta;
2462     struct ar_softc *raid = NULL;
2463     u_int16_t checksum, *ptr;
2464     u_int64_t disk_size;
2465     int count, array, disk, total_disks, retval = 0;
2466
2467     if (!(meta = (struct jmicron_raid_conf *)
2468           malloc(sizeof(struct jmicron_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
2469         return ENOMEM;
2470
2471     if (ata_raid_rw(parent, JMICRON_LBA(parent),
2472                     meta, sizeof(struct jmicron_raid_conf), ATA_R_READ)) {
2473         if (testing || bootverbose)
2474             device_printf(parent,
2475                           "JMicron read metadata failed\n");
2476     }
2477
2478     /* check for JMicron signature */
2479     if (strncmp(meta->signature, JMICRON_MAGIC, 2)) {
2480         if (testing || bootverbose)
2481             device_printf(parent, "JMicron check1 failed\n");
2482         goto jmicron_out;
2483     }
2484
2485     /* calculate checksum and compare for valid */
2486     for (checksum = 0, ptr = (u_int16_t *)meta, count = 0; count < 64; count++)
2487         checksum += *ptr++;
2488     if (checksum) {  
2489         if (testing || bootverbose)
2490             device_printf(parent, "JMicron check2 failed\n");
2491         goto jmicron_out;
2492     }
2493
2494     if (testing || bootverbose)
2495         ata_raid_jmicron_print_meta(meta);
2496
2497     /* now convert JMicron meta into our generic form */
2498     for (array = 0; array < MAX_ARRAYS; array++) {
2499 jmicron_next:
2500         if (!raidp[array]) {
2501             raidp[array] = 
2502                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
2503                                           M_NOWAIT | M_ZERO);
2504             if (!raidp[array]) {
2505                 device_printf(parent, "failed to allocate metadata storage\n");
2506                 goto jmicron_out;
2507             }
2508         }
2509         raid = raidp[array];
2510         if (raid->format && (raid->format != AR_F_JMICRON_RAID))
2511             continue;
2512
2513         for (total_disks = 0, disk = 0; disk < JM_MAX_DISKS; disk++) {
2514             if (meta->disks[disk]) {
2515                 if (raid->format == AR_F_JMICRON_RAID) {
2516                     if (bcmp(&meta->disks[disk], 
2517                         raid->disks[disk].serial, sizeof(u_int32_t))) {
2518                         array++;
2519                         goto jmicron_next;
2520                     }
2521                 }
2522                 else 
2523                     bcopy(&meta->disks[disk],
2524                           raid->disks[disk].serial, sizeof(u_int32_t));
2525                 total_disks++;
2526             }
2527         }
2528         /* handle spares XXX SOS */
2529
2530         switch (meta->type) {
2531         case JM_T_RAID0:
2532             raid->type = AR_T_RAID0;
2533             raid->width = total_disks;
2534             break;
2535
2536         case JM_T_RAID1:
2537             raid->type = AR_T_RAID1;
2538             raid->width = 1;
2539             break;
2540
2541         case JM_T_RAID01:
2542             raid->type = AR_T_RAID01;
2543             raid->width = total_disks / 2;
2544             break;
2545
2546         case JM_T_RAID5:
2547             raid->type = AR_T_RAID5;
2548             raid->width = total_disks;
2549             break;
2550
2551         case JM_T_JBOD:
2552             raid->type = AR_T_SPAN;
2553             raid->width = 1;
2554             break;
2555
2556         default:
2557             device_printf(parent,
2558                           "JMicron unknown RAID type 0x%02x\n", meta->type);
2559             free(raidp[array], M_AR);
2560             raidp[array] = NULL;
2561             goto jmicron_out;
2562         }
2563         disk_size = (meta->disk_sectors_high << 16) + meta->disk_sectors_low;
2564         raid->format = AR_F_JMICRON_RAID;
2565         strncpy(raid->name, meta->name, sizeof(meta->name));
2566         raid->generation = 0;
2567         raid->interleave = 2 << meta->stripe_shift;
2568         raid->total_disks = total_disks;
2569         raid->total_sectors = disk_size * (raid->width-(raid->type==AR_RAID5));
2570         raid->heads = 255;
2571         raid->sectors = 63;
2572         raid->cylinders = raid->total_sectors / (63 * 255);
2573         raid->offset_sectors = meta->offset * 16;
2574         raid->rebuild_lba = 0;
2575         raid->lun = array;
2576
2577         for (disk = 0; disk < raid->total_disks; disk++) {
2578             if (meta->disks[disk] == meta->disk_id) {
2579                 raid->disks[disk].dev = parent;
2580                 raid->disks[disk].sectors = disk_size;
2581                 raid->disks[disk].flags =
2582                     (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED);
2583                 ars->raid[raid->volume] = raid;
2584                 ars->disk_number[raid->volume] = disk;
2585                 retval = 1;
2586                 break;
2587             }
2588         }
2589         break;
2590     }
2591 jmicron_out:
2592     free(meta, M_AR);
2593     return retval;
2594 }
2595
2596 static int
2597 ata_raid_jmicron_write_meta(struct ar_softc *rdp)
2598 {
2599     struct jmicron_raid_conf *meta;
2600     u_int64_t disk_sectors;
2601     int disk, error = 0;
2602
2603     if (!(meta = (struct jmicron_raid_conf *)
2604           malloc(sizeof(struct jmicron_raid_conf), M_AR, M_NOWAIT | M_ZERO))) {
2605         printf("ar%d: failed to allocate metadata storage\n", rdp->lun);
2606         return ENOMEM;
2607     }
2608
2609     rdp->generation++;
2610     switch (rdp->type) {
2611     case AR_T_JBOD:
2612         meta->type = JM_T_JBOD;
2613         break;
2614
2615     case AR_T_RAID0:
2616         meta->type = JM_T_RAID0;
2617         break;
2618
2619     case AR_T_RAID1:
2620         meta->type = JM_T_RAID1;
2621         break;
2622
2623     case AR_T_RAID5:
2624         meta->type = JM_T_RAID5;
2625         break;
2626
2627     case AR_T_RAID01:
2628         meta->type = JM_T_RAID01;
2629         break;
2630
2631     default:
2632         free(meta, M_AR);
2633         return ENODEV;
2634     }
2635     bcopy(JMICRON_MAGIC, meta->signature, sizeof(JMICRON_MAGIC));
2636     meta->version = JMICRON_VERSION;
2637     meta->offset = rdp->offset_sectors / 16;
2638     disk_sectors = rdp->total_sectors / (rdp->width - (rdp->type == AR_RAID5));
2639     meta->disk_sectors_low = disk_sectors & 0xffff;
2640     meta->disk_sectors_high = disk_sectors >> 16;
2641     strncpy(meta->name, rdp->name, sizeof(meta->name));
2642     meta->stripe_shift = ffs(rdp->interleave) - 2;
2643
2644     for (disk = 0; disk < rdp->total_disks; disk++) {
2645         if (rdp->disks[disk].serial[0])
2646             bcopy(rdp->disks[disk].serial,&meta->disks[disk],sizeof(u_int32_t));
2647         else
2648             meta->disks[disk] = (u_int32_t)(uintptr_t)rdp->disks[disk].dev;
2649     }
2650
2651     for (disk = 0; disk < rdp->total_disks; disk++) {
2652         if (rdp->disks[disk].dev) {
2653             u_int16_t checksum = 0, *ptr;
2654             int count;
2655
2656             meta->disk_id = meta->disks[disk];
2657             meta->checksum = 0;
2658             for (ptr = (u_int16_t *)meta, count = 0; count < 64; count++)
2659                 checksum += *ptr++;
2660             meta->checksum -= checksum;
2661
2662             if (testing || bootverbose)
2663                 ata_raid_jmicron_print_meta(meta);
2664
2665             if (ata_raid_rw(rdp->disks[disk].dev,
2666                             JMICRON_LBA(rdp->disks[disk].dev),
2667                             meta, sizeof(struct jmicron_raid_conf),
2668                             ATA_R_WRITE | ATA_R_DIRECT)) {
2669                 device_printf(rdp->disks[disk].dev, "write metadata failed\n");
2670                 error = EIO;
2671             }
2672         }
2673     }
2674     /* handle spares XXX SOS */
2675
2676     free(meta, M_AR);
2677     return error;
2678 }
2679
2680 /* LSILogic V2 MegaRAID Metadata */
2681 static int
2682 ata_raid_lsiv2_read_meta(device_t dev, struct ar_softc **raidp)
2683 {
2684     struct ata_raid_subdisk *ars = device_get_softc(dev);
2685     device_t parent = device_get_parent(dev);
2686     struct lsiv2_raid_conf *meta;
2687     struct ar_softc *raid = NULL;
2688     int array, retval = 0;
2689
2690     if (!(meta = (struct lsiv2_raid_conf *)
2691           malloc(sizeof(struct lsiv2_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
2692         return ENOMEM;
2693
2694     if (ata_raid_rw(parent, LSIV2_LBA(parent),
2695                     meta, sizeof(struct lsiv2_raid_conf), ATA_R_READ)) {
2696         if (testing || bootverbose)
2697             device_printf(parent, "LSI (v2) read metadata failed\n");
2698         goto lsiv2_out;
2699     }
2700
2701     /* check if this is a LSI RAID struct */
2702     if (strncmp(meta->lsi_id, LSIV2_MAGIC, strlen(LSIV2_MAGIC))) {
2703         if (testing || bootverbose)
2704             device_printf(parent, "LSI (v2) check1 failed\n");
2705         goto lsiv2_out;
2706     }
2707
2708     if (testing || bootverbose)
2709         ata_raid_lsiv2_print_meta(meta);
2710
2711     /* now convert LSI (v2) config meta into our generic form */
2712     for (array = 0; array < MAX_ARRAYS; array++) {
2713         int raid_entry, conf_entry;
2714
2715         if (!raidp[array + meta->raid_number]) {
2716             raidp[array + meta->raid_number] = 
2717                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
2718                                           M_NOWAIT | M_ZERO);
2719             if (!raidp[array + meta->raid_number]) {
2720                 device_printf(parent, "failed to allocate metadata storage\n");
2721                 goto lsiv2_out;
2722             }
2723         }
2724         raid = raidp[array + meta->raid_number];
2725         if (raid->format && (raid->format != AR_F_LSIV2_RAID))
2726             continue;
2727
2728         if (raid->magic_0 && 
2729             ((raid->magic_0 != meta->timestamp) ||
2730              (raid->magic_1 != meta->raid_number)))
2731             continue;
2732
2733         array += meta->raid_number;
2734
2735         raid_entry = meta->raid_number;
2736         conf_entry = (meta->configs[raid_entry].raid.config_offset >> 4) +
2737                      meta->disk_number - 1;
2738
2739         switch (meta->configs[raid_entry].raid.type) {
2740         case LSIV2_T_RAID0:
2741             raid->magic_0 = meta->timestamp;
2742             raid->magic_1 = meta->raid_number;
2743             raid->type = AR_T_RAID0;
2744             raid->interleave = meta->configs[raid_entry].raid.stripe_sectors;
2745             raid->width = meta->configs[raid_entry].raid.array_width; 
2746             break;
2747
2748         case LSIV2_T_RAID1:
2749             raid->magic_0 = meta->timestamp;
2750             raid->magic_1 = meta->raid_number;
2751             raid->type = AR_T_RAID1;
2752             raid->width = meta->configs[raid_entry].raid.array_width; 
2753             break;
2754             
2755         case LSIV2_T_RAID0 | LSIV2_T_RAID1:
2756             raid->magic_0 = meta->timestamp;
2757             raid->magic_1 = meta->raid_number;
2758             raid->type = AR_T_RAID01;
2759             raid->interleave = meta->configs[raid_entry].raid.stripe_sectors;
2760             raid->width = meta->configs[raid_entry].raid.array_width; 
2761             break;
2762
2763         default:
2764             device_printf(parent, "LSI v2 unknown RAID type 0x%02x\n",
2765                           meta->configs[raid_entry].raid.type);
2766             free(raidp[array], M_AR);
2767             raidp[array] = NULL;
2768             goto lsiv2_out;
2769         }
2770
2771         raid->format = AR_F_LSIV2_RAID;
2772         raid->generation = 0;
2773         raid->total_disks = meta->configs[raid_entry].raid.disk_count;
2774         raid->total_sectors = meta->configs[raid_entry].raid.total_sectors;
2775         raid->heads = 255;
2776         raid->sectors = 63;
2777         raid->cylinders = raid->total_sectors / (63 * 255);
2778         raid->offset_sectors = 0;
2779         raid->rebuild_lba = 0;
2780         raid->lun = array;
2781
2782         if (meta->configs[conf_entry].disk.device != LSIV2_D_NONE) {
2783             raid->disks[meta->disk_number].dev = parent;
2784             raid->disks[meta->disk_number].sectors = 
2785                 meta->configs[conf_entry].disk.disk_sectors;
2786             raid->disks[meta->disk_number].flags = 
2787                 (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED);
2788             ars->raid[raid->volume] = raid;
2789             ars->disk_number[raid->volume] = meta->disk_number;
2790             retval = 1;
2791         }
2792         else
2793             raid->disks[meta->disk_number].flags &= ~AR_DF_ONLINE;
2794
2795         break;
2796     }
2797
2798 lsiv2_out:
2799     free(meta, M_AR);
2800     return retval;
2801 }
2802
2803 /* LSILogic V3 MegaRAID Metadata */
2804 static int
2805 ata_raid_lsiv3_read_meta(device_t dev, struct ar_softc **raidp)
2806 {
2807     struct ata_raid_subdisk *ars = device_get_softc(dev);
2808     device_t parent = device_get_parent(dev);
2809     struct lsiv3_raid_conf *meta;
2810     struct ar_softc *raid = NULL;
2811     u_int8_t checksum, *ptr;
2812     int array, entry, count, disk_number, retval = 0;
2813
2814     if (!(meta = (struct lsiv3_raid_conf *)
2815           malloc(sizeof(struct lsiv3_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
2816         return ENOMEM;
2817
2818     if (ata_raid_rw(parent, LSIV3_LBA(parent),
2819                     meta, sizeof(struct lsiv3_raid_conf), ATA_R_READ)) {
2820         if (testing || bootverbose)
2821             device_printf(parent, "LSI (v3) read metadata failed\n");
2822         goto lsiv3_out;
2823     }
2824
2825     /* check if this is a LSI RAID struct */
2826     if (strncmp(meta->lsi_id, LSIV3_MAGIC, strlen(LSIV3_MAGIC))) {
2827         if (testing || bootverbose)
2828             device_printf(parent, "LSI (v3) check1 failed\n");
2829         goto lsiv3_out;
2830     }
2831
2832     /* check if the checksum is OK */
2833     for (checksum = 0, ptr = meta->lsi_id, count = 0; count < 512; count++)
2834         checksum += *ptr++;
2835     if (checksum) {  
2836         if (testing || bootverbose)
2837             device_printf(parent, "LSI (v3) check2 failed\n");
2838         goto lsiv3_out;
2839     }
2840
2841     if (testing || bootverbose)
2842         ata_raid_lsiv3_print_meta(meta);
2843
2844     /* now convert LSI (v3) config meta into our generic form */
2845     for (array = 0, entry = 0; array < MAX_ARRAYS && entry < 8;) {
2846         if (!raidp[array]) {
2847             raidp[array] = 
2848                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
2849                                           M_NOWAIT | M_ZERO);
2850             if (!raidp[array]) {
2851                 device_printf(parent, "failed to allocate metadata storage\n");
2852                 goto lsiv3_out;
2853             }
2854         }
2855         raid = raidp[array];
2856         if (raid->format && (raid->format != AR_F_LSIV3_RAID)) {
2857             array++;
2858             continue;
2859         }
2860
2861         if ((raid->format == AR_F_LSIV3_RAID) &&
2862             (raid->magic_0 != meta->timestamp)) {
2863             array++;
2864             continue;
2865         }
2866
2867         switch (meta->raid[entry].total_disks) {
2868         case 0:
2869             entry++;
2870             continue;
2871         case 1:
2872             if (meta->raid[entry].device == meta->device) {
2873                 disk_number = 0;
2874                 break;
2875             }
2876             if (raid->format)
2877                 array++;
2878             entry++;
2879             continue;
2880         case 2:
2881             disk_number = (meta->device & (LSIV3_D_DEVICE|LSIV3_D_CHANNEL))?1:0;
2882             break;
2883         default:
2884             device_printf(parent, "lsiv3 > 2 disk support untested!!\n");
2885             disk_number = (meta->device & LSIV3_D_DEVICE ? 1 : 0) +
2886                           (meta->device & LSIV3_D_CHANNEL ? 2 : 0);
2887             break;
2888         }
2889
2890         switch (meta->raid[entry].type) {
2891         case LSIV3_T_RAID0:
2892             raid->type = AR_T_RAID0;
2893             raid->width = meta->raid[entry].total_disks;
2894             break;
2895
2896         case LSIV3_T_RAID1:
2897             raid->type = AR_T_RAID1;
2898             raid->width = meta->raid[entry].array_width;
2899             break;
2900
2901         default:
2902             device_printf(parent, "LSI v3 unknown RAID type 0x%02x\n",
2903                           meta->raid[entry].type);
2904             free(raidp[array], M_AR);
2905             raidp[array] = NULL;
2906             entry++;
2907             continue;
2908         }
2909
2910         raid->magic_0 = meta->timestamp;
2911         raid->format = AR_F_LSIV3_RAID;
2912         raid->generation = 0;
2913         raid->interleave = meta->raid[entry].stripe_pages * 8;
2914         raid->total_disks = meta->raid[entry].total_disks;
2915         raid->total_sectors = raid->width * meta->raid[entry].sectors;
2916         raid->heads = 255;
2917         raid->sectors = 63;
2918         raid->cylinders = raid->total_sectors / (63 * 255);
2919         raid->offset_sectors = meta->raid[entry].offset;
2920         raid->rebuild_lba = 0;
2921         raid->lun = array;
2922
2923         raid->disks[disk_number].dev = parent;
2924         raid->disks[disk_number].sectors = raid->total_sectors / raid->width;
2925         raid->disks[disk_number].flags = 
2926             (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE);
2927         ars->raid[raid->volume] = raid;
2928         ars->disk_number[raid->volume] = disk_number;
2929         retval = 1;
2930         entry++;
2931         array++;
2932     }
2933
2934 lsiv3_out:
2935     free(meta, M_AR);
2936     return retval;
2937 }
2938
2939 /* nVidia MediaShield Metadata */
2940 static int
2941 ata_raid_nvidia_read_meta(device_t dev, struct ar_softc **raidp)
2942 {
2943     struct ata_raid_subdisk *ars = device_get_softc(dev);
2944     device_t parent = device_get_parent(dev);
2945     struct nvidia_raid_conf *meta;
2946     struct ar_softc *raid = NULL;
2947     u_int32_t checksum, *ptr;
2948     int array, count, retval = 0;
2949
2950     if (!(meta = (struct nvidia_raid_conf *)
2951           malloc(sizeof(struct nvidia_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
2952         return ENOMEM;
2953
2954     if (ata_raid_rw(parent, NVIDIA_LBA(parent),
2955                     meta, sizeof(struct nvidia_raid_conf), ATA_R_READ)) {
2956         if (testing || bootverbose)
2957             device_printf(parent, "nVidia read metadata failed\n");
2958         goto nvidia_out;
2959     }
2960
2961     /* check if this is a nVidia RAID struct */
2962     if (strncmp(meta->nvidia_id, NV_MAGIC, strlen(NV_MAGIC))) {
2963         if (testing || bootverbose)
2964             device_printf(parent, "nVidia check1 failed\n");
2965         goto nvidia_out;
2966     }
2967
2968     /* check if the checksum is OK */
2969     for (checksum = 0, ptr = (u_int32_t*)meta, count = 0; 
2970          count < meta->config_size; count++)
2971         checksum += *ptr++;
2972     if (checksum) {  
2973         if (testing || bootverbose)
2974             device_printf(parent, "nVidia check2 failed\n");
2975         goto nvidia_out;
2976     }
2977
2978     if (testing || bootverbose)
2979         ata_raid_nvidia_print_meta(meta);
2980
2981     /* now convert nVidia meta into our generic form */
2982     for (array = 0; array < MAX_ARRAYS; array++) {
2983         if (!raidp[array]) {
2984             raidp[array] =
2985                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
2986                                           M_NOWAIT | M_ZERO);
2987             if (!raidp[array]) {
2988                 device_printf(parent, "failed to allocate metadata storage\n");
2989                 goto nvidia_out;
2990             }
2991         }
2992         raid = raidp[array];
2993         if (raid->format && (raid->format != AR_F_NVIDIA_RAID))
2994             continue;
2995
2996         if (raid->format == AR_F_NVIDIA_RAID &&
2997             ((raid->magic_0 != meta->magic_1) ||
2998              (raid->magic_1 != meta->magic_2))) {
2999             continue;
3000         }
3001
3002         switch (meta->type) {
3003         case NV_T_SPAN:
3004             raid->type = AR_T_SPAN;
3005             break;
3006
3007         case NV_T_RAID0: 
3008             raid->type = AR_T_RAID0;
3009             break;
3010
3011         case NV_T_RAID1:
3012             raid->type = AR_T_RAID1;
3013             break;
3014
3015         case NV_T_RAID5:
3016             raid->type = AR_T_RAID5;
3017             break;
3018
3019         case NV_T_RAID01:
3020             raid->type = AR_T_RAID01;
3021             break;
3022
3023         default:
3024             device_printf(parent, "nVidia unknown RAID type 0x%02x\n",
3025                           meta->type);
3026             free(raidp[array], M_AR);
3027             raidp[array] = NULL;
3028             goto nvidia_out;
3029         }
3030         raid->magic_0 = meta->magic_1;
3031         raid->magic_1 = meta->magic_2;
3032         raid->format = AR_F_NVIDIA_RAID;
3033         raid->generation = 0;
3034         raid->interleave = meta->stripe_sectors;
3035         raid->width = meta->array_width;
3036         raid->total_disks = meta->total_disks;
3037         raid->total_sectors = meta->total_sectors;
3038         raid->heads = 255;
3039         raid->sectors = 63;
3040         raid->cylinders = raid->total_sectors / (63 * 255);
3041         raid->offset_sectors = 0;
3042         raid->rebuild_lba = meta->rebuild_lba;
3043         raid->lun = array;
3044         raid->status = AR_S_READY;
3045         if (meta->status & NV_S_DEGRADED)
3046             raid->status |= AR_S_DEGRADED;
3047
3048         raid->disks[meta->disk_number].dev = parent;
3049         raid->disks[meta->disk_number].sectors =
3050             raid->total_sectors / raid->width;
3051         raid->disks[meta->disk_number].flags =
3052             (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE);
3053         ars->raid[raid->volume] = raid;
3054         ars->disk_number[raid->volume] = meta->disk_number;
3055         retval = 1;
3056         break;
3057     }
3058
3059 nvidia_out:
3060     free(meta, M_AR);
3061     return retval;
3062 }
3063
3064 /* Promise FastTrak Metadata */
3065 static int
3066 ata_raid_promise_read_meta(device_t dev, struct ar_softc **raidp, int native)
3067 {
3068     struct ata_raid_subdisk *ars = device_get_softc(dev);
3069     device_t parent = device_get_parent(dev);
3070     struct promise_raid_conf *meta;
3071     struct ar_softc *raid;
3072     u_int32_t checksum, *ptr;
3073     int array, count, disk, disksum = 0, retval = 0; 
3074
3075     if (!(meta = (struct promise_raid_conf *)
3076           malloc(sizeof(struct promise_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
3077         return ENOMEM;
3078
3079     if (ata_raid_rw(parent, PROMISE_LBA(parent),
3080                     meta, sizeof(struct promise_raid_conf), ATA_R_READ)) {
3081         if (testing || bootverbose)
3082             device_printf(parent, "%s read metadata failed\n",
3083                           native ? "FreeBSD" : "Promise");
3084         goto promise_out;
3085     }
3086
3087     /* check the signature */
3088     if (native) {
3089         if (strncmp(meta->promise_id, ATA_MAGIC, strlen(ATA_MAGIC))) {
3090             if (testing || bootverbose)
3091                 device_printf(parent, "FreeBSD check1 failed\n");
3092             goto promise_out;
3093         }
3094     }
3095     else {
3096         if (strncmp(meta->promise_id, PR_MAGIC, strlen(PR_MAGIC))) {
3097             if (testing || bootverbose)
3098                 device_printf(parent, "Promise check1 failed\n");
3099             goto promise_out;
3100         }
3101     }
3102
3103     /* check if the checksum is OK */
3104     for (checksum = 0, ptr = (u_int32_t *)meta, count = 0; count < 511; count++)
3105         checksum += *ptr++;
3106     if (checksum != *ptr) {  
3107         if (testing || bootverbose)
3108             device_printf(parent, "%s check2 failed\n",
3109                           native ? "FreeBSD" : "Promise");           
3110         goto promise_out;
3111     }
3112
3113     /* check on disk integrity status */
3114     if (meta->raid.integrity != PR_I_VALID) {
3115         if (testing || bootverbose)
3116             device_printf(parent, "%s check3 failed\n",
3117                           native ? "FreeBSD" : "Promise");           
3118         goto promise_out;
3119     }
3120
3121     if (testing || bootverbose)
3122         ata_raid_promise_print_meta(meta);
3123
3124     /* now convert Promise metadata into our generic form */
3125     for (array = 0; array < MAX_ARRAYS; array++) {
3126         if (!raidp[array]) {
3127             raidp[array] = 
3128                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
3129                                           M_NOWAIT | M_ZERO);
3130             if (!raidp[array]) {
3131                 device_printf(parent, "failed to allocate metadata storage\n");
3132                 goto promise_out;
3133             }
3134         }
3135         raid = raidp[array];
3136         if (raid->format &&
3137             (raid->format != (native ? AR_F_FREEBSD_RAID : AR_F_PROMISE_RAID)))
3138             continue;
3139
3140         if ((raid->format == (native ? AR_F_FREEBSD_RAID : AR_F_PROMISE_RAID))&&
3141             !(meta->raid.magic_1 == (raid->magic_1)))
3142             continue;
3143
3144         /* update our knowledge about the array config based on generation */
3145         if (!meta->raid.generation || meta->raid.generation > raid->generation){
3146             switch (meta->raid.type) {
3147             case PR_T_SPAN:
3148                 raid->type = AR_T_SPAN;
3149                 break;
3150
3151             case PR_T_JBOD:
3152                 raid->type = AR_T_JBOD;
3153                 break;
3154
3155             case PR_T_RAID0:
3156                 raid->type = AR_T_RAID0;
3157                 break;
3158
3159             case PR_T_RAID1:
3160                 raid->type = AR_T_RAID1;
3161                 if (meta->raid.array_width > 1)
3162                     raid->type = AR_T_RAID01;
3163                 break;
3164
3165             case PR_T_RAID5:
3166                 raid->type = AR_T_RAID5;
3167                 break;
3168
3169             default:
3170                 device_printf(parent, "%s unknown RAID type 0x%02x\n",
3171                               native ? "FreeBSD" : "Promise", meta->raid.type);
3172                 free(raidp[array], M_AR);
3173                 raidp[array] = NULL;
3174                 goto promise_out;
3175             }
3176             raid->magic_1 = meta->raid.magic_1;
3177             raid->format = (native ? AR_F_FREEBSD_RAID : AR_F_PROMISE_RAID);
3178             raid->generation = meta->raid.generation;
3179             raid->interleave = 1 << meta->raid.stripe_shift;
3180             raid->width = meta->raid.array_width;
3181             raid->total_disks = meta->raid.total_disks;
3182             raid->heads = meta->raid.heads + 1;
3183             raid->sectors = meta->raid.sectors;
3184             raid->cylinders = meta->raid.cylinders + 1;
3185             raid->total_sectors = meta->raid.total_sectors;
3186             raid->offset_sectors = 0;
3187             raid->rebuild_lba = meta->raid.rebuild_lba;
3188             raid->lun = array;
3189             if ((meta->raid.status &
3190                  (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY)) ==
3191                 (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY)) {
3192                 raid->status |= AR_S_READY;
3193                 if (meta->raid.status & PR_S_DEGRADED)
3194                     raid->status |= AR_S_DEGRADED;
3195             }
3196             else
3197                 raid->status &= ~AR_S_READY;
3198
3199             /* convert disk flags to our internal types */
3200             for (disk = 0; disk < meta->raid.total_disks; disk++) {
3201                 raid->disks[disk].dev = NULL;
3202                 raid->disks[disk].flags = 0;
3203                 *((u_int64_t *)(raid->disks[disk].serial)) = 
3204                     meta->raid.disk[disk].magic_0;
3205                 disksum += meta->raid.disk[disk].flags;
3206                 if (meta->raid.disk[disk].flags & PR_F_ONLINE)
3207                     raid->disks[disk].flags |= AR_DF_ONLINE;
3208                 if (meta->raid.disk[disk].flags & PR_F_ASSIGNED)
3209                     raid->disks[disk].flags |= AR_DF_ASSIGNED;
3210                 if (meta->raid.disk[disk].flags & PR_F_SPARE) {
3211                     raid->disks[disk].flags &= ~(AR_DF_ONLINE | AR_DF_ASSIGNED);
3212                     raid->disks[disk].flags |= AR_DF_SPARE;
3213                 }
3214                 if (meta->raid.disk[disk].flags & (PR_F_REDIR | PR_F_DOWN))
3215                     raid->disks[disk].flags &= ~AR_DF_ONLINE;
3216             }
3217             if (!disksum) {
3218                 device_printf(parent, "%s subdisks has no flags\n",
3219                               native ? "FreeBSD" : "Promise");
3220                 free(raidp[array], M_AR);
3221                 raidp[array] = NULL;
3222                 goto promise_out;
3223             }
3224         }
3225         if (meta->raid.generation >= raid->generation) {
3226             int disk_number = meta->raid.disk_number;
3227
3228             if (raid->disks[disk_number].flags && (meta->magic_0 ==
3229                 *((u_int64_t *)(raid->disks[disk_number].serial)))) {
3230                 raid->disks[disk_number].dev = parent;
3231                 raid->disks[disk_number].flags |= AR_DF_PRESENT;
3232                 raid->disks[disk_number].sectors = meta->raid.disk_sectors;
3233                 if ((raid->disks[disk_number].flags &
3234                     (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE)) ==
3235                     (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE)) {
3236                     ars->raid[raid->volume] = raid;
3237                     ars->disk_number[raid->volume] = disk_number;
3238                     retval = 1;
3239                 }
3240             }
3241         }
3242         break;
3243     }
3244
3245 promise_out:
3246     free(meta, M_AR);
3247     return retval;
3248 }
3249
3250 static int
3251 ata_raid_promise_write_meta(struct ar_softc *rdp)
3252 {
3253     struct promise_raid_conf *meta;
3254     struct timeval timestamp;
3255     u_int32_t *ckptr;
3256     int count, disk, drive, error = 0;
3257
3258     if (!(meta = (struct promise_raid_conf *)
3259           malloc(sizeof(struct promise_raid_conf), M_AR, M_NOWAIT))) {
3260         printf("ar%d: failed to allocate metadata storage\n", rdp->lun);
3261         return ENOMEM;
3262     }
3263
3264     rdp->generation++;
3265     microtime(&timestamp);
3266
3267     for (disk = 0; disk < rdp->total_disks; disk++) {
3268         for (count = 0; count < sizeof(struct promise_raid_conf); count++)
3269             *(((u_int8_t *)meta) + count) = 255 - (count % 256);
3270         meta->dummy_0 = 0x00020000;
3271         meta->raid.disk_number = disk;
3272
3273         if (rdp->disks[disk].dev) {
3274             struct ata_device *atadev = device_get_softc(rdp->disks[disk].dev);
3275             struct ata_channel *ch = 
3276                 device_get_softc(device_get_parent(rdp->disks[disk].dev));
3277
3278             meta->raid.channel = ch->unit;
3279             meta->raid.device = ATA_DEV(atadev->unit);
3280             meta->raid.disk_sectors = rdp->disks[disk].sectors;
3281             meta->raid.disk_offset = rdp->offset_sectors;
3282         }
3283         else {
3284             meta->raid.channel = 0;
3285             meta->raid.device = 0;
3286             meta->raid.disk_sectors = 0;
3287             meta->raid.disk_offset = 0;
3288         }
3289         meta->magic_0 = PR_MAGIC0(meta->raid) | timestamp.tv_sec;
3290         meta->magic_1 = timestamp.tv_sec >> 16;
3291         meta->magic_2 = timestamp.tv_sec;
3292         meta->raid.integrity = PR_I_VALID;
3293         meta->raid.magic_0 = meta->magic_0;
3294         meta->raid.rebuild_lba = rdp->rebuild_lba;
3295         meta->raid.generation = rdp->generation;
3296
3297         if (rdp->status & AR_S_READY) {
3298             meta->raid.flags = (PR_F_VALID | PR_F_ASSIGNED | PR_F_ONLINE);
3299             meta->raid.status = 
3300                 (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY);
3301             if (rdp->status & AR_S_DEGRADED)
3302                 meta->raid.status |= PR_S_DEGRADED;
3303             else
3304                 meta->raid.status |= PR_S_FUNCTIONAL;
3305         }
3306         else {
3307             meta->raid.flags = PR_F_DOWN;
3308             meta->raid.status = 0;
3309         }
3310
3311         switch (rdp->type) {
3312         case AR_T_RAID0:
3313             meta->raid.type = PR_T_RAID0;
3314             break;
3315         case AR_T_RAID1:
3316             meta->raid.type = PR_T_RAID1;
3317             break;
3318         case AR_T_RAID01:
3319             meta->raid.type = PR_T_RAID1;
3320             break;
3321         case AR_T_RAID5:
3322             meta->raid.type = PR_T_RAID5;
3323             break;
3324         case AR_T_SPAN:
3325             meta->raid.type = PR_T_SPAN;
3326             break;
3327         case AR_T_JBOD:
3328             meta->raid.type = PR_T_JBOD;
3329             break;
3330         default:
3331             free(meta, M_AR);
3332             return ENODEV;
3333         }
3334
3335         meta->raid.total_disks = rdp->total_disks;
3336         meta->raid.stripe_shift = ffs(rdp->interleave) - 1;
3337         meta->raid.array_width = rdp->width;
3338         meta->raid.array_number = rdp->lun;
3339         meta->raid.total_sectors = rdp->total_sectors;
3340         meta->raid.cylinders = rdp->cylinders - 1;
3341         meta->raid.heads = rdp->heads - 1;
3342         meta->raid.sectors = rdp->sectors;
3343         meta->raid.magic_1 = (u_int64_t)meta->magic_2<<16 | meta->magic_1;
3344
3345         bzero(&meta->raid.disk, 8 * 12);
3346         for (drive = 0; drive < rdp->total_disks; drive++) {
3347             meta->raid.disk[drive].flags = 0;
3348             if (rdp->disks[drive].flags & AR_DF_PRESENT)
3349                 meta->raid.disk[drive].flags |= PR_F_VALID;
3350             if (rdp->disks[drive].flags & AR_DF_ASSIGNED)
3351                 meta->raid.disk[drive].flags |= PR_F_ASSIGNED;
3352             if (rdp->disks[drive].flags & AR_DF_ONLINE)
3353                 meta->raid.disk[drive].flags |= PR_F_ONLINE;
3354             else
3355                 if (rdp->disks[drive].flags & AR_DF_PRESENT)
3356                     meta->raid.disk[drive].flags = (PR_F_REDIR | PR_F_DOWN);
3357             if (rdp->disks[drive].flags & AR_DF_SPARE)
3358                 meta->raid.disk[drive].flags |= PR_F_SPARE;
3359             meta->raid.disk[drive].dummy_0 = 0x0;
3360             if (rdp->disks[drive].dev) {
3361                 struct ata_channel *ch = 
3362                     device_get_softc(device_get_parent(rdp->disks[drive].dev));
3363                 struct ata_device *atadev =
3364                     device_get_softc(rdp->disks[drive].dev);
3365
3366                 meta->raid.disk[drive].channel = ch->unit;
3367                 meta->raid.disk[drive].device = ATA_DEV(atadev->unit);
3368             }
3369             meta->raid.disk[drive].magic_0 =
3370                 PR_MAGIC0(meta->raid.disk[drive]) | timestamp.tv_sec;
3371         }
3372
3373         if (rdp->disks[disk].dev) {
3374             if ((rdp->disks[disk].flags & (AR_DF_PRESENT | AR_DF_ONLINE)) ==
3375                 (AR_DF_PRESENT | AR_DF_ONLINE)) {
3376                 if (rdp->format == AR_F_FREEBSD_RAID)
3377                     bcopy(ATA_MAGIC, meta->promise_id, sizeof(ATA_MAGIC));
3378                 else
3379                     bcopy(PR_MAGIC, meta->promise_id, sizeof(PR_MAGIC));
3380             }
3381             else
3382                 bzero(meta->promise_id, sizeof(meta->promise_id));
3383             meta->checksum = 0;
3384             for (ckptr = (int32_t *)meta, count = 0; count < 511; count++)
3385                 meta->checksum += *ckptr++;
3386             if (testing || bootverbose)
3387                 ata_raid_promise_print_meta(meta);
3388             if (ata_raid_rw(rdp->disks[disk].dev,
3389                             PROMISE_LBA(rdp->disks[disk].dev),
3390                             meta, sizeof(struct promise_raid_conf),
3391                             ATA_R_WRITE | ATA_R_DIRECT)) {
3392                 device_printf(rdp->disks[disk].dev, "write metadata failed\n");
3393                 error = EIO;
3394             }
3395         }
3396     }
3397     free(meta, M_AR);
3398     return error;
3399 }
3400
3401 /* Silicon Image Medley Metadata */
3402 static int
3403 ata_raid_sii_read_meta(device_t dev, struct ar_softc **raidp)
3404 {
3405     struct ata_raid_subdisk *ars = device_get_softc(dev);
3406     device_t parent = device_get_parent(dev);
3407     struct sii_raid_conf *meta;
3408     struct ar_softc *raid = NULL;
3409     u_int16_t checksum, *ptr;
3410     int array, count, disk, retval = 0;
3411
3412     if (!(meta = (struct sii_raid_conf *)
3413           malloc(sizeof(struct sii_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
3414         return ENOMEM;
3415
3416     if (ata_raid_rw(parent, SII_LBA(parent),
3417                     meta, sizeof(struct sii_raid_conf), ATA_R_READ)) {
3418         if (testing || bootverbose)
3419             device_printf(parent, "Silicon Image read metadata failed\n");
3420         goto sii_out;
3421     }
3422
3423     /* check if this is a Silicon Image (Medley) RAID struct */
3424     for (checksum = 0, ptr = (u_int16_t *)meta, count = 0; count < 160; count++)
3425         checksum += *ptr++;
3426     if (checksum) {  
3427         if (testing || bootverbose)
3428             device_printf(parent, "Silicon Image check1 failed\n");
3429         goto sii_out;
3430     }
3431
3432     for (checksum = 0, ptr = (u_int16_t *)meta, count = 0; count < 256; count++)
3433         checksum += *ptr++;
3434     if (checksum != meta->checksum_1) {  
3435         if (testing || bootverbose)
3436             device_printf(parent, "Silicon Image check2 failed\n");          
3437         goto sii_out;
3438     }
3439
3440     /* check verison */
3441     if (meta->version_major != 0x0002 ||
3442         (meta->version_minor != 0x0000 && meta->version_minor != 0x0001)) {
3443         if (testing || bootverbose)
3444             device_printf(parent, "Silicon Image check3 failed\n");          
3445         goto sii_out;
3446     }
3447
3448     if (testing || bootverbose)
3449         ata_raid_sii_print_meta(meta);
3450
3451     /* now convert Silicon Image meta into our generic form */
3452     for (array = 0; array < MAX_ARRAYS; array++) {
3453         if (!raidp[array]) {
3454             raidp[array] = 
3455                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
3456                                           M_NOWAIT | M_ZERO);
3457             if (!raidp[array]) {
3458                 device_printf(parent, "failed to allocate metadata storage\n");
3459                 goto sii_out;
3460             }
3461         }
3462         raid = raidp[array];
3463         if (raid->format && (raid->format != AR_F_SII_RAID))
3464             continue;
3465
3466         if (raid->format == AR_F_SII_RAID &&
3467             (raid->magic_0 != *((u_int64_t *)meta->timestamp))) {
3468             continue;
3469         }
3470
3471         /* update our knowledge about the array config based on generation */
3472         if (!meta->generation || meta->generation > raid->generation) {
3473             switch (meta->type) {
3474             case SII_T_RAID0:
3475                 raid->type = AR_T_RAID0;
3476                 break;
3477
3478             case SII_T_RAID1:
3479                 raid->type = AR_T_RAID1;
3480                 break;
3481
3482             case SII_T_RAID01:
3483                 raid->type = AR_T_RAID01;
3484                 break;
3485
3486             case SII_T_SPARE:
3487                 device_printf(parent, "Silicon Image SPARE disk\n");
3488                 free(raidp[array], M_AR);
3489                 raidp[array] = NULL;
3490                 goto sii_out;
3491
3492             default:
3493                 device_printf(parent,"Silicon Image unknown RAID type 0x%02x\n",
3494                               meta->type);
3495                 free(raidp[array], M_AR);
3496                 raidp[array] = NULL;
3497                 goto sii_out;
3498             }
3499             raid->magic_0 = *((u_int64_t *)meta->timestamp);
3500             raid->format = AR_F_SII_RAID;
3501             raid->generation = meta->generation;
3502             raid->interleave = meta->stripe_sectors;
3503             raid->width = (meta->raid0_disks != 0xff) ? meta->raid0_disks : 1;
3504             raid->total_disks = 
3505                 ((meta->raid0_disks != 0xff) ? meta->raid0_disks : 0) +
3506                 ((meta->raid1_disks != 0xff) ? meta->raid1_disks : 0);
3507             raid->total_sectors = meta->total_sectors;
3508             raid->heads = 255;
3509             raid->sectors = 63;
3510             raid->cylinders = raid->total_sectors / (63 * 255);
3511             raid->offset_sectors = 0;
3512             raid->rebuild_lba = meta->rebuild_lba;
3513             raid->lun = array;
3514             strncpy(raid->name, meta->name,
3515                     min(sizeof(raid->name), sizeof(meta->name)));
3516
3517             /* clear out any old info */
3518             if (raid->generation) {
3519                 for (disk = 0; disk < raid->total_disks; disk++) {
3520                     raid->disks[disk].dev = NULL;
3521                     raid->disks[disk].flags = 0;
3522                 }
3523             }
3524         }
3525         if (meta->generation >= raid->generation) {
3526             /* XXX SOS add check for the right physical disk by serial# */
3527             if (meta->status & SII_S_READY) {
3528                 int disk_number = (raid->type == AR_T_RAID01) ?
3529                     meta->raid1_ident + (meta->raid0_ident << 1) :
3530                     meta->disk_number;
3531
3532                 raid->disks[disk_number].dev = parent;
3533                 raid->disks[disk_number].sectors = 
3534                     raid->total_sectors / raid->width;
3535                 raid->disks[disk_number].flags =
3536                     (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED);
3537                 ars->raid[raid->volume] = raid;
3538                 ars->disk_number[raid->volume] = disk_number;
3539                 retval = 1;
3540             }
3541         }
3542         break;
3543     }
3544
3545 sii_out:
3546     free(meta, M_AR);
3547     return retval;
3548 }
3549
3550 /* Silicon Integrated Systems Metadata */
3551 static int
3552 ata_raid_sis_read_meta(device_t dev, struct ar_softc **raidp)
3553 {
3554     struct ata_raid_subdisk *ars = device_get_softc(dev);
3555     device_t parent = device_get_parent(dev);
3556     struct sis_raid_conf *meta;
3557     struct ar_softc *raid = NULL;
3558     int array, disk_number, drive, retval = 0;
3559
3560     if (!(meta = (struct sis_raid_conf *)
3561           malloc(sizeof(struct sis_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
3562         return ENOMEM;
3563
3564     if (ata_raid_rw(parent, SIS_LBA(parent),
3565                     meta, sizeof(struct sis_raid_conf), ATA_R_READ)) {
3566         if (testing || bootverbose)
3567             device_printf(parent,
3568                           "Silicon Integrated Systems read metadata failed\n");
3569     }
3570
3571     /* check for SiS magic */
3572     if (meta->magic != SIS_MAGIC) {
3573         if (testing || bootverbose)
3574             device_printf(parent,
3575                           "Silicon Integrated Systems check1 failed\n");
3576         goto sis_out;
3577     }
3578
3579     if (testing || bootverbose)
3580         ata_raid_sis_print_meta(meta);
3581
3582     /* now convert SiS meta into our generic form */
3583     for (array = 0; array < MAX_ARRAYS; array++) {
3584         if (!raidp[array]) {
3585             raidp[array] = 
3586                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
3587                                           M_NOWAIT | M_ZERO);
3588             if (!raidp[array]) {
3589                 device_printf(parent, "failed to allocate metadata storage\n");
3590                 goto sis_out;
3591             }
3592         }
3593
3594         raid = raidp[array];
3595         if (raid->format && (raid->format != AR_F_SIS_RAID))
3596             continue;
3597
3598         if ((raid->format == AR_F_SIS_RAID) &&
3599             ((raid->magic_0 != meta->controller_pci_id) ||
3600              (raid->magic_1 != meta->timestamp))) {
3601             continue;
3602         }
3603
3604         switch (meta->type_total_disks & SIS_T_MASK) {
3605         case SIS_T_JBOD:
3606             raid->type = AR_T_JBOD;
3607             raid->width = (meta->type_total_disks & SIS_D_MASK);
3608             raid->total_sectors += SIS_LBA(parent);
3609             break;
3610
3611         case SIS_T_RAID0:
3612             raid->type = AR_T_RAID0;
3613             raid->width = (meta->type_total_disks & SIS_D_MASK);
3614             if (!raid->total_sectors || 
3615                 (raid->total_sectors > (raid->width * SIS_LBA(parent))))
3616                 raid->total_sectors = raid->width * SIS_LBA(parent);
3617             break;
3618
3619         case SIS_T_RAID1:
3620             raid->type = AR_T_RAID1;
3621             raid->width = 1;
3622             if (!raid->total_sectors || (raid->total_sectors > SIS_LBA(parent)))
3623                 raid->total_sectors = SIS_LBA(parent);
3624             break;
3625
3626         default:
3627             device_printf(parent, "Silicon Integrated Systems "
3628                           "unknown RAID type 0x%08x\n", meta->magic);
3629             free(raidp[array], M_AR);
3630             raidp[array] = NULL;
3631             goto sis_out;
3632         }
3633         raid->magic_0 = meta->controller_pci_id;
3634         raid->magic_1 = meta->timestamp;
3635         raid->format = AR_F_SIS_RAID;
3636         raid->generation = 0;
3637         raid->interleave = meta->stripe_sectors;
3638         raid->total_disks = (meta->type_total_disks & SIS_D_MASK);
3639         raid->heads = 255;
3640         raid->sectors = 63;
3641         raid->cylinders = raid->total_sectors / (63 * 255);
3642         raid->offset_sectors = 0;
3643         raid->rebuild_lba = 0;
3644         raid->lun = array;
3645         /* XXX SOS if total_disks > 2 this doesn't float */
3646         if (((meta->disks & SIS_D_MASTER) >> 4) == meta->disk_number)
3647             disk_number = 0;
3648         else 
3649             disk_number = 1;
3650
3651         for (drive = 0; drive < raid->total_disks; drive++) {
3652             raid->disks[drive].sectors = raid->total_sectors/raid->width;
3653             if (drive == disk_number) {
3654                 raid->disks[disk_number].dev = parent;
3655                 raid->disks[disk_number].flags =
3656                     (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED);
3657                 ars->raid[raid->volume] = raid;
3658                 ars->disk_number[raid->volume] = disk_number;
3659             }
3660         }
3661         retval = 1;
3662         break;
3663     }
3664
3665 sis_out:
3666     free(meta, M_AR);
3667     return retval;
3668 }
3669
3670 static int
3671 ata_raid_sis_write_meta(struct ar_softc *rdp)
3672 {
3673     struct sis_raid_conf *meta;
3674     struct timeval timestamp;
3675     int disk, error = 0;
3676
3677     if (!(meta = (struct sis_raid_conf *)
3678           malloc(sizeof(struct sis_raid_conf), M_AR, M_NOWAIT | M_ZERO))) {
3679         printf("ar%d: failed to allocate metadata storage\n", rdp->lun);
3680         return ENOMEM;
3681     }
3682
3683     rdp->generation++;
3684     microtime(&timestamp);
3685
3686     meta->magic = SIS_MAGIC;
3687     /* XXX SOS if total_disks > 2 this doesn't float */
3688     for (disk = 0; disk < rdp->total_disks; disk++) {
3689         if (rdp->disks[disk].dev) {
3690             struct ata_channel *ch = 
3691                 device_get_softc(device_get_parent(rdp->disks[disk].dev));
3692             struct ata_device *atadev = device_get_softc(rdp->disks[disk].dev);
3693             int disk_number = 1 + ATA_DEV(atadev->unit) + (ch->unit << 1);
3694
3695             meta->disks |= disk_number << ((1 - disk) << 2);
3696         }
3697     }
3698     switch (rdp->type) {
3699     case AR_T_JBOD:
3700         meta->type_total_disks = SIS_T_JBOD;
3701         break;
3702
3703     case AR_T_RAID0:
3704         meta->type_total_disks = SIS_T_RAID0;
3705         break;
3706
3707     case AR_T_RAID1:
3708         meta->type_total_disks = SIS_T_RAID1;
3709         break;
3710
3711     default:
3712         free(meta, M_AR);
3713         return ENODEV;
3714     }
3715     meta->type_total_disks |= (rdp->total_disks & SIS_D_MASK);
3716     meta->stripe_sectors = rdp->interleave;
3717     meta->timestamp = timestamp.tv_sec;
3718
3719     for (disk = 0; disk < rdp->total_disks; disk++) {
3720         if (rdp->disks[disk].dev) {
3721             struct ata_channel *ch = 
3722                 device_get_softc(device_get_parent(rdp->disks[disk].dev));
3723             struct ata_device *atadev = device_get_softc(rdp->disks[disk].dev);
3724
3725             meta->controller_pci_id =
3726                 (pci_get_vendor(GRANDPARENT(rdp->disks[disk].dev)) << 16) |
3727                 pci_get_device(GRANDPARENT(rdp->disks[disk].dev));
3728             bcopy(atadev->param.model, meta->model, sizeof(meta->model));
3729
3730             /* XXX SOS if total_disks > 2 this may not float */
3731             meta->disk_number = 1 + ATA_DEV(atadev->unit) + (ch->unit << 1);
3732
3733             if (testing || bootverbose)
3734                 ata_raid_sis_print_meta(meta);
3735
3736             if (ata_raid_rw(rdp->disks[disk].dev,
3737                             SIS_LBA(rdp->disks[disk].dev),
3738                             meta, sizeof(struct sis_raid_conf),
3739                             ATA_R_WRITE | ATA_R_DIRECT)) {
3740                 device_printf(rdp->disks[disk].dev, "write metadata failed\n");
3741                 error = EIO;
3742             }
3743         }
3744     }
3745     free(meta, M_AR);
3746     return error;
3747 }
3748
3749 /* VIA Tech V-RAID Metadata */
3750 static int
3751 ata_raid_via_read_meta(device_t dev, struct ar_softc **raidp)
3752 {
3753     struct ata_raid_subdisk *ars = device_get_softc(dev);
3754     device_t parent = device_get_parent(dev);
3755     struct via_raid_conf *meta;
3756     struct ar_softc *raid = NULL;
3757     u_int8_t checksum, *ptr;
3758     int array, count, disk, retval = 0;
3759
3760     if (!(meta = (struct via_raid_conf *)
3761           malloc(sizeof(struct via_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
3762         return ENOMEM;
3763
3764     if (ata_raid_rw(parent, VIA_LBA(parent),
3765                     meta, sizeof(struct via_raid_conf), ATA_R_READ)) {
3766         if (testing || bootverbose)
3767             device_printf(parent, "VIA read metadata failed\n");
3768         goto via_out;
3769     }
3770
3771     /* check if this is a VIA RAID struct */
3772     if (meta->magic != VIA_MAGIC) {
3773         if (testing || bootverbose)
3774             device_printf(parent, "VIA check1 failed\n");
3775         goto via_out;
3776     }
3777
3778     /* calculate checksum and compare for valid */
3779     for (checksum = 0, ptr = (u_int8_t *)meta, count = 0; count < 50; count++)
3780         checksum += *ptr++;
3781     if (checksum != meta->checksum) {  
3782         if (testing || bootverbose)
3783             device_printf(parent, "VIA check2 failed\n");
3784         goto via_out;
3785     }
3786
3787     if (testing || bootverbose)
3788         ata_raid_via_print_meta(meta);
3789
3790     /* now convert VIA meta into our generic form */
3791     for (array = 0; array < MAX_ARRAYS; array++) {
3792         if (!raidp[array]) {
3793             raidp[array] = 
3794                 (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR,
3795                                           M_NOWAIT | M_ZERO);
3796             if (!raidp[array]) {
3797                 device_printf(parent, "failed to allocate metadata storage\n");
3798                 goto via_out;
3799             }
3800         }
3801         raid = raidp[array];
3802         if (raid->format && (raid->format != AR_F_VIA_RAID))
3803             continue;
3804
3805         if (raid->format == AR_F_VIA_RAID && (raid->magic_0 != meta->disks[0]))
3806             continue;
3807
3808         switch (meta->type & VIA_T_MASK) {
3809         case VIA_T_RAID0:
3810             raid->type = AR_T_RAID0;
3811             raid->width = meta->stripe_layout & VIA_L_DISKS;
3812             if (!raid->total_sectors ||
3813                 (raid->total_sectors > (raid->width * meta->disk_sectors)))
3814                 raid->total_sectors = raid->width * meta->disk_sectors;
3815             break;
3816
3817         case VIA_T_RAID1:
3818             raid->type = AR_T_RAID1;
3819             raid->width = 1;
3820             raid->total_sectors = meta->disk_sectors;
3821             break;
3822
3823         case VIA_T_RAID01:
3824             raid->type = AR_T_RAID01;
3825             raid->width = meta->stripe_layout & VIA_L_DISKS;
3826             if (!raid->total_sectors ||
3827                 (raid->total_sectors > (raid->width * meta->disk_sectors)))
3828                 raid->total_sectors = raid->width * meta->disk_sectors;
3829             break;
3830
3831         case VIA_T_RAID5:
3832             raid->type = AR_T_RAID5;
3833             raid->width = meta->stripe_layout & VIA_L_DISKS;
3834             if (!raid->total_sectors ||
3835                 (raid->total_sectors > ((raid->width - 1)*meta->disk_sectors)))
3836                 raid->total_sectors = (raid->width - 1) * meta->disk_sectors;
3837             break;
3838
3839         case VIA_T_SPAN:
3840             raid->type = AR_T_SPAN;
3841             raid->width = 1;
3842             raid->total_sectors += meta->disk_sectors;
3843             break;
3844
3845         default:
3846             device_printf(parent,"VIA unknown RAID type 0x%02x\n", meta->type);
3847             free(raidp[array], M_AR);
3848             raidp[array] = NULL;
3849             goto via_out;
3850         }
3851         raid->magic_0 = meta->disks[0];
3852         raid->format = AR_F_VIA_RAID;
3853         raid->generation = 0;
3854         raid->interleave = 
3855             0x08 << ((meta->stripe_layout & VIA_L_MASK) >> VIA_L_SHIFT);
3856         for (count = 0, disk = 0; disk < 8; disk++)
3857             if (meta->disks[disk])
3858                 count++;
3859         raid->total_disks = count;
3860         raid->heads = 255;
3861         raid->sectors = 63;
3862         raid->cylinders = raid->total_sectors / (63 * 255);
3863         raid->offset_sectors = 0;
3864         raid->rebuild_lba = 0;
3865         raid->lun = array;
3866
3867         for (disk = 0; disk < raid->total_disks; disk++) {
3868             if (meta->disks[disk] == meta->disk_id) {
3869                 raid->disks[disk].dev = parent;
3870                 bcopy(&meta->disk_id, raid->disks[disk].serial,
3871                       sizeof(u_int32_t));
3872                 raid->disks[disk].sectors = meta->disk_sectors;
3873                 raid->disks[disk].flags =
3874                     (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED);
3875                 ars->raid[raid->volume] = raid;
3876                 ars->disk_number[raid->volume] = disk;
3877                 retval = 1;
3878                 break;
3879             }
3880         }
3881         break;
3882     }
3883
3884 via_out:
3885     free(meta, M_AR);
3886     return retval;
3887 }
3888
3889 static int
3890 ata_raid_via_write_meta(struct ar_softc *rdp)
3891 {
3892     struct via_raid_conf *meta;
3893     int disk, error = 0;
3894
3895     if (!(meta = (struct via_raid_conf *)
3896           malloc(sizeof(struct via_raid_conf), M_AR, M_NOWAIT | M_ZERO))) {
3897         printf("ar%d: failed to allocate metadata storage\n", rdp->lun);
3898         return ENOMEM;
3899     }
3900
3901     rdp->generation++;
3902
3903     meta->magic = VIA_MAGIC;
3904     meta->dummy_0 = 0x02;
3905     switch (rdp->type) {
3906     case AR_T_SPAN:
3907         meta->type = VIA_T_SPAN;
3908         meta->stripe_layout = (rdp->total_disks & VIA_L_DISKS);
3909         break;
3910
3911     case AR_T_RAID0:
3912         meta->type = VIA_T_RAID0;
3913         meta->stripe_layout = ((rdp->interleave >> 1) & VIA_L_MASK);
3914         meta->stripe_layout |= (rdp->total_disks & VIA_L_DISKS);
3915         break;
3916
3917     case AR_T_RAID1:
3918         meta->type = VIA_T_RAID1;
3919         meta->stripe_layout = (rdp->total_disks & VIA_L_DISKS);
3920         break;
3921
3922     case AR_T_RAID5:
3923         meta->type = VIA_T_RAID5;
3924         meta->stripe_layout = ((rdp->interleave >> 1) & VIA_L_MASK);
3925         meta->stripe_layout |= (rdp->total_disks & VIA_L_DISKS);
3926         break;
3927
3928     case AR_T_RAID01:
3929         meta->type = VIA_T_RAID01;
3930         meta->stripe_layout = ((rdp->interleave >> 1) & VIA_L_MASK);
3931         meta->stripe_layout |= (rdp->width & VIA_L_DISKS);
3932         break;
3933
3934     default:
3935         free(meta, M_AR);
3936         return ENODEV;
3937     }
3938     meta->type |= VIA_T_BOOTABLE;       /* XXX SOS */
3939     meta->disk_sectors = 
3940         rdp->total_sectors / (rdp->width - (rdp->type == AR_RAID5));
3941     for (disk = 0; disk < rdp->total_disks; disk++)
3942         meta->disks[disk] = (u_int32_t)(uintptr_t)rdp->disks[disk].dev;
3943
3944     for (disk = 0; disk < rdp->total_disks; disk++) {
3945         if (rdp->disks[disk].dev) {
3946             u_int8_t *ptr;
3947             int count;
3948
3949             meta->disk_index = disk * sizeof(u_int32_t);
3950             if (rdp->type == AR_T_RAID01)
3951                 meta->disk_index = ((meta->disk_index & 0x08) << 2) |
3952                                    (meta->disk_index & ~0x08);
3953             meta->disk_id = meta->disks[disk];
3954             meta->checksum = 0;
3955             for (ptr = (u_int8_t *)meta, count = 0; count < 50; count++)
3956                 meta->checksum += *ptr++;
3957
3958             if (testing || bootverbose)
3959                 ata_raid_via_print_meta(meta);
3960
3961             if (ata_raid_rw(rdp->disks[disk].dev,
3962                             VIA_LBA(rdp->disks[disk].dev),
3963                             meta, sizeof(struct via_raid_conf),
3964                             ATA_R_WRITE | ATA_R_DIRECT)) {
3965                 device_printf(rdp->disks[disk].dev, "write metadata failed\n");
3966                 error = EIO;
3967             }
3968         }
3969     }
3970     free(meta, M_AR);
3971     return error;
3972 }
3973
3974 static struct ata_request *
3975 ata_raid_init_request(struct ar_softc *rdp, struct bio *bio)
3976 {
3977     struct ata_request *request;
3978
3979     if (!(request = ata_alloc_request())) {
3980         printf("FAILURE - out of memory in ata_raid_init_request\n");
3981         return NULL;
3982     }
3983     request->timeout = 5;
3984     request->retries = 2;
3985     request->callback = ata_raid_done;
3986     request->driver = rdp;
3987     request->bio = bio;
3988     switch (request->bio->bio_cmd) {
3989     case BIO_READ:
3990         request->flags = ATA_R_READ;
3991         break;
3992     case BIO_WRITE:
3993         request->flags = ATA_R_WRITE;
3994         break;
3995     }
3996     return request;
3997 }
3998
3999 static int
4000 ata_raid_send_request(struct ata_request *request)
4001 {
4002     struct ata_device *atadev = device_get_softc(request->dev);
4003   
4004     request->transfersize = min(request->bytecount, atadev->max_iosize);
4005     if (request->flags & ATA_R_READ) {
4006         if (atadev->mode >= ATA_DMA) {
4007             request->flags |= ATA_R_DMA;
4008             request->u.ata.command = ATA_READ_DMA;
4009         }
4010         else if (atadev->max_iosize > DEV_BSIZE)
4011             request->u.ata.command = ATA_READ_MUL;
4012         else
4013             request->u.ata.command = ATA_READ;
4014     }
4015     else if (request->flags & ATA_R_WRITE) {
4016         if (atadev->mode >= ATA_DMA) {
4017             request->flags |= ATA_R_DMA;
4018             request->u.ata.command = ATA_WRITE_DMA;
4019         }
4020         else if (atadev->max_iosize > DEV_BSIZE)
4021             request->u.ata.command = ATA_WRITE_MUL;
4022         else
4023             request->u.ata.command = ATA_WRITE;
4024     }
4025     else {
4026         device_printf(request->dev, "FAILURE - unknown IO operation\n");
4027         ata_free_request(request);
4028         return EIO;
4029     }
4030     request->flags |= (ATA_R_ORDERED | ATA_R_THREAD);
4031     ata_queue_request(request);
4032     return 0;
4033 }
4034
4035 static int
4036 ata_raid_rw(device_t dev, u_int64_t lba, void *data, u_int bcount, int flags)
4037 {
4038     struct ata_device *atadev = device_get_softc(dev);
4039     struct ata_request *request;
4040     int error;
4041
4042     if (bcount % DEV_BSIZE) {
4043         device_printf(dev, "FAILURE - transfers must be modulo sectorsize\n");
4044         return ENOMEM;
4045     }
4046         
4047     if (!(request = ata_alloc_request())) {
4048         device_printf(dev, "FAILURE - out of memory in ata_raid_rw\n");
4049         return ENOMEM;
4050     }
4051
4052     /* setup request */
4053     request->dev = dev;
4054     request->timeout = 10;
4055     request->retries = 0;
4056     request->data = data;
4057     request->bytecount = bcount;
4058     request->transfersize = DEV_BSIZE;
4059     request->u.ata.lba = lba;
4060     request->u.ata.count = request->bytecount / DEV_BSIZE;
4061     request->flags = flags;
4062
4063     if (flags & ATA_R_READ) {
4064         if (atadev->mode >= ATA_DMA) {
4065             request->u.ata.command = ATA_READ_DMA;
4066             request->flags |= ATA_R_DMA;
4067         }
4068         else
4069             request->u.ata.command = ATA_READ;
4070         ata_queue_request(request);
4071     }
4072     else if (flags & ATA_R_WRITE) {
4073         if (atadev->mode >= ATA_DMA) {
4074             request->u.ata.command = ATA_WRITE_DMA;
4075             request->flags |= ATA_R_DMA;
4076         }
4077         else
4078             request->u.ata.command = ATA_WRITE;
4079         ata_queue_request(request);
4080     }
4081     else {
4082         device_printf(dev, "FAILURE - unknown IO operation\n");
4083         request->result = EIO;
4084     }
4085     error = request->result;
4086     ata_free_request(request);
4087     return error;
4088 }
4089
4090 /*
4091  * module handeling
4092  */
4093 static int
4094 ata_raid_subdisk_probe(device_t dev)
4095 {
4096     device_quiet(dev);
4097     return 0;
4098 }
4099
4100 static int
4101 ata_raid_subdisk_attach(device_t dev)
4102 {
4103     struct ata_raid_subdisk *ars = device_get_softc(dev);
4104     int volume;
4105
4106     for (volume = 0; volume < MAX_VOLUMES; volume++) {
4107         ars->raid[volume] = NULL;
4108         ars->disk_number[volume] = -1;
4109     }
4110     ata_raid_read_metadata(dev);
4111     return 0;
4112 }
4113
4114 static int
4115 ata_raid_subdisk_detach(device_t dev)
4116 {
4117     struct ata_raid_subdisk *ars = device_get_softc(dev);
4118     int volume;
4119
4120     for (volume = 0; volume < MAX_VOLUMES; volume++) {
4121         if (ars->raid[volume]) {
4122             ars->raid[volume]->disks[ars->disk_number[volume]].flags &= 
4123                 ~(AR_DF_PRESENT | AR_DF_ONLINE);
4124             ars->raid[volume]->disks[ars->disk_number[volume]].dev = NULL;
4125             if (mtx_initialized(&ars->raid[volume]->lock))
4126                 ata_raid_config_changed(ars->raid[volume], 1);
4127             ars->raid[volume] = NULL;
4128             ars->disk_number[volume] = -1;
4129         }
4130     }
4131     return 0;
4132 }
4133
4134 static device_method_t ata_raid_sub_methods[] = {
4135     /* device interface */
4136     DEVMETHOD(device_probe,     ata_raid_subdisk_probe),
4137     DEVMETHOD(device_attach,    ata_raid_subdisk_attach),
4138     DEVMETHOD(device_detach,    ata_raid_subdisk_detach),
4139     { 0, 0 }
4140 };
4141
4142 static driver_t ata_raid_sub_driver = {
4143     "subdisk",
4144     ata_raid_sub_methods,
4145     sizeof(struct ata_raid_subdisk)
4146 };
4147
4148 DRIVER_MODULE(subdisk, ad, ata_raid_sub_driver, ata_raid_sub_devclass, NULL, NULL);
4149
4150 static int
4151 ata_raid_module_event_handler(module_t mod, int what, void *arg)
4152 {
4153     int i;
4154
4155     switch (what) {
4156     case MOD_LOAD:
4157         if (testing || bootverbose)
4158             printf("ATA PseudoRAID loaded\n");
4159 #if 0
4160         /* setup table to hold metadata for all ATA PseudoRAID arrays */
4161         ata_raid_arrays = malloc(sizeof(struct ar_soft *) * MAX_ARRAYS,
4162                                 M_AR, M_NOWAIT | M_ZERO);
4163         if (!ata_raid_arrays) {
4164             printf("ataraid: no memory for metadata storage\n");
4165             return ENOMEM;
4166         }
4167 #endif
4168         /* attach found PseudoRAID arrays */
4169         for (i = 0; i < MAX_ARRAYS; i++) {
4170             struct ar_softc *rdp = ata_raid_arrays[i];
4171             
4172             if (!rdp || !rdp->format)
4173                 continue;
4174             if (testing || bootverbose)
4175                 ata_raid_print_meta(rdp);
4176             ata_raid_attach(rdp, 0);
4177         }   
4178         ata_raid_ioctl_func = ata_raid_ioctl;
4179         return 0;
4180
4181     case MOD_UNLOAD:
4182         /* detach found PseudoRAID arrays */
4183         for (i = 0; i < MAX_ARRAYS; i++) {
4184             struct ar_softc *rdp = ata_raid_arrays[i];
4185
4186             if (!rdp || !rdp->status)
4187                 continue;
4188             if (mtx_initialized(&rdp->lock))
4189                 mtx_destroy(&rdp->lock);
4190             if (rdp->disk)
4191                 disk_destroy(rdp->disk);
4192         }
4193         if (testing || bootverbose)
4194             printf("ATA PseudoRAID unloaded\n");
4195 #if 0
4196         free(ata_raid_arrays, M_AR);
4197 #endif
4198         ata_raid_ioctl_func = NULL;
4199         return 0;
4200         
4201     default:
4202         return EOPNOTSUPP;
4203     }
4204 }
4205
4206 static moduledata_t ata_raid_moduledata =
4207     { "ataraid", ata_raid_module_event_handler, NULL };
4208 DECLARE_MODULE(ata, ata_raid_moduledata, SI_SUB_RAID, SI_ORDER_FIRST);
4209 MODULE_VERSION(ataraid, 1);
4210 MODULE_DEPEND(ataraid, ata, 1, 1, 1);
4211 MODULE_DEPEND(ataraid, ad, 1, 1, 1);
4212
4213 static char *
4214 ata_raid_format(struct ar_softc *rdp)
4215 {
4216     switch (rdp->format) {
4217     case AR_F_FREEBSD_RAID:     return "FreeBSD PseudoRAID";
4218     case AR_F_ADAPTEC_RAID:     return "Adaptec HostRAID";
4219     case AR_F_HPTV2_RAID:       return "HighPoint v2 RocketRAID";
4220     case AR_F_HPTV3_RAID:       return "HighPoint v3 RocketRAID";
4221     case AR_F_INTEL_RAID:       return "Intel MatrixRAID";
4222     case AR_F_ITE_RAID:         return "Integrated Technology Express";
4223     case AR_F_JMICRON_RAID:     return "JMicron Technology Corp";
4224     case AR_F_LSIV2_RAID:       return "LSILogic v2 MegaRAID";
4225     case AR_F_LSIV3_RAID:       return "LSILogic v3 MegaRAID";
4226     case AR_F_NVIDIA_RAID:      return "nVidia MediaShield";
4227     case AR_F_PROMISE_RAID:     return "Promise Fasttrak";
4228     case AR_F_SII_RAID:         return "Silicon Image Medley";
4229     case AR_F_SIS_RAID:         return "Silicon Integrated Systems";
4230     case AR_F_VIA_RAID:         return "VIA Tech V-RAID";
4231     default:                    return "UNKNOWN";
4232     }
4233 }
4234
4235 static char *
4236 ata_raid_type(struct ar_softc *rdp)
4237 {
4238     switch (rdp->type) {
4239     case AR_T_JBOD:     return "JBOD";
4240     case AR_T_SPAN:     return "SPAN";
4241     case AR_T_RAID0:    return "RAID0";
4242     case AR_T_RAID1:    return "RAID1";
4243     case AR_T_RAID3:    return "RAID3";
4244     case AR_T_RAID4:    return "RAID4";
4245     case AR_T_RAID5:    return "RAID5";
4246     case AR_T_RAID01:   return "RAID0+1";
4247     default:            return "UNKNOWN";
4248     }
4249 }
4250
4251 static char *
4252 ata_raid_flags(struct ar_softc *rdp)
4253 {
4254     switch (rdp->status & (AR_S_READY | AR_S_DEGRADED | AR_S_REBUILDING)) {
4255     case AR_S_READY:                                    return "READY";
4256     case AR_S_READY | AR_S_DEGRADED:                    return "DEGRADED";
4257     case AR_S_READY | AR_S_REBUILDING:
4258     case AR_S_READY | AR_S_DEGRADED | AR_S_REBUILDING:  return "REBUILDING";
4259     default:                                            return "BROKEN";
4260     }
4261 }
4262
4263 /* debugging gunk */
4264 static void
4265 ata_raid_print_meta(struct ar_softc *raid)
4266 {
4267     int i;
4268
4269     printf("********** ATA PseudoRAID ar%d Metadata **********\n", raid->lun);
4270     printf("=================================================\n");
4271     printf("format              %s\n", ata_raid_format(raid));
4272     printf("type                %s\n", ata_raid_type(raid));
4273     printf("flags               0x%02x %b\n", raid->status, raid->status,
4274            "\20\3REBUILDING\2DEGRADED\1READY\n");
4275     printf("magic_0             0x%016jx\n", raid->magic_0);
4276     printf("magic_1             0x%016jx\n",raid->magic_1);
4277     printf("generation          %u\n", raid->generation);
4278     printf("total_sectors       %ju\n", raid->total_sectors);
4279     printf("offset_sectors      %ju\n", raid->offset_sectors);
4280     printf("heads               %u\n", raid->heads);
4281     printf("sectors             %u\n", raid->sectors);
4282     printf("cylinders           %u\n", raid->cylinders);
4283     printf("width               %u\n", raid->width);
4284     printf("interleave          %u\n", raid->interleave);
4285     printf("total_disks         %u\n", raid->total_disks);
4286     for (i = 0; i < raid->total_disks; i++) {
4287         printf("    disk %d:      flags = 0x%02x %b\n", i, raid->disks[i].flags,
4288                raid->disks[i].flags, "\20\4ONLINE\3SPARE\2ASSIGNED\1PRESENT\n");
4289         if (raid->disks[i].dev) {
4290             printf("        ");
4291             device_printf(raid->disks[i].dev, " sectors %jd\n",
4292                           raid->disks[i].sectors);
4293         }
4294     }
4295     printf("=================================================\n");
4296 }
4297
4298 static char *
4299 ata_raid_adaptec_type(int type)
4300 {
4301     static char buffer[16];
4302
4303     switch (type) {
4304     case ADP_T_RAID0:   return "RAID0";
4305     case ADP_T_RAID1:   return "RAID1";
4306     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4307                         return buffer;
4308     }
4309 }
4310
4311 static void
4312 ata_raid_adaptec_print_meta(struct adaptec_raid_conf *meta)
4313 {
4314     int i;
4315
4316     printf("********* ATA Adaptec HostRAID Metadata *********\n");
4317     printf("magic_0             <0x%08x>\n", be32toh(meta->magic_0));
4318     printf("generation          0x%08x\n", be32toh(meta->generation));
4319     printf("dummy_0             0x%04x\n", be16toh(meta->dummy_0));
4320     printf("total_configs       %u\n", be16toh(meta->total_configs));
4321     printf("dummy_1             0x%04x\n", be16toh(meta->dummy_1));
4322     printf("checksum            0x%04x\n", be16toh(meta->checksum));
4323     printf("dummy_2             0x%08x\n", be32toh(meta->dummy_2));
4324     printf("dummy_3             0x%08x\n", be32toh(meta->dummy_3));
4325     printf("flags               0x%08x\n", be32toh(meta->flags));
4326     printf("timestamp           0x%08x\n", be32toh(meta->timestamp));
4327     printf("dummy_4             0x%08x 0x%08x 0x%08x 0x%08x\n",
4328            be32toh(meta->dummy_4[0]), be32toh(meta->dummy_4[1]),
4329            be32toh(meta->dummy_4[2]), be32toh(meta->dummy_4[3]));
4330     printf("dummy_5             0x%08x 0x%08x 0x%08x 0x%08x\n",
4331            be32toh(meta->dummy_5[0]), be32toh(meta->dummy_5[1]),
4332            be32toh(meta->dummy_5[2]), be32toh(meta->dummy_5[3]));
4333
4334     for (i = 0; i < be16toh(meta->total_configs); i++) {
4335         printf("    %d   total_disks  %u\n", i,
4336                be16toh(meta->configs[i].disk_number));
4337         printf("    %d   generation   %u\n", i,
4338                be16toh(meta->configs[i].generation));
4339         printf("    %d   magic_0      0x%08x\n", i,
4340                be32toh(meta->configs[i].magic_0));
4341         printf("    %d   dummy_0      0x%02x\n", i, meta->configs[i].dummy_0);
4342         printf("    %d   type         %s\n", i,
4343                ata_raid_adaptec_type(meta->configs[i].type));
4344         printf("    %d   dummy_1      0x%02x\n", i, meta->configs[i].dummy_1);
4345         printf("    %d   flags        %d\n", i,
4346                be32toh(meta->configs[i].flags));
4347         printf("    %d   dummy_2      0x%02x\n", i, meta->configs[i].dummy_2);
4348         printf("    %d   dummy_3      0x%02x\n", i, meta->configs[i].dummy_3);
4349         printf("    %d   dummy_4      0x%02x\n", i, meta->configs[i].dummy_4);
4350         printf("    %d   dummy_5      0x%02x\n", i, meta->configs[i].dummy_5);
4351         printf("    %d   disk_number  %u\n", i,
4352                be32toh(meta->configs[i].disk_number));
4353         printf("    %d   dummy_6      0x%08x\n", i,
4354                be32toh(meta->configs[i].dummy_6));
4355         printf("    %d   sectors      %u\n", i,
4356                be32toh(meta->configs[i].sectors));
4357         printf("    %d   stripe_shift %u\n", i,
4358                be16toh(meta->configs[i].stripe_shift));
4359         printf("    %d   dummy_7      0x%08x\n", i,
4360                be32toh(meta->configs[i].dummy_7));
4361         printf("    %d   dummy_8      0x%08x 0x%08x 0x%08x 0x%08x\n", i,
4362                be32toh(meta->configs[i].dummy_8[0]),
4363                be32toh(meta->configs[i].dummy_8[1]),
4364                be32toh(meta->configs[i].dummy_8[2]),
4365                be32toh(meta->configs[i].dummy_8[3]));
4366         printf("    %d   name         <%s>\n", i, meta->configs[i].name);
4367     }
4368     printf("magic_1             <0x%08x>\n", be32toh(meta->magic_1));
4369     printf("magic_2             <0x%08x>\n", be32toh(meta->magic_2));
4370     printf("magic_3             <0x%08x>\n", be32toh(meta->magic_3));
4371     printf("magic_4             <0x%08x>\n", be32toh(meta->magic_4));
4372     printf("=================================================\n");
4373 }
4374
4375 static char *
4376 ata_raid_hptv2_type(int type)
4377 {
4378     static char buffer[16];
4379
4380     switch (type) {
4381     case HPTV2_T_RAID0:         return "RAID0";
4382     case HPTV2_T_RAID1:         return "RAID1";
4383     case HPTV2_T_RAID01_RAID0:  return "RAID01_RAID0";
4384     case HPTV2_T_SPAN:          return "SPAN";
4385     case HPTV2_T_RAID_3:        return "RAID3";
4386     case HPTV2_T_RAID_5:        return "RAID5";
4387     case HPTV2_T_JBOD:          return "JBOD";
4388     case HPTV2_T_RAID01_RAID1:  return "RAID01_RAID1";
4389     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4390                         return buffer;
4391     }
4392 }
4393
4394 static void
4395 ata_raid_hptv2_print_meta(struct hptv2_raid_conf *meta)
4396 {
4397     int i;
4398
4399     printf("****** ATA Highpoint V2 RocketRAID Metadata *****\n");
4400     printf("magic               0x%08x\n", meta->magic);
4401     printf("magic_0             0x%08x\n", meta->magic_0);
4402     printf("magic_1             0x%08x\n", meta->magic_1);
4403     printf("order               0x%08x\n", meta->order);
4404     printf("array_width         %u\n", meta->array_width);
4405     printf("stripe_shift        %u\n", meta->stripe_shift);
4406     printf("type                %s\n", ata_raid_hptv2_type(meta->type));
4407     printf("disk_number         %u\n", meta->disk_number);
4408     printf("total_sectors       %u\n", meta->total_sectors);
4409     printf("disk_mode           0x%08x\n", meta->disk_mode);
4410     printf("boot_mode           0x%08x\n", meta->boot_mode);
4411     printf("boot_disk           0x%02x\n", meta->boot_disk);
4412     printf("boot_protect        0x%02x\n", meta->boot_protect);
4413     printf("log_entries         0x%02x\n", meta->error_log_entries);
4414     printf("log_index           0x%02x\n", meta->error_log_index);
4415     if (meta->error_log_entries) {
4416         printf("    timestamp  reason disk  status  sectors lba\n");
4417         for (i = meta->error_log_index;
4418              i < meta->error_log_index + meta->error_log_entries; i++)
4419             printf("    0x%08x  0x%02x  0x%02x  0x%02x    0x%02x    0x%08x\n",
4420                    meta->errorlog[i%32].timestamp,
4421                    meta->errorlog[i%32].reason,
4422                    meta->errorlog[i%32].disk, meta->errorlog[i%32].status,
4423                    meta->errorlog[i%32].sectors, meta->errorlog[i%32].lba);
4424     }
4425     printf("rebuild_lba         0x%08x\n", meta->rebuild_lba);
4426     printf("dummy_1             0x%02x\n", meta->dummy_1);
4427     printf("name_1              <%.15s>\n", meta->name_1);
4428     printf("dummy_2             0x%02x\n", meta->dummy_2);
4429     printf("name_2              <%.15s>\n", meta->name_2);
4430     printf("=================================================\n");
4431 }
4432
4433 static char *
4434 ata_raid_hptv3_type(int type)
4435 {
4436     static char buffer[16];
4437
4438     switch (type) {
4439     case HPTV3_T_SPARE: return "SPARE";
4440     case HPTV3_T_JBOD:  return "JBOD";
4441     case HPTV3_T_SPAN:  return "SPAN";
4442     case HPTV3_T_RAID0: return "RAID0";
4443     case HPTV3_T_RAID1: return "RAID1";
4444     case HPTV3_T_RAID3: return "RAID3";
4445     case HPTV3_T_RAID5: return "RAID5";
4446     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4447                         return buffer;
4448     }
4449 }
4450
4451 static void
4452 ata_raid_hptv3_print_meta(struct hptv3_raid_conf *meta)
4453 {
4454     int i;
4455
4456     printf("****** ATA Highpoint V3 RocketRAID Metadata *****\n");
4457     printf("magic               0x%08x\n", meta->magic);
4458     printf("magic_0             0x%08x\n", meta->magic_0);
4459     printf("checksum_0          0x%02x\n", meta->checksum_0);
4460     printf("mode                0x%02x\n", meta->mode);
4461     printf("user_mode           0x%02x\n", meta->user_mode);
4462     printf("config_entries      0x%02x\n", meta->config_entries);
4463     for (i = 0; i < meta->config_entries; i++) {
4464         printf("config %d:\n", i);
4465         printf("    total_sectors       %ju\n",
4466                meta->configs[0].total_sectors +
4467                ((u_int64_t)meta->configs_high[0].total_sectors << 32));
4468         printf("    type                %s\n",
4469                ata_raid_hptv3_type(meta->configs[i].type)); 
4470         printf("    total_disks         %u\n", meta->configs[i].total_disks);
4471         printf("    disk_number         %u\n", meta->configs[i].disk_number);
4472         printf("    stripe_shift        %u\n", meta->configs[i].stripe_shift);
4473         printf("    status              %b\n", meta->configs[i].status,
4474                "\20\2RAID5\1NEED_REBUILD\n");
4475         printf("    critical_disks      %u\n", meta->configs[i].critical_disks);
4476         printf("    rebuild_lba         %ju\n",
4477                meta->configs_high[0].rebuild_lba +
4478                ((u_int64_t)meta->configs_high[0].rebuild_lba << 32));
4479     }
4480     printf("name                <%.16s>\n", meta->name);
4481     printf("timestamp           0x%08x\n", meta->timestamp);
4482     printf("description         <%.16s>\n", meta->description);
4483     printf("creator             <%.16s>\n", meta->creator);
4484     printf("checksum_1          0x%02x\n", meta->checksum_1);
4485     printf("dummy_0             0x%02x\n", meta->dummy_0);
4486     printf("dummy_1             0x%02x\n", meta->dummy_1);
4487     printf("flags               %b\n", meta->flags,
4488            "\20\4RCACHE\3WCACHE\2NCQ\1TCQ\n");
4489     printf("=================================================\n");
4490 }
4491
4492 static char *
4493 ata_raid_intel_type(int type)
4494 {
4495     static char buffer[16];
4496
4497     switch (type) {
4498     case INTEL_T_RAID0: return "RAID0";
4499     case INTEL_T_RAID1: return "RAID1";
4500     case INTEL_T_RAID5: return "RAID5";
4501     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4502                         return buffer;
4503     }
4504 }
4505
4506 static void
4507 ata_raid_intel_print_meta(struct intel_raid_conf *meta)
4508 {
4509     struct intel_raid_mapping *map;
4510     int i, j;
4511
4512     printf("********* ATA Intel MatrixRAID Metadata *********\n");
4513     printf("intel_id            <%.24s>\n", meta->intel_id);
4514     printf("version             <%.6s>\n", meta->version);
4515     printf("checksum            0x%08x\n", meta->checksum);
4516     printf("config_size         0x%08x\n", meta->config_size);
4517     printf("config_id           0x%08x\n", meta->config_id);
4518     printf("generation          0x%08x\n", meta->generation);
4519     printf("total_disks         %u\n", meta->total_disks);
4520     printf("total_volumes       %u\n", meta->total_volumes);
4521     printf("DISK#   serial disk_sectors disk_id flags\n");
4522     for (i = 0; i < meta->total_disks; i++ ) {
4523         printf("    %d   <%.16s> %u 0x%08x 0x%08x\n", i,
4524                meta->disk[i].serial, meta->disk[i].sectors,
4525                meta->disk[i].id, meta->disk[i].flags);
4526     }
4527     map = (struct intel_raid_mapping *)&meta->disk[meta->total_disks];
4528     for (j = 0; j < meta->total_volumes; j++) {
4529         printf("name                %.16s\n", map->name);
4530         printf("total_sectors       %ju\n", map->total_sectors);
4531         printf("state               %u\n", map->state);
4532         printf("reserved            %u\n", map->reserved);
4533         printf("offset              %u\n", map->offset);
4534         printf("disk_sectors        %u\n", map->disk_sectors);
4535         printf("stripe_count        %u\n", map->stripe_count);
4536         printf("stripe_sectors      %u\n", map->stripe_sectors);
4537         printf("status              %u\n", map->status);
4538         printf("type                %s\n", ata_raid_intel_type(map->type));
4539         printf("total_disks         %u\n", map->total_disks);
4540         printf("magic[0]            0x%02x\n", map->magic[0]);
4541         printf("magic[1]            0x%02x\n", map->magic[1]);
4542         printf("magic[2]            0x%02x\n", map->magic[2]);
4543         for (i = 0; i < map->total_disks; i++ ) {
4544             printf("    disk %d at disk_idx 0x%08x\n", i, map->disk_idx[i]);
4545         }
4546         map = (struct intel_raid_mapping *)&map->disk_idx[map->total_disks];
4547     }
4548     printf("=================================================\n");
4549 }
4550
4551 static char *
4552 ata_raid_ite_type(int type)
4553 {
4554     static char buffer[16];
4555
4556     switch (type) {
4557     case ITE_T_RAID0:   return "RAID0";
4558     case ITE_T_RAID1:   return "RAID1";
4559     case ITE_T_RAID01:  return "RAID0+1";
4560     case ITE_T_SPAN:    return "SPAN";
4561     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4562                         return buffer;
4563     }
4564 }
4565
4566 static void
4567 ata_raid_ite_print_meta(struct ite_raid_conf *meta)
4568 {
4569     printf("*** ATA Integrated Technology Express Metadata **\n");
4570     printf("ite_id              <%.40s>\n", meta->ite_id);
4571     printf("timestamp_0         %04x/%02x/%02x %02x:%02x:%02x.%02x\n",
4572            *((u_int16_t *)meta->timestamp_0), meta->timestamp_0[2],
4573            meta->timestamp_0[3], meta->timestamp_0[5], meta->timestamp_0[4],
4574            meta->timestamp_0[7], meta->timestamp_0[6]);
4575     printf("total_sectors       %jd\n", meta->total_sectors);
4576     printf("type                %s\n", ata_raid_ite_type(meta->type));
4577     printf("stripe_1kblocks     %u\n", meta->stripe_1kblocks);
4578     printf("timestamp_1         %04x/%02x/%02x %02x:%02x:%02x.%02x\n",
4579            *((u_int16_t *)meta->timestamp_1), meta->timestamp_1[2],
4580            meta->timestamp_1[3], meta->timestamp_1[5], meta->timestamp_1[4],
4581            meta->timestamp_1[7], meta->timestamp_1[6]);
4582     printf("stripe_sectors      %u\n", meta->stripe_sectors);
4583     printf("array_width         %u\n", meta->array_width);
4584     printf("disk_number         %u\n", meta->disk_number);
4585     printf("disk_sectors        %u\n", meta->disk_sectors);
4586     printf("=================================================\n");
4587 }
4588
4589 static char *
4590 ata_raid_jmicron_type(int type)
4591 {
4592     static char buffer[16];
4593
4594     switch (type) {
4595     case JM_T_RAID0:    return "RAID0";
4596     case JM_T_RAID1:    return "RAID1";
4597     case JM_T_RAID01:   return "RAID0+1";
4598     case JM_T_JBOD:     return "JBOD";
4599     case JM_T_RAID5:    return "RAID5";
4600     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4601                         return buffer;
4602     }
4603 }
4604
4605 static void
4606 ata_raid_jmicron_print_meta(struct jmicron_raid_conf *meta)
4607 {
4608     int i;
4609
4610     printf("***** ATA JMicron Technology Corp Metadata ******\n");
4611     printf("signature           %.2s\n", meta->signature);
4612     printf("version             0x%04x\n", meta->version);
4613     printf("checksum            0x%04x\n", meta->checksum);
4614     printf("disk_id             0x%08x\n", meta->disk_id);
4615     printf("offset              0x%08x\n", meta->offset);
4616     printf("disk_sectors_low    0x%08x\n", meta->disk_sectors_low);
4617     printf("disk_sectors_high   0x%08x\n", meta->disk_sectors_high);
4618     printf("name                %.16s\n", meta->name);
4619     printf("type                %s\n", ata_raid_jmicron_type(meta->type));
4620     printf("stripe_shift        %d\n", meta->stripe_shift);
4621     printf("flags               0x%04x\n", meta->flags);
4622     printf("spare:\n");
4623     for (i=0; i < 2 && meta->spare[i]; i++)
4624         printf("    %d                  0x%08x\n", i, meta->spare[i]);
4625     printf("disks:\n");
4626     for (i=0; i < 8 && meta->disks[i]; i++)
4627         printf("    %d                  0x%08x\n", i, meta->disks[i]);
4628     printf("=================================================\n");
4629 }
4630
4631 static char *
4632 ata_raid_lsiv2_type(int type)
4633 {
4634     static char buffer[16];
4635
4636     switch (type) {
4637     case LSIV2_T_RAID0: return "RAID0";
4638     case LSIV2_T_RAID1: return "RAID1";
4639     case LSIV2_T_SPARE: return "SPARE";
4640     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4641                         return buffer;
4642     }
4643 }
4644
4645 static void
4646 ata_raid_lsiv2_print_meta(struct lsiv2_raid_conf *meta)
4647 {
4648     int i;
4649
4650     printf("******* ATA LSILogic V2 MegaRAID Metadata *******\n");
4651     printf("lsi_id              <%s>\n", meta->lsi_id);
4652     printf("dummy_0             0x%02x\n", meta->dummy_0);
4653     printf("flags               0x%02x\n", meta->flags);
4654     printf("version             0x%04x\n", meta->version);
4655     printf("config_entries      0x%02x\n", meta->config_entries);
4656     printf("raid_count          0x%02x\n", meta->raid_count);
4657     printf("total_disks         0x%02x\n", meta->total_disks);
4658     printf("dummy_1             0x%02x\n", meta->dummy_1);
4659     printf("dummy_2             0x%04x\n", meta->dummy_2);
4660     for (i = 0; i < meta->config_entries; i++) {
4661         printf("    type             %s\n",
4662                ata_raid_lsiv2_type(meta->configs[i].raid.type));
4663         printf("    dummy_0          %02x\n", meta->configs[i].raid.dummy_0);
4664         printf("    stripe_sectors   %u\n",
4665                meta->configs[i].raid.stripe_sectors);
4666         printf("    array_width      %u\n",
4667                meta->configs[i].raid.array_width);
4668         printf("    disk_count       %u\n", meta->configs[i].raid.disk_count);
4669         printf("    config_offset    %u\n",
4670                meta->configs[i].raid.config_offset);
4671         printf("    dummy_1          %u\n", meta->configs[i].raid.dummy_1);
4672         printf("    flags            %02x\n", meta->configs[i].raid.flags);
4673         printf("    total_sectors    %u\n",
4674                meta->configs[i].raid.total_sectors);
4675     }
4676     printf("disk_number         0x%02x\n", meta->disk_number);
4677     printf("raid_number         0x%02x\n", meta->raid_number);
4678     printf("timestamp           0x%08x\n", meta->timestamp);
4679     printf("=================================================\n");
4680 }
4681
4682 static char *
4683 ata_raid_lsiv3_type(int type)
4684 {
4685     static char buffer[16];
4686
4687     switch (type) {
4688     case LSIV3_T_RAID0: return "RAID0";
4689     case LSIV3_T_RAID1: return "RAID1";
4690     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4691                         return buffer;
4692     }
4693 }
4694
4695 static void
4696 ata_raid_lsiv3_print_meta(struct lsiv3_raid_conf *meta)
4697 {
4698     int i;
4699
4700     printf("******* ATA LSILogic V3 MegaRAID Metadata *******\n");
4701     printf("lsi_id              <%.6s>\n", meta->lsi_id);
4702     printf("dummy_0             0x%04x\n", meta->dummy_0);
4703     printf("version             0x%04x\n", meta->version);
4704     printf("dummy_0             0x%04x\n", meta->dummy_1);
4705     printf("RAID configs:\n");
4706     for (i = 0; i < 8; i++) {
4707         if (meta->raid[i].total_disks) {
4708             printf("%02d  stripe_pages       %u\n", i,
4709                    meta->raid[i].stripe_pages);
4710             printf("%02d  type               %s\n", i,
4711                    ata_raid_lsiv3_type(meta->raid[i].type));
4712             printf("%02d  total_disks        %u\n", i,
4713                    meta->raid[i].total_disks);
4714             printf("%02d  array_width        %u\n", i,
4715                    meta->raid[i].array_width);
4716             printf("%02d  sectors            %u\n", i, meta->raid[i].sectors);
4717             printf("%02d  offset             %u\n", i, meta->raid[i].offset);
4718             printf("%02d  device             0x%02x\n", i,
4719                    meta->raid[i].device);
4720         }
4721     }
4722     printf("DISK configs:\n");
4723     for (i = 0; i < 6; i++) {
4724             if (meta->disk[i].disk_sectors) {
4725             printf("%02d  disk_sectors       %u\n", i,
4726                    meta->disk[i].disk_sectors);
4727             printf("%02d  flags              0x%02x\n", i, meta->disk[i].flags);
4728         }
4729     }
4730     printf("device              0x%02x\n", meta->device);
4731     printf("timestamp           0x%08x\n", meta->timestamp);
4732     printf("checksum_1          0x%02x\n", meta->checksum_1);
4733     printf("=================================================\n");
4734 }
4735
4736 static char *
4737 ata_raid_nvidia_type(int type)
4738 {
4739     static char buffer[16];
4740
4741     switch (type) {
4742     case NV_T_SPAN:     return "SPAN";
4743     case NV_T_RAID0:    return "RAID0";
4744     case NV_T_RAID1:    return "RAID1";
4745     case NV_T_RAID3:    return "RAID3";
4746     case NV_T_RAID5:    return "RAID5";
4747     case NV_T_RAID01:   return "RAID0+1";
4748     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4749                         return buffer;
4750     }
4751 }
4752
4753 static void
4754 ata_raid_nvidia_print_meta(struct nvidia_raid_conf *meta)
4755 {
4756     printf("******** ATA nVidia MediaShield Metadata ********\n");
4757     printf("nvidia_id           <%.8s>\n", meta->nvidia_id);
4758     printf("config_size         %d\n", meta->config_size);
4759     printf("checksum            0x%08x\n", meta->checksum);
4760     printf("version             0x%04x\n", meta->version);
4761     printf("disk_number         %d\n", meta->disk_number);
4762     printf("dummy_0             0x%02x\n", meta->dummy_0);
4763     printf("total_sectors       %d\n", meta->total_sectors);
4764     printf("sectors_size        %d\n", meta->sector_size);
4765     printf("serial              %.16s\n", meta->serial);
4766     printf("revision            %.4s\n", meta->revision);
4767     printf("dummy_1             0x%08x\n", meta->dummy_1);
4768     printf("magic_0             0x%08x\n", meta->magic_0);
4769     printf("magic_1             0x%016jx\n", meta->magic_1);
4770     printf("magic_2             0x%016jx\n", meta->magic_2);
4771     printf("flags               0x%02x\n", meta->flags);
4772     printf("array_width         %d\n", meta->array_width);
4773     printf("total_disks         %d\n", meta->total_disks);
4774     printf("dummy_2             0x%02x\n", meta->dummy_2);
4775     printf("type                %s\n", ata_raid_nvidia_type(meta->type));
4776     printf("dummy_3             0x%04x\n", meta->dummy_3);
4777     printf("stripe_sectors      %d\n", meta->stripe_sectors);
4778     printf("stripe_bytes        %d\n", meta->stripe_bytes);
4779     printf("stripe_shift        %d\n", meta->stripe_shift);
4780     printf("stripe_mask         0x%08x\n", meta->stripe_mask);
4781     printf("stripe_sizesectors  %d\n", meta->stripe_sizesectors);
4782     printf("stripe_sizebytes    %d\n", meta->stripe_sizebytes);
4783     printf("rebuild_lba         %d\n", meta->rebuild_lba);
4784     printf("dummy_4             0x%08x\n", meta->dummy_4);
4785     printf("dummy_5             0x%08x\n", meta->dummy_5);
4786     printf("status              0x%08x\n", meta->status);
4787     printf("=================================================\n");
4788 }
4789
4790 static char *
4791 ata_raid_promise_type(int type)
4792 {
4793     static char buffer[16];
4794
4795     switch (type) {
4796     case PR_T_RAID0:    return "RAID0";
4797     case PR_T_RAID1:    return "RAID1";
4798     case PR_T_RAID3:    return "RAID3";
4799     case PR_T_RAID5:    return "RAID5";
4800     case PR_T_SPAN:     return "SPAN";
4801     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4802                         return buffer;
4803     }
4804 }
4805
4806 static void
4807 ata_raid_promise_print_meta(struct promise_raid_conf *meta)
4808 {
4809     int i;
4810
4811     printf("********* ATA Promise FastTrak Metadata *********\n");
4812     printf("promise_id          <%s>\n", meta->promise_id);
4813     printf("dummy_0             0x%08x\n", meta->dummy_0);
4814     printf("magic_0             0x%016jx\n", meta->magic_0);
4815     printf("magic_1             0x%04x\n", meta->magic_1);
4816     printf("magic_2             0x%08x\n", meta->magic_2);
4817     printf("integrity           0x%08x %b\n", meta->raid.integrity,
4818                 meta->raid.integrity, "\20\10VALID\n" );
4819     printf("flags               0x%02x %b\n",
4820            meta->raid.flags, meta->raid.flags,
4821            "\20\10READY\7DOWN\6REDIR\5DUPLICATE\4SPARE"
4822            "\3ASSIGNED\2ONLINE\1VALID\n");
4823     printf("disk_number         %d\n", meta->raid.disk_number);
4824     printf("channel             0x%02x\n", meta->raid.channel);
4825     printf("device              0x%02x\n", meta->raid.device);
4826     printf("magic_0             0x%016jx\n", meta->raid.magic_0);
4827     printf("disk_offset         %u\n", meta->raid.disk_offset);
4828     printf("disk_sectors        %u\n", meta->raid.disk_sectors);
4829     printf("rebuild_lba         0x%08x\n", meta->raid.rebuild_lba);
4830     printf("generation          0x%04x\n", meta->raid.generation);
4831     printf("status              0x%02x %b\n",
4832             meta->raid.status, meta->raid.status,
4833            "\20\6MARKED\5DEGRADED\4READY\3INITED\2ONLINE\1VALID\n");
4834     printf("type                %s\n", ata_raid_promise_type(meta->raid.type));
4835     printf("total_disks         %u\n", meta->raid.total_disks);
4836     printf("stripe_shift        %u\n", meta->raid.stripe_shift);
4837     printf("array_width         %u\n", meta->raid.array_width);
4838     printf("array_number        %u\n", meta->raid.array_number);
4839     printf("total_sectors       %u\n", meta->raid.total_sectors);
4840     printf("cylinders           %u\n", meta->raid.cylinders);
4841     printf("heads               %u\n", meta->raid.heads);
4842     printf("sectors             %u\n", meta->raid.sectors);
4843     printf("magic_1             0x%016jx\n", meta->raid.magic_1);
4844     printf("DISK#   flags dummy_0 channel device  magic_0\n");
4845     for (i = 0; i < 8; i++) {
4846         printf("  %d    %b    0x%02x  0x%02x  0x%02x  ",
4847                i, meta->raid.disk[i].flags,
4848                "\20\10READY\7DOWN\6REDIR\5DUPLICATE\4SPARE"
4849                "\3ASSIGNED\2ONLINE\1VALID\n", meta->raid.disk[i].dummy_0,
4850                meta->raid.disk[i].channel, meta->raid.disk[i].device);
4851         printf("0x%016jx\n", meta->raid.disk[i].magic_0);
4852     }
4853     printf("checksum            0x%08x\n", meta->checksum);
4854     printf("=================================================\n");
4855 }
4856
4857 static char *
4858 ata_raid_sii_type(int type)
4859 {
4860     static char buffer[16];
4861
4862     switch (type) {
4863     case SII_T_RAID0:   return "RAID0";
4864     case SII_T_RAID1:   return "RAID1";
4865     case SII_T_RAID01:  return "RAID0+1";
4866     case SII_T_SPARE:   return "SPARE";
4867     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4868                         return buffer;
4869     }
4870 }
4871
4872 static void
4873 ata_raid_sii_print_meta(struct sii_raid_conf *meta)
4874 {
4875     printf("******* ATA Silicon Image Medley Metadata *******\n");
4876     printf("total_sectors       %ju\n", meta->total_sectors);
4877     printf("dummy_0             0x%04x\n", meta->dummy_0);
4878     printf("dummy_1             0x%04x\n", meta->dummy_1);
4879     printf("controller_pci_id   0x%08x\n", meta->controller_pci_id);
4880     printf("version_minor       0x%04x\n", meta->version_minor);
4881     printf("version_major       0x%04x\n", meta->version_major);
4882     printf("timestamp           20%02x/%02x/%02x %02x:%02x:%02x\n",
4883            meta->timestamp[5], meta->timestamp[4], meta->timestamp[3],
4884            meta->timestamp[2], meta->timestamp[1], meta->timestamp[0]);
4885     printf("stripe_sectors      %u\n", meta->stripe_sectors);
4886     printf("dummy_2             0x%04x\n", meta->dummy_2);
4887     printf("disk_number         %u\n", meta->disk_number);
4888     printf("type                %s\n", ata_raid_sii_type(meta->type));
4889     printf("raid0_disks         %u\n", meta->raid0_disks);
4890     printf("raid0_ident         %u\n", meta->raid0_ident);
4891     printf("raid1_disks         %u\n", meta->raid1_disks);
4892     printf("raid1_ident         %u\n", meta->raid1_ident);
4893     printf("rebuild_lba         %ju\n", meta->rebuild_lba);
4894     printf("generation          0x%08x\n", meta->generation);
4895     printf("status              0x%02x %b\n",
4896             meta->status, meta->status,
4897            "\20\1READY\n");
4898     printf("base_raid1_position %02x\n", meta->base_raid1_position);
4899     printf("base_raid0_position %02x\n", meta->base_raid0_position);
4900     printf("position            %02x\n", meta->position);
4901     printf("dummy_3             %04x\n", meta->dummy_3);
4902     printf("name                <%.16s>\n", meta->name);
4903     printf("checksum_0          0x%04x\n", meta->checksum_0);
4904     printf("checksum_1          0x%04x\n", meta->checksum_1);
4905     printf("=================================================\n");
4906 }
4907
4908 static char *
4909 ata_raid_sis_type(int type)
4910 {
4911     static char buffer[16];
4912
4913     switch (type) {
4914     case SIS_T_JBOD:    return "JBOD";
4915     case SIS_T_RAID0:   return "RAID0";
4916     case SIS_T_RAID1:   return "RAID1";
4917     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4918                         return buffer;
4919     }
4920 }
4921
4922 static void
4923 ata_raid_sis_print_meta(struct sis_raid_conf *meta)
4924 {
4925     printf("**** ATA Silicon Integrated Systems Metadata ****\n");
4926     printf("magic               0x%04x\n", meta->magic);
4927     printf("disks               0x%02x\n", meta->disks);
4928     printf("type                %s\n",
4929            ata_raid_sis_type(meta->type_total_disks & SIS_T_MASK));
4930     printf("total_disks         %u\n", meta->type_total_disks & SIS_D_MASK);
4931     printf("dummy_0             0x%08x\n", meta->dummy_0);
4932     printf("controller_pci_id   0x%08x\n", meta->controller_pci_id);
4933     printf("stripe_sectors      %u\n", meta->stripe_sectors);
4934     printf("dummy_1             0x%04x\n", meta->dummy_1);
4935     printf("timestamp           0x%08x\n", meta->timestamp);
4936     printf("model               %.40s\n", meta->model);
4937     printf("disk_number         %u\n", meta->disk_number);
4938     printf("dummy_2             0x%02x 0x%02x 0x%02x\n",
4939            meta->dummy_2[0], meta->dummy_2[1], meta->dummy_2[2]);
4940     printf("=================================================\n");
4941 }
4942
4943 static char *
4944 ata_raid_via_type(int type)
4945 {
4946     static char buffer[16];
4947
4948     switch (type) {
4949     case VIA_T_RAID0:   return "RAID0";
4950     case VIA_T_RAID1:   return "RAID1";
4951     case VIA_T_RAID5:   return "RAID5";
4952     case VIA_T_RAID01:  return "RAID0+1";
4953     case VIA_T_SPAN:    return "SPAN";
4954     default:            sprintf(buffer, "UNKNOWN 0x%02x", type);
4955                         return buffer;
4956     }
4957 }
4958
4959 static void
4960 ata_raid_via_print_meta(struct via_raid_conf *meta)
4961 {
4962     int i;
4963   
4964     printf("*************** ATA VIA Metadata ****************\n");
4965     printf("magic               0x%02x\n", meta->magic);
4966     printf("dummy_0             0x%02x\n", meta->dummy_0);
4967     printf("type                %s\n",
4968            ata_raid_via_type(meta->type & VIA_T_MASK));
4969     printf("bootable            %d\n", meta->type & VIA_T_BOOTABLE);
4970     printf("unknown             %d\n", meta->type & VIA_T_UNKNOWN);
4971     printf("disk_index          0x%02x\n", meta->disk_index);
4972     printf("stripe_layout       0x%02x\n", meta->stripe_layout);
4973     printf(" stripe_disks       %d\n", meta->stripe_layout & VIA_L_DISKS);
4974     printf(" stripe_sectors     %d\n",
4975            0x08 << ((meta->stripe_layout & VIA_L_MASK) >> VIA_L_SHIFT));
4976     printf("disk_sectors        %ju\n", meta->disk_sectors);
4977     printf("disk_id             0x%08x\n", meta->disk_id);
4978     printf("DISK#   disk_id\n");
4979     for (i = 0; i < 8; i++) {
4980         if (meta->disks[i])
4981             printf("  %d    0x%08x\n", i, meta->disks[i]);
4982     }    
4983     printf("checksum            0x%02x\n", meta->checksum);
4984     printf("=================================================\n");
4985 }