autoconf.c revision 1.7
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.1Smw */
421.1Smw
431.1Smw/*
441.1Smw * Setup the system to run on the current machine.
451.1Smw *
461.1Smw * Configure() is called at boot time.  Available
471.1Smw * devices are determined (from possibilities mentioned in ioconf.c),
481.1Smw * and the drivers are initialized.
491.1Smw */
501.1Smw
511.1Smw#include "sys/param.h"
521.1Smw#include "sys/systm.h"
531.1Smw#include "sys/buf.h"
541.1Smw#include "sys/dkstat.h"
551.1Smw#include "sys/conf.h"
561.1Smw#include "sys/dmap.h"
571.1Smw#include "sys/reboot.h"
581.1Smw
591.1Smw#include "machine/vmparam.h"
601.1Smw#include "machine/cpu.h"
611.1Smw#include "pte.h"
621.1Smw#include "../dev/device.h"
631.1Smw
641.3Smw#include "configdev.h"
651.3Smw#include "custom.h"
661.1Smw
671.1Smw/*
681.1Smw * The following several variables are related to
691.1Smw * the configuration process, and are used in initializing
701.1Smw * the machine.
711.1Smw */
721.1Smwint	cold;		    /* if 1, still working on cold-start */
731.1Smwint	dkn;		    /* number of iostat dk numbers assigned so far */
741.1Smwint	cpuspeed = MHZ_8;   /* relative cpu speed */
751.1Smwstruct	amiga_hw sc_table[MAXCTLRS];
761.1Smw
771.3Smw/* set up in amiga_init.c */
781.3Smwextern caddr_t ZORRO2ADDR;
791.3Smw
801.3Smw/* maps a zorro2 and/or A3000 builtin address into the mapped kva address */
811.3Smw#define zorro2map(pa) ((caddr_t) ((u_int)ZORRO2ADDR - ZORRO2BASE + (u_int)pa))
821.3Smw/* tests whether the address lies in our zorro2 space */
831.3Smw#define iszorro2kva(kva) ((u_int)kva >= (u_int)ZORRO2ADDR && (u_int)kva < ((u_int)ZORRO2ADDR+(u_int)ZORRO2TOP-(u_int)ZORRO2BASE))
841.3Smw#define iszorro2pa(pa) ((u_int)pa >= ZORRO2BASE && (u_int)pa <= ZORRO2TOP)
851.3Smw
861.1Smw#ifdef DEBUG
871.1Smwint	acdebug = 0;
881.1Smw#endif
891.1Smw
901.1Smw/*
911.1Smw * Determine mass storage and memory configuration for a machine.
921.1Smw */
931.1Smwconfigure()
941.1Smw{
951.1Smw	register struct amiga_hw *hw;
961.1Smw	int found;
971.3Smw
981.3Smw	/* XXXX I HATE IT XXXX */
991.3Smw	custom.intena = INTF_INTEN;
1001.1Smw
1011.1Smw	/*
1021.1Smw	 * Look over each hardware device actually found and attempt
1031.1Smw	 * to match it with an ioconf.c table entry.
1041.1Smw	 */
1051.1Smw	for (hw = sc_table; hw->hw_type; hw++) {
1061.1Smw		if (HW_ISCTLR(hw))
1071.1Smw			found = find_controller(hw);
1081.1Smw		else
1091.1Smw			found = find_device(hw);
1101.1Smw#ifdef DEBUG
1111.1Smw		if (!found && acdebug) {
1121.1Smw			printf("unconfigured device %d/%d\n",
1131.1Smw			       hw->hw_manufacturer, hw->hw_product);
1141.1Smw		}
1151.1Smw#endif
1161.1Smw	}
1171.1Smw
1181.1Smw#if 0
1191.1Smw#include "cd.h"
1201.1Smw#if NCD > 0
1211.1Smw	/*
1221.1Smw	 * Now deal with concatenated disks
1231.1Smw	 */
1241.1Smw	find_cdevices();
1251.1Smw#endif
1261.1Smw#endif
1271.1Smw
1281.1Smw#if GENERIC
1291.1Smw	if ((boothowto & RB_ASKNAME) == 0)
1301.1Smw		setroot();
1311.1Smw	setconf();
1321.1Smw#else
1331.1Smw	setroot();
1341.1Smw#endif
1351.1Smw	swapconf();
1361.1Smw	cold = 0;
1371.3Smw
1381.3Smw	custom.intena = INTF_SETCLR | INTF_INTEN;
1391.1Smw}
1401.1Smw
1411.1Smw#define dr_type(d, s)	\
1421.1Smw	(strcmp((d)->d_name, (s)) == 0)
1431.1Smw
1441.1Smw#define same_hw_ctlr(hw, ac) \
1451.1Smw	(HW_ISFLOPPY(hw) && dr_type((ac)->amiga_driver, "floppy") || \
1461.5Smw	 HW_ISSCSI(hw) && (dr_type((ac)->amiga_driver, "a3000scsi") \
1471.5Smw	 || dr_type((ac)->amiga_driver, "a2091scsi") \
1481.5Smw	 || dr_type((ac)->amiga_driver, "GVPIIscsi") \
1491.5Smw	 || dr_type((ac)->amiga_driver, "Zeusscsi") \
1501.5Smw	 || dr_type((ac)->amiga_driver, "Magnumscsi")))
1511.1Smw
1521.1Smwfind_controller(hw)
1531.1Smw	register struct amiga_hw *hw;
1541.1Smw{
1551.1Smw	register struct amiga_ctlr *ac;
1561.1Smw	struct amiga_ctlr *match_c;
1571.1Smw	caddr_t oaddr;
1581.1Smw	int sc;
1591.1Smw
1601.1Smw#ifdef DEBUG
1611.1Smw	if (acdebug)
1621.1Smw		printf("find_controller: hw: [%d/%d] (%x), type %x...",
1631.1Smw		       hw->hw_manufacturer, hw->hw_product,
1641.1Smw		       hw->hw_kva, hw->hw_type);
1651.1Smw#endif
1661.1Smw	sc = (hw->hw_manufacturer << 16) | hw->hw_product;
1671.1Smw	match_c = NULL;
1681.1Smw	for (ac = amiga_cinit; ac->amiga_driver; ac++) {
1691.1Smw		if (ac->amiga_alive)
1701.1Smw			continue;
1711.1Smw		/*
1721.1Smw		 * Make sure we are looking at the right
1731.1Smw		 * controller type.
1741.1Smw		 */
1751.1Smw		if (!same_hw_ctlr(hw, ac))
1761.1Smw			continue;
1771.1Smw		/*
1781.1Smw		 * Exact match; all done
1791.1Smw		 */
1801.1Smw		if ((int)ac->amiga_addr == sc) {
1811.1Smw			match_c = ac;
1821.1Smw			break;
1831.1Smw		}
1841.1Smw		/*
1851.1Smw		 * Wildcard; possible match so remember first instance
1861.1Smw		 * but continue looking for exact match.
1871.1Smw		 */
1881.1Smw		if (ac->amiga_addr == NULL && match_c == NULL)
1891.1Smw			match_c = ac;
1901.1Smw	}
1911.1Smw#ifdef DEBUG
1921.1Smw	if (acdebug) {
1931.1Smw		if (match_c)
1941.1Smw			printf("found %s%d\n",
1951.1Smw			       match_c->amiga_driver->d_name,
1961.1Smw			       match_c->amiga_unit);
1971.1Smw		else
1981.1Smw			printf("not found\n");
1991.1Smw	}
2001.1Smw#endif
2011.1Smw	/*
2021.1Smw	 * Didn't find an ioconf entry for this piece of hardware,
2031.1Smw	 * just ignore it.
2041.1Smw	 */
2051.1Smw	if (match_c == NULL)
2061.1Smw		return(0);
2071.1Smw	/*
2081.1Smw	 * Found a match, attempt to initialize and configure all attached
2091.1Smw	 * slaves.  Note, we can still fail if HW won't initialize.
2101.1Smw	 */
2111.1Smw	ac = match_c;
2121.1Smw	oaddr = ac->amiga_addr;
2131.1Smw	ac->amiga_addr = hw->hw_kva;
2141.1Smw	if ((*ac->amiga_driver->d_init)(ac)) {
2151.1Smw		ac->amiga_alive = 1;
2161.1Smw		printf ("%s%d", ac->amiga_driver->d_name, ac->amiga_unit);
2171.1Smw		printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product);
2181.1Smw		if (ac->amiga_flags)
2191.1Smw			printf(", flags 0x%x", ac->amiga_flags);
2201.1Smw		printf("\n");
2211.1Smw		find_slaves(ac);
2221.1Smw	} else
2231.1Smw		ac->amiga_addr = oaddr;
2241.1Smw	return(1);
2251.1Smw}
2261.1Smw
2271.1Smwfind_device(hw)
2281.1Smw	register struct amiga_hw *hw;
2291.1Smw{
2301.1Smw	register struct amiga_device *ad;
2311.1Smw	struct amiga_device *match_d;
2321.1Smw	caddr_t oaddr;
2331.1Smw	int sc;
2341.1Smw
2351.1Smw#ifdef DEBUG
2361.1Smw	if (acdebug)
2371.1Smw		printf("find_device: hw: [%d/%d] (%x), type %x...",
2381.1Smw		       hw->hw_manufacturer, hw->hw_product,
2391.1Smw		       hw->hw_kva, hw->hw_type);
2401.1Smw#endif
2411.1Smw	match_d = NULL;
2421.1Smw	for (ad = amiga_dinit; ad->amiga_driver; ad++) {
2431.1Smw		if (ad->amiga_alive)
2441.1Smw			continue;
2451.1Smw		/* Must not be a slave */
2461.1Smw		if (ad->amiga_cdriver)
2471.1Smw			continue;
2481.1Smw
2491.3Smw		/*
2501.3Smw		 * XXX: A graphics device that was found as part of the
2511.3Smw		 * console init will have the amiga_addr field already set
2521.3Smw		 * (i.e. no longer the select code).  Gotta perform a
2531.3Smw		 * slightly different check for an exact match.
2541.3Smw		 */
2551.3Smw		if (HW_ISDEV(hw, D_BITMAP) && iszorro2kva(ad->amiga_addr))
2561.3Smw		  {
2571.3Smw		    if (ad->amiga_addr == hw->hw_kva)
2581.3Smw		      {
2591.3Smw		        match_d = ad;
2601.3Smw		        break;
2611.3Smw		      }
2621.3Smw		    continue;
2631.3Smw		  }
2641.1Smw		sc = (int) ad->amiga_addr;
2651.1Smw		/*
2661.1Smw		 * Exact match; all done.
2671.1Smw		 */
2681.1Smw		if (sc > 0 && sc == ((hw->hw_manufacturer << 16) | hw->hw_product)) {
2691.1Smw			match_d = ad;
2701.1Smw			break;
2711.1Smw		}
2721.1Smw		/*
2731.1Smw		 * Wildcard; possible match so remember first instance
2741.1Smw		 * but continue looking for exact match.
2751.1Smw		 */
2761.1Smw		if (sc == 0 && same_hw_device(hw, ad) && match_d == NULL)
2771.1Smw			match_d = ad;
2781.1Smw	}
2791.1Smw#ifdef DEBUG
2801.1Smw	if (acdebug) {
2811.1Smw		if (match_d)
2821.1Smw			printf("found %s%d\n",
2831.1Smw			       match_d->amiga_driver->d_name,
2841.1Smw			       match_d->amiga_unit);
2851.1Smw		else
2861.1Smw			printf("not found\n");
2871.1Smw	}
2881.1Smw#endif
2891.1Smw	/*
2901.1Smw	 * Didn't find an ioconf entry for this piece
2911.1Smw	 * of hardware, just ignore it.
2921.1Smw	 */
2931.1Smw	if (match_d == NULL)
2941.1Smw		return(0);
2951.1Smw	/*
2961.1Smw	 * Found a match, attempt to initialize.
2971.1Smw	 * Note, we can still fail if HW won't initialize.
2981.1Smw	 */
2991.1Smw	ad = match_d;
3001.1Smw	oaddr = ad->amiga_addr;
3011.1Smw	ad->amiga_addr = hw->hw_kva;
3021.3Smw	ad->amiga_serno = hw->hw_serno;
3031.3Smw	ad->amiga_size = hw->hw_size;
3041.1Smw	if ((*ad->amiga_driver->d_init)(ad)) {
3051.1Smw		ad->amiga_alive = 1;
3061.1Smw		printf("%s%d", ad->amiga_driver->d_name, ad->amiga_unit);
3071.1Smw		printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product);
3081.1Smw		if (ad->amiga_flags)
3091.1Smw			printf(", flags 0x%x", ad->amiga_flags);
3101.1Smw		printf("\n");
3111.1Smw	} else
3121.1Smw		ad->amiga_addr = oaddr;
3131.1Smw	return(1);
3141.1Smw}
3151.1Smw
3161.1Smwfind_slaves(ac)
3171.1Smw	struct amiga_ctlr *ac;
3181.1Smw{
3191.1Smw	if (dr_type(ac->amiga_driver, "floppy"))
3201.1Smw		find_busslaves(ac, 4);
3211.5Smw	else if (dr_type(ac->amiga_driver, "a3000scsi")
3221.5Smw            || dr_type(ac->amiga_driver, "a2091scsi")
3231.5Smw	    || dr_type(ac->amiga_driver, "GVPIIscsi")
3241.5Smw	    || dr_type(ac->amiga_driver, "Zeusscsi")
3251.5Smw	    || dr_type(ac->amiga_driver, "Magnumscsi"))
3261.1Smw		find_busslaves(ac, 7);
3271.1Smw}
3281.1Smw
3291.1Smw/*
3301.1Smw */
3311.1Smwfind_busslaves(ac, maxslaves)
3321.1Smw	register struct amiga_ctlr *ac;
3331.1Smw	int maxslaves;
3341.1Smw{
3351.1Smw	register int s;
3361.1Smw	register struct amiga_device *ad;
3371.1Smw	struct amiga_device *match_s;
3381.1Smw	int new_s, new_c, old_s, old_c;
3391.1Smw	int rescan;
3401.1Smw
3411.1Smw#ifdef DEBUG
3421.1Smw	if (acdebug)
3431.1Smw		printf("find_busslaves: for %s%d\n",
3441.1Smw		       ac->amiga_driver->d_name, ac->amiga_unit);
3451.1Smw#endif
3461.1Smw	for (s = 0; s < maxslaves; s++) {
3471.1Smw		rescan = 1;
3481.1Smw		match_s = NULL;
3491.1Smw		for (ad = amiga_dinit; ad->amiga_driver; ad++) {
3501.1Smw			/*
3511.1Smw			 * Rule out the easy ones:
3521.1Smw			 * 1. slave already assigned or not a slave
3531.1Smw			 * 2. not of the proper type
3541.1Smw			 * 3. controller specified but not this one
3551.1Smw			 * 4. slave specified but not this one
3561.1Smw			 */
3571.1Smw			if (ad->amiga_alive || ad->amiga_cdriver == NULL)
3581.1Smw				continue;
3591.1Smw			if (!dr_type(ac->amiga_driver, ad->amiga_cdriver->d_name))
3601.1Smw				continue;
3611.1Smw			if (ad->amiga_ctlr >= 0 && ad->amiga_ctlr != ac->amiga_unit)
3621.1Smw				continue;
3631.1Smw			if (ad->amiga_slave >= 0 && ad->amiga_slave != s)
3641.1Smw				continue;
3651.1Smw			/*
3661.1Smw			 * Case 0: first possible match.
3671.1Smw			 * Remember it and keep looking for better.
3681.1Smw			 */
3691.1Smw			if (match_s == NULL) {
3701.1Smw				match_s = ad;
3711.1Smw				new_c = ac->amiga_unit;
3721.1Smw				new_s = s;
3731.1Smw				continue;
3741.1Smw			}
3751.1Smw			/*
3761.1Smw			 * Case 1: exact match.
3771.1Smw			 * All done.  Note that we do not attempt any other
3781.1Smw			 * matches if this one fails.  This allows us to
3791.1Smw			 * "reserve" locations for dynamic addition of
3801.1Smw			 * disk/tape drives by fully qualifing the location.
3811.1Smw			 */
3821.1Smw			if (ad->amiga_slave == s && ad->amiga_ctlr == ac->amiga_unit) {
3831.1Smw				match_s = ad;
3841.1Smw				rescan = 0;
3851.1Smw				break;
3861.1Smw			}
3871.1Smw			/*
3881.1Smw			 * Case 2: right controller, wildcarded slave.
3891.1Smw			 * Remember first and keep looking for an exact match.
3901.1Smw			 */
3911.1Smw			if (ad->amiga_ctlr == ac->amiga_unit &&
3921.1Smw			    match_s->amiga_ctlr < 0) {
3931.1Smw				match_s = ad;
3941.1Smw				new_s = s;
3951.1Smw				continue;
3961.1Smw			}
3971.1Smw			/*
3981.1Smw			 * Case 3: right slave, wildcarded controller.
3991.1Smw			 * Remember and keep looking for a better match.
4001.1Smw			 */
4011.1Smw			if (ad->amiga_slave == s &&
4021.1Smw			    match_s->amiga_ctlr < 0 && match_s->amiga_slave < 0) {
4031.1Smw				match_s = ad;
4041.1Smw				new_c = ac->amiga_unit;
4051.1Smw				continue;
4061.1Smw			}
4071.1Smw			/*
4081.1Smw			 * OW: we had a totally wildcarded spec.
4091.1Smw			 * If we got this far, we have found a possible
4101.1Smw			 * match already (match_s != NULL) so there is no
4111.1Smw			 * reason to remember this one.
4121.1Smw			 */
4131.1Smw			continue;
4141.1Smw		}
4151.1Smw		/*
4161.1Smw		 * Found a match.  We need to set amiga_ctlr/amiga_slave properly
4171.1Smw		 * for the init routines but we also need to remember all
4181.1Smw		 * the old values in case this doesn't pan out.
4191.1Smw		 */
4201.1Smw		if (match_s) {
4211.1Smw			ad = match_s;
4221.1Smw			old_c = ad->amiga_ctlr;
4231.1Smw			old_s = ad->amiga_slave;
4241.1Smw			if (ad->amiga_ctlr < 0)
4251.1Smw				ad->amiga_ctlr = new_c;
4261.1Smw			if (ad->amiga_slave < 0)
4271.1Smw				ad->amiga_slave = new_s;
4281.1Smw#ifdef DEBUG
4291.1Smw			if (acdebug)
4301.1Smw				printf("looking for %s%d at slave %d...",
4311.1Smw				       ad->amiga_driver->d_name,
4321.1Smw				       ad->amiga_unit, ad->amiga_slave);
4331.1Smw#endif
4341.1Smw
4351.1Smw			if ((*ad->amiga_driver->d_init)(ad)) {
4361.1Smw#ifdef DEBUG
4371.1Smw				if (acdebug)
4381.1Smw					printf("found\n");
4391.1Smw#endif
4401.1Smw				printf("%s%d at %s%d, slave %d",
4411.1Smw				       ad->amiga_driver->d_name, ad->amiga_unit,
4421.1Smw				       ac->amiga_driver->d_name, ad->amiga_ctlr,
4431.1Smw				       ad->amiga_slave);
4441.1Smw				if (ad->amiga_flags)
4451.1Smw					printf(" flags 0x%x", ad->amiga_flags);
4461.1Smw				printf("\n");
4471.1Smw				ad->amiga_alive = 1;
4481.1Smw				if (ad->amiga_dk && dkn < DK_NDRIVE)
4491.1Smw					ad->amiga_dk = dkn++;
4501.1Smw				else
4511.1Smw					ad->amiga_dk = -1;
4521.1Smw				rescan = 1;
4531.7Schopps				/*
4541.7Schopps				 * The init on this unit suceeded, so we need to
4551.7Schopps				 * mark the same device/unit on other hardware
4561.7Schopps				 * controllers as "alive" since we can't reuse
4571.7Schopps				 * the same unit for that device driver. mlh
4581.7Schopps				 */
4591.7Schopps				for (ad = amiga_dinit; ad->amiga_driver; ad++) {
4601.7Schopps					if (ad->amiga_driver == match_s->amiga_driver &&
4611.7Schopps					    ad->amiga_unit == match_s->amiga_unit)
4621.7Schopps						ad->amiga_alive = 2;
4631.7Schopps				}
4641.1Smw			} else {
4651.1Smw#ifdef DEBUG
4661.1Smw				if (acdebug)
4671.1Smw					printf("not found\n");
4681.1Smw#endif
4691.1Smw				ad->amiga_ctlr = old_c;
4701.1Smw				ad->amiga_slave = old_s;
4711.1Smw			}
4721.1Smw			/*
4731.1Smw			 * XXX: This should be handled better.
4741.1Smw			 * Re-scan a slave.  There are two reasons to do this.
4751.1Smw			 * 1. It is possible to have both a tape and disk
4761.1Smw			 *    (e.g. 7946) or two disks (e.g. 9122) at the
4771.1Smw			 *    same slave address.  Here we need to rescan
4781.1Smw			 *    looking only at entries with a different
4791.1Smw			 *    physical unit number (amiga_flags).
4801.1Smw			 * 2. It is possible that an init failed because the
4811.1Smw			 *    slave was there but of the wrong type.  In this
4821.1Smw			 *    case it may still be possible to match the slave
4831.1Smw			 *    to another ioconf entry of a different type.
4841.1Smw			 *    Here we need to rescan looking only at entries
4851.1Smw			 *    of different types.
4861.1Smw			 * In both cases we avoid looking at undesirable
4871.1Smw			 * ioconf entries of the same type by setting their
4881.1Smw			 * alive fields to -1.
4891.1Smw			 */
4901.1Smw			if (rescan) {
4911.1Smw				for (ad = amiga_dinit; ad->amiga_driver; ad++) {
4921.1Smw					if (ad->amiga_alive)
4931.1Smw						continue;
4941.1Smw					if (match_s->amiga_alive == 1) {	/* 1 */
4951.1Smw						if (ad->amiga_flags == match_s->amiga_flags)
4961.1Smw							ad->amiga_alive = -1;
4971.1Smw					} else {			/* 2 */
4981.1Smw						if (ad->amiga_driver == match_s->amiga_driver)
4991.1Smw							ad->amiga_alive = -1;
5001.1Smw					}
5011.1Smw				}
5021.1Smw				s--;
5031.1Smw				continue;
5041.1Smw			}
5051.1Smw		}
5061.1Smw		/*
5071.1Smw		 * Reset bogon alive fields prior to attempting next slave
5081.1Smw		 */
5091.1Smw		for (ad = amiga_dinit; ad->amiga_driver; ad++)
5101.1Smw			if (ad->amiga_alive == -1)
5111.1Smw				ad->amiga_alive = 0;
5121.1Smw	}
5131.1Smw}
5141.1Smw
5151.1Smwsame_hw_device(hw, ad)
5161.1Smw	struct amiga_hw *hw;
5171.1Smw	struct amiga_device *ad;
5181.1Smw{
5191.1Smw	int found = 0;
5201.1Smw
5211.1Smw	switch (hw->hw_type & ~B_MASK) {
5221.1Smw	case C_FLOPPY:
5231.1Smw		found = dr_type(ad->amiga_driver, "floppy");
5241.1Smw		break;
5251.1Smw	case C_SCSI:
5261.3Smw		found = (dr_type(ad->amiga_driver, "a3000scsi")
5271.3Smw			 || dr_type(ad->amiga_driver, "a2091scsi")
5281.5Smw			 || dr_type(ad->amiga_driver, "GVPIIscsi")
5291.5Smw			 || dr_type(ad->amiga_driver, "Zeusscsi")
5301.5Smw			 || dr_type(ad->amiga_driver, "Magnumscsi"));
5311.1Smw		break;
5321.1Smw	case D_BITMAP:
5331.1Smw		found = dr_type(ad->amiga_driver, "grf");
5341.1Smw		break;
5351.1Smw	case D_LAN:
5361.1Smw		found = dr_type(ad->amiga_driver, "le");
5371.1Smw		break;
5381.1Smw	case D_COMMSER:
5391.1Smw		found = dr_type(ad->amiga_driver, "ser");
5401.1Smw		break;
5411.3Smw	case D_CLOCK:
5421.3Smw		found = dr_type(ad->amiga_driver, "rtclock");
5431.4Smw		break;
5441.4Smw	case D_PPORT:
5451.4Smw		found = dr_type(ad->amiga_driver, "par");
5461.3Smw		break;
5471.1Smw	default:
5481.1Smw		break;
5491.1Smw	}
5501.1Smw	return(found);
5511.1Smw}
5521.1Smw
5531.1Smwchar notmappedmsg[] = "WARNING: no space to map IO card, ignored\n";
5541.1Smw
5551.1Smw/*
5561.1Smw * Scan the IO space looking for devices.
5571.1Smw */
5581.1Smwfind_devs()
5591.1Smw{
5601.1Smw  short sc;
5611.1Smw  u_char *id_reg;
5621.1Smw  register caddr_t addr;
5631.1Smw  register struct amiga_hw *hw;
5641.1Smw  int didmap, sctop;
5651.1Smw  extern int num_ConfigDev;
5661.1Smw  extern struct ConfigDev *ConfigDev;
5671.1Smw  struct ConfigDev *cd;
5681.1Smw
5691.1Smw#if 0
5701.1Smw  /*
5711.1Smw   * Initialize IO resource map for iomap().
5721.1Smw   */
5731.1Smw  rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);
5741.1Smw#endif
5751.1Smw  hw = sc_table;
5761.1Smw
5771.1Smw  /* first enter builtin devices */
5781.1Smw
5791.5Smw  if (is_a4000 ())
5801.5Smw    {
5811.5Smw      /* The A4000 appears to use the same realtime clock as the A3000.
5821.5Smw         Add the IDE controller when that information becomes available.
5831.5Smw	 */
5841.5Smw
5851.6Schopps      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
5861.5Smw      hw->hw_size	  = NBPG;
5871.5Smw      hw->hw_kva	  = zorro2map (0xdc0000);
5881.5Smw      hw->hw_manufacturer = MANUF_BUILTIN;
5891.5Smw      hw->hw_product      = PROD_BUILTIN_CLOCK;
5901.5Smw      hw->hw_type	  = B_BUILTIN | D_CLOCK;
5911.5Smw      hw->hw_serno	  = 0;
5921.5Smw      hw++;
5931.5Smw    }
5941.5Smw  else if (is_a3000 ())
5951.3Smw    {
5961.3Smw      /* hm, this doesn't belong here... */
5971.3Smw      volatile u_char *magic_reset_reg = zorro2map (0xde0002);
5981.3Smw      /* this bit makes the next reset look like a powerup reset, Amiga
5991.3Smw	 Unix sets this bit, and perhaps it will enable 16M machines to
6001.3Smw	 boot again... */
6011.3Smw      *magic_reset_reg   |= 0x80;
6021.3Smw
6031.6Schopps      hw->hw_pa		  = (caddr_t) 0xdd0000;
6041.3Smw      hw->hw_size	  = NBPG;
6051.3Smw      hw->hw_kva	  = zorro2map (0xdd0000);
6061.3Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6071.3Smw      hw->hw_product      = PROD_BUILTIN_SCSI;
6081.3Smw      hw->hw_type	  = B_BUILTIN | C_SCSI;
6091.3Smw      hw->hw_serno	  = 0;
6101.3Smw      hw++;
6111.1Smw
6121.6Schopps      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
6131.3Smw      hw->hw_size	  = NBPG;
6141.3Smw      hw->hw_kva	  = zorro2map (0xdc0000);
6151.3Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6161.3Smw      hw->hw_product      = PROD_BUILTIN_CLOCK;
6171.3Smw      hw->hw_type	  = B_BUILTIN | D_CLOCK;
6181.3Smw      hw->hw_serno	  = 0;
6191.3Smw      hw++;
6201.3Smw    }
6211.3Smw  else
6221.3Smw    {
6231.3Smw      /* what about other Amigas? Oh well.. */
6241.6Schopps      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
6251.3Smw      hw->hw_size	  = NBPG;
6261.3Smw      hw->hw_kva	  = zorro2map (0xdc0000);
6271.3Smw      hw->hw_manufacturer = MANUF_BUILTIN;
6281.3Smw      hw->hw_product      = PROD_BUILTIN_CLOCK2;
6291.3Smw      hw->hw_type	  = B_BUILTIN | D_CLOCK;
6301.3Smw      hw->hw_serno	  = 0;
6311.3Smw      hw++;
6321.3Smw    }
6331.1Smw
6341.1Smw  hw->hw_pa	      = 0;
6351.1Smw  hw->hw_size	      = 0;
6361.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6371.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6381.1Smw  hw->hw_product      = PROD_BUILTIN_FLOPPY;
6391.1Smw  hw->hw_type	      = B_BUILTIN | C_FLOPPY;
6401.3Smw  hw->hw_serno	      = 0;
6411.1Smw  hw++;
6421.1Smw
6431.1Smw  hw->hw_pa	      = 0;
6441.1Smw  hw->hw_size	      = 0;
6451.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6461.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6471.1Smw  hw->hw_product      = PROD_BUILTIN_KEYBOARD;
6481.1Smw  hw->hw_type	      = B_BUILTIN | D_KEYBOARD;
6491.3Smw  hw->hw_serno	      = 0;
6501.1Smw  hw++;
6511.1Smw
6521.1Smw  hw->hw_pa	      = 0;
6531.1Smw  hw->hw_size	      = 0;
6541.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6551.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6561.1Smw  hw->hw_product      = PROD_BUILTIN_PPORT;
6571.1Smw  hw->hw_type	      = B_BUILTIN | D_PPORT;
6581.3Smw  hw->hw_serno	      = 0;
6591.1Smw  hw++;
6601.1Smw
6611.1Smw  hw->hw_pa	      = 0;
6621.1Smw  hw->hw_size	      = 0;
6631.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6641.1Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6651.1Smw  hw->hw_product      = PROD_BUILTIN_DISPLAY;
6661.1Smw  hw->hw_type	      = B_BUILTIN | D_BITMAP;
6671.3Smw  hw->hw_serno	      = 0;
6681.3Smw  hw++;
6691.3Smw
6701.3Smw  hw->hw_pa	      = 0;
6711.3Smw  hw->hw_size	      = 0;
6721.6Schopps  hw->hw_kva	      = (caddr_t) CUSTOMbase;
6731.3Smw  hw->hw_manufacturer = MANUF_BUILTIN;
6741.3Smw  hw->hw_product      = PROD_BUILTIN_RS232;
6751.3Smw  hw->hw_type	      = B_BUILTIN | D_COMMSER;
6761.3Smw  hw->hw_serno	      = 0;
6771.1Smw  hw++;
6781.3Smw
6791.1Smw  /* and afterwards add Zorro II/III devices passed by the loader */
6801.1Smw
6811.1Smw  for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++)
6821.1Smw    {
6831.1Smw      hw->hw_pa		  = cd->cd_BoardAddr;
6841.1Smw      hw->hw_size	  = cd->cd_BoardSize;
6851.3Smw      /* ADD ZORRO3 SUPPORT HERE !! */
6861.3Smw      hw->hw_kva	  = iszorro2pa(cd->cd_BoardAddr) ? zorro2map (cd->cd_BoardAddr) : 0;
6871.1Smw      hw->hw_manufacturer = cd->cd_Rom.er_Manufacturer;
6881.1Smw      hw->hw_product	  = cd->cd_Rom.er_Product;
6891.3Smw      hw->hw_serno	  = cd->cd_Rom.er_SerialNumber;
6901.1Smw
6911.1Smw      switch (hw->hw_manufacturer)
6921.1Smw        {
6931.1Smw        case MANUF_CBM_1:
6941.1Smw          switch (hw->hw_product)
6951.1Smw            {
6961.1Smw            case PROD_CBM_1_A2088:
6971.1Smw              hw->hw_type = B_ZORROII | D_MISC;
6981.1Smw              break;
6991.1Smw
7001.1Smw            default:
7011.1Smw              continue;
7021.1Smw            }
7031.3Smw          break;
7041.3Smw
7051.3Smw	case MANUF_CBM_2:
7061.3Smw	  switch (hw->hw_product)
7071.3Smw	    {
7081.3Smw	    case PROD_CBM_2_A2091:
7091.3Smw	      hw->hw_type = B_ZORROII | C_SCSI;
7101.3Smw	      break;
7111.3Smw
7121.3Smw	    case PROD_CBM_2_A2065:
7131.3Smw	      hw->hw_type = B_ZORROII | D_LAN;
7141.3Smw              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
7151.3Smw                 whether Commodore or Ameristar board. */
7161.3Smw              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x01000000;
7171.3Smw	      break;
7181.3Smw
7191.3Smw	    default:
7201.3Smw	      continue;
7211.3Smw	    }
7221.3Smw	  break;
7231.3Smw
7241.3Smw	case MANUF_AMERISTAR:
7251.3Smw	  switch (hw->hw_product)
7261.3Smw	    {
7271.3Smw	    case PROD_AMERISTAR_ETHER:
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) | 0x02000000;
7321.3Smw	      break;
7331.3Smw
7341.3Smw	    default:
7351.3Smw	      continue;
7361.3Smw	    }
7371.3Smw	  break;
7381.3Smw
7391.1Smw        case MANUF_UNILOWELL:
7401.1Smw          switch (hw->hw_product)
7411.1Smw            {
7421.1Smw            case PROD_UNILOWELL_A2410:
7431.1Smw              hw->hw_type = B_ZORROII | D_BITMAP;
7441.1Smw              break;
7451.1Smw
7461.1Smw            default:
7471.1Smw              continue;
7481.1Smw            }
7491.3Smw          break;
7501.3Smw
7511.3Smw	case MANUF_MACROSYSTEM:
7521.3Smw	  switch (hw->hw_product)
7531.3Smw	    {
7541.3Smw	    case PROD_MACROSYSTEM_RETINA:
7551.3Smw	      hw->hw_type = B_ZORROII | D_BITMAP;
7561.3Smw	      break;
7571.3Smw
7581.3Smw	    default:
7591.3Smw	      continue;
7601.3Smw	    }
7611.3Smw	  break;
7621.3Smw
7631.3Smw	case MANUF_GVP:
7641.3Smw	  switch (hw->hw_product)
7651.3Smw	    {
7661.3Smw	    case PROD_GVP_SERIES_II:
7671.5Smw	      /* Kludge for I/O extender:
7681.5Smw		 if er_notused != 0, it's a SCSI controller
7691.5Smw		 if er_notused == 0, it's either an I/O extender or might
7701.5Smw		 possibly be a SCSI controller with autoboot disabled */
7711.5Smw	      if (cd->cd_Rom.er_notused)
7721.5Smw	        hw->hw_type = B_ZORROII | C_SCSI;
7731.5Smw	      else
7741.5Smw		hw->hw_type = B_ZORROII | D_COMMSER;
7751.3Smw	      break;
7761.3Smw
7771.3Smw	    case PROD_GVP_IV24:
7781.3Smw	      hw->hw_type = B_ZORROII | D_BITMAP;
7791.3Smw	      break;
7801.3Smw
7811.3Smw	    default:
7821.3Smw	      continue;
7831.3Smw	    }
7841.3Smw	  break;
7851.3Smw
7861.5Smw	case MANUF_PPI:
7871.5Smw	  switch (hw->hw_product)
7881.5Smw	    {
7891.5Smw	    case PROD_PPI_ZEUS:
7901.5Smw	      hw->hw_type = B_ZORROII | C_SCSI;
7911.5Smw	      break;
7921.5Smw
7931.5Smw	    default:
7941.5Smw	      continue;
7951.5Smw	    }
7961.5Smw	  break;
7971.5Smw
7981.5Smw	case MANUF_CSA:
7991.5Smw	  switch (hw->hw_product)
8001.5Smw	    {
8011.5Smw	    case PROD_CSA_MAGNUM:
8021.5Smw	      hw->hw_type = B_ZORROII | C_SCSI;
8031.5Smw	      break;
8041.5Smw
8051.5Smw	    default:
8061.5Smw	      continue;
8071.5Smw	    }
8081.5Smw	  break;
8091.5Smw
8101.1Smw        default:
8111.1Smw          continue;
8121.1Smw	}
8131.1Smw
8141.1Smw      hw++;
8151.1Smw    }
8161.1Smw}
8171.1Smw
8181.1Smw#if 0
8191.1Smw/*
8201.1Smw * Allocate/deallocate a cache-inhibited range of kernel virtual address
8211.1Smw * space mapping the indicated physical address range [pa - pa+size)
8221.1Smw */
8231.1Smwcaddr_t
8241.1Smwiomap(pa, size)
8251.1Smw	caddr_t pa;
8261.1Smw	int size;
8271.1Smw{
8281.1Smw	int ix, npf;
8291.1Smw	caddr_t kva;
8301.1Smw
8311.1Smw#ifdef DEBUG
8321.1Smw	if (((int)pa & PGOFSET) || (size & PGOFSET))
8331.1Smw		panic("iomap: unaligned");
8341.1Smw#endif
8351.1Smw	npf = btoc(size);
8361.1Smw	ix = rmalloc(extiomap, npf);
8371.1Smw	if (ix == 0)
8381.1Smw		return(0);
8391.1Smw	kva = extiobase + ctob(ix-1);
8401.1Smw	physaccess(kva, pa, size, PG_RW|PG_CI);
8411.1Smw	return(kva);
8421.1Smw}
8431.1Smw
8441.1Smwiounmap(kva, size)
8451.1Smw	caddr_t kva;
8461.1Smw	int size;
8471.1Smw{
8481.1Smw	int ix;
8491.1Smw
8501.1Smw#ifdef DEBUG
8511.1Smw	if (((int)kva & PGOFSET) || (size & PGOFSET))
8521.1Smw		panic("iounmap: unaligned");
8531.1Smw	if (kva < extiobase || kva >= extiobase + ctob(EIOMAPSIZE))
8541.1Smw		panic("iounmap: bad address");
8551.1Smw#endif
8561.1Smw	physunaccess(kva, size);
8571.1Smw	ix = btoc(kva - extiobase) + 1;
8581.1Smw	rmfree(extiomap, btoc(size), ix);
8591.1Smw}
8601.1Smw#endif
8611.1Smw
8621.1Smw#if NCD > 0
8631.1Smw#include "../dev/cdvar.h"
8641.1Smw
8651.1Smwfind_cdevices()
8661.1Smw{
8671.1Smw	register struct cddevice *cd;
8681.1Smw
8691.1Smw	for (cd = cddevice; cd->cd_unit >= 0; cd++) {
8701.1Smw		/*
8711.1Smw		 * XXX
8721.1Smw		 * Assign disk index first so that init routine
8731.1Smw		 * can use it (saves having the driver drag around
8741.1Smw		 * the cddevice pointer just to set up the dk_*
8751.1Smw		 * info in the open routine).
8761.1Smw		 */
8771.1Smw		if (dkn < DK_NDRIVE)
8781.1Smw			cd->cd_dk = dkn++;
8791.1Smw		else
8801.1Smw			cd->cd_dk = -1;
8811.1Smw		if (cdinit(cd))
8821.1Smw			printf("cd%d configured\n", cd->cd_unit);
8831.1Smw		else if (cd->cd_dk >= 0) {
8841.1Smw			cd->cd_dk = -1;
8851.1Smw			dkn--;
8861.1Smw		}
8871.1Smw	}
8881.1Smw}
8891.1Smw#endif
8901.1Smw
8911.1Smw#if 0
8921.1Smwisrinit()
8931.1Smw{
8941.1Smw	register int i;
8951.1Smw
8961.1Smw	for (i = 0; i < NISR; i++)
8971.1Smw		isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i];
8981.1Smw}
8991.1Smw
9001.1Smwvoid
9011.1Smwisrlink(isr)
9021.1Smw	register struct isr *isr;
9031.1Smw{
9041.1Smw	int i = ISRIPL(isr->isr_ipl);
9051.1Smw
9061.1Smw	if (i < 0 || i >= NISR) {
9071.1Smw		printf("bad IPL %d\n", i);
9081.1Smw		panic("configure");
9091.1Smw	}
9101.1Smw	insque(isr, isrqueue[i].isr_back);
9111.1Smw}
9121.1Smw#endif
9131.1Smw
9141.1Smw/*
9151.1Smw * Configure swap space and related parameters.
9161.1Smw */
9171.1Smwswapconf()
9181.1Smw{
9191.1Smw	register struct swdevt *swp;
9201.1Smw	register int nblks;
9211.1Smw
9221.1Smw	for (swp = swdevt; swp->sw_dev; swp++)
9231.1Smw	  {
9241.1Smw		if (bdevsw[major(swp->sw_dev)].d_psize) {
9251.1Smw			nblks =
9261.1Smw			  (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
9271.1Smw			if (nblks != -1 &&
9281.1Smw			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
9291.1Smw			      {
9301.1Smw				swp->sw_nblks = nblks;
9311.1Smw/*				printf ("swap: dev %x = %d\n", swp->sw_dev, nblks);*/
9321.1Smw			      }
9331.1Smw		}
9341.1Smw	  }
9351.1Smw	dumpconf();
9361.1Smw
9371.1Smw	printf ("\n");
9381.1Smw}
9391.1Smw
9401.1Smw#define	DOSWAP			/* Change swdevt and dumpdev too */
9411.1Smwu_long	bootdev;		/* should be dev_t, but not until 32 bits */
9421.1Smw
9431.1Smwstatic	char devname[][2] = {
9441.1Smw	0,0,		/* 0 = ct */
9451.1Smw	0,0,		/* 1 = xx */
9461.1Smw	'r','d',	/* 2 = rd */
9471.1Smw	0,0,		/* 3 = sw */
9481.1Smw	's','d',	/* 4 = sd */
9491.5Smw	'r','z',	/* 5 = sz */
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.1Smwsetroot()
9611.1Smw{
9621.1Smw	register struct amiga_ctlr *ac;
9631.1Smw	register struct amiga_device *ad;
9641.1Smw	int  majdev, mindev, unit, part, adaptor;
9651.1Smw	dev_t temp, orootdev;
9661.1Smw	struct swdevt *swp;
9671.1Smw
9681.3Smw#ifdef DEBUG
9691.3Smw	if (acdebug > 1)
9701.3Smw	  printf ("setroot: boothowto = 0x%x, bootdev = 0x%x\n", boothowto, bootdev);
9711.3Smw#endif
9721.1Smw
9731.1Smw	if (boothowto & RB_DFLTROOT ||
9741.1Smw	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
9751.3Smw	  {
9761.3Smw#ifdef DEBUG
9771.3Smw	    if (acdebug > 1)
9781.3Smw	      printf ("returning due to: bad boothowto\n");
9791.3Smw#endif
9801.3Smw	    return;
9811.3Smw	  }
9821.1Smw	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
9831.1Smw	if (majdev > sizeof(devname) / sizeof(devname[0]))
9841.3Smw	  {
9851.3Smw#ifdef DEBUG
9861.3Smw	    if (acdebug > 1)
9871.3Smw	      printf ("returning due to: majdev (%d) > maxdevs (%d)\n",
9881.3Smw		      majdev, sizeof(devname) / sizeof(devname[0]));
9891.3Smw#endif
9901.3Smw	    return;
9911.3Smw	  }
9921.1Smw	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
9931.1Smw	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
9941.1Smw	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
9951.3Smw
9961.3Smw	/* First, find the controller type which support this device.
9971.3Smw
9981.3Smw	   Can have more than one controller for the same device, with
9991.3Smw	   just one of them configured, so test for ad->amiga_cdriver != 0
10001.3Smw	   too.  */
10011.3Smw
10021.1Smw	for (ad = amiga_dinit; ad->amiga_driver; ad++)
10031.3Smw	  {
10041.3Smw	    if (ad->amiga_driver->d_name[0] != devname[majdev][0]
10051.3Smw		|| ad->amiga_driver->d_name[1] != devname[majdev][1])
10061.3Smw	      continue;
10071.3Smw
10081.3Smw	    /*
10091.3Smw	     * Next, find the controller of that type corresponding to
10101.3Smw	     * the adaptor number.
10111.3Smw	     */
10121.3Smw	    for (ac = amiga_cinit; ac->amiga_driver; ac++)
10131.3Smw	      if (ac->amiga_alive && ac->amiga_unit == adaptor &&
10141.3Smw		  ac->amiga_driver == ad->amiga_cdriver)
10151.3Smw		goto found_it;
10161.3Smw	  }
10171.3Smw
10181.3Smw/* could also place after test, but I'd like to be on the safe side */
10191.3Smwfound_it:
10201.1Smw	if (ad->amiga_driver == 0)
10211.3Smw	  {
10221.3Smw#ifdef DEBUG
10231.3Smw	    if (acdebug > 1)
10241.3Smw	      printf ("returning due to: amiga_driver == 0\n");
10251.3Smw#endif
10261.3Smw	    return;
10271.3Smw	  }
10281.3Smw
10291.1Smw	/*
10301.1Smw	 * Finally, find the device in question attached to that controller.
10311.1Smw	 */
10321.1Smw	for (ad = amiga_dinit; ad->amiga_driver; ad++)
10331.1Smw		if (ad->amiga_alive && ad->amiga_slave == unit &&
10341.1Smw		    ad->amiga_cdriver == ac->amiga_driver &&
10351.1Smw		    ad->amiga_ctlr == ac->amiga_unit)
10361.1Smw			break;
10371.1Smw	if (ad->amiga_driver == 0)
10381.3Smw	  {
10391.3Smw#ifdef DEBUG
10401.3Smw	    if (acdebug > 1)
10411.3Smw	      printf ("returning due to: no device\n");
10421.3Smw#endif
10431.3Smw	    return;
10441.3Smw	  }
10451.1Smw	mindev = ad->amiga_unit;
10461.1Smw	/*
10471.1Smw	 * Form a new rootdev
10481.1Smw	 */
10491.1Smw	mindev = (mindev << PARTITIONSHIFT) + part;
10501.1Smw	orootdev = rootdev;
10511.1Smw	rootdev = makedev(majdev, mindev);
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.1Smw	if (rootdev == orootdev)
10571.3Smw	  {
10581.3Smw#ifdef DEBUG
10591.3Smw	    if (acdebug > 1)
10601.3Smw	      printf ("returning due to: new root == old root\n");
10611.3Smw#endif
10621.3Smw	    return;
10631.3Smw	  }
10641.3Smw
10651.3Smw
10661.1Smw
10671.1Smw	printf("Changing root device to %c%c%d%c\n",
10681.1Smw		devname[majdev][0], devname[majdev][1],
10691.1Smw		mindev >> PARTITIONSHIFT, part + 'a');
10701.1Smw
10711.1Smw#ifdef DOSWAP
10721.1Smw	mindev &= ~PARTITIONMASK;
10731.1Smw	for (swp = swdevt; swp->sw_dev; swp++) {
10741.1Smw		if (majdev == major(swp->sw_dev) &&
10751.1Smw		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
10761.1Smw			temp = swdevt[0].sw_dev;
10771.1Smw			swdevt[0].sw_dev = swp->sw_dev;
10781.1Smw			swp->sw_dev = temp;
10791.1Smw			break;
10801.1Smw		}
10811.1Smw	}
10821.1Smw	if (swp->sw_dev == 0)
10831.1Smw		return;
10841.1Smw
10851.1Smw	/*
10861.1Smw	 * If dumpdev was the same as the old primary swap
10871.1Smw	 * device, move it to the new primary swap device.
10881.1Smw	 */
10891.1Smw	if (temp == dumpdev)
10901.1Smw		dumpdev = swdevt[0].sw_dev;
10911.1Smw#endif
10921.3Smw}
10931.3Smw
10941.3Smw/* try to determine, of this machine is an A3000, which has a builtin
10951.3Smw   realtime clock and scsi controller, so that this hardware is only
10961.3Smw   included as "configured" if this IS an A3000  */
10971.5Smw
10981.5Smwint a3000_flag = 1;		/* patchable */
10991.5Smw#ifdef A4000
11001.5Smwint a4000_flag = 1;		/* patchable - default to A4000 */
11011.5Smw#else
11021.5Smwint a4000_flag = 0;		/* patchable */
11031.5Smw#endif
11041.5Smw
11051.3Smwint
11061.3Smwis_a3000 ()
11071.3Smw{
11081.3Smw  /* this is a dirty kludge.. but how do you do this RIGHT ? :-) */
11091.3Smw  extern long orig_fastram_start;
11101.5Smw  short sc;
11111.5Smw  extern int num_ConfigDev;
11121.5Smw  extern struct ConfigDev *ConfigDev;
11131.5Smw  struct ConfigDev *cd;
11141.3Smw
11151.3Smw  /* where is fastram on the A4000 ?? */
11161.5Smw  /* if fastram is below 0x07000000, assume it's not an A3000 */
11171.5Smw  if (orig_fastram_start < 0x07000000)
11181.5Smw    return (0);
11191.5Smw
11201.5Smw  /* OK, fastram starts at or above 0x07000000, check specific machines */
11211.5Smw  for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++) {
11221.5Smw    switch (cd->cd_Rom.er_Manufacturer) {
11231.5Smw    case MANUF_PPI:			/* Progressive Peripherals, Inc */
11241.5Smw      switch (cd->cd_Rom.er_Product) {
11251.5Smw#if 0
11261.5Smw      case PROD_PPI_MECURY:		/* PPI Mecury - it's an A3000 */
11271.5Smw        return (1);
11281.5Smw      case PROD_PPI_2000:
11291.5Smw      case PROD_PPI_500:
11301.5Smw#endif
11311.5Smw      case PROD_PPI_ZEUS:
11321.5Smw        return (0);
11331.5Smw      }
11341.5Smw    }
11351.5Smw  }
11361.5Smw  /* assume it's an A3000 */
11371.5Smw  return (a3000_flag);
11381.5Smw}
11391.5Smw
11401.5Smwint
11411.5Smwis_a4000 ()
11421.5Smw{
11431.5Smw  /* This is a real dirty kludge.. */
11441.5Smw  return (a4000_flag);
11451.1Smw}
1146