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