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