autoconf.c revision 1.11
11.1Smw/*
21.1Smw * Copyright (c) 1988 University of Utah.
31.1Smw * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
41.1Smw * All rights reserved.
51.1Smw *
61.1Smw * This code is derived from software contributed to Berkeley by
71.1Smw * the Systems Programming Group of the University of Utah Computer
81.1Smw * Science Department.
91.1Smw *
101.1Smw * Redistribution and use in source and binary forms, with or without
111.1Smw * modification, are permitted provided that the following conditions
121.1Smw * are met:
131.1Smw * 1. Redistributions of source code must retain the above copyright
141.1Smw *    notice, this list of conditions and the following disclaimer.
151.1Smw * 2. Redistributions in binary form must reproduce the above copyright
161.1Smw *    notice, this list of conditions and the following disclaimer in the
171.1Smw *    documentation and/or other materials provided with the distribution.
181.1Smw * 3. All advertising materials mentioning features or use of this software
191.1Smw *    must display the following acknowledgement:
201.1Smw *	This product includes software developed by the University of
211.1Smw *	California, Berkeley and its contributors.
221.1Smw * 4. Neither the name of the University nor the names of its contributors
231.1Smw *    may be used to endorse or promote products derived from this software
241.1Smw *    without specific prior written permission.
251.1Smw *
261.1Smw * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
271.1Smw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
281.1Smw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
291.1Smw * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
301.1Smw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
311.1Smw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
321.1Smw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
331.1Smw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
341.1Smw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
351.1Smw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
361.1Smw * SUCH DAMAGE.
371.1Smw *
381.4Smw * from: Utah $Hdr: autoconf.c 1.31 91/01/21$
391.4Smw *
401.4Smw *	@(#)autoconf.c	7.5 (Berkeley) 5/7/91
411.11Schopps *	$Id: autoconf.c,v 1.11 1994/03/08 10:48:49 chopps Exp $
421.1Smw */
431.1Smw
441.1Smw/*
451.1Smw * Setup the system to run on the current machine.
461.1Smw *
471.1Smw * Configure() is called at boot time.  Available
481.1Smw * devices are determined (from possibilities mentioned in ioconf.c),
491.1Smw * and the drivers are initialized.
501.1Smw */
511.1Smw
521.9Schopps#include <sys/param.h>
531.9Schopps#include <sys/systm.h>
541.9Schopps#include <sys/buf.h>
551.9Schopps#include <sys/dkstat.h>
561.9Schopps#include <sys/conf.h>
571.9Schopps#include <sys/dmap.h>
581.9Schopps#include <sys/reboot.h>
591.9Schopps
601.10Schopps#include <vm/vm.h>		/* XXXX Kludge for IVS Vector - mlh */
611.10Schopps
621.9Schopps#include <machine/vmparam.h>
631.9Schopps#include <machine/cpu.h>
641.9Schopps#include <machine/pte.h>
651.9Schopps#include <amiga/dev/device.h>
661.1Smw
671.9Schopps#include <amiga/amiga/configdev.h>
681.9Schopps#include <amiga/amiga/custom.h>
691.1Smw
701.1Smw/*
711.1Smw * The following several variables are related to
721.1Smw * the configuration process, and are used in initializing
731.1Smw * the machine.
741.1Smw */
751.1Smwint	cold;		    /* if 1, still working on cold-start */
761.1Smwint	dkn;		    /* number of iostat dk numbers assigned so far */
771.1Smwint	cpuspeed = MHZ_8;   /* relative cpu speed */
781.1Smwstruct	amiga_hw sc_table[MAXCTLRS];
791.1Smw
801.3Smw/* set up in amiga_init.c */
811.3Smwextern caddr_t ZORRO2ADDR;
821.3Smw
831.3Smw/* maps a zorro2 and/or A3000 builtin address into the mapped kva address */
841.3Smw#define zorro2map(pa) ((caddr_t) ((u_int)ZORRO2ADDR - ZORRO2BASE + (u_int)pa))
851.11Schopps
861.3Smw/* tests whether the address lies in our zorro2 space */
871.11Schopps#define iszorro2kva(kva) \
881.11Schopps    ((u_int)kva >= (u_int)ZORRO2ADDR && \
891.11Schopps    (u_int)kva < ((u_int)ZORRO2ADDR + (u_int)ZORRO2TOP - (u_int)ZORRO2BASE))
901.11Schopps
911.3Smw#define iszorro2pa(pa) ((u_int)pa >= ZORRO2BASE && (u_int)pa <= ZORRO2TOP)
921.3Smw
931.1Smw#ifdef DEBUG
941.1Smwint	acdebug = 0;
951.1Smw#endif
961.1Smw
971.11Schoppsvoid setroot __P((void));
981.11Schoppsvoid swapconf __P((void));
991.11Schoppsvoid configure __P((void));
1001.11Schoppsvoid find_devs __P((void));
1011.11Schoppsvoid find_slaves __P((struct amiga_ctlr *));
1021.11Schoppsvoid find_busslaves __P((struct amiga_ctlr *, int));
1031.11Schopps
1041.1Smw/*
1051.1Smw * Determine mass storage and memory configuration for a machine.
1061.1Smw */
1071.11Schoppsvoid
1081.1Smwconfigure()
1091.1Smw{
1101.1Smw	register struct amiga_hw *hw;
1111.1Smw	int found;
1121.3Smw
1131.3Smw	/* XXXX I HATE IT XXXX */
1141.3Smw	custom.intena = INTF_INTEN;
1151.1Smw
1161.1Smw	/*
1171.1Smw	 * Look over each hardware device actually found and attempt
1181.1Smw	 * to match it with an ioconf.c table entry.
1191.1Smw	 */
1201.1Smw	for (hw = sc_table; hw->hw_type; hw++) {
1211.1Smw		if (HW_ISCTLR(hw))
1221.1Smw			found = find_controller(hw);
1231.1Smw		else
1241.1Smw			found = find_device(hw);
1251.1Smw#ifdef DEBUG
1261.11Schopps		if (!found && acdebug)
1271.1Smw			printf("unconfigured device %d/%d\n",
1281.11Schopps			    hw->hw_manufacturer, hw->hw_product);
1291.11Schopps
1301.1Smw#endif
1311.1Smw	}
1321.11Schopps
1331.1Smw#if GENERIC
1341.1Smw	if ((boothowto & RB_ASKNAME) == 0)
1351.1Smw		setroot();
1361.1Smw	setconf();
1371.1Smw#else
1381.1Smw	setroot();
1391.1Smw#endif
1401.1Smw	swapconf();
1411.1Smw	cold = 0;
1421.3Smw
1431.3Smw	custom.intena = INTF_SETCLR | INTF_INTEN;
1441.1Smw}
1451.1Smw
1461.11Schopps#define dr_type(d, s) (strcmp((d)->d_name, (s)) == 0)
1471.1Smw
1481.1Smw#define same_hw_ctlr(hw, ac) \
1491.11Schopps    (HW_ISFLOPPY(hw) && dr_type((ac)->amiga_driver, "floppy") || \
1501.11Schopps    HW_ISSCSI(hw) && (dr_type((ac)->amiga_driver, "a3000scsi") \
1511.11Schopps    || dr_type((ac)->amiga_driver, "a2091scsi") \
1521.11Schopps    || dr_type((ac)->amiga_driver, "GVPIIscsi") \
1531.11Schopps    || dr_type((ac)->amiga_driver, "Zeusscsi") \
1541.11Schopps    || dr_type((ac)->amiga_driver, "Magnumscsi") \
1551.11Schopps    || dr_type((ac)->amiga_driver, "Mlhscsi") \
1561.11Schopps    || dr_type((ac)->amiga_driver, "Csa12gscsi") \
1571.11Schopps    || dr_type((ac)->amiga_driver, "Suprascsi") \
1581.11Schopps    || dr_type((ac)->amiga_driver, "IVSscsi")))
1591.1Smw
1601.11Schoppsint
1611.1Smwfind_controller(hw)
1621.1Smw	register struct amiga_hw *hw;
1631.1Smw{
1641.1Smw	register struct amiga_ctlr *ac;
1651.1Smw	struct amiga_ctlr *match_c;
1661.1Smw	caddr_t oaddr;
1671.1Smw	int sc;
1681.1Smw
1691.1Smw#ifdef DEBUG
1701.1Smw	if (acdebug)
1711.1Smw		printf("find_controller: hw: [%d/%d] (%x), type %x...",
1721.11Schopps		    hw->hw_manufacturer, hw->hw_product,
1731.11Schopps		    hw->hw_kva, hw->hw_type);
1741.1Smw#endif
1751.1Smw	sc = (hw->hw_manufacturer << 16) | hw->hw_product;
1761.1Smw	match_c = NULL;
1771.11Schopps
1781.1Smw	for (ac = amiga_cinit; ac->amiga_driver; ac++) {
1791.1Smw		if (ac->amiga_alive)
1801.1Smw			continue;
1811.1Smw		/*
1821.1Smw		 * Make sure we are looking at the right
1831.1Smw		 * controller type.
1841.1Smw		 */
1851.1Smw		if (!same_hw_ctlr(hw, ac))
1861.1Smw			continue;
1871.1Smw		/*
1881.1Smw		 * Exact match; all done
1891.1Smw		 */
1901.1Smw		if ((int)ac->amiga_addr == sc) {
1911.1Smw			match_c = ac;
1921.1Smw			break;
1931.1Smw		}
1941.1Smw		/*
1951.1Smw		 * Wildcard; possible match so remember first instance
1961.1Smw		 * but continue looking for exact match.
1971.1Smw		 */
1981.1Smw		if (ac->amiga_addr == NULL && match_c == NULL)
1991.1Smw			match_c = ac;
2001.1Smw	}
2011.1Smw#ifdef DEBUG
2021.1Smw	if (acdebug) {
2031.1Smw		if (match_c)
2041.1Smw			printf("found %s%d\n",
2051.11Schopps			    match_c->amiga_driver->d_name,
2061.11Schopps			    match_c->amiga_unit);
2071.1Smw		else
2081.1Smw			printf("not found\n");
2091.1Smw	}
2101.1Smw#endif
2111.1Smw	/*
2121.1Smw	 * Didn't find an ioconf entry for this piece of hardware,
2131.1Smw	 * just ignore it.
2141.1Smw	 */
2151.1Smw	if (match_c == NULL)
2161.1Smw		return(0);
2171.1Smw	/*
2181.1Smw	 * Found a match, attempt to initialize and configure all attached
2191.1Smw	 * slaves.  Note, we can still fail if HW won't initialize.
2201.1Smw	 */
2211.1Smw	ac = match_c;
2221.1Smw	oaddr = ac->amiga_addr;
2231.1Smw	ac->amiga_addr = hw->hw_kva;
2241.11Schopps	if (0 == (*ac->amiga_driver->d_init)(ac))
2251.11Schopps		ac->amiga_addr = oaddr;
2261.11Schopps	else {
2271.1Smw		ac->amiga_alive = 1;
2281.11Schopps		printf("%s%d", ac->amiga_driver->d_name, ac->amiga_unit);
2291.11Schopps		printf(" [%d/%d]", hw->hw_manufacturer, hw->hw_product);
2301.1Smw		if (ac->amiga_flags)
2311.1Smw			printf(", flags 0x%x", ac->amiga_flags);
2321.1Smw		printf("\n");
2331.1Smw		find_slaves(ac);
2341.11Schopps	}
2351.1Smw	return(1);
2361.1Smw}
2371.1Smw
2381.11Schoppsint
2391.1Smwfind_device(hw)
2401.1Smw	register struct amiga_hw *hw;
2411.1Smw{
2421.1Smw	register struct amiga_device *ad;
2431.1Smw	struct amiga_device *match_d;
2441.1Smw	caddr_t oaddr;
2451.1Smw	int sc;
2461.1Smw
2471.1Smw#ifdef DEBUG
2481.1Smw	if (acdebug)
2491.1Smw		printf("find_device: hw: [%d/%d] (%x), type %x...",
2501.11Schopps		    hw->hw_manufacturer, hw->hw_product,
2511.11Schopps		    hw->hw_kva, hw->hw_type);
2521.1Smw#endif
2531.1Smw	match_d = NULL;
2541.11Schopps
2551.1Smw	for (ad = amiga_dinit; ad->amiga_driver; ad++) {
2561.1Smw		if (ad->amiga_alive)
2571.1Smw			continue;
2581.1Smw		/* Must not be a slave */
2591.1Smw		if (ad->amiga_cdriver)
2601.1Smw			continue;
2611.1Smw
2621.3Smw		/*
2631.3Smw		 * XXX: A graphics device that was found as part of the
2641.3Smw		 * console init will have the amiga_addr field already set
2651.3Smw		 * (i.e. no longer the select code).  Gotta perform a
2661.3Smw		 * slightly different check for an exact match.
2671.3Smw		 */
2681.11Schopps		if (HW_ISDEV(hw, D_BITMAP) && iszorro2kva(ad->amiga_addr)) {
2691.11Schopps			if (ad->amiga_addr == hw->hw_kva) {
2701.11Schopps				match_d = ad;
2711.11Schopps				break;
2721.11Schopps			}
2731.11Schopps			continue;
2741.11Schopps		}
2751.1Smw		sc = (int) ad->amiga_addr;
2761.1Smw		/*
2771.1Smw		 * Exact match; all done.
2781.1Smw		 */
2791.11Schopps		if (sc > 0 &&
2801.11Schopps		    sc == ((hw->hw_manufacturer << 16) | hw->hw_product)) {
2811.1Smw			match_d = ad;
2821.1Smw			break;
2831.1Smw		}
2841.1Smw		/*
2851.1Smw		 * Wildcard; possible match so remember first instance
2861.1Smw		 * but continue looking for exact match.
2871.1Smw		 */
2881.1Smw		if (sc == 0 && same_hw_device(hw, ad) && match_d == NULL)
2891.1Smw			match_d = ad;
2901.1Smw	}
2911.1Smw#ifdef DEBUG
2921.1Smw	if (acdebug) {
2931.1Smw		if (match_d)
2941.1Smw			printf("found %s%d\n",
2951.1Smw			       match_d->amiga_driver->d_name,
2961.1Smw			       match_d->amiga_unit);
2971.1Smw		else
2981.1Smw			printf("not found\n");
2991.1Smw	}
3001.1Smw#endif
3011.1Smw	/*
3021.1Smw	 * Didn't find an ioconf entry for this piece
3031.1Smw	 * of hardware, just ignore it.
3041.1Smw	 */
3051.1Smw	if (match_d == NULL)
3061.1Smw		return(0);
3071.1Smw	/*
3081.1Smw	 * Found a match, attempt to initialize.
3091.1Smw	 * Note, we can still fail if HW won't initialize.
3101.1Smw	 */
3111.1Smw	ad = match_d;
3121.1Smw	oaddr = ad->amiga_addr;
3131.1Smw	ad->amiga_addr = hw->hw_kva;
3141.3Smw	ad->amiga_serno = hw->hw_serno;
3151.3Smw	ad->amiga_size = hw->hw_size;
3161.11Schopps
3171.11Schopps	if (0 == (*ad->amiga_driver->d_init)(ad))
3181.11Schopps		ad->amiga_addr = oaddr;
3191.11Schopps	else {
3201.1Smw		ad->amiga_alive = 1;
3211.1Smw		printf("%s%d", ad->amiga_driver->d_name, ad->amiga_unit);
3221.11Schopps		printf(" [%d/%d]", hw->hw_manufacturer, hw->hw_product);
3231.1Smw		if (ad->amiga_flags)
3241.1Smw			printf(", flags 0x%x", ad->amiga_flags);
3251.1Smw		printf("\n");
3261.11Schopps	}
3271.1Smw	return(1);
3281.1Smw}
3291.1Smw
3301.11Schoppsvoid
3311.1Smwfind_slaves(ac)
3321.1Smw	struct amiga_ctlr *ac;
3331.1Smw{
3341.1Smw	if (dr_type(ac->amiga_driver, "floppy"))
3351.1Smw		find_busslaves(ac, 4);
3361.5Smw	else if (dr_type(ac->amiga_driver, "a3000scsi")
3371.5Smw            || dr_type(ac->amiga_driver, "a2091scsi")
3381.5Smw	    || dr_type(ac->amiga_driver, "GVPIIscsi")
3391.5Smw	    || dr_type(ac->amiga_driver, "Zeusscsi")
3401.10Schopps	    || dr_type(ac->amiga_driver, "Magnumscsi")
3411.10Schopps	    || dr_type(ac->amiga_driver, "Mlhscsi")
3421.10Schopps	    || dr_type(ac->amiga_driver, "Csa12gscsi")
3431.10Schopps	    || dr_type(ac->amiga_driver, "Suprascsi")
3441.10Schopps	    || dr_type(ac->amiga_driver, "IVSscsi"))
3451.1Smw		find_busslaves(ac, 7);
3461.1Smw}
3471.1Smw
3481.1Smw/*
3491.1Smw */
3501.11Schoppsvoid
3511.1Smwfind_busslaves(ac, maxslaves)
3521.1Smw	register struct amiga_ctlr *ac;
3531.1Smw	int maxslaves;
3541.1Smw{
3551.1Smw	register int s;
3561.1Smw	register struct amiga_device *ad;
3571.1Smw	struct amiga_device *match_s;
3581.1Smw	int new_s, new_c, old_s, old_c;
3591.1Smw	int rescan;
3601.1Smw
3611.1Smw#ifdef DEBUG
3621.1Smw	if (acdebug)
3631.1Smw		printf("find_busslaves: for %s%d\n",
3641.1Smw		       ac->amiga_driver->d_name, ac->amiga_unit);
3651.1Smw#endif
3661.1Smw	for (s = 0; s < maxslaves; s++) {
3671.1Smw		rescan = 1;
3681.1Smw		match_s = NULL;
3691.1Smw		for (ad = amiga_dinit; ad->amiga_driver; ad++) {
3701.1Smw			/*
3711.1Smw			 * Rule out the easy ones:
3721.1Smw			 * 1. slave already assigned or not a slave
3731.1Smw			 * 2. not of the proper type
3741.1Smw			 * 3. controller specified but not this one
3751.1Smw			 * 4. slave specified but not this one
3761.1Smw			 */
3771.1Smw			if (ad->amiga_alive || ad->amiga_cdriver == NULL)
3781.1Smw				continue;
3791.11Schopps			else if (0 == dr_type(ac->amiga_driver,
3801.11Schopps			    ad->amiga_cdriver->d_name))
3811.1Smw				continue;
3821.11Schopps			else if (ad->amiga_ctlr >= 0 &&
3831.11Schopps			    ad->amiga_ctlr != ac->amiga_unit)
3841.1Smw				continue;
3851.11Schopps			else if (ad->amiga_slave >= 0 && ad->amiga_slave != s)
3861.1Smw				continue;
3871.1Smw			/*
3881.1Smw			 * Case 0: first possible match.
3891.1Smw			 * Remember it and keep looking for better.
3901.1Smw			 */
3911.1Smw			if (match_s == NULL) {
3921.1Smw				match_s = ad;
3931.1Smw				new_c = ac->amiga_unit;
3941.1Smw				new_s = s;
3951.1Smw				continue;
3961.1Smw			}
3971.1Smw			/*
3981.1Smw			 * Case 1: exact match.
3991.1Smw			 * All done.  Note that we do not attempt any other
4001.1Smw			 * matches if this one fails.  This allows us to
4011.1Smw			 * "reserve" locations for dynamic addition of
4021.1Smw			 * disk/tape drives by fully qualifing the location.
4031.1Smw			 */
4041.11Schopps			if (ad->amiga_slave == s &&
4051.11Schopps			    ad->amiga_ctlr == ac->amiga_unit) {
4061.1Smw				match_s = ad;
4071.1Smw				rescan = 0;
4081.1Smw				break;
4091.1Smw			}
4101.1Smw			/*
4111.1Smw			 * Case 2: right controller, wildcarded slave.
4121.1Smw			 * Remember first and keep looking for an exact match.
4131.1Smw			 */
4141.1Smw			if (ad->amiga_ctlr == ac->amiga_unit &&
4151.1Smw			    match_s->amiga_ctlr < 0) {
4161.1Smw				match_s = ad;
4171.1Smw				new_s = s;
4181.1Smw				continue;
4191.1Smw			}
4201.1Smw			/*
4211.1Smw			 * Case 3: right slave, wildcarded controller.
4221.1Smw			 * Remember and keep looking for a better match.
4231.1Smw			 */
4241.1Smw			if (ad->amiga_slave == s &&
4251.11Schopps			    match_s->amiga_ctlr < 0 &&
4261.11Schopps			    match_s->amiga_slave < 0) {
4271.1Smw				match_s = ad;
4281.1Smw				new_c = ac->amiga_unit;
4291.1Smw				continue;
4301.1Smw			}
4311.1Smw			/*
4321.1Smw			 * OW: we had a totally wildcarded spec.
4331.1Smw			 * If we got this far, we have found a possible
4341.1Smw			 * match already (match_s != NULL) so there is no
4351.1Smw			 * reason to remember this one.
4361.1Smw			 */
4371.1Smw			continue;
4381.1Smw		}
4391.1Smw		/*
4401.11Schopps		 * Found a match.  We need to set
4411.11Schopps		 * amiga_ctlr/amiga_slave properly for the init
4421.11Schopps		 * routines but we also need to remember all the old
4431.11Schopps		 * values in case this doesn't pan out.
4441.1Smw		 */
4451.1Smw		if (match_s) {
4461.1Smw			ad = match_s;
4471.1Smw			old_c = ad->amiga_ctlr;
4481.1Smw			old_s = ad->amiga_slave;
4491.1Smw			if (ad->amiga_ctlr < 0)
4501.1Smw				ad->amiga_ctlr = new_c;
4511.1Smw			if (ad->amiga_slave < 0)
4521.1Smw				ad->amiga_slave = new_s;
4531.1Smw#ifdef DEBUG
4541.1Smw			if (acdebug)
4551.1Smw				printf("looking for %s%d at slave %d...",
4561.1Smw				       ad->amiga_driver->d_name,
4571.1Smw				       ad->amiga_unit, ad->amiga_slave);
4581.1Smw#endif
4591.1Smw
4601.1Smw			if ((*ad->amiga_driver->d_init)(ad)) {
4611.1Smw#ifdef DEBUG
4621.1Smw				if (acdebug)
4631.1Smw					printf("found\n");
4641.1Smw#endif
4651.1Smw				printf("%s%d at %s%d, slave %d",
4661.11Schopps				       ad->amiga_driver->d_name,
4671.11Schopps				       ad->amiga_unit,
4681.11Schopps				       ac->amiga_driver->d_name,
4691.11Schopps				       ad->amiga_ctlr,ad->amiga_slave);
4701.1Smw				if (ad->amiga_flags)
4711.11Schopps					printf(" flags 0x%x",ad->amiga_flags);
4721.1Smw				printf("\n");
4731.11Schopps
4741.1Smw				ad->amiga_alive = 1;
4751.1Smw				if (ad->amiga_dk && dkn < DK_NDRIVE)
4761.1Smw					ad->amiga_dk = dkn++;
4771.1Smw				else
4781.1Smw					ad->amiga_dk = -1;
4791.1Smw				rescan = 1;
4801.7Schopps				/*
4811.11Schopps				 * The init on this unit suceeded, so
4821.11Schopps				 * we need to mark the same
4831.11Schopps				 * device/unit on other hardware
4841.11Schopps				 * controllers as "alive" since we
4851.11Schopps				 * can't reuse the same unit for that
4861.11Schopps				 * device driver. mlh
4871.7Schopps				 */
4881.11Schopps				for (ad = amiga_dinit; ad->amiga_driver;
4891.11Schopps				     ad++) {
4901.11Schopps					if (ad->amiga_driver ==
4911.11Schopps					    match_s->amiga_driver &&
4921.11Schopps					    ad->amiga_unit ==
4931.11Schopps					    match_s->amiga_unit)
4941.7Schopps						ad->amiga_alive = 2;
4951.7Schopps				}
4961.1Smw			} else {
4971.1Smw#ifdef DEBUG
4981.1Smw				if (acdebug)
4991.1Smw					printf("not found\n");
5001.1Smw#endif
5011.1Smw				ad->amiga_ctlr = old_c;
5021.1Smw				ad->amiga_slave = old_s;
5031.1Smw			}
5041.1Smw			/*
5051.1Smw			 * XXX: This should be handled better.
5061.1Smw			 * Re-scan a slave.  There are two reasons to do this.
5071.1Smw			 * 1. It is possible to have both a tape and disk
5081.1Smw			 *    (e.g. 7946) or two disks (e.g. 9122) at the
5091.1Smw			 *    same slave address.  Here we need to rescan
5101.1Smw			 *    looking only at entries with a different
5111.1Smw			 *    physical unit number (amiga_flags).
5121.1Smw			 * 2. It is possible that an init failed because the
5131.1Smw			 *    slave was there but of the wrong type.  In this
5141.1Smw			 *    case it may still be possible to match the slave
5151.1Smw			 *    to another ioconf entry of a different type.
5161.1Smw			 *    Here we need to rescan looking only at entries
5171.1Smw			 *    of different types.
5181.1Smw			 * In both cases we avoid looking at undesirable
5191.1Smw			 * ioconf entries of the same type by setting their
5201.1Smw			 * alive fields to -1.
5211.1Smw			 */
5221.1Smw			if (rescan) {
5231.11Schopps				for (ad = amiga_dinit; ad->amiga_driver;
5241.11Schopps				    ad++) {
5251.1Smw					if (ad->amiga_alive)
5261.1Smw						continue;
5271.11Schopps					else if (match_s->amiga_alive == 1) {
5281.11Schopps						if (ad->amiga_flags ==
5291.11Schopps						    match_s->amiga_flags)
5301.1Smw							ad->amiga_alive = -1;
5311.11Schopps					} else { /* 2 */
5321.11Schopps						if (ad->amiga_driver ==
5331.11Schopps						    match_s->amiga_driver)
5341.1Smw							ad->amiga_alive = -1;
5351.1Smw					}
5361.1Smw				}
5371.1Smw				s--;
5381.1Smw				continue;
5391.1Smw			}
5401.1Smw		}
5411.1Smw		/*
5421.1Smw		 * Reset bogon alive fields prior to attempting next slave
5431.1Smw		 */
5441.1Smw		for (ad = amiga_dinit; ad->amiga_driver; ad++)
5451.1Smw			if (ad->amiga_alive == -1)
5461.1Smw				ad->amiga_alive = 0;
5471.1Smw	}
5481.1Smw}
5491.1Smw
5501.11Schoppsint
5511.1Smwsame_hw_device(hw, ad)
5521.1Smw	struct amiga_hw *hw;
5531.1Smw	struct amiga_device *ad;
5541.1Smw{
5551.11Schopps	int found;
5561.11Schopps
5571.11Schopps	found = 0;
5581.1Smw
5591.1Smw	switch (hw->hw_type & ~B_MASK) {
5601.1Smw	case C_FLOPPY:
5611.1Smw		found = dr_type(ad->amiga_driver, "floppy");
5621.1Smw		break;
5631.1Smw	case C_SCSI:
5641.3Smw		found = (dr_type(ad->amiga_driver, "a3000scsi")
5651.3Smw			 || dr_type(ad->amiga_driver, "a2091scsi")
5661.5Smw			 || dr_type(ad->amiga_driver, "GVPIIscsi")
5671.5Smw			 || dr_type(ad->amiga_driver, "Zeusscsi")
5681.10Schopps			 || dr_type(ad->amiga_driver, "Magnumscsi")
5691.10Schopps			 || dr_type(ad->amiga_driver, "Mlhscsi")
5701.10Schopps			 || dr_type(ad->amiga_driver, "Csa12gscsi")
5711.10Schopps			 || dr_type(ad->amiga_driver, "Suprascsi")
5721.10Schopps			 || dr_type(ad->amiga_driver, "IVSscsi"));
5731.1Smw		break;
5741.1Smw	case D_BITMAP:
5751.1Smw		found = dr_type(ad->amiga_driver, "grf");
5761.1Smw		break;
5771.1Smw	case D_LAN:
5781.1Smw		found = dr_type(ad->amiga_driver, "le");
5791.1Smw		break;
5801.1Smw	case D_COMMSER:
5811.1Smw		found = dr_type(ad->amiga_driver, "ser");
5821.1Smw		break;
5831.3Smw	case D_CLOCK:
5841.3Smw		found = dr_type(ad->amiga_driver, "rtclock");
5851.4Smw		break;
5861.4Smw	case D_PPORT:
5871.4Smw		found = dr_type(ad->amiga_driver, "par");
5881.3Smw		break;
5891.1Smw	default:
5901.1Smw		break;
5911.1Smw	}
5921.1Smw	return(found);
5931.1Smw}
5941.1Smw
5951.1Smwchar notmappedmsg[] = "WARNING: no space to map IO card, ignored\n";
5961.1Smw
5971.1Smw/*
5981.1Smw * Scan the IO space looking for devices.
5991.1Smw */
6001.11Schoppsvoid
6011.1Smwfind_devs()
6021.1Smw{
6031.11Schopps  extern int num_ConfigDev;
6041.11Schopps  extern struct ConfigDev *ConfigDev;
6051.1Smw  short sc;
6061.1Smw  u_char *id_reg;
6071.1Smw  register caddr_t addr;
6081.1Smw  register struct amiga_hw *hw;
6091.1Smw  int didmap, sctop;
6101.1Smw  struct ConfigDev *cd;
6111.1Smw
6121.1Smw#if 0
6131.1Smw  /*
6141.1Smw   * Initialize IO resource map for iomap().
6151.1Smw   */
6161.1Smw  rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);
6171.1Smw#endif
6181.1Smw  hw = sc_table;
6191.1Smw
6201.1Smw  /* first enter builtin devices */
6211.1Smw
6221.5Smw  if (is_a4000 ())
6231.5Smw    {
6241.5Smw      /* The A4000 appears to use the same realtime clock as the A3000.
6251.5Smw         Add the IDE controller when that information becomes available.
6261.5Smw	 */
6271.5Smw
6281.6Schopps      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
6291.5Smw      hw->hw_size	  = NBPG;
6301.5Smw      hw->hw_kva	  = zorro2map (0xdc0000);
6311.5Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6321.5Smw      hw->hw_product      = PROD_BUILTIN_CLOCK;
6331.5Smw      hw->hw_type	  = B_BUILTIN | D_CLOCK;
6341.5Smw      hw->hw_serno	  = 0;
6351.5Smw      hw++;
6361.5Smw    }
6371.5Smw  else if (is_a3000 ())
6381.3Smw    {
6391.3Smw      /* hm, this doesn't belong here... */
6401.3Smw      volatile u_char *magic_reset_reg = zorro2map (0xde0002);
6411.3Smw      /* this bit makes the next reset look like a powerup reset, Amiga
6421.3Smw	 Unix sets this bit, and perhaps it will enable 16M machines to
6431.3Smw	 boot again... */
6441.3Smw      *magic_reset_reg   |= 0x80;
6451.3Smw
6461.6Schopps      hw->hw_pa		  = (caddr_t) 0xdd0000;
6471.3Smw      hw->hw_size	  = NBPG;
6481.3Smw      hw->hw_kva	  = zorro2map (0xdd0000);
6491.3Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6501.3Smw      hw->hw_product      = PROD_BUILTIN_SCSI;
6511.3Smw      hw->hw_type	  = B_BUILTIN | C_SCSI;
6521.3Smw      hw->hw_serno	  = 0;
6531.3Smw      hw++;
6541.1Smw
6551.6Schopps      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
6561.3Smw      hw->hw_size	  = NBPG;
6571.3Smw      hw->hw_kva	  = zorro2map (0xdc0000);
6581.3Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6591.3Smw      hw->hw_product      = PROD_BUILTIN_CLOCK;
6601.3Smw      hw->hw_type	  = B_BUILTIN | D_CLOCK;
6611.3Smw      hw->hw_serno	  = 0;
6621.3Smw      hw++;
6631.3Smw    }
6641.3Smw  else
6651.3Smw    {
6661.3Smw      /* what about other Amigas? Oh well.. */
6671.6Schopps      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
6681.3Smw      hw->hw_size	  = NBPG;
6691.3Smw      hw->hw_kva	  = zorro2map (0xdc0000);
6701.3Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6711.3Smw      hw->hw_product      = PROD_BUILTIN_CLOCK2;
6721.3Smw      hw->hw_type	  = B_BUILTIN | D_CLOCK;
6731.3Smw      hw->hw_serno	  = 0;
6741.3Smw      hw++;
6751.3Smw    }
6761.1Smw
6771.1Smw  hw->hw_pa	      = 0;
6781.1Smw  hw->hw_size	      = 0;
6791.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6801.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6811.1Smw  hw->hw_product      = PROD_BUILTIN_FLOPPY;
6821.1Smw  hw->hw_type	      = B_BUILTIN | C_FLOPPY;
6831.3Smw  hw->hw_serno	      = 0;
6841.1Smw  hw++;
6851.1Smw
6861.1Smw  hw->hw_pa	      = 0;
6871.1Smw  hw->hw_size	      = 0;
6881.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6891.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6901.1Smw  hw->hw_product      = PROD_BUILTIN_KEYBOARD;
6911.1Smw  hw->hw_type	      = B_BUILTIN | D_KEYBOARD;
6921.3Smw  hw->hw_serno	      = 0;
6931.1Smw  hw++;
6941.1Smw
6951.1Smw  hw->hw_pa	      = 0;
6961.1Smw  hw->hw_size	      = 0;
6971.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6981.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6991.1Smw  hw->hw_product      = PROD_BUILTIN_PPORT;
7001.1Smw  hw->hw_type	      = B_BUILTIN | D_PPORT;
7011.3Smw  hw->hw_serno	      = 0;
7021.1Smw  hw++;
7031.1Smw
7041.1Smw  hw->hw_pa	      = 0;
7051.1Smw  hw->hw_size	      = 0;
7061.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
7071.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
7081.1Smw  hw->hw_product      = PROD_BUILTIN_DISPLAY;
7091.1Smw  hw->hw_type	      = B_BUILTIN | D_BITMAP;
7101.3Smw  hw->hw_serno	      = 0;
7111.3Smw  hw++;
7121.3Smw
7131.3Smw  hw->hw_pa	      = 0;
7141.3Smw  hw->hw_size	      = 0;
7151.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
7161.3Smw  hw->hw_manufacturer = MANUF_BUILTIN;
7171.3Smw  hw->hw_product      = PROD_BUILTIN_RS232;
7181.3Smw  hw->hw_type	      = B_BUILTIN | D_COMMSER;
7191.3Smw  hw->hw_serno	      = 0;
7201.1Smw  hw++;
7211.3Smw
7221.1Smw  /* and afterwards add Zorro II/III devices passed by the loader */
7231.1Smw
7241.1Smw  for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++)
7251.1Smw    {
7261.1Smw      hw->hw_pa		  = cd->cd_BoardAddr;
7271.1Smw      hw->hw_size	  = cd->cd_BoardSize;
7281.3Smw      /* ADD ZORRO3 SUPPORT HERE !! */
7291.3Smw      hw->hw_kva	  = iszorro2pa(cd->cd_BoardAddr) ? zorro2map (cd->cd_BoardAddr) : 0;
7301.1Smw      hw->hw_manufacturer = cd->cd_Rom.er_Manufacturer;
7311.1Smw      hw->hw_product	  = cd->cd_Rom.er_Product;
7321.3Smw      hw->hw_serno	  = cd->cd_Rom.er_SerialNumber;
7331.1Smw
7341.1Smw      switch (hw->hw_manufacturer)
7351.1Smw        {
7361.1Smw        case MANUF_CBM_1:
7371.1Smw          switch (hw->hw_product)
7381.1Smw            {
7391.1Smw            case PROD_CBM_1_A2088:
7401.1Smw              hw->hw_type = B_ZORROII | D_MISC;
7411.1Smw              break;
7421.1Smw
7431.1Smw            default:
7441.1Smw              continue;
7451.1Smw            }
7461.3Smw          break;
7471.3Smw
7481.3Smw	case MANUF_CBM_2:
7491.3Smw	  switch (hw->hw_product)
7501.3Smw	    {
7511.3Smw	    case PROD_CBM_2_A2091:
7521.3Smw	      hw->hw_type = B_ZORROII | C_SCSI;
7531.3Smw	      break;
7541.3Smw
7551.3Smw	    case PROD_CBM_2_A2065:
7561.3Smw	      hw->hw_type = B_ZORROII | D_LAN;
7571.3Smw              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
7581.3Smw                 whether Commodore or Ameristar board. */
7591.3Smw              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x01000000;
7601.3Smw	      break;
7611.3Smw
7621.3Smw	    default:
7631.3Smw	      continue;
7641.3Smw	    }
7651.3Smw	  break;
7661.3Smw
7671.3Smw	case MANUF_AMERISTAR:
7681.3Smw	  switch (hw->hw_product)
7691.3Smw	    {
7701.3Smw	    case PROD_AMERISTAR_ETHER:
7711.3Smw	      hw->hw_type = B_ZORROII | D_LAN;
7721.3Smw              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
7731.3Smw                 whether Commodore or Ameristar board. */
7741.3Smw              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x02000000;
7751.3Smw	      break;
7761.3Smw
7771.3Smw	    default:
7781.3Smw	      continue;
7791.3Smw	    }
7801.3Smw	  break;
7811.3Smw
7821.1Smw        case MANUF_UNILOWELL:
7831.1Smw          switch (hw->hw_product)
7841.1Smw            {
7851.1Smw            case PROD_UNILOWELL_A2410:
7861.1Smw              hw->hw_type = B_ZORROII | D_BITMAP;
7871.1Smw              break;
7881.1Smw
7891.1Smw            default:
7901.1Smw              continue;
7911.1Smw            }
7921.3Smw          break;
7931.3Smw
7941.3Smw	case MANUF_MACROSYSTEM:
7951.3Smw	  switch (hw->hw_product)
7961.3Smw	    {
7971.3Smw	    case PROD_MACROSYSTEM_RETINA:
7981.3Smw	      hw->hw_type = B_ZORROII | D_BITMAP;
7991.3Smw	      break;
8001.3Smw
8011.3Smw	    default:
8021.3Smw	      continue;
8031.3Smw	    }
8041.3Smw	  break;
8051.3Smw
8061.3Smw	case MANUF_GVP:
8071.3Smw	  switch (hw->hw_product)
8081.3Smw	    {
8091.10Schopps	    case PROD_GVP_SERIES_I:
8101.10Schopps	      /* XXX need to pass product code to driver */
8111.10Schopps	      hw->hw_type = B_ZORROII | C_SCSI;
8121.10Schopps	      break;
8131.10Schopps
8141.3Smw	    case PROD_GVP_SERIES_II:
8151.10Schopps	      /* Figure out what kind of board this is */
8161.10Schopps	      id_reg = (u_char *)hw->hw_kva + 0x8001;
8171.10Schopps	      switch (*id_reg & 0xf8)
8181.10Schopps		{
8191.10Schopps		case PROD_GVP_X_GF40_SCSI:
8201.10Schopps		case PROD_GVP_X_COMBO4_SCSI:
8211.10Schopps		case PROD_GVP_X_GF30_SCSI:
8221.10Schopps		case PROD_GVP_X_COMBO3_SCSI:
8231.10Schopps		case PROD_GVP_X_SCSI_II:
8241.10Schopps		  hw->hw_type = B_ZORROII | C_SCSI;
8251.10Schopps		  break;
8261.10Schopps		case PROD_GVP_X_IOEXTEND:
8271.10Schopps		  hw->hw_type = B_ZORROII | D_COMMSER;
8281.10Schopps		  break;
8291.10Schopps		}
8301.3Smw	      break;
8311.3Smw
8321.3Smw	    case PROD_GVP_IV24:
8331.3Smw	      hw->hw_type = B_ZORROII | D_BITMAP;
8341.3Smw	      break;
8351.3Smw
8361.3Smw	    default:
8371.3Smw	      continue;
8381.3Smw	    }
8391.3Smw	  break;
8401.3Smw
8411.5Smw	case MANUF_PPI:
8421.5Smw	  switch (hw->hw_product)
8431.5Smw	    {
8441.5Smw	    case PROD_PPI_ZEUS:
8451.5Smw	      hw->hw_type = B_ZORROII | C_SCSI;
8461.5Smw	      break;
8471.5Smw
8481.5Smw	    default:
8491.5Smw	      continue;
8501.5Smw	    }
8511.5Smw	  break;
8521.5Smw
8531.5Smw	case MANUF_CSA:
8541.5Smw	  switch (hw->hw_product)
8551.5Smw	    {
8561.5Smw	    case PROD_CSA_MAGNUM:
8571.10Schopps	    case PROD_CSA_12G:
8581.10Schopps	      hw->hw_type = B_ZORROII | C_SCSI;
8591.10Schopps	      break;
8601.10Schopps
8611.10Schopps	    default:
8621.10Schopps	      continue;
8631.10Schopps	    }
8641.10Schopps	  break;
8651.10Schopps
8661.10Schopps	case MANUF_SUPRA:
8671.10Schopps	  switch (hw->hw_product)
8681.10Schopps	    {
8691.10Schopps	    /* XXXX need to distinguish different controllers with a single driver */
8701.10Schopps	    case PROD_SUPRA_WORDSYNC_2:
8711.10Schopps	      hw->hw_type = B_ZORROII | C_SCSI;
8721.10Schopps	      break;
8731.10Schopps
8741.10Schopps	    default:
8751.10Schopps	      continue;
8761.10Schopps	    }
8771.10Schopps	  break;
8781.10Schopps
8791.10Schopps	case MANUF_IVS:
8801.10Schopps	  switch (hw->hw_product)
8811.10Schopps	    {
8821.10Schopps	    /* XXXX need to distinguish different controllers with a single driver */
8831.10Schopps	    case PROD_IVS_VECTOR:
8841.10Schopps	      /* XXXX Ouch! board addresss isn't Zorro II or Zorro III! */
8851.10Schopps	      {
8861.10Schopps		if (pmap_extract(zorro2map(0x00f00000)) == 0x00f00000) {
8871.10Schopps		  /* remap to Vector pa */
8881.10Schopps		}
8891.10Schopps	      }
8901.10Schopps	      hw->hw_type = B_ZORROII | C_SCSI;
8911.10Schopps	      break;
8921.10Schopps
8931.10Schopps	    default:
8941.10Schopps	      continue;
8951.10Schopps	    }
8961.10Schopps	  break;
8971.10Schopps
8981.10Schopps	case MANUF_HACKER:
8991.10Schopps	  switch (hw->hw_product)
9001.10Schopps	    {
9011.10Schopps	    case PROD_HACKER_MLH:
9021.5Smw	      hw->hw_type = B_ZORROII | C_SCSI;
9031.5Smw	      break;
9041.5Smw
9051.5Smw	    default:
9061.5Smw	      continue;
9071.5Smw	    }
9081.5Smw	  break;
9091.5Smw
9101.1Smw        default:
9111.1Smw          continue;
9121.1Smw	}
9131.1Smw
9141.1Smw      hw++;
9151.1Smw    }
9161.1Smw}
9171.1Smw
9181.1Smw/*
9191.11Schopps * Configure swap space and related parameters.
9201.1Smw */
9211.1Smwvoid
9221.1Smwswapconf()
9231.1Smw{
9241.1Smw	register struct swdevt *swp;
9251.1Smw	register int nblks;
9261.1Smw
9271.11Schopps	for (swp = swdevt; swp->sw_dev; swp++) {
9281.1Smw		if (bdevsw[major(swp->sw_dev)].d_psize) {
9291.1Smw			nblks =
9301.11Schopps			    bdevsw[major(swp->sw_dev)].d_psize(swp->sw_dev);
9311.1Smw			if (nblks != -1 &&
9321.11Schopps			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) {
9331.1Smw				swp->sw_nblks = nblks;
9341.11Schopps			}
9351.1Smw		}
9361.11Schopps	}
9371.1Smw	dumpconf();
9381.1Smw	printf ("\n");
9391.1Smw}
9401.1Smw
9411.1Smw#define	DOSWAP			/* Change swdevt and dumpdev too */
9421.1Smwu_long	bootdev;		/* should be dev_t, but not until 32 bits */
9431.1Smw
9441.1Smwstatic	char devname[][2] = {
9451.1Smw	0,0,		/* 0 = ct */
9461.1Smw	0,0,		/* 1 = xx */
9471.1Smw	'r','d',	/* 2 = rd */
9481.1Smw	0,0,		/* 3 = sw */
9491.1Smw	's','d',	/* 4 = sd */
9501.1Smw};
9511.1Smw
9521.1Smw#define	PARTITIONMASK	0x7
9531.1Smw#define	PARTITIONSHIFT	3
9541.1Smw
9551.1Smw/*
9561.1Smw * Attempt to find the device from which we were booted.
9571.1Smw * If we can do so, and not instructed not to do so,
9581.1Smw * change rootdev to correspond to the load device.
9591.1Smw */
9601.11Schoppsvoid
9611.1Smwsetroot()
9621.1Smw{
9631.1Smw	register struct amiga_ctlr *ac;
9641.1Smw	register struct amiga_device *ad;
9651.1Smw	int  majdev, mindev, unit, part, adaptor;
9661.1Smw	dev_t temp, orootdev;
9671.1Smw	struct swdevt *swp;
9681.1Smw
9691.3Smw#ifdef DEBUG
9701.3Smw	if (acdebug > 1)
9711.11Schopps		printf("setroot: boothowto = 0x%x, bootdev = 0x%x\n",
9721.11Schopps			boothowto, bootdev);
9731.3Smw#endif
9741.1Smw
9751.1Smw	if (boothowto & RB_DFLTROOT ||
9761.11Schopps	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) {
9771.3Smw#ifdef DEBUG
9781.11Schopps		if (acdebug > 1)
9791.11Schopps			printf("returning due to: bad boothowto\n");
9801.3Smw#endif
9811.11Schopps		return;
9821.11Schopps	}
9831.1Smw	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
9841.11Schopps	if (majdev > sizeof(devname) / sizeof(devname[0])) {
9851.3Smw#ifdef DEBUG
9861.11Schopps		if (acdebug > 1)
9871.11Schopps			printf("returning due to: majdev(%d) > maxdevs(%d)\n",
9881.11Schopps			    majdev, sizeof(devname) / sizeof(devname[0]));
9891.3Smw#endif
9901.11Schopps		return;
9911.11Schopps	}
9921.11Schopps
9931.1Smw	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
9941.1Smw	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
9951.1Smw	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
9961.3Smw
9971.11Schopps	/*
9981.11Schopps	 * First, find the controller type which support this device.
9991.11Schopps	 * Can have more than one controller for the same device, with
10001.11Schopps	 * just one of them configured, so test for
10011.11Schopps	 * ad->amiga_cdriver != 0 too.
10021.11Schopps	 */
10031.11Schopps	for (ad = amiga_dinit; ad->amiga_driver; ad++) {
10041.11Schopps		if (ad->amiga_driver->d_name[0] != devname[majdev][0]
10051.11Schopps		    || ad->amiga_driver->d_name[1] != devname[majdev][1])
10061.11Schopps			continue;
10071.3Smw
10081.11Schopps		/*
10091.11Schopps		 * Next, find the controller of that type corresponding to
10101.11Schopps		 * the adaptor number.
10111.11Schopps		 */
10121.11Schopps		for (ac = amiga_cinit; ac->amiga_driver; ac++)
10131.11Schopps			if (ac->amiga_alive && ac->amiga_unit == adaptor &&
10141.11Schopps			    ac->amiga_driver == ad->amiga_cdriver)
10151.11Schopps				goto found_it;
10161.11Schopps	}
10171.3Smw
10181.11Schopps	/* could also place after test, but I'd like to be on the safe side */
10191.3Smwfound_it:
10201.11Schopps	if (ad->amiga_driver == 0) {
10211.3Smw#ifdef DEBUG
10221.11Schopps		if (acdebug > 1)
10231.11Schopps			printf("returning due to: amiga_driver == 0\n");
10241.3Smw#endif
10251.11Schopps		return;
10261.11Schopps	}
10271.3Smw
10281.1Smw	/*
10291.1Smw	 * Finally, find the device in question attached to that controller.
10301.1Smw	 */
10311.1Smw	for (ad = amiga_dinit; ad->amiga_driver; ad++)
10321.1Smw		if (ad->amiga_alive && ad->amiga_slave == unit &&
10331.1Smw		    ad->amiga_cdriver == ac->amiga_driver &&
10341.1Smw		    ad->amiga_ctlr == ac->amiga_unit)
10351.1Smw			break;
10361.11Schopps	if (ad->amiga_driver == 0) {
10371.3Smw#ifdef DEBUG
10381.11Schopps		if (acdebug > 1)
10391.11Schopps			printf("returning due to: no device\n");
10401.3Smw#endif
10411.11Schopps		return;
10421.11Schopps	}
10431.1Smw	mindev = ad->amiga_unit;
10441.11Schopps
10451.1Smw	/*
10461.1Smw	 * Form a new rootdev
10471.1Smw	 */
10481.1Smw	mindev = (mindev << PARTITIONSHIFT) + part;
10491.1Smw	orootdev = rootdev;
10501.1Smw	rootdev = makedev(majdev, mindev);
10511.11Schopps
10521.1Smw	/*
10531.1Smw	 * If the original rootdev is the same as the one
10541.1Smw	 * just calculated, don't need to adjust the swap configuration.
10551.1Smw	 */
10561.11Schopps	if (rootdev == orootdev) {
10571.3Smw#ifdef DEBUG
10581.11Schopps		if (acdebug > 1)
10591.11Schopps			printf("returning due to: new root == old root\n");
10601.3Smw#endif
10611.11Schopps		return;
10621.11Schopps	}
10631.1Smw
10641.1Smw	printf("Changing root device to %c%c%d%c\n",
10651.1Smw		devname[majdev][0], devname[majdev][1],
10661.1Smw		mindev >> PARTITIONSHIFT, part + 'a');
10671.1Smw
10681.1Smw#ifdef DOSWAP
10691.1Smw	mindev &= ~PARTITIONMASK;
10701.1Smw	for (swp = swdevt; swp->sw_dev; swp++) {
10711.1Smw		if (majdev == major(swp->sw_dev) &&
10721.1Smw		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
10731.1Smw			temp = swdevt[0].sw_dev;
10741.1Smw			swdevt[0].sw_dev = swp->sw_dev;
10751.1Smw			swp->sw_dev = temp;
10761.1Smw			break;
10771.1Smw		}
10781.1Smw	}
10791.1Smw	if (swp->sw_dev == 0)
10801.1Smw		return;
10811.1Smw
10821.1Smw	/*
10831.1Smw	 * If dumpdev was the same as the old primary swap
10841.1Smw	 * device, move it to the new primary swap device.
10851.1Smw	 */
10861.1Smw	if (temp == dumpdev)
10871.1Smw		dumpdev = swdevt[0].sw_dev;
10881.1Smw#endif
10891.3Smw}
10901.3Smw
10911.11Schopps/*
10921.11Schopps * Try to determine, of this machine is an A3000, which has a builtin
10931.11Schopps * realtime clock and scsi controller, so that this hardware is only
10941.11Schopps * included as "configured" if this IS an A3000
10951.11Schopps */
10961.5Smw
10971.5Smwint a3000_flag = 1;		/* patchable */
10981.5Smw#ifdef A4000
10991.5Smwint a4000_flag = 1;		/* patchable - default to A4000 */
11001.5Smw#else
11011.5Smwint a4000_flag = 0;		/* patchable */
11021.5Smw#endif
11031.5Smw
11041.3Smwint
11051.11Schoppsis_a3000()
11061.3Smw{
11071.11Schopps	/* this is a dirty kludge.. but how do you do this RIGHT ? :-) */
11081.11Schopps	extern long orig_fastram_start;
11091.11Schopps	extern int num_ConfigDev;
11101.11Schopps	extern struct ConfigDev *ConfigDev;
11111.11Schopps	short sc;
11121.11Schopps	struct ConfigDev *cd;
11131.11Schopps
11141.11Schopps	/* where is fastram on the A4000 ?? */
11151.11Schopps	/* if fastram is below 0x07000000, assume it's not an A3000 */
11161.11Schopps	if (orig_fastram_start < 0x07000000)
11171.11Schopps		return (0);
11181.11Schopps
11191.11Schopps	/*
11201.11Schopps	 * OK, fastram starts at or above 0x07000000, check specific
11211.11Schopps	 * machines
11221.11Schopps	 */
11231.11Schopps	for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++) {
11241.11Schopps		switch (cd->cd_Rom.er_Manufacturer) {
11251.11Schopps		case MANUF_PPI:		/* Progressive Peripherals, Inc */
11261.11Schopps			switch (cd->cd_Rom.er_Product) {
11271.11Schopps			case PROD_PPI_MERCURY:	/* PPI Mercury - A3000 */
11281.11Schopps			case PROD_PPI_A3000_040:/* PP&S A3000 '040 */
11291.11Schopps				return (1);
11301.11Schopps			case PROD_PPI_ZEUS:	/* PPI Zeus - it's an A2000 */
11311.11Schopps			case PROD_PPI_A2000_040:/* PP&S A2000 '040 */
11321.11Schopps			case PROD_PPI_A500_040:	/* PP&S A500 '040 */
11331.11Schopps				return (0);
11341.11Schopps			}
11351.11Schopps			break;
11361.3Smw
11371.11Schopps		case MANUF_IVS:			/* IVS */
11381.11Schopps			switch (cd->cd_Rom.er_Product) {
11391.11Schopps			case PROD_IVS_VECTOR_ACC:
11401.11Schopps				return (0); /* A2000 accelerator? */
11411.11Schopps			}
11421.11Schopps			break;
11431.11Schopps		}
11441.11Schopps	}
11451.11Schopps	/* XXX assume it's an A3000 */
11461.11Schopps	return (a3000_flag);
11471.5Smw}
11481.5Smw
11491.5Smwint
11501.11Schoppsis_a4000()
11511.5Smw{
11521.11Schopps	return (a4000_flag);		/* XXX */
11531.1Smw}
1154