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