xref: /csrg-svn/sys/luna68k/stand/autoconf.c (revision 63199)
157079Sakito /*
257079Sakito  * Copyright (c) 1992 OMRON Corporation.
3*63199Sbostic  * Copyright (c) 1992, 1993
4*63199Sbostic  *	The Regents of the University of California.  All rights reserved.
557079Sakito  *
657079Sakito  * This code is derived from software contributed to Berkeley by
757079Sakito  * OMRON Corporation.
857079Sakito  *
957079Sakito  * %sccs.include.redist.c%
1057079Sakito  *
11*63199Sbostic  *	@(#)autoconf.c	8.1 (Berkeley) 06/10/93
1257079Sakito  */
1357079Sakito 
1457079Sakito /*
1557079Sakito  * autoconf.c -- Determine mass storage and memory configuration for a machine.
1657079Sakito  *          by A.Fujita, NOV-30-1991
1757079Sakito  *
1857079Sakito  * Modified by A.Fujita, FEB-04-1992
1957079Sakito  */
2057079Sakito 
2157079Sakito 
2257079Sakito #include <sys/param.h>
2357079Sakito #include <sys/dkstat.h>
2457079Sakito #include <luna68k/stand/device.h>
2557079Sakito 
2657079Sakito int	dkn;		    /* number of iostat dk numbers assigned so far */
2757079Sakito struct	hp_hw sc_table[MAX_CTLR];
2857079Sakito 
2957079Sakito #ifdef DEBUG
3057079Sakito int	acdebug = 1;
3157079Sakito #endif
3257079Sakito 
3357079Sakito /*
3457079Sakito  * Determine mass storage and memory configuration for a machine.
3557079Sakito  */
configure()3657079Sakito configure()
3757079Sakito {
3857079Sakito 	register struct hp_hw *hw;
3957079Sakito 	int found;
4057079Sakito 
4157079Sakito 	/*
4257079Sakito 	 * Look over each hardware device actually found and attempt
4357079Sakito 	 * to match it with an ioconf.c table entry.
4457079Sakito 	 */
4557079Sakito 	for (hw = sc_table; hw->hw_type; hw++) {
4657079Sakito 		if (hw->hw_type & CONTROLLER)
4757079Sakito 			found = find_controller(hw);
4857079Sakito 		else
4957079Sakito 			found = find_device(hw);
5057079Sakito #ifdef DEBUG
5157079Sakito 		if (!found) {
5257079Sakito 			printf("unconfigured %s ", hw->hw_name);
5357079Sakito 			printf("at 0x%x\n", hw->hw_addr);
5457079Sakito 		}
5557079Sakito #endif
5657079Sakito 	}
5757079Sakito 
5857079Sakito }
5957079Sakito 
6057079Sakito #define dr_type(d, s)	\
6157079Sakito 	(strcmp((d)->d_name, (s)) == 0)
6257079Sakito 
6357079Sakito #define same_hw_ctlr(hw, hc) \
6457079Sakito 	((hw)->hw_type == SCSI && dr_type((hc)->hp_driver, "sc"))
6557079Sakito 
find_controller(hw)6657079Sakito find_controller(hw)
6757079Sakito 	register struct hp_hw *hw;
6857079Sakito {
6957079Sakito 	register struct hp_ctlr *hc;
7057079Sakito 	struct hp_ctlr *match_c;
7157079Sakito 	caddr_t oaddr;
7257079Sakito 	int sc;
7357079Sakito 
7457079Sakito #ifdef DEBUG
7557079Sakito 	if (acdebug)
7657079Sakito 		printf("find_controller: hw: %s at sc%d (%x), type %x...",
7757079Sakito 		       hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type);
7857079Sakito #endif
7957079Sakito 	sc = hw->hw_sc;
8057079Sakito 	match_c = NULL;
8157079Sakito 	for (hc = hp_cinit; hc->hp_driver; hc++) {
8257079Sakito 		if (hc->hp_alive)
8357079Sakito 			continue;
8457079Sakito 		/*
8557079Sakito 		 * Make sure we are looking at the right
8657079Sakito 		 * controller type.
8757079Sakito 		 */
8857079Sakito 		if (!same_hw_ctlr(hw, hc))
8957079Sakito 			continue;
9057079Sakito 		/*
9157079Sakito 		 * Exact match; all done
9257079Sakito 		 */
9357079Sakito 		if ((int)hc->hp_addr == sc) {
9457079Sakito 			match_c = hc;
9557079Sakito 			break;
9657079Sakito 		}
9757079Sakito 		/*
9857079Sakito 		 * Wildcard; possible match so remember first instance
9957079Sakito 		 * but continue looking for exact match.
10057079Sakito 		 */
10157079Sakito 		if ((int)hc->hp_addr == WILD_CARD_CTLR && match_c == NULL)
10257079Sakito 			match_c = hc;
10357079Sakito 	}
10457079Sakito #ifdef DEBUG
10557079Sakito 	if (acdebug) {
10657079Sakito 		if (match_c)
10757079Sakito 			printf("found %s%d\n",
10857079Sakito 			       match_c->hp_driver->d_name,
10957079Sakito 			       match_c->hp_unit);
11057079Sakito 		else
11157079Sakito 			printf("not found\n");
11257079Sakito 	}
11357079Sakito #endif
11457079Sakito 	/*
11557079Sakito 	 * Didn't find an ioconf entry for this piece of hardware,
11657079Sakito 	 * just ignore it.
11757079Sakito 	 */
11857079Sakito 	if (match_c == NULL)
11957079Sakito 		return(0);
12057079Sakito 	/*
12157079Sakito 	 * Found a match, attempt to initialize and configure all attached
12257079Sakito 	 * slaves.  Note, we can still fail if HW won't initialize.
12357079Sakito 	 */
12457079Sakito 	hc = match_c;
12557079Sakito 	oaddr = hc->hp_addr;
12657079Sakito 	hc->hp_addr = hw->hw_addr;
12757079Sakito 	if ((*hc->hp_driver->d_init)(hc)) {
12857079Sakito 		hc->hp_alive = 1;
12957079Sakito 		printf("%s%d", hc->hp_driver->d_name, hc->hp_unit);
13057079Sakito 		printf(" at 0x%x,", hc->hp_addr);
13157079Sakito 		printf(" ipl %d", hc->hp_ipl);
13257079Sakito 		if (hc->hp_flags)
13357079Sakito 			printf(" flags 0x%x", hc->hp_flags);
13457079Sakito 		printf("\n");
13557079Sakito 		find_slaves(hc);
13657079Sakito 	} else
13757079Sakito 		hc->hp_addr = oaddr;
13857079Sakito 	return(1);
13957079Sakito }
14057079Sakito 
find_device(hw)14157079Sakito find_device(hw)
14257079Sakito 	register struct hp_hw *hw;
14357079Sakito {
14457079Sakito 	register struct hp_device *hd;
14557079Sakito 	struct hp_device *match_d;
14657079Sakito 	caddr_t oaddr;
14757079Sakito 	int sc;
14857079Sakito 
14957079Sakito #ifdef DEBUG
15057079Sakito 	if (acdebug)
15157079Sakito 		printf("find_device: hw: %s at sc%d (%x), type %x...",
15257079Sakito 		       hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type);
15357079Sakito #endif
15457079Sakito 	match_d = NULL;
15557079Sakito 	for (hd = hp_dinit; hd->hp_driver; hd++) {
15657079Sakito 		if (hd->hp_alive)
15757079Sakito 			continue;
15857079Sakito 		/* Must not be a slave */
15957079Sakito 		if (hd->hp_cdriver)
16057079Sakito 			continue;
16157079Sakito 		sc = (int) hd->hp_addr;
16257079Sakito 		/*
16357079Sakito 		 * Exact match; all done.
16457079Sakito 		 */
16557079Sakito 		if (sc > 0 && sc == hw->hw_sc) {
16657079Sakito 			match_d = hd;
16757079Sakito 			break;
16857079Sakito 		}
16957079Sakito 		/*
17057079Sakito 		 * Wildcard; possible match so remember first instance
17157079Sakito 		 * but continue looking for exact match.
17257079Sakito 		 */
17357079Sakito 		if (sc == 0 && same_hw_device(hw, hd) && match_d == NULL)
17457079Sakito 			match_d = hd;
17557079Sakito 	}
17657079Sakito #ifdef DEBUG
17757079Sakito 	if (acdebug) {
17857079Sakito 		if (match_d)
17957079Sakito 			printf("found %s%d\n",
18057079Sakito 			       match_d->hp_driver->d_name,
18157079Sakito 			       match_d->hp_unit);
18257079Sakito 		else
18357079Sakito 			printf("not found\n");
18457079Sakito 	}
18557079Sakito #endif
18657079Sakito 	/*
18757079Sakito 	 * Didn't find an ioconf entry for this piece
18857079Sakito 	 * of hardware, just ignore it.
18957079Sakito 	 */
19057079Sakito 	if (match_d == NULL)
19157079Sakito 		return(0);
19257079Sakito 	/*
19357079Sakito 	 * Found a match, attempt to initialize.
19457079Sakito 	 * Note, we can still fail if HW won't initialize.
19557079Sakito 	 */
19657079Sakito 	hd = match_d;
19757079Sakito 	oaddr = hd->hp_addr;
19857079Sakito 	hd->hp_addr = hw->hw_addr;
19957079Sakito 	if ((*hd->hp_driver->d_init)(hd)) {
20057079Sakito 		hd->hp_alive = 1;
20157079Sakito 		printf("%s%d", hd->hp_driver->d_name, hd->hp_unit);
20257079Sakito 		printf(" at 0x%x", hd->hp_addr);
20357079Sakito 		if (hd->hp_ipl)
20457079Sakito 			printf(", ipl %d", hd->hp_ipl);
20557079Sakito 		if (hd->hp_flags)
20657079Sakito 			printf(", flags 0x%x", hd->hp_flags);
20757079Sakito 		printf("\n");
20857079Sakito 	} else
20957079Sakito 		hd->hp_addr = oaddr;
21057079Sakito 	return(1);
21157079Sakito }
21257079Sakito 
21357079Sakito /*
21457079Sakito  * Search each BUS controller found for slaves attached to it.
21557079Sakito  * The bad news is that we don't know how to uniquely identify all slaves
21657079Sakito  * (e.g. PPI devices on HP-IB).  The good news is that we can at least
21757079Sakito  * differentiate those from slaves we can identify.  At worst (a totally
21857079Sakito  * wildcarded entry) this will cause us to locate such a slave at the first
21957079Sakito  * unused position instead of where it really is.  To save grief, non-
22057079Sakito  * identifing devices should always be fully qualified.
22157079Sakito  */
find_slaves(hc)22257079Sakito find_slaves(hc)
22357079Sakito 	register struct hp_ctlr *hc;
22457079Sakito {
22557079Sakito 	register int s;
22657079Sakito 	register struct hp_device *hd;
22757079Sakito 	struct hp_device *match_s;
22857079Sakito 	int maxslaves = MAXSLAVES-1;
22957079Sakito 	int new_s, new_c, old_s, old_c;
23057079Sakito 	int rescan;
23157079Sakito 
23257079Sakito #ifdef DEBUG
23357079Sakito 	if (acdebug)
23457079Sakito 		printf("find_slaves: for %s%d\n",
23557079Sakito 		       hc->hp_driver->d_name, hc->hp_unit);
23657079Sakito #endif
23757079Sakito 	for (s = 0; s < maxslaves; s++) {
23857079Sakito 		rescan = 1;
23957079Sakito 		match_s = NULL;
24057079Sakito 		for (hd = hp_dinit; hd->hp_driver; hd++) {
24157079Sakito 			/*
24257079Sakito 			 * Rule out the easy ones:
24357079Sakito 			 * 1. slave already assigned or not a slave
24457079Sakito 			 * 2. not of the proper type
24557079Sakito 			 * 3. controller specified but not this one
24657079Sakito 			 * 4. slave specified but not this one
24757079Sakito 			 */
24857079Sakito 			if (hd->hp_alive || hd->hp_cdriver == NULL)
24957079Sakito 				continue;
25057079Sakito 			if (!dr_type(hc->hp_driver, hd->hp_cdriver->d_name))
25157079Sakito 				continue;
25257079Sakito 			if (hd->hp_ctlr >= 0 && hd->hp_ctlr != hc->hp_unit)
25357079Sakito 				continue;
25457079Sakito 			if (hd->hp_slave >= 0 && hd->hp_slave != s)
25557079Sakito 				continue;
25657079Sakito 			/*
25757079Sakito 			 * Case 0: first possible match.
25857079Sakito 			 * Remember it and keep looking for better.
25957079Sakito 			 */
26057079Sakito 			if (match_s == NULL) {
26157079Sakito 				match_s = hd;
26257079Sakito 				new_c = hc->hp_unit;
26357079Sakito 				new_s = s;
26457079Sakito 				continue;
26557079Sakito 			}
26657079Sakito 			/*
26757079Sakito 			 * Case 1: exact match.
26857079Sakito 			 * All done.  Note that we do not attempt any other
26957079Sakito 			 * matches if this one fails.  This allows us to
27057079Sakito 			 * "reserve" locations for dynamic addition of
27157079Sakito 			 * disk/tape drives by fully qualifing the location.
27257079Sakito 			 */
27357079Sakito 			if (hd->hp_slave == s && hd->hp_ctlr == hc->hp_unit) {
27457079Sakito 				match_s = hd;
27557079Sakito 				rescan = 0;
27657079Sakito 				break;
27757079Sakito 			}
27857079Sakito 			/*
27957079Sakito 			 * Case 2: right controller, wildcarded slave.
28057079Sakito 			 * Remember first and keep looking for an exact match.
28157079Sakito 			 */
28257079Sakito 			if (hd->hp_ctlr == hc->hp_unit &&
28357079Sakito 			    match_s->hp_ctlr < 0) {
28457079Sakito 				match_s = hd;
28557079Sakito 				new_s = s;
28657079Sakito 				continue;
28757079Sakito 			}
28857079Sakito 			/*
28957079Sakito 			 * Case 3: right slave, wildcarded controller.
29057079Sakito 			 * Remember and keep looking for a better match.
29157079Sakito 			 */
29257079Sakito 			if (hd->hp_slave == s &&
29357079Sakito 			    match_s->hp_ctlr < 0 && match_s->hp_slave < 0) {
29457079Sakito 				match_s = hd;
29557079Sakito 				new_c = hc->hp_unit;
29657079Sakito 				continue;
29757079Sakito 			}
29857079Sakito 			/*
29957079Sakito 			 * OW: we had a totally wildcarded spec.
30057079Sakito 			 * If we got this far, we have found a possible
30157079Sakito 			 * match already (match_s != NULL) so there is no
30257079Sakito 			 * reason to remember this one.
30357079Sakito 			 */
30457079Sakito 			continue;
30557079Sakito 		}
30657079Sakito 		/*
30757079Sakito 		 * Found a match.  We need to set hp_ctlr/hp_slave properly
30857079Sakito 		 * for the init routines but we also need to remember all
30957079Sakito 		 * the old values in case this doesn't pan out.
31057079Sakito 		 */
31157079Sakito 		if (match_s) {
31257079Sakito 			hd = match_s;
31357079Sakito 			old_c = hd->hp_ctlr;
31457079Sakito 			old_s = hd->hp_slave;
31557079Sakito 			if (hd->hp_ctlr < 0)
31657079Sakito 				hd->hp_ctlr = new_c;
31757079Sakito 			if (hd->hp_slave < 0)
31857079Sakito 				hd->hp_slave = new_s;
31957079Sakito #ifdef DEBUG
32057079Sakito 			if (acdebug)
32157079Sakito 				printf("looking for %s%d at slave %d...",
32257079Sakito 				       hd->hp_driver->d_name,
32357079Sakito 				       hd->hp_unit, hd->hp_slave);
32457079Sakito #endif
32557079Sakito 
32657079Sakito 			if ((*hd->hp_driver->d_init)(hd)) {
32757079Sakito #ifdef DEBUG
32857079Sakito 				if (acdebug)
32957079Sakito 					printf("found\n");
33057079Sakito #endif
33157079Sakito 				printf("%s%d at %s%d, slave %d",
33257079Sakito 				       hd->hp_driver->d_name, hd->hp_unit,
33357079Sakito 				       hc->hp_driver->d_name, hd->hp_ctlr,
33457079Sakito 				       hd->hp_slave);
33557079Sakito 				if (hd->hp_flags)
33657079Sakito 					printf(" flags 0x%x", hd->hp_flags);
33757079Sakito 				printf("\n");
33857079Sakito 				hd->hp_alive = 1;
33957079Sakito 				if (hd->hp_dk && dkn < DK_NDRIVE)
34057079Sakito 					hd->hp_dk = dkn++;
34157079Sakito 				else
34257079Sakito 					hd->hp_dk = -1;
34357079Sakito 				rescan = 1;
34457079Sakito 			} else {
34557079Sakito #ifdef DEBUG
34657079Sakito 				if (acdebug)
34757079Sakito 					printf("not found\n");
34857079Sakito #endif
34957079Sakito 				hd->hp_ctlr = old_c;
35057079Sakito 				hd->hp_slave = old_s;
35157079Sakito 			}
35257079Sakito 			/*
35357079Sakito 			 * XXX: This should be handled better.
35457079Sakito 			 * Re-scan a slave.  There are two reasons to do this.
35557079Sakito 			 * 1. It is possible to have both a tape and disk
35657079Sakito 			 *    (e.g. 7946) or two disks (e.g. 9122) at the
35757079Sakito 			 *    same slave address.  Here we need to rescan
35857079Sakito 			 *    looking only at entries with a different
35957079Sakito 			 *    physical unit number (hp_flags).
36057079Sakito 			 * 2. It is possible that an init failed because the
36157079Sakito 			 *    slave was there but of the wrong type.  In this
36257079Sakito 			 *    case it may still be possible to match the slave
36357079Sakito 			 *    to another ioconf entry of a different type.
36457079Sakito 			 *    Here we need to rescan looking only at entries
36557079Sakito 			 *    of different types.
36657079Sakito 			 * In both cases we avoid looking at undesirable
36757079Sakito 			 * ioconf entries of the same type by setting their
36857079Sakito 			 * alive fields to -1.
36957079Sakito 			 */
37057079Sakito 			if (rescan) {
37157079Sakito 				for (hd = hp_dinit; hd->hp_driver; hd++) {
37257079Sakito 					if (hd->hp_alive)
37357079Sakito 						continue;
37457079Sakito 					if (match_s->hp_alive == 1) {	/* 1 */
37557079Sakito 						if (hd->hp_flags == match_s->hp_flags)
37657079Sakito 							hd->hp_alive = -1;
37757079Sakito 					} else {			/* 2 */
37857079Sakito 						if (hd->hp_driver == match_s->hp_driver)
37957079Sakito 							hd->hp_alive = -1;
38057079Sakito 					}
38157079Sakito 				}
38257079Sakito 				s--;
38357079Sakito 				continue;
38457079Sakito 			}
38557079Sakito 		}
38657079Sakito 		/*
38757079Sakito 		 * Reset bogon alive fields prior to attempting next slave
38857079Sakito 		 */
38957079Sakito 		for (hd = hp_dinit; hd->hp_driver; hd++)
39057079Sakito 			if (hd->hp_alive == -1)
39157079Sakito 				hd->hp_alive = 0;
39257079Sakito 	}
39357079Sakito }
39457079Sakito 
39557079Sakito same_hw_device(hw, hd)
39657079Sakito 	struct hp_hw *hw;
39757079Sakito 	struct hp_device *hd;
39857079Sakito {
39957079Sakito 	int found = 0;
40057079Sakito 
40157079Sakito 	switch (hw->hw_type) {
40257079Sakito 	case NET:
40357079Sakito 		found = dr_type(hd->hp_driver, "le");
40457079Sakito 		break;
40557079Sakito 	case SCSI:
40657079Sakito 		found = dr_type(hd->hp_driver, "scsi");
40757079Sakito 		break;
40857079Sakito 	case VME:
40957079Sakito 	case MISC:
41057079Sakito 		break;
41157079Sakito 	}
41257079Sakito 	return(found);
41357079Sakito }
41457079Sakito 
41557079Sakito #define setup_hw(hw, addr, sc, type, id, name) \
41657079Sakito 	(hw)->hw_addr = addr; \
41757079Sakito 	(hw)->hw_sc   = sc; \
41857079Sakito 	(hw)->hw_type = type; \
41957079Sakito 	(hw)->hw_id   = id; \
42057079Sakito 	(hw)->hw_name = name
42157079Sakito 
find_devs()42257079Sakito find_devs()
42357079Sakito {
42457079Sakito 	register struct hp_hw *hw = sc_table;
42557079Sakito 
42657079Sakito 	setup_hw(hw, (char *) 0x51000000, 0x5, SIO,      0x5, "uPD7201A (SIO)");
42757079Sakito 	hw->hw_id2 = 0; hw++;
42857079Sakito 
42957079Sakito 	setup_hw(hw, (char *) 0x51000004, 0x5, KEYBOARD, 0x5, "uPD7201A (KBD)");
43057079Sakito 	hw->hw_id2 = 1; hw++;
43157079Sakito 
43257079Sakito 	setup_hw(hw, (char *) 0xe1000000, 0xe, SCSI,     0xe, "MB89352  (SPC)");
43357079Sakito 	hw++;
43457079Sakito 
43557079Sakito 	if (!badaddr((caddr_t) 0xf1000000)) {
43657079Sakito 		setup_hw(hw, (char *) 0xf1000000, 0xf, NET,      0xf, "Am7990 (LANCE)");
43757079Sakito 		hw++;
43857079Sakito 	}
43957079Sakito }
44057079Sakito 
strcmp(s1,s2)44157079Sakito strcmp(s1, s2)
44257079Sakito 	register char *s1, *s2;
44357079Sakito {
44457079Sakito 	while (*s1 == *s2)
44557079Sakito 		if (*s1++=='\0' || *s2++ == '\0')
44657079Sakito 			return (0);
44757079Sakito 	return (*s1 - *s2);
44857079Sakito }
449