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