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