|
|
1.1 root 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 COMMA
13: %token CONFIG
14: %token CONTROLLER
15: %token CPU
16: %token CSR
17: %token DEVICE
18: %token DISK
19: %token DRIVE
20: %token DST
21: %token DUMPS
22: %token EQUALS
23: %token FLAGS
24: %token HZ
25: %token IDENT
26: %token MACHINE
27: %token MAJOR
28: %token MASTER
29: %token MAXUSERS
30: %token MBA
31: %token MINOR
32: %token MINUS
33: %token NEXUS
34: %token ON
35: %token OPTIONS
36: %token PRIORITY
37: %token PSEUDO_DEVICE
38: %token ROOT
39: %token SEMICOLON
40: %token SIZE
41: %token SLAVE
42: %token SWAP
43: %token TIMEZONE
44: %token TRACE
45: %token UBA
46: %token VECTOR
47:
48: %token <str> ID
49: %token <val> NUMBER
50: %token <val> FPNUMBER
51:
52: %type <str> Save_id
53: %type <str> Opt_value
54: %type <str> Dev
55: %type <lst> Id_list
56: %type <val> optional_size
57: %type <str> device_name
58: %type <val> major_minor
59: %type <val> arg_device_spec
60: %type <val> root_device_spec
61: %type <val> dump_device_spec
62: %type <file> swap_device_spec
63:
64: %{
65:
66: /* config.y 1.18 83/05/18 */
67:
68: #include "config.h"
69: #include <ctype.h>
70: #include <stdio.h>
71:
72: struct device cur;
73: struct device *curp = 0;
74: char *temp_id;
75: char *val_id;
76: char *malloc();
77:
78: %}
79: %%
80: Configuration:
81: Many_specs
82: = { verifysystemspecs(); }
83: ;
84:
85: Many_specs:
86: Many_specs Spec
87: |
88: /* lambda */
89: ;
90:
91: Spec:
92: Device_spec SEMICOLON
93: = { newdev(&cur); } |
94: Config_spec SEMICOLON
95: |
96: TRACE SEMICOLON
97: = { do_trace = !do_trace; } |
98: SEMICOLON
99: |
100: error SEMICOLON
101: ;
102:
103: Config_spec:
104: MACHINE Save_id
105: = {
106: if (!strcmp($2, "vax")) {
107: machine = MACHINE_VAX;
108: machinename = "vax";
109: } else if (!strcmp($2, "sun")) {
110: machine = MACHINE_SUN;
111: machinename = "sun";
112: } else
113: yyerror("Unknown machine type");
114: } |
115: CPU Save_id
116: = {
117: struct cputype *cp =
118: (struct cputype *)malloc(sizeof (struct cputype));
119: cp->cpu_name = ns($2);
120: cp->cpu_next = cputype;
121: cputype = cp;
122: free(temp_id);
123: } |
124: OPTIONS Opt_list
125: |
126: IDENT ID
127: = { ident = ns($2); } |
128: System_spec
129: |
130: HZ NUMBER
131: = { yyerror("HZ specification obsolete; delete"); } |
132: TIMEZONE NUMBER
133: = { timezone = 60 * $2; check_tz(); } |
134: TIMEZONE NUMBER DST NUMBER
135: = { timezone = 60 * $2; dst = $4; check_tz(); } |
136: TIMEZONE NUMBER DST
137: = { timezone = 60 * $2; dst = 1; check_tz(); } |
138: TIMEZONE FPNUMBER
139: = { timezone = $2; check_tz(); } |
140: TIMEZONE FPNUMBER DST NUMBER
141: = { timezone = $2; dst = $4; check_tz(); } |
142: TIMEZONE FPNUMBER DST
143: = { timezone = $2; dst = 1; check_tz(); } |
144: TIMEZONE MINUS NUMBER
145: = { timezone = -60 * $3; check_tz(); } |
146: TIMEZONE MINUS NUMBER DST NUMBER
147: = { timezone = -60 * $3; dst = $5; check_tz(); } |
148: TIMEZONE MINUS NUMBER DST
149: = { timezone = -60 * $3; dst = 1; check_tz(); } |
150: TIMEZONE MINUS FPNUMBER
151: = { timezone = -$3; check_tz(); } |
152: TIMEZONE MINUS FPNUMBER DST NUMBER
153: = { timezone = -$3; dst = $5; check_tz(); } |
154: TIMEZONE MINUS FPNUMBER DST
155: = { timezone = -$3; dst = 1; check_tz(); } |
156: MAXUSERS NUMBER
157: = { maxusers = $2; };
158:
159: System_spec:
160: System_id System_parameter_list
161: = { checksystemspec(*confp); }
162: ;
163:
164: System_id:
165: CONFIG Save_id
166: = { mkconf($2); }
167: ;
168:
169: System_parameter_list:
170: System_parameter_list System_parameter
171: | System_parameter
172: ;
173:
174: System_parameter:
175: swap_spec
176: | root_spec
177: | dump_spec
178: | arg_spec
179: ;
180:
181: swap_spec:
182: SWAP optional_on swap_device_list
183: ;
184:
185: swap_device_list:
186: swap_device_list AND swap_device
187: | swap_device
188: ;
189:
190: swap_device:
191: swap_device_spec optional_size
192: = { mkswap(*confp, $1, $2); }
193: ;
194:
195: swap_device_spec:
196: device_name
197: = {
198: struct file_list *fl = newswap();
199:
200: if (eq($1, "generic"))
201: fl->f_fn = $1;
202: else {
203: fl->f_swapdev = nametodev($1, 0, 'b');
204: fl->f_fn = devtoname(fl->f_swapdev);
205: }
206: $$ = fl;
207: }
208: | major_minor
209: = {
210: struct file_list *fl = newswap();
211:
212: fl->f_swapdev = $1;
213: fl->f_fn = devtoname($1);
214: $$ = fl;
215: }
216: ;
217:
218: root_spec:
219: ROOT optional_on root_device_spec
220: = {
221: struct file_list *fl = *confp;
222:
223: if (fl && fl->f_rootdev != NODEV)
224: yyerror("extraneous root device specification");
225: else
226: fl->f_rootdev = $3;
227: }
228: ;
229:
230: root_device_spec:
231: device_name
232: = { $$ = nametodev($1, 0, 'a'); }
233: | major_minor
234: ;
235:
236: dump_spec:
237: DUMPS optional_on dump_device_spec
238: = {
239: struct file_list *fl = *confp;
240:
241: if (fl && fl->f_dumpdev != NODEV)
242: yyerror("extraneous dump device specification");
243: else
244: fl->f_dumpdev = $3;
245: }
246:
247: ;
248:
249: dump_device_spec:
250: device_name
251: = { $$ = nametodev($1, 0, 'b'); }
252: | major_minor
253: ;
254:
255: arg_spec:
256: ARGS optional_on arg_device_spec
257: = {
258: struct file_list *fl = *confp;
259:
260: if (fl && fl->f_argdev != NODEV)
261: yyerror("extraneous arg device specification");
262: else
263: fl->f_argdev = $3;
264: }
265: ;
266:
267: arg_device_spec:
268: device_name
269: = { $$ = nametodev($1, 0, 'b'); }
270: | major_minor
271: ;
272:
273: major_minor:
274: MAJOR NUMBER MINOR NUMBER
275: = { $$ = makedev($2, $4); }
276: ;
277:
278: optional_on:
279: ON
280: | /* empty */
281: ;
282:
283: optional_size:
284: SIZE NUMBER
285: = { $$ = $2; }
286: | /* empty */
287: = { $$ = 0; }
288: ;
289:
290: device_name:
291: Save_id
292: = { $$ = $1; }
293: | Save_id NUMBER
294: = {
295: char buf[80];
296:
297: (void) sprintf(buf, "%s%d", $1, $2);
298: $$ = ns(buf); free($1);
299: }
300: | Save_id NUMBER ID
301: = {
302: char buf[80];
303:
304: (void) sprintf(buf, "%s%d%s", $1, $2, $3);
305: $$ = ns(buf); free($1);
306: }
307: ;
308:
309: Opt_list:
310: Opt_list COMMA Option
311: |
312: Option
313: ;
314:
315: Option:
316: Save_id
317: = {
318: struct opt *op = (struct opt *)malloc(sizeof (struct opt));
319: op->op_name = ns($1);
320: op->op_next = opt;
321: op->op_value = 0;
322: opt = op;
323: free(temp_id);
324: } |
325: Save_id EQUALS Opt_value
326: = {
327: struct opt *op = (struct opt *)malloc(sizeof (struct opt));
328: op->op_name = ns($1);
329: op->op_next = opt;
330: op->op_value = ns($3);
331: opt = op;
332: free(temp_id);
333: free(val_id);
334: } ;
335:
336: Opt_value:
337: ID
338: = { $$ = val_id = ns($1); } |
339: NUMBER
340: = { char nb[16]; $$ = val_id = ns(sprintf(nb, "%d", $1)); };
341:
342:
343: Save_id:
344: ID
345: = { $$ = temp_id = ns($1); }
346: ;
347:
348: Dev:
349: UBA
350: = { $$ = ns("uba"); } |
351: MBA
352: = { $$ = ns("mba"); } |
353: ID
354: = { $$ = ns($1); }
355: ;
356:
357: Device_spec:
358: DEVICE Dev_name Dev_info Int_spec
359: = { cur.d_type = DEVICE; } |
360: MASTER Dev_name Dev_info Int_spec
361: = { cur.d_type = MASTER; } |
362: DISK Dev_name Dev_info Int_spec
363: = { cur.d_dk = 1; cur.d_type = DEVICE; } |
364: CONTROLLER Dev_name Dev_info Int_spec
365: = { cur.d_type = CONTROLLER; } |
366: PSEUDO_DEVICE Init_dev Dev
367: = {
368: cur.d_name = $3;
369: cur.d_type = PSEUDO_DEVICE;
370: } |
371: PSEUDO_DEVICE Init_dev Dev NUMBER
372: = {
373: cur.d_name = $3;
374: cur.d_type = PSEUDO_DEVICE;
375: cur.d_slave = $4;
376: };
377:
378: Dev_name:
379: Init_dev Dev NUMBER
380: = {
381: cur.d_name = $2;
382: if (eq($2, "mba"))
383: seen_mba = 1;
384: else if (eq($2, "uba"))
385: seen_uba = 1;
386: cur.d_unit = $3;
387: };
388:
389: Init_dev:
390: /* lambda */
391: = { init_dev(&cur); };
392:
393: Dev_info:
394: Con_info Info_list
395: |
396: /* lambda */
397: ;
398:
399: Con_info:
400: AT Dev NUMBER
401: = {
402: if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba"))
403: yyerror(sprintf(errbuf,
404: "%s must be connected to a nexus", cur.d_name));
405: cur.d_conn = connect($2, $3);
406: } |
407: AT NEXUS NUMBER
408: = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; };
409:
410: Info_list:
411: Info_list Info
412: |
413: /* lambda */
414: ;
415:
416: Info:
417: CSR NUMBER
418: = { cur.d_addr = $2; } |
419: DRIVE NUMBER
420: = { cur.d_drive = $2; } |
421: SLAVE NUMBER
422: = {
423: if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS &&
424: cur.d_conn->d_type == MASTER)
425: cur.d_slave = $2;
426: else
427: yyerror("can't specify slave--not to master");
428: } |
429: FLAGS NUMBER
430: = { cur.d_flags = $2; };
431:
432: Int_spec:
433: VECTOR Id_list
434: = { cur.d_vec = $2; } |
435: PRIORITY NUMBER
436: = { cur.d_pri = $2; } |
437: /* lambda */
438: ;
439:
440: Id_list:
441: Save_id
442: = {
443: struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
444: a->id = $1; a->id_next = 0; $$ = a;
445: } |
446: Save_id Id_list =
447: {
448: struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
449: a->id = $1; a->id_next = $2; $$ = a;
450: };
451:
452: %%
453:
454: yyerror(s)
455: char *s;
456: {
457:
458: fprintf(stderr, "config: line %d: %s\n", yyline, s);
459: }
460:
461: /*
462: * return the passed string in a new space
463: */
464: char *
465: ns(str)
466: register char *str;
467: {
468: register char *cp;
469:
470: cp = malloc((unsigned)(strlen(str)+1));
471: (void) strcpy(cp, str);
472: return (cp);
473: }
474:
475: /*
476: * add a device to the list of devices
477: */
478: newdev(dp)
479: register struct device *dp;
480: {
481: register struct device *np;
482:
483: np = (struct device *) malloc(sizeof *np);
484: *np = *dp;
485: if (curp == 0)
486: dtab = np;
487: else
488: curp->d_next = np;
489: curp = np;
490: }
491:
492: /*
493: * note that a configuration should be made
494: */
495: mkconf(sysname)
496: char *sysname;
497: {
498: register struct file_list *fl, **flp;
499:
500: fl = (struct file_list *) malloc(sizeof *fl);
501: fl->f_type = SYSTEMSPEC;
502: fl->f_needs = sysname;
503: fl->f_rootdev = NODEV;
504: fl->f_argdev = NODEV;
505: fl->f_dumpdev = NODEV;
506: fl->f_fn = 0;
507: fl->f_next = 0;
508: for (flp = confp; *flp; flp = &(*flp)->f_next)
509: ;
510: *flp = fl;
511: confp = flp;
512: }
513:
514: struct file_list *
515: newswap()
516: {
517: struct file_list *fl = (struct file_list *)malloc(sizeof (*fl));
518:
519: fl->f_type = SWAPSPEC;
520: fl->f_next = 0;
521: fl->f_swapdev = NODEV;
522: fl->f_swapsize = 0;
523: fl->f_needs = 0;
524: fl->f_fn = 0;
525: return (fl);
526: }
527:
528: /*
529: * Add a swap device to the system's configuration
530: */
531: mkswap(system, fl, size)
532: struct file_list *system, *fl;
533: int size;
534: {
535: register struct file_list **flp;
536: char *cp, name[80];
537:
538: if (system == 0 || system->f_type != SYSTEMSPEC) {
539: yyerror("\"swap\" spec precedes \"config\" specification");
540: return;
541: }
542: if (size < 0) {
543: yyerror("illegal swap partition size");
544: return;
545: }
546: /*
547: * Append swap description to the end of the list.
548: */
549: flp = &system->f_next;
550: for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next)
551: ;
552: fl->f_next = *flp;
553: *flp = fl;
554: /*
555: * If first swap device for this system,
556: * set up f_fn field to insure swap
557: * files are created with unique names.
558: */
559: if (system->f_fn)
560: return;
561: if (eq(fl->f_fn, "generic"))
562: system->f_fn = ns(fl->f_fn);
563: else
564: system->f_fn = ns(system->f_needs);
565: }
566:
567: /*
568: * find the pointer to connect to the given device and number.
569: * returns 0 if no such device and prints an error message
570: */
571: struct device *
572: connect(dev, num)
573: register char *dev;
574: register int num;
575: {
576: register struct device *dp;
577: struct device *huhcon();
578:
579: if (num == QUES)
580: return (huhcon(dev));
581: for (dp = dtab; dp != 0; dp = dp->d_next) {
582: if ((num != dp->d_unit) || !eq(dev, dp->d_name))
583: continue;
584: if (dp->d_type != CONTROLLER && dp->d_type != MASTER) {
585: yyerror(sprintf(errbuf,
586: "%s connected to non-controller", dev));
587: return (0);
588: }
589: return (dp);
590: }
591: yyerror(sprintf(errbuf, "%s %d not defined", dev, num));
592: return (0);
593: }
594:
595: /*
596: * connect to an unspecific thing
597: */
598: struct device *
599: huhcon(dev)
600: register char *dev;
601: {
602: register struct device *dp, *dcp;
603: struct device rdev;
604: int oldtype;
605:
606: /*
607: * First make certain that there are some of these to wildcard on
608: */
609: for (dp = dtab; dp != 0; dp = dp->d_next)
610: if (eq(dp->d_name, dev))
611: break;
612: if (dp == 0) {
613: yyerror(sprintf(errbuf, "no %s's to wildcard", dev));
614: return (0);
615: }
616: oldtype = dp->d_type;
617: dcp = dp->d_conn;
618: /*
619: * Now see if there is already a wildcard entry for this device
620: * (e.g. Search for a "uba ?")
621: */
622: for (; dp != 0; dp = dp->d_next)
623: if (eq(dev, dp->d_name) && dp->d_unit == -1)
624: break;
625: /*
626: * If there isn't, make one because everything needs to be connected
627: * to something.
628: */
629: if (dp == 0) {
630: dp = &rdev;
631: init_dev(dp);
632: dp->d_unit = QUES;
633: dp->d_name = ns(dev);
634: dp->d_type = oldtype;
635: newdev(dp);
636: dp = curp;
637: /*
638: * Connect it to the same thing that other similar things are
639: * connected to, but make sure it is a wildcard unit
640: * (e.g. up connected to sc ?, here we make connect sc? to a
641: * uba?). If other things like this are on the NEXUS or
642: * if they aren't connected to anything, then make the same
643: * connection, else call ourself to connect to another
644: * unspecific device.
645: */
646: if (dcp == TO_NEXUS || dcp == 0)
647: dp->d_conn = dcp;
648: else
649: dp->d_conn = connect(dcp->d_name, QUES);
650: }
651: return (dp);
652: }
653:
654: init_dev(dp)
655: register struct device *dp;
656: {
657:
658: dp->d_name = "OHNO!!!";
659: dp->d_type = DEVICE;
660: dp->d_conn = 0;
661: dp->d_vec = 0;
662: dp->d_addr = dp->d_pri = dp->d_flags = dp->d_dk = 0;
663: dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN;
664: }
665:
666: /*
667: * make certain that this is a reasonable type of thing to connect to a nexus
668: */
669: check_nexus(dev, num)
670: register struct device *dev;
671: int num;
672: {
673:
674: switch (machine) {
675:
676: case MACHINE_VAX:
677: if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba"))
678: yyerror("only uba's and mba's should be connected to the nexus");
679: if (num != QUES)
680: yyerror("can't give specific nexus numbers");
681: break;
682:
683: case MACHINE_SUN:
684: if (!eq(dev->d_name, "mb"))
685: yyerror("only mb's should be connected to the nexus");
686: break;
687: }
688: }
689:
690: /*
691: * Check the timezone to make certain it is sensible
692: */
693:
694: check_tz()
695: {
696: if (abs(timezone) > 12 * 60)
697: yyerror("timezone is unreasonable");
698: else
699: hadtz = 1;
700: }
701:
702: /*
703: * Check system specification and apply defaulting
704: * rules on root, argument, dump, and swap devices.
705: */
706: checksystemspec(fl)
707: register struct file_list *fl;
708: {
709: char buf[BUFSIZ];
710: register struct file_list *swap;
711: int generic;
712:
713: if (fl == 0 || fl->f_type != SYSTEMSPEC) {
714: yyerror("internal error, bad system specification");
715: exit(1);
716: }
717: swap = fl->f_next;
718: generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic");
719: if (fl->f_rootdev == NODEV && !generic) {
720: yyerror("no root device specified");
721: exit(1);
722: }
723: /*
724: * Default swap area to be in 'b' partition of root's
725: * device. If root specified to be other than on 'a'
726: * partition, give warning, something probably amiss.
727: */
728: if (swap == 0 || swap->f_type != SWAPSPEC) {
729: dev_t dev;
730:
731: swap = newswap();
732: dev = fl->f_rootdev;
733: if (minor(dev) & 07) {
734: sprintf(buf,
735: "Warning, swap defaulted to 'b' partition with root on '%c' partition",
736: (minor(dev) & 07) + 'a');
737: yyerror(buf);
738: }
739: swap->f_swapdev =
740: makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a'));
741: swap->f_fn = devtoname(swap->f_swapdev);
742: mkswap(fl, swap, 0);
743: }
744: /*
745: * Make sure a generic swap isn't specified, along with
746: * other stuff (user must really be confused).
747: */
748: if (generic) {
749: if (fl->f_rootdev != NODEV)
750: yyerror("root device specified with generic swap");
751: if (fl->f_argdev != NODEV)
752: yyerror("arg device specified with generic swap");
753: if (fl->f_dumpdev != NODEV)
754: yyerror("dump device specified with generic swap");
755: return;
756: }
757: /*
758: * Default argument device and check for oddball arrangements.
759: */
760: if (fl->f_argdev == NODEV)
761: fl->f_argdev = swap->f_swapdev;
762: if (fl->f_argdev != swap->f_swapdev)
763: yyerror("Warning, arg device different than primary swap");
764: /*
765: * Default dump device and warn if place is not a
766: * swap area or the argument device partition.
767: */
768: if (fl->f_dumpdev == NODEV)
769: fl->f_dumpdev = swap->f_swapdev;
770: if (fl->f_dumpdev != swap->f_swapdev && fl->f_dumpdev != fl->f_argdev) {
771: struct file_list *p = swap->f_next;
772:
773: for (; p && p->f_type == SWAPSPEC; p = p->f_next)
774: if (fl->f_dumpdev == p->f_swapdev)
775: return;
776: sprintf(buf, "Warning, orphaned dump device, %s",
777: "do you know what you're doing");
778: yyerror(buf);
779: }
780: }
781:
782: /*
783: * Verify all devices specified in the system specification
784: * are present in the device specifications.
785: */
786: verifysystemspecs()
787: {
788: register struct file_list *fl;
789: dev_t checked[50], *verifyswap();
790: register dev_t *pchecked = checked;
791:
792: for (fl = conf_list; fl; fl = fl->f_next) {
793: if (fl->f_type != SYSTEMSPEC)
794: continue;
795: if (!finddev(fl->f_rootdev))
796: deverror(fl->f_needs, "root");
797: *pchecked++ = fl->f_rootdev;
798: pchecked = verifyswap(fl->f_next, checked, pchecked);
799: #define samedev(dev1, dev2) \
800: ((minor(dev1) &~ 07) != (minor(dev2) &~ 07))
801: if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) {
802: if (!finddev(fl->f_dumpdev))
803: deverror(fl->f_needs, "dump");
804: *pchecked++ = fl->f_dumpdev;
805: }
806: if (!alreadychecked(fl->f_argdev, checked, pchecked)) {
807: if (!finddev(fl->f_argdev))
808: deverror(fl->f_needs, "arg");
809: *pchecked++ = fl->f_argdev;
810: }
811: }
812: }
813:
814: /*
815: * Do as above, but for swap devices.
816: */
817: dev_t *
818: verifyswap(fl, checked, pchecked)
819: register struct file_list *fl;
820: dev_t checked[];
821: register dev_t *pchecked;
822: {
823:
824: for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) {
825: if (eq(fl->f_fn, "generic"))
826: continue;
827: if (alreadychecked(fl->f_swapdev, checked, pchecked))
828: continue;
829: if (!finddev(fl->f_swapdev))
830: fprintf(stderr,
831: "config: swap device %s not configured", fl->f_fn);
832: *pchecked++ = fl->f_swapdev;
833: }
834: return (pchecked);
835: }
836:
837: /*
838: * Has a device already been checked
839: * for it's existence in the configuration?
840: */
841: alreadychecked(dev, list, last)
842: dev_t dev, list[];
843: register dev_t *last;
844: {
845: register dev_t *p;
846:
847: for (p = list; p < last; p++)
848: if (samedev(*p, dev))
849: return (1);
850: return (0);
851: }
852:
853: deverror(systemname, devtype)
854: char *systemname, *devtype;
855: {
856:
857: fprintf(stderr, "config: %s: %s device not configured\n",
858: systemname, devtype);
859: }
860:
861: /*
862: * Look for the device in the list of
863: * configured hardware devices. Must
864: * take into account stuff wildcarded.
865: */
866: finddev(dev)
867: dev_t dev;
868: {
869:
870: /* punt on this right now */
871: return (1);
872: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.