autoconf.c revision 1.10
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.10Schopps *	$Id: autoconf.c,v 1.10 1994/02/28 06:05:44 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.3Smw/* tests whether the address lies in our zorro2 space */
861.3Smw#define iszorro2kva(kva) ((u_int)kva >= (u_int)ZORRO2ADDR && (u_int)kva < ((u_int)ZORRO2ADDR+(u_int)ZORRO2TOP-(u_int)ZORRO2BASE))
871.3Smw#define iszorro2pa(pa) ((u_int)pa >= ZORRO2BASE && (u_int)pa <= ZORRO2TOP)
881.3Smw
891.1Smw#ifdef DEBUG
901.1Smwint	acdebug = 0;
911.1Smw#endif
921.1Smw
931.1Smw/*
941.1Smw * Determine mass storage and memory configuration for a machine.
951.1Smw */
961.1Smwconfigure()
971.1Smw{
981.1Smw	register struct amiga_hw *hw;
991.1Smw	int found;
1001.3Smw
1011.3Smw	/* XXXX I HATE IT XXXX */
1021.3Smw	custom.intena = INTF_INTEN;
1031.1Smw
1041.1Smw	/*
1051.1Smw	 * Look over each hardware device actually found and attempt
1061.1Smw	 * to match it with an ioconf.c table entry.
1071.1Smw	 */
1081.1Smw	for (hw = sc_table; hw->hw_type; hw++) {
1091.1Smw		if (HW_ISCTLR(hw))
1101.1Smw			found = find_controller(hw);
1111.1Smw		else
1121.1Smw			found = find_device(hw);
1131.1Smw#ifdef DEBUG
1141.1Smw		if (!found && acdebug) {
1151.1Smw			printf("unconfigured device %d/%d\n",
1161.1Smw			       hw->hw_manufacturer, hw->hw_product);
1171.1Smw		}
1181.1Smw#endif
1191.1Smw	}
1201.1Smw
1211.1Smw#if 0
1221.1Smw#include "cd.h"
1231.1Smw#if NCD > 0
1241.1Smw	/*
1251.1Smw	 * Now deal with concatenated disks
1261.1Smw	 */
1271.1Smw	find_cdevices();
1281.1Smw#endif
1291.1Smw#endif
1301.1Smw
1311.1Smw#if GENERIC
1321.1Smw	if ((boothowto & RB_ASKNAME) == 0)
1331.1Smw		setroot();
1341.1Smw	setconf();
1351.1Smw#else
1361.1Smw	setroot();
1371.1Smw#endif
1381.1Smw	swapconf();
1391.1Smw	cold = 0;
1401.3Smw
1411.3Smw	custom.intena = INTF_SETCLR | INTF_INTEN;
1421.1Smw}
1431.1Smw
1441.1Smw#define dr_type(d, s)	\
1451.1Smw	(strcmp((d)->d_name, (s)) == 0)
1461.1Smw
1471.1Smw#define same_hw_ctlr(hw, ac) \
1481.1Smw	(HW_ISFLOPPY(hw) && dr_type((ac)->amiga_driver, "floppy") || \
1491.5Smw	 HW_ISSCSI(hw) && (dr_type((ac)->amiga_driver, "a3000scsi") \
1501.5Smw	 || dr_type((ac)->amiga_driver, "a2091scsi") \
1511.5Smw	 || dr_type((ac)->amiga_driver, "GVPIIscsi") \
1521.5Smw	 || dr_type((ac)->amiga_driver, "Zeusscsi") \
1531.10Schopps	 || dr_type((ac)->amiga_driver, "Magnumscsi") \
1541.10Schopps	 || dr_type((ac)->amiga_driver, "Mlhscsi") \
1551.10Schopps	 || dr_type((ac)->amiga_driver, "Csa12gscsi") \
1561.10Schopps	 || dr_type((ac)->amiga_driver, "Suprascsi") \
1571.10Schopps	 || dr_type((ac)->amiga_driver, "IVSscsi")))
1581.1Smw
1591.1Smwfind_controller(hw)
1601.1Smw	register struct amiga_hw *hw;
1611.1Smw{
1621.1Smw	register struct amiga_ctlr *ac;
1631.1Smw	struct amiga_ctlr *match_c;
1641.1Smw	caddr_t oaddr;
1651.1Smw	int sc;
1661.1Smw
1671.1Smw#ifdef DEBUG
1681.1Smw	if (acdebug)
1691.1Smw		printf("find_controller: hw: [%d/%d] (%x), type %x...",
1701.1Smw		       hw->hw_manufacturer, hw->hw_product,
1711.1Smw		       hw->hw_kva, hw->hw_type);
1721.1Smw#endif
1731.1Smw	sc = (hw->hw_manufacturer << 16) | hw->hw_product;
1741.1Smw	match_c = NULL;
1751.1Smw	for (ac = amiga_cinit; ac->amiga_driver; ac++) {
1761.1Smw		if (ac->amiga_alive)
1771.1Smw			continue;
1781.1Smw		/*
1791.1Smw		 * Make sure we are looking at the right
1801.1Smw		 * controller type.
1811.1Smw		 */
1821.1Smw		if (!same_hw_ctlr(hw, ac))
1831.1Smw			continue;
1841.1Smw		/*
1851.1Smw		 * Exact match; all done
1861.1Smw		 */
1871.1Smw		if ((int)ac->amiga_addr == sc) {
1881.1Smw			match_c = ac;
1891.1Smw			break;
1901.1Smw		}
1911.1Smw		/*
1921.1Smw		 * Wildcard; possible match so remember first instance
1931.1Smw		 * but continue looking for exact match.
1941.1Smw		 */
1951.1Smw		if (ac->amiga_addr == NULL && match_c == NULL)
1961.1Smw			match_c = ac;
1971.1Smw	}
1981.1Smw#ifdef DEBUG
1991.1Smw	if (acdebug) {
2001.1Smw		if (match_c)
2011.1Smw			printf("found %s%d\n",
2021.1Smw			       match_c->amiga_driver->d_name,
2031.1Smw			       match_c->amiga_unit);
2041.1Smw		else
2051.1Smw			printf("not found\n");
2061.1Smw	}
2071.1Smw#endif
2081.1Smw	/*
2091.1Smw	 * Didn't find an ioconf entry for this piece of hardware,
2101.1Smw	 * just ignore it.
2111.1Smw	 */
2121.1Smw	if (match_c == NULL)
2131.1Smw		return(0);
2141.1Smw	/*
2151.1Smw	 * Found a match, attempt to initialize and configure all attached
2161.1Smw	 * slaves.  Note, we can still fail if HW won't initialize.
2171.1Smw	 */
2181.1Smw	ac = match_c;
2191.1Smw	oaddr = ac->amiga_addr;
2201.1Smw	ac->amiga_addr = hw->hw_kva;
2211.1Smw	if ((*ac->amiga_driver->d_init)(ac)) {
2221.1Smw		ac->amiga_alive = 1;
2231.1Smw		printf ("%s%d", ac->amiga_driver->d_name, ac->amiga_unit);
2241.1Smw		printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product);
2251.1Smw		if (ac->amiga_flags)
2261.1Smw			printf(", flags 0x%x", ac->amiga_flags);
2271.1Smw		printf("\n");
2281.1Smw		find_slaves(ac);
2291.1Smw	} else
2301.1Smw		ac->amiga_addr = oaddr;
2311.1Smw	return(1);
2321.1Smw}
2331.1Smw
2341.1Smwfind_device(hw)
2351.1Smw	register struct amiga_hw *hw;
2361.1Smw{
2371.1Smw	register struct amiga_device *ad;
2381.1Smw	struct amiga_device *match_d;
2391.1Smw	caddr_t oaddr;
2401.1Smw	int sc;
2411.1Smw
2421.1Smw#ifdef DEBUG
2431.1Smw	if (acdebug)
2441.1Smw		printf("find_device: hw: [%d/%d] (%x), type %x...",
2451.1Smw		       hw->hw_manufacturer, hw->hw_product,
2461.1Smw		       hw->hw_kva, hw->hw_type);
2471.1Smw#endif
2481.1Smw	match_d = NULL;
2491.1Smw	for (ad = amiga_dinit; ad->amiga_driver; ad++) {
2501.1Smw		if (ad->amiga_alive)
2511.1Smw			continue;
2521.1Smw		/* Must not be a slave */
2531.1Smw		if (ad->amiga_cdriver)
2541.1Smw			continue;
2551.1Smw
2561.3Smw		/*
2571.3Smw		 * XXX: A graphics device that was found as part of the
2581.3Smw		 * console init will have the amiga_addr field already set
2591.3Smw		 * (i.e. no longer the select code).  Gotta perform a
2601.3Smw		 * slightly different check for an exact match.
2611.3Smw		 */
2621.3Smw		if (HW_ISDEV(hw, D_BITMAP) && iszorro2kva(ad->amiga_addr))
2631.3Smw		  {
2641.3Smw		    if (ad->amiga_addr == hw->hw_kva)
2651.3Smw		      {
2661.3Smw		        match_d = ad;
2671.3Smw		        break;
2681.3Smw		      }
2691.3Smw		    continue;
2701.3Smw		  }
2711.1Smw		sc = (int) ad->amiga_addr;
2721.1Smw		/*
2731.1Smw		 * Exact match; all done.
2741.1Smw		 */
2751.1Smw		if (sc > 0 && sc == ((hw->hw_manufacturer << 16) | hw->hw_product)) {
2761.1Smw			match_d = ad;
2771.1Smw			break;
2781.1Smw		}
2791.1Smw		/*
2801.1Smw		 * Wildcard; possible match so remember first instance
2811.1Smw		 * but continue looking for exact match.
2821.1Smw		 */
2831.1Smw		if (sc == 0 && same_hw_device(hw, ad) && match_d == NULL)
2841.1Smw			match_d = ad;
2851.1Smw	}
2861.1Smw#ifdef DEBUG
2871.1Smw	if (acdebug) {
2881.1Smw		if (match_d)
2891.1Smw			printf("found %s%d\n",
2901.1Smw			       match_d->amiga_driver->d_name,
2911.1Smw			       match_d->amiga_unit);
2921.1Smw		else
2931.1Smw			printf("not found\n");
2941.1Smw	}
2951.1Smw#endif
2961.1Smw	/*
2971.1Smw	 * Didn't find an ioconf entry for this piece
2981.1Smw	 * of hardware, just ignore it.
2991.1Smw	 */
3001.1Smw	if (match_d == NULL)
3011.1Smw		return(0);
3021.1Smw	/*
3031.1Smw	 * Found a match, attempt to initialize.
3041.1Smw	 * Note, we can still fail if HW won't initialize.
3051.1Smw	 */
3061.1Smw	ad = match_d;
3071.1Smw	oaddr = ad->amiga_addr;
3081.1Smw	ad->amiga_addr = hw->hw_kva;
3091.3Smw	ad->amiga_serno = hw->hw_serno;
3101.3Smw	ad->amiga_size = hw->hw_size;
3111.1Smw	if ((*ad->amiga_driver->d_init)(ad)) {
3121.1Smw		ad->amiga_alive = 1;
3131.1Smw		printf("%s%d", ad->amiga_driver->d_name, ad->amiga_unit);
3141.1Smw		printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product);
3151.1Smw		if (ad->amiga_flags)
3161.1Smw			printf(", flags 0x%x", ad->amiga_flags);
3171.1Smw		printf("\n");
3181.1Smw	} else
3191.1Smw		ad->amiga_addr = oaddr;
3201.1Smw	return(1);
3211.1Smw}
3221.1Smw
3231.1Smwfind_slaves(ac)
3241.1Smw	struct amiga_ctlr *ac;
3251.1Smw{
3261.1Smw	if (dr_type(ac->amiga_driver, "floppy"))
3271.1Smw		find_busslaves(ac, 4);
3281.5Smw	else if (dr_type(ac->amiga_driver, "a3000scsi")
3291.5Smw            || dr_type(ac->amiga_driver, "a2091scsi")
3301.5Smw	    || dr_type(ac->amiga_driver, "GVPIIscsi")
3311.5Smw	    || dr_type(ac->amiga_driver, "Zeusscsi")
3321.10Schopps	    || dr_type(ac->amiga_driver, "Magnumscsi")
3331.10Schopps	    || dr_type(ac->amiga_driver, "Mlhscsi")
3341.10Schopps	    || dr_type(ac->amiga_driver, "Csa12gscsi")
3351.10Schopps	    || dr_type(ac->amiga_driver, "Suprascsi")
3361.10Schopps	    || dr_type(ac->amiga_driver, "IVSscsi"))
3371.1Smw		find_busslaves(ac, 7);
3381.1Smw}
3391.1Smw
3401.1Smw/*
3411.1Smw */
3421.1Smwfind_busslaves(ac, maxslaves)
3431.1Smw	register struct amiga_ctlr *ac;
3441.1Smw	int maxslaves;
3451.1Smw{
3461.1Smw	register int s;
3471.1Smw	register struct amiga_device *ad;
3481.1Smw	struct amiga_device *match_s;
3491.1Smw	int new_s, new_c, old_s, old_c;
3501.1Smw	int rescan;
3511.1Smw
3521.1Smw#ifdef DEBUG
3531.1Smw	if (acdebug)
3541.1Smw		printf("find_busslaves: for %s%d\n",
3551.1Smw		       ac->amiga_driver->d_name, ac->amiga_unit);
3561.1Smw#endif
3571.1Smw	for (s = 0; s < maxslaves; s++) {
3581.1Smw		rescan = 1;
3591.1Smw		match_s = NULL;
3601.1Smw		for (ad = amiga_dinit; ad->amiga_driver; ad++) {
3611.1Smw			/*
3621.1Smw			 * Rule out the easy ones:
3631.1Smw			 * 1. slave already assigned or not a slave
3641.1Smw			 * 2. not of the proper type
3651.1Smw			 * 3. controller specified but not this one
3661.1Smw			 * 4. slave specified but not this one
3671.1Smw			 */
3681.1Smw			if (ad->amiga_alive || ad->amiga_cdriver == NULL)
3691.1Smw				continue;
3701.1Smw			if (!dr_type(ac->amiga_driver, ad->amiga_cdriver->d_name))
3711.1Smw				continue;
3721.1Smw			if (ad->amiga_ctlr >= 0 && ad->amiga_ctlr != ac->amiga_unit)
3731.1Smw				continue;
3741.1Smw			if (ad->amiga_slave >= 0 && ad->amiga_slave != s)
3751.1Smw				continue;
3761.1Smw			/*
3771.1Smw			 * Case 0: first possible match.
3781.1Smw			 * Remember it and keep looking for better.
3791.1Smw			 */
3801.1Smw			if (match_s == NULL) {
3811.1Smw				match_s = ad;
3821.1Smw				new_c = ac->amiga_unit;
3831.1Smw				new_s = s;
3841.1Smw				continue;
3851.1Smw			}
3861.1Smw			/*
3871.1Smw			 * Case 1: exact match.
3881.1Smw			 * All done.  Note that we do not attempt any other
3891.1Smw			 * matches if this one fails.  This allows us to
3901.1Smw			 * "reserve" locations for dynamic addition of
3911.1Smw			 * disk/tape drives by fully qualifing the location.
3921.1Smw			 */
3931.1Smw			if (ad->amiga_slave == s && ad->amiga_ctlr == ac->amiga_unit) {
3941.1Smw				match_s = ad;
3951.1Smw				rescan = 0;
3961.1Smw				break;
3971.1Smw			}
3981.1Smw			/*
3991.1Smw			 * Case 2: right controller, wildcarded slave.
4001.1Smw			 * Remember first and keep looking for an exact match.
4011.1Smw			 */
4021.1Smw			if (ad->amiga_ctlr == ac->amiga_unit &&
4031.1Smw			    match_s->amiga_ctlr < 0) {
4041.1Smw				match_s = ad;
4051.1Smw				new_s = s;
4061.1Smw				continue;
4071.1Smw			}
4081.1Smw			/*
4091.1Smw			 * Case 3: right slave, wildcarded controller.
4101.1Smw			 * Remember and keep looking for a better match.
4111.1Smw			 */
4121.1Smw			if (ad->amiga_slave == s &&
4131.1Smw			    match_s->amiga_ctlr < 0 && match_s->amiga_slave < 0) {
4141.1Smw				match_s = ad;
4151.1Smw				new_c = ac->amiga_unit;
4161.1Smw				continue;
4171.1Smw			}
4181.1Smw			/*
4191.1Smw			 * OW: we had a totally wildcarded spec.
4201.1Smw			 * If we got this far, we have found a possible
4211.1Smw			 * match already (match_s != NULL) so there is no
4221.1Smw			 * reason to remember this one.
4231.1Smw			 */
4241.1Smw			continue;
4251.1Smw		}
4261.1Smw		/*
4271.1Smw		 * Found a match.  We need to set amiga_ctlr/amiga_slave properly
4281.1Smw		 * for the init routines but we also need to remember all
4291.1Smw		 * the old values in case this doesn't pan out.
4301.1Smw		 */
4311.1Smw		if (match_s) {
4321.1Smw			ad = match_s;
4331.1Smw			old_c = ad->amiga_ctlr;
4341.1Smw			old_s = ad->amiga_slave;
4351.1Smw			if (ad->amiga_ctlr < 0)
4361.1Smw				ad->amiga_ctlr = new_c;
4371.1Smw			if (ad->amiga_slave < 0)
4381.1Smw				ad->amiga_slave = new_s;
4391.1Smw#ifdef DEBUG
4401.1Smw			if (acdebug)
4411.1Smw				printf("looking for %s%d at slave %d...",
4421.1Smw				       ad->amiga_driver->d_name,
4431.1Smw				       ad->amiga_unit, ad->amiga_slave);
4441.1Smw#endif
4451.1Smw
4461.1Smw			if ((*ad->amiga_driver->d_init)(ad)) {
4471.1Smw#ifdef DEBUG
4481.1Smw				if (acdebug)
4491.1Smw					printf("found\n");
4501.1Smw#endif
4511.1Smw				printf("%s%d at %s%d, slave %d",
4521.1Smw				       ad->amiga_driver->d_name, ad->amiga_unit,
4531.1Smw				       ac->amiga_driver->d_name, ad->amiga_ctlr,
4541.1Smw				       ad->amiga_slave);
4551.1Smw				if (ad->amiga_flags)
4561.1Smw					printf(" flags 0x%x", ad->amiga_flags);
4571.1Smw				printf("\n");
4581.1Smw				ad->amiga_alive = 1;
4591.1Smw				if (ad->amiga_dk && dkn < DK_NDRIVE)
4601.1Smw					ad->amiga_dk = dkn++;
4611.1Smw				else
4621.1Smw					ad->amiga_dk = -1;
4631.1Smw				rescan = 1;
4641.7Schopps				/*
4651.7Schopps				 * The init on this unit suceeded, so we need to
4661.7Schopps				 * mark the same device/unit on other hardware
4671.7Schopps				 * controllers as "alive" since we can't reuse
4681.7Schopps				 * the same unit for that device driver. mlh
4691.7Schopps				 */
4701.7Schopps				for (ad = amiga_dinit; ad->amiga_driver; ad++) {
4711.7Schopps					if (ad->amiga_driver == match_s->amiga_driver &&
4721.7Schopps					    ad->amiga_unit == match_s->amiga_unit)
4731.7Schopps						ad->amiga_alive = 2;
4741.7Schopps				}
4751.1Smw			} else {
4761.1Smw#ifdef DEBUG
4771.1Smw				if (acdebug)
4781.1Smw					printf("not found\n");
4791.1Smw#endif
4801.1Smw				ad->amiga_ctlr = old_c;
4811.1Smw				ad->amiga_slave = old_s;
4821.1Smw			}
4831.1Smw			/*
4841.1Smw			 * XXX: This should be handled better.
4851.1Smw			 * Re-scan a slave.  There are two reasons to do this.
4861.1Smw			 * 1. It is possible to have both a tape and disk
4871.1Smw			 *    (e.g. 7946) or two disks (e.g. 9122) at the
4881.1Smw			 *    same slave address.  Here we need to rescan
4891.1Smw			 *    looking only at entries with a different
4901.1Smw			 *    physical unit number (amiga_flags).
4911.1Smw			 * 2. It is possible that an init failed because the
4921.1Smw			 *    slave was there but of the wrong type.  In this
4931.1Smw			 *    case it may still be possible to match the slave
4941.1Smw			 *    to another ioconf entry of a different type.
4951.1Smw			 *    Here we need to rescan looking only at entries
4961.1Smw			 *    of different types.
4971.1Smw			 * In both cases we avoid looking at undesirable
4981.1Smw			 * ioconf entries of the same type by setting their
4991.1Smw			 * alive fields to -1.
5001.1Smw			 */
5011.1Smw			if (rescan) {
5021.1Smw				for (ad = amiga_dinit; ad->amiga_driver; ad++) {
5031.1Smw					if (ad->amiga_alive)
5041.1Smw						continue;
5051.1Smw					if (match_s->amiga_alive == 1) {	/* 1 */
5061.1Smw						if (ad->amiga_flags == match_s->amiga_flags)
5071.1Smw							ad->amiga_alive = -1;
5081.1Smw					} else {			/* 2 */
5091.1Smw						if (ad->amiga_driver == match_s->amiga_driver)
5101.1Smw							ad->amiga_alive = -1;
5111.1Smw					}
5121.1Smw				}
5131.1Smw				s--;
5141.1Smw				continue;
5151.1Smw			}
5161.1Smw		}
5171.1Smw		/*
5181.1Smw		 * Reset bogon alive fields prior to attempting next slave
5191.1Smw		 */
5201.1Smw		for (ad = amiga_dinit; ad->amiga_driver; ad++)
5211.1Smw			if (ad->amiga_alive == -1)
5221.1Smw				ad->amiga_alive = 0;
5231.1Smw	}
5241.1Smw}
5251.1Smw
5261.1Smwsame_hw_device(hw, ad)
5271.1Smw	struct amiga_hw *hw;
5281.1Smw	struct amiga_device *ad;
5291.1Smw{
5301.1Smw	int found = 0;
5311.1Smw
5321.1Smw	switch (hw->hw_type & ~B_MASK) {
5331.1Smw	case C_FLOPPY:
5341.1Smw		found = dr_type(ad->amiga_driver, "floppy");
5351.1Smw		break;
5361.1Smw	case C_SCSI:
5371.3Smw		found = (dr_type(ad->amiga_driver, "a3000scsi")
5381.3Smw			 || dr_type(ad->amiga_driver, "a2091scsi")
5391.5Smw			 || dr_type(ad->amiga_driver, "GVPIIscsi")
5401.5Smw			 || dr_type(ad->amiga_driver, "Zeusscsi")
5411.10Schopps			 || dr_type(ad->amiga_driver, "Magnumscsi")
5421.10Schopps			 || dr_type(ad->amiga_driver, "Mlhscsi")
5431.10Schopps			 || dr_type(ad->amiga_driver, "Csa12gscsi")
5441.10Schopps			 || dr_type(ad->amiga_driver, "Suprascsi")
5451.10Schopps			 || dr_type(ad->amiga_driver, "IVSscsi"));
5461.1Smw		break;
5471.1Smw	case D_BITMAP:
5481.1Smw		found = dr_type(ad->amiga_driver, "grf");
5491.1Smw		break;
5501.1Smw	case D_LAN:
5511.1Smw		found = dr_type(ad->amiga_driver, "le");
5521.1Smw		break;
5531.1Smw	case D_COMMSER:
5541.1Smw		found = dr_type(ad->amiga_driver, "ser");
5551.1Smw		break;
5561.3Smw	case D_CLOCK:
5571.3Smw		found = dr_type(ad->amiga_driver, "rtclock");
5581.4Smw		break;
5591.4Smw	case D_PPORT:
5601.4Smw		found = dr_type(ad->amiga_driver, "par");
5611.3Smw		break;
5621.1Smw	default:
5631.1Smw		break;
5641.1Smw	}
5651.1Smw	return(found);
5661.1Smw}
5671.1Smw
5681.1Smwchar notmappedmsg[] = "WARNING: no space to map IO card, ignored\n";
5691.1Smw
5701.1Smw/*
5711.1Smw * Scan the IO space looking for devices.
5721.1Smw */
5731.1Smwfind_devs()
5741.1Smw{
5751.1Smw  short sc;
5761.1Smw  u_char *id_reg;
5771.1Smw  register caddr_t addr;
5781.1Smw  register struct amiga_hw *hw;
5791.1Smw  int didmap, sctop;
5801.1Smw  extern int num_ConfigDev;
5811.1Smw  extern struct ConfigDev *ConfigDev;
5821.1Smw  struct ConfigDev *cd;
5831.1Smw
5841.1Smw#if 0
5851.1Smw  /*
5861.1Smw   * Initialize IO resource map for iomap().
5871.1Smw   */
5881.1Smw  rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);
5891.1Smw#endif
5901.1Smw  hw = sc_table;
5911.1Smw
5921.1Smw  /* first enter builtin devices */
5931.1Smw
5941.5Smw  if (is_a4000 ())
5951.5Smw    {
5961.5Smw      /* The A4000 appears to use the same realtime clock as the A3000.
5971.5Smw         Add the IDE controller when that information becomes available.
5981.5Smw	 */
5991.5Smw
6001.6Schopps      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
6011.5Smw      hw->hw_size	  = NBPG;
6021.5Smw      hw->hw_kva	  = zorro2map (0xdc0000);
6031.5Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6041.5Smw      hw->hw_product      = PROD_BUILTIN_CLOCK;
6051.5Smw      hw->hw_type	  = B_BUILTIN | D_CLOCK;
6061.5Smw      hw->hw_serno	  = 0;
6071.5Smw      hw++;
6081.5Smw    }
6091.5Smw  else if (is_a3000 ())
6101.3Smw    {
6111.3Smw      /* hm, this doesn't belong here... */
6121.3Smw      volatile u_char *magic_reset_reg = zorro2map (0xde0002);
6131.3Smw      /* this bit makes the next reset look like a powerup reset, Amiga
6141.3Smw	 Unix sets this bit, and perhaps it will enable 16M machines to
6151.3Smw	 boot again... */
6161.3Smw      *magic_reset_reg   |= 0x80;
6171.3Smw
6181.6Schopps      hw->hw_pa		  = (caddr_t) 0xdd0000;
6191.3Smw      hw->hw_size	  = NBPG;
6201.3Smw      hw->hw_kva	  = zorro2map (0xdd0000);
6211.3Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6221.3Smw      hw->hw_product      = PROD_BUILTIN_SCSI;
6231.3Smw      hw->hw_type	  = B_BUILTIN | C_SCSI;
6241.3Smw      hw->hw_serno	  = 0;
6251.3Smw      hw++;
6261.1Smw
6271.6Schopps      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
6281.3Smw      hw->hw_size	  = NBPG;
6291.3Smw      hw->hw_kva	  = zorro2map (0xdc0000);
6301.3Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6311.3Smw      hw->hw_product      = PROD_BUILTIN_CLOCK;
6321.3Smw      hw->hw_type	  = B_BUILTIN | D_CLOCK;
6331.3Smw      hw->hw_serno	  = 0;
6341.3Smw      hw++;
6351.3Smw    }
6361.3Smw  else
6371.3Smw    {
6381.3Smw      /* what about other Amigas? Oh well.. */
6391.6Schopps      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
6401.3Smw      hw->hw_size	  = NBPG;
6411.3Smw      hw->hw_kva	  = zorro2map (0xdc0000);
6421.3Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6431.3Smw      hw->hw_product      = PROD_BUILTIN_CLOCK2;
6441.3Smw      hw->hw_type	  = B_BUILTIN | D_CLOCK;
6451.3Smw      hw->hw_serno	  = 0;
6461.3Smw      hw++;
6471.3Smw    }
6481.1Smw
6491.1Smw  hw->hw_pa	      = 0;
6501.1Smw  hw->hw_size	      = 0;
6511.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6521.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6531.1Smw  hw->hw_product      = PROD_BUILTIN_FLOPPY;
6541.1Smw  hw->hw_type	      = B_BUILTIN | C_FLOPPY;
6551.3Smw  hw->hw_serno	      = 0;
6561.1Smw  hw++;
6571.1Smw
6581.1Smw  hw->hw_pa	      = 0;
6591.1Smw  hw->hw_size	      = 0;
6601.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6611.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6621.1Smw  hw->hw_product      = PROD_BUILTIN_KEYBOARD;
6631.1Smw  hw->hw_type	      = B_BUILTIN | D_KEYBOARD;
6641.3Smw  hw->hw_serno	      = 0;
6651.1Smw  hw++;
6661.1Smw
6671.1Smw  hw->hw_pa	      = 0;
6681.1Smw  hw->hw_size	      = 0;
6691.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6701.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6711.1Smw  hw->hw_product      = PROD_BUILTIN_PPORT;
6721.1Smw  hw->hw_type	      = B_BUILTIN | D_PPORT;
6731.3Smw  hw->hw_serno	      = 0;
6741.1Smw  hw++;
6751.1Smw
6761.1Smw  hw->hw_pa	      = 0;
6771.1Smw  hw->hw_size	      = 0;
6781.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6791.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6801.1Smw  hw->hw_product      = PROD_BUILTIN_DISPLAY;
6811.1Smw  hw->hw_type	      = B_BUILTIN | D_BITMAP;
6821.3Smw  hw->hw_serno	      = 0;
6831.3Smw  hw++;
6841.3Smw
6851.3Smw  hw->hw_pa	      = 0;
6861.3Smw  hw->hw_size	      = 0;
6871.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6881.3Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6891.3Smw  hw->hw_product      = PROD_BUILTIN_RS232;
6901.3Smw  hw->hw_type	      = B_BUILTIN | D_COMMSER;
6911.3Smw  hw->hw_serno	      = 0;
6921.1Smw  hw++;
6931.3Smw
6941.1Smw  /* and afterwards add Zorro II/III devices passed by the loader */
6951.1Smw
6961.1Smw  for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++)
6971.1Smw    {
6981.1Smw      hw->hw_pa		  = cd->cd_BoardAddr;
6991.1Smw      hw->hw_size	  = cd->cd_BoardSize;
7001.3Smw      /* ADD ZORRO3 SUPPORT HERE !! */
7011.3Smw      hw->hw_kva	  = iszorro2pa(cd->cd_BoardAddr) ? zorro2map (cd->cd_BoardAddr) : 0;
7021.1Smw      hw->hw_manufacturer = cd->cd_Rom.er_Manufacturer;
7031.1Smw      hw->hw_product	  = cd->cd_Rom.er_Product;
7041.3Smw      hw->hw_serno	  = cd->cd_Rom.er_SerialNumber;
7051.1Smw
7061.1Smw      switch (hw->hw_manufacturer)
7071.1Smw        {
7081.1Smw        case MANUF_CBM_1:
7091.1Smw          switch (hw->hw_product)
7101.1Smw            {
7111.1Smw            case PROD_CBM_1_A2088:
7121.1Smw              hw->hw_type = B_ZORROII | D_MISC;
7131.1Smw              break;
7141.1Smw
7151.1Smw            default:
7161.1Smw              continue;
7171.1Smw            }
7181.3Smw          break;
7191.3Smw
7201.3Smw	case MANUF_CBM_2:
7211.3Smw	  switch (hw->hw_product)
7221.3Smw	    {
7231.3Smw	    case PROD_CBM_2_A2091:
7241.3Smw	      hw->hw_type = B_ZORROII | C_SCSI;
7251.3Smw	      break;
7261.3Smw
7271.3Smw	    case PROD_CBM_2_A2065:
7281.3Smw	      hw->hw_type = B_ZORROII | D_LAN;
7291.3Smw              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
7301.3Smw                 whether Commodore or Ameristar board. */
7311.3Smw              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x01000000;
7321.3Smw	      break;
7331.3Smw
7341.3Smw	    default:
7351.3Smw	      continue;
7361.3Smw	    }
7371.3Smw	  break;
7381.3Smw
7391.3Smw	case MANUF_AMERISTAR:
7401.3Smw	  switch (hw->hw_product)
7411.3Smw	    {
7421.3Smw	    case PROD_AMERISTAR_ETHER:
7431.3Smw	      hw->hw_type = B_ZORROII | D_LAN;
7441.3Smw              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
7451.3Smw                 whether Commodore or Ameristar board. */
7461.3Smw              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x02000000;
7471.3Smw	      break;
7481.3Smw
7491.3Smw	    default:
7501.3Smw	      continue;
7511.3Smw	    }
7521.3Smw	  break;
7531.3Smw
7541.1Smw        case MANUF_UNILOWELL:
7551.1Smw          switch (hw->hw_product)
7561.1Smw            {
7571.1Smw            case PROD_UNILOWELL_A2410:
7581.1Smw              hw->hw_type = B_ZORROII | D_BITMAP;
7591.1Smw              break;
7601.1Smw
7611.1Smw            default:
7621.1Smw              continue;
7631.1Smw            }
7641.3Smw          break;
7651.3Smw
7661.3Smw	case MANUF_MACROSYSTEM:
7671.3Smw	  switch (hw->hw_product)
7681.3Smw	    {
7691.3Smw	    case PROD_MACROSYSTEM_RETINA:
7701.3Smw	      hw->hw_type = B_ZORROII | D_BITMAP;
7711.3Smw	      break;
7721.3Smw
7731.3Smw	    default:
7741.3Smw	      continue;
7751.3Smw	    }
7761.3Smw	  break;
7771.3Smw
7781.3Smw	case MANUF_GVP:
7791.3Smw	  switch (hw->hw_product)
7801.3Smw	    {
7811.10Schopps	    case PROD_GVP_SERIES_I:
7821.10Schopps	      /* XXX need to pass product code to driver */
7831.10Schopps	      hw->hw_type = B_ZORROII | C_SCSI;
7841.10Schopps	      break;
7851.10Schopps
7861.3Smw	    case PROD_GVP_SERIES_II:
7871.10Schopps	      /* Figure out what kind of board this is */
7881.10Schopps	      id_reg = (u_char *)hw->hw_kva + 0x8001;
7891.10Schopps	      switch (*id_reg & 0xf8)
7901.10Schopps		{
7911.10Schopps		case PROD_GVP_X_GF40_SCSI:
7921.10Schopps		case PROD_GVP_X_COMBO4_SCSI:
7931.10Schopps		case PROD_GVP_X_GF30_SCSI:
7941.10Schopps		case PROD_GVP_X_COMBO3_SCSI:
7951.10Schopps		case PROD_GVP_X_SCSI_II:
7961.10Schopps		  hw->hw_type = B_ZORROII | C_SCSI;
7971.10Schopps		  break;
7981.10Schopps		case PROD_GVP_X_IOEXTEND:
7991.10Schopps		  hw->hw_type = B_ZORROII | D_COMMSER;
8001.10Schopps		  break;
8011.10Schopps		}
8021.3Smw	      break;
8031.3Smw
8041.3Smw	    case PROD_GVP_IV24:
8051.3Smw	      hw->hw_type = B_ZORROII | D_BITMAP;
8061.3Smw	      break;
8071.3Smw
8081.3Smw	    default:
8091.3Smw	      continue;
8101.3Smw	    }
8111.3Smw	  break;
8121.3Smw
8131.5Smw	case MANUF_PPI:
8141.5Smw	  switch (hw->hw_product)
8151.5Smw	    {
8161.5Smw	    case PROD_PPI_ZEUS:
8171.5Smw	      hw->hw_type = B_ZORROII | C_SCSI;
8181.5Smw	      break;
8191.5Smw
8201.5Smw	    default:
8211.5Smw	      continue;
8221.5Smw	    }
8231.5Smw	  break;
8241.5Smw
8251.5Smw	case MANUF_CSA:
8261.5Smw	  switch (hw->hw_product)
8271.5Smw	    {
8281.5Smw	    case PROD_CSA_MAGNUM:
8291.10Schopps	    case PROD_CSA_12G:
8301.10Schopps	      hw->hw_type = B_ZORROII | C_SCSI;
8311.10Schopps	      break;
8321.10Schopps
8331.10Schopps	    default:
8341.10Schopps	      continue;
8351.10Schopps	    }
8361.10Schopps	  break;
8371.10Schopps
8381.10Schopps	case MANUF_SUPRA:
8391.10Schopps	  switch (hw->hw_product)
8401.10Schopps	    {
8411.10Schopps	    /* XXXX need to distinguish different controllers with a single driver */
8421.10Schopps	    case PROD_SUPRA_WORDSYNC_2:
8431.10Schopps	      hw->hw_type = B_ZORROII | C_SCSI;
8441.10Schopps	      break;
8451.10Schopps
8461.10Schopps	    default:
8471.10Schopps	      continue;
8481.10Schopps	    }
8491.10Schopps	  break;
8501.10Schopps
8511.10Schopps	case MANUF_IVS:
8521.10Schopps	  switch (hw->hw_product)
8531.10Schopps	    {
8541.10Schopps	    /* XXXX need to distinguish different controllers with a single driver */
8551.10Schopps	    case PROD_IVS_VECTOR:
8561.10Schopps	      /* XXXX Ouch! board addresss isn't Zorro II or Zorro III! */
8571.10Schopps	      {
8581.10Schopps		if (pmap_extract(zorro2map(0x00f00000)) == 0x00f00000) {
8591.10Schopps		  /* remap to Vector pa */
8601.10Schopps		}
8611.10Schopps	      }
8621.10Schopps	      hw->hw_type = B_ZORROII | C_SCSI;
8631.10Schopps	      break;
8641.10Schopps
8651.10Schopps	    default:
8661.10Schopps	      continue;
8671.10Schopps	    }
8681.10Schopps	  break;
8691.10Schopps
8701.10Schopps	case MANUF_HACKER:
8711.10Schopps	  switch (hw->hw_product)
8721.10Schopps	    {
8731.10Schopps	    case PROD_HACKER_MLH:
8741.5Smw	      hw->hw_type = B_ZORROII | C_SCSI;
8751.5Smw	      break;
8761.5Smw
8771.5Smw	    default:
8781.5Smw	      continue;
8791.5Smw	    }
8801.5Smw	  break;
8811.5Smw
8821.1Smw        default:
8831.1Smw          continue;
8841.1Smw	}
8851.1Smw
8861.1Smw      hw++;
8871.1Smw    }
8881.1Smw}
8891.1Smw
8901.1Smw#if 0
8911.1Smw/*
8921.1Smw * Allocate/deallocate a cache-inhibited range of kernel virtual address
8931.1Smw * space mapping the indicated physical address range [pa - pa+size)
8941.1Smw */
8951.1Smwcaddr_t
8961.1Smwiomap(pa, size)
8971.1Smw	caddr_t pa;
8981.1Smw	int size;
8991.1Smw{
9001.1Smw	int ix, npf;
9011.1Smw	caddr_t kva;
9021.1Smw
9031.1Smw#ifdef DEBUG
9041.1Smw	if (((int)pa & PGOFSET) || (size & PGOFSET))
9051.1Smw		panic("iomap: unaligned");
9061.1Smw#endif
9071.1Smw	npf = btoc(size);
9081.1Smw	ix = rmalloc(extiomap, npf);
9091.1Smw	if (ix == 0)
9101.1Smw		return(0);
9111.1Smw	kva = extiobase + ctob(ix-1);
9121.1Smw	physaccess(kva, pa, size, PG_RW|PG_CI);
9131.1Smw	return(kva);
9141.1Smw}
9151.1Smw
9161.1Smwiounmap(kva, size)
9171.1Smw	caddr_t kva;
9181.1Smw	int size;
9191.1Smw{
9201.1Smw	int ix;
9211.1Smw
9221.1Smw#ifdef DEBUG
9231.1Smw	if (((int)kva & PGOFSET) || (size & PGOFSET))
9241.1Smw		panic("iounmap: unaligned");
9251.1Smw	if (kva < extiobase || kva >= extiobase + ctob(EIOMAPSIZE))
9261.1Smw		panic("iounmap: bad address");
9271.1Smw#endif
9281.1Smw	physunaccess(kva, size);
9291.1Smw	ix = btoc(kva - extiobase) + 1;
9301.1Smw	rmfree(extiomap, btoc(size), ix);
9311.1Smw}
9321.1Smw#endif
9331.1Smw
9341.1Smw#if NCD > 0
9351.9Schopps#include <amiga/dev/cdvar.h>
9361.1Smw
9371.1Smwfind_cdevices()
9381.1Smw{
9391.1Smw	register struct cddevice *cd;
9401.1Smw
9411.1Smw	for (cd = cddevice; cd->cd_unit >= 0; cd++) {
9421.1Smw		/*
9431.1Smw		 * XXX
9441.1Smw		 * Assign disk index first so that init routine
9451.1Smw		 * can use it (saves having the driver drag around
9461.1Smw		 * the cddevice pointer just to set up the dk_*
9471.1Smw		 * info in the open routine).
9481.1Smw		 */
9491.1Smw		if (dkn < DK_NDRIVE)
9501.1Smw			cd->cd_dk = dkn++;
9511.1Smw		else
9521.1Smw			cd->cd_dk = -1;
9531.1Smw		if (cdinit(cd))
9541.1Smw			printf("cd%d configured\n", cd->cd_unit);
9551.1Smw		else if (cd->cd_dk >= 0) {
9561.1Smw			cd->cd_dk = -1;
9571.1Smw			dkn--;
9581.1Smw		}
9591.1Smw	}
9601.1Smw}
9611.1Smw#endif
9621.1Smw
9631.1Smw#if 0
9641.1Smwisrinit()
9651.1Smw{
9661.1Smw	register int i;
9671.1Smw
9681.1Smw	for (i = 0; i < NISR; i++)
9691.1Smw		isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i];
9701.1Smw}
9711.1Smw
9721.1Smwvoid
9731.1Smwisrlink(isr)
9741.1Smw	register struct isr *isr;
9751.1Smw{
9761.1Smw	int i = ISRIPL(isr->isr_ipl);
9771.1Smw
9781.1Smw	if (i < 0 || i >= NISR) {
9791.1Smw		printf("bad IPL %d\n", i);
9801.1Smw		panic("configure");
9811.1Smw	}
9821.1Smw	insque(isr, isrqueue[i].isr_back);
9831.1Smw}
9841.1Smw#endif
9851.1Smw
9861.1Smw/*
9871.1Smw * Configure swap space and related parameters.
9881.1Smw */
9891.1Smwswapconf()
9901.1Smw{
9911.1Smw	register struct swdevt *swp;
9921.1Smw	register int nblks;
9931.1Smw
9941.1Smw	for (swp = swdevt; swp->sw_dev; swp++)
9951.1Smw	  {
9961.1Smw		if (bdevsw[major(swp->sw_dev)].d_psize) {
9971.1Smw			nblks =
9981.1Smw			  (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
9991.1Smw			if (nblks != -1 &&
10001.1Smw			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
10011.1Smw			      {
10021.1Smw				swp->sw_nblks = nblks;
10031.1Smw/*				printf ("swap: dev %x = %d\n", swp->sw_dev, nblks);*/
10041.1Smw			      }
10051.1Smw		}
10061.1Smw	  }
10071.1Smw	dumpconf();
10081.1Smw
10091.1Smw	printf ("\n");
10101.1Smw}
10111.1Smw
10121.1Smw#define	DOSWAP			/* Change swdevt and dumpdev too */
10131.1Smwu_long	bootdev;		/* should be dev_t, but not until 32 bits */
10141.1Smw
10151.1Smwstatic	char devname[][2] = {
10161.1Smw	0,0,		/* 0 = ct */
10171.1Smw	0,0,		/* 1 = xx */
10181.1Smw	'r','d',	/* 2 = rd */
10191.1Smw	0,0,		/* 3 = sw */
10201.1Smw	's','d',	/* 4 = sd */
10211.1Smw};
10221.1Smw
10231.1Smw#define	PARTITIONMASK	0x7
10241.1Smw#define	PARTITIONSHIFT	3
10251.1Smw
10261.1Smw/*
10271.1Smw * Attempt to find the device from which we were booted.
10281.1Smw * If we can do so, and not instructed not to do so,
10291.1Smw * change rootdev to correspond to the load device.
10301.1Smw */
10311.1Smwsetroot()
10321.1Smw{
10331.1Smw	register struct amiga_ctlr *ac;
10341.1Smw	register struct amiga_device *ad;
10351.1Smw	int  majdev, mindev, unit, part, adaptor;
10361.1Smw	dev_t temp, orootdev;
10371.1Smw	struct swdevt *swp;
10381.1Smw
10391.3Smw#ifdef DEBUG
10401.3Smw	if (acdebug > 1)
10411.3Smw	  printf ("setroot: boothowto = 0x%x, bootdev = 0x%x\n", boothowto, bootdev);
10421.3Smw#endif
10431.1Smw
10441.1Smw	if (boothowto & RB_DFLTROOT ||
10451.1Smw	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
10461.3Smw	  {
10471.3Smw#ifdef DEBUG
10481.3Smw	    if (acdebug > 1)
10491.3Smw	      printf ("returning due to: bad boothowto\n");
10501.3Smw#endif
10511.3Smw	    return;
10521.3Smw	  }
10531.1Smw	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
10541.1Smw	if (majdev > sizeof(devname) / sizeof(devname[0]))
10551.3Smw	  {
10561.3Smw#ifdef DEBUG
10571.3Smw	    if (acdebug > 1)
10581.3Smw	      printf ("returning due to: majdev (%d) > maxdevs (%d)\n",
10591.3Smw		      majdev, sizeof(devname) / sizeof(devname[0]));
10601.3Smw#endif
10611.3Smw	    return;
10621.3Smw	  }
10631.1Smw	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
10641.1Smw	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
10651.1Smw	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
10661.3Smw
10671.3Smw	/* First, find the controller type which support this device.
10681.3Smw
10691.3Smw	   Can have more than one controller for the same device, with
10701.3Smw	   just one of them configured, so test for ad->amiga_cdriver != 0
10711.3Smw	   too.  */
10721.3Smw
10731.1Smw	for (ad = amiga_dinit; ad->amiga_driver; ad++)
10741.3Smw	  {
10751.3Smw	    if (ad->amiga_driver->d_name[0] != devname[majdev][0]
10761.3Smw		|| ad->amiga_driver->d_name[1] != devname[majdev][1])
10771.3Smw	      continue;
10781.3Smw
10791.3Smw	    /*
10801.3Smw	     * Next, find the controller of that type corresponding to
10811.3Smw	     * the adaptor number.
10821.3Smw	     */
10831.3Smw	    for (ac = amiga_cinit; ac->amiga_driver; ac++)
10841.3Smw	      if (ac->amiga_alive && ac->amiga_unit == adaptor &&
10851.3Smw		  ac->amiga_driver == ad->amiga_cdriver)
10861.3Smw		goto found_it;
10871.3Smw	  }
10881.3Smw
10891.3Smw/* could also place after test, but I'd like to be on the safe side */
10901.3Smwfound_it:
10911.1Smw	if (ad->amiga_driver == 0)
10921.3Smw	  {
10931.3Smw#ifdef DEBUG
10941.3Smw	    if (acdebug > 1)
10951.3Smw	      printf ("returning due to: amiga_driver == 0\n");
10961.3Smw#endif
10971.3Smw	    return;
10981.3Smw	  }
10991.3Smw
11001.1Smw	/*
11011.1Smw	 * Finally, find the device in question attached to that controller.
11021.1Smw	 */
11031.1Smw	for (ad = amiga_dinit; ad->amiga_driver; ad++)
11041.1Smw		if (ad->amiga_alive && ad->amiga_slave == unit &&
11051.1Smw		    ad->amiga_cdriver == ac->amiga_driver &&
11061.1Smw		    ad->amiga_ctlr == ac->amiga_unit)
11071.1Smw			break;
11081.1Smw	if (ad->amiga_driver == 0)
11091.3Smw	  {
11101.3Smw#ifdef DEBUG
11111.3Smw	    if (acdebug > 1)
11121.3Smw	      printf ("returning due to: no device\n");
11131.3Smw#endif
11141.3Smw	    return;
11151.3Smw	  }
11161.1Smw	mindev = ad->amiga_unit;
11171.1Smw	/*
11181.1Smw	 * Form a new rootdev
11191.1Smw	 */
11201.1Smw	mindev = (mindev << PARTITIONSHIFT) + part;
11211.1Smw	orootdev = rootdev;
11221.1Smw	rootdev = makedev(majdev, mindev);
11231.1Smw	/*
11241.1Smw	 * If the original rootdev is the same as the one
11251.1Smw	 * just calculated, don't need to adjust the swap configuration.
11261.1Smw	 */
11271.1Smw	if (rootdev == orootdev)
11281.3Smw	  {
11291.3Smw#ifdef DEBUG
11301.3Smw	    if (acdebug > 1)
11311.3Smw	      printf ("returning due to: new root == old root\n");
11321.3Smw#endif
11331.3Smw	    return;
11341.3Smw	  }
11351.3Smw
11361.3Smw
11371.1Smw
11381.1Smw	printf("Changing root device to %c%c%d%c\n",
11391.1Smw		devname[majdev][0], devname[majdev][1],
11401.1Smw		mindev >> PARTITIONSHIFT, part + 'a');
11411.1Smw
11421.1Smw#ifdef DOSWAP
11431.1Smw	mindev &= ~PARTITIONMASK;
11441.1Smw	for (swp = swdevt; swp->sw_dev; swp++) {
11451.1Smw		if (majdev == major(swp->sw_dev) &&
11461.1Smw		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
11471.1Smw			temp = swdevt[0].sw_dev;
11481.1Smw			swdevt[0].sw_dev = swp->sw_dev;
11491.1Smw			swp->sw_dev = temp;
11501.1Smw			break;
11511.1Smw		}
11521.1Smw	}
11531.1Smw	if (swp->sw_dev == 0)
11541.1Smw		return;
11551.1Smw
11561.1Smw	/*
11571.1Smw	 * If dumpdev was the same as the old primary swap
11581.1Smw	 * device, move it to the new primary swap device.
11591.1Smw	 */
11601.1Smw	if (temp == dumpdev)
11611.1Smw		dumpdev = swdevt[0].sw_dev;
11621.1Smw#endif
11631.3Smw}
11641.3Smw
11651.3Smw/* try to determine, of this machine is an A3000, which has a builtin
11661.3Smw   realtime clock and scsi controller, so that this hardware is only
11671.3Smw   included as "configured" if this IS an A3000  */
11681.5Smw
11691.5Smwint a3000_flag = 1;		/* patchable */
11701.5Smw#ifdef A4000
11711.5Smwint a4000_flag = 1;		/* patchable - default to A4000 */
11721.5Smw#else
11731.5Smwint a4000_flag = 0;		/* patchable */
11741.5Smw#endif
11751.5Smw
11761.3Smwint
11771.3Smwis_a3000 ()
11781.3Smw{
11791.3Smw  /* this is a dirty kludge.. but how do you do this RIGHT ? :-) */
11801.3Smw  extern long orig_fastram_start;
11811.5Smw  short sc;
11821.5Smw  extern int num_ConfigDev;
11831.5Smw  extern struct ConfigDev *ConfigDev;
11841.5Smw  struct ConfigDev *cd;
11851.3Smw
11861.3Smw  /* where is fastram on the A4000 ?? */
11871.5Smw  /* if fastram is below 0x07000000, assume it's not an A3000 */
11881.5Smw  if (orig_fastram_start < 0x07000000)
11891.5Smw    return (0);
11901.5Smw
11911.5Smw  /* OK, fastram starts at or above 0x07000000, check specific machines */
11921.5Smw  for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++) {
11931.5Smw    switch (cd->cd_Rom.er_Manufacturer) {
11941.5Smw    case MANUF_PPI:			/* Progressive Peripherals, Inc */
11951.5Smw      switch (cd->cd_Rom.er_Product) {
11961.10Schopps      case PROD_PPI_MERCURY:		/* PPI Mercury - it's an A3000 */
11971.10Schopps      case PROD_PPI_A3000_040:		/* PP&S A3000 '040 */
11981.5Smw        return (1);
11991.10Schopps      case PROD_PPI_ZEUS:		/* PPI Zeus - it's an A2000 */
12001.10Schopps      case PROD_PPI_A2000_040:		/* PP&S A2000 '040 */
12011.10Schopps      case PROD_PPI_A500_040:		/* PP&S A500 '040 */
12021.5Smw        return (0);
12031.5Smw      }
12041.10Schopps      break;
12051.10Schopps
12061.10Schopps    case MANUF_IVS:			/* IVS */
12071.10Schopps      switch (cd->cd_Rom.er_Product) {
12081.10Schopps      case PROD_IVS_VECTOR_ACC:
12091.10Schopps	return (0);			/* Is this an A2000 accelerator? */
12101.10Schopps      }
12111.10Schopps      break;
12121.5Smw    }
12131.5Smw  }
12141.5Smw  /* assume it's an A3000 */
12151.5Smw  return (a3000_flag);
12161.5Smw}
12171.5Smw
12181.5Smwint
12191.5Smwis_a4000 ()
12201.5Smw{
12211.5Smw  /* This is a real dirty kludge.. */
12221.5Smw  return (a4000_flag);
12231.1Smw}
1224