⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 autoconf.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1988 University of Utah. * Copyright (c) 1982, 1986, 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: Utah $Hdr: autoconf.c 1.36 92/12/20$ * *	@(#)autoconf.c	8.2 (Berkeley) 1/12/94 *//* * Setup the system to run on the current machine. * * Configure() is called at boot time.  Available * devices are determined (from possibilities mentioned in ioconf.c), * and the drivers are initialized. */#include <sys/param.h>#include <sys/systm.h>#include <sys/map.h>#include <sys/buf.h>#include <sys/dkstat.h>#include <sys/conf.h>#include <sys/dmap.h>#include <sys/reboot.h>#include <machine/vmparam.h>#include <machine/cpu.h>#include <hp300/hp300/pte.h>#include <hp300/hp300/isr.h>#include <hp/dev/device.h>#include <hp/dev/grfreg.h>#include <hp/dev/hilreg.h>/* * The following several variables are related to * the configuration process, and are used in initializing * the machine. */int	cold;		    /* if 1, still working on cold-start */int	dkn;		    /* number of iostat dk numbers assigned so far */int	cpuspeed = 0;	    /* relative cpu speed -- can be patched */	struct	isr isrqueue[NISR];struct	hp_hw sc_table[MAXCTLRS];/* XXX must be allocated statically because of early console init */struct	map extiomap[EIOMAPSIZE/16];extern	caddr_t internalhpib;extern	char *extiobase;#ifdef DEBUGint	acdebug = 0;#endif/* * Determine mass storage and memory configuration for a machine. */configure(){	register struct hp_hw *hw;	int found;	/*	 * XXX: these should be consolidated into some kind of table	 */	hilsoftinit(0, HILADDR);	hilinit(0, HILADDR);	isrinit();	dmainit();	/*	 * Look over each hardware device actually found and attempt	 * to match it with an ioconf.c table entry.	 */	for (hw = sc_table; hw->hw_type; hw++) {		if (HW_ISCTLR(hw))			found = find_controller(hw);		else			found = find_device(hw);#ifdef DEBUG		if (!found) {			int sc = patosc(hw->hw_pa);			printf("unconfigured card id %x ", hw->hw_id);			if (sc < 256)				printf("at sc%d\n", sc);			else				printf("csr at %x\n", sc);		}#endif	}#if GENERIC	if ((boothowto & RB_ASKNAME) == 0)		setroot();	setconf();#else	setroot();#endif	swapconf();	cold = 0;}#define dr_type(d, s)	\	(strcmp((d)->d_name, (s)) == 0)#define same_hw_ctlr(hw, hc) \	(HW_ISHPIB(hw) && dr_type((hc)->hp_driver, "hpib") || \	 HW_ISSCSI(hw) && dr_type((hc)->hp_driver, "scsi"))find_controller(hw)	register struct hp_hw *hw;{	register struct hp_ctlr *hc;	struct hp_ctlr *match_c;	caddr_t oaddr;	int sc;#ifdef DEBUG	if (acdebug)		printf("find_controller: hw: id%x at sc%d (%x), type %x...",		       hw->hw_id, hw->hw_sc, hw->hw_kva, hw->hw_type);#endif	sc = hw->hw_sc;	match_c = NULL;	for (hc = hp_cinit; hc->hp_driver; hc++) {		if (hc->hp_alive)			continue;		/*		 * Make sure we are looking at the right		 * controller type.		 */		if (!same_hw_ctlr(hw, hc))			continue;		/*		 * Exact match; all done		 */		if ((int)hc->hp_addr == sc) {			match_c = hc;			break;		}		/*		 * Wildcard; possible match so remember first instance		 * but continue looking for exact match.		 */		if (hc->hp_addr == NULL && match_c == NULL)			match_c = hc;	}#ifdef DEBUG	if (acdebug) {		if (match_c)			printf("found %s%d\n",			       match_c->hp_driver->d_name,			       match_c->hp_unit);		else			printf("not found\n");	}#endif	/*	 * Didn't find an ioconf entry for this piece of hardware,	 * just ignore it.	 */	if (match_c == NULL)		return(0);	/*	 * Found a match, attempt to initialize and configure all attached	 * slaves.  Note, we can still fail if HW won't initialize.	 */	hc = match_c;	oaddr = hc->hp_addr;	hc->hp_addr = hw->hw_kva;	if ((*hc->hp_driver->d_init)(hc)) {		hc->hp_alive = 1;		printf("%s%d", hc->hp_driver->d_name, hc->hp_unit);		sc = patosc(hw->hw_pa);		if (sc < 256)			printf(" at sc%d,", sc);		else			printf(" csr 0x%x,", sc);		printf(" ipl %d", hc->hp_ipl);		if (hc->hp_flags)			printf(" flags 0x%x", hc->hp_flags);		printf("\n");		find_slaves(hc);	} else		hc->hp_addr = oaddr;	return(1);}find_device(hw)	register struct hp_hw *hw;{	register struct hp_device *hd;	struct hp_device *match_d;	caddr_t oaddr;	int sc;#ifdef DEBUG	if (acdebug)		printf("find_device: hw: id%x at sc%d (%x), type %x...",		       hw->hw_id, hw->hw_sc, hw->hw_kva, hw->hw_type);#endif	match_d = NULL;	for (hd = hp_dinit; hd->hp_driver; hd++) {		if (hd->hp_alive)			continue;		/* Must not be a slave */		if (hd->hp_cdriver)			continue;		/*		 * XXX: A graphics device that was found as part of the		 * console init will have the hp_addr field already set		 * (i.e. no longer the select code).  Gotta perform a		 * slightly different check for an exact match.		 */		if (HW_ISDEV(hw, D_BITMAP) && hd->hp_addr >= intiobase) {			/* must be an exact match */			if (hd->hp_addr == hw->hw_kva) {				match_d = hd;				break;			}			continue;		}		sc = (int) hd->hp_addr;		/*		 * Exact match; all done.		 */		if (sc > 0 && sc == hw->hw_sc) {			match_d = hd;			break;		}		/*		 * Wildcard; possible match so remember first instance		 * but continue looking for exact match.		 */		if (sc == 0 && same_hw_device(hw, hd) && match_d == NULL)			match_d = hd;	}#ifdef DEBUG	if (acdebug) {		if (match_d)			printf("found %s%d\n",			       match_d->hp_driver->d_name,			       match_d->hp_unit);		else			printf("not found\n");	}#endif	/*	 * Didn't find an ioconf entry for this piece	 * of hardware, just ignore it.	 */	if (match_d == NULL)		return(0);	/*	 * Found a match, attempt to initialize.	 * Note, we can still fail if HW won't initialize.	 */	hd = match_d;	oaddr = hd->hp_addr;	hd->hp_addr = hw->hw_kva;	if ((*hd->hp_driver->d_init)(hd)) {		hd->hp_alive = 1;		printf("%s%d", hd->hp_driver->d_name, hd->hp_unit);		sc = patosc(hw->hw_pa);		if (sc < 256)			printf(" at sc%d", sc);		else			printf(" csr 0x%x", sc);		if (hd->hp_ipl)			printf(", ipl %d", hd->hp_ipl);		if (hd->hp_flags)			printf(", flags 0x%x", hd->hp_flags);		printf("\n");	} else		hd->hp_addr = oaddr;	return(1);}find_slaves(hc)	struct hp_ctlr *hc;{	/*	 * The SCSI bus is structured very much like the HP-IB 	 * except that the host adaptor is slave 7 so we only want	 * to look at the first 6 slaves.	 */	if (dr_type(hc->hp_driver, "hpib"))		find_busslaves(hc, 0, MAXSLAVES-1);	else if (dr_type(hc->hp_driver, "scsi"))#ifdef SCSI_REVPRI		/*		 * Later releases of the HP boot ROM start searching for		 * boot devices starting with slave 6 and working down.		 * This is apparently the order in which priority is given		 * to slaves on the host adaptor.		 */		find_busslaves(hc, MAXSLAVES-2, 0);#else		find_busslaves(hc, 0, MAXSLAVES-2);#endif}/* * Search each BUS controller found for slaves attached to it. * The bad news is that we don't know how to uniquely identify all slaves * (e.g. PPI devices on HP-IB).  The good news is that we can at least * differentiate those from slaves we can identify.  At worst (a totally * wildcarded entry) this will cause us to locate such a slave at the first * unused position instead of where it really is.  To save grief, non- * identifing devices should always be fully qualified. */find_busslaves(hc, startslave, endslave)	register struct hp_ctlr *hc;	int startslave, endslave;{	register int s;	register struct hp_device *hd;	struct hp_device *match_s;	int new_s, new_c, old_s, old_c;	int rescan;	#define NEXTSLAVE(s) (startslave < endslave ? (s)++ : (s)--)#define LASTSLAVE(s) (startslave < endslave ? (s)-- : (s)++)#ifdef DEBUG	if (acdebug)		printf("find_busslaves: for %s%d\n",		       hc->hp_driver->d_name, hc->hp_unit);#endif	NEXTSLAVE(endslave);	for (s = startslave; s != endslave; NEXTSLAVE(s)) {		rescan = 1;		match_s = NULL;		for (hd = hp_dinit; hd->hp_driver; hd++) {			/*			 * Rule out the easy ones:			 * 1. slave already assigned or not a slave			 * 2. not of the proper type			 * 3. controller specified but not this one			 * 4. slave specified but not this one			 */			if (hd->hp_alive || hd->hp_cdriver == NULL)				continue;			if (!dr_type(hc->hp_driver, hd->hp_cdriver->d_name))				continue;			if (hd->hp_ctlr >= 0 && hd->hp_ctlr != hc->hp_unit)				continue;			if (hd->hp_slave >= 0 && hd->hp_slave != s)				continue;			/*			 * Case 0: first possible match.			 * Remember it and keep looking for better.			 */			if (match_s == NULL) {				match_s = hd;				new_c = hc->hp_unit;				new_s = s;				continue;			}			/*			 * Case 1: exact match.			 * All done.  Note that we do not attempt any other			 * matches if this one fails.  This allows us to			 * "reserve" locations for dynamic addition of			 * disk/tape drives by fully qualifing the location.			 */			if (hd->hp_slave == s && hd->hp_ctlr == hc->hp_unit) {				match_s = hd;				rescan = 0;				break;			}			/*			 * Case 2: right controller, wildcarded slave.			 * Remember first and keep looking for an exact match.			 */			if (hd->hp_ctlr == hc->hp_unit &&			    match_s->hp_ctlr < 0) {				match_s = hd;				new_s = s;				continue;			}			/*			 * Case 3: right slave, wildcarded controller.			 * Remember and keep looking for a better match.			 */			if (hd->hp_slave == s &&			    match_s->hp_ctlr < 0 && match_s->hp_slave < 0) {				match_s = hd;				new_c = hc->hp_unit;				continue;			}			/*			 * OW: we had a totally wildcarded spec.			 * If we got this far, we have found a possible			 * match already (match_s != NULL) so there is no			 * reason to remember this one.			 */			continue;		}		/*		 * Found a match.  We need to set hp_ctlr/hp_slave properly		 * for the init routines but we also need to remember all		 * the old values in case this doesn't pan out.		 */		if (match_s) {			hd = match_s;			old_c = hd->hp_ctlr;			old_s = hd->hp_slave;			if (hd->hp_ctlr < 0)				hd->hp_ctlr = new_c;			if (hd->hp_slave < 0)				hd->hp_slave = new_s;#ifdef DEBUG			if (acdebug)				printf("looking for %s%d at slave %d...",				       hd->hp_driver->d_name,				       hd->hp_unit, hd->hp_slave);#endif			if ((*hd->hp_driver->d_init)(hd)) {#ifdef DEBUG				if (acdebug)					printf("found\n");#endif				printf("%s%d at %s%d, slave %d",				       hd->hp_driver->d_name, hd->hp_unit,				       hc->hp_driver->d_name, hd->hp_ctlr,				       hd->hp_slave);				if (hd->hp_flags)					printf(" flags 0x%x", hd->hp_flags);				printf("\n");				hd->hp_alive = 1;				if (hd->hp_dk && dkn < DK_NDRIVE)					hd->hp_dk = dkn++;				else					hd->hp_dk = -1;				rescan = 1;			} else {#ifdef DEBUG				if (acdebug)					printf("not found\n");#endif				hd->hp_ctlr = old_c;				hd->hp_slave = old_s;			}			/*			 * XXX: This should be handled better.			 * Re-scan a slave.  There are two reasons to do this.			 * 1. It is possible to have both a tape and disk			 *    (e.g. 7946) or two disks (e.g. 9122) at the			 *    same slave address.  Here we need to rescan			 *    looking only at entries with a different			 *    physical unit number (hp_flags).			 * 2. It is possible that an init failed because the			 *    slave was there but of the wrong type.  In this			 *    case it may still be possible to match the slave			 *    to another ioconf entry of a different type.			 *    Here we need to rescan looking only at entries			 *    of different types.			 * In both cases we avoid looking at undesirable			 * ioconf entries of the same type by setting their			 * alive fields to -1.			 */			if (rescan) {				for (hd = hp_dinit; hd->hp_driver; hd++) {					if (hd->hp_alive)						continue;					if (match_s->hp_alive == 1) {	/* 1 */						if (hd->hp_flags == match_s->hp_flags)							hd->hp_alive = -1;					} else {			/* 2 */						if (hd->hp_driver == match_s->hp_driver)							hd->hp_alive = -1;					}				}				LASTSLAVE(s);				continue;			}		}		/*		 * Reset bogon alive fields prior to attempting next slave		 */		for (hd = hp_dinit; hd->hp_driver; hd++)			if (hd->hp_alive == -1)				hd->hp_alive = 0;	}#undef NEXTSLAVE#undef LASTSLAVE}caddr_tsctopa(sc)	register int sc;{	register caddr_t addr;	if (sc == 7 && internalhpib)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -