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