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