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