xref: /original-bsd/sys/hp300/hp300/autoconf.c (revision dd262573)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: autoconf.c 1.25 89/10/07$
13  *
14  *	@(#)autoconf.c	7.4 (Berkeley) 12/16/90
15  */
16 
17 /*
18  * Setup the system to run on the current machine.
19  *
20  * Configure() is called at boot time.  Available
21  * devices are determined (from possibilities mentioned in ioconf.c),
22  * and the drivers are initialized.
23  */
24 
25 #include "sys/param.h"
26 #include "sys/systm.h"
27 #include "sys/map.h"
28 #include "sys/buf.h"
29 #include "sys/dkstat.h"
30 #include "sys/conf.h"
31 #include "sys/dmap.h"
32 #include "sys/reboot.h"
33 
34 #include "../include/cpu.h"
35 #include "isr.h"
36 #include "../dev/device.h"
37 #include "../dev/grfioctl.h"
38 #include "../dev/grfvar.h"
39 
40 /*
41  * The following several variables are related to
42  * the configuration process, and are used in initializing
43  * the machine.
44  */
45 int	cold;		    /* if 1, still working on cold-start */
46 int	dkn;		    /* number of iostat dk numbers assigned so far */
47 int	cpuspeed = MHZ_8;   /* relative cpu speed */
48 struct	isr isrqueue[NISR];
49 struct	hp_hw sc_table[MAX_CTLR];
50 
51 extern	int internalhpib;
52 
53 #ifdef DEBUG
54 int	acdebug = 0;
55 #endif
56 
57 /*
58  * Determine mass storage and memory configuration for a machine.
59  */
60 configure()
61 {
62 	register struct hp_hw *hw;
63 	int found;
64 
65 	/*
66 	 * XXX: these should be consolidated into some kind of table
67 	 */
68 	hilinit();
69 	isrinit();
70 	dmainit();
71 
72 	/*
73 	 * Look over each hardware device actually found and attempt
74 	 * to match it with an ioconf.c table entry.
75 	 */
76 	for (hw = sc_table; hw->hw_type; hw++) {
77 		if (hw->hw_type & CONTROLLER)
78 			found = find_controller(hw);
79 		else
80 			found = find_device(hw);
81 #ifdef DEBUG
82 		if (!found) {
83 			int sc = addrtosc((u_int)hw->hw_addr);
84 
85 			printf("unconfigured %s ", hw->hw_name);
86 			if (sc < 256)
87 				printf("at sc%d\n", sc);
88 			else
89 				printf("csr at %x\n", sc);
90 		}
91 #endif
92 	}
93 
94 #include "cd.h"
95 #if NCD > 0
96 	/*
97 	 * Now deal with concatenated disks
98 	 */
99 	find_cdevices();
100 #endif
101 
102 #if GENERIC
103 	if ((boothowto & RB_ASKNAME) == 0)
104 		setroot();
105 	setconf();
106 #else
107 	setroot();
108 #endif
109 	swapconf();
110 	cold = 0;
111 }
112 
113 #define dr_type(d, s)	\
114 	(strcmp((d)->d_name, (s)) == 0)
115 
116 #define same_hw_ctlr(hw, hc) \
117 	((hw)->hw_type == HPIB && dr_type((hc)->hp_driver, "hpib") || \
118 	 (hw)->hw_type == SCSI && dr_type((hc)->hp_driver, "scsi"))
119 
120 find_controller(hw)
121 	register struct hp_hw *hw;
122 {
123 	register struct hp_ctlr *hc;
124 	struct hp_ctlr *match_c;
125 	caddr_t oaddr;
126 	int sc;
127 
128 #ifdef DEBUG
129 	if (acdebug)
130 		printf("find_controller: hw: %s at sc%d (%x), type %x...",
131 		       hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type);
132 #endif
133 	sc = hw->hw_sc;
134 	match_c = NULL;
135 	for (hc = hp_cinit; hc->hp_driver; hc++) {
136 		if (hc->hp_alive)
137 			continue;
138 		/*
139 		 * Make sure we are looking at the right
140 		 * controller type.
141 		 */
142 		if (!same_hw_ctlr(hw, hc))
143 			continue;
144 		/*
145 		 * Exact match; all done
146 		 */
147 		if ((int)hc->hp_addr == sc) {
148 			match_c = hc;
149 			break;
150 		}
151 		/*
152 		 * Wildcard; possible match so remember first instance
153 		 * but continue looking for exact match.
154 		 */
155 		if ((int)hc->hp_addr == WILD_CARD_CTLR && match_c == NULL)
156 			match_c = hc;
157 	}
158 #ifdef DEBUG
159 	if (acdebug) {
160 		if (match_c)
161 			printf("found %s%d\n",
162 			       match_c->hp_driver->d_name,
163 			       match_c->hp_unit);
164 		else
165 			printf("not found\n");
166 	}
167 #endif
168 	/*
169 	 * Didn't find an ioconf entry for this piece of hardware,
170 	 * just ignore it.
171 	 */
172 	if (match_c == NULL)
173 		return(0);
174 	/*
175 	 * Found a match, attempt to initialize and configure all attached
176 	 * slaves.  Note, we can still fail if HW won't initialize.
177 	 */
178 	hc = match_c;
179 	oaddr = hc->hp_addr;
180 	hc->hp_addr = hw->hw_addr;
181 	if ((*hc->hp_driver->d_init)(hc)) {
182 		hc->hp_alive = 1;
183 		printf("%s%d", hc->hp_driver->d_name, hc->hp_unit);
184 		sc = addrtosc((u_int)hc->hp_addr);
185 		if (sc < 256)
186 			printf(" at sc%d,", sc);
187 		else
188 			printf(" csr 0x%x,", sc);
189 		printf(" ipl %d", hc->hp_ipl);
190 		if (hc->hp_flags)
191 			printf(" flags 0x%x", hc->hp_flags);
192 		printf("\n");
193 		find_slaves(hc);
194 	} else
195 		hc->hp_addr = oaddr;
196 	return(1);
197 }
198 
199 find_device(hw)
200 	register struct hp_hw *hw;
201 {
202 	register struct hp_device *hd;
203 	struct hp_device *match_d;
204 	caddr_t oaddr;
205 	int sc;
206 
207 #ifdef DEBUG
208 	if (acdebug)
209 		printf("find_device: hw: %s at sc%d (%x), type %x...",
210 		       hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type);
211 #endif
212 	match_d = NULL;
213 	for (hd = hp_dinit; hd->hp_driver; hd++) {
214 		if (hd->hp_alive)
215 			continue;
216 		/* Must not be a slave */
217 		if (hd->hp_cdriver)
218 			continue;
219 		/*
220 		 * XXX: A graphics device that was found as part of the
221 		 * console init will have the hp_addr field already set
222 		 * (i.e. no longer the select code).  Gotta perform a
223 		 * slightly different check for an exact match.
224 		 */
225 		if (hw->hw_type == BITMAP && hd->hp_addr >= (caddr_t)IOBASE) {
226 			/* must be an exact match */
227 			if (hd->hp_addr == hw->hw_addr) {
228 				match_d = hd;
229 				break;
230 			}
231 			continue;
232 		}
233 		sc = (int) hd->hp_addr;
234 		/*
235 		 * Exact match; all done.
236 		 */
237 		if (sc > 0 && sc == hw->hw_sc) {
238 			match_d = hd;
239 			break;
240 		}
241 		/*
242 		 * Wildcard; possible match so remember first instance
243 		 * but continue looking for exact match.
244 		 */
245 		if (sc == 0 && same_hw_device(hw, hd) && match_d == NULL)
246 			match_d = hd;
247 	}
248 #ifdef DEBUG
249 	if (acdebug) {
250 		if (match_d)
251 			printf("found %s%d\n",
252 			       match_d->hp_driver->d_name,
253 			       match_d->hp_unit);
254 		else
255 			printf("not found\n");
256 	}
257 #endif
258 	/*
259 	 * Didn't find an ioconf entry for this piece
260 	 * of hardware, just ignore it.
261 	 */
262 	if (match_d == NULL)
263 		return(0);
264 	/*
265 	 * Found a match, attempt to initialize.
266 	 * Note, we can still fail if HW won't initialize.
267 	 */
268 	hd = match_d;
269 	oaddr = hd->hp_addr;
270 	hd->hp_addr = hw->hw_addr;
271 	if ((*hd->hp_driver->d_init)(hd)) {
272 		hd->hp_alive = 1;
273 		printf("%s%d", hd->hp_driver->d_name, hd->hp_unit);
274 		sc = addrtosc((u_int)hd->hp_addr);
275 		if (sc < 256)
276 			printf(" at sc%d", sc);
277 		else
278 			printf(" csr 0x%x", sc);
279 		if (hd->hp_ipl)
280 			printf(", ipl %d", hd->hp_ipl);
281 		if (hd->hp_flags)
282 			printf(", flags 0x%x", hd->hp_flags);
283 		printf("\n");
284 	} else
285 		hd->hp_addr = oaddr;
286 	return(1);
287 }
288 
289 find_slaves(hc)
290 	struct hp_ctlr *hc;
291 {
292 	/*
293 	 * The SCSI bus is structured very much like the HP-IB
294 	 * except that the host adaptor is slave 7 so we only want
295 	 * to look at the first 6 slaves.
296 	 */
297 	if (dr_type(hc->hp_driver, "hpib"))
298 		find_busslaves(hc, MAXSLAVES);
299 	else if (dr_type(hc->hp_driver, "scsi"))
300 		find_busslaves(hc, MAXSLAVES-1);
301 }
302 
303 /*
304  * Search each BUS controller found for slaves attached to it.
305  * The bad news is that we don't know how to uniquely identify all slaves
306  * (e.g. PPI devices on HP-IB).  The good news is that we can at least
307  * differentiate those from slaves we can identify.  At worst (a totally
308  * wildcarded entry) this will cause us to locate such a slave at the first
309  * unused position instead of where it really is.  To save grief, non-
310  * identifing devices should always be fully qualified.
311  */
312 find_busslaves(hc, maxslaves)
313 	register struct hp_ctlr *hc;
314 	int maxslaves;
315 {
316 	register int s;
317 	register struct hp_device *hd;
318 	struct hp_device *match_s;
319 	int new_s, new_c, old_s, old_c;
320 	int rescan;
321 
322 #ifdef DEBUG
323 	if (acdebug)
324 		printf("find_busslaves: for %s%d\n",
325 		       hc->hp_driver->d_name, hc->hp_unit);
326 #endif
327 	for (s = 0; s < maxslaves; s++) {
328 		rescan = 1;
329 		match_s = NULL;
330 		for (hd = hp_dinit; hd->hp_driver; hd++) {
331 			/*
332 			 * Rule out the easy ones:
333 			 * 1. slave already assigned or not a slave
334 			 * 2. not of the proper type
335 			 * 3. controller specified but not this one
336 			 * 4. slave specified but not this one
337 			 */
338 			if (hd->hp_alive || hd->hp_cdriver == NULL)
339 				continue;
340 			if (!dr_type(hc->hp_driver, hd->hp_cdriver->d_name))
341 				continue;
342 			if (hd->hp_ctlr >= 0 && hd->hp_ctlr != hc->hp_unit)
343 				continue;
344 			if (hd->hp_slave >= 0 && hd->hp_slave != s)
345 				continue;
346 			/*
347 			 * Case 0: first possible match.
348 			 * Remember it and keep looking for better.
349 			 */
350 			if (match_s == NULL) {
351 				match_s = hd;
352 				new_c = hc->hp_unit;
353 				new_s = s;
354 				continue;
355 			}
356 			/*
357 			 * Case 1: exact match.
358 			 * All done.  Note that we do not attempt any other
359 			 * matches if this one fails.  This allows us to
360 			 * "reserve" locations for dynamic addition of
361 			 * disk/tape drives by fully qualifing the location.
362 			 */
363 			if (hd->hp_slave == s && hd->hp_ctlr == hc->hp_unit) {
364 				match_s = hd;
365 				rescan = 0;
366 				break;
367 			}
368 			/*
369 			 * Case 2: right controller, wildcarded slave.
370 			 * Remember first and keep looking for an exact match.
371 			 */
372 			if (hd->hp_ctlr == hc->hp_unit &&
373 			    match_s->hp_ctlr < 0) {
374 				match_s = hd;
375 				new_s = s;
376 				continue;
377 			}
378 			/*
379 			 * Case 3: right slave, wildcarded controller.
380 			 * Remember and keep looking for a better match.
381 			 */
382 			if (hd->hp_slave == s &&
383 			    match_s->hp_ctlr < 0 && match_s->hp_slave < 0) {
384 				match_s = hd;
385 				new_c = hc->hp_unit;
386 				continue;
387 			}
388 			/*
389 			 * OW: we had a totally wildcarded spec.
390 			 * If we got this far, we have found a possible
391 			 * match already (match_s != NULL) so there is no
392 			 * reason to remember this one.
393 			 */
394 			continue;
395 		}
396 		/*
397 		 * Found a match.  We need to set hp_ctlr/hp_slave properly
398 		 * for the init routines but we also need to remember all
399 		 * the old values in case this doesn't pan out.
400 		 */
401 		if (match_s) {
402 			hd = match_s;
403 			old_c = hd->hp_ctlr;
404 			old_s = hd->hp_slave;
405 			if (hd->hp_ctlr < 0)
406 				hd->hp_ctlr = new_c;
407 			if (hd->hp_slave < 0)
408 				hd->hp_slave = new_s;
409 #ifdef DEBUG
410 			if (acdebug)
411 				printf("looking for %s%d at slave %d...",
412 				       hd->hp_driver->d_name,
413 				       hd->hp_unit, hd->hp_slave);
414 #endif
415 
416 			if ((*hd->hp_driver->d_init)(hd)) {
417 #ifdef DEBUG
418 				if (acdebug)
419 					printf("found\n");
420 #endif
421 				printf("%s%d at %s%d, slave %d",
422 				       hd->hp_driver->d_name, hd->hp_unit,
423 				       hc->hp_driver->d_name, hd->hp_ctlr,
424 				       hd->hp_slave);
425 				if (hd->hp_flags)
426 					printf(" flags 0x%x", hd->hp_flags);
427 				printf("\n");
428 				hd->hp_alive = 1;
429 				if (hd->hp_dk && dkn < DK_NDRIVE)
430 					hd->hp_dk = dkn++;
431 				else
432 					hd->hp_dk = -1;
433 				rescan = 1;
434 			} else {
435 #ifdef DEBUG
436 				if (acdebug)
437 					printf("not found\n");
438 #endif
439 				hd->hp_ctlr = old_c;
440 				hd->hp_slave = old_s;
441 			}
442 			/*
443 			 * XXX: This should be handled better.
444 			 * Re-scan a slave.  There are two reasons to do this.
445 			 * 1. It is possible to have both a tape and disk
446 			 *    (e.g. 7946) or two disks (e.g. 9122) at the
447 			 *    same slave address.  Here we need to rescan
448 			 *    looking only at entries with a different
449 			 *    physical unit number (hp_flags).
450 			 * 2. It is possible that an init failed because the
451 			 *    slave was there but of the wrong type.  In this
452 			 *    case it may still be possible to match the slave
453 			 *    to another ioconf entry of a different type.
454 			 *    Here we need to rescan looking only at entries
455 			 *    of different types.
456 			 * In both cases we avoid looking at undesirable
457 			 * ioconf entries of the same type by setting their
458 			 * alive fields to -1.
459 			 */
460 			if (rescan) {
461 				for (hd = hp_dinit; hd->hp_driver; hd++) {
462 					if (hd->hp_alive)
463 						continue;
464 					if (match_s->hp_alive == 1) {	/* 1 */
465 						if (hd->hp_flags == match_s->hp_flags)
466 							hd->hp_alive = -1;
467 					} else {			/* 2 */
468 						if (hd->hp_driver == match_s->hp_driver)
469 							hd->hp_alive = -1;
470 					}
471 				}
472 				s--;
473 				continue;
474 			}
475 		}
476 		/*
477 		 * Reset bogon alive fields prior to attempting next slave
478 		 */
479 		for (hd = hp_dinit; hd->hp_driver; hd++)
480 			if (hd->hp_alive == -1)
481 				hd->hp_alive = 0;
482 	}
483 }
484 
485 sctoaddr(addr)
486 	register int addr;
487 {
488 	if (addr == 7 && internalhpib)
489 		addr = internalhpib;
490 	else if (addr < 32)
491 		addr = IOV(EXTIOBASE + (addr * IOCARDSIZE));
492 	else
493 		addr = IOV(addr);
494 	return(addr);
495 }
496 
497 addrtosc(addr)
498 	register u_int addr;
499 {
500 	if (addr == internalhpib)
501 		addr = 7;
502 	else if (addr >= IOV(IOBASE)) {
503 		addr = UNIOV(addr);
504 		if (addr >= EXTIOBASE)
505 			addr = (addr - EXTIOBASE) / IOCARDSIZE;
506 	}
507 	return((int)addr);
508 }
509 
510 same_hw_device(hw, hd)
511 	struct hp_hw *hw;
512 	struct hp_device *hd;
513 {
514 	int found = 0;
515 
516 	switch (hw->hw_type) {
517 	case HPIB:
518 	case RD:
519 	case PPI:
520 	case CT:
521 		found = dr_type(hd->hp_driver, "hpib");
522 		break;
523 	case BITMAP:
524 		found = dr_type(hd->hp_driver, "grf");
525 		break;
526 	case NET:
527 		found = dr_type(hd->hp_driver, "le");
528 		break;
529 	case COMMDCA:
530 		found = dr_type(hd->hp_driver, "dca");
531 		break;
532 	case COMMDCL:
533 		found = dr_type(hd->hp_driver, "dcl");
534 		break;
535 	case COMMDCM:
536 		found = dr_type(hd->hp_driver, "dcm");
537 		break;
538 	case SCSI:
539 		found = dr_type(hd->hp_driver, "scsi");
540 		break;
541 	case FPA:    /* Unsupported so far */
542 	case VME:
543 	case FLINK:
544 	case MISC:
545 		break;
546 	}
547 	return(found);
548 }
549 
550 find_devs()
551 {
552 	short sc;
553 	u_char *id_reg;
554 	register int addr;
555 	register struct hp_hw *hw;
556 
557 	/*
558 	 * XXX record actual address of internal HP-IB if present.
559 	 */
560 	if (internalhpib)
561 		internalhpib = IOV(INTERNALHPIB);
562 
563 	hw = sc_table;
564 	for (sc = -1; sc < 32; sc++) {
565 		/*
566 		 * Probe all select codes + internal display addr
567 		 */
568 		if (sc == -1)
569 			addr = IOV(GRFIADDR);
570 		else
571 			addr = sctoaddr(sc);
572 		if (badaddr((caddr_t)addr))
573 			continue;
574 
575 		id_reg = (u_char *) addr;
576 		hw->hw_id = id_reg[1] & 0xff;
577 		hw->hw_sc = sc;
578 		hw->hw_addr = (char *) addr;
579 		/*
580 		 * Internal HP-IB on some machines (345/375) doesn't return
581 		 * consistant id info so we use the info gleaned from the
582 		 * boot ROMs SYSFLAG.
583 		 */
584 		if (sc == 7 && internalhpib) {
585 			hw->hw_name = "98624A";
586 			hw->hw_type = HPIB;
587 			hw++;
588 			continue;
589 		}
590 		/*
591 		 * XXX: the following could be in a big static table
592 		 */
593 		switch (hw->hw_id) {
594 		/* Null device? */
595 		case 0:
596 			break;
597 		case 2:
598 		case 128+2:
599 			hw->hw_name = "98626A";
600 			hw->hw_type = COMMDCA;
601 			break;
602 		case 3:
603 			hw->hw_name = "98622A";
604 			hw->hw_type = MISC;
605 			break;
606 		case 4:
607 			hw->hw_name = "98623A";
608 			hw->hw_type = MISC;
609 			break;
610 		case 5:
611 		case 128+5:
612 			hw->hw_name = "98642A";
613 			hw->hw_type = COMMDCM;
614 			break;
615 		case 6:
616 			hw->hw_name = "Parallel Port";
617 			hw->hw_type = PPORT;
618 			break;
619 		case 7:
620 		case 39:
621 		case 71:
622 		case 103:
623 			hw->hw_name = "98265A";
624 			hw->hw_type = SCSI;
625 			break;
626 		case 8:
627 			hw->hw_name = "98625B";
628 			hw->hw_type = HPIB;
629 			break;
630 		case 9:
631 			hw->hw_name = "98287A";
632 			hw->hw_type = KEYBOARD;
633 			break;
634 		case 10:
635 			hw->hw_name = "98635A";
636 			hw->hw_type = FPA;
637 			break;
638 		case 11:
639 			hw->hw_name = "Timer";
640 			hw->hw_type = MISC;
641 			break;
642 		case 18:
643 			hw->hw_name = "98640A";
644 			hw->hw_type = MISC;
645 			break;
646 		case 21:
647 			hw->hw_name = "98643A";
648 			hw->hw_type = NET;
649 			break;
650 		case 22:
651 			hw->hw_name = "98659A";
652 			hw->hw_type = MISC;
653 			break;
654 		case 25:
655 			hw->hw_name = "237";
656 			hw->hw_type = BITMAP;
657 			break;
658 		case 26:
659 			hw->hw_name = "Quad";
660 			hw->hw_type = MISC;
661 			break;
662 		case 27:
663 			hw->hw_name = "98253A";
664 			hw->hw_type = MISC;
665 			break;
666 		case 28:
667 			hw->hw_name = "98627A";
668 			hw->hw_type = BITMAP;
669 			break;
670 		case 29:
671 			hw->hw_name = "98633A";
672 			hw->hw_type = BITMAP;
673 			break;
674 		case 30:
675 			hw->hw_name = "98259A";
676 			hw->hw_type = MISC;
677 			break;
678 		case 31:
679 			hw->hw_name = "8741";
680 			hw->hw_type = MISC;
681 			break;
682 		case 49:
683 			hw->hw_name = "98577A";
684 			hw->hw_type = VME;
685 			sc++;
686 			break;
687 		case 52:
688 		case 128+52:
689 			hw->hw_name = "98628A";
690 			hw->hw_type = COMMDCL;
691 			break;
692 		case 57:
693 			hw->hw_type = BITMAP;
694 			hw->hw_id2 = id_reg[0x15];
695 			switch (hw->hw_id2) {
696 			case 1:
697 				hw->hw_name = "98700 ";
698 				break;
699 			case 2:
700 				hw->hw_name = "TOPCAT";
701 				break;
702 			case 4:
703 				hw->hw_name = "98720 ";
704 				sc++;
705 				break;
706 			case 5:
707 			case 6:
708 			case 7:
709 			case 9:
710 				hw->hw_name = "CATSEYE";
711 				break;
712 			case 8:
713 				hw->hw_name = "98730 ";
714 				sc++;
715 				break;
716 			default:
717 				hw->hw_name = "987xx ";
718 				break;
719 			}
720 			break;
721 		case 66:
722 		case 128+66:
723 			hw->hw_name = "98644A";
724 			hw->hw_type = COMMDCA;
725 			break;
726 		case 128:
727 			hw->hw_name = "98624A";
728 			hw->hw_type = HPIB;
729 			break;
730 		default:
731 			hw->hw_name = "DEFAULT";
732 			hw->hw_type = MISC;
733 			break;
734 		}
735 		hw++;
736 	}
737 }
738 
739 #if NCD > 0
740 #include "../dev/cdvar.h"
741 
742 find_cdevices()
743 {
744 	register struct cddevice *cd;
745 
746 	for (cd = cddevice; cd->cd_unit >= 0; cd++) {
747 		/*
748 		 * XXX
749 		 * Assign disk index first so that init routine
750 		 * can use it (saves having the driver drag around
751 		 * the cddevice pointer just to set up the dk_*
752 		 * info in the open routine).
753 		 */
754 		if (dkn < DK_NDRIVE)
755 			cd->cd_dk = dkn++;
756 		else
757 			cd->cd_dk = -1;
758 		if (cdinit(cd))
759 			printf("cd%d configured\n", cd->cd_unit);
760 		else if (cd->cd_dk >= 0) {
761 			cd->cd_dk = -1;
762 			dkn--;
763 		}
764 	}
765 }
766 #endif
767 
768 isrinit()
769 {
770 	register int i;
771 
772 	for (i = 0; i < NISR; i++)
773 		isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i];
774 }
775 
776 void
777 isrlink(isr)
778 	register struct isr *isr;
779 {
780 	int i = ISRIPL(isr->isr_ipl);
781 
782 	if (i < 0 || i >= NISR) {
783 		printf("bad IPL %d\n", i);
784 		panic("configure");
785 	}
786 	insque(isr, isrqueue[i].isr_back);
787 }
788 
789 /*
790  * Configure swap space and related parameters.
791  */
792 swapconf()
793 {
794 	register struct swdevt *swp;
795 	register int nblks;
796 
797 	for (swp = swdevt; swp->sw_dev; swp++)
798 		if (bdevsw[major(swp->sw_dev)].d_psize) {
799 			nblks =
800 			  (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
801 			if (nblks != -1 &&
802 			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
803 				swp->sw_nblks = nblks;
804 		}
805 	dumpconf();
806 }
807 
808 #define	DOSWAP			/* Change swdevt, argdev, and dumpdev too */
809 u_long	bootdev;		/* should be dev_t, but not until 32 bits */
810 
811 static	char devname[][2] = {
812 	0,0,		/* 0 = ct */
813 	0,0,		/* 1 = xx */
814 	'r','d',	/* 2 = rd */
815 	0,0,		/* 3 = sw */
816 	's','d',	/* 4 = rd */
817 };
818 
819 #define	PARTITIONMASK	0x7
820 #define	PARTITIONSHIFT	3
821 
822 /*
823  * Attempt to find the device from which we were booted.
824  * If we can do so, and not instructed not to do so,
825  * change rootdev to correspond to the load device.
826  */
827 setroot()
828 {
829 	register struct hp_ctlr *hc;
830 	register struct hp_device *hd;
831 	int  majdev, mindev, unit, part, adaptor;
832 	dev_t temp, orootdev;
833 	struct swdevt *swp;
834 
835 	if (boothowto & RB_DFLTROOT ||
836 	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
837 		return;
838 	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
839 	if (majdev > sizeof(devname) / sizeof(devname[0]))
840 		return;
841 	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
842 	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
843 	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
844 	/*
845 	 * First, find the controller type which support this device.
846 	 */
847 	for (hd = hp_dinit; hd->hp_driver; hd++)
848 		if (hd->hp_driver->d_name[0] == devname[majdev][0] &&
849 		    hd->hp_driver->d_name[1] == devname[majdev][1])
850 			break;
851 	if (hd->hp_driver == 0)
852 		return;
853 	/*
854 	 * Next, find the controller of that type corresponding to
855 	 * the adaptor number.
856 	 */
857 	for (hc = hp_cinit; hc->hp_driver; hc++)
858 		if (hc->hp_alive && hc->hp_unit == adaptor &&
859 		    hc->hp_driver == hd->hp_cdriver)
860 			break;
861 	if (hc->hp_driver == 0)
862 		return;
863 	/*
864 	 * Finally, find the device in question attached to that controller.
865 	 */
866 	for (hd = hp_dinit; hd->hp_driver; hd++)
867 		if (hd->hp_alive && hd->hp_slave == unit &&
868 		    hd->hp_cdriver == hc->hp_driver &&
869 		    hd->hp_ctlr == hc->hp_unit)
870 			break;
871 	if (hd->hp_driver == 0)
872 		return;
873 	mindev = hd->hp_unit;
874 	/*
875 	 * Form a new rootdev
876 	 */
877 	mindev = (mindev << PARTITIONSHIFT) + part;
878 	orootdev = rootdev;
879 	rootdev = makedev(majdev, mindev);
880 	/*
881 	 * If the original rootdev is the same as the one
882 	 * just calculated, don't need to adjust the swap configuration.
883 	 */
884 	if (rootdev == orootdev)
885 		return;
886 
887 	printf("Changing root device to %c%c%d%c\n",
888 		devname[majdev][0], devname[majdev][1],
889 		mindev >> PARTITIONSHIFT, part + 'a');
890 
891 #ifdef DOSWAP
892 	mindev &= ~PARTITIONMASK;
893 	for (swp = swdevt; swp->sw_dev; swp++) {
894 		if (majdev == major(swp->sw_dev) &&
895 		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
896 			temp = swdevt[0].sw_dev;
897 			swdevt[0].sw_dev = swp->sw_dev;
898 			swp->sw_dev = temp;
899 			break;
900 		}
901 	}
902 	if (swp->sw_dev == 0)
903 		return;
904 
905 	/*
906 	 * If argdev and dumpdev were the same as the old primary swap
907 	 * device, move them to the new primary swap device.
908 	 */
909 	if (temp == dumpdev)
910 		dumpdev = swdevt[0].sw_dev;
911 	if (temp == argdev)
912 		argdev = swdevt[0].sw_dev;
913 #endif
914 }
915 
916 strcmp(s1, s2)
917 	register char *s1, *s2;
918 {
919 	while (*s1 == *s2++)
920 		if (*s1++=='\0')
921 			return (0);
922 	return (*s1 - *--s2);
923 }
924