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