|
|
1.1 root 1: %union {
2: int i;
3: char *cp;
4: struct idlst *idlst;
5: }
6: %token CPU IDENT CONFIG ANY DEVICE UBA MBA NEXUS CSR DRIVE VECTOR OPTIONS
7: %token CONTROLLER PSEUDO_DEVICE FLAGS ID SEMICOLON NUMBER FPNUMBER TRACE
8: %token DISK SLAVE AT HZ TIMEZONE DST MAXUSERS MASTER MAKEFILE COMMA MINUS
9: %type <cp> Save_id ID Dev
10: %type <i> NUMBER FPNUMBER
11: %type <idlst> Id_list
12: %{
13: /* config.y 1.11 81/05/22 */
14: #include "config.h"
15: #include <stdio.h>
16: struct device cur;
17: struct device *curp = NULL;
18: char *temp_id;
19: %}
20: %%
21: Configuration:
22: Many_specs
23: ;
24:
25: Many_specs:
26: Many_specs Spec
27: |
28: ;
29:
30: Spec:
31: Device_spec SEMICOLON = { newdev(&cur); } |
32: Config_spec SEMICOLON |
33: TRACE SEMICOLON = { do_trace = ! do_trace; } |
34: SEMICOLON |
35: error SEMICOLON
36: ;
37:
38: Config_spec:
39: CPU Save_id = {
40: struct cputype *cp = (struct cputype *)malloc(sizeof (struct cputype));
41: cp->cpu_name = ns($2);
42: cp->cpu_next = cputype;
43: cputype = cp;
44: free(temp_id);
45: } |
46: OPTIONS Opt_list |
47: IDENT ID { ident = ns($2); } |
48: CONFIG Save_id ID = { mkconf(temp_id, $3); free(temp_id); } |
49: HZ NUMBER = {
50: yyerror("HZ specification obsolete; delete");
51: hz = 60;
52: } |
53: TIMEZONE NUMBER = { timezone = 60 * $2; check_tz(); } |
54: TIMEZONE NUMBER DST = { timezone = 60 * $2; dst = 1; check_tz(); } |
55: TIMEZONE FPNUMBER = { timezone = $2; check_tz(); } |
56: TIMEZONE FPNUMBER DST = { timezone = $2; dst = 1; check_tz(); } |
57: MINUS TIMEZONE NUMBER =
58: { timezone = -60 * $3; check_tz(); } |
59: MINUS TIMEZONE NUMBER DST =
60: { timezone = -60 * $3; dst = 1; check_tz(); } |
61: MINUS TIMEZONE FPNUMBER =
62: { timezone = -$3; check_tz(); } |
63: MINUS TIMEZONE FPNUMBER DST =
64: { timezone = -$3; dst = 1; check_tz(); } |
65: MAKEFILE ID =
66: { mkfile = ns($2); } |
67: MAXUSERS NUMBER = { maxusers = $2; }
68: ;
69:
70: Opt_list:
71: Opt_list COMMA Option |
72: Option
73: ;
74:
75: Option:
76: Save_id = {
77: struct opt *op = (struct opt *)malloc(sizeof (struct opt));
78: op->op_name = ns($1);
79: op->op_next = opt;
80: opt = op;
81: free(temp_id);
82: }
83: ;
84:
85: Save_id:
86: ID = { $$ = temp_id = ns($1); }
87: ;
88:
89: Dev:
90: UBA = { $$ = ns("uba"); } |
91: MBA = { $$ = ns("mba"); } |
92: ID = { $$ = ns($1); }
93: ;
94:
95: Device_spec:
96: DEVICE Dev_name Dev_info Int_spec = { cur.d_type = DEVICE; } |
97: MASTER Dev_name Dev_info Int_spec = { cur.d_type = MASTER; } |
98: DISK Dev_name Dev_info Int_spec =
99: { cur.d_dk = 1; cur.d_type = DEVICE; } |
100: CONTROLLER Dev_name Dev_info Int_spec = { cur.d_type = CONTROLLER; } |
101: PSEUDO_DEVICE Init_dev Dev =
102: { cur.d_name = $3; cur.d_type = PSEUDO_DEVICE; } |
103: PSEUDO_DEVICE Init_dev Dev NUMBER =
104: { cur.d_name = $3; cur.d_type = PSEUDO_DEVICE;
105: cur.d_count = $4; }
106: ;
107:
108: Dev_name:
109: Init_dev Dev NUMBER = {
110: cur.d_name = $2;
111: if (eq($2, "mba"))
112: seen_mba = TRUE;
113: else if (eq($2, "uba"))
114: seen_uba = TRUE;
115: cur.d_unit = $3;
116: }
117: ;
118:
119: Init_dev:
120: = { init_dev(&cur); }
121: ;
122:
123: Dev_info:
124: Con_info Info_list
125: |
126: ;
127:
128: Con_info:
129: AT Dev NUMBER = {
130: if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) {
131: sprintf(errbuf,
132: "%s must be connected to a nexus", cur.d_name);
133: yyerror(errbuf);
134: }
135: cur.d_conn = connect($2, $3);
136: } |
137: AT NEXUS NUMBER = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; }
138: ;
139:
140: Info_list:
141: Info_list Info
142: |
143: ;
144:
145: Info:
146: CSR NUMBER = { cur.d_addr = $2; } |
147: DRIVE NUMBER = { cur.d_drive = $2; } |
148: SLAVE NUMBER =
149: {
150: if (cur.d_conn != NULL && cur.d_conn != TO_NEXUS
151: && cur.d_conn->d_type == MASTER)
152: cur.d_slave = $2;
153: else
154: yyerror("can't specify slave--not to master");
155: } |
156: FLAGS NUMBER = { cur.d_flags = $2; }
157: ;
158:
159: Int_spec:
160: VECTOR Id_list = { cur.d_vec = $2; } | ;
161:
162: Id_list:
163: Save_id =
164: { struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
165: a->id = $1; a->id_next = 0; $$ = a; } |
166: Save_id Id_list =
167: { struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
168: a->id = $1; a->id_next = $2; $$ = a; } ;
169: %%
170:
171: yyerror(s)
172: char *s;
173: {
174: fprintf(stderr, "config: %s at line %d\n", s, yyline);
175: }
176:
177: /*
178: * ns:
179: * Return the passed string in a new space
180: */
181:
182: char *
183: ns(str)
184: register char *str;
185: {
186: register char *cp;
187:
188: cp = malloc(strlen(str)+1);
189: strcpy(cp, str);
190: return cp;
191: }
192:
193: /*
194: * newdev
195: * Add a device to the list
196: */
197:
198: newdev(dp)
199: register struct device *dp;
200: {
201: register struct device *np;
202:
203: np = (struct device *) malloc(sizeof *np);
204: *np = *dp;
205: if (curp == NULL)
206: dtab = np;
207: else
208: curp->d_next = np;
209: curp = np;
210: }
211:
212: /*
213: * mkconf
214: * Note that a configuration should be made
215: */
216:
217: mkconf(dev, sysname)
218: char *dev, *sysname;
219: {
220: register struct file_list *fl;
221:
222: fl = (struct file_list *) malloc(sizeof *fl);
223: fl->f_fn = ns(dev);
224: fl->f_needs = ns(sysname);
225: if (confp == NULL)
226: conf_list = fl;
227: else
228: confp->f_next = fl;
229: confp = fl;
230: }
231:
232: /*
233: * Connect:
234: * Find the pointer to connect to the given device and number.
235: * returns NULL if no such device and prints an error message
236: */
237:
238: struct device *connect(dev, num)
239: register char *dev;
240: register int num;
241: {
242: register struct device *dp;
243: struct device *huhcon();
244:
245: if (num == QUES)
246: return huhcon(dev);
247: for (dp = dtab; dp != NULL; dp = dp->d_next)
248: if ((num == dp->d_unit) && eq(dev, dp->d_name))
249: if (dp->d_type != CONTROLLER && dp->d_type != MASTER)
250: {
251: sprintf(errbuf, "%s connected to non-controller", dev);
252: yyerror(errbuf);
253: return NULL;
254: }
255: else
256: return dp;
257: sprintf(errbuf, "%s %d not defined", dev, num);
258: yyerror(errbuf);
259: return NULL;
260: }
261:
262: /*
263: * huhcon
264: * Connect to an unspecific thing
265: */
266:
267: struct device *huhcon(dev)
268: register char *dev;
269: {
270: register struct device *dp, *dcp;
271: struct device rdev;
272: int oldtype;
273:
274: /*
275: * First make certain that there are some of these to wildcard on
276: */
277: for (dp = dtab; dp != NULL; dp = dp->d_next)
278: if (eq(dp->d_name, dev))
279: break;
280: if (dp == NULL)
281: {
282: sprintf(errbuf, "no %s's to wildcard", dev);
283: yyerror(errbuf);
284: return NULL;
285: }
286: oldtype = dp->d_type;
287: dcp = dp->d_conn;
288: /*
289: * Now see if there is already a wildcard entry for this device
290: * (e.g. Search for a "uba ?")
291: */
292: for (; dp != NULL; dp = dp->d_next)
293: if (eq(dev, dp->d_name) && dp->d_unit == -1)
294: break;
295: /*
296: * If there isn't, make one becuase everything needs to be connected
297: * to something.
298: */
299: if (dp == NULL)
300: {
301: dp = &rdev;
302: init_dev(dp);
303: dp->d_unit = QUES;
304: dp->d_name = ns(dev);
305: dp->d_type = oldtype;
306: newdev(dp);
307: dp = curp;
308: /*
309: * Connect it to the same thing that other similar things are
310: * connected to, but make sure it is a wildcard unit
311: * (e.g. up connected to sc ?, here we make connect sc? to a uba?)
312: * If other things like this are on the NEXUS or if the aren't
313: * connected to anything, then make the same connection, else
314: * call ourself to connect to another unspecific device.
315: */
316: if (dcp == TO_NEXUS || dcp == NULL)
317: dp->d_conn = dcp;
318: else
319: dp->d_conn = connect(dcp->d_name, QUES);
320: }
321: return dp;
322: }
323:
324: /*
325: * init_dev:
326: * Set up the fields in the current device to their
327: * default values.
328: */
329:
330: init_dev(dp)
331: register struct device *dp;
332: {
333: dp->d_name = "OHNO!!!";
334: dp->d_type = DEVICE;
335: dp->d_conn = NULL;
336: dp->d_vec = NULL;
337: dp->d_addr = dp->d_flags = dp->d_dk = 0;
338: dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN;
339: dp->d_count = 0;
340: }
341:
342: /*
343: * Check_nexus:
344: * Make certain that this is a reasonable type of thing to put
345: * on the nexus.
346: */
347:
348: check_nexus(dev, num)
349: register struct device *dev;
350: int num;
351: {
352: if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba"))
353: yyerror("only uba's and mba's should be connected to the nexus");
354: if (num != QUES)
355: yyerror("can't give specific nexus numbers");
356: }
357:
358: /*
359: * Check the timezone to make certain it is sensible
360: */
361:
362: check_tz()
363: {
364: if (timezone > 24 * 60)
365: yyerror("timezone is unreasonable");
366: else
367: hadtz = TRUE;
368: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.