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