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 COMMA 13 %token CONFIG 14 %token CONTROLLER 15 %token CPU 16 %token CSR 17 %token DEVICE 18 %token DISK 19 %token DRIVE 20 %token DST 21 %token DUMPS 22 %token EQUALS 23 %token FLAGS 24 %token HZ 25 %token IDENT 26 %token MACHINE 27 %token MAJOR 28 %token MASTER 29 %token MAXUSERS 30 %token MINOR 31 %token MINUS 32 %token NEXUS 33 %token ON 34 %token OPTIONS 35 %token MAKEOPTIONS 36 %token PRIORITY 37 %token PSEUDO_DEVICE 38 %token ROOT 39 %token SEMICOLON 40 %token SIZE 41 %token SLAVE 42 %token SWAP 43 %token TIMEZONE 44 %token TRACE 45 %token VECTOR 46 47 %token <str> ID 48 %token <val> NUMBER 49 %token <val> FPNUMBER 50 51 %type <str> Save_id 52 %type <str> Opt_value 53 %type <str> Dev 54 %type <lst> Id_list 55 %type <val> optional_size 56 %type <str> device_name 57 %type <val> major_minor 58 %type <val> arg_device_spec 59 %type <val> root_device_spec 60 %type <val> dump_device_spec 61 %type <file> swap_device_spec 62 63 %{ 64 65 /* 66 * Copyright (c) 1988 Regents of the University of California. 67 * All rights reserved. 68 * 69 * Redistribution and use in source and binary forms are permitted 70 * provided that the above copyright notice and this paragraph are 71 * duplicated in all such forms and that any documentation, 72 * advertising materials, and other materials related to such 73 * distribution and use acknowledge that the software was developed 74 * by the University of California, Berkeley. The name of the 75 * University may not be used to endorse or promote products derived 76 * from this software without specific prior written permission. 77 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 78 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 79 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 80 * 81 * @(#)config.y 5.9 (Berkeley) 05/16/90 82 */ 83 84 #include "config.h" 85 #include <ctype.h> 86 #include <stdio.h> 87 88 struct device cur; 89 struct device *curp = 0; 90 char *temp_id; 91 char *val_id; 92 char *malloc(); 93 94 %} 95 %% 96 Configuration: 97 Many_specs 98 = { verifysystemspecs(); } 99 ; 100 101 Many_specs: 102 Many_specs Spec 103 | 104 /* lambda */ 105 ; 106 107 Spec: 108 Device_spec SEMICOLON 109 = { newdev(&cur); } | 110 Config_spec SEMICOLON 111 | 112 TRACE SEMICOLON 113 = { do_trace = !do_trace; } | 114 SEMICOLON 115 | 116 error SEMICOLON 117 ; 118 119 Config_spec: 120 MACHINE Save_id 121 = { 122 if (!strcmp($2, "vax")) { 123 machine = MACHINE_VAX; 124 machinename = "vax"; 125 } else if (!strcmp($2, "tahoe")) { 126 machine = MACHINE_TAHOE; 127 machinename = "tahoe"; 128 } else if (!strcmp($2, "hp300")) { 129 machine = MACHINE_HP300; 130 machinename = "hp300"; 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 = { timezone = 60 * $2; check_tz(); } | 155 TIMEZONE NUMBER DST NUMBER 156 = { timezone = 60 * $2; dst = $4; check_tz(); } | 157 TIMEZONE NUMBER DST 158 = { timezone = 60 * $2; dst = 1; check_tz(); } | 159 TIMEZONE FPNUMBER 160 = { timezone = $2; check_tz(); } | 161 TIMEZONE FPNUMBER DST NUMBER 162 = { timezone = $2; dst = $4; check_tz(); } | 163 TIMEZONE FPNUMBER DST 164 = { timezone = $2; dst = 1; check_tz(); } | 165 TIMEZONE MINUS NUMBER 166 = { timezone = -60 * $3; check_tz(); } | 167 TIMEZONE MINUS NUMBER DST NUMBER 168 = { timezone = -60 * $3; dst = $5; check_tz(); } | 169 TIMEZONE MINUS NUMBER DST 170 = { timezone = -60 * $3; dst = 1; check_tz(); } | 171 TIMEZONE MINUS FPNUMBER 172 = { timezone = -$3; check_tz(); } | 173 TIMEZONE MINUS FPNUMBER DST NUMBER 174 = { timezone = -$3; dst = $5; check_tz(); } | 175 TIMEZONE MINUS FPNUMBER DST 176 = { timezone = -$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 cur.d_unit = $3; 428 }; 429 430 Init_dev: 431 /* lambda */ 432 = { init_dev(&cur); }; 433 434 Dev_info: 435 Con_info Info_list 436 | 437 /* lambda */ 438 ; 439 440 Con_info: 441 AT Dev NUMBER 442 = { 443 if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) { 444 (void) sprintf(errbuf, 445 "%s must be connected to a nexus", cur.d_name); 446 yyerror(errbuf); 447 } 448 cur.d_conn = connect($2, $3); 449 } | 450 AT NEXUS NUMBER 451 = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; }; 452 453 Info_list: 454 Info_list Info 455 | 456 /* lambda */ 457 ; 458 459 Info: 460 CSR NUMBER 461 = { cur.d_addr = $2; } | 462 DRIVE NUMBER 463 = { cur.d_drive = $2; } | 464 SLAVE NUMBER 465 = { 466 if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS && 467 cur.d_conn->d_type == MASTER) 468 cur.d_slave = $2; 469 else 470 yyerror("can't specify slave--not to master"); 471 } | 472 FLAGS NUMBER 473 = { cur.d_flags = $2; }; 474 475 Int_spec: 476 VECTOR Id_list 477 = { cur.d_vec = $2; } | 478 PRIORITY NUMBER 479 = { cur.d_pri = $2; } | 480 /* lambda */ 481 ; 482 483 Id_list: 484 Save_id 485 = { 486 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); 487 a->id = $1; a->id_next = 0; $$ = a; 488 } | 489 Save_id Id_list = 490 { 491 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); 492 a->id = $1; a->id_next = $2; $$ = a; 493 }; 494 495 %% 496 497 yyerror(s) 498 char *s; 499 { 500 501 fprintf(stderr, "config: line %d: %s\n", yyline + 1, s); 502 } 503 504 /* 505 * return the passed string in a new space 506 */ 507 char * 508 ns(str) 509 register char *str; 510 { 511 register char *cp; 512 513 cp = malloc((unsigned)(strlen(str)+1)); 514 (void) strcpy(cp, str); 515 return (cp); 516 } 517 518 /* 519 * add a device to the list of devices 520 */ 521 newdev(dp) 522 register struct device *dp; 523 { 524 register struct device *np; 525 526 np = (struct device *) malloc(sizeof *np); 527 *np = *dp; 528 np->d_next = 0; 529 if (curp == 0) 530 dtab = np; 531 else 532 curp->d_next = np; 533 curp = np; 534 } 535 536 /* 537 * note that a configuration should be made 538 */ 539 mkconf(sysname) 540 char *sysname; 541 { 542 register struct file_list *fl, **flp; 543 544 fl = (struct file_list *) malloc(sizeof *fl); 545 fl->f_type = SYSTEMSPEC; 546 fl->f_needs = sysname; 547 fl->f_rootdev = NODEV; 548 fl->f_argdev = NODEV; 549 fl->f_dumpdev = NODEV; 550 fl->f_fn = 0; 551 fl->f_next = 0; 552 for (flp = confp; *flp; flp = &(*flp)->f_next) 553 ; 554 *flp = fl; 555 confp = flp; 556 } 557 558 struct file_list * 559 newswap() 560 { 561 struct file_list *fl = (struct file_list *)malloc(sizeof (*fl)); 562 563 fl->f_type = SWAPSPEC; 564 fl->f_next = 0; 565 fl->f_swapdev = NODEV; 566 fl->f_swapsize = 0; 567 fl->f_needs = 0; 568 fl->f_fn = 0; 569 return (fl); 570 } 571 572 /* 573 * Add a swap device to the system's configuration 574 */ 575 mkswap(system, fl, size) 576 struct file_list *system, *fl; 577 int size; 578 { 579 register struct file_list **flp; 580 char name[80]; 581 582 if (system == 0 || system->f_type != SYSTEMSPEC) { 583 yyerror("\"swap\" spec precedes \"config\" specification"); 584 return; 585 } 586 if (size < 0) { 587 yyerror("illegal swap partition size"); 588 return; 589 } 590 /* 591 * Append swap description to the end of the list. 592 */ 593 flp = &system->f_next; 594 for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next) 595 ; 596 fl->f_next = *flp; 597 *flp = fl; 598 fl->f_swapsize = size; 599 /* 600 * If first swap device for this system, 601 * set up f_fn field to insure swap 602 * files are created with unique names. 603 */ 604 if (system->f_fn) 605 return; 606 if (eq(fl->f_fn, "generic")) 607 system->f_fn = ns(fl->f_fn); 608 else 609 system->f_fn = ns(system->f_needs); 610 } 611 612 /* 613 * find the pointer to connect to the given device and number. 614 * returns 0 if no such device and prints an error message 615 */ 616 struct device * 617 connect(dev, num) 618 register char *dev; 619 register int num; 620 { 621 register struct device *dp; 622 struct device *huhcon(); 623 624 if (num == QUES) 625 return (huhcon(dev)); 626 for (dp = dtab; dp != 0; dp = dp->d_next) { 627 if ((num != dp->d_unit) || !eq(dev, dp->d_name)) 628 continue; 629 if (dp->d_type != CONTROLLER && dp->d_type != MASTER) { 630 (void) sprintf(errbuf, 631 "%s connected to non-controller", dev); 632 yyerror(errbuf); 633 return (0); 634 } 635 return (dp); 636 } 637 (void) sprintf(errbuf, "%s %d not defined", dev, num); 638 yyerror(errbuf); 639 return (0); 640 } 641 642 /* 643 * connect to an unspecific thing 644 */ 645 struct device * 646 huhcon(dev) 647 register char *dev; 648 { 649 register struct device *dp, *dcp; 650 struct device rdev; 651 int oldtype; 652 653 /* 654 * First make certain that there are some of these to wildcard on 655 */ 656 for (dp = dtab; dp != 0; dp = dp->d_next) 657 if (eq(dp->d_name, dev)) 658 break; 659 if (dp == 0) { 660 (void) sprintf(errbuf, "no %s's to wildcard", dev); 661 yyerror(errbuf); 662 return (0); 663 } 664 oldtype = dp->d_type; 665 dcp = dp->d_conn; 666 /* 667 * Now see if there is already a wildcard entry for this device 668 * (e.g. Search for a "uba ?") 669 */ 670 for (; dp != 0; dp = dp->d_next) 671 if (eq(dev, dp->d_name) && dp->d_unit == -1) 672 break; 673 /* 674 * If there isn't, make one because everything needs to be connected 675 * to something. 676 */ 677 if (dp == 0) { 678 dp = &rdev; 679 init_dev(dp); 680 dp->d_unit = QUES; 681 dp->d_name = ns(dev); 682 dp->d_type = oldtype; 683 newdev(dp); 684 dp = curp; 685 /* 686 * Connect it to the same thing that other similar things are 687 * connected to, but make sure it is a wildcard unit 688 * (e.g. up connected to sc ?, here we make connect sc? to a 689 * uba?). If other things like this are on the NEXUS or 690 * if they aren't connected to anything, then make the same 691 * connection, else call ourself to connect to another 692 * unspecific device. 693 */ 694 if (dcp == TO_NEXUS || dcp == 0) 695 dp->d_conn = dcp; 696 else 697 dp->d_conn = connect(dcp->d_name, QUES); 698 } 699 return (dp); 700 } 701 702 init_dev(dp) 703 register struct device *dp; 704 { 705 706 dp->d_name = "OHNO!!!"; 707 dp->d_type = DEVICE; 708 dp->d_conn = 0; 709 dp->d_vec = 0; 710 dp->d_addr = dp->d_pri = dp->d_flags = dp->d_dk = 0; 711 dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN; 712 } 713 714 /* 715 * make certain that this is a reasonable type of thing to connect to a nexus 716 */ 717 check_nexus(dev, num) 718 register struct device *dev; 719 int num; 720 { 721 722 switch (machine) { 723 724 case MACHINE_VAX: 725 if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") && 726 !eq(dev->d_name, "bi")) 727 yyerror("only uba's, mba's, and bi's should be connected to the nexus"); 728 if (num != QUES) 729 yyerror("can't give specific nexus numbers"); 730 break; 731 732 case MACHINE_TAHOE: 733 if (!eq(dev->d_name, "vba")) 734 yyerror("only vba's should be connected to the nexus"); 735 break; 736 737 case MACHINE_HP300: 738 if (num != QUES) 739 dev->d_addr = num; 740 break; 741 } 742 } 743 744 /* 745 * Check the timezone to make certain it is sensible 746 */ 747 748 check_tz() 749 { 750 if (abs(timezone) > 12 * 60) 751 yyerror("timezone is unreasonable"); 752 else 753 hadtz = 1; 754 } 755 756 /* 757 * Check system specification and apply defaulting 758 * rules on root, argument, dump, and swap devices. 759 */ 760 checksystemspec(fl) 761 register struct file_list *fl; 762 { 763 char buf[BUFSIZ]; 764 register struct file_list *swap; 765 int generic; 766 767 if (fl == 0 || fl->f_type != SYSTEMSPEC) { 768 yyerror("internal error, bad system specification"); 769 exit(1); 770 } 771 swap = fl->f_next; 772 generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic"); 773 if (fl->f_rootdev == NODEV && !generic) { 774 yyerror("no root device specified"); 775 exit(1); 776 } 777 /* 778 * Default swap area to be in 'b' partition of root's 779 * device. If root specified to be other than on 'a' 780 * partition, give warning, something probably amiss. 781 */ 782 if (swap == 0 || swap->f_type != SWAPSPEC) { 783 dev_t dev; 784 785 swap = newswap(); 786 dev = fl->f_rootdev; 787 if (minor(dev) & 07) { 788 (void) sprintf(buf, 789 "Warning, swap defaulted to 'b' partition with root on '%c' partition", 790 (minor(dev) & 07) + 'a'); 791 yyerror(buf); 792 } 793 swap->f_swapdev = 794 makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a')); 795 swap->f_fn = devtoname(swap->f_swapdev); 796 mkswap(fl, swap, 0); 797 } 798 /* 799 * Make sure a generic swap isn't specified, along with 800 * other stuff (user must really be confused). 801 */ 802 if (generic) { 803 if (fl->f_rootdev != NODEV) 804 yyerror("root device specified with generic swap"); 805 if (fl->f_argdev != NODEV) 806 yyerror("arg device specified with generic swap"); 807 if (fl->f_dumpdev != NODEV) 808 yyerror("dump device specified with generic swap"); 809 return; 810 } 811 /* 812 * Default argument device and check for oddball arrangements. 813 */ 814 if (fl->f_argdev == NODEV) 815 fl->f_argdev = swap->f_swapdev; 816 if (fl->f_argdev != swap->f_swapdev) 817 yyerror("Warning, arg device different than primary swap"); 818 /* 819 * Default dump device and warn if place is not a 820 * swap area or the argument device partition. 821 */ 822 if (fl->f_dumpdev == NODEV) 823 fl->f_dumpdev = swap->f_swapdev; 824 if (fl->f_dumpdev != swap->f_swapdev && fl->f_dumpdev != fl->f_argdev) { 825 struct file_list *p = swap->f_next; 826 827 for (; p && p->f_type == SWAPSPEC; p = p->f_next) 828 if (fl->f_dumpdev == p->f_swapdev) 829 return; 830 (void) sprintf(buf, "Warning, orphaned dump device, %s", 831 "do you know what you're doing"); 832 yyerror(buf); 833 } 834 } 835 836 /* 837 * Verify all devices specified in the system specification 838 * are present in the device specifications. 839 */ 840 verifysystemspecs() 841 { 842 register struct file_list *fl; 843 dev_t checked[50], *verifyswap(); 844 register dev_t *pchecked = checked; 845 846 for (fl = conf_list; fl; fl = fl->f_next) { 847 if (fl->f_type != SYSTEMSPEC) 848 continue; 849 if (!finddev(fl->f_rootdev)) 850 deverror(fl->f_needs, "root"); 851 *pchecked++ = fl->f_rootdev; 852 pchecked = verifyswap(fl->f_next, checked, pchecked); 853 #define samedev(dev1, dev2) \ 854 ((minor(dev1) &~ 07) != (minor(dev2) &~ 07)) 855 if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) { 856 if (!finddev(fl->f_dumpdev)) 857 deverror(fl->f_needs, "dump"); 858 *pchecked++ = fl->f_dumpdev; 859 } 860 if (!alreadychecked(fl->f_argdev, checked, pchecked)) { 861 if (!finddev(fl->f_argdev)) 862 deverror(fl->f_needs, "arg"); 863 *pchecked++ = fl->f_argdev; 864 } 865 } 866 } 867 868 /* 869 * Do as above, but for swap devices. 870 */ 871 dev_t * 872 verifyswap(fl, checked, pchecked) 873 register struct file_list *fl; 874 dev_t checked[]; 875 register dev_t *pchecked; 876 { 877 878 for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) { 879 if (eq(fl->f_fn, "generic")) 880 continue; 881 if (alreadychecked(fl->f_swapdev, checked, pchecked)) 882 continue; 883 if (!finddev(fl->f_swapdev)) 884 fprintf(stderr, 885 "config: swap device %s not configured", fl->f_fn); 886 *pchecked++ = fl->f_swapdev; 887 } 888 return (pchecked); 889 } 890 891 /* 892 * Has a device already been checked 893 * for it's existence in the configuration? 894 */ 895 alreadychecked(dev, list, last) 896 dev_t dev, list[]; 897 register dev_t *last; 898 { 899 register dev_t *p; 900 901 for (p = list; p < last; p++) 902 if (samedev(*p, dev)) 903 return (1); 904 return (0); 905 } 906 907 deverror(systemname, devtype) 908 char *systemname, *devtype; 909 { 910 911 fprintf(stderr, "config: %s: %s device not configured\n", 912 systemname, devtype); 913 } 914 915 /* 916 * Look for the device in the list of 917 * configured hardware devices. Must 918 * take into account stuff wildcarded. 919 */ 920 /*ARGSUSED*/ 921 finddev(dev) 922 dev_t dev; 923 { 924 925 /* punt on this right now */ 926 return (1); 927 } 928