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