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