1 %union { 2 char *str; 3 int val; 4 struct file_list *file; 5 struct idlst *lst; 6 } 7 8 %token AND 9 %token ANY 10 %token ARGS 11 %token AT 12 %token BIO 13 %token COMMA 14 %token CONFIG 15 %token CONTROLLER 16 %token CPU 17 %token CSR 18 %token DEVICE 19 %token DISK 20 %token DRIVE 21 %token DRQ 22 %token DST 23 %token DUMPS 24 %token EQUALS 25 %token FLAGS 26 %token HZ 27 %token IDENT 28 %token IOMEM 29 %token IOSIZ 30 %token IRQ 31 %token MACHINE 32 %token MAJOR 33 %token MASTER 34 %token MAXUSERS 35 %token MINOR 36 %token MINUS 37 %token NET 38 %token NEXUS 39 %token ON 40 %token OPTIONS 41 %token MAKEOPTIONS 42 %token PORT 43 %token PRIORITY 44 %token PSEUDO_DEVICE 45 %token ROOT 46 %token SEMICOLON 47 %token SIZE 48 %token SLAVE 49 %token SWAP 50 %token TIMEZONE 51 %token TTY 52 %token TRACE 53 %token VECTOR 54 55 %token <str> ID 56 %token <val> NUMBER 57 %token <val> FPNUMBER 58 59 %type <str> Save_id 60 %type <str> Opt_value 61 %type <str> Dev 62 %type <lst> Id_list 63 %type <val> optional_size 64 %type <str> device_name 65 %type <val> major_minor 66 %type <val> arg_device_spec 67 %type <val> root_device_spec 68 %type <val> dump_device_spec 69 %type <file> swap_device_spec 70 71 %{ 72 73 /* 74 * Copyright (c) 1988 Regents of the University of California. 75 * All rights reserved. 76 * 77 * %sccs.include.redist.c% 78 * 79 * @(#)config.y 5.13 (Berkeley) 05/24/91 80 */ 81 82 #include "config.h" 83 #include <ctype.h> 84 #include <stdio.h> 85 86 struct device cur; 87 struct device *curp = 0; 88 char *temp_id; 89 char *val_id; 90 91 %} 92 %% 93 Configuration: 94 Many_specs 95 = { verifysystemspecs(); } 96 ; 97 98 Many_specs: 99 Many_specs Spec 100 | 101 /* lambda */ 102 ; 103 104 Spec: 105 Device_spec SEMICOLON 106 = { newdev(&cur); } | 107 Config_spec SEMICOLON 108 | 109 TRACE SEMICOLON 110 = { do_trace = !do_trace; } | 111 SEMICOLON 112 | 113 error SEMICOLON 114 ; 115 116 Config_spec: 117 MACHINE Save_id 118 = { 119 if (!strcmp($2, "vax")) { 120 machine = MACHINE_VAX; 121 machinename = "vax"; 122 } else if (!strcmp($2, "tahoe")) { 123 machine = MACHINE_TAHOE; 124 machinename = "tahoe"; 125 } else if (!strcmp($2, "hp300")) { 126 machine = MACHINE_HP300; 127 machinename = "hp300"; 128 } else if (!strcmp($2, "i386")) { 129 machine = MACHINE_I386; 130 machinename = "i386"; 131 } else 132 yyerror("Unknown machine type"); 133 } | 134 CPU Save_id 135 = { 136 struct cputype *cp = 137 (struct cputype *)malloc(sizeof (struct cputype)); 138 cp->cpu_name = ns($2); 139 cp->cpu_next = cputype; 140 cputype = cp; 141 free(temp_id); 142 } | 143 OPTIONS Opt_list 144 | 145 MAKEOPTIONS Mkopt_list 146 | 147 IDENT ID 148 = { ident = ns($2); } | 149 System_spec 150 | 151 HZ NUMBER 152 = { yyerror("HZ specification obsolete; delete"); } | 153 TIMEZONE NUMBER 154 = { zone = 60 * $2; check_tz(); } | 155 TIMEZONE NUMBER DST NUMBER 156 = { zone = 60 * $2; dst = $4; check_tz(); } | 157 TIMEZONE NUMBER DST 158 = { zone = 60 * $2; dst = 1; check_tz(); } | 159 TIMEZONE FPNUMBER 160 = { zone = $2; check_tz(); } | 161 TIMEZONE FPNUMBER DST NUMBER 162 = { zone = $2; dst = $4; check_tz(); } | 163 TIMEZONE FPNUMBER DST 164 = { zone = $2; dst = 1; check_tz(); } | 165 TIMEZONE MINUS NUMBER 166 = { zone = -60 * $3; check_tz(); } | 167 TIMEZONE MINUS NUMBER DST NUMBER 168 = { zone = -60 * $3; dst = $5; check_tz(); } | 169 TIMEZONE MINUS NUMBER DST 170 = { zone = -60 * $3; dst = 1; check_tz(); } | 171 TIMEZONE MINUS FPNUMBER 172 = { zone = -$3; check_tz(); } | 173 TIMEZONE MINUS FPNUMBER DST NUMBER 174 = { zone = -$3; dst = $5; check_tz(); } | 175 TIMEZONE MINUS FPNUMBER DST 176 = { zone = -$3; dst = 1; check_tz(); } | 177 MAXUSERS NUMBER 178 = { maxusers = $2; }; 179 180 System_spec: 181 System_id System_parameter_list 182 = { checksystemspec(*confp); } 183 ; 184 185 System_id: 186 CONFIG Save_id 187 = { mkconf($2); } 188 ; 189 190 System_parameter_list: 191 System_parameter_list System_parameter 192 | System_parameter 193 ; 194 195 System_parameter: 196 swap_spec 197 | root_spec 198 | dump_spec 199 | arg_spec 200 ; 201 202 swap_spec: 203 SWAP optional_on swap_device_list 204 ; 205 206 swap_device_list: 207 swap_device_list AND swap_device 208 | swap_device 209 ; 210 211 swap_device: 212 swap_device_spec optional_size 213 = { mkswap(*confp, $1, $2); } 214 ; 215 216 swap_device_spec: 217 device_name 218 = { 219 struct file_list *fl = newswap(); 220 221 if (eq($1, "generic")) 222 fl->f_fn = $1; 223 else { 224 fl->f_swapdev = nametodev($1, 0, 'b'); 225 fl->f_fn = devtoname(fl->f_swapdev); 226 } 227 $$ = fl; 228 } 229 | major_minor 230 = { 231 struct file_list *fl = newswap(); 232 233 fl->f_swapdev = $1; 234 fl->f_fn = devtoname($1); 235 $$ = fl; 236 } 237 ; 238 239 root_spec: 240 ROOT optional_on root_device_spec 241 = { 242 struct file_list *fl = *confp; 243 244 if (fl && fl->f_rootdev != NODEV) 245 yyerror("extraneous root device specification"); 246 else 247 fl->f_rootdev = $3; 248 } 249 ; 250 251 root_device_spec: 252 device_name 253 = { $$ = nametodev($1, 0, 'a'); } 254 | major_minor 255 ; 256 257 dump_spec: 258 DUMPS optional_on dump_device_spec 259 = { 260 struct file_list *fl = *confp; 261 262 if (fl && fl->f_dumpdev != NODEV) 263 yyerror("extraneous dump device specification"); 264 else 265 fl->f_dumpdev = $3; 266 } 267 268 ; 269 270 dump_device_spec: 271 device_name 272 = { $$ = nametodev($1, 0, 'b'); } 273 | major_minor 274 ; 275 276 arg_spec: 277 ARGS optional_on arg_device_spec 278 = { 279 struct file_list *fl = *confp; 280 281 if (fl && fl->f_argdev != NODEV) 282 yyerror("extraneous arg device specification"); 283 else 284 fl->f_argdev = $3; 285 } 286 ; 287 288 arg_device_spec: 289 device_name 290 = { $$ = nametodev($1, 0, 'b'); } 291 | major_minor 292 ; 293 294 major_minor: 295 MAJOR NUMBER MINOR NUMBER 296 = { $$ = makedev($2, $4); } 297 ; 298 299 optional_on: 300 ON 301 | /* empty */ 302 ; 303 304 optional_size: 305 SIZE NUMBER 306 = { $$ = $2; } 307 | /* empty */ 308 = { $$ = 0; } 309 ; 310 311 device_name: 312 Save_id 313 = { $$ = $1; } 314 | Save_id NUMBER 315 = { 316 char buf[80]; 317 318 (void) sprintf(buf, "%s%d", $1, $2); 319 $$ = ns(buf); free($1); 320 } 321 | Save_id NUMBER ID 322 = { 323 char buf[80]; 324 325 (void) sprintf(buf, "%s%d%s", $1, $2, $3); 326 $$ = ns(buf); free($1); 327 } 328 ; 329 330 Opt_list: 331 Opt_list COMMA Option 332 | 333 Option 334 ; 335 336 Option: 337 Save_id 338 = { 339 struct opt *op = (struct opt *)malloc(sizeof (struct opt)); 340 op->op_name = ns($1); 341 op->op_next = opt; 342 op->op_value = 0; 343 opt = op; 344 free(temp_id); 345 } | 346 Save_id EQUALS Opt_value 347 = { 348 struct opt *op = (struct opt *)malloc(sizeof (struct opt)); 349 op->op_name = ns($1); 350 op->op_next = opt; 351 op->op_value = ns($3); 352 opt = op; 353 free(temp_id); 354 free(val_id); 355 } ; 356 357 Opt_value: 358 ID 359 = { $$ = val_id = ns($1); } | 360 NUMBER 361 = { 362 char nb[16]; 363 (void) sprintf(nb, "%d", $1); 364 $$ = val_id = ns(nb); 365 } ; 366 367 368 Save_id: 369 ID 370 = { $$ = temp_id = ns($1); } 371 ; 372 373 Mkopt_list: 374 Mkopt_list COMMA Mkoption 375 | 376 Mkoption 377 ; 378 379 Mkoption: 380 Save_id EQUALS Opt_value 381 = { 382 struct opt *op = (struct opt *)malloc(sizeof (struct opt)); 383 op->op_name = ns($1); 384 op->op_next = mkopt; 385 op->op_value = ns($3); 386 mkopt = op; 387 free(temp_id); 388 free(val_id); 389 } ; 390 391 Dev: 392 ID 393 = { $$ = ns($1); } 394 ; 395 396 Device_spec: 397 DEVICE Dev_name Dev_info Int_spec 398 = { cur.d_type = DEVICE; } | 399 MASTER Dev_name Dev_info Int_spec 400 = { cur.d_type = MASTER; } | 401 DISK Dev_name Dev_info Int_spec 402 = { cur.d_dk = 1; cur.d_type = DEVICE; } | 403 CONTROLLER Dev_name Dev_info Int_spec 404 = { cur.d_type = CONTROLLER; } | 405 PSEUDO_DEVICE Init_dev Dev 406 = { 407 cur.d_name = $3; 408 cur.d_type = PSEUDO_DEVICE; 409 } | 410 PSEUDO_DEVICE Init_dev Dev NUMBER 411 = { 412 cur.d_name = $3; 413 cur.d_type = PSEUDO_DEVICE; 414 cur.d_slave = $4; 415 }; 416 417 Dev_name: 418 Init_dev Dev NUMBER 419 = { 420 cur.d_name = $2; 421 if (eq($2, "mba")) 422 seen_mba = 1; 423 else if (eq($2, "uba")) 424 seen_uba = 1; 425 else if (eq($2, "vba")) 426 seen_vba = 1; 427 else if (eq($2, "isa")) 428 seen_isa = 1; 429 cur.d_unit = $3; 430 }; 431 432 Init_dev: 433 /* lambda */ 434 = { init_dev(&cur); }; 435 436 Dev_info: 437 Con_info Info_list 438 | 439 /* lambda */ 440 ; 441 442 Con_info: 443 AT Dev NUMBER 444 = { 445 if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) { 446 (void) sprintf(errbuf, 447 "%s must be connected to a nexus", cur.d_name); 448 yyerror(errbuf); 449 } 450 cur.d_conn = connect($2, $3); 451 } | 452 AT NEXUS NUMBER 453 = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; }; 454 455 Info_list: 456 Info_list Info 457 | 458 /* lambda */ 459 ; 460 461 Info: 462 CSR NUMBER 463 = { cur.d_addr = $2; } | 464 DRIVE NUMBER 465 = { cur.d_drive = $2; } | 466 SLAVE NUMBER 467 = { 468 if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS && 469 cur.d_conn->d_type == MASTER) 470 cur.d_slave = $2; 471 else 472 yyerror("can't specify slave--not to master"); 473 } | 474 IRQ NUMBER 475 = { cur.d_irq = $2; } | 476 DRQ NUMBER 477 = { cur.d_drq = $2; } | 478 IOMEM NUMBER 479 = { cur.d_maddr = $2; } | 480 IOSIZ NUMBER 481 = { cur.d_msize = $2; } | 482 PORT device_name 483 = { cur.d_port = ns($2); } | 484 PORT NUMBER 485 = { cur.d_portn = $2; } | 486 TTY 487 = { cur.d_mask = "tty"; } | 488 BIO 489 = { cur.d_mask = "bio"; } | 490 NET 491 = { cur.d_mask = "net"; } | 492 FLAGS NUMBER 493 = { cur.d_flags = $2; }; 494 495 Int_spec: 496 VECTOR Id_list 497 = { cur.d_vec = $2; } | 498 PRIORITY NUMBER 499 = { cur.d_pri = $2; } | 500 /* lambda */ 501 ; 502 503 Id_list: 504 Save_id 505 = { 506 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); 507 a->id = $1; a->id_next = 0; $$ = a; 508 } | 509 Save_id Id_list = 510 { 511 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); 512 a->id = $1; a->id_next = $2; $$ = a; 513 }; 514 515 %% 516 517 yyerror(s) 518 char *s; 519 { 520 521 fprintf(stderr, "config: line %d: %s\n", yyline + 1, s); 522 } 523 524 /* 525 * return the passed string in a new space 526 */ 527 char * 528 ns(str) 529 register char *str; 530 { 531 register char *cp; 532 533 cp = malloc((unsigned)(strlen(str)+1)); 534 (void) strcpy(cp, str); 535 return (cp); 536 } 537 538 /* 539 * add a device to the list of devices 540 */ 541 newdev(dp) 542 register struct device *dp; 543 { 544 register struct device *np; 545 546 np = (struct device *) malloc(sizeof *np); 547 *np = *dp; 548 np->d_next = 0; 549 if (curp == 0) 550 dtab = np; 551 else 552 curp->d_next = np; 553 curp = np; 554 } 555 556 /* 557 * note that a configuration should be made 558 */ 559 mkconf(sysname) 560 char *sysname; 561 { 562 register struct file_list *fl, **flp; 563 564 fl = (struct file_list *) malloc(sizeof *fl); 565 fl->f_type = SYSTEMSPEC; 566 fl->f_needs = sysname; 567 fl->f_rootdev = NODEV; 568 fl->f_argdev = NODEV; 569 fl->f_dumpdev = NODEV; 570 fl->f_fn = 0; 571 fl->f_next = 0; 572 for (flp = confp; *flp; flp = &(*flp)->f_next) 573 ; 574 *flp = fl; 575 confp = flp; 576 } 577 578 struct file_list * 579 newswap() 580 { 581 struct file_list *fl = (struct file_list *)malloc(sizeof (*fl)); 582 583 fl->f_type = SWAPSPEC; 584 fl->f_next = 0; 585 fl->f_swapdev = NODEV; 586 fl->f_swapsize = 0; 587 fl->f_needs = 0; 588 fl->f_fn = 0; 589 return (fl); 590 } 591 592 /* 593 * Add a swap device to the system's configuration 594 */ 595 mkswap(system, fl, size) 596 struct file_list *system, *fl; 597 int size; 598 { 599 register struct file_list **flp; 600 char name[80]; 601 602 if (system == 0 || system->f_type != SYSTEMSPEC) { 603 yyerror("\"swap\" spec precedes \"config\" specification"); 604 return; 605 } 606 if (size < 0) { 607 yyerror("illegal swap partition size"); 608 return; 609 } 610 /* 611 * Append swap description to the end of the list. 612 */ 613 flp = &system->f_next; 614 for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next) 615 ; 616 fl->f_next = *flp; 617 *flp = fl; 618 fl->f_swapsize = size; 619 /* 620 * If first swap device for this system, 621 * set up f_fn field to insure swap 622 * files are created with unique names. 623 */ 624 if (system->f_fn) 625 return; 626 if (eq(fl->f_fn, "generic")) 627 system->f_fn = ns(fl->f_fn); 628 else 629 system->f_fn = ns(system->f_needs); 630 } 631 632 /* 633 * find the pointer to connect to the given device and number. 634 * returns 0 if no such device and prints an error message 635 */ 636 struct device * 637 connect(dev, num) 638 register char *dev; 639 register int num; 640 { 641 register struct device *dp; 642 struct device *huhcon(); 643 644 if (num == QUES) 645 return (huhcon(dev)); 646 for (dp = dtab; dp != 0; dp = dp->d_next) { 647 if ((num != dp->d_unit) || !eq(dev, dp->d_name)) 648 continue; 649 if (dp->d_type != CONTROLLER && dp->d_type != MASTER) { 650 (void) sprintf(errbuf, 651 "%s connected to non-controller", dev); 652 yyerror(errbuf); 653 return (0); 654 } 655 return (dp); 656 } 657 (void) sprintf(errbuf, "%s %d not defined", dev, num); 658 yyerror(errbuf); 659 return (0); 660 } 661 662 /* 663 * connect to an unspecific thing 664 */ 665 struct device * 666 huhcon(dev) 667 register char *dev; 668 { 669 register struct device *dp, *dcp; 670 struct device rdev; 671 int oldtype; 672 673 /* 674 * First make certain that there are some of these to wildcard on 675 */ 676 for (dp = dtab; dp != 0; dp = dp->d_next) 677 if (eq(dp->d_name, dev)) 678 break; 679 if (dp == 0) { 680 (void) sprintf(errbuf, "no %s's to wildcard", dev); 681 yyerror(errbuf); 682 return (0); 683 } 684 oldtype = dp->d_type; 685 dcp = dp->d_conn; 686 /* 687 * Now see if there is already a wildcard entry for this device 688 * (e.g. Search for a "uba ?") 689 */ 690 for (; dp != 0; dp = dp->d_next) 691 if (eq(dev, dp->d_name) && dp->d_unit == -1) 692 break; 693 /* 694 * If there isn't, make one because everything needs to be connected 695 * to something. 696 */ 697 if (dp == 0) { 698 dp = &rdev; 699 init_dev(dp); 700 dp->d_unit = QUES; 701 dp->d_name = ns(dev); 702 dp->d_type = oldtype; 703 newdev(dp); 704 dp = curp; 705 /* 706 * Connect it to the same thing that other similar things are 707 * connected to, but make sure it is a wildcard unit 708 * (e.g. up connected to sc ?, here we make connect sc? to a 709 * uba?). If other things like this are on the NEXUS or 710 * if they aren't connected to anything, then make the same 711 * connection, else call ourself to connect to another 712 * unspecific device. 713 */ 714 if (dcp == TO_NEXUS || dcp == 0) 715 dp->d_conn = dcp; 716 else 717 dp->d_conn = connect(dcp->d_name, QUES); 718 } 719 return (dp); 720 } 721 722 init_dev(dp) 723 register struct device *dp; 724 { 725 726 dp->d_name = "OHNO!!!"; 727 dp->d_type = DEVICE; 728 dp->d_conn = 0; 729 dp->d_vec = 0; 730 dp->d_addr = dp->d_pri = dp->d_flags = dp->d_dk = 0; 731 dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN; 732 dp->d_port = (char *)0; 733 dp->d_portn = 0; 734 dp->d_irq = -1; 735 dp->d_drq = -1; 736 dp->d_maddr = 0; 737 dp->d_msize = 0; 738 dp->d_mask = "null"; 739 } 740 741 /* 742 * make certain that this is a reasonable type of thing to connect to a nexus 743 */ 744 check_nexus(dev, num) 745 register struct device *dev; 746 int num; 747 { 748 749 switch (machine) { 750 751 case MACHINE_VAX: 752 if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") && 753 !eq(dev->d_name, "bi")) 754 yyerror("only uba's, mba's, and bi's should be connected to the nexus"); 755 if (num != QUES) 756 yyerror("can't give specific nexus numbers"); 757 break; 758 759 case MACHINE_TAHOE: 760 if (!eq(dev->d_name, "vba")) 761 yyerror("only vba's should be connected to the nexus"); 762 break; 763 764 case MACHINE_HP300: 765 if (num != QUES) 766 dev->d_addr = num; 767 break; 768 769 case MACHINE_I386: 770 if (!eq(dev->d_name, "isa")) 771 yyerror("only isa's should be connected to the nexus"); 772 break; 773 } 774 } 775 776 /* 777 * Check the timezone to make certain it is sensible 778 */ 779 780 check_tz() 781 { 782 if (abs(zone) > 12 * 60) 783 yyerror("timezone is unreasonable"); 784 else 785 hadtz = 1; 786 } 787 788 /* 789 * Check system specification and apply defaulting 790 * rules on root, argument, dump, and swap devices. 791 */ 792 checksystemspec(fl) 793 register struct file_list *fl; 794 { 795 char buf[BUFSIZ]; 796 register struct file_list *swap; 797 int generic; 798 799 if (fl == 0 || fl->f_type != SYSTEMSPEC) { 800 yyerror("internal error, bad system specification"); 801 exit(1); 802 } 803 swap = fl->f_next; 804 generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic"); 805 if (fl->f_rootdev == NODEV && !generic) { 806 yyerror("no root device specified"); 807 exit(1); 808 } 809 /* 810 * Default swap area to be in 'b' partition of root's 811 * device. If root specified to be other than on 'a' 812 * partition, give warning, something probably amiss. 813 */ 814 if (swap == 0 || swap->f_type != SWAPSPEC) { 815 dev_t dev; 816 817 swap = newswap(); 818 dev = fl->f_rootdev; 819 if (minor(dev) & 07) { 820 (void) sprintf(buf, 821 "Warning, swap defaulted to 'b' partition with root on '%c' partition", 822 (minor(dev) & 07) + 'a'); 823 yyerror(buf); 824 } 825 swap->f_swapdev = 826 makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a')); 827 swap->f_fn = devtoname(swap->f_swapdev); 828 mkswap(fl, swap, 0); 829 } 830 /* 831 * Make sure a generic swap isn't specified, along with 832 * other stuff (user must really be confused). 833 */ 834 if (generic) { 835 if (fl->f_rootdev != NODEV) 836 yyerror("root device specified with generic swap"); 837 if (fl->f_argdev != NODEV) 838 yyerror("arg device specified with generic swap"); 839 if (fl->f_dumpdev != NODEV) 840 yyerror("dump device specified with generic swap"); 841 return; 842 } 843 /* 844 * Default argument device and check for oddball arrangements. 845 */ 846 if (fl->f_argdev == NODEV) 847 fl->f_argdev = swap->f_swapdev; 848 if (fl->f_argdev != swap->f_swapdev) 849 yyerror("Warning, arg device different than primary swap"); 850 /* 851 * Default dump device and warn if place is not a 852 * swap area or the argument device partition. 853 */ 854 if (fl->f_dumpdev == NODEV) 855 fl->f_dumpdev = swap->f_swapdev; 856 if (fl->f_dumpdev != swap->f_swapdev && fl->f_dumpdev != fl->f_argdev) { 857 struct file_list *p = swap->f_next; 858 859 for (; p && p->f_type == SWAPSPEC; p = p->f_next) 860 if (fl->f_dumpdev == p->f_swapdev) 861 return; 862 (void) sprintf(buf, "Warning, orphaned dump device, %s", 863 "do you know what you're doing"); 864 yyerror(buf); 865 } 866 } 867 868 /* 869 * Verify all devices specified in the system specification 870 * are present in the device specifications. 871 */ 872 verifysystemspecs() 873 { 874 register struct file_list *fl; 875 dev_t checked[50], *verifyswap(); 876 register dev_t *pchecked = checked; 877 878 for (fl = conf_list; fl; fl = fl->f_next) { 879 if (fl->f_type != SYSTEMSPEC) 880 continue; 881 if (!finddev(fl->f_rootdev)) 882 deverror(fl->f_needs, "root"); 883 *pchecked++ = fl->f_rootdev; 884 pchecked = verifyswap(fl->f_next, checked, pchecked); 885 #define samedev(dev1, dev2) \ 886 ((minor(dev1) &~ 07) != (minor(dev2) &~ 07)) 887 if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) { 888 if (!finddev(fl->f_dumpdev)) 889 deverror(fl->f_needs, "dump"); 890 *pchecked++ = fl->f_dumpdev; 891 } 892 if (!alreadychecked(fl->f_argdev, checked, pchecked)) { 893 if (!finddev(fl->f_argdev)) 894 deverror(fl->f_needs, "arg"); 895 *pchecked++ = fl->f_argdev; 896 } 897 } 898 } 899 900 /* 901 * Do as above, but for swap devices. 902 */ 903 dev_t * 904 verifyswap(fl, checked, pchecked) 905 register struct file_list *fl; 906 dev_t checked[]; 907 register dev_t *pchecked; 908 { 909 910 for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) { 911 if (eq(fl->f_fn, "generic")) 912 continue; 913 if (alreadychecked(fl->f_swapdev, checked, pchecked)) 914 continue; 915 if (!finddev(fl->f_swapdev)) 916 fprintf(stderr, 917 "config: swap device %s not configured", fl->f_fn); 918 *pchecked++ = fl->f_swapdev; 919 } 920 return (pchecked); 921 } 922 923 /* 924 * Has a device already been checked 925 * for it's existence in the configuration? 926 */ 927 alreadychecked(dev, list, last) 928 dev_t dev, list[]; 929 register dev_t *last; 930 { 931 register dev_t *p; 932 933 for (p = list; p < last; p++) 934 if (samedev(*p, dev)) 935 return (1); 936 return (0); 937 } 938 939 deverror(systemname, devtype) 940 char *systemname, *devtype; 941 { 942 943 fprintf(stderr, "config: %s: %s device not configured\n", 944 systemname, devtype); 945 } 946 947 /* 948 * Look for the device in the list of 949 * configured hardware devices. Must 950 * take into account stuff wildcarded. 951 */ 952 /*ARGSUSED*/ 953 finddev(dev) 954 dev_t dev; 955 { 956 957 /* punt on this right now */ 958 return (1); 959 } 960