xref: /dragonfly/usr.sbin/config/config.y (revision 2cd2d2b5)
1 %union {
2 	char	*str;
3 	int	val;
4 	struct	file_list *file;
5 }
6 
7 %token	ANY
8 %token	ARCH
9 %token	AT
10 %token	BUS
11 %token	COMMA
12 %token	CONFIG
13 %token	CONFLICTS
14 %token	CONTROLLER
15 %token	CPU
16 %token	DEVICE
17 %token	DISABLE
18 %token	DISK
19 %token	DRIVE
20 %token	DRQ
21 %token	EQUALS
22 %token	FLAGS
23 %token	IDENT
24 %token	IOMEM
25 %token	IOSIZ
26 %token	IRQ
27 %token	MAXUSERS
28 %token	MINUS
29 %token	NEXUS
30 %token	OPTIONS
31 %token	MAKEOPTIONS
32 %token	PORT
33 %token	PSEUDO_DEVICE
34 %token	SEMICOLON
35 %token	TAPE
36 %token	TARGET
37 %token	TTY
38 %token	UNIT
39 %token	VECTOR
40 
41 %token	<str>	ID
42 %token	<val>	NUMBER
43 %token	<val>	FPNUMBER
44 
45 %type	<str>	Save_id
46 %type	<str>	Opt_value
47 %type	<str>	Dev
48 %type	<str>	device_name
49 
50 %{
51 
52 /*
53  * Copyright (c) 1988, 1993
54  *	The Regents of the University of California.  All rights reserved.
55  *
56  * Redistribution and use in source and binary forms, with or without
57  * modification, are permitted provided that the following conditions
58  * are met:
59  * 1. Redistributions of source code must retain the above copyright
60  *    notice, this list of conditions and the following disclaimer.
61  * 2. Redistributions in binary form must reproduce the above copyright
62  *    notice, this list of conditions and the following disclaimer in the
63  *    documentation and/or other materials provided with the distribution.
64  * 3. All advertising materials mentioning features or use of this software
65  *    must display the following acknowledgement:
66  *	This product includes software developed by the University of
67  *	California, Berkeley and its contributors.
68  * 4. Neither the name of the University nor the names of its contributors
69  *    may be used to endorse or promote products derived from this software
70  *    without specific prior written permission.
71  *
72  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
73  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
74  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
75  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
76  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
77  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
78  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
79  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
80  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
81  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82  * SUCH DAMAGE.
83  *
84  *	@(#)config.y	8.1 (Berkeley) 6/6/93
85  * $FreeBSD: src/usr.sbin/config/config.y,v 1.42.2.1 2001/01/23 00:09:32 peter Exp $
86  * $DragonFly: src/usr.sbin/config/config.y,v 1.10 2004/03/08 03:28:01 dillon Exp $
87  */
88 
89 #include <ctype.h>
90 #include <err.h>
91 #include <stdio.h>
92 #include <string.h>
93 
94 #include "config.h"
95 
96 static struct	device cur;
97 static struct	device *curp = 0;
98 
99 struct  device *dtab;
100 char	*ident;
101 int	yyline;
102 struct  file_list *ftab;
103 char	errbuf[80];
104 int	maxusers;
105 
106 static int connect(char *, int);
107 static void yyerror(char *s);
108 
109 
110 %}
111 %%
112 Configuration:
113 	Many_specs
114 		;
115 
116 Many_specs:
117 	Many_specs Spec
118 		|
119 	/* lambda */
120 		;
121 
122 Spec:
123 	Device_spec SEMICOLON
124 	      = { newdev(&cur); } |
125 	Config_spec SEMICOLON
126 		|
127 	SEMICOLON
128 		|
129 	error SEMICOLON
130 		;
131 
132 Config_spec:
133 	ARCH Save_id
134 	    = {
135 		if (machinename != NULL) {
136 		    errx(1, "%d: only one machine directive is allowed",
137 			yyline);
138 		}
139 		machinename = $2;
140 	      } |
141 	CPU Save_id
142 	      = {
143 		struct cputype *cp;
144 
145 		cp = malloc(sizeof(struct cputype));
146 		bzero(cp, sizeof(*cp));
147 		cp->cpu_name = $2;
148 		cp->cpu_next = cputype;
149 		cputype = cp;
150 	      } |
151 	OPTIONS Opt_list
152 		|
153 	MAKEOPTIONS Mkopt_list
154 		|
155 	IDENT ID
156 	      = { ident = $2; } |
157 	System_spec
158 		|
159 	MAXUSERS NUMBER
160 	      = { maxusers = $2; };
161 
162 System_spec:
163 	CONFIG System_id System_parameter_list
164 	  = { errx(1,"line %d: root/dump/swap specifications obsolete", yyline);}
165 	  |
166 	CONFIG System_id
167 	  ;
168 
169 System_id:
170 	Save_id
171 	      = {
172 		struct opt *op;
173 
174 		op = malloc(sizeof(struct opt));
175 		bzero(op, sizeof(*op));
176 		op->op_name = strdup("KERNEL");
177 		op->op_ownfile = 0;
178 		op->op_next = mkopt;
179 		op->op_value = $1;
180 		op->op_line = yyline + 1;
181 		mkopt = op;
182 	      };
183 
184 System_parameter_list:
185 	  System_parameter_list ID
186 	| ID
187 	;
188 
189 device_name:
190 	  Save_id
191 		= { $$ = $1; }
192 	| Save_id NUMBER
193 		= {
194 			char buf[80];
195 
196 			snprintf(buf, sizeof(buf), "%s%d", $1, $2);
197 			$$ = strdup(buf);
198 			free($1);
199 		}
200 	| Save_id NUMBER ID
201 		= {
202 			char buf[80];
203 
204 			snprintf(buf, sizeof(buf), "%s%d%s", $1, $2, $3);
205 			$$ = strdup(buf);
206 			free($1);
207 		}
208 	| Save_id NUMBER ID NUMBER
209 		= {
210 			char buf[80];
211 
212 			snprintf(buf, sizeof(buf), "%s%d%s%d",
213 			     $1, $2, $3, $4);
214 			$$ = strdup(buf);
215 			free($1);
216 		}
217 	| Save_id NUMBER ID NUMBER ID
218 		= {
219 			char buf[80];
220 
221 			snprintf(buf, sizeof(buf), "%s%d%s%d%s",
222 			     $1, $2, $3, $4, $5);
223 			$$ = strdup(buf);
224 			free($1);
225 		}
226 	;
227 
228 Opt_list:
229 	Opt_list COMMA Option
230 		|
231 	Option
232 		;
233 
234 Option:
235 	Save_id
236 	      = {
237 		struct opt *op;
238 
239 		op = malloc(sizeof(struct opt));
240 		bzero(op, sizeof(*op));
241 		op->op_name = $1;
242 		op->op_next = opt;
243 		op->op_value = 0;
244 		/*
245 		 * op->op_line is 1-based; yyline is 0-based but is now 1
246 		 * larger than when `Save_id' was lexed.
247 		 */
248 		op->op_line = yyline;
249 		opt = op;
250 		if (strchr(op->op_name, '=') != NULL)
251 			errx(1, "line %d: The `=' in options should not be quoted", yyline);
252 	      } |
253 	Save_id EQUALS Opt_value
254 	      = {
255 		struct opt *op;
256 
257 		op = malloc(sizeof(struct opt));
258 		bzero(op, sizeof(*op));
259 		op->op_name = $1;
260 		op->op_next = opt;
261 		op->op_value = $3;
262 		op->op_line = yyline + 1;
263 		opt = op;
264 	      } ;
265 
266 Opt_value:
267 	ID
268 		= { $$ = $1; } |
269 	NUMBER
270 		= {
271 			char buf[80];
272 
273 			snprintf(buf, sizeof(buf), "%d", $1);
274 			$$ = strdup(buf);
275 		} ;
276 
277 Save_id:
278 	ID
279 	      = { $$ = $1; }
280 	;
281 
282 Mkopt_list:
283 	Mkopt_list COMMA Mkoption
284 		|
285 	Mkoption
286 		;
287 
288 Mkoption:
289 	Save_id EQUALS Opt_value
290 	      = {
291 		struct opt *op;
292 
293 		op = malloc(sizeof(struct opt));
294 		bzero(op, sizeof(*op));
295 		op->op_name = $1;
296 		op->op_ownfile = 0;	/* for now */
297 		op->op_next = mkopt;
298 		op->op_value = $3;
299 		op->op_line = yyline + 1;
300 		mkopt = op;
301 	      } ;
302 
303 Dev:
304 	ID
305 	      = { $$ = $1; }
306 	;
307 
308 Device_spec:
309 	DEVICE Dev_spec
310 	      = { cur.d_type = DEVICE; } |
311 	DISK Dev_spec
312 	      = {
313 		errx(1, "line %d: Obsolete keyword 'disk' found - use 'device'", yyline);
314 		} |
315 	TAPE Dev_spec
316 	      = {
317 		errx(1, "line %d: Obsolete keyword 'tape' found - use 'device'", yyline);
318 		} |
319 	CONTROLLER Dev_spec
320 	      = {
321 		errx(1, "line %d: Obsolete keyword 'controller' found - use 'device'", yyline);
322 	        } |
323 	PSEUDO_DEVICE Init_dev Dev
324 	      = {
325 		cur.d_name = $3;
326 		cur.d_type = PSEUDO_DEVICE;
327 		} |
328 	PSEUDO_DEVICE Init_dev Dev NUMBER
329 	      = {
330 		cur.d_name = $3;
331 		cur.d_type = PSEUDO_DEVICE;
332 		cur.d_count = $4;
333 		} ;
334 
335 Dev_spec:
336 	Init_dev Dev
337 	      = {
338 		cur.d_name = $2;
339 		cur.d_unit = UNKNOWN;
340 		} |
341 	Init_dev Dev NUMBER Dev_info
342 	      = {
343 		cur.d_name = $2;
344 		cur.d_unit = $3;
345 		};
346 
347 Init_dev:
348 	/* lambda */
349 	      = { init_dev(&cur); };
350 
351 Dev_info:
352 	Con_info Info_list
353 		|
354 	/* lambda */
355 		;
356 
357 Con_info:
358 	AT Dev NUMBER
359 	      = {
360 		connect($2, $3);
361 		cur.d_conn = $2;
362 		cur.d_connunit = $3;
363 		} |
364 	AT NEXUS NUMBER
365 	      = {
366 	        cur.d_conn = "nexus";
367 	        cur.d_connunit = 0;
368 	        };
369 
370 Info_list:
371 	Info_list Info
372 		|
373 	/* lambda */
374 		;
375 
376 Info:
377 	BUS NUMBER	/* device scbus1 at ahc0 bus 1 - twin channel */
378 	      = { cur.d_bus = $2; } |
379 	TARGET NUMBER
380 	      = { cur.d_target = $2; } |
381 	UNIT NUMBER
382 	      = { cur.d_lun = $2; } |
383 	DRIVE NUMBER
384 	      = { cur.d_drive = $2; } |
385 	IRQ NUMBER
386 	      = { cur.d_irq = $2; } |
387 	DRQ NUMBER
388 	      = { cur.d_drq = $2; } |
389 	IOMEM NUMBER
390 	      = { cur.d_maddr = $2; } |
391 	IOSIZ NUMBER
392 	      = { cur.d_msize = $2; } |
393 	PORT device_name
394 	      = { cur.d_port = $2; } |
395 	PORT NUMBER
396 	      = { cur.d_portn = $2; } |
397 	FLAGS NUMBER
398 	      = { cur.d_flags = $2; } |
399 	DISABLE
400 	      = { cur.d_disabled = 1; } |
401 	CONFLICTS
402 	      = {
403 		errx(1, "line %d: Obsolete keyword 'conflicts' found", yyline);
404 		};
405 
406 %%
407 
408 static void
409 yyerror(char *s)
410 {
411 
412 	errx(1, "line %d: %s", yyline + 1, s);
413 }
414 
415 /*
416  * add a device to the list of devices
417  */
418 static void
419 newdev(struct device *dp)
420 {
421 	struct device *np, *xp;
422 
423 	if (dp->d_unit >= 0) {
424 		for (xp = dtab; xp != NULL; xp = xp->d_next) {
425 			if ((xp->d_unit == dp->d_unit) &&
426 			    !strcmp(xp->d_name, dp->d_name)) {
427 				errx(1, "line %d: already seen device %s%d",
428 				    yyline, xp->d_name, xp->d_unit);
429 			}
430 		}
431 	}
432 	np = malloc(sizeof(*np));
433 	bzero(np, sizeof(*np));
434 	*np = *dp;
435 	np->d_next = NULL;
436 	if (curp == NULL)
437 		dtab = np;
438 	else
439 		curp->d_next = np;
440 	curp = np;
441 }
442 
443 
444 /*
445  * find the pointer to connect to the given device and number.
446  * returns 0 if no such device and prints an error message
447  */
448 static int
449 connect(char *dev, int num)
450 {
451 	struct device *dp;
452 
453 	if (num == QUES) {
454 		for (dp = dtab; dp != NULL; dp = dp->d_next)
455 			if (!strcmp(dp->d_name, dev))
456 				break;
457 		if (dp == NULL) {
458 			snprintf(errbuf, sizeof(errbuf),
459 			    "no %s's to wildcard", dev);
460 			yyerror(errbuf);
461 			return(0);
462 		}
463 		return(1);
464 	}
465 	for (dp = dtab; dp != NULL; dp = dp->d_next) {
466 		if ((num != dp->d_unit) || strcmp(dev, dp->d_name))
467 			continue;
468 		if (dp->d_type != DEVICE) {
469 			snprintf(errbuf, sizeof(errbuf),
470 			    "%s connected to non-device", dev);
471 			yyerror(errbuf);
472 			return(0);
473 		}
474 		return(1);
475 	}
476 	snprintf(errbuf, sizeof(errbuf), "%s %d not defined", dev, num);
477 	yyerror(errbuf);
478 	return(0);
479 }
480 
481 void
482 init_dev(struct device *dp)
483 {
484 
485 	dp->d_name = "OHNO!!!";
486 	dp->d_type = DEVICE;
487 	dp->d_conn = 0;
488 	dp->d_disabled = 0;
489 	dp->d_flags = 0;
490 	dp->d_bus = dp->d_lun = dp->d_target = dp->d_drive = dp->d_unit =
491 	    dp->d_count = UNKNOWN;
492 	dp->d_port = NULL;
493 	dp->d_portn = -1;
494 	dp->d_irq = -1;
495 	dp->d_drq = -1;
496 	dp->d_maddr = 0;
497 	dp->d_msize = 0;
498 }
499