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