xref: /original-bsd/usr.sbin/config/config.y (revision c3e32dec)
1 %union {
2 	char	*str;
3 	int	val;
4 	struct	file_list *file;
5 	struct	idlst *lst;
6 }
7 
8 %token	AND
9 %token	ANY
10 %token	ARGS
11 %token	AT
12 %token	BIO
13 %token	COMMA
14 %token	CONFIG
15 %token	CONTROLLER
16 %token	CPU
17 %token	CSR
18 %token	DEVICE
19 %token	DISK
20 %token	DRIVE
21 %token	DRQ
22 %token	DST
23 %token	DUMPS
24 %token	EQUALS
25 %token	FLAGS
26 %token	HZ
27 %token	IDENT
28 %token	INTERLEAVE
29 %token	IOMEM
30 %token	IOSIZ
31 %token	IRQ
32 %token	MACHINE
33 %token	MAJOR
34 %token	MASTER
35 %token	MAXUSERS
36 %token	MINOR
37 %token	MINUS
38 %token	NET
39 %token	NEXUS
40 %token	ON
41 %token	OPTIONS
42 %token	MAKEOPTIONS
43 %token	PORT
44 %token	PRIORITY
45 %token	PSEUDO_DEVICE
46 %token	ROOT
47 %token	SEMICOLON
48 %token	SEQUENTIAL
49 %token	SIZE
50 %token	SLAVE
51 %token	SWAP
52 %token	TIMEZONE
53 %token	TTY
54 %token	TRACE
55 %token	VECTOR
56 
57 %token	<str>	ID
58 %token	<val>	NUMBER
59 %token	<val>	FPNUMBER
60 
61 %type	<str>	Save_id
62 %type	<str>	Opt_value
63 %type	<str>	Dev
64 %type	<lst>	Id_list
65 %type	<val>	optional_size
66 %type	<val>	optional_sflag
67 %type	<str>	device_name
68 %type	<val>	major_minor
69 %type	<val>	arg_device_spec
70 %type	<val>	root_device_spec
71 %type	<val>	dump_device_spec
72 %type	<file>	swap_device_spec
73 %type	<file>	comp_device_spec
74 
75 %{
76 
77 /*
78  * Copyright (c) 1988, 1993
79  *	The Regents of the University of California.  All rights reserved.
80  *
81  * %sccs.include.redist.c%
82  *
83  *	@(#)config.y	8.1 (Berkeley) 06/06/93
84  */
85 
86 #include "config.h"
87 #include <ctype.h>
88 #include <stdio.h>
89 
90 struct	device cur;
91 struct	device *curp = 0;
92 char	*temp_id;
93 char	*val_id;
94 
95 %}
96 %%
97 Configuration:
98 	Many_specs
99 		= { verifysystemspecs(); }
100 		;
101 
102 Many_specs:
103 	Many_specs Spec
104 		|
105 	/* lambda */
106 		;
107 
108 Spec:
109 	Device_spec SEMICOLON
110 	      = { newdev(&cur); } |
111 	Config_spec SEMICOLON
112 		|
113 	TRACE SEMICOLON
114 	      = { do_trace = !do_trace; } |
115 	SEMICOLON
116 		|
117 	error SEMICOLON
118 		;
119 
120 Config_spec:
121 	MACHINE Save_id
122 	    = {
123 		if (!strcmp($2, "vax")) {
124 			machine = MACHINE_VAX;
125 			machinename = "vax";
126 		} else if (!strcmp($2, "tahoe")) {
127 			machine = MACHINE_TAHOE;
128 			machinename = "tahoe";
129 		} else if (!strcmp($2, "hp300")) {
130 			machine = MACHINE_HP300;
131 			machinename = "hp300";
132 		} else if (!strcmp($2, "i386")) {
133 			machine = MACHINE_I386;
134 			machinename = "i386";
135 		} else if (!strcmp($2, "mips")) {
136 			machine = MACHINE_MIPS;
137 			machinename = "mips";
138 		} else if (!strcmp($2, "pmax")) {
139 			machine = MACHINE_PMAX;
140 			machinename = "pmax";
141 		} else if (!strcmp($2, "luna68k")) {
142 			machine = MACHINE_LUNA68K;
143 			machinename = "luna68k";
144 		} else if (!strcmp($2, "news3400")) {
145 			machine = MACHINE_NEWS3400;
146 			machinename = "news3400";
147 		} else
148 			yyerror("Unknown machine type");
149 	      } |
150 	CPU Save_id
151 	      = {
152 		struct cputype *cp =
153 		    (struct cputype *)malloc(sizeof (struct cputype));
154 		cp->cpu_name = ns($2);
155 		cp->cpu_next = cputype;
156 		cputype = cp;
157 		free(temp_id);
158 	      } |
159 	OPTIONS Opt_list
160 		|
161 	MAKEOPTIONS Mkopt_list
162 		|
163 	IDENT ID
164 	      = { ident = ns($2); } |
165 	System_spec
166 		|
167 	HZ NUMBER
168 	      = { hz = $2; }|
169 	TIMEZONE NUMBER
170 	      = { zone = 60 * $2; check_tz(); } |
171 	TIMEZONE NUMBER DST NUMBER
172 	      = { zone = 60 * $2; dst = $4; check_tz(); } |
173 	TIMEZONE NUMBER DST
174 	      = { zone = 60 * $2; dst = 1; check_tz(); } |
175 	TIMEZONE FPNUMBER
176 	      = { zone = $2; check_tz(); } |
177 	TIMEZONE FPNUMBER DST NUMBER
178 	      = { zone = $2; dst = $4; check_tz(); } |
179 	TIMEZONE FPNUMBER DST
180 	      = { zone = $2; dst = 1; check_tz(); } |
181 	TIMEZONE MINUS NUMBER
182 	      = { zone = -60 * $3; check_tz(); } |
183 	TIMEZONE MINUS NUMBER DST NUMBER
184 	      = { zone = -60 * $3; dst = $5; check_tz(); } |
185 	TIMEZONE MINUS NUMBER DST
186 	      = { zone = -60 * $3; dst = 1; check_tz(); } |
187 	TIMEZONE MINUS FPNUMBER
188 	      = { zone = -$3; check_tz(); } |
189 	TIMEZONE MINUS FPNUMBER DST NUMBER
190 	      = { zone = -$3; dst = $5; check_tz(); } |
191 	TIMEZONE MINUS FPNUMBER DST
192 	      = { zone = -$3; dst = 1; check_tz(); } |
193 	MAXUSERS NUMBER
194 	      = { maxusers = $2; };
195 
196 System_spec:
197 	  System_id System_parameter_list
198 		= { checksystemspec(*confp); }
199 	;
200 
201 System_id:
202 	  CONFIG Save_id
203 		= { mkconf($2); }
204 	;
205 
206 System_parameter_list:
207 	  System_parameter_list System_parameter
208 	| System_parameter
209 	;
210 
211 System_parameter:
212 	  swap_spec
213 	| root_spec
214 	| dump_spec
215 	| arg_spec
216 	;
217 
218 swap_spec:
219 	  SWAP optional_on swap_device_list
220 	;
221 
222 swap_device_list:
223 	  swap_device_list AND swap_device
224 	| swap_device
225 	;
226 
227 swap_device:
228 	  swap_device_spec optional_size optional_sflag
229 	      = { mkswap(*confp, $1, $2, $3); }
230 	;
231 
232 swap_device_spec:
233 	  device_name
234 		= {
235 			struct file_list *fl = newflist(SWAPSPEC);
236 
237 			if (eq($1, "generic"))
238 				fl->f_fn = $1;
239 			else {
240 				fl->f_swapdev = nametodev($1, 0, 'b');
241 				fl->f_fn = devtoname(fl->f_swapdev);
242 			}
243 			$$ = fl;
244 		}
245 	| major_minor
246 		= {
247 			struct file_list *fl = newflist(SWAPSPEC);
248 
249 			fl->f_swapdev = $1;
250 			fl->f_fn = devtoname($1);
251 			$$ = fl;
252 		}
253 	;
254 
255 root_spec:
256 	  ROOT optional_on root_device_spec
257 		= {
258 			struct file_list *fl = *confp;
259 
260 			if (fl && fl->f_rootdev != NODEV)
261 				yyerror("extraneous root device specification");
262 			else
263 				fl->f_rootdev = $3;
264 		}
265 	;
266 
267 root_device_spec:
268 	  device_name
269 		= { $$ = nametodev($1, 0, 'a'); }
270 	| major_minor
271 	;
272 
273 dump_spec:
274 	  DUMPS optional_on dump_device_spec
275 		= {
276 			struct file_list *fl = *confp;
277 
278 			if (fl && fl->f_dumpdev != NODEV)
279 				yyerror("extraneous dump device specification");
280 			else
281 				fl->f_dumpdev = $3;
282 		}
283 
284 	;
285 
286 dump_device_spec:
287 	  device_name
288 		= { $$ = nametodev($1, 0, 'b'); }
289 	| major_minor
290 	;
291 
292 arg_spec:
293 	  ARGS optional_on arg_device_spec
294 		= { yyerror("arg device specification obsolete, ignored"); }
295 	;
296 
297 arg_device_spec:
298 	  device_name
299 		= { $$ = nametodev($1, 0, 'b'); }
300 	| major_minor
301 	;
302 
303 major_minor:
304 	  MAJOR NUMBER MINOR NUMBER
305 		= { $$ = makedev($2, $4); }
306 	;
307 
308 optional_on:
309 	  ON
310 	| /* empty */
311 	;
312 
313 optional_size:
314 	  SIZE NUMBER
315 	      = { $$ = $2; }
316 	| /* empty */
317 	      = { $$ = 0; }
318 	;
319 
320 optional_sflag:
321 	  SEQUENTIAL
322 	      = { $$ = 2; }
323 	| /* empty */
324 	      = { $$ = 0; }
325 	;
326 
327 device_name:
328 	  Save_id
329 		= { $$ = $1; }
330 	| Save_id NUMBER
331 		= {
332 			char buf[80];
333 
334 			(void) sprintf(buf, "%s%d", $1, $2);
335 			$$ = ns(buf); free($1);
336 		}
337 	| Save_id NUMBER ID
338 		= {
339 			char buf[80];
340 
341 			(void) sprintf(buf, "%s%d%s", $1, $2, $3);
342 			$$ = ns(buf); free($1);
343 		}
344 	;
345 
346 Opt_list:
347 	Opt_list COMMA Option
348 		|
349 	Option
350 		;
351 
352 Option:
353 	Save_id
354 	      = {
355 		struct opt *op = (struct opt *)malloc(sizeof (struct opt));
356 		op->op_name = ns($1);
357 		op->op_next = opt;
358 		op->op_value = 0;
359 		opt = op;
360 		free(temp_id);
361 	      } |
362 	Save_id EQUALS Opt_value
363 	      = {
364 		struct opt *op = (struct opt *)malloc(sizeof (struct opt));
365 		op->op_name = ns($1);
366 		op->op_next = opt;
367 		op->op_value = ns($3);
368 		opt = op;
369 		free(temp_id);
370 		free(val_id);
371 	      } ;
372 
373 Opt_value:
374 	ID
375 	      = { $$ = val_id = ns($1); } |
376 	NUMBER
377 	      = {
378 		char nb[16];
379 	        (void) sprintf(nb, "%d", $1);
380 		$$ = val_id = ns(nb);
381 	      } ;
382 
383 
384 Save_id:
385 	ID
386 	      = { $$ = temp_id = ns($1); }
387 	;
388 
389 Mkopt_list:
390 	Mkopt_list COMMA Mkoption
391 		|
392 	Mkoption
393 		;
394 
395 Mkoption:
396 	Save_id EQUALS Opt_value
397 	      = {
398 		struct opt *op = (struct opt *)malloc(sizeof (struct opt));
399 		op->op_name = ns($1);
400 		op->op_next = mkopt;
401 		op->op_value = ns($3);
402 		mkopt = op;
403 		free(temp_id);
404 		free(val_id);
405 	      } ;
406 
407 Dev:
408 	ID
409 	      = { $$ = ns($1); }
410 	;
411 
412 Device_spec:
413 	DEVICE Dev_name Dev_info Int_spec
414 	      = { cur.d_type = DEVICE; } |
415 	MASTER Dev_name Dev_info Int_spec
416 	      = { cur.d_type = MASTER; } |
417 	DISK Dev_name Dev_info Int_spec
418 	      = { cur.d_dk = 1; cur.d_type = DEVICE; } |
419 	CONTROLLER Dev_name Dev_info Int_spec
420 	      = { cur.d_type = CONTROLLER; } |
421 	PSEUDO_DEVICE Init_dev Dev
422 	      = {
423 		cur.d_name = $3;
424 		cur.d_type = PSEUDO_DEVICE;
425 		} |
426 	PSEUDO_DEVICE Init_dev Dev NUMBER
427 	      = {
428 		cur.d_name = $3;
429 		cur.d_type = PSEUDO_DEVICE;
430 		cur.d_slave = $4;
431 		} |
432 	PSEUDO_DEVICE Dev_name Cdev_init Cdev_info
433 	      = {
434 		if (!eq(cur.d_name, "cd"))
435 			yyerror("improper spec for pseudo-device");
436 		seen_cd = 1;
437 		cur.d_type = DEVICE;
438 		verifycomp(*compp);
439 		};
440 
441 Cdev_init:
442 	/* lambda */
443 	      = { mkcomp(&cur); };
444 
445 Cdev_info:
446 	  optional_on comp_device_list comp_option_list
447 	;
448 
449 comp_device_list:
450 	  comp_device_list AND comp_device
451 	| comp_device
452 	;
453 
454 comp_device:
455 	  comp_device_spec
456 	      = { addcomp(*compp, $1); }
457 	;
458 
459 comp_device_spec:
460 	  device_name
461 		= {
462 			struct file_list *fl = newflist(COMPSPEC);
463 
464 			fl->f_compdev = nametodev($1, 0, 'c');
465 			fl->f_fn = devtoname(fl->f_compdev);
466 			$$ = fl;
467 		}
468 	| major_minor
469 		= {
470 			struct file_list *fl = newflist(COMPSPEC);
471 
472 			fl->f_compdev = $1;
473 			fl->f_fn = devtoname($1);
474 			$$ = fl;
475 		}
476 	;
477 
478 comp_option_list:
479 	  comp_option_list comp_option
480 		|
481 	  /* lambda */
482 		;
483 
484 comp_option:
485 	INTERLEAVE NUMBER
486 	      = { cur.d_pri = $2; } |
487 	FLAGS NUMBER
488 	      = { cur.d_flags = $2; };
489 
490 Dev_name:
491 	Init_dev Dev NUMBER
492 	      = {
493 		cur.d_name = $2;
494 		if (eq($2, "mba"))
495 			seen_mba = 1;
496 		else if (eq($2, "uba"))
497 			seen_uba = 1;
498 		else if (eq($2, "vba"))
499 			seen_vba = 1;
500 		else if (eq($2, "isa"))
501 			seen_isa = 1;
502 		cur.d_unit = $3;
503 		};
504 
505 Init_dev:
506 	/* lambda */
507 	      = { init_dev(&cur); };
508 
509 Dev_info:
510 	Con_info Info_list
511 		|
512 	/* lambda */
513 		;
514 
515 Con_info:
516 	AT Dev NUMBER
517 	      = {
518 		if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) {
519 			(void) sprintf(errbuf,
520 				"%s must be connected to a nexus", cur.d_name);
521 			yyerror(errbuf);
522 		}
523 		cur.d_conn = connect($2, $3);
524 		} |
525 	AT NEXUS NUMBER
526 	      = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; };
527 
528 Info_list:
529 	Info_list Info
530 		|
531 	/* lambda */
532 		;
533 
534 Info:
535 	CSR NUMBER
536 	      = { cur.d_addr = $2; } |
537 	DRIVE NUMBER
538 	      = { cur.d_drive = $2; } |
539 	SLAVE NUMBER
540 	      = {
541 		if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS &&
542 		    cur.d_conn->d_type == MASTER)
543 			cur.d_slave = $2;
544 		else
545 			yyerror("can't specify slave--not to master");
546 		} |
547 	IRQ NUMBER
548 	      = { cur.d_irq = $2; } |
549 	DRQ NUMBER
550 	      = { cur.d_drq = $2; } |
551 	IOMEM NUMBER
552 	      = { cur.d_maddr = $2; } |
553 	IOSIZ NUMBER
554 	      = { cur.d_msize = $2; } |
555 	PORT device_name
556 	      = { cur.d_port = ns($2); } |
557 	PORT NUMBER
558 	      = { cur.d_portn = $2; } |
559 	TTY
560 	      = { cur.d_mask = "tty"; } |
561 	BIO
562 	      = { cur.d_mask = "bio"; } |
563 	NET
564 	      = { cur.d_mask = "net"; } |
565 	FLAGS NUMBER
566 	      = { cur.d_flags = $2; };
567 
568 Int_spec:
569 	VECTOR Id_list
570 	      = { cur.d_vec = $2; } |
571 	PRIORITY NUMBER
572 	      = { cur.d_pri = $2; } |
573 	/* lambda */
574 		;
575 
576 Id_list:
577 	Save_id
578 	      = {
579 		struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
580 		a->id = $1; a->id_next = 0; $$ = a;
581 		} |
582 	Save_id Id_list =
583 		{
584 		struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
585 	        a->id = $1; a->id_next = $2; $$ = a;
586 		};
587 
588 %%
589 
590 yyerror(s)
591 	char *s;
592 {
593 
594 	fprintf(stderr, "config: line %d: %s\n", yyline + 1, s);
595 }
596 
597 /*
598  * return the passed string in a new space
599  */
600 char *
601 ns(str)
602 	register char *str;
603 {
604 	register char *cp;
605 
606 	cp = malloc((unsigned)(strlen(str)+1));
607 	(void) strcpy(cp, str);
608 	return (cp);
609 }
610 
611 /*
612  * add a device to the list of devices
613  */
614 newdev(dp)
615 	register struct device *dp;
616 {
617 	register struct device *np;
618 
619 	np = (struct device *) malloc(sizeof *np);
620 	*np = *dp;
621 	np->d_next = 0;
622 	if (curp == 0)
623 		dtab = np;
624 	else
625 		curp->d_next = np;
626 	curp = np;
627 }
628 
629 /*
630  * note that a configuration should be made
631  */
632 mkconf(sysname)
633 	char *sysname;
634 {
635 	register struct file_list *fl, **flp;
636 
637 	fl = (struct file_list *) malloc(sizeof *fl);
638 	fl->f_type = SYSTEMSPEC;
639 	fl->f_needs = sysname;
640 	fl->f_rootdev = NODEV;
641 	fl->f_dumpdev = NODEV;
642 	fl->f_fn = 0;
643 	fl->f_next = 0;
644 	for (flp = confp; *flp; flp = &(*flp)->f_next)
645 		;
646 	*flp = fl;
647 	confp = flp;
648 }
649 
650 struct file_list *
651 newflist(ftype)
652 	u_char ftype;
653 {
654 	struct file_list *fl = (struct file_list *)malloc(sizeof (*fl));
655 
656 	fl->f_type = ftype;
657 	fl->f_next = 0;
658 	fl->f_swapdev = NODEV;
659 	fl->f_swapsize = 0;
660 	fl->f_needs = 0;
661 	fl->f_fn = 0;
662 	return (fl);
663 }
664 
665 /*
666  * Add a swap device to the system's configuration
667  */
668 mkswap(system, fl, size, flag)
669 	struct file_list *system, *fl;
670 	int size, flag;
671 {
672 	register struct file_list **flp;
673 	char name[80];
674 
675 	if (system == 0 || system->f_type != SYSTEMSPEC) {
676 		yyerror("\"swap\" spec precedes \"config\" specification");
677 		return;
678 	}
679 	if (size < 0) {
680 		yyerror("illegal swap partition size");
681 		return;
682 	}
683 	/*
684 	 * Append swap description to the end of the list.
685 	 */
686 	flp = &system->f_next;
687 	for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next)
688 		;
689 	fl->f_next = *flp;
690 	*flp = fl;
691 	fl->f_swapsize = size;
692 	fl->f_swapflag = flag;
693 	/*
694 	 * If first swap device for this system,
695 	 * set up f_fn field to insure swap
696 	 * files are created with unique names.
697 	 */
698 	if (system->f_fn)
699 		return;
700 	if (eq(fl->f_fn, "generic"))
701 		system->f_fn = ns(fl->f_fn);
702 	else
703 		system->f_fn = ns(system->f_needs);
704 }
705 
706 mkcomp(dp)
707 	register struct device *dp;
708 {
709 	register struct file_list *fl, **flp;
710 	char buf[80];
711 
712 	fl = (struct file_list *) malloc(sizeof *fl);
713 	fl->f_type = COMPDEVICE;
714 	fl->f_compinfo = dp->d_unit;
715 	fl->f_fn = ns(dp->d_name);
716 	(void) sprintf(buf, "%s%d", dp->d_name, dp->d_unit);
717 	fl->f_needs = ns(buf);
718 	fl->f_next = 0;
719 	for (flp = compp; *flp; flp = &(*flp)->f_next)
720 		;
721 	*flp = fl;
722 	compp = flp;
723 }
724 
725 addcomp(compdev, fl)
726 	struct file_list *compdev, *fl;
727 {
728 	register struct file_list **flp;
729 	char name[80];
730 
731 	if (compdev == 0 || compdev->f_type != COMPDEVICE) {
732 		yyerror("component spec precedes device specification");
733 		return;
734 	}
735 	/*
736 	 * Append description to the end of the list.
737 	 */
738 	flp = &compdev->f_next;
739 	for (; *flp && (*flp)->f_type == COMPSPEC; flp = &(*flp)->f_next)
740 		;
741 	fl->f_next = *flp;
742 	*flp = fl;
743 }
744 
745 /*
746  * find the pointer to connect to the given device and number.
747  * returns 0 if no such device and prints an error message
748  */
749 struct device *
750 connect(dev, num)
751 	register char *dev;
752 	register int num;
753 {
754 	register struct device *dp;
755 	struct device *huhcon();
756 
757 	if (num == QUES)
758 		return (huhcon(dev));
759 	for (dp = dtab; dp != 0; dp = dp->d_next) {
760 		if ((num != dp->d_unit) || !eq(dev, dp->d_name))
761 			continue;
762 		if (dp->d_type != CONTROLLER && dp->d_type != MASTER) {
763 			(void) sprintf(errbuf,
764 			    "%s connected to non-controller", dev);
765 			yyerror(errbuf);
766 			return (0);
767 		}
768 		return (dp);
769 	}
770 	(void) sprintf(errbuf, "%s %d not defined", dev, num);
771 	yyerror(errbuf);
772 	return (0);
773 }
774 
775 /*
776  * connect to an unspecific thing
777  */
778 struct device *
779 huhcon(dev)
780 	register char *dev;
781 {
782 	register struct device *dp, *dcp;
783 	struct device rdev;
784 	int oldtype;
785 
786 	/*
787 	 * First make certain that there are some of these to wildcard on
788 	 */
789 	for (dp = dtab; dp != 0; dp = dp->d_next)
790 		if (eq(dp->d_name, dev))
791 			break;
792 	if (dp == 0) {
793 		(void) sprintf(errbuf, "no %s's to wildcard", dev);
794 		yyerror(errbuf);
795 		return (0);
796 	}
797 	oldtype = dp->d_type;
798 	dcp = dp->d_conn;
799 	/*
800 	 * Now see if there is already a wildcard entry for this device
801 	 * (e.g. Search for a "uba ?")
802 	 */
803 	for (; dp != 0; dp = dp->d_next)
804 		if (eq(dev, dp->d_name) && dp->d_unit == -1)
805 			break;
806 	/*
807 	 * If there isn't, make one because everything needs to be connected
808 	 * to something.
809 	 */
810 	if (dp == 0) {
811 		dp = &rdev;
812 		init_dev(dp);
813 		dp->d_unit = QUES;
814 		dp->d_name = ns(dev);
815 		dp->d_type = oldtype;
816 		newdev(dp);
817 		dp = curp;
818 		/*
819 		 * Connect it to the same thing that other similar things are
820 		 * connected to, but make sure it is a wildcard unit
821 		 * (e.g. up connected to sc ?, here we make connect sc? to a
822 		 * uba?).  If other things like this are on the NEXUS or
823 		 * if they aren't connected to anything, then make the same
824 		 * connection, else call ourself to connect to another
825 		 * unspecific device.
826 		 */
827 		if (dcp == TO_NEXUS || dcp == 0)
828 			dp->d_conn = dcp;
829 		else
830 			dp->d_conn = connect(dcp->d_name, QUES);
831 	}
832 	return (dp);
833 }
834 
835 init_dev(dp)
836 	register struct device *dp;
837 {
838 
839 	dp->d_name = "OHNO!!!";
840 	dp->d_type = DEVICE;
841 	dp->d_conn = 0;
842 	dp->d_vec = 0;
843 	dp->d_addr = dp->d_flags = dp->d_dk = 0;
844 	dp->d_pri = -1;
845 	dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN;
846 	dp->d_port = (char *)0;
847 	dp->d_portn = 0;
848 	dp->d_irq = -1;
849 	dp->d_drq = -1;
850 	dp->d_maddr = 0;
851 	dp->d_msize = 0;
852 	dp->d_mask = "null";
853 }
854 
855 /*
856  * make certain that this is a reasonable type of thing to connect to a nexus
857  */
858 check_nexus(dev, num)
859 	register struct device *dev;
860 	int num;
861 {
862 
863 	switch (machine) {
864 
865 	case MACHINE_VAX:
866 		if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") &&
867 		    !eq(dev->d_name, "bi"))
868 			yyerror("only uba's, mba's, and bi's should be connected to the nexus");
869 		if (num != QUES)
870 			yyerror("can't give specific nexus numbers");
871 		break;
872 
873 	case MACHINE_TAHOE:
874 		if (!eq(dev->d_name, "vba"))
875 			yyerror("only vba's should be connected to the nexus");
876 		break;
877 
878 	case MACHINE_HP300:
879 	case MACHINE_LUNA68K:
880 		if (num != QUES)
881 			dev->d_addr = num;
882 		break;
883 
884 	case MACHINE_I386:
885 		if (!eq(dev->d_name, "isa"))
886 			yyerror("only isa's should be connected to the nexus");
887 		break;
888 
889 	case MACHINE_NEWS3400:
890 		if (!eq(dev->d_name, "iop") && !eq(dev->d_name, "hb") &&
891 		    !eq(dev->d_name, "vme"))
892 			yyerror("only iop's, hb's and vme's should be connected to the nexus");
893 		break;
894 	}
895 }
896 
897 /*
898  * Check the timezone to make certain it is sensible
899  */
900 
901 check_tz()
902 {
903 	if (abs(zone) > 12 * 60)
904 		yyerror("timezone is unreasonable");
905 	else
906 		hadtz = 1;
907 }
908 
909 /*
910  * Check system specification and apply defaulting
911  * rules on root, argument, dump, and swap devices.
912  */
913 checksystemspec(fl)
914 	register struct file_list *fl;
915 {
916 	char buf[BUFSIZ];
917 	register struct file_list *swap;
918 	int generic;
919 
920 	if (fl == 0 || fl->f_type != SYSTEMSPEC) {
921 		yyerror("internal error, bad system specification");
922 		exit(1);
923 	}
924 	swap = fl->f_next;
925 	generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic");
926 	if (fl->f_rootdev == NODEV && !generic) {
927 		yyerror("no root device specified");
928 		exit(1);
929 	}
930 	/*
931 	 * Default swap area to be in 'b' partition of root's
932 	 * device.  If root specified to be other than on 'a'
933 	 * partition, give warning, something probably amiss.
934 	 */
935 	if (swap == 0 || swap->f_type != SWAPSPEC) {
936 		dev_t dev;
937 
938 		swap = newflist(SWAPSPEC);
939 		dev = fl->f_rootdev;
940 		if (minor(dev) & 07) {
941 			(void) sprintf(buf,
942 "Warning, swap defaulted to 'b' partition with root on '%c' partition",
943 				(minor(dev) & 07) + 'a');
944 			yyerror(buf);
945 		}
946 		swap->f_swapdev =
947 		   makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a'));
948 		swap->f_fn = devtoname(swap->f_swapdev);
949 		mkswap(fl, swap, 0);
950 	}
951 	/*
952 	 * Make sure a generic swap isn't specified, along with
953 	 * other stuff (user must really be confused).
954 	 */
955 	if (generic) {
956 		if (fl->f_rootdev != NODEV)
957 			yyerror("root device specified with generic swap");
958 		if (fl->f_dumpdev != NODEV)
959 			yyerror("dump device specified with generic swap");
960 		return;
961 	}
962 	/*
963 	 * Default dump device and warn if place is not a
964 	 * swap area.
965 	 */
966 	if (fl->f_dumpdev == NODEV)
967 		fl->f_dumpdev = swap->f_swapdev;
968 	if (fl->f_dumpdev != swap->f_swapdev) {
969 		struct file_list *p = swap->f_next;
970 
971 		for (; p && p->f_type == SWAPSPEC; p = p->f_next)
972 			if (fl->f_dumpdev == p->f_swapdev)
973 				return;
974 		(void) sprintf(buf,
975 		    "Warning: dump device is not a swap partition");
976 		yyerror(buf);
977 	}
978 }
979 
980 /*
981  * Verify all devices specified in the system specification
982  * are present in the device specifications.
983  */
984 verifysystemspecs()
985 {
986 	register struct file_list *fl;
987 	dev_t checked[50], *verifyswap();
988 	register dev_t *pchecked = checked;
989 
990 	for (fl = conf_list; fl; fl = fl->f_next) {
991 		if (fl->f_type != SYSTEMSPEC)
992 			continue;
993 		if (!finddev(fl->f_rootdev))
994 			deverror(fl->f_needs, "root");
995 		*pchecked++ = fl->f_rootdev;
996 		pchecked = verifyswap(fl->f_next, checked, pchecked);
997 #define	samedev(dev1, dev2) \
998 	((minor(dev1) &~ 07) != (minor(dev2) &~ 07))
999 		if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) {
1000 			if (!finddev(fl->f_dumpdev))
1001 				deverror(fl->f_needs, "dump");
1002 			*pchecked++ = fl->f_dumpdev;
1003 		}
1004 	}
1005 }
1006 
1007 /*
1008  * Do as above, but for swap devices.
1009  */
1010 dev_t *
1011 verifyswap(fl, checked, pchecked)
1012 	register struct file_list *fl;
1013 	dev_t checked[];
1014 	register dev_t *pchecked;
1015 {
1016 
1017 	for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) {
1018 		if (eq(fl->f_fn, "generic"))
1019 			continue;
1020 		if (alreadychecked(fl->f_swapdev, checked, pchecked))
1021 			continue;
1022 		if (!finddev(fl->f_swapdev))
1023 			fprintf(stderr,
1024 			   "config: swap device %s not configured", fl->f_fn);
1025 		*pchecked++ = fl->f_swapdev;
1026 	}
1027 	return (pchecked);
1028 }
1029 
1030 /*
1031  * Verify that components of a compound device have themselves been config'ed
1032  */
1033 verifycomp(fl)
1034 	register struct file_list *fl;
1035 {
1036 	char *dname = fl->f_needs;
1037 
1038 	for (fl = fl->f_next; fl; fl = fl->f_next) {
1039 		if (fl->f_type != COMPSPEC || finddev(fl->f_compdev))
1040 			continue;
1041 		fprintf(stderr,
1042 			"config: %s: component device %s not configured\n",
1043 			dname, fl->f_needs);
1044 	}
1045 }
1046 
1047 /*
1048  * Has a device already been checked
1049  * for it's existence in the configuration?
1050  */
1051 alreadychecked(dev, list, last)
1052 	dev_t dev, list[];
1053 	register dev_t *last;
1054 {
1055 	register dev_t *p;
1056 
1057 	for (p = list; p < last; p++)
1058 		if (samedev(*p, dev))
1059 			return (1);
1060 	return (0);
1061 }
1062 
1063 deverror(systemname, devtype)
1064 	char *systemname, *devtype;
1065 {
1066 
1067 	fprintf(stderr, "config: %s: %s device not configured\n",
1068 		systemname, devtype);
1069 }
1070 
1071 /*
1072  * Look for the device in the list of
1073  * configured hardware devices.  Must
1074  * take into account stuff wildcarded.
1075  */
1076 /*ARGSUSED*/
1077 finddev(dev)
1078 	dev_t dev;
1079 {
1080 
1081 	/* punt on this right now */
1082 	return (1);
1083 }
1084