1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: autoconf.c 1.25 89/10/07$ 13 * 14 * @(#)autoconf.c 7.4 (Berkeley) 12/16/90 15 */ 16 17 /* 18 * Setup the system to run on the current machine. 19 * 20 * Configure() is called at boot time. Available 21 * devices are determined (from possibilities mentioned in ioconf.c), 22 * and the drivers are initialized. 23 */ 24 25 #include "sys/param.h" 26 #include "sys/systm.h" 27 #include "sys/map.h" 28 #include "sys/buf.h" 29 #include "sys/dkstat.h" 30 #include "sys/conf.h" 31 #include "sys/dmap.h" 32 #include "sys/reboot.h" 33 34 #include "../include/cpu.h" 35 #include "isr.h" 36 #include "../dev/device.h" 37 #include "../dev/grfioctl.h" 38 #include "../dev/grfvar.h" 39 40 /* 41 * The following several variables are related to 42 * the configuration process, and are used in initializing 43 * the machine. 44 */ 45 int cold; /* if 1, still working on cold-start */ 46 int dkn; /* number of iostat dk numbers assigned so far */ 47 int cpuspeed = MHZ_8; /* relative cpu speed */ 48 struct isr isrqueue[NISR]; 49 struct hp_hw sc_table[MAX_CTLR]; 50 51 extern int internalhpib; 52 53 #ifdef DEBUG 54 int acdebug = 0; 55 #endif 56 57 /* 58 * Determine mass storage and memory configuration for a machine. 59 */ 60 configure() 61 { 62 register struct hp_hw *hw; 63 int found; 64 65 /* 66 * XXX: these should be consolidated into some kind of table 67 */ 68 hilinit(); 69 isrinit(); 70 dmainit(); 71 72 /* 73 * Look over each hardware device actually found and attempt 74 * to match it with an ioconf.c table entry. 75 */ 76 for (hw = sc_table; hw->hw_type; hw++) { 77 if (hw->hw_type & CONTROLLER) 78 found = find_controller(hw); 79 else 80 found = find_device(hw); 81 #ifdef DEBUG 82 if (!found) { 83 int sc = addrtosc((u_int)hw->hw_addr); 84 85 printf("unconfigured %s ", hw->hw_name); 86 if (sc < 256) 87 printf("at sc%d\n", sc); 88 else 89 printf("csr at %x\n", sc); 90 } 91 #endif 92 } 93 94 #include "cd.h" 95 #if NCD > 0 96 /* 97 * Now deal with concatenated disks 98 */ 99 find_cdevices(); 100 #endif 101 102 #if GENERIC 103 if ((boothowto & RB_ASKNAME) == 0) 104 setroot(); 105 setconf(); 106 #else 107 setroot(); 108 #endif 109 swapconf(); 110 cold = 0; 111 } 112 113 #define dr_type(d, s) \ 114 (strcmp((d)->d_name, (s)) == 0) 115 116 #define same_hw_ctlr(hw, hc) \ 117 ((hw)->hw_type == HPIB && dr_type((hc)->hp_driver, "hpib") || \ 118 (hw)->hw_type == SCSI && dr_type((hc)->hp_driver, "scsi")) 119 120 find_controller(hw) 121 register struct hp_hw *hw; 122 { 123 register struct hp_ctlr *hc; 124 struct hp_ctlr *match_c; 125 caddr_t oaddr; 126 int sc; 127 128 #ifdef DEBUG 129 if (acdebug) 130 printf("find_controller: hw: %s at sc%d (%x), type %x...", 131 hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type); 132 #endif 133 sc = hw->hw_sc; 134 match_c = NULL; 135 for (hc = hp_cinit; hc->hp_driver; hc++) { 136 if (hc->hp_alive) 137 continue; 138 /* 139 * Make sure we are looking at the right 140 * controller type. 141 */ 142 if (!same_hw_ctlr(hw, hc)) 143 continue; 144 /* 145 * Exact match; all done 146 */ 147 if ((int)hc->hp_addr == sc) { 148 match_c = hc; 149 break; 150 } 151 /* 152 * Wildcard; possible match so remember first instance 153 * but continue looking for exact match. 154 */ 155 if ((int)hc->hp_addr == WILD_CARD_CTLR && match_c == NULL) 156 match_c = hc; 157 } 158 #ifdef DEBUG 159 if (acdebug) { 160 if (match_c) 161 printf("found %s%d\n", 162 match_c->hp_driver->d_name, 163 match_c->hp_unit); 164 else 165 printf("not found\n"); 166 } 167 #endif 168 /* 169 * Didn't find an ioconf entry for this piece of hardware, 170 * just ignore it. 171 */ 172 if (match_c == NULL) 173 return(0); 174 /* 175 * Found a match, attempt to initialize and configure all attached 176 * slaves. Note, we can still fail if HW won't initialize. 177 */ 178 hc = match_c; 179 oaddr = hc->hp_addr; 180 hc->hp_addr = hw->hw_addr; 181 if ((*hc->hp_driver->d_init)(hc)) { 182 hc->hp_alive = 1; 183 printf("%s%d", hc->hp_driver->d_name, hc->hp_unit); 184 sc = addrtosc((u_int)hc->hp_addr); 185 if (sc < 256) 186 printf(" at sc%d,", sc); 187 else 188 printf(" csr 0x%x,", sc); 189 printf(" ipl %d", hc->hp_ipl); 190 if (hc->hp_flags) 191 printf(" flags 0x%x", hc->hp_flags); 192 printf("\n"); 193 find_slaves(hc); 194 } else 195 hc->hp_addr = oaddr; 196 return(1); 197 } 198 199 find_device(hw) 200 register struct hp_hw *hw; 201 { 202 register struct hp_device *hd; 203 struct hp_device *match_d; 204 caddr_t oaddr; 205 int sc; 206 207 #ifdef DEBUG 208 if (acdebug) 209 printf("find_device: hw: %s at sc%d (%x), type %x...", 210 hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type); 211 #endif 212 match_d = NULL; 213 for (hd = hp_dinit; hd->hp_driver; hd++) { 214 if (hd->hp_alive) 215 continue; 216 /* Must not be a slave */ 217 if (hd->hp_cdriver) 218 continue; 219 /* 220 * XXX: A graphics device that was found as part of the 221 * console init will have the hp_addr field already set 222 * (i.e. no longer the select code). Gotta perform a 223 * slightly different check for an exact match. 224 */ 225 if (hw->hw_type == BITMAP && hd->hp_addr >= (caddr_t)IOBASE) { 226 /* must be an exact match */ 227 if (hd->hp_addr == hw->hw_addr) { 228 match_d = hd; 229 break; 230 } 231 continue; 232 } 233 sc = (int) hd->hp_addr; 234 /* 235 * Exact match; all done. 236 */ 237 if (sc > 0 && sc == hw->hw_sc) { 238 match_d = hd; 239 break; 240 } 241 /* 242 * Wildcard; possible match so remember first instance 243 * but continue looking for exact match. 244 */ 245 if (sc == 0 && same_hw_device(hw, hd) && match_d == NULL) 246 match_d = hd; 247 } 248 #ifdef DEBUG 249 if (acdebug) { 250 if (match_d) 251 printf("found %s%d\n", 252 match_d->hp_driver->d_name, 253 match_d->hp_unit); 254 else 255 printf("not found\n"); 256 } 257 #endif 258 /* 259 * Didn't find an ioconf entry for this piece 260 * of hardware, just ignore it. 261 */ 262 if (match_d == NULL) 263 return(0); 264 /* 265 * Found a match, attempt to initialize. 266 * Note, we can still fail if HW won't initialize. 267 */ 268 hd = match_d; 269 oaddr = hd->hp_addr; 270 hd->hp_addr = hw->hw_addr; 271 if ((*hd->hp_driver->d_init)(hd)) { 272 hd->hp_alive = 1; 273 printf("%s%d", hd->hp_driver->d_name, hd->hp_unit); 274 sc = addrtosc((u_int)hd->hp_addr); 275 if (sc < 256) 276 printf(" at sc%d", sc); 277 else 278 printf(" csr 0x%x", sc); 279 if (hd->hp_ipl) 280 printf(", ipl %d", hd->hp_ipl); 281 if (hd->hp_flags) 282 printf(", flags 0x%x", hd->hp_flags); 283 printf("\n"); 284 } else 285 hd->hp_addr = oaddr; 286 return(1); 287 } 288 289 find_slaves(hc) 290 struct hp_ctlr *hc; 291 { 292 /* 293 * The SCSI bus is structured very much like the HP-IB 294 * except that the host adaptor is slave 7 so we only want 295 * to look at the first 6 slaves. 296 */ 297 if (dr_type(hc->hp_driver, "hpib")) 298 find_busslaves(hc, MAXSLAVES); 299 else if (dr_type(hc->hp_driver, "scsi")) 300 find_busslaves(hc, MAXSLAVES-1); 301 } 302 303 /* 304 * Search each BUS controller found for slaves attached to it. 305 * The bad news is that we don't know how to uniquely identify all slaves 306 * (e.g. PPI devices on HP-IB). The good news is that we can at least 307 * differentiate those from slaves we can identify. At worst (a totally 308 * wildcarded entry) this will cause us to locate such a slave at the first 309 * unused position instead of where it really is. To save grief, non- 310 * identifing devices should always be fully qualified. 311 */ 312 find_busslaves(hc, maxslaves) 313 register struct hp_ctlr *hc; 314 int maxslaves; 315 { 316 register int s; 317 register struct hp_device *hd; 318 struct hp_device *match_s; 319 int new_s, new_c, old_s, old_c; 320 int rescan; 321 322 #ifdef DEBUG 323 if (acdebug) 324 printf("find_busslaves: for %s%d\n", 325 hc->hp_driver->d_name, hc->hp_unit); 326 #endif 327 for (s = 0; s < maxslaves; s++) { 328 rescan = 1; 329 match_s = NULL; 330 for (hd = hp_dinit; hd->hp_driver; hd++) { 331 /* 332 * Rule out the easy ones: 333 * 1. slave already assigned or not a slave 334 * 2. not of the proper type 335 * 3. controller specified but not this one 336 * 4. slave specified but not this one 337 */ 338 if (hd->hp_alive || hd->hp_cdriver == NULL) 339 continue; 340 if (!dr_type(hc->hp_driver, hd->hp_cdriver->d_name)) 341 continue; 342 if (hd->hp_ctlr >= 0 && hd->hp_ctlr != hc->hp_unit) 343 continue; 344 if (hd->hp_slave >= 0 && hd->hp_slave != s) 345 continue; 346 /* 347 * Case 0: first possible match. 348 * Remember it and keep looking for better. 349 */ 350 if (match_s == NULL) { 351 match_s = hd; 352 new_c = hc->hp_unit; 353 new_s = s; 354 continue; 355 } 356 /* 357 * Case 1: exact match. 358 * All done. Note that we do not attempt any other 359 * matches if this one fails. This allows us to 360 * "reserve" locations for dynamic addition of 361 * disk/tape drives by fully qualifing the location. 362 */ 363 if (hd->hp_slave == s && hd->hp_ctlr == hc->hp_unit) { 364 match_s = hd; 365 rescan = 0; 366 break; 367 } 368 /* 369 * Case 2: right controller, wildcarded slave. 370 * Remember first and keep looking for an exact match. 371 */ 372 if (hd->hp_ctlr == hc->hp_unit && 373 match_s->hp_ctlr < 0) { 374 match_s = hd; 375 new_s = s; 376 continue; 377 } 378 /* 379 * Case 3: right slave, wildcarded controller. 380 * Remember and keep looking for a better match. 381 */ 382 if (hd->hp_slave == s && 383 match_s->hp_ctlr < 0 && match_s->hp_slave < 0) { 384 match_s = hd; 385 new_c = hc->hp_unit; 386 continue; 387 } 388 /* 389 * OW: we had a totally wildcarded spec. 390 * If we got this far, we have found a possible 391 * match already (match_s != NULL) so there is no 392 * reason to remember this one. 393 */ 394 continue; 395 } 396 /* 397 * Found a match. We need to set hp_ctlr/hp_slave properly 398 * for the init routines but we also need to remember all 399 * the old values in case this doesn't pan out. 400 */ 401 if (match_s) { 402 hd = match_s; 403 old_c = hd->hp_ctlr; 404 old_s = hd->hp_slave; 405 if (hd->hp_ctlr < 0) 406 hd->hp_ctlr = new_c; 407 if (hd->hp_slave < 0) 408 hd->hp_slave = new_s; 409 #ifdef DEBUG 410 if (acdebug) 411 printf("looking for %s%d at slave %d...", 412 hd->hp_driver->d_name, 413 hd->hp_unit, hd->hp_slave); 414 #endif 415 416 if ((*hd->hp_driver->d_init)(hd)) { 417 #ifdef DEBUG 418 if (acdebug) 419 printf("found\n"); 420 #endif 421 printf("%s%d at %s%d, slave %d", 422 hd->hp_driver->d_name, hd->hp_unit, 423 hc->hp_driver->d_name, hd->hp_ctlr, 424 hd->hp_slave); 425 if (hd->hp_flags) 426 printf(" flags 0x%x", hd->hp_flags); 427 printf("\n"); 428 hd->hp_alive = 1; 429 if (hd->hp_dk && dkn < DK_NDRIVE) 430 hd->hp_dk = dkn++; 431 else 432 hd->hp_dk = -1; 433 rescan = 1; 434 } else { 435 #ifdef DEBUG 436 if (acdebug) 437 printf("not found\n"); 438 #endif 439 hd->hp_ctlr = old_c; 440 hd->hp_slave = old_s; 441 } 442 /* 443 * XXX: This should be handled better. 444 * Re-scan a slave. There are two reasons to do this. 445 * 1. It is possible to have both a tape and disk 446 * (e.g. 7946) or two disks (e.g. 9122) at the 447 * same slave address. Here we need to rescan 448 * looking only at entries with a different 449 * physical unit number (hp_flags). 450 * 2. It is possible that an init failed because the 451 * slave was there but of the wrong type. In this 452 * case it may still be possible to match the slave 453 * to another ioconf entry of a different type. 454 * Here we need to rescan looking only at entries 455 * of different types. 456 * In both cases we avoid looking at undesirable 457 * ioconf entries of the same type by setting their 458 * alive fields to -1. 459 */ 460 if (rescan) { 461 for (hd = hp_dinit; hd->hp_driver; hd++) { 462 if (hd->hp_alive) 463 continue; 464 if (match_s->hp_alive == 1) { /* 1 */ 465 if (hd->hp_flags == match_s->hp_flags) 466 hd->hp_alive = -1; 467 } else { /* 2 */ 468 if (hd->hp_driver == match_s->hp_driver) 469 hd->hp_alive = -1; 470 } 471 } 472 s--; 473 continue; 474 } 475 } 476 /* 477 * Reset bogon alive fields prior to attempting next slave 478 */ 479 for (hd = hp_dinit; hd->hp_driver; hd++) 480 if (hd->hp_alive == -1) 481 hd->hp_alive = 0; 482 } 483 } 484 485 sctoaddr(addr) 486 register int addr; 487 { 488 if (addr == 7 && internalhpib) 489 addr = internalhpib; 490 else if (addr < 32) 491 addr = IOV(EXTIOBASE + (addr * IOCARDSIZE)); 492 else 493 addr = IOV(addr); 494 return(addr); 495 } 496 497 addrtosc(addr) 498 register u_int addr; 499 { 500 if (addr == internalhpib) 501 addr = 7; 502 else if (addr >= IOV(IOBASE)) { 503 addr = UNIOV(addr); 504 if (addr >= EXTIOBASE) 505 addr = (addr - EXTIOBASE) / IOCARDSIZE; 506 } 507 return((int)addr); 508 } 509 510 same_hw_device(hw, hd) 511 struct hp_hw *hw; 512 struct hp_device *hd; 513 { 514 int found = 0; 515 516 switch (hw->hw_type) { 517 case HPIB: 518 case RD: 519 case PPI: 520 case CT: 521 found = dr_type(hd->hp_driver, "hpib"); 522 break; 523 case BITMAP: 524 found = dr_type(hd->hp_driver, "grf"); 525 break; 526 case NET: 527 found = dr_type(hd->hp_driver, "le"); 528 break; 529 case COMMDCA: 530 found = dr_type(hd->hp_driver, "dca"); 531 break; 532 case COMMDCL: 533 found = dr_type(hd->hp_driver, "dcl"); 534 break; 535 case COMMDCM: 536 found = dr_type(hd->hp_driver, "dcm"); 537 break; 538 case SCSI: 539 found = dr_type(hd->hp_driver, "scsi"); 540 break; 541 case FPA: /* Unsupported so far */ 542 case VME: 543 case FLINK: 544 case MISC: 545 break; 546 } 547 return(found); 548 } 549 550 find_devs() 551 { 552 short sc; 553 u_char *id_reg; 554 register int addr; 555 register struct hp_hw *hw; 556 557 /* 558 * XXX record actual address of internal HP-IB if present. 559 */ 560 if (internalhpib) 561 internalhpib = IOV(INTERNALHPIB); 562 563 hw = sc_table; 564 for (sc = -1; sc < 32; sc++) { 565 /* 566 * Probe all select codes + internal display addr 567 */ 568 if (sc == -1) 569 addr = IOV(GRFIADDR); 570 else 571 addr = sctoaddr(sc); 572 if (badaddr((caddr_t)addr)) 573 continue; 574 575 id_reg = (u_char *) addr; 576 hw->hw_id = id_reg[1] & 0xff; 577 hw->hw_sc = sc; 578 hw->hw_addr = (char *) addr; 579 /* 580 * Internal HP-IB on some machines (345/375) doesn't return 581 * consistant id info so we use the info gleaned from the 582 * boot ROMs SYSFLAG. 583 */ 584 if (sc == 7 && internalhpib) { 585 hw->hw_name = "98624A"; 586 hw->hw_type = HPIB; 587 hw++; 588 continue; 589 } 590 /* 591 * XXX: the following could be in a big static table 592 */ 593 switch (hw->hw_id) { 594 /* Null device? */ 595 case 0: 596 break; 597 case 2: 598 case 128+2: 599 hw->hw_name = "98626A"; 600 hw->hw_type = COMMDCA; 601 break; 602 case 3: 603 hw->hw_name = "98622A"; 604 hw->hw_type = MISC; 605 break; 606 case 4: 607 hw->hw_name = "98623A"; 608 hw->hw_type = MISC; 609 break; 610 case 5: 611 case 128+5: 612 hw->hw_name = "98642A"; 613 hw->hw_type = COMMDCM; 614 break; 615 case 6: 616 hw->hw_name = "Parallel Port"; 617 hw->hw_type = PPORT; 618 break; 619 case 7: 620 case 39: 621 case 71: 622 case 103: 623 hw->hw_name = "98265A"; 624 hw->hw_type = SCSI; 625 break; 626 case 8: 627 hw->hw_name = "98625B"; 628 hw->hw_type = HPIB; 629 break; 630 case 9: 631 hw->hw_name = "98287A"; 632 hw->hw_type = KEYBOARD; 633 break; 634 case 10: 635 hw->hw_name = "98635A"; 636 hw->hw_type = FPA; 637 break; 638 case 11: 639 hw->hw_name = "Timer"; 640 hw->hw_type = MISC; 641 break; 642 case 18: 643 hw->hw_name = "98640A"; 644 hw->hw_type = MISC; 645 break; 646 case 21: 647 hw->hw_name = "98643A"; 648 hw->hw_type = NET; 649 break; 650 case 22: 651 hw->hw_name = "98659A"; 652 hw->hw_type = MISC; 653 break; 654 case 25: 655 hw->hw_name = "237"; 656 hw->hw_type = BITMAP; 657 break; 658 case 26: 659 hw->hw_name = "Quad"; 660 hw->hw_type = MISC; 661 break; 662 case 27: 663 hw->hw_name = "98253A"; 664 hw->hw_type = MISC; 665 break; 666 case 28: 667 hw->hw_name = "98627A"; 668 hw->hw_type = BITMAP; 669 break; 670 case 29: 671 hw->hw_name = "98633A"; 672 hw->hw_type = BITMAP; 673 break; 674 case 30: 675 hw->hw_name = "98259A"; 676 hw->hw_type = MISC; 677 break; 678 case 31: 679 hw->hw_name = "8741"; 680 hw->hw_type = MISC; 681 break; 682 case 49: 683 hw->hw_name = "98577A"; 684 hw->hw_type = VME; 685 sc++; 686 break; 687 case 52: 688 case 128+52: 689 hw->hw_name = "98628A"; 690 hw->hw_type = COMMDCL; 691 break; 692 case 57: 693 hw->hw_type = BITMAP; 694 hw->hw_id2 = id_reg[0x15]; 695 switch (hw->hw_id2) { 696 case 1: 697 hw->hw_name = "98700 "; 698 break; 699 case 2: 700 hw->hw_name = "TOPCAT"; 701 break; 702 case 4: 703 hw->hw_name = "98720 "; 704 sc++; 705 break; 706 case 5: 707 case 6: 708 case 7: 709 case 9: 710 hw->hw_name = "CATSEYE"; 711 break; 712 case 8: 713 hw->hw_name = "98730 "; 714 sc++; 715 break; 716 default: 717 hw->hw_name = "987xx "; 718 break; 719 } 720 break; 721 case 66: 722 case 128+66: 723 hw->hw_name = "98644A"; 724 hw->hw_type = COMMDCA; 725 break; 726 case 128: 727 hw->hw_name = "98624A"; 728 hw->hw_type = HPIB; 729 break; 730 default: 731 hw->hw_name = "DEFAULT"; 732 hw->hw_type = MISC; 733 break; 734 } 735 hw++; 736 } 737 } 738 739 #if NCD > 0 740 #include "../dev/cdvar.h" 741 742 find_cdevices() 743 { 744 register struct cddevice *cd; 745 746 for (cd = cddevice; cd->cd_unit >= 0; cd++) { 747 /* 748 * XXX 749 * Assign disk index first so that init routine 750 * can use it (saves having the driver drag around 751 * the cddevice pointer just to set up the dk_* 752 * info in the open routine). 753 */ 754 if (dkn < DK_NDRIVE) 755 cd->cd_dk = dkn++; 756 else 757 cd->cd_dk = -1; 758 if (cdinit(cd)) 759 printf("cd%d configured\n", cd->cd_unit); 760 else if (cd->cd_dk >= 0) { 761 cd->cd_dk = -1; 762 dkn--; 763 } 764 } 765 } 766 #endif 767 768 isrinit() 769 { 770 register int i; 771 772 for (i = 0; i < NISR; i++) 773 isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i]; 774 } 775 776 void 777 isrlink(isr) 778 register struct isr *isr; 779 { 780 int i = ISRIPL(isr->isr_ipl); 781 782 if (i < 0 || i >= NISR) { 783 printf("bad IPL %d\n", i); 784 panic("configure"); 785 } 786 insque(isr, isrqueue[i].isr_back); 787 } 788 789 /* 790 * Configure swap space and related parameters. 791 */ 792 swapconf() 793 { 794 register struct swdevt *swp; 795 register int nblks; 796 797 for (swp = swdevt; swp->sw_dev; swp++) 798 if (bdevsw[major(swp->sw_dev)].d_psize) { 799 nblks = 800 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 801 if (nblks != -1 && 802 (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 803 swp->sw_nblks = nblks; 804 } 805 dumpconf(); 806 } 807 808 #define DOSWAP /* Change swdevt, argdev, and dumpdev too */ 809 u_long bootdev; /* should be dev_t, but not until 32 bits */ 810 811 static char devname[][2] = { 812 0,0, /* 0 = ct */ 813 0,0, /* 1 = xx */ 814 'r','d', /* 2 = rd */ 815 0,0, /* 3 = sw */ 816 's','d', /* 4 = rd */ 817 }; 818 819 #define PARTITIONMASK 0x7 820 #define PARTITIONSHIFT 3 821 822 /* 823 * Attempt to find the device from which we were booted. 824 * If we can do so, and not instructed not to do so, 825 * change rootdev to correspond to the load device. 826 */ 827 setroot() 828 { 829 register struct hp_ctlr *hc; 830 register struct hp_device *hd; 831 int majdev, mindev, unit, part, adaptor; 832 dev_t temp, orootdev; 833 struct swdevt *swp; 834 835 if (boothowto & RB_DFLTROOT || 836 (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 837 return; 838 majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 839 if (majdev > sizeof(devname) / sizeof(devname[0])) 840 return; 841 adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 842 part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 843 unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 844 /* 845 * First, find the controller type which support this device. 846 */ 847 for (hd = hp_dinit; hd->hp_driver; hd++) 848 if (hd->hp_driver->d_name[0] == devname[majdev][0] && 849 hd->hp_driver->d_name[1] == devname[majdev][1]) 850 break; 851 if (hd->hp_driver == 0) 852 return; 853 /* 854 * Next, find the controller of that type corresponding to 855 * the adaptor number. 856 */ 857 for (hc = hp_cinit; hc->hp_driver; hc++) 858 if (hc->hp_alive && hc->hp_unit == adaptor && 859 hc->hp_driver == hd->hp_cdriver) 860 break; 861 if (hc->hp_driver == 0) 862 return; 863 /* 864 * Finally, find the device in question attached to that controller. 865 */ 866 for (hd = hp_dinit; hd->hp_driver; hd++) 867 if (hd->hp_alive && hd->hp_slave == unit && 868 hd->hp_cdriver == hc->hp_driver && 869 hd->hp_ctlr == hc->hp_unit) 870 break; 871 if (hd->hp_driver == 0) 872 return; 873 mindev = hd->hp_unit; 874 /* 875 * Form a new rootdev 876 */ 877 mindev = (mindev << PARTITIONSHIFT) + part; 878 orootdev = rootdev; 879 rootdev = makedev(majdev, mindev); 880 /* 881 * If the original rootdev is the same as the one 882 * just calculated, don't need to adjust the swap configuration. 883 */ 884 if (rootdev == orootdev) 885 return; 886 887 printf("Changing root device to %c%c%d%c\n", 888 devname[majdev][0], devname[majdev][1], 889 mindev >> PARTITIONSHIFT, part + 'a'); 890 891 #ifdef DOSWAP 892 mindev &= ~PARTITIONMASK; 893 for (swp = swdevt; swp->sw_dev; swp++) { 894 if (majdev == major(swp->sw_dev) && 895 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { 896 temp = swdevt[0].sw_dev; 897 swdevt[0].sw_dev = swp->sw_dev; 898 swp->sw_dev = temp; 899 break; 900 } 901 } 902 if (swp->sw_dev == 0) 903 return; 904 905 /* 906 * If argdev and dumpdev were the same as the old primary swap 907 * device, move them to the new primary swap device. 908 */ 909 if (temp == dumpdev) 910 dumpdev = swdevt[0].sw_dev; 911 if (temp == argdev) 912 argdev = swdevt[0].sw_dev; 913 #endif 914 } 915 916 strcmp(s1, s2) 917 register char *s1, *s2; 918 { 919 while (*s1 == *s2++) 920 if (*s1++=='\0') 921 return (0); 922 return (*s1 - *--s2); 923 } 924