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