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 116struct device cur; 117struct device *curp = 0; 118char *temp_id; 119char *val_id; 120 121%} 122%% 123Configuration: 124 Many_specs 125 = { verifysystemspecs(); } 126 ; 127 128Many_specs: 129 Many_specs Spec 130 | 131 /* lambda */ 132 ; 133 134Spec: 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 146Config_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
| 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 116struct device cur; 117struct device *curp = 0; 118char *temp_id; 119char *val_id; 120 121%} 122%% 123Configuration: 124 Many_specs 125 = { verifysystemspecs(); } 126 ; 127 128Many_specs: 129 Many_specs Spec 130 | 131 /* lambda */ 132 ; 133 134Spec: 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 146Config_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
|
244swap_spec: 245 SWAP optional_on swap_device_list 246 ; 247 248swap_device_list: 249 swap_device_list AND swap_device 250 | swap_device 251 ; 252 253swap_device: 254 swap_device_spec optional_size optional_sflag 255 = { mkswap(*confp, $1, $2, $3); } 256 ; 257 258swap_device_spec: 259 device_name 260 = { 261 struct file_list *fl = newflist(SWAPSPEC); 262 263 if (eq($1, "generic")) 264 fl->f_fn = $1; 265 else { 266 fl->f_swapdev = nametodev($1, 0, 'b'); 267 fl->f_fn = devtoname(fl->f_swapdev); 268 } 269 $$ = fl; 270 } 271 | major_minor 272 = { 273 struct file_list *fl = newflist(SWAPSPEC); 274 275 fl->f_swapdev = $1; 276 fl->f_fn = devtoname($1); 277 $$ = fl; 278 } 279 ; 280 281root_spec: 282 ROOT optional_on root_device_spec 283 = { 284 struct file_list *fl = *confp; 285 286 if (fl && fl->f_rootdev != NODEV) 287 yyerror("extraneous root device specification"); 288 else 289 fl->f_rootdev = $3; 290 } 291 ; 292 293root_device_spec: 294 device_name 295 = { $$ = nametodev($1, 0, '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, '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, '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) sprintf(buf, "%s%d", $1, $2); 361 $$ = ns(buf); free($1); 362 } 363 | Save_id NUMBER ID 364 = { 365 char buf[80]; 366 367 (void) sprintf(buf, "%s%d%s", $1, $2, $3); 368 $$ = ns(buf); free($1); 369 } 370 ; 371 372Opt_list: 373 Opt_list COMMA Option 374 | 375 Option 376 ; 377 378Option: 379 Save_id 380 = { 381 struct opt *op = (struct opt *)malloc(sizeof (struct opt)); 382 op->op_name = ns($1); 383 op->op_next = opt; 384 op->op_value = 0; 385 opt = op; 386 free(temp_id); 387 } | 388 Save_id EQUALS Opt_value 389 = { 390 struct opt *op = (struct opt *)malloc(sizeof (struct opt)); 391 op->op_name = ns($1); 392 op->op_next = opt; 393 op->op_value = ns($3); 394 opt = op; 395 free(temp_id); 396 free(val_id); 397 } ; 398 399Opt_value: 400 ID 401 = { $$ = val_id = ns($1); } | 402 NUMBER 403 = { 404 char nb[16]; 405 (void) sprintf(nb, "%d", $1); 406 $$ = val_id = ns(nb); 407 } ; 408 409 410Save_id: 411 ID 412 = { $$ = temp_id = ns($1); } 413 ; 414 415Mkopt_list: 416 Mkopt_list COMMA Mkoption 417 | 418 Mkoption 419 ; 420 421Mkoption: 422 Save_id EQUALS Opt_value 423 = { 424 struct opt *op = (struct opt *)malloc(sizeof (struct opt)); 425 op->op_name = ns($1); 426 op->op_next = mkopt; 427 op->op_value = ns($3); 428 mkopt = op; 429 free(temp_id); 430 free(val_id); 431 } ; 432 433Dev: 434 ID 435 = { $$ = ns($1); } 436 ; 437 438Device_spec: 439 DEVICE Dev_name Dev_info Int_spec 440 = { cur.d_type = DEVICE; } | 441 MASTER Dev_name Dev_info Int_spec 442 = { cur.d_type = MASTER; } | 443 DISK Dev_name Dev_info Int_spec 444 = { cur.d_dk = 1; cur.d_type = DEVICE; } | 445 CONTROLLER Dev_name Dev_info Int_spec 446 = { cur.d_type = CONTROLLER; } | 447 PSEUDO_DEVICE Init_dev Dev 448 = { 449 cur.d_name = $3; 450 cur.d_type = PSEUDO_DEVICE; 451 } | 452 PSEUDO_DEVICE Init_dev Dev NUMBER 453 = { 454 cur.d_name = $3; 455 cur.d_type = PSEUDO_DEVICE; 456 cur.d_slave = $4; 457 } | 458 PSEUDO_DEVICE Dev_name Cdev_init Cdev_info 459 = { 460 if (!eq(cur.d_name, "cd")) 461 yyerror("improper spec for pseudo-device"); 462 seen_cd = 1; 463 cur.d_type = DEVICE; 464 verifycomp(*compp); 465 }; 466 467Cdev_init: 468 /* lambda */ 469 = { mkcomp(&cur); }; 470 471Cdev_info: 472 optional_on comp_device_list comp_option_list 473 ; 474 475comp_device_list: 476 comp_device_list AND comp_device 477 | comp_device 478 ; 479 480comp_device: 481 comp_device_spec 482 = { addcomp(*compp, $1); } 483 ; 484 485comp_device_spec: 486 device_name 487 = { 488 struct file_list *fl = newflist(COMPSPEC); 489 490 fl->f_compdev = nametodev($1, 0, 'c'); 491 fl->f_fn = devtoname(fl->f_compdev); 492 $$ = fl; 493 } 494 | major_minor 495 = { 496 struct file_list *fl = newflist(COMPSPEC); 497 498 fl->f_compdev = $1; 499 fl->f_fn = devtoname($1); 500 $$ = fl; 501 } 502 ; 503 504comp_option_list: 505 comp_option_list comp_option 506 | 507 /* lambda */ 508 ; 509 510comp_option: 511 INTERLEAVE NUMBER 512 = { cur.d_pri = $2; } | 513 FLAGS NUMBER 514 = { cur.d_flags = $2; }; 515 516Dev_name: 517 Init_dev Dev NUMBER 518 = { 519 cur.d_name = $2; 520 if (eq($2, "mba")) 521 seen_mba = 1; 522 else if (eq($2, "uba")) 523 seen_uba = 1; 524 else if (eq($2, "vba")) 525 seen_vba = 1; 526 else if (eq($2, "isa")) 527 seen_isa = 1; 528 cur.d_unit = $3; 529 }; 530 531Init_dev: 532 /* lambda */ 533 = { init_dev(&cur); }; 534 535Dev_info: 536 Con_info Info_list 537 | 538 /* lambda */ 539 ; 540 541Con_info: 542 AT Dev NUMBER 543 = { 544 if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) { 545 (void) sprintf(errbuf, 546 "%s must be connected to a nexus", cur.d_name); 547 yyerror(errbuf); 548 } 549 cur.d_conn = connect($2, $3); 550 } | 551 AT NEXUS NUMBER 552 = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; }; 553 554Info_list: 555 Info_list Info 556 | 557 /* lambda */ 558 ; 559 560Info: 561 CSR NUMBER 562 = { cur.d_addr = $2; } | 563 DRIVE NUMBER 564 = { cur.d_drive = $2; } | 565 SLAVE NUMBER 566 = { 567 if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS && 568 cur.d_conn->d_type == MASTER) 569 cur.d_slave = $2; 570 else 571 yyerror("can't specify slave--not to master"); 572 } | 573 IRQ NUMBER 574 = { cur.d_irq = $2; } | 575 DRQ NUMBER 576 = { cur.d_drq = $2; } | 577 IOMEM NUMBER 578 = { cur.d_maddr = $2; } | 579 IOSIZ NUMBER 580 = { cur.d_msize = $2; } | 581 PORT device_name 582 = { cur.d_port = ns($2); } | 583 PORT NUMBER 584 = { cur.d_portn = $2; } | 585 TTY 586 = { cur.d_mask = "tty"; } | 587 BIO 588 = { cur.d_mask = "bio"; } | 589 NET 590 = { cur.d_mask = "net"; } | 591 FLAGS NUMBER 592 = { cur.d_flags = $2; }; 593 594Int_spec: 595 VECTOR Id_list 596 = { cur.d_vec = $2; } | 597 PRIORITY NUMBER 598 = { cur.d_pri = $2; } | 599 /* lambda */ 600 ; 601 602Id_list: 603 Save_id 604 = { 605 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); 606 a->id = $1; a->id_next = 0; $$ = a; 607 } | 608 Save_id Id_list = 609 { 610 struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); 611 a->id = $1; a->id_next = $2; $$ = a; 612 }; 613 614%% 615 616yyerror(s) 617 char *s; 618{ 619 620 fprintf(stderr, "config: line %d: %s\n", yyline + 1, s); 621} 622 623/* 624 * return the passed string in a new space 625 */ 626char * 627ns(str) 628 register char *str; 629{ 630 register char *cp; 631 632 cp = malloc((unsigned)(strlen(str)+1)); 633 (void) strcpy(cp, str); 634 return (cp); 635} 636 637/* 638 * add a device to the list of devices 639 */ 640newdev(dp) 641 register struct device *dp; 642{ 643 register struct device *np; 644 645 np = (struct device *) malloc(sizeof *np); 646 *np = *dp; 647 np->d_next = 0; 648 if (curp == 0) 649 dtab = np; 650 else 651 curp->d_next = np; 652 curp = np; 653} 654 655/* 656 * note that a configuration should be made 657 */ 658mkconf(sysname) 659 char *sysname; 660{ 661 register struct file_list *fl, **flp; 662 663 fl = (struct file_list *) malloc(sizeof *fl); 664 fl->f_type = SYSTEMSPEC; 665 fl->f_needs = sysname; 666 fl->f_rootdev = NODEV; 667 fl->f_dumpdev = NODEV; 668 fl->f_fn = 0; 669 fl->f_next = 0; 670 for (flp = confp; *flp; flp = &(*flp)->f_next) 671 ; 672 *flp = fl; 673 confp = flp; 674} 675 676struct file_list * 677newflist(ftype) 678 u_char ftype; 679{ 680 struct file_list *fl = (struct file_list *)malloc(sizeof (*fl)); 681 682 fl->f_type = ftype; 683 fl->f_next = 0; 684 fl->f_swapdev = NODEV; 685 fl->f_swapsize = 0; 686 fl->f_needs = 0; 687 fl->f_fn = 0; 688 return (fl); 689} 690 691/* 692 * Add a swap device to the system's configuration 693 */ 694mkswap(system, fl, size, flag) 695 struct file_list *system, *fl; 696 int size, flag; 697{ 698 register struct file_list **flp; 699 char name[80]; 700 701 if (system == 0 || system->f_type != SYSTEMSPEC) { 702 yyerror("\"swap\" spec precedes \"config\" specification"); 703 return; 704 } 705 if (size < 0) { 706 yyerror("illegal swap partition size"); 707 return; 708 } 709 /* 710 * Append swap description to the end of the list. 711 */ 712 flp = &system->f_next; 713 for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next) 714 ; 715 fl->f_next = *flp; 716 *flp = fl; 717 fl->f_swapsize = size; 718 fl->f_swapflag = flag; 719 /* 720 * If first swap device for this system, 721 * set up f_fn field to insure swap 722 * files are created with unique names. 723 */ 724 if (system->f_fn) 725 return; 726 if (eq(fl->f_fn, "generic")) 727 system->f_fn = ns(fl->f_fn); 728 else 729 system->f_fn = ns(system->f_needs); 730} 731 732mkcomp(dp) 733 register struct device *dp; 734{ 735 register struct file_list *fl, **flp; 736 char buf[80]; 737 738 fl = (struct file_list *) malloc(sizeof *fl); 739 fl->f_type = COMPDEVICE; 740 fl->f_compinfo = dp->d_unit; 741 fl->f_fn = ns(dp->d_name); 742 (void) sprintf(buf, "%s%d", dp->d_name, dp->d_unit); 743 fl->f_needs = ns(buf); 744 fl->f_next = 0; 745 for (flp = compp; *flp; flp = &(*flp)->f_next) 746 ; 747 *flp = fl; 748 compp = flp; 749} 750 751addcomp(compdev, fl) 752 struct file_list *compdev, *fl; 753{ 754 register struct file_list **flp; 755 char name[80]; 756 757 if (compdev == 0 || compdev->f_type != COMPDEVICE) { 758 yyerror("component spec precedes device specification"); 759 return; 760 } 761 /* 762 * Append description to the end of the list. 763 */ 764 flp = &compdev->f_next; 765 for (; *flp && (*flp)->f_type == COMPSPEC; flp = &(*flp)->f_next) 766 ; 767 fl->f_next = *flp; 768 *flp = fl; 769} 770 771/* 772 * find the pointer to connect to the given device and number. 773 * returns 0 if no such device and prints an error message 774 */ 775struct device * 776connect(dev, num) 777 register char *dev; 778 register int num; 779{ 780 register struct device *dp; 781 struct device *huhcon(); 782 783 if (num == QUES) 784 return (huhcon(dev)); 785 for (dp = dtab; dp != 0; dp = dp->d_next) { 786 if ((num != dp->d_unit) || !eq(dev, dp->d_name)) 787 continue; 788 if (dp->d_type != CONTROLLER && dp->d_type != MASTER) { 789 (void) sprintf(errbuf, 790 "%s connected to non-controller", dev); 791 yyerror(errbuf); 792 return (0); 793 } 794 return (dp); 795 } 796 (void) sprintf(errbuf, "%s %d not defined", dev, num); 797 yyerror(errbuf); 798 return (0); 799} 800 801/* 802 * connect to an unspecific thing 803 */ 804struct device * 805huhcon(dev) 806 register char *dev; 807{ 808 register struct device *dp, *dcp; 809 struct device rdev; 810 int oldtype; 811 812 /* 813 * First make certain that there are some of these to wildcard on 814 */ 815 for (dp = dtab; dp != 0; dp = dp->d_next) 816 if (eq(dp->d_name, dev)) 817 break; 818 if (dp == 0) { 819 (void) sprintf(errbuf, "no %s's to wildcard", dev); 820 yyerror(errbuf); 821 return (0); 822 } 823 oldtype = dp->d_type; 824 dcp = dp->d_conn; 825 /* 826 * Now see if there is already a wildcard entry for this device 827 * (e.g. Search for a "uba ?") 828 */ 829 for (; dp != 0; dp = dp->d_next) 830 if (eq(dev, dp->d_name) && dp->d_unit == -1) 831 break; 832 /* 833 * If there isn't, make one because everything needs to be connected 834 * to something. 835 */ 836 if (dp == 0) { 837 dp = &rdev; 838 init_dev(dp); 839 dp->d_unit = QUES; 840 dp->d_name = ns(dev); 841 dp->d_type = oldtype; 842 newdev(dp); 843 dp = curp; 844 /* 845 * Connect it to the same thing that other similar things are 846 * connected to, but make sure it is a wildcard unit 847 * (e.g. up connected to sc ?, here we make connect sc? to a 848 * uba?). If other things like this are on the NEXUS or 849 * if they aren't connected to anything, then make the same 850 * connection, else call ourself to connect to another 851 * unspecific device. 852 */ 853 if (dcp == TO_NEXUS || dcp == 0) 854 dp->d_conn = dcp; 855 else 856 dp->d_conn = connect(dcp->d_name, QUES); 857 } 858 return (dp); 859} 860 861init_dev(dp) 862 register struct device *dp; 863{ 864 865 dp->d_name = "OHNO!!!"; 866 dp->d_type = DEVICE; 867 dp->d_conn = 0; 868 dp->d_vec = 0; 869 dp->d_addr = dp->d_flags = dp->d_dk = 0; 870 dp->d_pri = -1; 871 dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN; 872 dp->d_port = (char *)0; 873 dp->d_portn = 0; 874 dp->d_irq = -1; 875 dp->d_drq = -1; 876 dp->d_maddr = 0; 877 dp->d_msize = 0; 878 dp->d_mask = "null"; 879} 880 881/* 882 * make certain that this is a reasonable type of thing to connect to a nexus 883 */ 884check_nexus(dev, num) 885 register struct device *dev; 886 int num; 887{ 888 889 switch (machine) { 890 891 case MACHINE_VAX: 892 if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") && 893 !eq(dev->d_name, "bi")) 894 yyerror("only uba's, mba's, and bi's should be connected to the nexus"); 895 if (num != QUES) 896 yyerror("can't give specific nexus numbers"); 897 break; 898 899 case MACHINE_TAHOE: 900 if (!eq(dev->d_name, "vba")) 901 yyerror("only vba's should be connected to the nexus"); 902 break; 903 904 case MACHINE_HP300: 905 case MACHINE_LUNA68K: 906 if (num != QUES) 907 dev->d_addr = num; 908 break; 909 910 case MACHINE_I386: 911 if (!eq(dev->d_name, "isa")) 912 yyerror("only isa's should be connected to the nexus"); 913 break; 914 915 case MACHINE_NEWS3400: 916 if (!eq(dev->d_name, "iop") && !eq(dev->d_name, "hb") && 917 !eq(dev->d_name, "vme")) 918 yyerror("only iop's, hb's and vme's should be connected to the nexus"); 919 break; 920 } 921} 922 923/* 924 * Check the timezone to make certain it is sensible 925 */ 926 927check_tz() 928{ 929 if (abs(zone) > 12 * 60) 930 yyerror("timezone is unreasonable"); 931 else 932 hadtz = 1; 933} 934 935/* 936 * Check system specification and apply defaulting 937 * rules on root, argument, dump, and swap devices. 938 */ 939checksystemspec(fl) 940 register struct file_list *fl; 941{ 942 char buf[BUFSIZ]; 943 register struct file_list *swap; 944 int generic; 945 946 if (fl == 0 || fl->f_type != SYSTEMSPEC) { 947 yyerror("internal error, bad system specification"); 948 exit(1); 949 } 950 swap = fl->f_next; 951 generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic"); 952 if (fl->f_rootdev == NODEV && !generic) { 953 yyerror("no root device specified"); 954 exit(1); 955 } 956 /* 957 * Default swap area to be in 'b' partition of root's 958 * device. If root specified to be other than on 'a' 959 * partition, give warning, something probably amiss. 960 */ 961 if (swap == 0 || swap->f_type != SWAPSPEC) { 962 dev_t dev; 963 964 swap = newflist(SWAPSPEC); 965 dev = fl->f_rootdev; 966 if (minor(dev) & 07) { 967 (void) sprintf(buf, 968"Warning, swap defaulted to 'b' partition with root on '%c' partition", 969 (minor(dev) & 07) + 'a'); 970 yyerror(buf); 971 } 972 swap->f_swapdev = 973 makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a')); 974 swap->f_fn = devtoname(swap->f_swapdev); 975 mkswap(fl, swap, 0); 976 } 977 /* 978 * Make sure a generic swap isn't specified, along with 979 * other stuff (user must really be confused). 980 */ 981 if (generic) { 982 if (fl->f_rootdev != NODEV) 983 yyerror("root device specified with generic swap"); 984 if (fl->f_dumpdev != NODEV) 985 yyerror("dump device specified with generic swap"); 986 return; 987 } 988 /* 989 * Default dump device and warn if place is not a 990 * swap area. 991 */ 992 if (fl->f_dumpdev == NODEV) 993 fl->f_dumpdev = swap->f_swapdev; 994 if (fl->f_dumpdev != swap->f_swapdev) { 995 struct file_list *p = swap->f_next; 996 997 for (; p && p->f_type == SWAPSPEC; p = p->f_next) 998 if (fl->f_dumpdev == p->f_swapdev) 999 return; 1000 (void) sprintf(buf, 1001 "Warning: dump device is not a swap partition"); 1002 yyerror(buf); 1003 } 1004} 1005 1006/* 1007 * Verify all devices specified in the system specification 1008 * are present in the device specifications. 1009 */ 1010verifysystemspecs() 1011{ 1012 register struct file_list *fl; 1013 dev_t checked[50], *verifyswap(); 1014 register dev_t *pchecked = checked; 1015 1016 for (fl = conf_list; fl; fl = fl->f_next) { 1017 if (fl->f_type != SYSTEMSPEC) 1018 continue; 1019 if (!finddev(fl->f_rootdev)) 1020 deverror(fl->f_needs, "root"); 1021 *pchecked++ = fl->f_rootdev; 1022 pchecked = verifyswap(fl->f_next, checked, pchecked); 1023#define samedev(dev1, dev2) \ 1024 ((minor(dev1) &~ 07) != (minor(dev2) &~ 07)) 1025 if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) { 1026 if (!finddev(fl->f_dumpdev)) 1027 deverror(fl->f_needs, "dump"); 1028 *pchecked++ = fl->f_dumpdev; 1029 } 1030 } 1031} 1032 1033/* 1034 * Do as above, but for swap devices. 1035 */ 1036dev_t * 1037verifyswap(fl, checked, pchecked) 1038 register struct file_list *fl; 1039 dev_t checked[]; 1040 register dev_t *pchecked; 1041{ 1042 1043 for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) { 1044 if (eq(fl->f_fn, "generic")) 1045 continue; 1046 if (alreadychecked(fl->f_swapdev, checked, pchecked)) 1047 continue; 1048 if (!finddev(fl->f_swapdev)) 1049 fprintf(stderr, 1050 "config: swap device %s not configured", fl->f_fn); 1051 *pchecked++ = fl->f_swapdev; 1052 } 1053 return (pchecked); 1054} 1055 1056/* 1057 * Verify that components of a compound device have themselves been config'ed 1058 */ 1059verifycomp(fl) 1060 register struct file_list *fl; 1061{ 1062 char *dname = fl->f_needs; 1063 1064 for (fl = fl->f_next; fl; fl = fl->f_next) { 1065 if (fl->f_type != COMPSPEC || finddev(fl->f_compdev)) 1066 continue; 1067 fprintf(stderr, 1068 "config: %s: component device %s not configured\n", 1069 dname, fl->f_needs); 1070 } 1071} 1072 1073/* 1074 * Has a device already been checked 1075 * for it's existence in the configuration? 1076 */ 1077alreadychecked(dev, list, last) 1078 dev_t dev, list[]; 1079 register dev_t *last; 1080{ 1081 register dev_t *p; 1082 1083 for (p = list; p < last; p++) 1084 if (samedev(*p, dev)) 1085 return (1); 1086 return (0); 1087} 1088 1089deverror(systemname, devtype) 1090 char *systemname, *devtype; 1091{ 1092 1093 fprintf(stderr, "config: %s: %s device not configured\n", 1094 systemname, devtype); 1095} 1096 1097/* 1098 * Look for the device in the list of 1099 * configured hardware devices. Must 1100 * take into account stuff wildcarded. 1101 */ 1102/*ARGSUSED*/ 1103finddev(dev) 1104 dev_t dev; 1105{ 1106 1107 /* punt on this right now */ 1108 return (1); 1109}
| 250swap_spec: 251 SWAP optional_on swap_device_list 252 ; 253 254swap_device_list: 255 swap_device_list AND swap_device 256 | swap_device 257 ; 258 259swap_device: 260 swap_device_spec optional_size optional_sflag 261 = { mkswap(*confp, $1, $2, $3); } 262 ; 263 264swap_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 287root_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 299root_device_spec: 300 device_name 301 = { $$ = nametodev($1, 0, 'a'); } 302 | major_minor 303 ; 304 305dump_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 318dump_device_spec: 319 device_name 320 = { $$ = nametodev($1, 0, 'b'); } 321 | major_minor 322 ; 323 324arg_spec: 325 ARGS optional_on arg_device_spec 326 = { yyerror("arg device specification obsolete, ignored"); } 327 ; 328 329arg_device_spec: 330 device_name 331 = { $$ = nametodev($1, 0, 'b'); } 332 | major_minor 333 ; 334 335major_minor: 336 MAJOR NUMBER MINOR NUMBER 337 = { $$ = makedev($2, $4); } 338 ; 339 340optional_on: 341 ON 342 | /* empty */ 343 ; 344 345optional_size: 346 SIZE NUMBER 347 = { $$ = $2; } 348 | /* empty */ 349 = { $$ = 0; } 350 ; 351 352optional_sflag: 353 SEQUENTIAL 354 = { $$ = 2; } 355 | /* empty */ 356 = { $$ = 0; } 357 ; 358 359device_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 378Opt_list: 379 Opt_list COMMA Option 380 | 381 Option 382 ; 383 384Option: 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 405Opt_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 416Save_id: 417 ID 418 = { $$ = temp_id = ns($1); } 419 ; 420 421Mkopt_list: 422 Mkopt_list COMMA Mkoption 423 | 424 Mkoption 425 ; 426 427Mkoption: 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 439Dev: 440 ID 441 = { $$ = ns($1); } 442 ; 443 444Device_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 473Cdev_init: 474 /* lambda */ 475 = { mkcomp(&cur); }; 476 477Cdev_info: 478 optional_on comp_device_list comp_option_list 479 ; 480 481comp_device_list: 482 comp_device_list AND comp_device 483 | comp_device 484 ; 485 486comp_device: 487 comp_device_spec 488 = { addcomp(*compp, $1); } 489 ; 490 491comp_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 510comp_option_list: 511 comp_option_list comp_option 512 | 513 /* lambda */ 514 ; 515 516comp_option: 517 INTERLEAVE NUMBER 518 = { cur.d_pri = $2; } | 519 FLAGS NUMBER 520 = { cur.d_flags = $2; }; 521 522Dev_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 537Init_dev: 538 /* lambda */ 539 = { init_dev(&cur); }; 540 541Dev_info: 542 Con_info Info_list 543 | 544 /* lambda */ 545 ; 546 547Con_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 560Info_list: 561 Info_list Info 562 | 563 /* lambda */ 564 ; 565 566Info: 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 600Int_spec: 601 VECTOR Id_list 602 = { cur.d_vec = $2; } | 603 PRIORITY NUMBER 604 = { cur.d_pri = $2; } | 605 /* lambda */ 606 ; 607 608Id_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 622yyerror(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 */ 632char * 633ns(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 */ 646newdev(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 */ 664mkconf(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 682struct file_list * 683newflist(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 */ 700mkswap(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 738mkcomp(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 757addcomp(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 */ 781struct device * 782connect(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 */ 810struct device * 811huhcon(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 867init_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 */ 890check_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 933check_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 */ 945checksystemspec(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 */ 1016verifysystemspecs() 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 */ 1042dev_t * 1043verifyswap(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 */ 1065verifycomp(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 */ 1083alreadychecked(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 1095deverror(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*/ 1109finddev(dev) 1110 dev_t dev; 1111{ 1112 1113 /* punt on this right now */ 1114 return (1); 1115}
|