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