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