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