DLW sent fix (anything that goes off at 2 won't work)
[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
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%%
13Configuration:
14 Many_specs
15 ;
16
17Many_specs:
18 Many_specs Spec
19 |
20 ;
21
22Spec:
23 Device_spec SEMICOLON = { newdev(&cur); } |
24 Config_spec SEMICOLON |
25 TRACE SEMICOLON = { do_trace = ! do_trace; } |
26 SEMICOLON |
27 error SEMICOLON
28 ;
29
30Config_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
53Opt_list:
54 Opt_list COMMA Option |
55 Option
56 ;
57
58Option:
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
68Save_id:
69 ID = { $$ = temp_id = ns($1); }
70 ;
71
72Dev:
73 UBA = { $$ = ns("uba"); } |
74 MBA = { $$ = ns("mba"); } |
75 ID = { $$ = ns($1); }
76 ;
77
78Device_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
88Dev_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
99Init_dev:
f6f4af06 100 = { init_dev(&cur); }
2f47f1cc
MT
101 ;
102
103Dev_info:
104 Con_info Info_list
105 |
106 ;
107
108Con_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
118Info_list:
119 Info_list Info
120 |
121 ;
122
123Info:
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
137Int_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
143yyerror(s)
144char *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
154char *
155ns(str)
156register 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
170newdev(dp)
171register 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
189mkconf(dev, sysname)
190char *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 210struct device *connect(dev, num)
2f47f1cc
MT
211register char *dev;
212register 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
238struct device *huhcon(dev)
239register 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
300init_dev(dp)
301register 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
317check_nexus(dev, num)
318register struct device *dev;
319int 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
331check_tz()
332{
333 if (timezone > 24 * 60)
334 yyerror("timezone is unreasonable");
335 else
336 hadtz = TRUE;
337}