The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ata/ata-raid.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 3e8e37e7e8b9b1c351a63bed89840fcd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.