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