[BACK]Return to rf_openbsdkintf.c CVS log [TXT][DIR] Up to [local] / sys / dev / raidframe

Annotation of sys/dev/raidframe/rf_openbsdkintf.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: rf_openbsdkintf.c,v 1.42 2007/06/23 03:11:34 krw Exp $    */
                      2: /* $NetBSD: rf_netbsdkintf.c,v 1.109 2001/07/27 03:30:07 oster Exp $   */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Greg Oster; Jason R. Thorpe.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *       This product includes software developed by the NetBSD
                     22:  *       Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: /*
                     41:  * Copyright (c) 1988 University of Utah.
                     42:  * Copyright (c) 1990, 1993
                     43:  *     The Regents of the University of California.  All rights reserved.
                     44:  *
                     45:  * This code is derived from software contributed to Berkeley by
                     46:  * the Systems Programming Group of the University of Utah Computer
                     47:  * Science Department.
                     48:  *
                     49:  * Redistribution and use in source and binary forms, with or without
                     50:  * modification, are permitted provided that the following conditions
                     51:  * are met:
                     52:  * 1. Redistributions of source code must retain the above copyright
                     53:  *    notice, this list of conditions and the following disclaimer.
                     54:  * 2. Redistributions in binary form must reproduce the above copyright
                     55:  *    notice, this list of conditions and the following disclaimer in the
                     56:  *    documentation and/or other materials provided with the distribution.
                     57:  * 3. Neither the name of the University nor the names of its contributors
                     58:  *    may be used to endorse or promote products derived from this software
                     59:  *    without specific prior written permission.
                     60:  *
                     61:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     62:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     63:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     64:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     65:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     66:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     67:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     68:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     69:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     70:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     71:  * SUCH DAMAGE.
                     72:  *
                     73:  * from: Utah $Hdr: cd.c 1.6 90/11/28$
                     74:  *
                     75:  *     @(#)cd.c        8.2 (Berkeley) 11/16/93
                     76:  */
                     77:
                     78: /*
                     79:  * Copyright (c) 1995 Carnegie-Mellon University.
                     80:  * All rights reserved.
                     81:  *
                     82:  * Authors: Mark Holland, Jim Zelenka
                     83:  *
                     84:  * Permission to use, copy, modify and distribute this software and
                     85:  * its documentation is hereby granted, provided that both the copyright
                     86:  * notice and this permission notice appear in all copies of the
                     87:  * software, derivative works or modified versions, and any portions
                     88:  * thereof, and that both notices appear in supporting documentation.
                     89:  *
                     90:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     91:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
                     92:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     93:  *
                     94:  * Carnegie Mellon requests users of this software to return to
                     95:  *
                     96:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     97:  *  School of Computer Science
                     98:  *  Carnegie Mellon University
                     99:  *  Pittsburgh PA 15213-3890
                    100:  *
                    101:  * any improvements or extensions that they make and grant Carnegie the
                    102:  * rights to redistribute these changes.
                    103:  */
                    104:
                    105: /*****************************************************************************
                    106:  *
                    107:  * rf_kintf.c -- The kernel interface routines for RAIDframe.
                    108:  *
                    109:  *****************************************************************************/
                    110:
                    111: #include <sys/errno.h>
                    112:
                    113: #include <sys/param.h>
                    114: #include <sys/pool.h>
                    115: #include <sys/malloc.h>
                    116: #include <sys/queue.h>
                    117: #include <sys/disk.h>
                    118: #include <sys/device.h>
                    119: #include <sys/stat.h>
                    120: #include <sys/ioctl.h>
                    121: #include <sys/fcntl.h>
                    122: #include <sys/systm.h>
                    123: #include <sys/namei.h>
                    124: #include <sys/conf.h>
                    125: #include <sys/lock.h>
                    126: #include <sys/buf.h>
                    127: #include <sys/user.h>
                    128: #include <sys/reboot.h>
                    129:
                    130: #include "raid.h"
                    131: #include "rf_raid.h"
                    132: #include "rf_raidframe.h"
                    133: #include "rf_copyback.h"
                    134: #include "rf_dag.h"
                    135: #include "rf_dagflags.h"
                    136: #include "rf_desc.h"
                    137: #include "rf_diskqueue.h"
                    138: #include "rf_engine.h"
                    139: #include "rf_acctrace.h"
                    140: #include "rf_etimer.h"
                    141: #include "rf_general.h"
                    142: #include "rf_debugMem.h"
                    143: #include "rf_kintf.h"
                    144: #include "rf_options.h"
                    145: #include "rf_driver.h"
                    146: #include "rf_parityscan.h"
                    147: #include "rf_debugprint.h"
                    148: #include "rf_threadstuff.h"
                    149: #include "rf_configure.h"
                    150:
                    151: int    rf_kdebug_level = 0;
                    152:
                    153: #ifdef RAIDDEBUG
                    154: #define        db1_printf(a) do { if (rf_kdebug_level > 0) printf a; } while(0)
                    155: #else  /* RAIDDEBUG */
                    156: #define        db1_printf(a) (void)0
                    157: #endif /* ! RAIDDEBUG */
                    158:
                    159: static RF_Raid_t **raidPtrs;   /* Global raid device descriptors. */
                    160:
                    161: RF_DECLARE_STATIC_MUTEX(rf_sparet_wait_mutex);
                    162:
                    163: /* Requests to install a spare table. */
                    164: static RF_SparetWait_t *rf_sparet_wait_queue;
                    165:
                    166: /* Responses from installation process. */
                    167: static RF_SparetWait_t *rf_sparet_resp_queue;
                    168:
                    169: /* Prototypes. */
                    170: void rf_KernelWakeupFunc(struct buf *);
                    171: void rf_InitBP(struct buf *, struct vnode *, unsigned, dev_t, RF_SectorNum_t,
                    172:     RF_SectorCount_t, caddr_t, void (*)(struct buf *), void *, int,
                    173:     struct proc *);
                    174: void raidinit(RF_Raid_t *);
                    175:
                    176: void raidattach(int);
                    177: daddr64_t raidsize(dev_t);
                    178: int  raidopen(dev_t, int, int, struct proc *);
                    179: int  raidclose(dev_t, int, int, struct proc *);
                    180: int  raidioctl(dev_t, u_long, caddr_t, int, struct proc *);
                    181: int  raidwrite(dev_t, struct uio *, int);
                    182: int  raidread(dev_t, struct uio *, int);
                    183: void raidstrategy(struct buf *);
                    184: int  raiddump(dev_t, daddr64_t, caddr_t, size_t);
                    185:
                    186: /*
                    187:  * Pilfered from ccd.c
                    188:  */
                    189: struct raidbuf {
                    190:        struct buf       rf_buf;        /* New I/O buf.  MUST BE FIRST!!! */
                    191:        struct buf      *rf_obp;        /* Ptr. to original I/O buf. */
                    192:        int              rf_flags;      /* Miscellaneous flags. */
                    193:        RF_DiskQueueData_t *req;        /* The request that this was part of. */
                    194: };
                    195:
                    196: #define        RAIDGETBUF(rs)          pool_get(&(rs)->sc_cbufpool, PR_NOWAIT)
                    197: #define        RAIDPUTBUF(rs, cbp)     pool_put(&(rs)->sc_cbufpool, cbp)
                    198:
                    199: /*
                    200:  * Some port (like i386) use a swapgeneric that wants to snoop around
                    201:  * in this raid_cd structure.  It is preserved (for now) to remain
                    202:  * compatible with such practice.
                    203:  */
                    204: struct cfdriver raid_cd = {
                    205:        NULL, "raid", DV_DISK
                    206: };
                    207:
                    208: /*
                    209:  * XXX Not sure if the following should be replacing the raidPtrs above,
                    210:  * or if it should be used in conjunction with that...
                    211:  */
                    212: struct raid_softc {
                    213:        int             sc_flags;               /* Flags. */
                    214:        int             sc_cflags;              /* Configuration flags. */
                    215:        size_t          sc_size;                /* Size of the raid device. */
                    216:        char            sc_xname[20];           /* XXX external name. */
                    217:        struct disk     sc_dkdev;               /* Generic disk device info. */
                    218:        struct pool     sc_cbufpool;            /* Component buffer pool. */
                    219:        struct buf      sc_q;                   /* Used for the device queue. */
                    220: };
                    221:
                    222: /* sc_flags */
                    223: #define        RAIDF_INITED    0x01    /* Unit has been initialized. */
                    224: #define        RAIDF_WLABEL    0x02    /* Label area is writable. */
                    225: #define        RAIDF_LABELLING 0x04    /* Unit is currently being labelled. */
                    226: #define        RAIDF_WANTED    0x40    /* Someone is waiting to obtain a lock. */
                    227: #define        RAIDF_LOCKED    0x80    /* Unit is locked. */
                    228:
                    229: int numraid = 0;
                    230:
                    231: /*
                    232:  * Here we define a cfattach structure for inserting any new raid device
                    233:  * into the device tree.  This is needed by some archs that look for
                    234:  * bootable devices in there.
                    235:  */
                    236: int  rf_probe(struct device *, void *, void *);
                    237: void rf_attach(struct device *, struct device *, void *);
                    238: int  rf_detach(struct device *, int);
                    239: int  rf_activate(struct device *, enum devact);
                    240:
                    241: struct cfattach raid_ca = {
                    242:        sizeof(struct raid_softc), rf_probe, rf_attach,
                    243:        rf_detach, rf_activate
                    244: };
                    245:
                    246: /*
                    247:  * Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device.
                    248:  * Be aware that large numbers can allow the driver to consume a lot of
                    249:  * kernel memory, especially on writes, and in degraded mode reads.
                    250:  *
                    251:  * For example: with a stripe width of 64 blocks (32k) and 5 disks,
                    252:  * a single 64K write will typically require 64K for the old data,
                    253:  * 64K for the old parity, and 64K for the new parity, for a total
                    254:  * of 192K (if the parity buffer is not re-used immediately).
                    255:  * Even it if is used immedately, that's still 128K, which when multiplied
                    256:  * by say 10 requests, is 1280K, *on top* of the 640K of incoming data.
                    257:  *
                    258:  * Now in degraded mode, for example, a 64K read on the above setup may
                    259:  * require data reconstruction, which will require *all* of the 4 remaining
                    260:  * disks to participate -- 4 * 32K/disk == 128K again.
                    261:  */
                    262:
                    263: #ifndef        RAIDOUTSTANDING
                    264: #define        RAIDOUTSTANDING         6
                    265: #endif
                    266:
                    267: /* Declared here, and made public, for the benefit of KVM stuff... */
                    268: struct raid_softc  *raid_softc;
                    269: struct raid_softc **raid_scPtrs;
                    270:
                    271: void rf_shutdown_hook(RF_ThreadArg_t);
                    272: void raidgetdefaultlabel(RF_Raid_t *, struct raid_softc *, struct disklabel *);
                    273: void raidgetdisklabel(dev_t, struct disklabel *, int);
                    274:
                    275: int  raidlock(struct raid_softc *);
                    276: void raidunlock(struct raid_softc *);
                    277:
                    278: void rf_markalldirty(RF_Raid_t *);
                    279:
                    280: struct device *raidrootdev;
                    281:
                    282: int  findblkmajor(struct device *dv);
                    283: char *findblkname(int);
                    284:
                    285: void rf_ReconThread(struct rf_recon_req *);
                    286: /* XXX what I want is: */
                    287: /*void rf_ReconThread(RF_Raid_t *raidPtr);*/
                    288: void rf_RewriteParityThread(RF_Raid_t *raidPtr);
                    289: void rf_CopybackThread(RF_Raid_t *raidPtr);
                    290: void rf_ReconstructInPlaceThread(struct rf_recon_req *);
                    291: #ifdef RAID_AUTOCONFIG
                    292: void rf_buildroothack(void *);
                    293: int  rf_reasonable_label(RF_ComponentLabel_t *);
                    294: #endif /* RAID_AUTOCONFIG */
                    295:
                    296: RF_AutoConfig_t *rf_find_raid_components(void);
                    297: RF_ConfigSet_t *rf_create_auto_sets(RF_AutoConfig_t *);
                    298: int  rf_does_it_fit(RF_ConfigSet_t *,RF_AutoConfig_t *);
                    299: void rf_create_configuration(RF_AutoConfig_t *,RF_Config_t *,
                    300:                                  RF_Raid_t *);
                    301: int  rf_set_autoconfig(RF_Raid_t *, int);
                    302: int  rf_set_rootpartition(RF_Raid_t *, int);
                    303: void rf_release_all_vps(RF_ConfigSet_t *);
                    304: void rf_cleanup_config_set(RF_ConfigSet_t *);
                    305: int  rf_have_enough_components(RF_ConfigSet_t *);
                    306: int  rf_auto_config_set(RF_ConfigSet_t *, int *);
                    307:
                    308: #ifdef RAID_AUTOCONFIG
                    309: static int raidautoconfig = 0; /*
                    310:                                 * Debugging, mostly.  Set to 0 to not
                    311:                                 * allow autoconfig to take place.
                    312:                                 * Note that this is overridden by having
                    313:                                 * RAID_AUTOCONFIG as an option in the
                    314:                                 * kernel config file.
                    315:                                 */
                    316: #endif /* RAID_AUTOCONFIG */
                    317:
                    318: int
                    319: rf_probe(struct device *parent, void *match_, void *aux)
                    320: {
                    321:        return 0;
                    322: }
                    323:
                    324: void
                    325: rf_attach(struct device *parent, struct device *self, void *aux)
                    326: {
                    327:        /*struct raid_softc *raid = (void *)self;*/
                    328: }
                    329:
                    330: int
                    331: rf_detach(struct device *self, int flags)
                    332: {
                    333:        return 0;
                    334: }
                    335:
                    336: int
                    337: rf_activate(struct device *self, enum devact act)
                    338: {
                    339:        return 0;
                    340: }
                    341:
                    342: void
                    343: raidattach(int num)
                    344: {
                    345:        int raidID;
                    346:        int i, rc;
                    347: #ifdef RAID_AUTOCONFIG
                    348:        RF_AutoConfig_t *ac_list;       /* Autoconfig list. */
                    349:        RF_ConfigSet_t *config_sets;
                    350: #endif /* RAID_AUTOCONFIG */
                    351:
                    352:        db1_printf(("raidattach: Asked for %d units\n", num));
                    353:
                    354:        if (num <= 0) {
                    355: #ifdef DIAGNOSTIC
                    356:                panic("raidattach: count <= 0");
                    357: #endif /* DIAGNOSTIC */
                    358:                return;
                    359:        }
                    360:
                    361:        /* This is where all the initialization stuff gets done. */
                    362:
                    363:        numraid = num;
                    364:
                    365:        /* Make some space for requested number of units... */
                    366:        RF_Calloc(raidPtrs, num, sizeof(RF_Raid_t *), (RF_Raid_t **));
                    367:        if (raidPtrs == NULL) {
                    368:                panic("raidPtrs is NULL!!");
                    369:        }
                    370:
                    371:        rc = rf_mutex_init(&rf_sparet_wait_mutex);
                    372:        if (rc) {
                    373:                RF_PANIC();
                    374:        }
                    375:
                    376:        rf_sparet_wait_queue = rf_sparet_resp_queue = NULL;
                    377:
                    378:        for (i = 0; i < num; i++)
                    379:                raidPtrs[i] = NULL;
                    380:        rc = rf_BootRaidframe();
                    381:        if (rc == 0)
                    382:                printf("Kernelized RAIDframe activated\n");
                    383:        else
                    384:                panic("Serious error booting RAID !!!");
                    385:
                    386:        /*
                    387:         * Put together some datastructures like the CCD device does...
                    388:         * This lets us lock the device and what-not when it gets opened.
                    389:         */
                    390:
                    391:        raid_softc = (struct raid_softc *)
                    392:                malloc(num * sizeof(struct raid_softc), M_RAIDFRAME, M_NOWAIT);
                    393:        if (raid_softc == NULL) {
                    394:                printf("WARNING: no memory for RAIDframe driver\n");
                    395:                return;
                    396:        }
                    397:
                    398:        bzero(raid_softc, num * sizeof (struct raid_softc));
                    399:
                    400:        raid_scPtrs = (struct raid_softc **)
                    401:                malloc(num * sizeof(struct raid_softc *), M_RAIDFRAME,
                    402:                    M_NOWAIT);
                    403:        if (raid_scPtrs == NULL) {
                    404:                printf("WARNING: no memory for RAIDframe driver\n");
                    405:                return;
                    406:        }
                    407:
                    408:        bzero(raid_scPtrs, num * sizeof (struct raid_softc *));
                    409:
                    410:        raidrootdev = (struct device *)malloc(num * sizeof(struct device),
                    411:            M_RAIDFRAME, M_NOWAIT);
                    412:        if (raidrootdev == NULL) {
                    413:                panic("No memory for RAIDframe driver!!?!?!");
                    414:        }
                    415:
                    416:        for (raidID = 0; raidID < num; raidID++) {
                    417: #if 0
                    418:                SIMPLEQ_INIT(&raid_softc[raidID].sc_q);
                    419: #endif
                    420:
                    421:                raidrootdev[raidID].dv_class  = DV_DISK;
                    422:                raidrootdev[raidID].dv_cfdata = NULL;
                    423:                raidrootdev[raidID].dv_unit   = raidID;
                    424:                raidrootdev[raidID].dv_parent = NULL;
                    425:                raidrootdev[raidID].dv_flags  = 0;
                    426:                snprintf(raidrootdev[raidID].dv_xname,
                    427:                    sizeof raidrootdev[raidID].dv_xname,"raid%d",raidID);
                    428:
                    429:                RF_Calloc(raidPtrs[raidID], 1, sizeof (RF_Raid_t),
                    430:                    (RF_Raid_t *));
                    431:                if (raidPtrs[raidID] == NULL) {
                    432:                        printf("WARNING: raidPtrs[%d] is NULL\n", raidID);
                    433:                        numraid = raidID;
                    434:                        return;
                    435:                }
                    436:        }
                    437:
                    438:        raid_cd.cd_devs = (void **) raid_scPtrs;
                    439:        raid_cd.cd_ndevs = num;
                    440:
                    441: #ifdef RAID_AUTOCONFIG
                    442:        raidautoconfig = 1;
                    443:
                    444:        if (raidautoconfig) {
                    445:                /* 1. Locate all RAID components on the system. */
                    446:
                    447: #ifdef RAIDDEBUG
                    448:                printf("Searching for raid components...\n");
                    449: #endif /* RAIDDEBUG */
                    450:                ac_list = rf_find_raid_components();
                    451:
                    452:                /* 2. Sort them into their respective sets. */
                    453:
                    454:                config_sets = rf_create_auto_sets(ac_list);
                    455:
                    456:                /*
                    457:                 * 3. Evaluate each set and configure the valid ones
                    458:                 * This gets done in rf_buildroothack().
                    459:                 */
                    460:
                    461:                /*
                    462:                 * Schedule the creation of the thread to do the
                    463:                 * "/ on RAID" stuff.
                    464:                 */
                    465:
                    466:                rf_buildroothack(config_sets);
                    467:
                    468:        }
                    469: #endif /* RAID_AUTOCONFIG */
                    470:
                    471: }
                    472:
                    473: #ifdef RAID_AUTOCONFIG
                    474: void
                    475: rf_buildroothack(void *arg)
                    476: {
                    477:        RF_ConfigSet_t *config_sets = arg;
                    478:        RF_ConfigSet_t *cset;
                    479:        RF_ConfigSet_t *next_cset;
                    480:        int retcode;
                    481:        int raidID;
                    482:        int rootID;
                    483:        int num_root;
                    484:        int majdev;
                    485:
                    486:        rootID = 0;
                    487:        num_root = 0;
                    488:        cset = config_sets;
                    489:        while(cset != NULL ) {
                    490:                next_cset = cset->next;
                    491:                if (rf_have_enough_components(cset) &&
                    492:                    cset->ac->clabel->autoconfigure==1) {
                    493:                        retcode = rf_auto_config_set(cset,&raidID);
                    494:                        if (!retcode) {
                    495:                                if (cset->rootable) {
                    496:                                        rootID = raidID;
                    497: #ifdef RAIDDEBUG
                    498:                                        printf("eligible root device %d:"
                    499:                                            " raid%d\n", num_root, rootID);
                    500: #endif /* RAIDDEBUG */
                    501:                                        num_root++;
                    502:                                }
                    503:                        } else {
                    504:                                /* The autoconfig didn't work :( */
                    505: #ifdef RAIDDEBUG
                    506:                                printf("Autoconfig failed with code %d for"
                    507:                                    " raid%d\n", retcode, raidID);
                    508: #endif /* RAIDDEBUG */
                    509:                                rf_release_all_vps(cset);
                    510:                        }
                    511:                } else {
                    512:                        /*
                    513:                         * We're not autoconfiguring this set...
                    514:                         * Release the associated resources.
                    515:                         */
                    516:                        rf_release_all_vps(cset);
                    517:                }
                    518:                /* Cleanup. */
                    519:                rf_cleanup_config_set(cset);
                    520:                cset = next_cset;
                    521:        }
                    522:        if (boothowto & RB_ASKNAME) {
                    523:                /* We don't auto-config... */
                    524:        } else {
                    525:                /* They didn't ask, and we found something bootable... */
                    526:
                    527:                if (num_root == 1) {
                    528:                        majdev = findblkmajor(&raidrootdev[rootID]);
                    529:                        if (majdev < 0)
                    530:                                boothowto |= RB_ASKNAME;
                    531:                        else {
                    532:                                rootdev = MAKEDISKDEV(majdev,rootID,0);
                    533:                                boothowto |= RB_DFLTROOT;
                    534:                        }
                    535:                } else if (num_root > 1) {
                    536:                        /* We can't guess... Require the user to answer... */
                    537:                        boothowto |= RB_ASKNAME;
                    538:                }
                    539:        }
                    540: }
                    541: #endif /* RAID_AUTOCONFIG */
                    542:
                    543: void
                    544: rf_shutdown_hook(RF_ThreadArg_t arg)
                    545: {
                    546:        int unit;
                    547:        struct raid_softc *rs;
                    548:        RF_Raid_t *raidPtr;
                    549:
                    550:        /* Don't do it if we are not "safe". */
                    551:        if (boothowto & RB_NOSYNC)
                    552:                return;
                    553:
                    554:        raidPtr = (RF_Raid_t *) arg;
                    555:        unit = raidPtr->raidid;
                    556:        rs = &raid_softc[unit];
                    557:
                    558:        /* Shutdown the system. */
                    559:
                    560:        if (rf_hook_cookies != NULL && rf_hook_cookies[unit] != NULL)
                    561:                rf_hook_cookies[unit] = NULL;
                    562:
                    563:        rf_Shutdown(raidPtr);
                    564:
                    565:        pool_destroy(&rs->sc_cbufpool);
                    566:
                    567:        /* It's no longer initialized... */
                    568:        rs->sc_flags &= ~RAIDF_INITED;
                    569:
                    570:        /* config_detach the device. */
                    571:        config_detach(device_lookup(&raid_cd, unit), 0);
                    572:
                    573:        /* Detach the disk. */
                    574:        disk_detach(&rs->sc_dkdev);
                    575: }
                    576:
                    577: daddr64_t
                    578: raidsize(dev_t dev)
                    579: {
                    580:        struct raid_softc *rs;
                    581:        struct disklabel *lp;
                    582:        int part, unit, omask, size;
                    583:
                    584:        unit = DISKUNIT(dev);
                    585:        if (unit >= numraid)
                    586:                return (-1);
                    587:        rs = &raid_softc[unit];
                    588:
                    589:        if ((rs->sc_flags & RAIDF_INITED) == 0)
                    590:                return (-1);
                    591:
                    592:        part = DISKPART(dev);
                    593:        omask = rs->sc_dkdev.dk_openmask & (1 << part);
                    594:        lp = rs->sc_dkdev.dk_label;
                    595:
                    596:        if (omask == 0 && raidopen(dev, 0, S_IFBLK, curproc))
                    597:                return (-1);
                    598:
                    599:        if (lp->d_partitions[part].p_fstype != FS_SWAP)
                    600:                size = -1;
                    601:        else
                    602:                size = DL_GETPSIZE(&lp->d_partitions[part]) *
                    603:                    (lp->d_secsize / DEV_BSIZE);
                    604:
                    605:        if (omask == 0 && raidclose(dev, 0, S_IFBLK, curproc))
                    606:                return (-1);
                    607:
                    608:        return (size);
                    609:
                    610: }
                    611:
                    612: int
                    613: raiddump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size)
                    614: {
                    615:        /* Not implemented. */
                    616:        return (ENXIO);
                    617: }
                    618:
                    619: /* ARGSUSED */
                    620: int
                    621: raidopen(dev_t dev, int flags, int fmt, struct proc *p)
                    622: {
                    623:        int unit = DISKUNIT(dev);
                    624:        struct raid_softc *rs;
                    625:        int part,pmask;
                    626:        int error = 0;
                    627:
                    628:        if (unit >= numraid)
                    629:                return (ENXIO);
                    630:        rs = &raid_softc[unit];
                    631:
                    632:        if ((error = raidlock(rs)) != 0)
                    633:                return (error);
                    634:
                    635:        part = DISKPART(dev);
                    636:        pmask = (1 << part);
                    637:
                    638:        db1_printf(
                    639:            ("Opening raid device number: %d partition: %d\n", unit, part));
                    640:
                    641:
                    642:        if ((rs->sc_flags & RAIDF_INITED) && (rs->sc_dkdev.dk_openmask == 0))
                    643:                raidgetdisklabel(dev, rs->sc_dkdev.dk_label, 0);
                    644:
                    645:        /* Make sure that this partition exists. */
                    646:
                    647:        if (part != RAW_PART) {
                    648:                db1_printf(("Not a raw partition..\n"));
                    649:                if (((rs->sc_flags & RAIDF_INITED) == 0) ||
                    650:                    ((part >= rs->sc_dkdev.dk_label->d_npartitions) ||
                    651:                    (rs->sc_dkdev.dk_label->d_partitions[part].p_fstype ==
                    652:                    FS_UNUSED))) {
                    653:                        error = ENXIO;
                    654:                        raidunlock(rs);
                    655:                        db1_printf(("Bailing out...\n"));
                    656:                        return (error);
                    657:                }
                    658:        }
                    659:
                    660:        /* Prevent this unit from being unconfigured while opened. */
                    661:        switch (fmt) {
                    662:        case S_IFCHR:
                    663:                rs->sc_dkdev.dk_copenmask |= pmask;
                    664:                break;
                    665:
                    666:        case S_IFBLK:
                    667:                rs->sc_dkdev.dk_bopenmask |= pmask;
                    668:                break;
                    669:        }
                    670:
                    671:        if ((rs->sc_dkdev.dk_openmask == 0) &&
                    672:            ((rs->sc_flags & RAIDF_INITED) != 0)) {
                    673:                /*
                    674:                 * First one...  Mark things as dirty...  Note that we *MUST*
                    675:                 * have done a configure before this.  I DO NOT WANT TO BE
                    676:                 * SCRIBBLING TO RANDOM COMPONENTS UNTIL IT'S BEEN DETERMINED
                    677:                 * THAT THEY BELONG TOGETHER!!!!!
                    678:                 */
                    679:                /*
                    680:                 * XXX should check to see if we're only open for reading
                    681:                 * here...  If so, we needn't do this, but then need some
                    682:                 * other way of keeping track of what's happened...
                    683:                 */
                    684:
                    685:                rf_markalldirty( raidPtrs[unit] );
                    686:        }
                    687:
                    688:        rs->sc_dkdev.dk_openmask =
                    689:            rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
                    690:
                    691:        raidunlock(rs);
                    692:
                    693:        return (error);
                    694: }
                    695:
                    696: /* ARGSUSED */
                    697: int
                    698: raidclose(dev_t dev, int flags, int fmt, struct proc *p)
                    699: {
                    700:        int unit = DISKUNIT(dev);
                    701:        struct raid_softc *rs;
                    702:        int error = 0;
                    703:        int part;
                    704:
                    705:        if (unit >= numraid)
                    706:                return (ENXIO);
                    707:        rs = &raid_softc[unit];
                    708:
                    709:        if ((error = raidlock(rs)) != 0)
                    710:                return (error);
                    711:
                    712:        part = DISKPART(dev);
                    713:
                    714:        /* ...that much closer to allowing unconfiguration... */
                    715:        switch (fmt) {
                    716:        case S_IFCHR:
                    717:                rs->sc_dkdev.dk_copenmask &= ~(1 << part);
                    718:                break;
                    719:
                    720:        case S_IFBLK:
                    721:                rs->sc_dkdev.dk_bopenmask &= ~(1 << part);
                    722:                break;
                    723:        }
                    724:        rs->sc_dkdev.dk_openmask =
                    725:            rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
                    726:
                    727:        if ((rs->sc_dkdev.dk_openmask == 0) &&
                    728:            ((rs->sc_flags & RAIDF_INITED) != 0)) {
                    729:                /*
                    730:                 * Last one...  Device is not unconfigured yet.
                    731:                 * Device shutdown has taken care of setting the
                    732:                 * clean bits if RAIDF_INITED is not set.
                    733:                 * Mark things as clean...
                    734:                 */
                    735:                db1_printf(("Last one on raid%d.  Updating status.\n",unit));
                    736:                rf_update_component_labels(raidPtrs[unit],
                    737:                                                 RF_FINAL_COMPONENT_UPDATE);
                    738:        }
                    739:
                    740:        raidunlock(rs);
                    741:        return (0);
                    742: }
                    743:
                    744: void
                    745: raidstrategy(struct buf *bp)
                    746: {
                    747:        int s;
                    748:
                    749:        unsigned int raidID = DISKUNIT(bp->b_dev);
                    750:        RF_Raid_t *raidPtr;
                    751:        struct raid_softc *rs = &raid_softc[raidID];
                    752:        struct disklabel *lp;
                    753:        int wlabel;
                    754:
                    755:        s = splbio();
                    756:
                    757:        if ((rs->sc_flags & RAIDF_INITED) ==0) {
                    758:                bp->b_error = ENXIO;
                    759:                bp->b_flags |= B_ERROR;
                    760:                bp->b_resid = bp->b_bcount;
                    761:                biodone(bp);
                    762:                goto raidstrategy_end;
                    763:        }
                    764:        if (raidID >= numraid || !raidPtrs[raidID]) {
                    765:                bp->b_error = ENODEV;
                    766:                bp->b_flags |= B_ERROR;
                    767:                bp->b_resid = bp->b_bcount;
                    768:                biodone(bp);
                    769:                goto raidstrategy_end;
                    770:        }
                    771:        raidPtr = raidPtrs[raidID];
                    772:        if (!raidPtr->valid) {
                    773:                bp->b_error = ENODEV;
                    774:                bp->b_flags |= B_ERROR;
                    775:                bp->b_resid = bp->b_bcount;
                    776:                biodone(bp);
                    777:                goto raidstrategy_end;
                    778:        }
                    779:        if (bp->b_bcount == 0) {
                    780:                db1_printf(("b_bcount is zero..\n"));
                    781:                biodone(bp);
                    782:                goto raidstrategy_end;
                    783:        }
                    784:        lp = rs->sc_dkdev.dk_label;
                    785:
                    786:        /*
                    787:         * Do bounds checking and adjust transfer.  If there's an
                    788:         * error, the bounds check will flag that for us.
                    789:         */
                    790:        wlabel = rs->sc_flags & (RAIDF_WLABEL | RAIDF_LABELLING);
                    791:        if (DISKPART(bp->b_dev) != RAW_PART)
                    792:                if (bounds_check_with_label(bp, lp, wlabel) <= 0) {
                    793:                        db1_printf(("Bounds check failed!!:%d %d\n",
                    794:                            (int)bp->b_blkno, (int)wlabel));
                    795:                        biodone(bp);
                    796:                        goto raidstrategy_end;
                    797:                }
                    798:
                    799:        bp->b_resid = 0;
                    800:
                    801:        bp->b_actf = rs->sc_q.b_actf;
                    802:        rs->sc_q.b_actf = bp;
                    803:        rs->sc_q.b_active++;
                    804:
                    805:        raidstart(raidPtrs[raidID]);
                    806:
                    807: raidstrategy_end:
                    808:        splx(s);
                    809: }
                    810:
                    811: /* ARGSUSED */
                    812: int
                    813: raidread(dev_t dev, struct uio *uio, int flags)
                    814: {
                    815:        int unit = DISKUNIT(dev);
                    816:        struct raid_softc *rs;
                    817:        int part;
                    818:
                    819:        if (unit >= numraid)
                    820:                return (ENXIO);
                    821:        rs = &raid_softc[unit];
                    822:
                    823:        if ((rs->sc_flags & RAIDF_INITED) == 0)
                    824:                return (ENXIO);
                    825:        part = DISKPART(dev);
                    826:
                    827:        db1_printf(("raidread: unit: %d partition: %d\n", unit, part));
                    828:
                    829:        return (physio(raidstrategy, NULL, dev, B_READ, minphys, uio));
                    830: }
                    831:
                    832: /* ARGSUSED */
                    833: int
                    834: raidwrite(dev_t dev, struct uio *uio, int flags)
                    835: {
                    836:        int unit = DISKUNIT(dev);
                    837:        struct raid_softc *rs;
                    838:
                    839:        if (unit >= numraid)
                    840:                return (ENXIO);
                    841:        rs = &raid_softc[unit];
                    842:
                    843:        if ((rs->sc_flags & RAIDF_INITED) == 0)
                    844:                return (ENXIO);
                    845:        db1_printf(("raidwrite\n"));
                    846:        return (physio(raidstrategy, NULL, dev, B_WRITE, minphys, uio));
                    847: }
                    848:
                    849: int
                    850: raidioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
                    851: {
                    852:        int unit = DISKUNIT(dev);
                    853:        int error = 0;
                    854:        int part, pmask;
                    855:        struct raid_softc *rs;
                    856:        RF_Config_t *k_cfg, *u_cfg;
                    857:        RF_Raid_t *raidPtr;
                    858:        RF_RaidDisk_t *diskPtr;
                    859:        RF_AccTotals_t *totals;
                    860:        RF_DeviceConfig_t *d_cfg, **ucfgp;
                    861:        u_char *specific_buf;
                    862:        int retcode = 0;
                    863:        int row;
                    864:        int column;
                    865:        struct rf_recon_req *rrcopy, *rr;
                    866:        RF_ComponentLabel_t *clabel;
                    867:        RF_ComponentLabel_t ci_label;
                    868:        RF_ComponentLabel_t **clabel_ptr;
                    869:        RF_SingleComponent_t *sparePtr,*componentPtr;
                    870:        RF_SingleComponent_t hot_spare;
                    871:        RF_SingleComponent_t component;
                    872:        RF_ProgressInfo_t progressInfo, **progressInfoPtr;
                    873:        int i, j, d;
                    874:
                    875:        if (unit >= numraid)
                    876:                return (ENXIO);
                    877:        rs = &raid_softc[unit];
                    878:        raidPtr = raidPtrs[unit];
                    879:
                    880:        db1_printf(("raidioctl: %d %d %d %d\n", (int)dev, (int)DISKPART(dev),
                    881:            (int)unit, (int)cmd));
                    882:
                    883:        /* Must be open for writes for these commands... */
                    884:        switch (cmd) {
                    885:        case DIOCSDINFO:
                    886:        case DIOCWDINFO:
                    887:        case DIOCWLABEL:
                    888:                if ((flag & FWRITE) == 0)
                    889:                        return (EBADF);
                    890:        }
                    891:
                    892:        /* Must be initialized for these... */
                    893:        switch (cmd) {
                    894:        case DIOCGDINFO:
                    895:        case DIOCSDINFO:
                    896:        case DIOCWDINFO:
                    897:        case DIOCGPART:
                    898:        case DIOCWLABEL:
                    899:        case DIOCGPDINFO:
                    900:        case RAIDFRAME_SHUTDOWN:
                    901:        case RAIDFRAME_REWRITEPARITY:
                    902:        case RAIDFRAME_GET_INFO:
                    903:        case RAIDFRAME_RESET_ACCTOTALS:
                    904:        case RAIDFRAME_GET_ACCTOTALS:
                    905:        case RAIDFRAME_KEEP_ACCTOTALS:
                    906:        case RAIDFRAME_GET_SIZE:
                    907:        case RAIDFRAME_FAIL_DISK:
                    908:        case RAIDFRAME_COPYBACK:
                    909:        case RAIDFRAME_CHECK_RECON_STATUS:
                    910:        case RAIDFRAME_CHECK_RECON_STATUS_EXT:
                    911:        case RAIDFRAME_GET_COMPONENT_LABEL:
                    912:        case RAIDFRAME_SET_COMPONENT_LABEL:
                    913:        case RAIDFRAME_ADD_HOT_SPARE:
                    914:        case RAIDFRAME_REMOVE_HOT_SPARE:
                    915:        case RAIDFRAME_INIT_LABELS:
                    916:        case RAIDFRAME_REBUILD_IN_PLACE:
                    917:        case RAIDFRAME_CHECK_PARITY:
                    918:        case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
                    919:        case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
                    920:        case RAIDFRAME_CHECK_COPYBACK_STATUS:
                    921:        case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
                    922:        case RAIDFRAME_SET_AUTOCONFIG:
                    923:        case RAIDFRAME_SET_ROOT:
                    924:        case RAIDFRAME_DELETE_COMPONENT:
                    925:        case RAIDFRAME_INCORPORATE_HOT_SPARE:
                    926:                if ((rs->sc_flags & RAIDF_INITED) == 0)
                    927:                        return (ENXIO);
                    928:        }
                    929:
                    930:        switch (cmd) {
                    931:                /* Configure the system. */
                    932:        case RAIDFRAME_CONFIGURE:
                    933:
                    934:                if (raidPtr->valid) {
                    935:                        /* There is a valid RAID set running on this unit ! */
                    936:                        printf("raid%d: Device already configured!\n",unit);
                    937:                        return(EINVAL);
                    938:                }
                    939:
                    940:                /*
                    941:                 * Copy-in the configuration information.
                    942:                 * data points to a pointer to the configuration structure.
                    943:                 */
                    944:                u_cfg = *((RF_Config_t **)data);
                    945:                RF_Malloc(k_cfg, sizeof (RF_Config_t), (RF_Config_t *));
                    946:                if (k_cfg == NULL) {
                    947:                        return (ENOMEM);
                    948:                }
                    949:                retcode = copyin((caddr_t)u_cfg, (caddr_t)k_cfg,
                    950:                    sizeof (RF_Config_t));
                    951:                if (retcode) {
                    952:                        RF_Free(k_cfg, sizeof(RF_Config_t));
                    953:                        return (retcode);
                    954:                }
                    955:
                    956:                /*
                    957:                 * Allocate a buffer for the layout-specific data,
                    958:                 * and copy it in.
                    959:                 */
                    960:                if (k_cfg->layoutSpecificSize) {
                    961:                        if (k_cfg->layoutSpecificSize > 10000) {
                    962:                                /* Sanity check. */
                    963:                                RF_Free(k_cfg, sizeof(RF_Config_t));
                    964:                                return (EINVAL);
                    965:                        }
                    966:                        RF_Malloc(specific_buf, k_cfg->layoutSpecificSize,
                    967:                            (u_char *));
                    968:                        if (specific_buf == NULL) {
                    969:                                RF_Free(k_cfg, sizeof (RF_Config_t));
                    970:                                return (ENOMEM);
                    971:                        }
                    972:                        retcode = copyin(k_cfg->layoutSpecific,
                    973:                            (caddr_t)specific_buf, k_cfg->layoutSpecificSize);
                    974:                        if (retcode) {
                    975:                                RF_Free(k_cfg, sizeof(RF_Config_t));
                    976:                                RF_Free(specific_buf,
                    977:                                        k_cfg->layoutSpecificSize);
                    978:                                return (retcode);
                    979:                        }
                    980:                } else
                    981:                        specific_buf = NULL;
                    982:                k_cfg->layoutSpecific = specific_buf;
                    983:
                    984:                /*
                    985:                 * We should do some kind of sanity check on the
                    986:                 * configuration.
                    987:                 * Store the sum of all the bytes in the last byte ?
                    988:                 */
                    989:
                    990:                /*
                    991:                 * Clear the entire RAID descriptor, just to make sure
                    992:                 *  there is no stale data left in the case of a
                    993:                 *  reconfiguration.
                    994:                 */
                    995:                bzero((char *) raidPtr, sizeof(RF_Raid_t));
                    996:
                    997:                /* Configure the system. */
                    998:                raidPtr->raidid = unit;
                    999:
                   1000:                retcode = rf_Configure(raidPtr, k_cfg, NULL);
                   1001:
                   1002:                if (retcode == 0) {
                   1003:
                   1004:                        /*
                   1005:                         * Allow this many simultaneous IO's to
                   1006:                         * this RAID device.
                   1007:                         */
                   1008:                        raidPtr->openings = RAIDOUTSTANDING;
                   1009:
                   1010:                        raidinit(raidPtr);
                   1011:                        rf_markalldirty(raidPtr);
                   1012:                }
                   1013:
                   1014:                /* Free the buffers.  No return code here. */
                   1015:                if (k_cfg->layoutSpecificSize) {
                   1016:                        RF_Free(specific_buf, k_cfg->layoutSpecificSize);
                   1017:                }
                   1018:                RF_Free(k_cfg, sizeof (RF_Config_t));
                   1019:
                   1020:                return (retcode);
                   1021:
                   1022:        case RAIDFRAME_SHUTDOWN:
                   1023:                /* Shutdown the system. */
                   1024:
                   1025:                if ((error = raidlock(rs)) != 0)
                   1026:                        return (error);
                   1027:
                   1028:                /*
                   1029:                 * If somebody has a partition mounted, we shouldn't
                   1030:                 * shutdown.
                   1031:                 */
                   1032:
                   1033:                part = DISKPART(dev);
                   1034:                pmask = (1 << part);
                   1035:                if ((rs->sc_dkdev.dk_openmask & ~pmask) ||
                   1036:                    ((rs->sc_dkdev.dk_bopenmask & pmask) &&
                   1037:                    (rs->sc_dkdev.dk_copenmask & pmask))) {
                   1038:                        raidunlock(rs);
                   1039:                        return (EBUSY);
                   1040:                }
                   1041:
                   1042:                if ((retcode = rf_Shutdown(raidPtr)) == 0) {
                   1043:
                   1044:                        pool_destroy(&rs->sc_cbufpool);
                   1045:
                   1046:                        /* It's no longer initialized... */
                   1047:                        rs->sc_flags &= ~RAIDF_INITED;
                   1048:
                   1049:                        /* config_detach the device. */
                   1050:                        config_detach(device_lookup(&raid_cd, unit), 0);
                   1051:
                   1052:                        /* Detach the disk. */
                   1053:                        disk_detach(&rs->sc_dkdev);
                   1054:                }
                   1055:
                   1056:                raidunlock(rs);
                   1057:
                   1058:                return (retcode);
                   1059:
                   1060:        case RAIDFRAME_GET_COMPONENT_LABEL:
                   1061:                clabel_ptr = (RF_ComponentLabel_t **) data;
                   1062:                /*
                   1063:                 * We need to read the component label for the disk indicated
                   1064:                 * by row,column in clabel.
                   1065:                 */
                   1066:
                   1067:                /*
                   1068:                 * For practice, let's get it directly from disk, rather
                   1069:                 * than from the in-core copy.
                   1070:                 */
                   1071:                RF_Malloc( clabel, sizeof( RF_ComponentLabel_t ),
                   1072:                           (RF_ComponentLabel_t *));
                   1073:                if (clabel == NULL)
                   1074:                        return (ENOMEM);
                   1075:
                   1076:                bzero((char *) clabel, sizeof(RF_ComponentLabel_t));
                   1077:
                   1078:                retcode = copyin( *clabel_ptr, clabel,
                   1079:                                  sizeof(RF_ComponentLabel_t));
                   1080:
                   1081:                if (retcode) {
                   1082:                        RF_Free( clabel, sizeof(RF_ComponentLabel_t));
                   1083:                        return(retcode);
                   1084:                }
                   1085:
                   1086:                row = clabel->row;
                   1087:                column = clabel->column;
                   1088:
                   1089:                if ((row < 0) || (row >= raidPtr->numRow) ||
                   1090:                    (column < 0) || (column >= raidPtr->numCol)) {
                   1091:                        RF_Free( clabel, sizeof(RF_ComponentLabel_t));
                   1092:                        return(EINVAL);
                   1093:                }
                   1094:
                   1095:                raidread_component_label(raidPtr->Disks[row][column].dev,
                   1096:                    raidPtr->raid_cinfo[row][column].ci_vp, clabel );
                   1097:
                   1098:                retcode = copyout((caddr_t) clabel,
                   1099:                                  (caddr_t) *clabel_ptr,
                   1100:                                  sizeof(RF_ComponentLabel_t));
                   1101:                RF_Free( clabel, sizeof(RF_ComponentLabel_t));
                   1102:                return (retcode);
                   1103:
                   1104:        case RAIDFRAME_SET_COMPONENT_LABEL:
                   1105:                clabel = (RF_ComponentLabel_t *) data;
                   1106:
                   1107:                /* XXX check the label for valid stuff... */
                   1108:                /*
                   1109:                 * Note that some things *should not* get modified --
                   1110:                 * the user should be re-initing the labels instead of
                   1111:                 * trying to patch things.
                   1112:                 */
                   1113:
                   1114: #ifdef RAIDDEBUG
                   1115:                printf("Got component label:\n");
                   1116:                printf("Version: %d\n",clabel->version);
                   1117:                printf("Serial Number: %d\n",clabel->serial_number);
                   1118:                printf("Mod counter: %d\n",clabel->mod_counter);
                   1119:                printf("Row: %d\n", clabel->row);
                   1120:                printf("Column: %d\n", clabel->column);
                   1121:                printf("Num Rows: %d\n", clabel->num_rows);
                   1122:                printf("Num Columns: %d\n", clabel->num_columns);
                   1123:                printf("Clean: %d\n", clabel->clean);
                   1124:                printf("Status: %d\n", clabel->status);
                   1125: #endif /* RAIDDEBUG */
                   1126:
                   1127:                row = clabel->row;
                   1128:                column = clabel->column;
                   1129:
                   1130:                if ((row < 0) || (row >= raidPtr->numRow) ||
                   1131:                    (column < 0) || (column >= raidPtr->numCol)) {
                   1132:                        return(EINVAL);
                   1133:                }
                   1134:
                   1135:                /* XXX this isn't allowed to do anything for now :-) */
                   1136: #if 0
                   1137:                raidwrite_component_label(raidPtr->Disks[row][column].dev,
                   1138:                    raidPtr->raid_cinfo[row][column].ci_vp, clabel );
                   1139: #endif
                   1140:                return (0);
                   1141:
                   1142:        case RAIDFRAME_INIT_LABELS:
                   1143:                clabel = (RF_ComponentLabel_t *) data;
                   1144:                /*
                   1145:                 * We only want the serial number from the above.
                   1146:                 * We get all the rest of the information from
                   1147:                 * the config that was used to create this RAID
                   1148:                 * set.
                   1149:                 */
                   1150:
                   1151:                raidPtr->serial_number = clabel->serial_number;
                   1152:
                   1153:                raid_init_component_label(raidPtr, &ci_label);
                   1154:                ci_label.serial_number = clabel->serial_number;
                   1155:
                   1156:                for(row=0;row<raidPtr->numRow;row++) {
                   1157:                        ci_label.row = row;
                   1158:                        for(column=0;column<raidPtr->numCol;column++) {
                   1159:                                diskPtr = &raidPtr->Disks[row][column];
                   1160:                                if (!RF_DEAD_DISK(diskPtr->status)) {
                   1161:                                        ci_label.partitionSize =
                   1162:                                            diskPtr->partitionSize;
                   1163:                                        ci_label.column = column;
                   1164:                                        raidwrite_component_label(
                   1165:                                            raidPtr->Disks[row][column].dev,
                   1166:                                            raidPtr->raid_cinfo[row][column].ci_vp,
                   1167:                                            &ci_label );
                   1168:                                }
                   1169:                        }
                   1170:                }
                   1171:
                   1172:                return (retcode);
                   1173:
                   1174:        case RAIDFRAME_REWRITEPARITY:
                   1175:
                   1176:                if (raidPtr->Layout.map->faultsTolerated == 0) {
                   1177:                        /* Parity for RAID 0 is trivially correct. */
                   1178:                        raidPtr->parity_good = RF_RAID_CLEAN;
                   1179:                        return(0);
                   1180:                }
                   1181:
                   1182:
                   1183:                if (raidPtr->parity_rewrite_in_progress == 1) {
                   1184:                        /* Re-write is already in progress ! */
                   1185:                        return(EINVAL);
                   1186:                }
                   1187:
                   1188:                retcode = RF_CREATE_THREAD(raidPtr->parity_rewrite_thread,
                   1189:                                           rf_RewriteParityThread,
                   1190:                                           raidPtr,"raid_parity");
                   1191:
                   1192:                return (retcode);
                   1193:
                   1194:        case RAIDFRAME_SET_AUTOCONFIG:
                   1195:                d = rf_set_autoconfig(raidPtr, *(int *) data);
                   1196:                db1_printf(("New autoconfig value is: %d\n", d));
                   1197:                *(int *) data = d;
                   1198:                return (retcode);
                   1199:
                   1200:        case RAIDFRAME_SET_ROOT:
                   1201:                d = rf_set_rootpartition(raidPtr, *(int *) data);
                   1202:                db1_printf(("New rootpartition value is: %d\n", d));
                   1203:                *(int *) data = d;
                   1204:                return (retcode);
                   1205:
                   1206:
                   1207:        case RAIDFRAME_ADD_HOT_SPARE:
                   1208:                sparePtr = (RF_SingleComponent_t *) data;
                   1209:                memcpy( &hot_spare, sparePtr, sizeof(RF_SingleComponent_t));
                   1210:                retcode = rf_add_hot_spare(raidPtr, &hot_spare);
                   1211:                return(retcode);
                   1212:
                   1213:        case RAIDFRAME_REMOVE_HOT_SPARE:
                   1214:                return(retcode);
                   1215:
                   1216:        case RAIDFRAME_DELETE_COMPONENT:
                   1217:                componentPtr = (RF_SingleComponent_t *)data;
                   1218:                memcpy( &component, componentPtr,
                   1219:                        sizeof(RF_SingleComponent_t));
                   1220:                retcode = rf_delete_component(raidPtr, &component);
                   1221:                return(retcode);
                   1222:
                   1223:        case RAIDFRAME_INCORPORATE_HOT_SPARE:
                   1224:                componentPtr = (RF_SingleComponent_t *)data;
                   1225:                memcpy( &component, componentPtr,
                   1226:                        sizeof(RF_SingleComponent_t));
                   1227:                retcode = rf_incorporate_hot_spare(raidPtr, &component);
                   1228:                return(retcode);
                   1229:
                   1230:        case RAIDFRAME_REBUILD_IN_PLACE:
                   1231:
                   1232:                if (raidPtr->Layout.map->faultsTolerated == 0) {
                   1233:                        /* Can't do this on a RAID 0 !! */
                   1234:                        return(EINVAL);
                   1235:                }
                   1236:
                   1237:                if (raidPtr->recon_in_progress == 1) {
                   1238:                        /* A reconstruct is already in progress ! */
                   1239:                        return(EINVAL);
                   1240:                }
                   1241:
                   1242:                componentPtr = (RF_SingleComponent_t *) data;
                   1243:                memcpy( &component, componentPtr,
                   1244:                        sizeof(RF_SingleComponent_t));
                   1245:                row = component.row;
                   1246:                column = component.column;
                   1247:                db1_printf(("Rebuild: %d %d\n",row, column));
                   1248:                if ((row < 0) || (row >= raidPtr->numRow) ||
                   1249:                    (column < 0) || (column >= raidPtr->numCol)) {
                   1250:                        return(EINVAL);
                   1251:                }
                   1252:
                   1253:                RF_Malloc(rrcopy, sizeof(*rrcopy), (struct rf_recon_req *));
                   1254:                if (rrcopy == NULL)
                   1255:                        return(ENOMEM);
                   1256:
                   1257:                rrcopy->raidPtr = (void *) raidPtr;
                   1258:                rrcopy->row = row;
                   1259:                rrcopy->col = column;
                   1260:
                   1261:                retcode = RF_CREATE_THREAD(raidPtr->recon_thread,
                   1262:                                           rf_ReconstructInPlaceThread,
                   1263:                                           rrcopy,"raid_reconip");
                   1264:
                   1265:                return (retcode);
                   1266:
                   1267:        case RAIDFRAME_GET_INFO:
                   1268:                if (!raidPtr->valid)
                   1269:                        return (ENODEV);
                   1270:                ucfgp = (RF_DeviceConfig_t **) data;
                   1271:                RF_Malloc(d_cfg, sizeof(RF_DeviceConfig_t),
                   1272:                          (RF_DeviceConfig_t *));
                   1273:                if (d_cfg == NULL)
                   1274:                        return (ENOMEM);
                   1275:                bzero((char *) d_cfg, sizeof(RF_DeviceConfig_t));
                   1276:                d_cfg->rows = raidPtr->numRow;
                   1277:                d_cfg->cols = raidPtr->numCol;
                   1278:                d_cfg->ndevs = raidPtr->numRow * raidPtr->numCol;
                   1279:                if (d_cfg->ndevs >= RF_MAX_DISKS) {
                   1280:                        RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
                   1281:                        return (ENOMEM);
                   1282:                }
                   1283:                d_cfg->nspares = raidPtr->numSpare;
                   1284:                if (d_cfg->nspares >= RF_MAX_DISKS) {
                   1285:                        RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
                   1286:                        return (ENOMEM);
                   1287:                }
                   1288:                d_cfg->maxqdepth = raidPtr->maxQueueDepth;
                   1289:                d = 0;
                   1290:                for (i = 0; i < d_cfg->rows; i++) {
                   1291:                        for (j = 0; j < d_cfg->cols; j++) {
                   1292:                                d_cfg->devs[d] = raidPtr->Disks[i][j];
                   1293:                                d++;
                   1294:                        }
                   1295:                }
                   1296:                for (j = d_cfg->cols, i = 0; i < d_cfg->nspares; i++, j++) {
                   1297:                        d_cfg->spares[i] = raidPtr->Disks[0][j];
                   1298:                }
                   1299:                retcode = copyout((caddr_t) d_cfg, (caddr_t) * ucfgp,
                   1300:                                  sizeof(RF_DeviceConfig_t));
                   1301:                RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
                   1302:
                   1303:                return (retcode);
                   1304:
                   1305:        case RAIDFRAME_CHECK_PARITY:
                   1306:                *(int *) data = raidPtr->parity_good;
                   1307:                return (0);
                   1308:
                   1309:        case RAIDFRAME_RESET_ACCTOTALS:
                   1310:                bzero(&raidPtr->acc_totals, sizeof(raidPtr->acc_totals));
                   1311:                return (0);
                   1312:
                   1313:        case RAIDFRAME_GET_ACCTOTALS:
                   1314:                totals = (RF_AccTotals_t *) data;
                   1315:                *totals = raidPtr->acc_totals;
                   1316:                return (0);
                   1317:
                   1318:        case RAIDFRAME_KEEP_ACCTOTALS:
                   1319:                raidPtr->keep_acc_totals = *(int *)data;
                   1320:                return (0);
                   1321:
                   1322:        case RAIDFRAME_GET_SIZE:
                   1323:                *(int *) data = raidPtr->totalSectors;
                   1324:                return (0);
                   1325:
                   1326:        /* Fail a disk & optionally start reconstruction. */
                   1327:        case RAIDFRAME_FAIL_DISK:
                   1328:                rr = (struct rf_recon_req *)data;
                   1329:
                   1330:                if (rr->row < 0 || rr->row >= raidPtr->numRow ||
                   1331:                    rr->col < 0 || rr->col >= raidPtr->numCol)
                   1332:                        return (EINVAL);
                   1333:
                   1334:                db1_printf(("raid%d: Failing the disk: row: %d col: %d\n",
                   1335:                    unit, rr->row, rr->col));
                   1336:
                   1337:                /*
                   1338:                 * Make a copy of the recon request so that we don't
                   1339:                 * rely on the user's buffer.
                   1340:                 */
                   1341:                RF_Malloc(rrcopy, sizeof(*rrcopy), (struct rf_recon_req *));
                   1342:                if (rrcopy == NULL)
                   1343:                        return(ENOMEM);
                   1344:                bcopy(rr, rrcopy, sizeof(*rr));
                   1345:                rrcopy->raidPtr = (void *)raidPtr;
                   1346:
                   1347:                retcode = RF_CREATE_THREAD(raidPtr->recon_thread,
                   1348:                                           rf_ReconThread,
                   1349:                                           rrcopy,"raid_recon");
                   1350:                return (0);
                   1351:
                   1352:        /*
                   1353:         * Invoke a copyback operation after recon on whatever
                   1354:         * disk needs it, if any.
                   1355:         */
                   1356:        case RAIDFRAME_COPYBACK:
                   1357:                if (raidPtr->Layout.map->faultsTolerated == 0) {
                   1358:                        /* This makes no sense on a RAID 0 !! */
                   1359:                        return(EINVAL);
                   1360:                }
                   1361:
                   1362:                if (raidPtr->copyback_in_progress == 1) {
                   1363:                        /* Copyback is already in progress ! */
                   1364:                        return(EINVAL);
                   1365:                }
                   1366:
                   1367:                retcode = RF_CREATE_THREAD(raidPtr->copyback_thread,
                   1368:                                           rf_CopybackThread,
                   1369:                                           raidPtr,"raid_copyback");
                   1370:                return (retcode);
                   1371:
                   1372:        /* Return the percentage completion of reconstruction. */
                   1373:        case RAIDFRAME_CHECK_RECON_STATUS:
                   1374:                if (raidPtr->Layout.map->faultsTolerated == 0) {
                   1375:                        /*
                   1376:                         * This makes no sense on a RAID 0, so tell the
                   1377:                         * user it's done.
                   1378:                         */
                   1379:                        *(int *) data = 100;
                   1380:                        return(0);
                   1381:                }
                   1382:                row = 0; /* XXX we only consider a single row... */
                   1383:                if (raidPtr->status[row] != rf_rs_reconstructing)
                   1384:                        *(int *)data = 100;
                   1385:                else
                   1386:                        *(int *)data =
                   1387:                            raidPtr->reconControl[row]->percentComplete;
                   1388:                return (0);
                   1389:
                   1390:        case RAIDFRAME_CHECK_RECON_STATUS_EXT:
                   1391:                progressInfoPtr = (RF_ProgressInfo_t **) data;
                   1392:                row = 0; /* XXX we only consider a single row... */
                   1393:                if (raidPtr->status[row] != rf_rs_reconstructing) {
                   1394:                        progressInfo.remaining = 0;
                   1395:                        progressInfo.completed = 100;
                   1396:                        progressInfo.total = 100;
                   1397:                } else {
                   1398:                        progressInfo.total =
                   1399:                                raidPtr->reconControl[row]->numRUsTotal;
                   1400:                        progressInfo.completed =
                   1401:                                raidPtr->reconControl[row]->numRUsComplete;
                   1402:                        progressInfo.remaining = progressInfo.total -
                   1403:                                progressInfo.completed;
                   1404:                }
                   1405:                retcode = copyout((caddr_t) &progressInfo,
                   1406:                                  (caddr_t) *progressInfoPtr,
                   1407:                                  sizeof(RF_ProgressInfo_t));
                   1408:                return (retcode);
                   1409:
                   1410:        case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
                   1411:                if (raidPtr->Layout.map->faultsTolerated == 0) {
                   1412:                        /*
                   1413:                         * This makes no sense on a RAID 0, so tell the
                   1414:                         * user it's done.
                   1415:                         */
                   1416:                        *(int *) data = 100;
                   1417:                        return(0);
                   1418:                }
                   1419:                if (raidPtr->parity_rewrite_in_progress == 1) {
                   1420:                        *(int *) data = 100 *
                   1421:                                raidPtr->parity_rewrite_stripes_done /
                   1422:                                raidPtr->Layout.numStripe;
                   1423:                } else {
                   1424:                        *(int *) data = 100;
                   1425:                }
                   1426:                return (0);
                   1427:
                   1428:        case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
                   1429:                progressInfoPtr = (RF_ProgressInfo_t **) data;
                   1430:                if (raidPtr->parity_rewrite_in_progress == 1) {
                   1431:                        progressInfo.total = raidPtr->Layout.numStripe;
                   1432:                        progressInfo.completed =
                   1433:                                raidPtr->parity_rewrite_stripes_done;
                   1434:                        progressInfo.remaining = progressInfo.total -
                   1435:                                progressInfo.completed;
                   1436:                } else {
                   1437:                        progressInfo.remaining = 0;
                   1438:                        progressInfo.completed = 100;
                   1439:                        progressInfo.total = 100;
                   1440:                }
                   1441:                retcode = copyout((caddr_t) &progressInfo,
                   1442:                                  (caddr_t) *progressInfoPtr,
                   1443:                                  sizeof(RF_ProgressInfo_t));
                   1444:                return (retcode);
                   1445:
                   1446:        case RAIDFRAME_CHECK_COPYBACK_STATUS:
                   1447:                if (raidPtr->Layout.map->faultsTolerated == 0) {
                   1448:                        /* This makes no sense on a RAID 0 !! */
                   1449:                        *(int *) data = 100;
                   1450:                        return(0);
                   1451:                }
                   1452:                if (raidPtr->copyback_in_progress == 1) {
                   1453:                        *(int *) data = 100 * raidPtr->copyback_stripes_done /
                   1454:                                raidPtr->Layout.numStripe;
                   1455:                } else {
                   1456:                        *(int *) data = 100;
                   1457:                }
                   1458:                return (0);
                   1459:
                   1460:        case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
                   1461:                progressInfoPtr = (RF_ProgressInfo_t **) data;
                   1462:                if (raidPtr->copyback_in_progress == 1) {
                   1463:                        progressInfo.total = raidPtr->Layout.numStripe;
                   1464:                        progressInfo.completed =
                   1465:                                raidPtr->copyback_stripes_done;
                   1466:                        progressInfo.remaining = progressInfo.total -
                   1467:                                progressInfo.completed;
                   1468:                } else {
                   1469:                        progressInfo.remaining = 0;
                   1470:                        progressInfo.completed = 100;
                   1471:                        progressInfo.total = 100;
                   1472:                }
                   1473:                retcode = copyout((caddr_t) &progressInfo,
                   1474:                                  (caddr_t) *progressInfoPtr,
                   1475:                                  sizeof(RF_ProgressInfo_t));
                   1476:                return (retcode);
                   1477:
                   1478: #if 0
                   1479:        case RAIDFRAME_SPARET_WAIT:
                   1480:                /*
                   1481:                 * The sparetable daemon calls this to wait for the
                   1482:                 * kernel to need a spare table.
                   1483:                 * This ioctl does not return until a spare table is needed.
                   1484:                 * XXX -- Calling mpsleep here in the ioctl code is almost
                   1485:                 * certainly wrong and evil. -- XXX
                   1486:                 * XXX -- I should either compute the spare table in the
                   1487:                 * kernel, or have a different. -- XXX
                   1488:                 * XXX -- Interface (a different character device) for
                   1489:                 * delivering the table. -- XXX
                   1490:                 */
                   1491:                RF_LOCK_MUTEX(rf_sparet_wait_mutex);
                   1492:                while (!rf_sparet_wait_queue)
                   1493:                        mpsleep(&rf_sparet_wait_queue, (PZERO + 1) | PCATCH,
                   1494:                            "sparet wait", 0,
                   1495:                            (void *)simple_lock_addr(rf_sparet_wait_mutex),
                   1496:                            MS_LOCK_SIMPLE);
                   1497:                waitreq = rf_sparet_wait_queue;
                   1498:                rf_sparet_wait_queue = rf_sparet_wait_queue->next;
                   1499:                RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
                   1500:
                   1501:                *((RF_SparetWait_t *)data) = *waitreq;
                   1502:
                   1503:                RF_Free(waitreq, sizeof *waitreq);
                   1504:                return (0);
                   1505:
                   1506:        case RAIDFRAME_ABORT_SPARET_WAIT:
                   1507:                /*
                   1508:                 * Wakes up a process waiting on SPARET_WAIT and puts an
                   1509:                 * error code in it that will cause the dameon to exit.
                   1510:                 */
                   1511:                RF_Malloc(waitreq, sizeof (*waitreq), (RF_SparetWait_t *));
                   1512:                waitreq->fcol = -1;
                   1513:                RF_LOCK_MUTEX(rf_sparet_wait_mutex);
                   1514:                waitreq->next = rf_sparet_wait_queue;
                   1515:                rf_sparet_wait_queue = waitreq;
                   1516:                RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
                   1517:                wakeup(&rf_sparet_wait_queue);
                   1518:                return (0);
                   1519:
                   1520:        case RAIDFRAME_SEND_SPARET:
                   1521:                /*
                   1522:                 * Used by the spare table daemon to deliver a spare table
                   1523:                 * into the kernel.
                   1524:                 */
                   1525:
                   1526:                /* Install the spare table. */
                   1527:                retcode = rf_SetSpareTable(raidPtr,*(void **)data);
                   1528:
                   1529:                /*
                   1530:                 * Respond to the requestor.  The return status of the
                   1531:                 * spare table installation is passed in the "fcol" field.
                   1532:                 */
                   1533:                RF_Malloc(waitreq, sizeof *waitreq, (RF_SparetWait_t *));
                   1534:                waitreq->fcol = retcode;
                   1535:                RF_LOCK_MUTEX(rf_sparet_wait_mutex);
                   1536:                waitreq->next = rf_sparet_resp_queue;
                   1537:                rf_sparet_resp_queue = waitreq;
                   1538:                wakeup(&rf_sparet_resp_queue);
                   1539:                RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
                   1540:
                   1541:                return (retcode);
                   1542: #endif
                   1543:        /* Fall through to the os-specific code below. */
                   1544:        default:
                   1545:                break;
                   1546:        }
                   1547:
                   1548:        if (!raidPtr->valid)
                   1549:                return (EINVAL);
                   1550:
                   1551:        /*
                   1552:         * Add support for "regular" device ioctls here.
                   1553:         */
                   1554:        switch (cmd) {
                   1555:        case DIOCGDINFO:
                   1556:                *(struct disklabel *)data = *(rs->sc_dkdev.dk_label);
                   1557:                break;
                   1558:
                   1559:        case DIOCGPART:
                   1560:                ((struct partinfo *)data)->disklab = rs->sc_dkdev.dk_label;
                   1561:                ((struct partinfo *)data)->part =
                   1562:                    &rs->sc_dkdev.dk_label->d_partitions[DISKPART(dev)];
                   1563:                break;
                   1564:
                   1565:        case DIOCWDINFO:
                   1566:        case DIOCSDINFO:
                   1567:        {
                   1568:                struct disklabel *lp;
                   1569:                lp = (struct disklabel *)data;
                   1570:
                   1571:                if ((error = raidlock(rs)) != 0)
                   1572:                        return (error);
                   1573:
                   1574:                rs->sc_flags |= RAIDF_LABELLING;
                   1575:
                   1576:                error = setdisklabel(rs->sc_dkdev.dk_label, lp, 0);
                   1577:                if (error == 0) {
                   1578:                        if (cmd == DIOCWDINFO)
                   1579:                                error = writedisklabel(DISKLABELDEV(dev),
                   1580:                                    raidstrategy, rs->sc_dkdev.dk_label);
                   1581:                }
                   1582:
                   1583:                rs->sc_flags &= ~RAIDF_LABELLING;
                   1584:
                   1585:                raidunlock(rs);
                   1586:
                   1587:                if (error)
                   1588:                        return (error);
                   1589:                break;
                   1590:        }
                   1591:
                   1592:        case DIOCWLABEL:
                   1593:                if (*(int *)data != 0)
                   1594:                        rs->sc_flags |= RAIDF_WLABEL;
                   1595:                else
                   1596:                        rs->sc_flags &= ~RAIDF_WLABEL;
                   1597:                break;
                   1598:
                   1599:        case DIOCGPDINFO:
                   1600:                raidgetdisklabel(dev, (struct disklabel *)data, 1);
                   1601:                break;
                   1602:
                   1603:        default:
                   1604:                retcode = ENOTTY;
                   1605:        }
                   1606:
                   1607:        return (retcode);
                   1608: }
                   1609:
                   1610: /*
                   1611:  * raidinit -- Complete the rest of the initialization for the
                   1612:  * RAIDframe device.
                   1613:  */
                   1614: void
                   1615: raidinit(RF_Raid_t *raidPtr)
                   1616: {
                   1617:        struct raid_softc *rs;
                   1618:        struct cfdata   *cf;
                   1619:        int unit;
                   1620:
                   1621:        unit = raidPtr->raidid;
                   1622:
                   1623:        rs = &raid_softc[unit];
                   1624:        pool_init(&rs->sc_cbufpool, sizeof(struct raidbuf), 0,
                   1625:                0, 0, "raidpl", NULL);
                   1626:
                   1627:        /* XXX should check return code first... */
                   1628:        rs->sc_flags |= RAIDF_INITED;
                   1629:
                   1630:        /* XXX doesn't check bounds. */
                   1631:        snprintf(rs->sc_xname, sizeof rs->sc_xname, "raid%d", unit);
                   1632:
                   1633:        rs->sc_dkdev.dk_name = rs->sc_xname;
                   1634:
                   1635:        /*
                   1636:         * disk_attach actually creates space for the CPU disklabel, among
                   1637:         * other things, so it's critical to call this *BEFORE* we try
                   1638:         * putzing with disklabels.
                   1639:         */
                   1640:        disk_attach(&rs->sc_dkdev);
                   1641:
                   1642:        /*
                   1643:         * XXX There may be a weird interaction here between this, and
                   1644:         * protectedSectors, as used in RAIDframe.
                   1645:         */
                   1646:        rs->sc_size = raidPtr->totalSectors;
                   1647:
                   1648:        /*
                   1649:         * config_attach the raid device into the device tree.
                   1650:         * For autoconf rootdev selection...
                   1651:         */
                   1652:        cf = malloc(sizeof(struct cfdata), M_RAIDFRAME, M_NOWAIT);
                   1653:        if (cf == NULL) {
                   1654:                printf("WARNING: no memory for cfdata struct\n");
                   1655:                return;
                   1656:        }
                   1657:        bzero(cf, sizeof(struct cfdata));
                   1658:
                   1659:        cf->cf_attach = &raid_ca;
                   1660:        cf->cf_driver = &raid_cd;
                   1661:        cf->cf_unit   = unit;
                   1662:
                   1663:        config_attach(NULL, cf, NULL, NULL);
                   1664: }
                   1665:
                   1666: /*
                   1667:  * Wake up the daemon & tell it to get us a spare table.
                   1668:  * XXX
                   1669:  * The entries in the queues should be tagged with the raidPtr so that
                   1670:  * in the extremely rare case that two recons happen at once, we know
                   1671:  * which devices were requesting a spare table.
                   1672:  * XXX
                   1673:  *
                   1674:  * XXX This code is not currently used. GO
                   1675:  */
                   1676: int
                   1677: rf_GetSpareTableFromDaemon(RF_SparetWait_t *req)
                   1678: {
                   1679:        int retcode;
                   1680:
                   1681:        RF_LOCK_MUTEX(rf_sparet_wait_mutex);
                   1682:        req->next = rf_sparet_wait_queue;
                   1683:        rf_sparet_wait_queue = req;
                   1684:        wakeup(&rf_sparet_wait_queue);
                   1685:
                   1686:        /* mpsleep unlocks the mutex. */
                   1687:        while (!rf_sparet_resp_queue) {
                   1688:                tsleep(&rf_sparet_resp_queue, PRIBIO,
                   1689:                    "RAIDframe getsparetable", 0);
                   1690:        }
                   1691:        req = rf_sparet_resp_queue;
                   1692:        rf_sparet_resp_queue = req->next;
                   1693:        RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
                   1694:
                   1695:        retcode = req->fcol;
                   1696:        /* This is not the same req as we alloc'd. */
                   1697:        RF_Free(req, sizeof *req);
                   1698:        return (retcode);
                   1699: }
                   1700:
                   1701: /*
                   1702:  * A wrapper around rf_DoAccess that extracts appropriate info from the
                   1703:  * bp and passes it down.
                   1704:  * Any calls originating in the kernel must use non-blocking I/O.
                   1705:  * Do some extra sanity checking to return "appropriate" error values for
                   1706:  * certain conditions (to make some standard utilities work).
                   1707:  *
                   1708:  * Formerly known as: rf_DoAccessKernel
                   1709:  */
                   1710: void
                   1711: raidstart(RF_Raid_t *raidPtr)
                   1712: {
                   1713:        RF_SectorCount_t num_blocks, pb, sum;
                   1714:        RF_RaidAddr_t raid_addr;
                   1715:        int retcode;
                   1716:        struct partition *pp;
                   1717:        daddr64_t blocknum;
                   1718:        int unit;
                   1719:        struct raid_softc *rs;
                   1720:        int     do_async;
                   1721:        struct buf *bp;
                   1722:
                   1723:        unit = raidPtr->raidid;
                   1724:        rs = &raid_softc[unit];
                   1725:
                   1726:        /* Quick check to see if anything has died recently. */
                   1727:        RF_LOCK_MUTEX(raidPtr->mutex);
                   1728:        if (raidPtr->numNewFailures > 0) {
                   1729:                rf_update_component_labels(raidPtr,
                   1730:                                           RF_NORMAL_COMPONENT_UPDATE);
                   1731:                raidPtr->numNewFailures--;
                   1732:        }
                   1733:        RF_UNLOCK_MUTEX(raidPtr->mutex);
                   1734:
                   1735:        /* Check to see if we're at the limit... */
                   1736:        RF_LOCK_MUTEX(raidPtr->mutex);
                   1737:        while (raidPtr->openings > 0) {
                   1738:                RF_UNLOCK_MUTEX(raidPtr->mutex);
                   1739:
                   1740:                bp = rs->sc_q.b_actf;
                   1741:                if (bp == NULL) {
                   1742:                        /* Nothing more to do. */
                   1743:                        return;
                   1744:                }
                   1745:                rs->sc_q.b_actf = bp->b_actf;
                   1746:
                   1747:                /*
                   1748:                 * Ok, for the bp we have here, bp->b_blkno is relative to the
                   1749:                 * partition... We need to make it absolute to the underlying
                   1750:                 * device...
                   1751:                 */
                   1752:
                   1753:                blocknum = bp->b_blkno;
                   1754:                if (DISKPART(bp->b_dev) != RAW_PART) {
                   1755:                        pp = &rs->sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)];
                   1756:                        blocknum += DL_GETPOFFSET(pp);
                   1757:                }
                   1758:
                   1759:                db1_printf(("Blocks: %d, %lld\n", (int) bp->b_blkno,
                   1760:                            blocknum));
                   1761:
                   1762:                db1_printf(("bp->b_bcount = %d\n", (int) bp->b_bcount));
                   1763:                db1_printf(("bp->b_resid = %d\n", (int) bp->b_resid));
                   1764:
                   1765:                /*
                   1766:                 * *THIS* is where we adjust what block we're going to...
                   1767:                 * But DO NOT TOUCH bp->b_blkno !!!
                   1768:                 */
                   1769:                raid_addr = blocknum;
                   1770:
                   1771:                num_blocks = bp->b_bcount >> raidPtr->logBytesPerSector;
                   1772:                pb = (bp->b_bcount & raidPtr->sectorMask) ? 1 : 0;
                   1773:                sum = raid_addr + num_blocks + pb;
                   1774:                if (1 || rf_debugKernelAccess) {
                   1775:                        db1_printf(("raid_addr=%d sum=%d num_blocks=%d(+%d)"
                   1776:                            " (%d)\n", (int)raid_addr, (int)sum,
                   1777:                            (int)num_blocks, (int)pb, (int)bp->b_resid));
                   1778:                }
                   1779:                if ((sum > raidPtr->totalSectors) || (sum < raid_addr)
                   1780:                    || (sum < num_blocks) || (sum < pb)) {
                   1781:                        bp->b_error = ENOSPC;
                   1782:                        bp->b_flags |= B_ERROR;
                   1783:                        bp->b_resid = bp->b_bcount;
                   1784:                        /* db1_printf(("%s: Calling biodone on 0x%x\n",
                   1785:                            __func__, bp)); */
                   1786:                        splassert(IPL_BIO);
                   1787:                        biodone(bp);
                   1788:                        RF_LOCK_MUTEX(raidPtr->mutex);
                   1789:                        continue;
                   1790:                }
                   1791:                /*
                   1792:                 * XXX rf_DoAccess() should do this, not just DoAccessKernel().
                   1793:                 */
                   1794:
                   1795:                if (bp->b_bcount & raidPtr->sectorMask) {
                   1796:                        bp->b_error = EINVAL;
                   1797:                        bp->b_flags |= B_ERROR;
                   1798:                        bp->b_resid = bp->b_bcount;
                   1799:                        /* db1_printf(("%s: Calling biodone on 0x%x\n",
                   1800:                            __func__, bp)); */
                   1801:                        splassert(IPL_BIO);
                   1802:                        biodone(bp);
                   1803:                        RF_LOCK_MUTEX(raidPtr->mutex);
                   1804:                        continue;
                   1805:
                   1806:                }
                   1807:                db1_printf(("Calling DoAccess..\n"));
                   1808:
                   1809:
                   1810:                RF_LOCK_MUTEX(raidPtr->mutex);
                   1811:                raidPtr->openings--;
                   1812:                RF_UNLOCK_MUTEX(raidPtr->mutex);
                   1813:
                   1814:                /*
                   1815:                 * Everything is async.
                   1816:                 */
                   1817:                do_async = 1;
                   1818:
                   1819:                disk_busy(&rs->sc_dkdev);
                   1820:
                   1821:                /*
                   1822:                 * XXX we're still at splbio() here...  Do we *really*
                   1823:                 * need to be ?
                   1824:                 */
                   1825:
                   1826:                /*
                   1827:                 * Don't ever condition on bp->b_flags & B_WRITE.
                   1828:                 * Always condition on B_READ instead.
                   1829:                 */
                   1830:
                   1831:                retcode = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
                   1832:                                      RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
                   1833:                                      do_async, raid_addr, num_blocks,
                   1834:                                      bp->b_data, bp, NULL, NULL,
                   1835:                                      RF_DAG_NONBLOCKING_IO, NULL, NULL, NULL);
                   1836:
                   1837:                RF_LOCK_MUTEX(raidPtr->mutex);
                   1838:        }
                   1839:        RF_UNLOCK_MUTEX(raidPtr->mutex);
                   1840: }
                   1841:
                   1842: /* Invoke an I/O from kernel mode.  Disk queue should be locked upon entry. */
                   1843:
                   1844: int
                   1845: rf_DispatchKernelIO(RF_DiskQueue_t *queue, RF_DiskQueueData_t *req)
                   1846: {
                   1847:        int op = (req->type == RF_IO_TYPE_READ) ? B_READ : B_WRITE;
                   1848:        struct buf *bp;
                   1849:        struct raidbuf *raidbp = NULL;
                   1850:        struct raid_softc *rs;
                   1851:        int unit;
                   1852:        /*int s = splbio();*/   /* Want to test this. */
                   1853:
                   1854:        /*
                   1855:         * XXX along with the vnode, we also need the softc associated with
                   1856:         * this device...
                   1857:         */
                   1858:        req->queue = queue;
                   1859:
                   1860:        unit = queue->raidPtr->raidid;
                   1861:
                   1862:        db1_printf(("DispatchKernelIO unit: %d\n", unit));
                   1863:
                   1864:        if (unit >= numraid) {
                   1865:                printf("Invalid unit number: %d %d\n", unit, numraid);
                   1866:                panic("Invalid Unit number in rf_DispatchKernelIO");
                   1867:        }
                   1868:
                   1869:        rs = &raid_softc[unit];
                   1870:
                   1871:        bp = req->bp;
                   1872:
                   1873: #if 1
                   1874:        /*
                   1875:         * XXX When there is a physical disk failure, someone is passing
                   1876:         * us a buffer that contains old stuff !!  Attempt to deal with
                   1877:         * this problem without taking a performance hit...
                   1878:         * (not sure where the real bug is; it's buried in RAIDframe
                   1879:         * somewhere) :-( GO )
                   1880:         */
                   1881:        if (bp->b_flags & B_ERROR) {
                   1882:                bp->b_flags &= ~B_ERROR;
                   1883:        }
                   1884:        if (bp->b_error!=0) {
                   1885:                bp->b_error = 0;
                   1886:        }
                   1887: #endif
                   1888:
                   1889:        raidbp = RAIDGETBUF(rs);
                   1890:
                   1891:        raidbp->rf_flags = 0;   /* XXX not really used anywhere... */
                   1892:
                   1893:        /*
                   1894:         * Context for raidiodone.
                   1895:         */
                   1896:        raidbp->rf_obp = bp;
                   1897:        raidbp->req = req;
                   1898:
                   1899:        LIST_INIT(&raidbp->rf_buf.b_dep);
                   1900:
                   1901:        switch (req->type) {
                   1902:        case RF_IO_TYPE_NOP:
                   1903:                /* Used primarily to unlock a locked queue. */
                   1904:
                   1905:                db1_printf(("rf_DispatchKernelIO: NOP to r %d c %d\n",
                   1906:                    queue->row, queue->col));
                   1907:
                   1908:                /* XXX need to do something extra here... */
                   1909:
                   1910:                /*
                   1911:                 * I'm leaving this in, as I've never actually seen it
                   1912:                 * used, and I'd like folks to report it... GO
                   1913:                 */
                   1914:                db1_printf(("WAKEUP CALLED\n"));
                   1915:                queue->numOutstanding++;
                   1916:
                   1917:                /* XXX need to glue the original buffer into this ?? */
                   1918:
                   1919:                rf_KernelWakeupFunc(&raidbp->rf_buf);
                   1920:                break;
                   1921:
                   1922:        case RF_IO_TYPE_READ:
                   1923:        case RF_IO_TYPE_WRITE:
                   1924:                if (req->tracerec) {
                   1925:                        RF_ETIMER_START(req->tracerec->timer);
                   1926:                }
                   1927:
                   1928:                rf_InitBP(&raidbp->rf_buf, queue->rf_cinfo->ci_vp,
                   1929:                    op | bp->b_flags, queue->rf_cinfo->ci_dev,
                   1930:                    req->sectorOffset, req->numSector,
                   1931:                    req->buf, rf_KernelWakeupFunc, (void *)req,
                   1932:                    queue->raidPtr->logBytesPerSector, req->b_proc);
                   1933:
                   1934:                if (rf_debugKernelAccess) {
                   1935:                        db1_printf(("dispatch: bp->b_blkno = %ld\n",
                   1936:                            (long)bp->b_blkno));
                   1937:                }
                   1938:                queue->numOutstanding++;
                   1939:                queue->last_deq_sector = req->sectorOffset;
                   1940:
                   1941:                /*
                   1942:                 * Acc wouldn't have been let in if there were any
                   1943:                 * pending reqs at any other priority.
                   1944:                 */
                   1945:                queue->curPriority = req->priority;
                   1946:
                   1947:                db1_printf(("Going for %c to unit %d row %d col %d\n",
                   1948:                    req->type, unit, queue->row, queue->col));
                   1949:                db1_printf(("sector %d count %d (%d bytes) %d\n",
                   1950:                    (int)req->sectorOffset, (int)req->numSector,
                   1951:                    (int)(req->numSector << queue->raidPtr->logBytesPerSector),
                   1952:                    (int)queue->raidPtr->logBytesPerSector));
                   1953:                if ((raidbp->rf_buf.b_flags & B_READ) == 0) {
                   1954:                        raidbp->rf_buf.b_vp->v_numoutput++;
                   1955:                }
                   1956:
                   1957:                VOP_STRATEGY(&raidbp->rf_buf);
                   1958:                break;
                   1959:
                   1960:        default:
                   1961:                panic("bad req->type in rf_DispatchKernelIO");
                   1962:        }
                   1963:        db1_printf(("Exiting from DispatchKernelIO\n"));
                   1964:        /*splx(s);*/    /* want to test this */
                   1965:        return (0);
                   1966: }
                   1967:
                   1968: /*
                   1969:  * This is the callback function associated with a I/O invoked from
                   1970:  * kernel code.
                   1971:  */
                   1972: void
                   1973: rf_KernelWakeupFunc(struct buf *vbp)
                   1974: {
                   1975:        RF_DiskQueueData_t *req = NULL;
                   1976:        RF_DiskQueue_t *queue;
                   1977:        struct raidbuf *raidbp = (struct raidbuf *)vbp;
                   1978:        struct buf *bp;
                   1979:        struct raid_softc *rs;
                   1980:        int unit;
                   1981:        int s;
                   1982:
                   1983:        s = splbio();
                   1984:        db1_printf(("recovering the request queue:\n"));
                   1985:        req = raidbp->req;
                   1986:
                   1987:        bp = raidbp->rf_obp;
                   1988:
                   1989:        queue = (RF_DiskQueue_t *)req->queue;
                   1990:
                   1991:        if (raidbp->rf_buf.b_flags & B_ERROR) {
                   1992:                bp->b_flags |= B_ERROR;
                   1993:                bp->b_error =
                   1994:                    raidbp->rf_buf.b_error ? raidbp->rf_buf.b_error : EIO;
                   1995:        }
                   1996:
                   1997: #if 1
                   1998:        /* XXX Methinks this could be wrong... */
                   1999:        bp->b_resid = raidbp->rf_buf.b_resid;
                   2000: #endif
                   2001:
                   2002:        if (req->tracerec) {
                   2003:                RF_ETIMER_STOP(req->tracerec->timer);
                   2004:                RF_ETIMER_EVAL(req->tracerec->timer);
                   2005:                RF_LOCK_MUTEX(rf_tracing_mutex);
                   2006:                req->tracerec->diskwait_us +=
                   2007:                    RF_ETIMER_VAL_US(req->tracerec->timer);
                   2008:                req->tracerec->phys_io_us +=
                   2009:                    RF_ETIMER_VAL_US(req->tracerec->timer);
                   2010:                req->tracerec->num_phys_ios++;
                   2011:                RF_UNLOCK_MUTEX(rf_tracing_mutex);
                   2012:        }
                   2013:
                   2014:        bp->b_bcount = raidbp->rf_buf.b_bcount; /* XXXX ?? */
                   2015:
                   2016:        unit = queue->raidPtr->raidid;  /* *Much* simpler :-> */
                   2017:
                   2018:        /*
                   2019:         * XXX Ok, let's get aggressive...  If B_ERROR is set, let's go
                   2020:         * ballistic, and mark the component as hosed...
                   2021:         */
                   2022:        if (bp->b_flags & B_ERROR) {
                   2023:                /* Mark the disk as dead but only mark it once... */
                   2024:                if (queue->raidPtr->Disks[queue->row][queue->col].status ==
                   2025:                    rf_ds_optimal) {
                   2026:                        printf("raid%d: IO Error.  Marking %s as failed.\n",
                   2027:                            unit,
                   2028:                            queue->raidPtr->
                   2029:                            Disks[queue->row][queue->col].devname);
                   2030:                        queue->raidPtr->Disks[queue->row][queue->col].status =
                   2031:                            rf_ds_failed;
                   2032:                        queue->raidPtr->status[queue->row] = rf_rs_degraded;
                   2033:                        queue->raidPtr->numFailures++;
                   2034:                        queue->raidPtr->numNewFailures++;
                   2035:                } else {
                   2036:                        /* Disk is already dead... */
                   2037:                        /* printf("Disk already marked as dead!\n"); */
                   2038:                }
                   2039:        }
                   2040:
                   2041:        rs = &raid_softc[unit];
                   2042:        RAIDPUTBUF(rs, raidbp);
                   2043:
                   2044:        rf_DiskIOComplete(queue, req, (bp->b_flags & B_ERROR) ? 1 : 0);
                   2045:        (req->CompleteFunc)(req->argument, (bp->b_flags & B_ERROR) ? 1 : 0);
                   2046:
                   2047:        splx(s);
                   2048: }
                   2049:
                   2050: /*
                   2051:  * Initialize a buf structure for doing an I/O in the kernel.
                   2052:  */
                   2053: void
                   2054: rf_InitBP(
                   2055:        struct buf       *bp,
                   2056:        struct vnode     *b_vp,
                   2057:        unsigned          rw_flag,
                   2058:        dev_t             dev,
                   2059:        RF_SectorNum_t    startSect,
                   2060:        RF_SectorCount_t  numSect,
                   2061:        caddr_t           buf,
                   2062:        void            (*cbFunc)(struct buf *),
                   2063:        void             *cbArg,
                   2064:        int               logBytesPerSector,
                   2065:        struct proc      *b_proc
                   2066: )
                   2067: {
                   2068:        /*bp->b_flags = B_PHYS | rw_flag;*/
                   2069:        bp->b_flags = B_CALL | rw_flag; /* XXX need B_PHYS here too ??? */
                   2070:        bp->b_bcount = numSect << logBytesPerSector;
                   2071:        bp->b_bufsize = bp->b_bcount;
                   2072:        bp->b_error = 0;
                   2073:        bp->b_dev = dev;
                   2074:        bp->b_data = buf;
                   2075:        bp->b_blkno = startSect;
                   2076:        bp->b_resid = bp->b_bcount;     /* XXX is this right !??!?!! */
                   2077:        if (bp->b_bcount == 0) {
                   2078:                panic("bp->b_bcount is zero in rf_InitBP!!");
                   2079:        }
                   2080:        bp->b_proc = b_proc;
                   2081:        bp->b_iodone = cbFunc;
                   2082:        bp->b_vp = b_vp;
                   2083:        LIST_INIT(&bp->b_dep);
                   2084: }
                   2085:
                   2086: void
                   2087: raidgetdefaultlabel(RF_Raid_t *raidPtr, struct raid_softc *rs,
                   2088:     struct disklabel *lp)
                   2089: {
                   2090:        db1_printf(("Building a default label...\n"));
                   2091:        bzero(lp, sizeof(*lp));
                   2092:
                   2093:        /* Fabricate a label... */
                   2094:        DL_SETDSIZE(lp, raidPtr->totalSectors);
                   2095:        lp->d_secsize = raidPtr->bytesPerSector;
                   2096:        lp->d_nsectors = raidPtr->Layout.dataSectorsPerStripe;
                   2097:        lp->d_ntracks = 4 * raidPtr->numCol;
                   2098:        lp->d_ncylinders = raidPtr->totalSectors /
                   2099:            (lp->d_nsectors * lp->d_ntracks);
                   2100:        lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
                   2101:
                   2102:        strncpy(lp->d_typename, "raid", sizeof(lp->d_typename));
                   2103:        lp->d_type = DTYPE_RAID;
                   2104:        strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
                   2105:        lp->d_rpm = 3600;
                   2106:        lp->d_flags = 0;
                   2107:        lp->d_interleave = 1;
                   2108:        lp->d_version = 1;
                   2109:
                   2110:        DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
                   2111:        DL_SETPSIZE(&lp->d_partitions[RAW_PART], raidPtr->totalSectors);
                   2112:        lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
                   2113:        lp->d_npartitions = RAW_PART + 1;
                   2114:
                   2115:        lp->d_magic = DISKMAGIC;
                   2116:        lp->d_magic2 = DISKMAGIC;
                   2117:        lp->d_checksum = dkcksum(rs->sc_dkdev.dk_label);
                   2118: }
                   2119:
                   2120: /*
                   2121:  * Read the disklabel from the raid device.
                   2122:  * If one is not present, fake one up.
                   2123:  */
                   2124: void
                   2125: raidgetdisklabel(dev_t dev, struct disklabel *lp, int spoofonly)
                   2126: {
                   2127:        int unit = DISKUNIT(dev);
                   2128:        struct raid_softc *rs = &raid_softc[unit];
                   2129:        char *errstring;
                   2130:        RF_Raid_t *raidPtr;
                   2131:        int i;
                   2132:        struct partition *pp;
                   2133:
                   2134:        db1_printf(("Getting the disklabel...\n"));
                   2135:
                   2136:        bzero(lp, sizeof(*lp));
                   2137:
                   2138:        raidPtr = raidPtrs[unit];
                   2139:
                   2140:        raidgetdefaultlabel(raidPtr, rs, lp);
                   2141:
                   2142:        /*
                   2143:         * Call the generic disklabel extraction routine.
                   2144:         */
                   2145:        errstring = readdisklabel(DISKLABELDEV(dev), raidstrategy, lp,
                   2146:            spoofonly);
                   2147:        if (errstring) {
                   2148:                /*printf("%s: %s\n", rs->sc_xname, errstring);*/
                   2149:                return;
                   2150:        }
                   2151:
                   2152:        /*
                   2153:         * Sanity check whether the found disklabel is valid.
                   2154:         *
                   2155:         * This is necessary since total size of the raid device
                   2156:         * may vary when an interleave is changed even though exactly
                   2157:         * same componets are used, and old disklabel may used
                   2158:         * if that is found.
                   2159:         */
                   2160: #ifdef RAIDDEBUG
                   2161:        if (DL_GETDSIZE(lp) != rs->sc_size)
                   2162:                printf("WARNING: %s: "
                   2163:                    "total sector size in disklabel (%d) != "
                   2164:                    "the size of raid (%ld)\n", rs->sc_xname,
                   2165:                    DL_GETDSIZE(lp), (long) rs->sc_size);
                   2166: #endif /* RAIDDEBUG */
                   2167:        for (i = 0; i < lp->d_npartitions; i++) {
                   2168:                pp = &lp->d_partitions[i];
                   2169:                if (DL_GETPOFFSET(pp) + DL_GETPSIZE(pp) > rs->sc_size)
                   2170:                        printf("WARNING: %s: end of partition `%c' "
                   2171:                            "exceeds the size of raid (%ld)\n",
                   2172:                            rs->sc_xname, 'a' + i, (long) rs->sc_size);
                   2173:        }
                   2174: }
                   2175:
                   2176: /*
                   2177:  * Lookup the provided name in the filesystem. If the file exists,
                   2178:  * is a valid block device, and isn't being used by anyone else,
                   2179:  * set *vpp to the file's vnode.
                   2180:  * You'll find the original of this in ccd.c
                   2181:  */
                   2182: int
                   2183: raidlookup(char *path, struct proc *p, struct vnode **vpp /* result */)
                   2184: {
                   2185:        struct nameidata nd;
                   2186:        struct vnode *vp;
                   2187:        struct vattr va;
                   2188:        int error;
                   2189:
                   2190:        NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p);
                   2191:        if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0) {
                   2192: #ifdef RAIDDEBUG
                   2193:                printf("RAIDframe: vn_open returned %d\n", error);
                   2194: #endif /* RAIDDEBUG */
                   2195:                return (error);
                   2196:        }
                   2197:        vp = nd.ni_vp;
                   2198:        if (vp->v_usecount > 1) {
                   2199:                VOP_UNLOCK(vp, 0, p);
                   2200:                (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
                   2201:                return (EBUSY);
                   2202:        }
                   2203:        if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) != 0) {
                   2204:                VOP_UNLOCK(vp, 0, p);
                   2205:                (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
                   2206:                return (error);
                   2207:        }
                   2208:        /* XXX: eventually we should handle VREG, too. */
                   2209:        if (va.va_type != VBLK) {
                   2210:                VOP_UNLOCK(vp, 0, p);
                   2211:                (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
                   2212:                return (ENOTBLK);
                   2213:        }
                   2214:        VOP_UNLOCK(vp, 0, p);
                   2215:        *vpp = vp;
                   2216:        return (0);
                   2217: }
                   2218:
                   2219: /*
                   2220:  * Wait interruptibly for an exclusive lock.
                   2221:  *
                   2222:  * XXX
                   2223:  * Several drivers do this; it should be abstracted and made MP-safe.
                   2224:  * (Hmm... where have we seen this warning before :->  GO )
                   2225:  */
                   2226: int
                   2227: raidlock(struct raid_softc *rs)
                   2228: {
                   2229:        int error;
                   2230:
                   2231:        while ((rs->sc_flags & RAIDF_LOCKED) != 0) {
                   2232:                rs->sc_flags |= RAIDF_WANTED;
                   2233:                if ((error = tsleep(rs, PRIBIO | PCATCH, "raidlck", 0)) != 0)
                   2234:                        return (error);
                   2235:        }
                   2236:        rs->sc_flags |= RAIDF_LOCKED;
                   2237:        return (0);
                   2238: }
                   2239:
                   2240: /*
                   2241:  * Unlock and wake up any waiters.
                   2242:  */
                   2243: void
                   2244: raidunlock(struct raid_softc *rs)
                   2245: {
                   2246:        rs->sc_flags &= ~RAIDF_LOCKED;
                   2247:        if ((rs->sc_flags & RAIDF_WANTED) != 0) {
                   2248:                rs->sc_flags &= ~RAIDF_WANTED;
                   2249:                wakeup(rs);
                   2250:        }
                   2251: }
                   2252:
                   2253:
                   2254: #define        RF_COMPONENT_INFO_OFFSET        16384   /* bytes */
                   2255: #define        RF_COMPONENT_INFO_SIZE           1024   /* bytes */
                   2256:
                   2257: int
                   2258: raidmarkclean(dev_t dev, struct vnode *b_vp, int mod_counter)
                   2259: {
                   2260:        RF_ComponentLabel_t clabel;
                   2261:        raidread_component_label(dev, b_vp, &clabel);
                   2262:        clabel.mod_counter = mod_counter;
                   2263:        clabel.clean = RF_RAID_CLEAN;
                   2264:        raidwrite_component_label(dev, b_vp, &clabel);
                   2265:        return(0);
                   2266: }
                   2267:
                   2268:
                   2269: int
                   2270: raidmarkdirty(dev_t dev, struct vnode *b_vp, int mod_counter)
                   2271: {
                   2272:        RF_ComponentLabel_t clabel;
                   2273:        raidread_component_label(dev, b_vp, &clabel);
                   2274:        clabel.mod_counter = mod_counter;
                   2275:        clabel.clean = RF_RAID_DIRTY;
                   2276:        raidwrite_component_label(dev, b_vp, &clabel);
                   2277:        return(0);
                   2278: }
                   2279:
                   2280: /* ARGSUSED */
                   2281: int
                   2282: raidread_component_label(dev_t dev, struct vnode *b_vp,
                   2283:     RF_ComponentLabel_t *clabel)
                   2284: {
                   2285:        struct buf *bp;
                   2286:        int error;
                   2287:
                   2288:        /*
                   2289:         * XXX should probably ensure that we don't try to do this if
                   2290:         * someone has changed rf_protected_sectors.
                   2291:         */
                   2292:
                   2293:        if (b_vp == NULL) {
                   2294:                /*
                   2295:                 * For whatever reason, this component is not valid.
                   2296:                 * Don't try to read a component label from it.
                   2297:                 */
                   2298:                return(EINVAL);
                   2299:        }
                   2300:
                   2301:        /* Get a block of the appropriate size... */
                   2302:        bp = geteblk((int)RF_COMPONENT_INFO_SIZE);
                   2303:        bp->b_dev = dev;
                   2304:
                   2305:        /* Get our ducks in a row for the read. */
                   2306:        bp->b_blkno = RF_COMPONENT_INFO_OFFSET / DEV_BSIZE;
                   2307:        bp->b_bcount = RF_COMPONENT_INFO_SIZE;
                   2308:        bp->b_flags |= B_READ;
                   2309:        bp->b_resid = RF_COMPONENT_INFO_SIZE / DEV_BSIZE;
                   2310:
                   2311:        (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
                   2312:
                   2313:        error = biowait(bp);
                   2314:
                   2315:        if (!error) {
                   2316:                memcpy(clabel, bp->b_data, sizeof(RF_ComponentLabel_t));
                   2317: #if 0
                   2318:                rf_print_component_label( clabel );
                   2319: #endif
                   2320:        } else {
                   2321:                db1_printf(("Failed to read RAID component label!\n"));
                   2322:        }
                   2323:
                   2324:        brelse(bp);
                   2325:        return(error);
                   2326: }
                   2327:
                   2328: /* ARGSUSED */
                   2329: int
                   2330: raidwrite_component_label(dev_t dev, struct vnode *b_vp,
                   2331:     RF_ComponentLabel_t *clabel)
                   2332: {
                   2333:        struct buf *bp;
                   2334:        int error;
                   2335:
                   2336:        /* Get a block of the appropriate size... */
                   2337:        bp = geteblk((int)RF_COMPONENT_INFO_SIZE);
                   2338:        bp->b_dev = dev;
                   2339:
                   2340:        /* Get our ducks in a row for the write. */
                   2341:        bp->b_blkno = RF_COMPONENT_INFO_OFFSET / DEV_BSIZE;
                   2342:        bp->b_bcount = RF_COMPONENT_INFO_SIZE;
                   2343:        bp->b_flags |= B_WRITE;
                   2344:        bp->b_resid = RF_COMPONENT_INFO_SIZE / DEV_BSIZE;
                   2345:
                   2346:        memset(bp->b_data, 0, RF_COMPONENT_INFO_SIZE );
                   2347:
                   2348:        memcpy(bp->b_data, clabel, sizeof(RF_ComponentLabel_t));
                   2349:
                   2350:        (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
                   2351:        error = biowait(bp);
                   2352:        brelse(bp);
                   2353:        if (error) {
                   2354:                printf("Failed to write RAID component info!\n");
                   2355:        }
                   2356:
                   2357:        return(error);
                   2358: }
                   2359:
                   2360: void
                   2361: rf_markalldirty(RF_Raid_t *raidPtr)
                   2362: {
                   2363:        RF_ComponentLabel_t clabel;
                   2364:        int r,c;
                   2365:
                   2366:        raidPtr->mod_counter++;
                   2367:        for (r = 0; r < raidPtr->numRow; r++) {
                   2368:                for (c = 0; c < raidPtr->numCol; c++) {
                   2369:                        /*
                   2370:                         * We don't want to touch (at all) a disk that has
                   2371:                         * failed.
                   2372:                         */
                   2373:                        if (!RF_DEAD_DISK(raidPtr->Disks[r][c].status)) {
                   2374:                                raidread_component_label(
                   2375:                                    raidPtr->Disks[r][c].dev,
                   2376:                                    raidPtr->raid_cinfo[r][c].ci_vp, &clabel);
                   2377:                                if (clabel.status == rf_ds_spared) {
                   2378:                                        /*
                   2379:                                         * XXX do something special...
                   2380:                                         * But whatever you do, don't
                   2381:                                         * try to access it !!!
                   2382:                                         */
                   2383:                                } else {
                   2384: #if 0
                   2385:                                        clabel.status =
                   2386:                                            raidPtr->Disks[r][c].status;
                   2387:                                        raidwrite_component_label(
                   2388:                                            raidPtr->Disks[r][c].dev,
                   2389:                                            raidPtr->raid_cinfo[r][c].ci_vp,
                   2390:                                            &clabel);
                   2391: #endif
                   2392:                                        raidmarkdirty(
                   2393:                                            raidPtr->Disks[r][c].dev,
                   2394:                                            raidPtr->raid_cinfo[r][c].ci_vp,
                   2395:                                            raidPtr->mod_counter);
                   2396:                                }
                   2397:                        }
                   2398:                }
                   2399:        }
                   2400:        /*printf("Component labels marked dirty.\n");*/
                   2401: #if 0
                   2402:        for( c = 0; c < raidPtr->numSpare ; c++) {
                   2403:                sparecol = raidPtr->numCol + c;
                   2404:                if (raidPtr->Disks[r][sparecol].status == rf_ds_used_spare) {
                   2405:                        /*
                   2406:                         * XXX This is where we get fancy and map this spare
                   2407:                         * into it's correct spot in the array.
                   2408:                         */
                   2409:                        /*
                   2410:                         * We claim this disk is "optimal" if it's
                   2411:                         * rf_ds_used_spare, as that means it should be
                   2412:                         * directly substitutable for the disk it replaced.
                   2413:                         * We note that too...
                   2414:                         */
                   2415:
                   2416:                        for(i=0;i<raidPtr->numRow;i++) {
                   2417:                                for(j=0;j<raidPtr->numCol;j++) {
                   2418:                                        if ((raidPtr->Disks[i][j].spareRow ==
                   2419:                                             r) &&
                   2420:                                            (raidPtr->Disks[i][j].spareCol ==
                   2421:                                             sparecol)) {
                   2422:                                                srow = r;
                   2423:                                                scol = sparecol;
                   2424:                                                break;
                   2425:                                        }
                   2426:                                }
                   2427:                        }
                   2428:
                   2429:                        raidread_component_label(
                   2430:                            raidPtr->Disks[r][sparecol].dev,
                   2431:                            raidPtr->raid_cinfo[r][sparecol].ci_vp, &clabel);
                   2432:                        /* Make sure status is noted. */
                   2433:                        clabel.version = RF_COMPONENT_LABEL_VERSION;
                   2434:                        clabel.mod_counter = raidPtr->mod_counter;
                   2435:                        clabel.serial_number = raidPtr->serial_number;
                   2436:                        clabel.row = srow;
                   2437:                        clabel.column = scol;
                   2438:                        clabel.num_rows = raidPtr->numRow;
                   2439:                        clabel.num_columns = raidPtr->numCol;
                   2440:                        clabel.clean = RF_RAID_DIRTY;   /* Changed in a bit. */
                   2441:                        clabel.status = rf_ds_optimal;
                   2442:                        raidwrite_component_label(
                   2443:                            raidPtr->Disks[r][sparecol].dev,
                   2444:                            raidPtr->raid_cinfo[r][sparecol].ci_vp, &clabel);
                   2445:                        raidmarkclean( raidPtr->Disks[r][sparecol].dev,
                   2446:                            raidPtr->raid_cinfo[r][sparecol].ci_vp);
                   2447:                }
                   2448:        }
                   2449:
                   2450: #endif
                   2451: }
                   2452:
                   2453:
                   2454: void
                   2455: rf_update_component_labels(RF_Raid_t *raidPtr, int final)
                   2456: {
                   2457:        RF_ComponentLabel_t clabel;
                   2458:        int sparecol;
                   2459:        int r,c;
                   2460:        int i,j;
                   2461:        int srow, scol;
                   2462:
                   2463:        srow = -1;
                   2464:        scol = -1;
                   2465:
                   2466:        /*
                   2467:         * XXX should do extra checks to make sure things really are clean,
                   2468:         * rather than blindly setting the clean bit...
                   2469:         */
                   2470:
                   2471:        raidPtr->mod_counter++;
                   2472:
                   2473:        for (r = 0; r < raidPtr->numRow; r++) {
                   2474:                for (c = 0; c < raidPtr->numCol; c++) {
                   2475:                        if (raidPtr->Disks[r][c].status == rf_ds_optimal) {
                   2476:                                raidread_component_label(
                   2477:                                        raidPtr->Disks[r][c].dev,
                   2478:                                        raidPtr->raid_cinfo[r][c].ci_vp,
                   2479:                                        &clabel);
                   2480:                                /* Make sure status is noted. */
                   2481:                                clabel.status = rf_ds_optimal;
                   2482:                                /* Bump the counter. */
                   2483:                                clabel.mod_counter = raidPtr->mod_counter;
                   2484:
                   2485:                                raidwrite_component_label(
                   2486:                                        raidPtr->Disks[r][c].dev,
                   2487:                                        raidPtr->raid_cinfo[r][c].ci_vp,
                   2488:                                        &clabel);
                   2489:                                if (final == RF_FINAL_COMPONENT_UPDATE) {
                   2490:                                        if (raidPtr->parity_good ==
                   2491:                                            RF_RAID_CLEAN) {
                   2492:                                                raidmarkclean(
                   2493:                                                    raidPtr->Disks[r][c].dev,
                   2494:                                                    raidPtr->
                   2495:                                                    raid_cinfo[r][c].ci_vp,
                   2496:                                                    raidPtr->mod_counter);
                   2497:                                        }
                   2498:                                }
                   2499:                        }
                   2500:                        /* Else we don't touch it... */
                   2501:                }
                   2502:        }
                   2503:
                   2504:        for( c = 0; c < raidPtr->numSpare ; c++) {
                   2505:                sparecol = raidPtr->numCol + c;
                   2506:                if (raidPtr->Disks[0][sparecol].status == rf_ds_used_spare) {
                   2507:                        /*
                   2508:                         * We claim this disk is "optimal" if it's
                   2509:                         * rf_ds_used_spare, as that means it should be
                   2510:                         * directly substitutable for the disk it replaced.
                   2511:                         * We note that too...
                   2512:                         */
                   2513:
                   2514:                        for(i=0;i<raidPtr->numRow;i++) {
                   2515:                                for(j=0;j<raidPtr->numCol;j++) {
                   2516:                                        if ((raidPtr->Disks[i][j].spareRow ==
                   2517:                                             0) &&
                   2518:                                            (raidPtr->Disks[i][j].spareCol ==
                   2519:                                             sparecol)) {
                   2520:                                                srow = i;
                   2521:                                                scol = j;
                   2522:                                                break;
                   2523:                                        }
                   2524:                                }
                   2525:                        }
                   2526:
                   2527:                        /* XXX Shouldn't *really* need this... */
                   2528:                        raidread_component_label(
                   2529:                            raidPtr->Disks[0][sparecol].dev,
                   2530:                            raidPtr->raid_cinfo[0][sparecol].ci_vp, &clabel);
                   2531:                        /* Make sure status is noted. */
                   2532:
                   2533:                        raid_init_component_label(raidPtr, &clabel);
                   2534:
                   2535:                        clabel.mod_counter = raidPtr->mod_counter;
                   2536:                        clabel.row = srow;
                   2537:                        clabel.column = scol;
                   2538:                        clabel.status = rf_ds_optimal;
                   2539:
                   2540:                        raidwrite_component_label(
                   2541:                            raidPtr->Disks[0][sparecol].dev,
                   2542:                            raidPtr->raid_cinfo[0][sparecol].ci_vp, &clabel);
                   2543:                        if (final == RF_FINAL_COMPONENT_UPDATE) {
                   2544:                                if (raidPtr->parity_good == RF_RAID_CLEAN) {
                   2545:                                        raidmarkclean(raidPtr->
                   2546:                                            Disks[0][sparecol].dev,
                   2547:                                            raidPtr->
                   2548:                                            raid_cinfo[0][sparecol].ci_vp,
                   2549:                                            raidPtr->mod_counter);
                   2550:                                }
                   2551:                        }
                   2552:                }
                   2553:        }
                   2554:        /*printf("Component labels updated\n");*/
                   2555: }
                   2556:
                   2557: void
                   2558: rf_close_component(RF_Raid_t *raidPtr, struct vnode *vp, int auto_configured)
                   2559: {
                   2560:        struct proc *p = curproc;
                   2561:
                   2562:        if (vp != NULL) {
                   2563:                if (auto_configured == 1) {
                   2564:                        /* component was opened by rf_find_raid_components() */
                   2565:                        VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, p);
                   2566:                        vrele(vp);
                   2567:                } else {
                   2568:                        /* component was opened by raidlookup() */
                   2569:                        (void) vn_close(vp, FREAD | FWRITE, p->p_ucred, p);
                   2570:                }
                   2571:        } else {
                   2572:                printf("vnode was NULL\n");
                   2573:        }
                   2574: }
                   2575:
                   2576: void
                   2577: rf_UnconfigureVnodes(RF_Raid_t *raidPtr)
                   2578: {
                   2579:        int r,c;
                   2580:        struct vnode *vp;
                   2581:        int acd;
                   2582:
                   2583:
                   2584:        /* We take this opportunity to close the vnodes like we should... */
                   2585:
                   2586:        for (r = 0; r < raidPtr->numRow; r++) {
                   2587:                for (c = 0; c < raidPtr->numCol; c++) {
                   2588:                        db1_printf(("Closing vnode for row: %d col: %d\n",
                   2589:                            r, c));
                   2590:                        vp = raidPtr->raid_cinfo[r][c].ci_vp;
                   2591:                        acd = raidPtr->Disks[r][c].auto_configured;
                   2592:                        rf_close_component(raidPtr, vp, acd);
                   2593:                        raidPtr->raid_cinfo[r][c].ci_vp = NULL;
                   2594:                        raidPtr->Disks[r][c].auto_configured = 0;
                   2595:                }
                   2596:        }
                   2597:        for (r = 0; r < raidPtr->numSpare; r++) {
                   2598:                db1_printf(("Closing vnode for spare: %d\n", r));
                   2599:                vp = raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp;
                   2600:                acd = raidPtr->Disks[0][raidPtr->numCol + r].auto_configured;
                   2601:                rf_close_component(raidPtr, vp, acd);
                   2602:                raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp = NULL;
                   2603:                raidPtr->Disks[0][raidPtr->numCol + r].auto_configured = 0;
                   2604:        }
                   2605: }
                   2606:
                   2607:
                   2608: void
                   2609: rf_ReconThread(struct rf_recon_req *req)
                   2610: {
                   2611:        int s;
                   2612:        RF_Raid_t *raidPtr;
                   2613:
                   2614:        s = splbio();
                   2615:        raidPtr = (RF_Raid_t *) req->raidPtr;
                   2616:        raidPtr->recon_in_progress = 1;
                   2617:
                   2618:        rf_FailDisk((RF_Raid_t *) req->raidPtr, req->row, req->col,
                   2619:                    ((req->flags & RF_FDFLAGS_RECON) ? 1 : 0));
                   2620:
                   2621:        /* XXX Get rid of this! we don't need it at all... */
                   2622:        RF_Free(req, sizeof(*req));
                   2623:
                   2624:        raidPtr->recon_in_progress = 0;
                   2625:        splx(s);
                   2626:
                   2627:        /* That's all... */
                   2628:        kthread_exit(0);        /* Does not return. */
                   2629: }
                   2630:
                   2631: void
                   2632: rf_RewriteParityThread(RF_Raid_t *raidPtr)
                   2633: {
                   2634:        int retcode;
                   2635:        int s;
                   2636:
                   2637:        s = splbio();
                   2638:        raidPtr->parity_rewrite_in_progress = 1;
                   2639:        retcode = rf_RewriteParity(raidPtr);
                   2640:        if (retcode) {
                   2641:                printf("raid%d: Error re-writing parity!\n",raidPtr->raidid);
                   2642:        } else {
                   2643:                /*
                   2644:                 * Set the clean bit !  If we shutdown correctly,
                   2645:                 * the clean bit on each component label will get
                   2646:                 * set.
                   2647:                 */
                   2648:                raidPtr->parity_good = RF_RAID_CLEAN;
                   2649:        }
                   2650:        raidPtr->parity_rewrite_in_progress = 0;
                   2651:        splx(s);
                   2652:
                   2653:        /* Anyone waiting for us to stop ?  If so, inform them... */
                   2654:        if (raidPtr->waitShutdown) {
                   2655:                wakeup(&raidPtr->parity_rewrite_in_progress);
                   2656:        }
                   2657:
                   2658:        /* That's all... */
                   2659:        kthread_exit(0);        /* Does not return. */
                   2660: }
                   2661:
                   2662:
                   2663: void
                   2664: rf_CopybackThread(RF_Raid_t *raidPtr)
                   2665: {
                   2666:        int s;
                   2667:
                   2668:        s = splbio();
                   2669:        raidPtr->copyback_in_progress = 1;
                   2670:        rf_CopybackReconstructedData(raidPtr);
                   2671:        raidPtr->copyback_in_progress = 0;
                   2672:        splx(s);
                   2673:
                   2674:        /* That's all... */
                   2675:        kthread_exit(0);        /* Does not return. */
                   2676: }
                   2677:
                   2678:
                   2679: void
                   2680: rf_ReconstructInPlaceThread(struct rf_recon_req *req)
                   2681: {
                   2682:        int retcode;
                   2683:        int s;
                   2684:        RF_Raid_t *raidPtr;
                   2685:
                   2686:        s = splbio();
                   2687:        raidPtr = req->raidPtr;
                   2688:        raidPtr->recon_in_progress = 1;
                   2689:        retcode = rf_ReconstructInPlace(raidPtr, req->row, req->col);
                   2690:        RF_Free(req, sizeof(*req));
                   2691:        raidPtr->recon_in_progress = 0;
                   2692:        splx(s);
                   2693:
                   2694:        /* That's all... */
                   2695:        kthread_exit(0);        /* Does not return. */
                   2696: }
                   2697:
                   2698:
                   2699: RF_AutoConfig_t *
                   2700: rf_find_raid_components(void)
                   2701: {
                   2702: #ifdef RAID_AUTOCONFIG
                   2703:        int major;
                   2704:        struct vnode *vp;
                   2705:        struct disklabel label;
                   2706:        struct device *dv;
                   2707:        dev_t dev;
                   2708:        int error;
                   2709:        int i;
                   2710:        int good_one;
                   2711:        RF_ComponentLabel_t *clabel;
                   2712:        RF_AutoConfig_t *ac;
                   2713: #endif /* RAID_AUTOCONFIG */
                   2714:        RF_AutoConfig_t *ac_list;
                   2715:
                   2716:
                   2717:        /* Initialize the AutoConfig list. */
                   2718:        ac_list = NULL;
                   2719:
                   2720: #ifdef RAID_AUTOCONFIG
                   2721:        /* We begin by trolling through *all* the devices on the system. */
                   2722:
                   2723:        TAILQ_FOREACH(dv, &alldevs, dv_list) {
                   2724:
                   2725:                /* We are only interested in disks... */
                   2726:                if (dv->dv_class != DV_DISK)
                   2727:                        continue;
                   2728:
                   2729:                /* We don't care about floppies... */
                   2730:                if (!strcmp(dv->dv_cfdata->cf_driver->cd_name,"fd")) {
                   2731:                        continue;
                   2732:                }
                   2733:
                   2734:                /*
                   2735:                 * We need to find the device_name_to_block_device_major
                   2736:                 * stuff.
                   2737:                 */
                   2738:                major = findblkmajor(dv);
                   2739:
                   2740:                /* Get a vnode for the raw partition of this disk. */
                   2741:
                   2742:                dev = MAKEDISKDEV(major, dv->dv_unit, RAW_PART);
                   2743:                if (bdevvp(dev, &vp))
                   2744:                        panic("RAID can't alloc vnode");
                   2745:
                   2746:                error = VOP_OPEN(vp, FREAD, NOCRED, 0);
                   2747:
                   2748:                if (error) {
                   2749:                        /*
                   2750:                         * "Who cares."  Continue looking
                   2751:                         * for something that exists.
                   2752:                         */
                   2753:                        vput(vp);
                   2754:                        continue;
                   2755:                }
                   2756:
                   2757:                /* Ok, the disk exists.  Go get the disklabel. */
                   2758:                error = VOP_IOCTL(vp, DIOCGDINFO, (caddr_t)&label,
                   2759:                                  FREAD, NOCRED, 0);
                   2760:                if (error) {
                   2761:                        /*
                   2762:                         * XXX can't happen - open() would
                   2763:                         * have errored out (or faked up one).
                   2764:                         */
                   2765:                        printf("can't get label for dev %s%c (%d)!?!?\n",
                   2766:                            dv->dv_xname, 'a' + RAW_PART, error);
                   2767:                }
                   2768:
                   2769:                /*
                   2770:                 * We don't need this any more.  We'll allocate it again
                   2771:                 * a little later if we really do...
                   2772:                 */
                   2773:                VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
                   2774:                vrele(vp);
                   2775:
                   2776:                for (i=0; i < label.d_npartitions; i++) {
                   2777:                        /*
                   2778:                         * We only support partitions marked as RAID.
                   2779:                         * Except on sparc/sparc64 where FS_RAID doesn't
                   2780:                         * fit in the SUN disklabel and we need to look
                   2781:                         * into each and every partition !!!
                   2782:                         */
                   2783: #if !defined(__sparc__) && !defined(__sparc64__) && !defined(__sun3__)
                   2784:                        if (label.d_partitions[i].p_fstype != FS_RAID)
                   2785:                                continue;
                   2786: #else /* !__sparc__ && !__sparc64__ && !__sun3__ */
                   2787:                        if (label.d_partitions[i].p_fstype == FS_SWAP ||
                   2788:                            label.d_partitions[i].p_fstype == FS_UNUSED)
                   2789:                                continue;
                   2790: #endif /* __sparc__ || __sparc64__ || __sun3__ */
                   2791:
                   2792:                        dev = MAKEDISKDEV(major, dv->dv_unit, i);
                   2793:                        if (bdevvp(dev, &vp))
                   2794:                                panic("RAID can't alloc vnode");
                   2795:
                   2796:                        error = VOP_OPEN(vp, FREAD, NOCRED, 0);
                   2797:                        if (error) {
                   2798:                                /* Whatever... */
                   2799:                                vput(vp);
                   2800:                                continue;
                   2801:                        }
                   2802:
                   2803:                        good_one = 0;
                   2804:
                   2805:                        clabel = (RF_ComponentLabel_t *)
                   2806:                                malloc(sizeof(RF_ComponentLabel_t), M_RAIDFRAME,
                   2807:                                    M_NOWAIT);
                   2808:                        if (clabel == NULL) {
                   2809:                                /* XXX CLEANUP HERE. */
                   2810:                                printf("RAID auto config: out of memory!\n");
                   2811:                                return(NULL); /* XXX probably should panic ? */
                   2812:                        }
                   2813:
                   2814:                        if (!raidread_component_label(dev, vp, clabel)) {
                   2815:                                /* Got the label.  Does it look reasonable ? */
                   2816:                                if (rf_reasonable_label(clabel) &&
                   2817:                                    (clabel->partitionSize <=
                   2818:                                     DL_GETPSIZE(&label.d_partitions[i]))) {
                   2819: #ifdef RAIDDEBUG
                   2820:                                        printf("Component on: %s%c: %d\n",
                   2821:                                            dv->dv_xname, 'a'+i,
                   2822:                                            DL_GETPSIZE(&label.d_partitions[i]));
                   2823:                                        rf_print_component_label(clabel);
                   2824: #endif /* RAIDDEBUG */
                   2825:                                        /*
                   2826:                                         * If it's reasonable, add it,
                   2827:                                         * else ignore it.
                   2828:                                         */
                   2829:                                        ac = (RF_AutoConfig_t *)
                   2830:                                                malloc(sizeof(RF_AutoConfig_t),
                   2831:                                                    M_RAIDFRAME, M_NOWAIT);
                   2832:                                        if (ac == NULL) {
                   2833:                                                /* XXX should panic ??? */
                   2834:                                                return(NULL);
                   2835:                                        }
                   2836:
                   2837:                                        snprintf(ac->devname,
                   2838:                                                 sizeof ac->devname, "%s%c",
                   2839:                                                 dv->dv_xname, 'a'+i);
                   2840:                                        ac->dev = dev;
                   2841:                                        ac->vp = vp;
                   2842:                                        ac->clabel = clabel;
                   2843:                                        ac->next = ac_list;
                   2844:                                        ac_list = ac;
                   2845:                                        good_one = 1;
                   2846:                                }
                   2847:                        }
                   2848:                        if (!good_one) {
                   2849:                                /* Cleanup. */
                   2850:                                free(clabel, M_RAIDFRAME);
                   2851:                                VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
                   2852:                                vrele(vp);
                   2853:                        }
                   2854:                }
                   2855:        }
                   2856: #endif /* RAID_AUTOCONFIG */
                   2857:        return(ac_list);
                   2858: }
                   2859:
                   2860: #ifdef RAID_AUTOCONFIG
                   2861: int
                   2862: rf_reasonable_label(RF_ComponentLabel_t *clabel)
                   2863: {
                   2864:
                   2865:        if (((clabel->version==RF_COMPONENT_LABEL_VERSION_1) ||
                   2866:             (clabel->version==RF_COMPONENT_LABEL_VERSION)) &&
                   2867:            ((clabel->clean == RF_RAID_CLEAN) ||
                   2868:             (clabel->clean == RF_RAID_DIRTY)) &&
                   2869:            clabel->row >=0 &&
                   2870:            clabel->column >= 0 &&
                   2871:            clabel->num_rows > 0 &&
                   2872:            clabel->num_columns > 0 &&
                   2873:            clabel->row < clabel->num_rows &&
                   2874:            clabel->column < clabel->num_columns &&
                   2875:            clabel->blockSize > 0 &&
                   2876:            clabel->numBlocks > 0) {
                   2877:                /* Label looks reasonable enough... */
                   2878:                return(1);
                   2879:        }
                   2880:        return(0);
                   2881: }
                   2882: #endif /* RAID_AUTOCONFIG */
                   2883:
                   2884: void
                   2885: rf_print_component_label(RF_ComponentLabel_t *clabel)
                   2886: {
                   2887:        printf("   Row: %d Column: %d Num Rows: %d Num Columns: %d\n",
                   2888:            clabel->row, clabel->column, clabel->num_rows, clabel->num_columns);
                   2889:        printf("   Version: %d Serial Number: %d Mod Counter: %d\n",
                   2890:            clabel->version, clabel->serial_number, clabel->mod_counter);
                   2891:        printf("   Clean: %s Status: %d\n", clabel->clean ? "Yes" : "No",
                   2892:            clabel->status );
                   2893:        printf("   sectPerSU: %d SUsPerPU: %d SUsPerRU: %d\n",
                   2894:            clabel->sectPerSU, clabel->SUsPerPU, clabel->SUsPerRU);
                   2895:        printf("   RAID Level: %c  blocksize: %d numBlocks: %d\n",
                   2896:            (char) clabel->parityConfig, clabel->blockSize, clabel->numBlocks);
                   2897:        printf("   Autoconfig: %s\n", clabel->autoconfigure ? "Yes" : "No" );
                   2898:        printf("   Contains root partition: %s\n", clabel->root_partition ?
                   2899:            "Yes" : "No" );
                   2900:        printf("   Last configured as: raid%d\n", clabel->last_unit );
                   2901: #if 0
                   2902:        printf("   Config order: %d\n", clabel->config_order);
                   2903: #endif
                   2904: }
                   2905:
                   2906: RF_ConfigSet_t *
                   2907: rf_create_auto_sets(RF_AutoConfig_t *ac_list)
                   2908: {
                   2909:        RF_AutoConfig_t *ac;
                   2910:        RF_ConfigSet_t *config_sets;
                   2911:        RF_ConfigSet_t *cset;
                   2912:        RF_AutoConfig_t *ac_next;
                   2913:
                   2914:
                   2915:        config_sets = NULL;
                   2916:
                   2917:        /*
                   2918:         * Go through the AutoConfig list, and figure out which components
                   2919:         * belong to what sets.
                   2920:         */
                   2921:        ac = ac_list;
                   2922:        while(ac!=NULL) {
                   2923:                /*
                   2924:                 * We're going to putz with ac->next, so save it here
                   2925:                 * for use at the end of the loop.
                   2926:                 */
                   2927:                ac_next = ac->next;
                   2928:
                   2929:                if (config_sets == NULL) {
                   2930:                        /* We will need at least this one... */
                   2931:                        config_sets = (RF_ConfigSet_t *)
                   2932:                                malloc(sizeof(RF_ConfigSet_t), M_RAIDFRAME,
                   2933:                                    M_NOWAIT);
                   2934:                        if (config_sets == NULL) {
                   2935:                                panic("rf_create_auto_sets: No memory!");
                   2936:                        }
                   2937:                        /* This one is easy :) */
                   2938:                        config_sets->ac = ac;
                   2939:                        config_sets->next = NULL;
                   2940:                        config_sets->rootable = 0;
                   2941:                        ac->next = NULL;
                   2942:                } else {
                   2943:                        /* Which set does this component fit into ? */
                   2944:                        cset = config_sets;
                   2945:                        while(cset!=NULL) {
                   2946:                                if (rf_does_it_fit(cset, ac)) {
                   2947:                                        /* Looks like it matches... */
                   2948:                                        ac->next = cset->ac;
                   2949:                                        cset->ac = ac;
                   2950:                                        break;
                   2951:                                }
                   2952:                                cset = cset->next;
                   2953:                        }
                   2954:                        if (cset==NULL) {
                   2955:                                /* Didn't find a match above... new set... */
                   2956:                                cset = (RF_ConfigSet_t *)
                   2957:                                        malloc(sizeof(RF_ConfigSet_t),
                   2958:                                            M_RAIDFRAME, M_NOWAIT);
                   2959:                                if (cset == NULL) {
                   2960:                                        panic("rf_create_auto_sets: No memory!");
                   2961:                                }
                   2962:                                cset->ac = ac;
                   2963:                                ac->next = NULL;
                   2964:                                cset->next = config_sets;
                   2965:                                cset->rootable = 0;
                   2966:                                config_sets = cset;
                   2967:                        }
                   2968:                }
                   2969:                ac = ac_next;
                   2970:        }
                   2971:
                   2972:
                   2973:        return(config_sets);
                   2974: }
                   2975:
                   2976: int
                   2977: rf_does_it_fit(RF_ConfigSet_t *cset, RF_AutoConfig_t *ac)
                   2978: {
                   2979:        RF_ComponentLabel_t *clabel1, *clabel2;
                   2980:
                   2981:        /*
                   2982:         * If this one matches the *first* one in the set, that's good
                   2983:         * enough, since the other members of the set would have been
                   2984:         * through here too...
                   2985:         */
                   2986:        /*
                   2987:         * Note that we are not checking partitionSize here...
                   2988:         *
                   2989:         * Note that we are also not checking the mod_counters here.
                   2990:         * If everything else matches except the mod_counter, that's
                   2991:         * good enough for this test.  We will deal with the mod_counters
                   2992:         * a little later in the autoconfiguration process.
                   2993:         *
                   2994:         *  (clabel1->mod_counter == clabel2->mod_counter) &&
                   2995:         *
                   2996:         * The reason we don't check for this is that failed disks
                   2997:         * will have lower modification counts.  If those disks are
                   2998:         * not added to the set they used to belong to, then they will
                   2999:         * form their own set, which may result in 2 different sets,
                   3000:         * for example, competing to be configured at raid0, and
                   3001:         * perhaps competing to be the root filesystem set.  If the
                   3002:         * wrong ones get configured, or both attempt to become /,
                   3003:         * weird behaviour and or serious lossage will occur.  Thus we
                   3004:         * need to bring them into the fold here, and kick them out at
                   3005:         * a later point.
                   3006:         */
                   3007:
                   3008:        clabel1 = cset->ac->clabel;
                   3009:        clabel2 = ac->clabel;
                   3010:        if ((clabel1->version == clabel2->version) &&
                   3011:            (clabel1->serial_number == clabel2->serial_number) &&
                   3012:            (clabel1->num_rows == clabel2->num_rows) &&
                   3013:            (clabel1->num_columns == clabel2->num_columns) &&
                   3014:            (clabel1->sectPerSU == clabel2->sectPerSU) &&
                   3015:            (clabel1->SUsPerPU == clabel2->SUsPerPU) &&
                   3016:            (clabel1->SUsPerRU == clabel2->SUsPerRU) &&
                   3017:            (clabel1->parityConfig == clabel2->parityConfig) &&
                   3018:            (clabel1->maxOutstanding == clabel2->maxOutstanding) &&
                   3019:            (clabel1->blockSize == clabel2->blockSize) &&
                   3020:            (clabel1->numBlocks == clabel2->numBlocks) &&
                   3021:            (clabel1->autoconfigure == clabel2->autoconfigure) &&
                   3022:            (clabel1->root_partition == clabel2->root_partition) &&
                   3023:            (clabel1->last_unit == clabel2->last_unit) &&
                   3024:            (clabel1->config_order == clabel2->config_order)) {
                   3025:                /* If it get's here, it almost *has* to be a match. */
                   3026:        } else {
                   3027:                /* It's not consistent with somebody in the set...  Punt. */
                   3028:                return(0);
                   3029:        }
                   3030:        /* All was fine.. It must fit... */
                   3031:        return(1);
                   3032: }
                   3033:
                   3034: int
                   3035: rf_have_enough_components(RF_ConfigSet_t *cset)
                   3036: {
                   3037:        RF_AutoConfig_t *ac;
                   3038:        RF_AutoConfig_t *auto_config;
                   3039:        RF_ComponentLabel_t *clabel;
                   3040:        int r,c;
                   3041:        int num_rows;
                   3042:        int num_cols;
                   3043:        int num_missing;
                   3044:        int mod_counter;
                   3045:        int mod_counter_found;
                   3046:        int even_pair_failed;
                   3047:        char parity_type;
                   3048:
                   3049:
                   3050:        /*
                   3051:         * Check to see that we have enough 'live' components
                   3052:         * of this set.  If so, we can configure it if necessary.
                   3053:         */
                   3054:
                   3055:        num_rows = cset->ac->clabel->num_rows;
                   3056:        num_cols = cset->ac->clabel->num_columns;
                   3057:        parity_type = cset->ac->clabel->parityConfig;
                   3058:
                   3059:        /* XXX Check for duplicate components !?!?!? */
                   3060:
                   3061:        /* Determine what the mod_counter is supposed to be for this set. */
                   3062:
                   3063:        mod_counter_found = 0;
                   3064:        mod_counter = 0;
                   3065:        ac = cset->ac;
                   3066:        while(ac!=NULL) {
                   3067:                if (mod_counter_found==0) {
                   3068:                        mod_counter = ac->clabel->mod_counter;
                   3069:                        mod_counter_found = 1;
                   3070:                } else {
                   3071:                        if (ac->clabel->mod_counter > mod_counter) {
                   3072:                                mod_counter = ac->clabel->mod_counter;
                   3073:                        }
                   3074:                }
                   3075:                ac = ac->next;
                   3076:        }
                   3077:
                   3078:        num_missing = 0;
                   3079:        auto_config = cset->ac;
                   3080:
                   3081:        for(r=0; r<num_rows; r++) {
                   3082:                even_pair_failed = 0;
                   3083:                for(c=0; c<num_cols; c++) {
                   3084:                        ac = auto_config;
                   3085:                        while(ac!=NULL) {
                   3086:                                if ((ac->clabel->row == r) &&
                   3087:                                    (ac->clabel->column == c) &&
                   3088:                                    (ac->clabel->mod_counter == mod_counter)) {
                   3089:                                        /* It's this one... */
                   3090: #ifdef RAIDDEBUG
                   3091:                                        printf("Found: %s at %d,%d\n",
                   3092:                                            ac->devname,r,c);
                   3093: #endif /* RAIDDEBUG */
                   3094:                                        break;
                   3095:                                }
                   3096:                                ac=ac->next;
                   3097:                        }
                   3098:                        if (ac==NULL) {
                   3099:                                /* Didn't find one here! */
                   3100:                                /*
                   3101:                                 * Special case for RAID 1, especially
                   3102:                                 * where there are more than 2
                   3103:                                 * components (where RAIDframe treats
                   3104:                                 * things a little differently :( )
                   3105:                                 */
                   3106:                                if (parity_type == '1') {
                   3107:                                        if (c%2 == 0) { /* Even component. */
                   3108:                                                even_pair_failed = 1;
                   3109:                                        } else {        /*
                   3110:                                                         * Odd component.
                   3111:                                                         * If we're failed,
                   3112:                                                         * and so is the even
                   3113:                                                         * component, it's
                   3114:                                                         * "Good Night, Charlie"
                   3115:                                                         */
                   3116:                                                if (even_pair_failed == 1) {
                   3117:                                                        return(0);
                   3118:                                                }
                   3119:                                        }
                   3120:                                } else {
                   3121:                                        /* Normal accounting. */
                   3122:                                        num_missing++;
                   3123:                                }
                   3124:                        }
                   3125:                        if ((parity_type == '1') && (c%2 == 1)) {
                   3126:                                /*
                   3127:                                 * Just did an even component, and we didn't
                   3128:                                 * bail... Reset the even_pair_failed flag,
                   3129:                                 * and go on to the next component...
                   3130:                                 */
                   3131:                                even_pair_failed = 0;
                   3132:                        }
                   3133:                }
                   3134:        }
                   3135:
                   3136:        clabel = cset->ac->clabel;
                   3137:
                   3138:        if (((clabel->parityConfig == '0') && (num_missing > 0)) ||
                   3139:            ((clabel->parityConfig == '4') && (num_missing > 1)) ||
                   3140:            ((clabel->parityConfig == '5') && (num_missing > 1))) {
                   3141:                /* XXX This needs to be made *much* more general. */
                   3142:                /* Too many failures. */
                   3143:                return(0);
                   3144:        }
                   3145:        /*
                   3146:         * Otherwise, all is well, and we've got enough to take a kick
                   3147:         * at autoconfiguring this set.
                   3148:         */
                   3149:        return(1);
                   3150: }
                   3151:
                   3152: void
                   3153: rf_create_configuration(RF_AutoConfig_t *ac, RF_Config_t *config,
                   3154:     RF_Raid_t *raidPtr)
                   3155: {
                   3156:        RF_ComponentLabel_t *clabel;
                   3157:        int i;
                   3158:
                   3159:        clabel = ac->clabel;
                   3160:
                   3161:        /* 1. Fill in the common stuff. */
                   3162:        config->numRow = clabel->num_rows;
                   3163:        config->numCol = clabel->num_columns;
                   3164:        config->numSpare = 0;   /* XXX Should this be set here ? */
                   3165:        config->sectPerSU = clabel->sectPerSU;
                   3166:        config->SUsPerPU = clabel->SUsPerPU;
                   3167:        config->SUsPerRU = clabel->SUsPerRU;
                   3168:        config->parityConfig = clabel->parityConfig;
                   3169:        /* XXX... */
                   3170:        strlcpy(config->diskQueueType,"fifo", sizeof config->diskQueueType);
                   3171:        config->maxOutstandingDiskReqs = clabel->maxOutstanding;
                   3172:        config->layoutSpecificSize = 0; /* XXX ?? */
                   3173:
                   3174:        while(ac!=NULL) {
                   3175:                /*
                   3176:                 * row/col values will be in range due to the checks
                   3177:                 * in reasonable_label().
                   3178:                 */
                   3179:                strlcpy(config->devnames[ac->clabel->row][ac->clabel->column],
                   3180:                    ac->devname,
                   3181:                    sizeof config->devnames[ac->clabel->row][ac->clabel->column]);
                   3182:                ac = ac->next;
                   3183:        }
                   3184:
                   3185:        for(i=0;i<RF_MAXDBGV;i++) {
                   3186:                config->debugVars[i][0] = NULL;
                   3187:        }
                   3188:
                   3189: #ifdef RAID_DEBUG_ALL
                   3190:
                   3191: #ifdef RF_DBG_OPTION
                   3192: #undef RF_DBG_OPTION
                   3193: #endif /* RF_DBG_OPTION */
                   3194:
                   3195: #ifdef __STDC__
                   3196: #define        RF_DBG_OPTION(_option_,_val_)   do {                            \
                   3197:        snprintf(&(config->debugVars[i++][0]), 50, "%s %ld",            \
                   3198:            #_option_, _val_);                                          \
                   3199: } while (0)
                   3200: #else  /* __STDC__ */
                   3201: #define        RF_DBG_OPTION(_option_,_val_)   do {                            \
                   3202:        snprintf(&(config->debugVars[i++][0]), 50, "%s %ld",            \
                   3203:            "/**/_option_/**/", _val_);                                 \
                   3204: } while (0)
                   3205: #endif /* __STDC__ */
                   3206:
                   3207:        i = 0;
                   3208:
                   3209: /*     RF_DBG_OPTION(accessDebug, 0);                                  */
                   3210: /*     RF_DBG_OPTION(accessTraceBufSize, 0);                           */
                   3211:        RF_DBG_OPTION(cscanDebug, 1);           /* Debug CSCAN sorting. */
                   3212:        RF_DBG_OPTION(dagDebug, 1);
                   3213: /*     RF_DBG_OPTION(debugPrintUseBuffer, 0);                          */
                   3214:        RF_DBG_OPTION(degDagDebug, 1);
                   3215:        RF_DBG_OPTION(disableAsyncAccs, 1);
                   3216:        RF_DBG_OPTION(diskDebug, 1);
                   3217:        RF_DBG_OPTION(enableAtomicRMW, 0);
                   3218:                /*
                   3219:                 * This debug variable enables locking of the
                   3220:                 * disk arm during small-write operations.
                   3221:                 * Setting this variable to anything other than
                   3222:                 * 0 will result in deadlock.  (wvcii)
                   3223:                 */
                   3224:        RF_DBG_OPTION(engineDebug, 1);
                   3225:        RF_DBG_OPTION(fifoDebug, 1);            /* Debug fifo queueing. */
                   3226: /*     RF_DBG_OPTION(floatingRbufDebug, 1);                            */
                   3227: /*     RF_DBG_OPTION(forceHeadSepLimit, -1);                           */
                   3228: /*     RF_DBG_OPTION(forceNumFloatingReconBufs, -1);                   */
                   3229:                /*
                   3230:                 * Wire down the number of extra recon buffers
                   3231:                 * to use.
                   3232:                 */
                   3233: /*     RF_DBG_OPTION(keepAccTotals, 1);                                */
                   3234:                /* Turn on keep_acc_totals. */
                   3235:        RF_DBG_OPTION(lockTableSize, RF_DEFAULT_LOCK_TABLE_SIZE);
                   3236:        RF_DBG_OPTION(mapDebug, 1);
                   3237:        RF_DBG_OPTION(maxNumTraces, -1);
                   3238:
                   3239: /*     RF_DBG_OPTION(memChunkDebug, 1);                                */
                   3240: /*     RF_DBG_OPTION(memDebug, 1);                                     */
                   3241: /*     RF_DBG_OPTION(memDebugAddress, 1);                              */
                   3242: /*     RF_DBG_OPTION(numBufsToAccumulate, 1);                          */
                   3243:                /*
                   3244:                 * Number of buffers to accumulate before
                   3245:                 * doing XOR.
                   3246:                 */
                   3247:        RF_DBG_OPTION(prReconSched, 0);
                   3248:        RF_DBG_OPTION(printDAGsDebug, 1);
                   3249:        RF_DBG_OPTION(printStatesDebug, 1);
                   3250:        RF_DBG_OPTION(protectedSectors, 64L);
                   3251:                /*
                   3252:                 * Number of sectors at start of disk to exclude
                   3253:                 * from RAID address space.
                   3254:                 */
                   3255:        RF_DBG_OPTION(pssDebug, 1);
                   3256:        RF_DBG_OPTION(queueDebug, 1);
                   3257:        RF_DBG_OPTION(quiesceDebug, 1);
                   3258:        RF_DBG_OPTION(raidSectorOffset, 0);
                   3259:                /*
                   3260:                 * Value added to all incoming sectors to debug
                   3261:                 * alignment problems.
                   3262:                 */
                   3263:        RF_DBG_OPTION(reconDebug, 1);
                   3264:        RF_DBG_OPTION(reconbufferDebug, 1);
                   3265:        RF_DBG_OPTION(scanDebug, 1);            /* Debug SCAN sorting.  */
                   3266:        RF_DBG_OPTION(showXorCallCounts, 0);
                   3267:                /* Show n-way Xor call counts. */
                   3268:        RF_DBG_OPTION(shutdownDebug, 1);        /* Show shutdown calls. */
                   3269:        RF_DBG_OPTION(sizePercentage, 100);
                   3270:        RF_DBG_OPTION(sstfDebug, 1);
                   3271:                /* Turn on debugging info for sstf queueing. */
                   3272:        RF_DBG_OPTION(stripeLockDebug, 1);
                   3273:        RF_DBG_OPTION(suppressLocksAndLargeWrites, 0);
                   3274:        RF_DBG_OPTION(suppressTraceDelays, 0);
                   3275:        RF_DBG_OPTION(useMemChunks, 1);
                   3276:        RF_DBG_OPTION(validateDAGDebug, 1);
                   3277:        RF_DBG_OPTION(validateVisitedDebug, 1);
                   3278:                /* XXX turn to zero by default ? */
                   3279:        RF_DBG_OPTION(verifyParityDebug, 1);
                   3280:        RF_DBG_OPTION(debugKernelAccess, 1);
                   3281:                /* DoAccessKernel debugging. */
                   3282:
                   3283: #if RF_INCLUDE_PARITYLOGGING > 0
                   3284:        RF_DBG_OPTION(forceParityLogReint, 0);
                   3285:        RF_DBG_OPTION(numParityRegions, 0);
                   3286:                /* Number of regions in the array. */
                   3287:        RF_DBG_OPTION(numReintegrationThreads, 1);
                   3288:        RF_DBG_OPTION(parityLogDebug, 1);
                   3289:                /* If nonzero, enables debugging of parity logging. */
                   3290:        RF_DBG_OPTION(totalInCoreLogCapacity, 1024 * 1024);
                   3291:                /* Target bytes available for in-core logs. */
                   3292: #endif /* RF_INCLUDE_PARITYLOGGING > 0 */
                   3293:
                   3294: #endif /* RAID_DEBUG_ALL */
                   3295: }
                   3296:
                   3297: int
                   3298: rf_set_autoconfig(RF_Raid_t *raidPtr, int new_value)
                   3299: {
                   3300:        RF_ComponentLabel_t clabel;
                   3301:        struct vnode *vp;
                   3302:        dev_t dev;
                   3303:        int row, column;
                   3304:
                   3305:        raidPtr->autoconfigure = new_value;
                   3306:        for(row=0; row<raidPtr->numRow; row++) {
                   3307:                for(column=0; column<raidPtr->numCol; column++) {
                   3308:                        if (raidPtr->Disks[row][column].status ==
                   3309:                            rf_ds_optimal) {
                   3310:                                dev = raidPtr->Disks[row][column].dev;
                   3311:                                vp = raidPtr->raid_cinfo[row][column].ci_vp;
                   3312:                                raidread_component_label(dev, vp, &clabel);
                   3313:                                clabel.autoconfigure = new_value;
                   3314:                                raidwrite_component_label(dev, vp, &clabel);
                   3315:                        }
                   3316:                }
                   3317:        }
                   3318:        return(new_value);
                   3319: }
                   3320:
                   3321: int
                   3322: rf_set_rootpartition(RF_Raid_t *raidPtr, int new_value)
                   3323: {
                   3324:        RF_ComponentLabel_t clabel;
                   3325:        struct vnode *vp;
                   3326:        dev_t dev;
                   3327:        int row, column;
                   3328:
                   3329:        raidPtr->root_partition = new_value;
                   3330:        for(row=0; row<raidPtr->numRow; row++) {
                   3331:                for(column=0; column<raidPtr->numCol; column++) {
                   3332:                        if (raidPtr->Disks[row][column].status ==
                   3333:                            rf_ds_optimal) {
                   3334:                                dev = raidPtr->Disks[row][column].dev;
                   3335:                                vp = raidPtr->raid_cinfo[row][column].ci_vp;
                   3336:                                raidread_component_label(dev, vp, &clabel);
                   3337:                                clabel.root_partition = new_value;
                   3338:                                raidwrite_component_label(dev, vp, &clabel);
                   3339:                        }
                   3340:                }
                   3341:        }
                   3342:        return(new_value);
                   3343: }
                   3344:
                   3345: void
                   3346: rf_release_all_vps(RF_ConfigSet_t *cset)
                   3347: {
                   3348:        RF_AutoConfig_t *ac;
                   3349:
                   3350:        ac = cset->ac;
                   3351:        while(ac!=NULL) {
                   3352:                /* Close the vp, and give it back. */
                   3353:                if (ac->vp) {
                   3354:                        VOP_CLOSE(ac->vp, FREAD, NOCRED, 0);
                   3355:                        vrele(ac->vp);
                   3356:                        ac->vp = NULL;
                   3357:                }
                   3358:                ac = ac->next;
                   3359:        }
                   3360: }
                   3361:
                   3362:
                   3363: void
                   3364: rf_cleanup_config_set(RF_ConfigSet_t *cset)
                   3365: {
                   3366:        RF_AutoConfig_t *ac;
                   3367:        RF_AutoConfig_t *next_ac;
                   3368:
                   3369:        ac = cset->ac;
                   3370:        while(ac!=NULL) {
                   3371:                next_ac = ac->next;
                   3372:                /* Nuke the label. */
                   3373:                free(ac->clabel, M_RAIDFRAME);
                   3374:                /* Cleanup the config structure. */
                   3375:                free(ac, M_RAIDFRAME);
                   3376:                /* "next..." */
                   3377:                ac = next_ac;
                   3378:        }
                   3379:        /* And, finally, nuke the config set. */
                   3380:        free(cset, M_RAIDFRAME);
                   3381: }
                   3382:
                   3383:
                   3384: void
                   3385: raid_init_component_label(RF_Raid_t *raidPtr, RF_ComponentLabel_t *clabel)
                   3386: {
                   3387:        /* Current version number. */
                   3388:        clabel->version = RF_COMPONENT_LABEL_VERSION;
                   3389:        clabel->serial_number = raidPtr->serial_number;
                   3390:        clabel->mod_counter = raidPtr->mod_counter;
                   3391:        clabel->num_rows = raidPtr->numRow;
                   3392:        clabel->num_columns = raidPtr->numCol;
                   3393:        clabel->clean = RF_RAID_DIRTY;  /* Not clean. */
                   3394:        clabel->status = rf_ds_optimal; /* "It's good !" */
                   3395:
                   3396:        clabel->sectPerSU = raidPtr->Layout.sectorsPerStripeUnit;
                   3397:        clabel->SUsPerPU = raidPtr->Layout.SUsPerPU;
                   3398:        clabel->SUsPerRU = raidPtr->Layout.SUsPerRU;
                   3399:
                   3400:        clabel->blockSize = raidPtr->bytesPerSector;
                   3401:        clabel->numBlocks = raidPtr->sectorsPerDisk;
                   3402:
                   3403:        /* XXX Not portable. */
                   3404:        clabel->parityConfig = raidPtr->Layout.map->parityConfig;
                   3405:        clabel->maxOutstanding = raidPtr->maxOutstanding;
                   3406:        clabel->autoconfigure = raidPtr->autoconfigure;
                   3407:        clabel->root_partition = raidPtr->root_partition;
                   3408:        clabel->last_unit = raidPtr->raidid;
                   3409:        clabel->config_order = raidPtr->config_order;
                   3410: }
                   3411:
                   3412: int
                   3413: rf_auto_config_set(RF_ConfigSet_t *cset, int *unit)
                   3414: {
                   3415:        RF_Raid_t *raidPtr;
                   3416:        RF_Config_t *config;
                   3417:        int raidID;
                   3418:        int retcode;
                   3419:
                   3420:        db1_printf(("RAID autoconfigure\n"));
                   3421:
                   3422:        retcode = 0;
                   3423:        *unit = -1;
                   3424:
                   3425:        /* 1. Create a config structure. */
                   3426:
                   3427:        config = (RF_Config_t *)malloc(sizeof(RF_Config_t), M_RAIDFRAME,
                   3428:            M_NOWAIT);
                   3429:        if (config==NULL) {
                   3430:                printf("Out of mem!?!?\n");
                   3431:                                /* XXX Do something more intelligent here. */
                   3432:                return(1);
                   3433:        }
                   3434:
                   3435:        memset(config, 0, sizeof(RF_Config_t));
                   3436:
                   3437:        /* XXX raidID needs to be set correctly... */
                   3438:
                   3439:        /*
                   3440:         * 2. Figure out what RAID ID this one is supposed to live at.
                   3441:         * See if we can get the same RAID dev that it was configured
                   3442:         * on last time...
                   3443:         */
                   3444:
                   3445:        raidID = cset->ac->clabel->last_unit;
                   3446:        if ((raidID < 0) || (raidID >= numraid)) {
                   3447:                /* Let's not wander off into lala land. */
                   3448:                raidID = numraid - 1;
                   3449:        }
                   3450:        if (raidPtrs[raidID]->valid != 0) {
                   3451:
                   3452:                /*
                   3453:                 * Nope...  Go looking for an alternative...
                   3454:                 * Start high so we don't immediately use raid0 if that's
                   3455:                 * not taken.
                   3456:                 */
                   3457:
                   3458:                for(raidID = numraid - 1; raidID >= 0; raidID--) {
                   3459:                        if (raidPtrs[raidID]->valid == 0) {
                   3460:                                /* We can use this one ! */
                   3461:                                break;
                   3462:                        }
                   3463:                }
                   3464:        }
                   3465:
                   3466:        if (raidID < 0) {
                   3467:                /* Punt... */
                   3468:                printf("Unable to auto configure this set!\n");
                   3469:                printf("(Out of RAID devs!)\n");
                   3470:                return(1);
                   3471:        }
                   3472:        raidPtr = raidPtrs[raidID];
                   3473:
                   3474:        /* XXX All this stuff should be done SOMEWHERE ELSE ! */
                   3475:        raidPtr->raidid = raidID;
                   3476:        raidPtr->openings = RAIDOUTSTANDING;
                   3477:
                   3478:        /* 3. Build the configuration structure. */
                   3479:        rf_create_configuration(cset->ac, config, raidPtr);
                   3480:
                   3481:        /* 4. Do the configuration. */
                   3482:        retcode = rf_Configure(raidPtr, config, cset->ac);
                   3483:
                   3484:        if (retcode == 0) {
                   3485:
                   3486:                raidinit(raidPtrs[raidID]);
                   3487:
                   3488:                rf_markalldirty(raidPtrs[raidID]);
                   3489:                raidPtrs[raidID]->autoconfigure = 1; /* XXX Do this here ? */
                   3490:                if (cset->ac->clabel->root_partition==1) {
                   3491:                        /*
                   3492:                         * Everything configured just fine.  Make a note
                   3493:                         * that this set is eligible to be root.
                   3494:                         */
                   3495:                        cset->rootable = 1;
                   3496:                        /* XXX Do this here ? */
                   3497:                        raidPtrs[raidID]->root_partition = 1;
                   3498:                }
                   3499:        }
                   3500:
                   3501:        printf(": (%s) total number of sectors is %lu (%lu MB)%s\n",
                   3502:            (raidPtrs[raidID]->Layout).map->configName,
                   3503:            (unsigned long) raidPtrs[raidID]->totalSectors,
                   3504:            (unsigned long) (raidPtrs[raidID]->totalSectors / 1024 *
                   3505:            (1 << raidPtrs[raidID]->logBytesPerSector) / 1024),
                   3506:            raidPtrs[raidID]->root_partition ? " as root" : "");
                   3507:
                   3508:        /* 5. Cleanup. */
                   3509:        free(config, M_RAIDFRAME);
                   3510:
                   3511:        *unit = raidID;
                   3512:        return(retcode);
                   3513: }
                   3514:
                   3515: void
                   3516: rf_disk_unbusy(RF_RaidAccessDesc_t *desc)
                   3517: {
                   3518:        struct buf *bp;
                   3519:
                   3520:        bp = (struct buf *)desc->bp;
                   3521:        disk_unbusy(&raid_softc[desc->raidPtr->raidid].sc_dkdev,
                   3522:                            (bp->b_bcount - bp->b_resid),
                   3523:                            (bp->b_flags & B_READ));
                   3524: }

CVSweb