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