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