document U= mailer field
[unix-history] / usr / src / usr.sbin / config / config.y
CommitLineData
22d68ad0
BJ
1%union {
2 char *str;
3 int val;
36edb824 4 struct file_list *file;
22d68ad0
BJ
5 struct idlst *lst;
6}
7
36edb824
SL
8%token AND
9%token ANY
10%token ARGS
11%token AT
1b6c65cb 12%token BIO
36edb824
SL
13%token COMMA
14%token CONFIG
15%token CONTROLLER
16%token CPU
17%token CSR
18%token DEVICE
19%token DISK
20%token DRIVE
1b6c65cb 21%token DRQ
36edb824
SL
22%token DST
23%token DUMPS
24%token EQUALS
25%token FLAGS
26%token HZ
27%token IDENT
6e5546fb 28%token INTERLEAVE
1b6c65cb
WN
29%token IOMEM
30%token IOSIZ
31%token IRQ
f025f13d 32%token MACHINE
36edb824
SL
33%token MAJOR
34%token MASTER
35%token MAXUSERS
36edb824
SL
36%token MINOR
37%token MINUS
1b6c65cb 38%token NET
36edb824
SL
39%token NEXUS
40%token ON
41%token OPTIONS
7c1d4665 42%token MAKEOPTIONS
1b6c65cb 43%token PORT
36edb824
SL
44%token PRIORITY
45%token PSEUDO_DEVICE
46%token ROOT
47%token SEMICOLON
6e5546fb 48%token SEQUENTIAL
36edb824
SL
49%token SIZE
50%token SLAVE
51%token SWAP
52%token TIMEZONE
1b6c65cb 53%token TTY
36edb824 54%token TRACE
36edb824 55%token VECTOR
22d68ad0
BJ
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
36edb824 65%type <val> optional_size
6e5546fb 66%type <val> optional_sflag
36edb824
SL
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
6e5546fb 73%type <file> comp_device_spec
22d68ad0 74
2f47f1cc 75%{
0bf41cfc 76
cd68466f 77/*
f3c08ca3
KB
78 * Copyright (c) 1988, 1993
79 * The Regents of the University of California. All rights reserved.
cd68466f 80 *
32ce521f 81 * %sccs.include.redist.c%
67259f7b 82 *
f3c08ca3 83 * @(#)config.y 8.1 (Berkeley) %G%
cd68466f 84 */
0bf41cfc 85
2f47f1cc 86#include "config.h"
36edb824 87#include <ctype.h>
2f47f1cc 88#include <stdio.h>
f025f13d
BJ
89
90struct device cur;
91struct device *curp = 0;
92char *temp_id;
93char *val_id;
94
2f47f1cc
MT
95%}
96%%
97Configuration:
98 Many_specs
36edb824 99 = { verifysystemspecs(); }
22d68ad0 100 ;
2f47f1cc
MT
101
102Many_specs:
103 Many_specs Spec
22d68ad0
BJ
104 |
105 /* lambda */
106 ;
2f47f1cc
MT
107
108Spec:
22d68ad0
BJ
109 Device_spec SEMICOLON
110 = { newdev(&cur); } |
111 Config_spec SEMICOLON
112 |
113 TRACE SEMICOLON
114 = { do_trace = !do_trace; } |
115 SEMICOLON
116 |
2f47f1cc 117 error SEMICOLON
22d68ad0 118 ;
2f47f1cc
MT
119
120Config_spec:
22d68ad0
BJ
121 MACHINE Save_id
122 = {
0bf41cfc
BJ
123 if (!strcmp($2, "vax")) {
124 machine = MACHINE_VAX;
125 machinename = "vax";
a0105456
SL
126 } else if (!strcmp($2, "tahoe")) {
127 machine = MACHINE_TAHOE;
128 machinename = "tahoe";
f4b2fb14
KM
129 } else if (!strcmp($2, "hp300")) {
130 machine = MACHINE_HP300;
131 machinename = "hp300";
1b6c65cb
WN
132 } else if (!strcmp($2, "i386")) {
133 machine = MACHINE_I386;
134 machinename = "i386";
202b4043
RC
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";
8b11ebd2
KM
141 } else if (!strcmp($2, "luna68k")) {
142 machine = MACHINE_LUNA68K;
143 machinename = "luna68k";
4bce7b73
KM
144 } else if (!strcmp($2, "news3400")) {
145 machine = MACHINE_NEWS3400;
146 machinename = "news3400";
0bf41cfc
BJ
147 } else
148 yyerror("Unknown machine type");
22d68ad0
BJ
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 |
7c1d4665
MK
161 MAKEOPTIONS Mkopt_list
162 |
22d68ad0
BJ
163 IDENT ID
164 = { ident = ns($2); } |
36edb824
SL
165 System_spec
166 |
22d68ad0 167 HZ NUMBER
8b11ebd2 168 = { hz = $2; }|
22d68ad0 169 TIMEZONE NUMBER
4b9d1c56 170 = { zone = 60 * $2; check_tz(); } |
c00c470f 171 TIMEZONE NUMBER DST NUMBER
4b9d1c56 172 = { zone = 60 * $2; dst = $4; check_tz(); } |
22d68ad0 173 TIMEZONE NUMBER DST
4b9d1c56 174 = { zone = 60 * $2; dst = 1; check_tz(); } |
22d68ad0 175 TIMEZONE FPNUMBER
4b9d1c56 176 = { zone = $2; check_tz(); } |
c00c470f 177 TIMEZONE FPNUMBER DST NUMBER
4b9d1c56 178 = { zone = $2; dst = $4; check_tz(); } |
22d68ad0 179 TIMEZONE FPNUMBER DST
4b9d1c56 180 = { zone = $2; dst = 1; check_tz(); } |
22d68ad0 181 TIMEZONE MINUS NUMBER
4b9d1c56 182 = { zone = -60 * $3; check_tz(); } |
c00c470f 183 TIMEZONE MINUS NUMBER DST NUMBER
4b9d1c56 184 = { zone = -60 * $3; dst = $5; check_tz(); } |
22d68ad0 185 TIMEZONE MINUS NUMBER DST
4b9d1c56 186 = { zone = -60 * $3; dst = 1; check_tz(); } |
22d68ad0 187 TIMEZONE MINUS FPNUMBER
4b9d1c56 188 = { zone = -$3; check_tz(); } |
c00c470f 189 TIMEZONE MINUS FPNUMBER DST NUMBER
4b9d1c56 190 = { zone = -$3; dst = $5; check_tz(); } |
22d68ad0 191 TIMEZONE MINUS FPNUMBER DST
4b9d1c56 192 = { zone = -$3; dst = 1; check_tz(); } |
22d68ad0
BJ
193 MAXUSERS NUMBER
194 = { maxusers = $2; };
2f47f1cc 195
36edb824
SL
196System_spec:
197 System_id System_parameter_list
198 = { checksystemspec(*confp); }
199 ;
200
201System_id:
202 CONFIG Save_id
203 = { mkconf($2); }
204 ;
205
206System_parameter_list:
207 System_parameter_list System_parameter
208 | System_parameter
209 ;
210
211System_parameter:
212 swap_spec
213 | root_spec
214 | dump_spec
215 | arg_spec
216 ;
217
218swap_spec:
219 SWAP optional_on swap_device_list
220 ;
221
222swap_device_list:
223 swap_device_list AND swap_device
224 | swap_device
225 ;
226
227swap_device:
6e5546fb
MH
228 swap_device_spec optional_size optional_sflag
229 = { mkswap(*confp, $1, $2, $3); }
36edb824
SL
230 ;
231
232swap_device_spec:
233 device_name
234 = {
6e5546fb 235 struct file_list *fl = newflist(SWAPSPEC);
36edb824
SL
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 = {
6e5546fb 247 struct file_list *fl = newflist(SWAPSPEC);
36edb824
SL
248
249 fl->f_swapdev = $1;
250 fl->f_fn = devtoname($1);
251 $$ = fl;
252 }
253 ;
254
255root_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
267root_device_spec:
268 device_name
269 = { $$ = nametodev($1, 0, 'a'); }
270 | major_minor
271 ;
272
273dump_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
286dump_device_spec:
287 device_name
288 = { $$ = nametodev($1, 0, 'b'); }
289 | major_minor
290 ;
291
292arg_spec:
293 ARGS optional_on arg_device_spec
441ba76a 294 = { yyerror("arg device specification obsolete, ignored"); }
36edb824
SL
295 ;
296
297arg_device_spec:
298 device_name
299 = { $$ = nametodev($1, 0, 'b'); }
300 | major_minor
301 ;
302
303major_minor:
304 MAJOR NUMBER MINOR NUMBER
305 = { $$ = makedev($2, $4); }
306 ;
307
308optional_on:
309 ON
310 | /* empty */
311 ;
312
313optional_size:
314 SIZE NUMBER
315 = { $$ = $2; }
316 | /* empty */
317 = { $$ = 0; }
318 ;
319
6e5546fb
MH
320optional_sflag:
321 SEQUENTIAL
322 = { $$ = 2; }
323 | /* empty */
324 = { $$ = 0; }
325 ;
326
36edb824
SL
327device_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
b1e602f2 346Opt_list:
22d68ad0
BJ
347 Opt_list COMMA Option
348 |
b1e602f2 349 Option
22d68ad0 350 ;
b1e602f2
MT
351
352Option:
22d68ad0
BJ
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 } ;
b1e602f2 372
841254c0 373Opt_value:
22d68ad0
BJ
374 ID
375 = { $$ = val_id = ns($1); } |
376 NUMBER
9bd38ba8
KB
377 = {
378 char nb[16];
379 (void) sprintf(nb, "%d", $1);
380 $$ = val_id = ns(nb);
381 } ;
841254c0
RE
382
383
2f47f1cc 384Save_id:
22d68ad0
BJ
385 ID
386 = { $$ = temp_id = ns($1); }
2f47f1cc 387 ;
7c1d4665
MK
388
389Mkopt_list:
390 Mkopt_list COMMA Mkoption
391 |
392 Mkoption
393 ;
394
395Mkoption:
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 } ;
2f47f1cc
MT
406
407Dev:
22d68ad0
BJ
408 ID
409 = { $$ = ns($1); }
2f47f1cc
MT
410 ;
411
412Device_spec:
22d68ad0
BJ
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;
6e5546fb
MH
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);
22d68ad0 439 };
2f47f1cc 440
6e5546fb
MH
441Cdev_init:
442 /* lambda */
443 = { mkcomp(&cur); };
444
445Cdev_info:
446 optional_on comp_device_list comp_option_list
447 ;
448
449comp_device_list:
450 comp_device_list AND comp_device
451 | comp_device
452 ;
453
454comp_device:
455 comp_device_spec
456 = { addcomp(*compp, $1); }
457 ;
458
459comp_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
478comp_option_list:
479 comp_option_list comp_option
480 |
481 /* lambda */
482 ;
483
484comp_option:
485 INTERLEAVE NUMBER
486 = { cur.d_pri = $2; } |
487 FLAGS NUMBER
488 = { cur.d_flags = $2; };
489
2f47f1cc 490Dev_name:
22d68ad0
BJ
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;
a0105456
SL
498 else if (eq($2, "vba"))
499 seen_vba = 1;
1b6c65cb
WN
500 else if (eq($2, "isa"))
501 seen_isa = 1;
22d68ad0
BJ
502 cur.d_unit = $3;
503 };
2f47f1cc
MT
504
505Init_dev:
22d68ad0
BJ
506 /* lambda */
507 = { init_dev(&cur); };
2f47f1cc
MT
508
509Dev_info:
510 Con_info Info_list
22d68ad0
BJ
511 |
512 /* lambda */
513 ;
2f47f1cc
MT
514
515Con_info:
22d68ad0
BJ
516 AT Dev NUMBER
517 = {
9bd38ba8
KB
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 }
b1e602f2 523 cur.d_conn = connect($2, $3);
22d68ad0
BJ
524 } |
525 AT NEXUS NUMBER
526 = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; };
2f47f1cc
MT
527
528Info_list:
529 Info_list Info
22d68ad0
BJ
530 |
531 /* lambda */
532 ;
2f47f1cc
MT
533
534Info:
22d68ad0
BJ
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)
b1e602f2
MT
543 cur.d_slave = $2;
544 else
545 yyerror("can't specify slave--not to master");
22d68ad0 546 } |
1b6c65cb
WN
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"; } |
22d68ad0
BJ
565 FLAGS NUMBER
566 = { cur.d_flags = $2; };
2f47f1cc
MT
567
568Int_spec:
22d68ad0
BJ
569 VECTOR Id_list
570 = { cur.d_vec = $2; } |
571 PRIORITY NUMBER
572 = { cur.d_pri = $2; } |
573 /* lambda */
574 ;
08f9a943
BJ
575
576Id_list:
22d68ad0
BJ
577 Save_id
578 = {
579 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
580 a->id = $1; a->id_next = 0; $$ = a;
581 } |
08f9a943 582 Save_id Id_list =
22d68ad0
BJ
583 {
584 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
585 a->id = $1; a->id_next = $2; $$ = a;
586 };
587
2f47f1cc
MT
588%%
589
590yyerror(s)
f025f13d 591 char *s;
2f47f1cc 592{
f025f13d 593
f6e835cd 594 fprintf(stderr, "config: line %d: %s\n", yyline + 1, s);
2f47f1cc
MT
595}
596
597/*
f025f13d 598 * return the passed string in a new space
2f47f1cc 599 */
2f47f1cc
MT
600char *
601ns(str)
f025f13d 602 register char *str;
2f47f1cc
MT
603{
604 register char *cp;
605
22d68ad0
BJ
606 cp = malloc((unsigned)(strlen(str)+1));
607 (void) strcpy(cp, str);
608 return (cp);
2f47f1cc
MT
609}
610
611/*
f025f13d 612 * add a device to the list of devices
2f47f1cc 613 */
2f47f1cc 614newdev(dp)
f025f13d 615 register struct device *dp;
2f47f1cc
MT
616{
617 register struct device *np;
618
619 np = (struct device *) malloc(sizeof *np);
620 *np = *dp;
057df410 621 np->d_next = 0;
f025f13d 622 if (curp == 0)
b1e602f2
MT
623 dtab = np;
624 else
625 curp->d_next = np;
626 curp = np;
2f47f1cc
MT
627}
628
629/*
f025f13d 630 * note that a configuration should be made
2f47f1cc 631 */
36edb824
SL
632mkconf(sysname)
633 char *sysname;
2f47f1cc 634{
36edb824 635 register struct file_list *fl, **flp;
2f47f1cc
MT
636
637 fl = (struct file_list *) malloc(sizeof *fl);
36edb824
SL
638 fl->f_type = SYSTEMSPEC;
639 fl->f_needs = sysname;
640 fl->f_rootdev = NODEV;
36edb824
SL
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
650struct file_list *
6e5546fb
MH
651newflist(ftype)
652 u_char ftype;
36edb824
SL
653{
654 struct file_list *fl = (struct file_list *)malloc(sizeof (*fl));
655
6e5546fb 656 fl->f_type = ftype;
36edb824
SL
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 */
6e5546fb 668mkswap(system, fl, size, flag)
36edb824 669 struct file_list *system, *fl;
6e5546fb 670 int size, flag;
36edb824
SL
671{
672 register struct file_list **flp;
67259f7b 673 char name[80];
36edb824
SL
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;
8df5b824 691 fl->f_swapsize = size;
6e5546fb 692 fl->f_swapflag = flag;
36edb824
SL
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);
2f47f1cc 702 else
36edb824 703 system->f_fn = ns(system->f_needs);
2f47f1cc
MT
704}
705
6e5546fb
MH
706mkcomp(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
725addcomp(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
2f47f1cc 745/*
f025f13d
BJ
746 * find the pointer to connect to the given device and number.
747 * returns 0 if no such device and prints an error message
2f47f1cc 748 */
f025f13d
BJ
749struct device *
750connect(dev, num)
751 register char *dev;
752 register int num;
2f47f1cc
MT
753{
754 register struct device *dp;
f6f4af06 755 struct device *huhcon();
2f47f1cc 756
a5e18d6b 757 if (num == QUES)
f025f13d
BJ
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) {
9bd38ba8
KB
763 (void) sprintf(errbuf,
764 "%s connected to non-controller", dev);
765 yyerror(errbuf);
f025f13d
BJ
766 return (0);
767 }
768 return (dp);
769 }
9bd38ba8
KB
770 (void) sprintf(errbuf, "%s %d not defined", dev, num);
771 yyerror(errbuf);
f025f13d 772 return (0);
2f47f1cc 773}
f6f4af06
MT
774
775/*
f025f13d 776 * connect to an unspecific thing
f6f4af06 777 */
f025f13d
BJ
778struct device *
779huhcon(dev)
780 register char *dev;
f6f4af06 781{
f025f13d
BJ
782 register struct device *dp, *dcp;
783 struct device rdev;
784 int oldtype;
785
f6f4af06 786 /*
f025f13d 787 * First make certain that there are some of these to wildcard on
f6f4af06 788 */
f025f13d
BJ
789 for (dp = dtab; dp != 0; dp = dp->d_next)
790 if (eq(dp->d_name, dev))
791 break;
792 if (dp == 0) {
9bd38ba8
KB
793 (void) sprintf(errbuf, "no %s's to wildcard", dev);
794 yyerror(errbuf);
f025f13d
BJ
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);
f6f4af06
MT
833}
834
835init_dev(dp)
f025f13d 836 register struct device *dp;
f6f4af06 837{
f025f13d
BJ
838
839 dp->d_name = "OHNO!!!";
840 dp->d_type = DEVICE;
841 dp->d_conn = 0;
842 dp->d_vec = 0;
e29e3c3e
KM
843 dp->d_addr = dp->d_flags = dp->d_dk = 0;
844 dp->d_pri = -1;
f025f13d 845 dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN;
1b6c65cb
WN
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";
a5e18d6b
MT
853}
854
855/*
f025f13d 856 * make certain that this is a reasonable type of thing to connect to a nexus
a5e18d6b 857 */
a5e18d6b 858check_nexus(dev, num)
f025f13d
BJ
859 register struct device *dev;
860 int num;
a5e18d6b 861{
f025f13d 862
0bf41cfc 863 switch (machine) {
f025f13d 864
0bf41cfc 865 case MACHINE_VAX:
67259f7b
MK
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");
0bf41cfc
BJ
869 if (num != QUES)
870 yyerror("can't give specific nexus numbers");
871 break;
872
a0105456
SL
873 case MACHINE_TAHOE:
874 if (!eq(dev->d_name, "vba"))
875 yyerror("only vba's should be connected to the nexus");
0bf41cfc 876 break;
f4b2fb14
KM
877
878 case MACHINE_HP300:
8b11ebd2 879 case MACHINE_LUNA68K:
f4b2fb14
KM
880 if (num != QUES)
881 dev->d_addr = num;
882 break;
1b6c65cb
WN
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;
4bce7b73
KM
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;
0bf41cfc 894 }
f6f4af06 895}
b1e602f2
MT
896
897/*
898 * Check the timezone to make certain it is sensible
899 */
900
901check_tz()
902{
4b9d1c56 903 if (abs(zone) > 12 * 60)
b1e602f2
MT
904 yyerror("timezone is unreasonable");
905 else
f025f13d 906 hadtz = 1;
b1e602f2 907}
36edb824
SL
908
909/*
910 * Check system specification and apply defaulting
911 * rules on root, argument, dump, and swap devices.
912 */
913checksystemspec(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
6e5546fb 938 swap = newflist(SWAPSPEC);
36edb824
SL
939 dev = fl->f_rootdev;
940 if (minor(dev) & 07) {
9bd38ba8 941 (void) sprintf(buf,
36edb824
SL
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");
36edb824
SL
958 if (fl->f_dumpdev != NODEV)
959 yyerror("dump device specified with generic swap");
960 return;
961 }
36edb824
SL
962 /*
963 * Default dump device and warn if place is not a
441ba76a 964 * swap area.
36edb824
SL
965 */
966 if (fl->f_dumpdev == NODEV)
967 fl->f_dumpdev = swap->f_swapdev;
441ba76a 968 if (fl->f_dumpdev != swap->f_swapdev) {
36edb824
SL
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;
441ba76a
MK
974 (void) sprintf(buf,
975 "Warning: dump device is not a swap partition");
36edb824
SL
976 yyerror(buf);
977 }
978}
979
980/*
981 * Verify all devices specified in the system specification
982 * are present in the device specifications.
983 */
984verifysystemspecs()
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 }
36edb824
SL
1004 }
1005}
1006
1007/*
1008 * Do as above, but for swap devices.
1009 */
1010dev_t *
1011verifyswap(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
6e5546fb
MH
1030/*
1031 * Verify that components of a compound device have themselves been config'ed
1032 */
1033verifycomp(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
36edb824
SL
1047/*
1048 * Has a device already been checked
1049 * for it's existence in the configuration?
1050 */
1051alreadychecked(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
1063deverror(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 */
67259f7b 1076/*ARGSUSED*/
36edb824
SL
1077finddev(dev)
1078 dev_t dev;
1079{
1080
1081 /* punt on this right now */
1082 return (1);
1083}