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