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