xref: /csrg-svn/sys/luna68k/stand/autoconf.c (revision 57079)
1*57079Sakito /*
2*57079Sakito  * Copyright (c) 1992 OMRON Corporation.
3*57079Sakito  * Copyright (c) 1992 The Regents of the University of California.
4*57079Sakito  * All rights reserved.
5*57079Sakito  *
6*57079Sakito  * This code is derived from software contributed to Berkeley by
7*57079Sakito  * OMRON Corporation.
8*57079Sakito  *
9*57079Sakito  * %sccs.include.redist.c%
10*57079Sakito  *
11*57079Sakito  *	@(#)autoconf.c	7.1 (Berkeley) 12/13/92
12*57079Sakito  */
13*57079Sakito 
14*57079Sakito /*
15*57079Sakito  * autoconf.c -- Determine mass storage and memory configuration for a machine.
16*57079Sakito  *          by A.Fujita, NOV-30-1991
17*57079Sakito  *
18*57079Sakito  * Modified by A.Fujita, FEB-04-1992
19*57079Sakito  */
20*57079Sakito 
21*57079Sakito 
22*57079Sakito #include <sys/param.h>
23*57079Sakito #include <sys/dkstat.h>
24*57079Sakito #include <luna68k/stand/device.h>
25*57079Sakito 
26*57079Sakito int	dkn;		    /* number of iostat dk numbers assigned so far */
27*57079Sakito struct	hp_hw sc_table[MAX_CTLR];
28*57079Sakito 
29*57079Sakito #ifdef DEBUG
30*57079Sakito int	acdebug = 1;
31*57079Sakito #endif
32*57079Sakito 
33*57079Sakito /*
34*57079Sakito  * Determine mass storage and memory configuration for a machine.
35*57079Sakito  */
36*57079Sakito configure()
37*57079Sakito {
38*57079Sakito 	register struct hp_hw *hw;
39*57079Sakito 	int found;
40*57079Sakito 
41*57079Sakito 	/*
42*57079Sakito 	 * Look over each hardware device actually found and attempt
43*57079Sakito 	 * to match it with an ioconf.c table entry.
44*57079Sakito 	 */
45*57079Sakito 	for (hw = sc_table; hw->hw_type; hw++) {
46*57079Sakito 		if (hw->hw_type & CONTROLLER)
47*57079Sakito 			found = find_controller(hw);
48*57079Sakito 		else
49*57079Sakito 			found = find_device(hw);
50*57079Sakito #ifdef DEBUG
51*57079Sakito 		if (!found) {
52*57079Sakito 			printf("unconfigured %s ", hw->hw_name);
53*57079Sakito 			printf("at 0x%x\n", hw->hw_addr);
54*57079Sakito 		}
55*57079Sakito #endif
56*57079Sakito 	}
57*57079Sakito 
58*57079Sakito }
59*57079Sakito 
60*57079Sakito #define dr_type(d, s)	\
61*57079Sakito 	(strcmp((d)->d_name, (s)) == 0)
62*57079Sakito 
63*57079Sakito #define same_hw_ctlr(hw, hc) \
64*57079Sakito 	((hw)->hw_type == SCSI && dr_type((hc)->hp_driver, "sc"))
65*57079Sakito 
66*57079Sakito find_controller(hw)
67*57079Sakito 	register struct hp_hw *hw;
68*57079Sakito {
69*57079Sakito 	register struct hp_ctlr *hc;
70*57079Sakito 	struct hp_ctlr *match_c;
71*57079Sakito 	caddr_t oaddr;
72*57079Sakito 	int sc;
73*57079Sakito 
74*57079Sakito #ifdef DEBUG
75*57079Sakito 	if (acdebug)
76*57079Sakito 		printf("find_controller: hw: %s at sc%d (%x), type %x...",
77*57079Sakito 		       hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type);
78*57079Sakito #endif
79*57079Sakito 	sc = hw->hw_sc;
80*57079Sakito 	match_c = NULL;
81*57079Sakito 	for (hc = hp_cinit; hc->hp_driver; hc++) {
82*57079Sakito 		if (hc->hp_alive)
83*57079Sakito 			continue;
84*57079Sakito 		/*
85*57079Sakito 		 * Make sure we are looking at the right
86*57079Sakito 		 * controller type.
87*57079Sakito 		 */
88*57079Sakito 		if (!same_hw_ctlr(hw, hc))
89*57079Sakito 			continue;
90*57079Sakito 		/*
91*57079Sakito 		 * Exact match; all done
92*57079Sakito 		 */
93*57079Sakito 		if ((int)hc->hp_addr == sc) {
94*57079Sakito 			match_c = hc;
95*57079Sakito 			break;
96*57079Sakito 		}
97*57079Sakito 		/*
98*57079Sakito 		 * Wildcard; possible match so remember first instance
99*57079Sakito 		 * but continue looking for exact match.
100*57079Sakito 		 */
101*57079Sakito 		if ((int)hc->hp_addr == WILD_CARD_CTLR && match_c == NULL)
102*57079Sakito 			match_c = hc;
103*57079Sakito 	}
104*57079Sakito #ifdef DEBUG
105*57079Sakito 	if (acdebug) {
106*57079Sakito 		if (match_c)
107*57079Sakito 			printf("found %s%d\n",
108*57079Sakito 			       match_c->hp_driver->d_name,
109*57079Sakito 			       match_c->hp_unit);
110*57079Sakito 		else
111*57079Sakito 			printf("not found\n");
112*57079Sakito 	}
113*57079Sakito #endif
114*57079Sakito 	/*
115*57079Sakito 	 * Didn't find an ioconf entry for this piece of hardware,
116*57079Sakito 	 * just ignore it.
117*57079Sakito 	 */
118*57079Sakito 	if (match_c == NULL)
119*57079Sakito 		return(0);
120*57079Sakito 	/*
121*57079Sakito 	 * Found a match, attempt to initialize and configure all attached
122*57079Sakito 	 * slaves.  Note, we can still fail if HW won't initialize.
123*57079Sakito 	 */
124*57079Sakito 	hc = match_c;
125*57079Sakito 	oaddr = hc->hp_addr;
126*57079Sakito 	hc->hp_addr = hw->hw_addr;
127*57079Sakito 	if ((*hc->hp_driver->d_init)(hc)) {
128*57079Sakito 		hc->hp_alive = 1;
129*57079Sakito 		printf("%s%d", hc->hp_driver->d_name, hc->hp_unit);
130*57079Sakito 		printf(" at 0x%x,", hc->hp_addr);
131*57079Sakito 		printf(" ipl %d", hc->hp_ipl);
132*57079Sakito 		if (hc->hp_flags)
133*57079Sakito 			printf(" flags 0x%x", hc->hp_flags);
134*57079Sakito 		printf("\n");
135*57079Sakito 		find_slaves(hc);
136*57079Sakito 	} else
137*57079Sakito 		hc->hp_addr = oaddr;
138*57079Sakito 	return(1);
139*57079Sakito }
140*57079Sakito 
141*57079Sakito find_device(hw)
142*57079Sakito 	register struct hp_hw *hw;
143*57079Sakito {
144*57079Sakito 	register struct hp_device *hd;
145*57079Sakito 	struct hp_device *match_d;
146*57079Sakito 	caddr_t oaddr;
147*57079Sakito 	int sc;
148*57079Sakito 
149*57079Sakito #ifdef DEBUG
150*57079Sakito 	if (acdebug)
151*57079Sakito 		printf("find_device: hw: %s at sc%d (%x), type %x...",
152*57079Sakito 		       hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type);
153*57079Sakito #endif
154*57079Sakito 	match_d = NULL;
155*57079Sakito 	for (hd = hp_dinit; hd->hp_driver; hd++) {
156*57079Sakito 		if (hd->hp_alive)
157*57079Sakito 			continue;
158*57079Sakito 		/* Must not be a slave */
159*57079Sakito 		if (hd->hp_cdriver)
160*57079Sakito 			continue;
161*57079Sakito 		sc = (int) hd->hp_addr;
162*57079Sakito 		/*
163*57079Sakito 		 * Exact match; all done.
164*57079Sakito 		 */
165*57079Sakito 		if (sc > 0 && sc == hw->hw_sc) {
166*57079Sakito 			match_d = hd;
167*57079Sakito 			break;
168*57079Sakito 		}
169*57079Sakito 		/*
170*57079Sakito 		 * Wildcard; possible match so remember first instance
171*57079Sakito 		 * but continue looking for exact match.
172*57079Sakito 		 */
173*57079Sakito 		if (sc == 0 && same_hw_device(hw, hd) && match_d == NULL)
174*57079Sakito 			match_d = hd;
175*57079Sakito 	}
176*57079Sakito #ifdef DEBUG
177*57079Sakito 	if (acdebug) {
178*57079Sakito 		if (match_d)
179*57079Sakito 			printf("found %s%d\n",
180*57079Sakito 			       match_d->hp_driver->d_name,
181*57079Sakito 			       match_d->hp_unit);
182*57079Sakito 		else
183*57079Sakito 			printf("not found\n");
184*57079Sakito 	}
185*57079Sakito #endif
186*57079Sakito 	/*
187*57079Sakito 	 * Didn't find an ioconf entry for this piece
188*57079Sakito 	 * of hardware, just ignore it.
189*57079Sakito 	 */
190*57079Sakito 	if (match_d == NULL)
191*57079Sakito 		return(0);
192*57079Sakito 	/*
193*57079Sakito 	 * Found a match, attempt to initialize.
194*57079Sakito 	 * Note, we can still fail if HW won't initialize.
195*57079Sakito 	 */
196*57079Sakito 	hd = match_d;
197*57079Sakito 	oaddr = hd->hp_addr;
198*57079Sakito 	hd->hp_addr = hw->hw_addr;
199*57079Sakito 	if ((*hd->hp_driver->d_init)(hd)) {
200*57079Sakito 		hd->hp_alive = 1;
201*57079Sakito 		printf("%s%d", hd->hp_driver->d_name, hd->hp_unit);
202*57079Sakito 		printf(" at 0x%x", hd->hp_addr);
203*57079Sakito 		if (hd->hp_ipl)
204*57079Sakito 			printf(", ipl %d", hd->hp_ipl);
205*57079Sakito 		if (hd->hp_flags)
206*57079Sakito 			printf(", flags 0x%x", hd->hp_flags);
207*57079Sakito 		printf("\n");
208*57079Sakito 	} else
209*57079Sakito 		hd->hp_addr = oaddr;
210*57079Sakito 	return(1);
211*57079Sakito }
212*57079Sakito 
213*57079Sakito /*
214*57079Sakito  * Search each BUS controller found for slaves attached to it.
215*57079Sakito  * The bad news is that we don't know how to uniquely identify all slaves
216*57079Sakito  * (e.g. PPI devices on HP-IB).  The good news is that we can at least
217*57079Sakito  * differentiate those from slaves we can identify.  At worst (a totally
218*57079Sakito  * wildcarded entry) this will cause us to locate such a slave at the first
219*57079Sakito  * unused position instead of where it really is.  To save grief, non-
220*57079Sakito  * identifing devices should always be fully qualified.
221*57079Sakito  */
222*57079Sakito find_slaves(hc)
223*57079Sakito 	register struct hp_ctlr *hc;
224*57079Sakito {
225*57079Sakito 	register int s;
226*57079Sakito 	register struct hp_device *hd;
227*57079Sakito 	struct hp_device *match_s;
228*57079Sakito 	int maxslaves = MAXSLAVES-1;
229*57079Sakito 	int new_s, new_c, old_s, old_c;
230*57079Sakito 	int rescan;
231*57079Sakito 
232*57079Sakito #ifdef DEBUG
233*57079Sakito 	if (acdebug)
234*57079Sakito 		printf("find_slaves: for %s%d\n",
235*57079Sakito 		       hc->hp_driver->d_name, hc->hp_unit);
236*57079Sakito #endif
237*57079Sakito 	for (s = 0; s < maxslaves; s++) {
238*57079Sakito 		rescan = 1;
239*57079Sakito 		match_s = NULL;
240*57079Sakito 		for (hd = hp_dinit; hd->hp_driver; hd++) {
241*57079Sakito 			/*
242*57079Sakito 			 * Rule out the easy ones:
243*57079Sakito 			 * 1. slave already assigned or not a slave
244*57079Sakito 			 * 2. not of the proper type
245*57079Sakito 			 * 3. controller specified but not this one
246*57079Sakito 			 * 4. slave specified but not this one
247*57079Sakito 			 */
248*57079Sakito 			if (hd->hp_alive || hd->hp_cdriver == NULL)
249*57079Sakito 				continue;
250*57079Sakito 			if (!dr_type(hc->hp_driver, hd->hp_cdriver->d_name))
251*57079Sakito 				continue;
252*57079Sakito 			if (hd->hp_ctlr >= 0 && hd->hp_ctlr != hc->hp_unit)
253*57079Sakito 				continue;
254*57079Sakito 			if (hd->hp_slave >= 0 && hd->hp_slave != s)
255*57079Sakito 				continue;
256*57079Sakito 			/*
257*57079Sakito 			 * Case 0: first possible match.
258*57079Sakito 			 * Remember it and keep looking for better.
259*57079Sakito 			 */
260*57079Sakito 			if (match_s == NULL) {
261*57079Sakito 				match_s = hd;
262*57079Sakito 				new_c = hc->hp_unit;
263*57079Sakito 				new_s = s;
264*57079Sakito 				continue;
265*57079Sakito 			}
266*57079Sakito 			/*
267*57079Sakito 			 * Case 1: exact match.
268*57079Sakito 			 * All done.  Note that we do not attempt any other
269*57079Sakito 			 * matches if this one fails.  This allows us to
270*57079Sakito 			 * "reserve" locations for dynamic addition of
271*57079Sakito 			 * disk/tape drives by fully qualifing the location.
272*57079Sakito 			 */
273*57079Sakito 			if (hd->hp_slave == s && hd->hp_ctlr == hc->hp_unit) {
274*57079Sakito 				match_s = hd;
275*57079Sakito 				rescan = 0;
276*57079Sakito 				break;
277*57079Sakito 			}
278*57079Sakito 			/*
279*57079Sakito 			 * Case 2: right controller, wildcarded slave.
280*57079Sakito 			 * Remember first and keep looking for an exact match.
281*57079Sakito 			 */
282*57079Sakito 			if (hd->hp_ctlr == hc->hp_unit &&
283*57079Sakito 			    match_s->hp_ctlr < 0) {
284*57079Sakito 				match_s = hd;
285*57079Sakito 				new_s = s;
286*57079Sakito 				continue;
287*57079Sakito 			}
288*57079Sakito 			/*
289*57079Sakito 			 * Case 3: right slave, wildcarded controller.
290*57079Sakito 			 * Remember and keep looking for a better match.
291*57079Sakito 			 */
292*57079Sakito 			if (hd->hp_slave == s &&
293*57079Sakito 			    match_s->hp_ctlr < 0 && match_s->hp_slave < 0) {
294*57079Sakito 				match_s = hd;
295*57079Sakito 				new_c = hc->hp_unit;
296*57079Sakito 				continue;
297*57079Sakito 			}
298*57079Sakito 			/*
299*57079Sakito 			 * OW: we had a totally wildcarded spec.
300*57079Sakito 			 * If we got this far, we have found a possible
301*57079Sakito 			 * match already (match_s != NULL) so there is no
302*57079Sakito 			 * reason to remember this one.
303*57079Sakito 			 */
304*57079Sakito 			continue;
305*57079Sakito 		}
306*57079Sakito 		/*
307*57079Sakito 		 * Found a match.  We need to set hp_ctlr/hp_slave properly
308*57079Sakito 		 * for the init routines but we also need to remember all
309*57079Sakito 		 * the old values in case this doesn't pan out.
310*57079Sakito 		 */
311*57079Sakito 		if (match_s) {
312*57079Sakito 			hd = match_s;
313*57079Sakito 			old_c = hd->hp_ctlr;
314*57079Sakito 			old_s = hd->hp_slave;
315*57079Sakito 			if (hd->hp_ctlr < 0)
316*57079Sakito 				hd->hp_ctlr = new_c;
317*57079Sakito 			if (hd->hp_slave < 0)
318*57079Sakito 				hd->hp_slave = new_s;
319*57079Sakito #ifdef DEBUG
320*57079Sakito 			if (acdebug)
321*57079Sakito 				printf("looking for %s%d at slave %d...",
322*57079Sakito 				       hd->hp_driver->d_name,
323*57079Sakito 				       hd->hp_unit, hd->hp_slave);
324*57079Sakito #endif
325*57079Sakito 
326*57079Sakito 			if ((*hd->hp_driver->d_init)(hd)) {
327*57079Sakito #ifdef DEBUG
328*57079Sakito 				if (acdebug)
329*57079Sakito 					printf("found\n");
330*57079Sakito #endif
331*57079Sakito 				printf("%s%d at %s%d, slave %d",
332*57079Sakito 				       hd->hp_driver->d_name, hd->hp_unit,
333*57079Sakito 				       hc->hp_driver->d_name, hd->hp_ctlr,
334*57079Sakito 				       hd->hp_slave);
335*57079Sakito 				if (hd->hp_flags)
336*57079Sakito 					printf(" flags 0x%x", hd->hp_flags);
337*57079Sakito 				printf("\n");
338*57079Sakito 				hd->hp_alive = 1;
339*57079Sakito 				if (hd->hp_dk && dkn < DK_NDRIVE)
340*57079Sakito 					hd->hp_dk = dkn++;
341*57079Sakito 				else
342*57079Sakito 					hd->hp_dk = -1;
343*57079Sakito 				rescan = 1;
344*57079Sakito 			} else {
345*57079Sakito #ifdef DEBUG
346*57079Sakito 				if (acdebug)
347*57079Sakito 					printf("not found\n");
348*57079Sakito #endif
349*57079Sakito 				hd->hp_ctlr = old_c;
350*57079Sakito 				hd->hp_slave = old_s;
351*57079Sakito 			}
352*57079Sakito 			/*
353*57079Sakito 			 * XXX: This should be handled better.
354*57079Sakito 			 * Re-scan a slave.  There are two reasons to do this.
355*57079Sakito 			 * 1. It is possible to have both a tape and disk
356*57079Sakito 			 *    (e.g. 7946) or two disks (e.g. 9122) at the
357*57079Sakito 			 *    same slave address.  Here we need to rescan
358*57079Sakito 			 *    looking only at entries with a different
359*57079Sakito 			 *    physical unit number (hp_flags).
360*57079Sakito 			 * 2. It is possible that an init failed because the
361*57079Sakito 			 *    slave was there but of the wrong type.  In this
362*57079Sakito 			 *    case it may still be possible to match the slave
363*57079Sakito 			 *    to another ioconf entry of a different type.
364*57079Sakito 			 *    Here we need to rescan looking only at entries
365*57079Sakito 			 *    of different types.
366*57079Sakito 			 * In both cases we avoid looking at undesirable
367*57079Sakito 			 * ioconf entries of the same type by setting their
368*57079Sakito 			 * alive fields to -1.
369*57079Sakito 			 */
370*57079Sakito 			if (rescan) {
371*57079Sakito 				for (hd = hp_dinit; hd->hp_driver; hd++) {
372*57079Sakito 					if (hd->hp_alive)
373*57079Sakito 						continue;
374*57079Sakito 					if (match_s->hp_alive == 1) {	/* 1 */
375*57079Sakito 						if (hd->hp_flags == match_s->hp_flags)
376*57079Sakito 							hd->hp_alive = -1;
377*57079Sakito 					} else {			/* 2 */
378*57079Sakito 						if (hd->hp_driver == match_s->hp_driver)
379*57079Sakito 							hd->hp_alive = -1;
380*57079Sakito 					}
381*57079Sakito 				}
382*57079Sakito 				s--;
383*57079Sakito 				continue;
384*57079Sakito 			}
385*57079Sakito 		}
386*57079Sakito 		/*
387*57079Sakito 		 * Reset bogon alive fields prior to attempting next slave
388*57079Sakito 		 */
389*57079Sakito 		for (hd = hp_dinit; hd->hp_driver; hd++)
390*57079Sakito 			if (hd->hp_alive == -1)
391*57079Sakito 				hd->hp_alive = 0;
392*57079Sakito 	}
393*57079Sakito }
394*57079Sakito 
395*57079Sakito same_hw_device(hw, hd)
396*57079Sakito 	struct hp_hw *hw;
397*57079Sakito 	struct hp_device *hd;
398*57079Sakito {
399*57079Sakito 	int found = 0;
400*57079Sakito 
401*57079Sakito 	switch (hw->hw_type) {
402*57079Sakito 	case NET:
403*57079Sakito 		found = dr_type(hd->hp_driver, "le");
404*57079Sakito 		break;
405*57079Sakito 	case SCSI:
406*57079Sakito 		found = dr_type(hd->hp_driver, "scsi");
407*57079Sakito 		break;
408*57079Sakito 	case VME:
409*57079Sakito 	case MISC:
410*57079Sakito 		break;
411*57079Sakito 	}
412*57079Sakito 	return(found);
413*57079Sakito }
414*57079Sakito 
415*57079Sakito #define setup_hw(hw, addr, sc, type, id, name) \
416*57079Sakito 	(hw)->hw_addr = addr; \
417*57079Sakito 	(hw)->hw_sc   = sc; \
418*57079Sakito 	(hw)->hw_type = type; \
419*57079Sakito 	(hw)->hw_id   = id; \
420*57079Sakito 	(hw)->hw_name = name
421*57079Sakito 
422*57079Sakito find_devs()
423*57079Sakito {
424*57079Sakito 	register struct hp_hw *hw = sc_table;
425*57079Sakito 
426*57079Sakito 	setup_hw(hw, (char *) 0x51000000, 0x5, SIO,      0x5, "uPD7201A (SIO)");
427*57079Sakito 	hw->hw_id2 = 0; hw++;
428*57079Sakito 
429*57079Sakito 	setup_hw(hw, (char *) 0x51000004, 0x5, KEYBOARD, 0x5, "uPD7201A (KBD)");
430*57079Sakito 	hw->hw_id2 = 1; hw++;
431*57079Sakito 
432*57079Sakito 	setup_hw(hw, (char *) 0xe1000000, 0xe, SCSI,     0xe, "MB89352  (SPC)");
433*57079Sakito 	hw++;
434*57079Sakito 
435*57079Sakito 	if (!badaddr((caddr_t) 0xf1000000)) {
436*57079Sakito 		setup_hw(hw, (char *) 0xf1000000, 0xf, NET,      0xf, "Am7990 (LANCE)");
437*57079Sakito 		hw++;
438*57079Sakito 	}
439*57079Sakito }
440*57079Sakito 
441*57079Sakito strcmp(s1, s2)
442*57079Sakito 	register char *s1, *s2;
443*57079Sakito {
444*57079Sakito 	while (*s1 == *s2)
445*57079Sakito 		if (*s1++=='\0' || *s2++ == '\0')
446*57079Sakito 			return (0);
447*57079Sakito 	return (*s1 - *s2);
448*57079Sakito }
449