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