Home | History | Annotate | Line # | Download | only in raidframe
rf_driver.c revision 1.101
      1  1.101    itojun /*	$NetBSD: rf_driver.c,v 1.101 2004/04/22 00:17:12 itojun Exp $	*/
      2    1.9     oster /*-
      3    1.9     oster  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      4    1.9     oster  * All rights reserved.
      5    1.9     oster  *
      6    1.9     oster  * This code is derived from software contributed to The NetBSD Foundation
      7    1.9     oster  * by Greg Oster
      8    1.9     oster  *
      9    1.9     oster  * Redistribution and use in source and binary forms, with or without
     10    1.9     oster  * modification, are permitted provided that the following conditions
     11    1.9     oster  * are met:
     12    1.9     oster  * 1. Redistributions of source code must retain the above copyright
     13    1.9     oster  *    notice, this list of conditions and the following disclaimer.
     14    1.9     oster  * 2. Redistributions in binary form must reproduce the above copyright
     15    1.9     oster  *    notice, this list of conditions and the following disclaimer in the
     16    1.9     oster  *    documentation and/or other materials provided with the distribution.
     17    1.9     oster  * 3. All advertising materials mentioning features or use of this software
     18    1.9     oster  *    must display the following acknowledgement:
     19    1.9     oster  *        This product includes software developed by the NetBSD
     20    1.9     oster  *        Foundation, Inc. and its contributors.
     21    1.9     oster  * 4. Neither the name of The NetBSD Foundation nor the names of its
     22    1.9     oster  *    contributors may be used to endorse or promote products derived
     23    1.9     oster  *    from this software without specific prior written permission.
     24    1.9     oster  *
     25    1.9     oster  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     26    1.9     oster  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27    1.9     oster  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28    1.9     oster  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     29    1.9     oster  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30    1.9     oster  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31    1.9     oster  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32    1.9     oster  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33    1.9     oster  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34    1.9     oster  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35    1.9     oster  * POSSIBILITY OF SUCH DAMAGE.
     36    1.9     oster  */
     37    1.9     oster 
     38    1.1     oster /*
     39    1.1     oster  * Copyright (c) 1995 Carnegie-Mellon University.
     40    1.1     oster  * All rights reserved.
     41    1.1     oster  *
     42    1.1     oster  * Author: Mark Holland, Khalil Amiri, Claudson Bornstein, William V. Courtright II,
     43    1.1     oster  *         Robby Findler, Daniel Stodolsky, Rachad Youssef, Jim Zelenka
     44    1.1     oster  *
     45    1.1     oster  * Permission to use, copy, modify and distribute this software and
     46    1.1     oster  * its documentation is hereby granted, provided that both the copyright
     47    1.1     oster  * notice and this permission notice appear in all copies of the
     48    1.1     oster  * software, derivative works or modified versions, and any portions
     49    1.1     oster  * thereof, and that both notices appear in supporting documentation.
     50    1.1     oster  *
     51    1.1     oster  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     52    1.1     oster  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     53    1.1     oster  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     54    1.1     oster  *
     55    1.1     oster  * Carnegie Mellon requests users of this software to return to
     56    1.1     oster  *
     57    1.1     oster  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     58    1.1     oster  *  School of Computer Science
     59    1.1     oster  *  Carnegie Mellon University
     60    1.1     oster  *  Pittsburgh PA 15213-3890
     61    1.1     oster  *
     62    1.1     oster  * any improvements or extensions that they make and grant Carnegie the
     63    1.1     oster  * rights to redistribute these changes.
     64    1.1     oster  */
     65    1.1     oster 
     66    1.1     oster /******************************************************************************
     67    1.1     oster  *
     68    1.1     oster  * rf_driver.c -- main setup, teardown, and access routines for the RAID driver
     69    1.1     oster  *
     70    1.1     oster  * all routines are prefixed with rf_ (raidframe), to avoid conficts.
     71    1.1     oster  *
     72    1.1     oster  ******************************************************************************/
     73    1.1     oster 
     74   1.44     lukem 
     75   1.44     lukem #include <sys/cdefs.h>
     76  1.101    itojun __KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.101 2004/04/22 00:17:12 itojun Exp $");
     77   1.71    martin 
     78   1.71    martin #include "opt_raid_diagnostic.h"
     79    1.1     oster 
     80    1.1     oster #include <sys/param.h>
     81    1.1     oster #include <sys/systm.h>
     82    1.1     oster #include <sys/ioctl.h>
     83    1.1     oster #include <sys/fcntl.h>
     84    1.1     oster #include <sys/vnode.h>
     85    1.1     oster 
     86    1.1     oster 
     87    1.1     oster #include "rf_archs.h"
     88    1.1     oster #include "rf_threadstuff.h"
     89    1.1     oster 
     90    1.1     oster #include <sys/errno.h>
     91    1.1     oster 
     92    1.1     oster #include "rf_raid.h"
     93    1.1     oster #include "rf_dag.h"
     94    1.1     oster #include "rf_aselect.h"
     95    1.1     oster #include "rf_diskqueue.h"
     96    1.1     oster #include "rf_parityscan.h"
     97    1.1     oster #include "rf_alloclist.h"
     98    1.1     oster #include "rf_dagutils.h"
     99    1.1     oster #include "rf_utils.h"
    100    1.1     oster #include "rf_etimer.h"
    101    1.1     oster #include "rf_acctrace.h"
    102    1.1     oster #include "rf_general.h"
    103    1.1     oster #include "rf_desc.h"
    104    1.1     oster #include "rf_states.h"
    105    1.1     oster #include "rf_decluster.h"
    106    1.1     oster #include "rf_map.h"
    107    1.1     oster #include "rf_revent.h"
    108    1.1     oster #include "rf_callback.h"
    109    1.1     oster #include "rf_engine.h"
    110    1.1     oster #include "rf_mcpair.h"
    111    1.1     oster #include "rf_nwayxor.h"
    112    1.1     oster #include "rf_copyback.h"
    113    1.1     oster #include "rf_driver.h"
    114    1.1     oster #include "rf_options.h"
    115    1.1     oster #include "rf_shutdown.h"
    116   1.24     oster #include "rf_kintf.h"
    117    1.1     oster 
    118    1.1     oster #include <sys/buf.h>
    119    1.1     oster 
    120   1.61     oster #ifndef RF_ACCESS_DEBUG
    121   1.61     oster #define RF_ACCESS_DEBUG 0
    122   1.61     oster #endif
    123   1.61     oster 
    124    1.1     oster /* rad == RF_RaidAccessDesc_t */
    125   1.91     oster RF_DECLARE_MUTEX(rf_rad_lock)
    126    1.1     oster #define RF_MAX_FREE_RAD 128
    127   1.88     oster #define RF_MIN_FREE_RAD  32
    128    1.1     oster 
    129    1.1     oster /* debug variables */
    130    1.6     oster char    rf_panicbuf[2048];	/* a buffer to hold an error msg when we panic */
    131    1.1     oster 
    132    1.1     oster /* main configuration routines */
    133    1.1     oster static int raidframe_booted = 0;
    134    1.1     oster 
    135    1.6     oster static void rf_ConfigureDebug(RF_Config_t * cfgPtr);
    136    1.1     oster static void set_debug_option(char *name, long val);
    137    1.1     oster static void rf_UnconfigureArray(void);
    138    1.1     oster static void rf_ShutdownRDFreeList(void *);
    139    1.1     oster static int rf_ConfigureRDFreeList(RF_ShutdownList_t **);
    140    1.1     oster 
    141    1.6     oster RF_DECLARE_MUTEX(rf_printf_mutex)	/* debug only:  avoids interleaved
    142    1.6     oster 					 * printfs by different stripes */
    143    1.1     oster 
    144    1.1     oster #define SIGNAL_QUIESCENT_COND(_raid_)  wakeup(&((_raid_)->accesses_suspended))
    145    1.1     oster #define WAIT_FOR_QUIESCENCE(_raid_) \
    146   1.38     oster 	ltsleep(&((_raid_)->accesses_suspended), PRIBIO, \
    147   1.38     oster 		"raidframe quiesce", 0, &((_raid_)->access_suspend_mutex))
    148    1.1     oster 
    149    1.9     oster static int configureCount = 0;	/* number of active configurations */
    150    1.9     oster static int isconfigged = 0;	/* is basic raidframe (non per-array)
    151    1.9     oster 				 * stuff configged */
    152   1.55     oster RF_DECLARE_LKMGR_STATIC_MUTEX(configureMutex)	/* used to lock the configuration
    153    1.6     oster 					 * stuff */
    154    1.9     oster static RF_ShutdownList_t *globalShutdown;	/* non array-specific
    155    1.9     oster 						 * stuff */
    156    1.1     oster 
    157    1.9     oster static int rf_ConfigureRDFreeList(RF_ShutdownList_t ** listp);
    158    1.1     oster 
    159    1.1     oster /* called at system boot time */
    160    1.7     oster int
    161    1.7     oster rf_BootRaidframe()
    162    1.1     oster {
    163    1.1     oster 
    164    1.6     oster 	if (raidframe_booted)
    165    1.6     oster 		return (EBUSY);
    166    1.6     oster 	raidframe_booted = 1;
    167   1.79     oster 	lockinit(&configureMutex, PRIBIO, "RAIDframe lock", 0, 0);
    168   1.79     oster  	configureCount = 0;
    169    1.6     oster 	isconfigged = 0;
    170    1.6     oster 	globalShutdown = NULL;
    171    1.6     oster 	return (0);
    172    1.1     oster }
    173    1.1     oster 
    174    1.1     oster /*
    175    1.1     oster  * Called whenever an array is shutdown
    176    1.1     oster  */
    177    1.6     oster static void
    178    1.6     oster rf_UnconfigureArray()
    179    1.1     oster {
    180    1.1     oster 
    181   1.55     oster 	RF_LOCK_LKMGR_MUTEX(configureMutex);
    182    1.6     oster 	if (--configureCount == 0) {	/* if no active configurations, shut
    183    1.6     oster 					 * everything down */
    184    1.6     oster 		isconfigged = 0;
    185   1.92     oster 		rf_ShutdownList(&globalShutdown);
    186    1.6     oster 
    187    1.6     oster 		/*
    188    1.6     oster 	         * We must wait until now, because the AllocList module
    189    1.6     oster 	         * uses the DebugMem module.
    190    1.6     oster 	         */
    191   1.60     oster #if RF_DEBUG_MEM
    192    1.6     oster 		if (rf_memDebug)
    193    1.6     oster 			rf_print_unfreed();
    194   1.60     oster #endif
    195    1.6     oster 	}
    196   1.55     oster 	RF_UNLOCK_LKMGR_MUTEX(configureMutex);
    197    1.9     oster }
    198    1.9     oster 
    199    1.1     oster /*
    200    1.1     oster  * Called to shut down an array.
    201    1.1     oster  */
    202    1.6     oster int
    203   1.80     oster rf_Shutdown(RF_Raid_t *raidPtr)
    204    1.1     oster {
    205  1.100     oster 	RF_VoidPointerListElem_t *tmp;
    206  1.100     oster 
    207    1.6     oster 	if (!raidPtr->valid) {
    208    1.6     oster 		RF_ERRORMSG("Attempt to shut down unconfigured RAIDframe driver.  Aborting shutdown\n");
    209    1.6     oster 		return (EINVAL);
    210    1.6     oster 	}
    211    1.6     oster 	/*
    212    1.6     oster          * wait for outstanding IOs to land
    213    1.6     oster          * As described in rf_raid.h, we use the rad_freelist lock
    214    1.6     oster          * to protect the per-array info about outstanding descs
    215    1.6     oster          * since we need to do freelist locking anyway, and this
    216    1.6     oster          * cuts down on the amount of serialization we've got going
    217    1.6     oster          * on.
    218    1.6     oster          */
    219   1.91     oster 	RF_LOCK_MUTEX(rf_rad_lock);
    220    1.6     oster 	if (raidPtr->waitShutdown) {
    221   1.91     oster 		RF_UNLOCK_MUTEX(rf_rad_lock);
    222    1.6     oster 		return (EBUSY);
    223    1.6     oster 	}
    224    1.6     oster 	raidPtr->waitShutdown = 1;
    225    1.6     oster 	while (raidPtr->nAccOutstanding) {
    226   1.91     oster 		RF_WAIT_COND(raidPtr->outstandingCond, rf_rad_lock);
    227    1.6     oster 	}
    228   1.91     oster 	RF_UNLOCK_MUTEX(rf_rad_lock);
    229   1.35     oster 
    230   1.35     oster 	/* Wait for any parity re-writes to stop... */
    231   1.35     oster 	while (raidPtr->parity_rewrite_in_progress) {
    232   1.35     oster 		printf("Waiting for parity re-write to exit...\n");
    233   1.35     oster 		tsleep(&raidPtr->parity_rewrite_in_progress, PRIBIO,
    234   1.35     oster 		       "rfprwshutdown", 0);
    235   1.35     oster 	}
    236    1.6     oster 
    237    1.6     oster 	raidPtr->valid = 0;
    238    1.6     oster 
    239   1.37     oster 	rf_update_component_labels(raidPtr, RF_FINAL_COMPONENT_UPDATE);
    240    1.6     oster 
    241    1.7     oster 	rf_UnconfigureVnodes(raidPtr);
    242    1.7     oster 
    243  1.100     oster 	/* Free the emergency IO buffers */
    244  1.100     oster 	while (raidPtr->iobuf != NULL) {
    245  1.100     oster 		tmp = raidPtr->iobuf;
    246  1.100     oster 		raidPtr->iobuf = raidPtr->iobuf->next;
    247  1.100     oster 		free(tmp->p, M_RAIDFRAME);
    248  1.100     oster 		rf_FreeVPListElem(tmp);
    249  1.100     oster 	}
    250  1.100     oster 
    251  1.100     oster 	/* Free the emergency stripe buffers */
    252  1.100     oster 	while (raidPtr->stripebuf != NULL) {
    253  1.100     oster 		tmp = raidPtr->stripebuf;
    254  1.100     oster 		raidPtr->stripebuf = raidPtr->stripebuf->next;
    255  1.100     oster 		free(tmp->p, M_RAIDFRAME);
    256  1.100     oster 		rf_FreeVPListElem(tmp);
    257  1.100     oster 	}
    258  1.100     oster 
    259    1.7     oster 	rf_ShutdownList(&raidPtr->shutdownList);
    260    1.7     oster 
    261    1.7     oster 	rf_UnconfigureArray();
    262    1.7     oster 
    263    1.7     oster 	return (0);
    264    1.7     oster }
    265    1.1     oster 
    266    1.6     oster 
    267    1.1     oster #define DO_INIT_CONFIGURE(f) { \
    268    1.1     oster 	rc = f (&globalShutdown); \
    269    1.1     oster 	if (rc) { \
    270    1.1     oster 		RF_ERRORMSG2("RAIDFRAME: failed %s with %d\n", RF_STRING(f), rc); \
    271    1.1     oster 		rf_ShutdownList(&globalShutdown); \
    272    1.1     oster 		configureCount--; \
    273   1.55     oster 		RF_UNLOCK_LKMGR_MUTEX(configureMutex); \
    274    1.1     oster 		return(rc); \
    275    1.1     oster 	} \
    276    1.1     oster }
    277    1.1     oster 
    278    1.1     oster #define DO_RAID_FAIL() { \
    279   1.12     oster 	rf_UnconfigureVnodes(raidPtr); \
    280    1.1     oster 	rf_ShutdownList(&raidPtr->shutdownList); \
    281    1.1     oster 	rf_UnconfigureArray(); \
    282    1.1     oster }
    283    1.1     oster 
    284    1.1     oster #define DO_RAID_INIT_CONFIGURE(f) { \
    285    1.1     oster 	rc = f (&raidPtr->shutdownList, raidPtr, cfgPtr); \
    286    1.1     oster 	if (rc) { \
    287    1.1     oster 		RF_ERRORMSG2("RAIDFRAME: failed %s with %d\n", RF_STRING(f), rc); \
    288    1.1     oster 		DO_RAID_FAIL(); \
    289    1.1     oster 		return(rc); \
    290    1.1     oster 	} \
    291    1.1     oster }
    292    1.1     oster 
    293    1.1     oster #define DO_RAID_MUTEX(_m_) { \
    294   1.75     oster 	rf_mutex_init((_m_)); \
    295    1.1     oster }
    296    1.1     oster 
    297    1.6     oster int
    298   1.80     oster rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac)
    299    1.6     oster {
    300   1.72     oster 	RF_RowCol_t col;
    301   1.99     oster 	void *tmpbuf;
    302   1.99     oster 	RF_VoidPointerListElem_t *vple;
    303   1.97     oster 	int rc, i;
    304    1.6     oster 
    305   1.55     oster 	RF_LOCK_LKMGR_MUTEX(configureMutex);
    306    1.6     oster 	configureCount++;
    307    1.6     oster 	if (isconfigged == 0) {
    308   1.75     oster 		rf_mutex_init(&rf_printf_mutex);
    309   1.75     oster 
    310    1.6     oster 		/* initialize globals */
    311    1.6     oster 
    312    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureAllocList);
    313   1.28     oster 
    314    1.6     oster 		/*
    315   1.28     oster 	         * Yes, this does make debugging general to the whole
    316   1.28     oster 	         * system instead of being array specific. Bummer, drag.
    317   1.28     oster 		 */
    318    1.6     oster 		rf_ConfigureDebug(cfgPtr);
    319    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureDebugMem);
    320   1.87     oster #if RF_ACC_TRACE > 0
    321    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureAccessTrace);
    322   1.87     oster #endif
    323    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureMapModule);
    324    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureReconEvent);
    325    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureCallback);
    326    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureRDFreeList);
    327    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureNWayXor);
    328    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureStripeLockFreeList);
    329    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureMCPair);
    330    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureDAGs);
    331    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureDAGFuncs);
    332    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureReconstruction);
    333    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureCopyback);
    334    1.6     oster 		DO_INIT_CONFIGURE(rf_ConfigureDiskQueueSystem);
    335    1.6     oster 		isconfigged = 1;
    336    1.6     oster 	}
    337   1.55     oster 	RF_UNLOCK_LKMGR_MUTEX(configureMutex);
    338    1.6     oster 
    339    1.6     oster 	DO_RAID_MUTEX(&raidPtr->mutex);
    340    1.6     oster 	/* set up the cleanup list.  Do this after ConfigureDebug so that
    341    1.6     oster 	 * value of memDebug will be set */
    342    1.6     oster 
    343    1.6     oster 	rf_MakeAllocList(raidPtr->cleanupList);
    344    1.6     oster 	if (raidPtr->cleanupList == NULL) {
    345    1.6     oster 		DO_RAID_FAIL();
    346    1.6     oster 		return (ENOMEM);
    347    1.6     oster 	}
    348   1.86     oster 	rf_ShutdownCreate(&raidPtr->shutdownList,
    349   1.86     oster 			  (void (*) (void *)) rf_FreeAllocList,
    350   1.86     oster 			  raidPtr->cleanupList);
    351   1.86     oster 
    352    1.6     oster 	raidPtr->numCol = cfgPtr->numCol;
    353    1.6     oster 	raidPtr->numSpare = cfgPtr->numSpare;
    354    1.6     oster 
    355   1.72     oster 	raidPtr->status = rf_rs_optimal;
    356   1.72     oster 	raidPtr->reconControl = NULL;
    357   1.72     oster 
    358   1.64     oster 	TAILQ_INIT(&(raidPtr->iodone));
    359   1.64     oster 	simple_lock_init(&(raidPtr->iodone_lock));
    360    1.6     oster 
    361    1.6     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureEngine);
    362    1.6     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureStripeLocks);
    363    1.6     oster 
    364   1.76     oster 	raidPtr->outstandingCond = 0;
    365    1.6     oster 
    366    1.6     oster 	raidPtr->nAccOutstanding = 0;
    367    1.6     oster 	raidPtr->waitShutdown = 0;
    368    1.6     oster 
    369    1.6     oster 	DO_RAID_MUTEX(&raidPtr->access_suspend_mutex);
    370    1.6     oster 
    371   1.76     oster 	raidPtr->waitForReconCond = 0;
    372    1.6     oster 
    373   1.28     oster 	if (ac!=NULL) {
    374   1.28     oster 		/* We have an AutoConfig structure..  Don't do the
    375   1.28     oster 		   normal disk configuration... call the auto config
    376   1.28     oster 		   stuff */
    377   1.28     oster 		rf_AutoConfigureDisks(raidPtr, cfgPtr, ac);
    378   1.28     oster 	} else {
    379   1.28     oster 		DO_RAID_INIT_CONFIGURE(rf_ConfigureDisks);
    380   1.28     oster 		DO_RAID_INIT_CONFIGURE(rf_ConfigureSpareDisks);
    381   1.28     oster 	}
    382    1.6     oster 	/* do this after ConfigureDisks & ConfigureSpareDisks to be sure dev
    383    1.6     oster 	 * no. is set */
    384    1.6     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureDiskQueues);
    385    1.6     oster 
    386    1.6     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigureLayout);
    387    1.6     oster 
    388    1.6     oster 	DO_RAID_INIT_CONFIGURE(rf_ConfigurePSStatus);
    389    1.6     oster 
    390   1.82     oster #if RF_INCLUDE_CHAINDECLUSTER > 0
    391   1.72     oster 	for (col = 0; col < raidPtr->numCol; col++) {
    392   1.72     oster 		/*
    393   1.72     oster 		 * XXX better distribution
    394   1.72     oster 		 */
    395   1.72     oster 		raidPtr->hist_diskreq[col] = 0;
    396    1.6     oster 	}
    397   1.82     oster #endif
    398   1.30     oster 	raidPtr->numNewFailures = 0;
    399   1.28     oster 	raidPtr->copyback_in_progress = 0;
    400   1.28     oster 	raidPtr->parity_rewrite_in_progress = 0;
    401   1.66     oster 	raidPtr->adding_hot_spare = 0;
    402   1.28     oster 	raidPtr->recon_in_progress = 0;
    403   1.29     oster 	raidPtr->maxOutstanding = cfgPtr->maxOutstandingDiskReqs;
    404   1.29     oster 
    405   1.29     oster 	/* autoconfigure and root_partition will actually get filled in
    406   1.29     oster 	   after the config is done */
    407   1.29     oster 	raidPtr->autoconfigure = 0;
    408   1.29     oster 	raidPtr->root_partition = 0;
    409   1.29     oster 	raidPtr->last_unit = raidPtr->raidid;
    410   1.29     oster 	raidPtr->config_order = 0;
    411    1.6     oster 
    412    1.6     oster 	if (rf_keepAccTotals) {
    413    1.6     oster 		raidPtr->keep_acc_totals = 1;
    414    1.6     oster 	}
    415    1.1     oster 
    416   1.97     oster 	/* Allocate a bunch of buffers to be used in low-memory conditions */
    417   1.97     oster 	raidPtr->iobuf = NULL;
    418   1.97     oster 	/* XXX next line needs tuning... */
    419   1.97     oster 	raidPtr->numEmergencyBuffers = 10 * raidPtr->numCol;
    420   1.97     oster #if DEBUG
    421   1.97     oster 	printf("raid%d: allocating %d buffers of %d bytes.\n",
    422   1.97     oster 	       raidPtr->raidid,
    423   1.97     oster 	       raidPtr->numEmergencyBuffers,
    424   1.97     oster 	       (int)(raidPtr->Layout.sectorsPerStripeUnit <<
    425   1.97     oster 	       raidPtr->logBytesPerSector));
    426   1.97     oster #endif
    427   1.97     oster 	for (i = 0; i < raidPtr->numEmergencyBuffers; i++) {
    428   1.97     oster 		tmpbuf = malloc( raidPtr->Layout.sectorsPerStripeUnit <<
    429   1.97     oster 				 raidPtr->logBytesPerSector,
    430   1.97     oster 				 M_RAIDFRAME, M_NOWAIT);
    431   1.97     oster 		if (tmpbuf) {
    432   1.99     oster 			vple = rf_AllocVPListElem();
    433   1.99     oster 			vple->p= tmpbuf;
    434   1.99     oster 			vple->next = raidPtr->iobuf;
    435   1.99     oster 			raidPtr->iobuf = vple;
    436   1.97     oster 			raidPtr->iobuf_count++;
    437   1.97     oster 		} else {
    438   1.97     oster 			printf("raid%d: failed to allocate emergency buffer!\n",
    439   1.97     oster 			       raidPtr->raidid);
    440   1.97     oster 		}
    441   1.97     oster 	}
    442   1.97     oster 
    443   1.99     oster 	/* XXX next line needs tuning too... */
    444   1.99     oster 	raidPtr->numEmergencyStripeBuffers = 10;
    445   1.99     oster         for (i = 0; i < raidPtr->numEmergencyStripeBuffers; i++) {
    446   1.99     oster                 tmpbuf = malloc( raidPtr->numCol * (raidPtr->Layout.sectorsPerStripeUnit <<
    447   1.99     oster                                  raidPtr->logBytesPerSector),
    448   1.99     oster                                  M_RAIDFRAME, M_NOWAIT);
    449   1.99     oster                 if (tmpbuf) {
    450   1.99     oster                         vple = rf_AllocVPListElem();
    451   1.99     oster                         vple->p= tmpbuf;
    452   1.99     oster                         vple->next = raidPtr->stripebuf;
    453   1.99     oster                         raidPtr->stripebuf = vple;
    454   1.99     oster                         raidPtr->stripebuf_count++;
    455   1.99     oster                 } else {
    456   1.99     oster                         printf("raid%d: failed to allocate emergency stripe buffer!\n",
    457   1.99     oster                                raidPtr->raidid);
    458   1.99     oster                 }
    459   1.99     oster         }
    460   1.99     oster 
    461   1.99     oster 
    462    1.6     oster 	raidPtr->valid = 1;
    463   1.52     oster 
    464   1.52     oster 	printf("raid%d: %s\n", raidPtr->raidid,
    465   1.52     oster 	       raidPtr->Layout.map->configName);
    466   1.52     oster 	printf("raid%d: Components:", raidPtr->raidid);
    467   1.72     oster 
    468   1.72     oster 	for (col = 0; col < raidPtr->numCol; col++) {
    469   1.72     oster 		printf(" %s", raidPtr->Disks[col].devname);
    470   1.72     oster 		if (RF_DEAD_DISK(raidPtr->Disks[col].status)) {
    471   1.72     oster 			printf("[**FAILED**]");
    472   1.52     oster 		}
    473   1.52     oster 	}
    474   1.52     oster 	printf("\n");
    475   1.52     oster 	printf("raid%d: Total Sectors: %lu (%lu MB)\n",
    476   1.52     oster 	       raidPtr->raidid,
    477   1.52     oster 	       (unsigned long) raidPtr->totalSectors,
    478   1.52     oster 	       (unsigned long) (raidPtr->totalSectors / 1024 *
    479   1.52     oster 				(1 << raidPtr->logBytesPerSector) / 1024));
    480   1.50     oster 
    481    1.6     oster 	return (0);
    482    1.1     oster }
    483    1.1     oster 
    484    1.6     oster static void
    485   1.80     oster rf_ShutdownRDFreeList(void *ignored)
    486    1.1     oster {
    487   1.89     oster 	pool_destroy(&rf_pools.rad);
    488    1.1     oster }
    489    1.1     oster 
    490    1.6     oster static int
    491   1.80     oster rf_ConfigureRDFreeList(RF_ShutdownList_t **listp)
    492    1.1     oster {
    493    1.1     oster 
    494   1.89     oster 	rf_pool_init(&rf_pools.rad, sizeof(RF_RaidAccessDesc_t),
    495   1.89     oster 		     "rf_rad_pl", RF_MIN_FREE_RAD, RF_MAX_FREE_RAD);
    496   1.86     oster 	rf_ShutdownCreate(listp, rf_ShutdownRDFreeList, NULL);
    497   1.91     oster 	simple_lock_init(&rf_rad_lock);
    498    1.6     oster 	return (0);
    499    1.6     oster }
    500    1.6     oster 
    501    1.6     oster RF_RaidAccessDesc_t *
    502   1.80     oster rf_AllocRaidAccDesc(RF_Raid_t *raidPtr, RF_IoType_t type,
    503   1.80     oster 		    RF_RaidAddr_t raidAddress, RF_SectorCount_t numBlocks,
    504   1.80     oster 		    caddr_t bufPtr, void *bp, RF_RaidAccessFlags_t flags,
    505   1.80     oster 		    RF_AccessState_t *states)
    506    1.6     oster {
    507    1.6     oster 	RF_RaidAccessDesc_t *desc;
    508    1.6     oster 
    509   1.89     oster 	desc = pool_get(&rf_pools.rad, PR_WAITOK);
    510   1.73     oster 
    511   1.91     oster 	RF_LOCK_MUTEX(rf_rad_lock);
    512    1.6     oster 	if (raidPtr->waitShutdown) {
    513    1.6     oster 		/*
    514    1.6     oster 	         * Actually, we're shutting the array down. Free the desc
    515    1.6     oster 	         * and return NULL.
    516    1.6     oster 	         */
    517   1.73     oster 
    518   1.91     oster 		RF_UNLOCK_MUTEX(rf_rad_lock);
    519   1.89     oster 		pool_put(&rf_pools.rad, desc);
    520    1.6     oster 		return (NULL);
    521    1.6     oster 	}
    522    1.6     oster 	raidPtr->nAccOutstanding++;
    523   1.73     oster 
    524   1.91     oster 	RF_UNLOCK_MUTEX(rf_rad_lock);
    525    1.6     oster 
    526    1.6     oster 	desc->raidPtr = (void *) raidPtr;
    527    1.6     oster 	desc->type = type;
    528    1.6     oster 	desc->raidAddress = raidAddress;
    529    1.6     oster 	desc->numBlocks = numBlocks;
    530    1.6     oster 	desc->bufPtr = bufPtr;
    531    1.6     oster 	desc->bp = bp;
    532    1.6     oster 	desc->flags = flags;
    533    1.6     oster 	desc->states = states;
    534    1.6     oster 	desc->state = 0;
    535   1.99     oster 	desc->dagList = NULL;
    536    1.6     oster 
    537    1.6     oster 	desc->status = 0;
    538   1.87     oster #if RF_ACC_TRACE > 0
    539   1.40   thorpej 	memset((char *) &desc->tracerec, 0, sizeof(RF_AccTraceEntry_t));
    540   1.87     oster #endif
    541   1.41     oster 	desc->callbackFunc = NULL;
    542   1.41     oster 	desc->callbackArg = NULL;
    543    1.6     oster 	desc->next = NULL;
    544   1.99     oster 	desc->iobufs = NULL;
    545   1.99     oster 	desc->stripebufs = NULL;
    546   1.99     oster 
    547    1.6     oster 	return (desc);
    548    1.6     oster }
    549    1.6     oster 
    550    1.6     oster void
    551   1.80     oster rf_FreeRaidAccDesc(RF_RaidAccessDesc_t *desc)
    552    1.6     oster {
    553    1.6     oster 	RF_Raid_t *raidPtr = desc->raidPtr;
    554   1.85     oster 	RF_DagList_t *dagList, *temp;
    555   1.99     oster 	RF_VoidPointerListElem_t *tmp;
    556    1.6     oster 
    557    1.6     oster 	RF_ASSERT(desc);
    558    1.6     oster 
    559   1.85     oster 	/* Cleanup the dagList(s) */
    560   1.85     oster 	dagList = desc->dagList;
    561   1.85     oster 	while(dagList != NULL) {
    562   1.85     oster 		temp = dagList;
    563   1.85     oster 		dagList = dagList->next;
    564   1.85     oster 		rf_FreeDAGList(temp);
    565   1.85     oster 	}
    566   1.85     oster 
    567   1.99     oster 	while (desc->iobufs) {
    568   1.99     oster 		tmp = desc->iobufs;
    569   1.99     oster 		desc->iobufs = desc->iobufs->next;
    570   1.99     oster 		rf_FreeIOBuffer(raidPtr, tmp);
    571   1.99     oster 	}
    572   1.99     oster 
    573   1.99     oster 	while (desc->stripebufs) {
    574   1.99     oster 		tmp = desc->stripebufs;
    575   1.99     oster 		desc->stripebufs = desc->stripebufs->next;
    576   1.99     oster 		rf_FreeStripeBuffer(raidPtr, tmp);
    577   1.99     oster 	}
    578   1.99     oster 
    579   1.89     oster 	pool_put(&rf_pools.rad, desc);
    580   1.91     oster 	RF_LOCK_MUTEX(rf_rad_lock);
    581    1.6     oster 	raidPtr->nAccOutstanding--;
    582    1.6     oster 	if (raidPtr->waitShutdown) {
    583    1.6     oster 		RF_SIGNAL_COND(raidPtr->outstandingCond);
    584    1.6     oster 	}
    585   1.91     oster 	RF_UNLOCK_MUTEX(rf_rad_lock);
    586    1.1     oster }
    587    1.1     oster /*********************************************************************
    588    1.1     oster  * Main routine for performing an access.
    589    1.1     oster  * Accesses are retried until a DAG can not be selected.  This occurs
    590    1.1     oster  * when either the DAG library is incomplete or there are too many
    591    1.1     oster  * failures in a parity group.
    592   1.80     oster  *
    593   1.80     oster  * type should be read or write async_flag should be RF_TRUE or
    594   1.80     oster  * RF_FALSE bp_in is a buf pointer.  void * to facilitate ignoring it
    595   1.80     oster  * outside the kernel
    596    1.1     oster  ********************************************************************/
    597    1.6     oster int
    598   1.80     oster rf_DoAccess(RF_Raid_t * raidPtr, RF_IoType_t type, int async_flag,
    599   1.80     oster 	    RF_RaidAddr_t raidAddress, RF_SectorCount_t numBlocks,
    600   1.80     oster 	    caddr_t bufPtr, void *bp_in, RF_RaidAccessFlags_t flags)
    601    1.1     oster {
    602    1.6     oster 	RF_RaidAccessDesc_t *desc;
    603    1.6     oster 	caddr_t lbufPtr = bufPtr;
    604    1.6     oster 	struct buf *bp = (struct buf *) bp_in;
    605    1.6     oster 
    606    1.6     oster 	raidAddress += rf_raidSectorOffset;
    607    1.6     oster 
    608   1.61     oster #if RF_ACCESS_DEBUG
    609    1.6     oster 	if (rf_accessDebug) {
    610    1.1     oster 
    611    1.6     oster 		printf("logBytes is: %d %d %d\n", raidPtr->raidid,
    612    1.6     oster 		    raidPtr->logBytesPerSector,
    613    1.6     oster 		    (int) rf_RaidAddressToByte(raidPtr, numBlocks));
    614   1.22     oster 		printf("raid%d: %s raidAddr %d (stripeid %d-%d) numBlocks %d (%d bytes) buf 0x%lx\n", raidPtr->raidid,
    615    1.6     oster 		    (type == RF_IO_TYPE_READ) ? "READ" : "WRITE", (int) raidAddress,
    616    1.6     oster 		    (int) rf_RaidAddressToStripeID(&raidPtr->Layout, raidAddress),
    617    1.6     oster 		    (int) rf_RaidAddressToStripeID(&raidPtr->Layout, raidAddress + numBlocks - 1),
    618    1.6     oster 		    (int) numBlocks,
    619    1.6     oster 		    (int) rf_RaidAddressToByte(raidPtr, numBlocks),
    620    1.6     oster 		    (long) bufPtr);
    621    1.6     oster 	}
    622   1.61     oster #endif
    623    1.6     oster 	if (raidAddress + numBlocks > raidPtr->totalSectors) {
    624    1.1     oster 
    625    1.6     oster 		printf("DoAccess: raid addr %lu too large to access %lu sectors.  Max legal addr is %lu\n",
    626    1.6     oster 		    (u_long) raidAddress, (u_long) numBlocks, (u_long) raidPtr->totalSectors);
    627    1.1     oster 
    628   1.77     oster 
    629   1.77     oster 		bp->b_flags |= B_ERROR;
    630   1.77     oster 		bp->b_resid = bp->b_bcount;
    631   1.77     oster 		bp->b_error = ENOSPC;
    632   1.77     oster 		biodone(bp);
    633   1.16     oster 		return (ENOSPC);
    634    1.6     oster 	}
    635    1.6     oster 	desc = rf_AllocRaidAccDesc(raidPtr, type, raidAddress,
    636   1.41     oster 	    numBlocks, lbufPtr, bp, flags, raidPtr->Layout.map->states);
    637    1.1     oster 
    638    1.6     oster 	if (desc == NULL) {
    639    1.6     oster 		return (ENOMEM);
    640    1.6     oster 	}
    641   1.87     oster #if RF_ACC_TRACE > 0
    642    1.6     oster 	RF_ETIMER_START(desc->tracerec.tot_timer);
    643   1.87     oster #endif
    644    1.6     oster 	desc->async_flag = async_flag;
    645    1.3  explorer 
    646    1.6     oster 	rf_ContinueRaidAccess(desc);
    647    1.1     oster 
    648    1.6     oster 	return (0);
    649    1.1     oster }
    650   1.46     oster #if 0
    651    1.1     oster /* force the array into reconfigured mode without doing reconstruction */
    652    1.6     oster int
    653   1.80     oster rf_SetReconfiguredMode(RF_Raid_t *raidPtr, int col)
    654    1.6     oster {
    655    1.6     oster 	if (!(raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
    656    1.6     oster 		printf("Can't set reconfigured mode in dedicated-spare array\n");
    657    1.6     oster 		RF_PANIC();
    658    1.6     oster 	}
    659    1.6     oster 	RF_LOCK_MUTEX(raidPtr->mutex);
    660    1.6     oster 	raidPtr->numFailures++;
    661   1.72     oster 	raidPtr->Disks[col].status = rf_ds_dist_spared;
    662   1.72     oster 	raidPtr->status = rf_rs_reconfigured;
    663   1.37     oster 	rf_update_component_labels(raidPtr, RF_NORMAL_COMPONENT_UPDATE);
    664    1.6     oster 	/* install spare table only if declustering + distributed sparing
    665    1.6     oster 	 * architecture. */
    666    1.6     oster 	if (raidPtr->Layout.map->flags & RF_BD_DECLUSTERED)
    667   1.72     oster 		rf_InstallSpareTable(raidPtr, col);
    668    1.6     oster 	RF_UNLOCK_MUTEX(raidPtr->mutex);
    669    1.6     oster 	return (0);
    670    1.1     oster }
    671   1.46     oster #endif
    672    1.1     oster 
    673    1.6     oster int
    674   1.80     oster rf_FailDisk(RF_Raid_t *raidPtr, int fcol, int initRecon)
    675    1.6     oster {
    676   1.98     oster 
    677   1.98     oster 	/* need to suspend IO's here -- if there are DAGs in flight
    678   1.98     oster 	   and we pull the rug out from under ci_vp, Bad Things
    679   1.98     oster 	   can happen.  */
    680   1.98     oster 
    681   1.98     oster 	rf_SuspendNewRequestsAndWait(raidPtr);
    682   1.98     oster 
    683    1.6     oster 	RF_LOCK_MUTEX(raidPtr->mutex);
    684   1.72     oster 	if (raidPtr->Disks[fcol].status != rf_ds_failed) {
    685   1.68     oster 		/* must be failing something that is valid, or else it's
    686   1.68     oster 		   already marked as failed (in which case we don't
    687   1.68     oster 		   want to mark it failed again!) */
    688   1.68     oster 		raidPtr->numFailures++;
    689   1.72     oster 		raidPtr->Disks[fcol].status = rf_ds_failed;
    690   1.72     oster 		raidPtr->status = rf_rs_degraded;
    691   1.68     oster 	}
    692   1.65     oster 	RF_UNLOCK_MUTEX(raidPtr->mutex);
    693   1.68     oster 
    694   1.37     oster 	rf_update_component_labels(raidPtr, RF_NORMAL_COMPONENT_UPDATE);
    695   1.68     oster 
    696   1.56     oster 	/* Close the component, so that it's not "locked" if someone
    697   1.56     oster 	   else want's to use it! */
    698   1.56     oster 
    699   1.72     oster 	rf_close_component(raidPtr, raidPtr->raid_cinfo[fcol].ci_vp,
    700   1.72     oster 			   raidPtr->Disks[fcol].auto_configured);
    701   1.65     oster 
    702   1.65     oster 	RF_LOCK_MUTEX(raidPtr->mutex);
    703   1.72     oster 	raidPtr->raid_cinfo[fcol].ci_vp = NULL;
    704   1.56     oster 
    705   1.56     oster 	/* Need to mark the component as not being auto_configured
    706   1.56     oster 	   (in case it was previously). */
    707   1.56     oster 
    708   1.72     oster 	raidPtr->Disks[fcol].auto_configured = 0;
    709   1.65     oster 	RF_UNLOCK_MUTEX(raidPtr->mutex);
    710   1.98     oster 	/* now we can allow IO to continue -- we'll be suspending it
    711   1.98     oster 	   again in rf_ReconstructFailedDisk() if we have to.. */
    712   1.98     oster 
    713   1.98     oster 	rf_ResumeNewRequests(raidPtr);
    714   1.56     oster 
    715    1.6     oster 	if (initRecon)
    716   1.72     oster 		rf_ReconstructFailedDisk(raidPtr, fcol);
    717    1.6     oster 	return (0);
    718    1.1     oster }
    719    1.1     oster /* releases a thread that is waiting for the array to become quiesced.
    720    1.1     oster  * access_suspend_mutex should be locked upon calling this
    721    1.1     oster  */
    722    1.6     oster void
    723   1.80     oster rf_SignalQuiescenceLock(RF_Raid_t *raidPtr)
    724    1.6     oster {
    725   1.61     oster #if RF_DEBUG_QUIESCE
    726    1.6     oster 	if (rf_quiesceDebug) {
    727   1.22     oster 		printf("raid%d: Signalling quiescence lock\n",
    728   1.22     oster 		       raidPtr->raidid);
    729    1.6     oster 	}
    730   1.61     oster #endif
    731    1.6     oster 	raidPtr->access_suspend_release = 1;
    732    1.6     oster 
    733    1.6     oster 	if (raidPtr->waiting_for_quiescence) {
    734    1.6     oster 		SIGNAL_QUIESCENT_COND(raidPtr);
    735    1.6     oster 	}
    736    1.1     oster }
    737    1.1     oster /* suspends all new requests to the array.  No effect on accesses that are in flight.  */
    738    1.6     oster int
    739   1.80     oster rf_SuspendNewRequestsAndWait(RF_Raid_t *raidPtr)
    740    1.6     oster {
    741   1.61     oster #if RF_DEBUG_QUIESCE
    742    1.6     oster 	if (rf_quiesceDebug)
    743   1.53     oster 		printf("raid%d: Suspending new reqs\n", raidPtr->raidid);
    744   1.61     oster #endif
    745    1.6     oster 	RF_LOCK_MUTEX(raidPtr->access_suspend_mutex);
    746    1.6     oster 	raidPtr->accesses_suspended++;
    747    1.6     oster 	raidPtr->waiting_for_quiescence = (raidPtr->accs_in_flight == 0) ? 0 : 1;
    748    1.6     oster 
    749    1.6     oster 	if (raidPtr->waiting_for_quiescence) {
    750    1.6     oster 		raidPtr->access_suspend_release = 0;
    751    1.6     oster 		while (!raidPtr->access_suspend_release) {
    752   1.93     oster #if RF_DEBUG_QUIESCE
    753   1.53     oster 			printf("raid%d: Suspending: Waiting for Quiescence\n",
    754   1.53     oster 			       raidPtr->raidid);
    755   1.93     oster #endif
    756    1.6     oster 			WAIT_FOR_QUIESCENCE(raidPtr);
    757    1.6     oster 			raidPtr->waiting_for_quiescence = 0;
    758    1.6     oster 		}
    759    1.6     oster 	}
    760   1.93     oster #if RF_DEBUG_QUIESCE
    761   1.53     oster 	printf("raid%d: Quiescence reached..\n", raidPtr->raidid);
    762   1.93     oster #endif
    763    1.1     oster 
    764    1.6     oster 	RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);
    765    1.6     oster 	return (raidPtr->waiting_for_quiescence);
    766    1.1     oster }
    767    1.1     oster /* wake up everyone waiting for quiescence to be released */
    768    1.6     oster void
    769   1.80     oster rf_ResumeNewRequests(RF_Raid_t *raidPtr)
    770    1.6     oster {
    771    1.6     oster 	RF_CallbackDesc_t *t, *cb;
    772    1.6     oster 
    773   1.61     oster #if RF_DEBUG_QUIESCE
    774    1.6     oster 	if (rf_quiesceDebug)
    775    1.6     oster 		printf("Resuming new reqs\n");
    776   1.61     oster #endif
    777    1.6     oster 
    778    1.6     oster 	RF_LOCK_MUTEX(raidPtr->access_suspend_mutex);
    779    1.6     oster 	raidPtr->accesses_suspended--;
    780    1.6     oster 	if (raidPtr->accesses_suspended == 0)
    781    1.6     oster 		cb = raidPtr->quiesce_wait_list;
    782    1.6     oster 	else
    783    1.6     oster 		cb = NULL;
    784    1.6     oster 	raidPtr->quiesce_wait_list = NULL;
    785    1.6     oster 	RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);
    786    1.6     oster 
    787    1.6     oster 	while (cb) {
    788    1.6     oster 		t = cb;
    789    1.6     oster 		cb = cb->next;
    790    1.6     oster 		(t->callbackFunc) (t->callbackArg);
    791    1.6     oster 		rf_FreeCallbackDesc(t);
    792    1.6     oster 	}
    793    1.1     oster }
    794    1.1     oster /*****************************************************************************************
    795    1.1     oster  *
    796    1.1     oster  * debug routines
    797    1.1     oster  *
    798    1.1     oster  ****************************************************************************************/
    799    1.1     oster 
    800    1.6     oster static void
    801   1.80     oster set_debug_option(char *name, long val)
    802    1.6     oster {
    803    1.6     oster 	RF_DebugName_t *p;
    804    1.6     oster 
    805    1.6     oster 	for (p = rf_debugNames; p->name; p++) {
    806    1.6     oster 		if (!strcmp(p->name, name)) {
    807    1.6     oster 			*(p->ptr) = val;
    808    1.6     oster 			printf("[Set debug variable %s to %ld]\n", name, val);
    809    1.6     oster 			return;
    810    1.6     oster 		}
    811    1.6     oster 	}
    812    1.6     oster 	RF_ERRORMSG1("Unknown debug string \"%s\"\n", name);
    813    1.1     oster }
    814    1.1     oster 
    815    1.1     oster 
    816    1.1     oster /* would like to use sscanf here, but apparently not available in kernel */
    817    1.1     oster /*ARGSUSED*/
    818    1.6     oster static void
    819   1.80     oster rf_ConfigureDebug(RF_Config_t *cfgPtr)
    820    1.6     oster {
    821    1.6     oster 	char   *val_p, *name_p, *white_p;
    822    1.6     oster 	long    val;
    823    1.6     oster 	int     i;
    824    1.6     oster 
    825    1.6     oster 	rf_ResetDebugOptions();
    826    1.6     oster 	for (i = 0; cfgPtr->debugVars[i][0] && i < RF_MAXDBGV; i++) {
    827    1.6     oster 		name_p = rf_find_non_white(&cfgPtr->debugVars[i][0]);
    828    1.6     oster 		white_p = rf_find_white(name_p);	/* skip to start of 2nd
    829    1.6     oster 							 * word */
    830    1.6     oster 		val_p = rf_find_non_white(white_p);
    831    1.6     oster 		if (*val_p == '0' && *(val_p + 1) == 'x')
    832    1.6     oster 			val = rf_htoi(val_p + 2);
    833    1.6     oster 		else
    834    1.6     oster 			val = rf_atoi(val_p);
    835    1.6     oster 		*white_p = '\0';
    836    1.6     oster 		set_debug_option(name_p, val);
    837    1.6     oster 	}
    838    1.1     oster }
    839   1.39     oster 
    840   1.39     oster void
    841   1.80     oster rf_print_panic_message(int line, char *file)
    842   1.39     oster {
    843  1.101    itojun 	snprintf(rf_panicbuf, sizeof(rf_panicbuf),
    844  1.101    itojun 	    "raidframe error at line %d file %s", line, file);
    845   1.39     oster }
    846   1.39     oster 
    847   1.62     oster #ifdef RAID_DIAGNOSTIC
    848   1.39     oster void
    849   1.80     oster rf_print_assert_panic_message(int line,	char *file, char *condition)
    850   1.39     oster {
    851  1.101    itojun 	snprintf(rf_panicbuf, sizeof(rf_panicbuf),
    852   1.39     oster 		"raidframe error at line %d file %s (failed asserting %s)\n",
    853   1.39     oster 		line, file, condition);
    854   1.58     oster }
    855   1.62     oster #endif
    856   1.58     oster 
    857   1.58     oster void
    858   1.80     oster rf_print_unable_to_init_mutex(char *file, int line, int rc)
    859   1.58     oster {
    860   1.58     oster 	RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d\n",
    861   1.58     oster 		     file, line, rc);
    862   1.58     oster }
    863   1.58     oster 
    864   1.58     oster void
    865   1.80     oster rf_print_unable_to_add_shutdown(char *file, int line, int rc)
    866   1.58     oster {
    867   1.58     oster 	RF_ERRORMSG3("Unable to add to shutdown list file %s line %d rc=%d\n",
    868   1.58     oster 		     file, line, rc);
    869    1.1     oster }
    870