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
yyerror(s)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 *
ns(str)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 */
newdev(dp)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 */
mkconf(sysname)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 *
newflist(ftype)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
mkcomp(dp)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 *
connect(dev,num)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 *
huhcon(dev)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
init_dev(dp)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 */
check_nexus(dev,num)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
check_tz()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 */
checksystemspec(fl)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 */
verifysystemspecs()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 *
verifyswap(fl,checked,pchecked)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 */
verifycomp(fl)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 */
alreadychecked(dev,list,last)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
deverror(systemname,devtype)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*/
finddev(dev)1077 finddev(dev)
1078 dev_t dev;
1079 {
1080
1081 /* punt on this right now */
1082 return (1);
1083 }
1084