1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* ONC_PLUS EXTRACT START */ 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 /* ONC_PLUS EXTRACT END */ 29 30 /* 31 * Configure root, swap and dump devices. 32 */ 33 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/sysmacros.h> 37 #include <sys/signal.h> 38 #include <sys/cred.h> 39 #include <sys/proc.h> 40 #include <sys/user.h> 41 #include <sys/conf.h> 42 #include <sys/buf.h> 43 #include <sys/systm.h> 44 #include <sys/vm.h> 45 #include <sys/reboot.h> 46 #include <sys/file.h> 47 #include <sys/vfs.h> 48 #include <sys/vnode.h> 49 #include <sys/errno.h> 50 #include <sys/kmem.h> 51 #include <sys/uio.h> 52 #include <sys/open.h> 53 #include <sys/mount.h> 54 #include <sys/kobj.h> 55 #include <sys/bootconf.h> 56 #include <sys/sysconf.h> 57 #include <sys/modctl.h> 58 #include <sys/autoconf.h> 59 #include <sys/debug.h> 60 #include <sys/fs/snode.h> 61 #include <fs/fs_subr.h> 62 #include <sys/socket.h> 63 #include <net/if.h> 64 65 #include <sys/mkdev.h> 66 #include <sys/cmn_err.h> 67 #include <sys/console.h> 68 69 #include <sys/conf.h> 70 #include <sys/ddi.h> 71 #include <sys/sunddi.h> 72 #include <sys/hwconf.h> 73 #include <sys/dc_ki.h> 74 #include <sys/promif.h> 75 76 77 /* 78 * Local routines 79 */ 80 static int preload_module(struct sysparam *, void *); 81 static struct vfssw *getfstype(char *, char *, size_t); 82 static int getphysdev(char *, char *, size_t); 83 static int load_bootpath_drivers(char *bootpath); 84 static int load_boot_driver(char *drv); 85 static int load_boot_platform_modules(char *drv); 86 static dev_info_t *path_to_devinfo(char *path); 87 static boolean_t netboot_over_ib(char *bootpath); 88 89 90 /* 91 * Module linkage information for the kernel. 92 */ 93 static struct modlmisc modlmisc = { 94 &mod_miscops, "root and swap configuration" 95 }; 96 97 static struct modlinkage modlinkage = { 98 MODREV_1, (void *)&modlmisc, NULL 99 }; 100 101 int 102 _init(void) 103 { 104 return (mod_install(&modlinkage)); 105 } 106 107 int 108 _fini(void) 109 { 110 return (mod_remove(&modlinkage)); 111 } 112 113 int 114 _info(struct modinfo *modinfop) 115 { 116 return (mod_info(&modlinkage, modinfop)); 117 } 118 119 /* 120 * Configure root file system. 121 */ 122 int 123 rootconf(void) 124 { 125 int error; 126 struct vfssw *vsw; 127 extern void pm_init(void); 128 129 BMDPRINTF(("rootconf: fstype %s\n", rootfs.bo_fstype)); 130 BMDPRINTF(("rootconf: name %s\n", rootfs.bo_name)); 131 BMDPRINTF(("rootconf: flags 0x%x\n", rootfs.bo_flags)); 132 BMDPRINTF(("rootconf: obp_bootpath %s\n", obp_bootpath)); 133 134 /* 135 * Install cluster modules that were only loaded during 136 * loadrootmodules(). 137 */ 138 if (error = clboot_rootconf()) 139 return (error); 140 141 if (root_is_svm) { 142 (void) strncpy(rootfs.bo_name, obp_bootpath, BO_MAXOBJNAME); 143 144 BMDPRINTF(("rootconf: svm: rootfs name %s\n", rootfs.bo_name)); 145 BMDPRINTF(("rootconf: svm: svm name %s\n", svm_bootpath)); 146 } 147 148 /* 149 * Run _init on the root filesystem (we already loaded it 150 * but we've been waiting until now to _init it) which will 151 * have the side-effect of running vsw_init() on this vfs. 152 * Because all the nfs filesystems are lumped into one 153 * module we need to special case it. 154 */ 155 if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) { 156 if (modload("fs", "nfs") == -1) { 157 cmn_err(CE_CONT, "Cannot initialize %s filesystem\n", 158 rootfs.bo_fstype); 159 return (ENXIO); 160 } 161 } else { 162 if (modload("fs", rootfs.bo_fstype) == -1) { 163 cmn_err(CE_CONT, "Cannot initialize %s filesystem\n", 164 rootfs.bo_fstype); 165 return (ENXIO); 166 } 167 } 168 RLOCK_VFSSW(); 169 vsw = vfs_getvfsswbyname(rootfs.bo_fstype); 170 RUNLOCK_VFSSW(); 171 VFS_INIT(rootvfs, &vsw->vsw_vfsops, (caddr_t)0); 172 VFS_HOLD(rootvfs); 173 174 if (root_is_svm) { 175 rootvfs->vfs_flag |= VFS_RDONLY; 176 } 177 178 /* 179 * This pm-releated call has to occur before root is mounted since we 180 * need to power up all devices. It is placed after VFS_INIT() such 181 * that opening a device via ddi_lyr_ interface just before root has 182 * been mounted would work. 183 */ 184 pm_init(); 185 186 if (netboot) { 187 if ((error = strplumb()) != 0) { 188 cmn_err(CE_CONT, "Cannot plumb network device\n"); 189 return (error); 190 } 191 } 192 193 /* 194 * ufs_mountroot() ends up calling getrootdev() 195 * (below) which actually triggers the _init, identify, 196 * probe and attach of the drivers that make up root device 197 * bush; these are also quietly waiting in memory. 198 */ 199 BMDPRINTF(("rootconf: calling VFS_MOUNTROOT %s\n", rootfs.bo_fstype)); 200 201 error = VFS_MOUNTROOT(rootvfs, ROOT_INIT); 202 vfs_unrefvfssw(vsw); 203 rootdev = rootvfs->vfs_dev; 204 205 if (error) 206 cmn_err(CE_CONT, "Cannot mount root on %s fstype %s\n", 207 rootfs.bo_name, rootfs.bo_fstype); 208 else 209 cmn_err(CE_CONT, "?root on %s fstype %s\n", 210 rootfs.bo_name, rootfs.bo_fstype); 211 return (error); 212 } 213 214 /* 215 * Remount root on an SVM mirror root device 216 * Only supported on UFS filesystems at present 217 */ 218 int 219 svm_rootconf(void) 220 { 221 int error; 222 extern int ufs_remountroot(struct vfs *vfsp); 223 224 ASSERT(root_is_svm == 1); 225 226 if (strcmp(rootfs.bo_fstype, "ufs") != 0) { 227 cmn_err(CE_CONT, "Mounting root on %s with filesystem " 228 "type %s is not supported\n", 229 rootfs.bo_name, rootfs.bo_fstype); 230 return (EINVAL); 231 } 232 233 (void) strncpy(rootfs.bo_name, svm_bootpath, BO_MAXOBJNAME); 234 235 BMDPRINTF(("svm_rootconf: rootfs %s\n", rootfs.bo_name)); 236 237 error = ufs_remountroot(rootvfs); 238 239 if (error) { 240 cmn_err(CE_CONT, "Cannot remount root on %s fstype %s\n", 241 rootfs.bo_name, rootfs.bo_fstype); 242 } else { 243 cmn_err(CE_CONT, "?root remounted on %s fstype %s\n", 244 rootfs.bo_name, rootfs.bo_fstype); 245 } 246 return (error); 247 } 248 249 /* 250 * Under the assumption that our root file system is on a 251 * disk partition, get the dev_t of the partition in question. 252 * 253 * By now, boot has faithfully loaded all our modules into memory, and 254 * we've taken over resource management. Before we go any further, we 255 * have to fire up the device drivers and stuff we need to mount the 256 * root filesystem. That's what we do here. Fingers crossed. 257 */ 258 dev_t 259 getrootdev(void) 260 { 261 dev_t d; 262 263 if ((d = ddi_pathname_to_dev_t(rootfs.bo_name)) == NODEV) 264 cmn_err(CE_CONT, "Cannot assemble drivers for root %s\n", 265 rootfs.bo_name); 266 return (d); 267 } 268 269 /* 270 * If booted with ASKNAME, prompt on the console for a filesystem 271 * name and return it. 272 */ 273 void 274 getfsname(char *askfor, char *name, size_t namelen) 275 { 276 if (boothowto & RB_ASKNAME) { 277 printf("%s name: ", askfor); 278 console_gets(name, namelen); 279 } 280 } 281 282 /*ARGSUSED1*/ 283 static int 284 preload_module(struct sysparam *sysp, void *p) 285 { 286 static char *wmesg = "forceload of %s failed"; 287 char *name; 288 289 name = sysp->sys_ptr; 290 BMDPRINTF(("preload_module: %s\n", name)); 291 if (modloadonly(NULL, name) < 0) 292 cmn_err(CE_WARN, wmesg, name); 293 return (0); 294 } 295 296 /* ONC_PLUS EXTRACT START */ 297 /* 298 * We want to load all the modules needed to mount the root filesystem, 299 * so that when we start the ball rolling in 'getrootdev', every module 300 * should already be in memory, just waiting to be init-ed. 301 */ 302 303 int 304 loadrootmodules(void) 305 { 306 struct vfssw *vsw; 307 char *this; 308 char *name; 309 int err; 310 /* ONC_PLUS EXTRACT END */ 311 int i, proplen; 312 extern char *impl_module_list[]; 313 extern char *platform_module_list[]; 314 315 /* Make sure that the PROM's devinfo tree has been created */ 316 ASSERT(ddi_root_node()); 317 318 BMDPRINTF(("loadrootmodules: fstype %s\n", rootfs.bo_fstype)); 319 BMDPRINTF(("loadrootmodules: name %s\n", rootfs.bo_name)); 320 BMDPRINTF(("loadrootmodules: flags 0x%x\n", rootfs.bo_flags)); 321 322 /* 323 * zzz We need to honor what's in rootfs if it's not null. 324 * non-null means use what's there. This way we can 325 * change rootfs with /etc/system AND with tunetool. 326 */ 327 if (root_is_svm) { 328 /* user replaced rootdev, record obp_bootpath */ 329 obp_bootpath[0] = '\0'; 330 (void) getphysdev("root", obp_bootpath, BO_MAXOBJNAME); 331 BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath)); 332 } else { 333 /* 334 * Get the root fstype and root device path from boot. 335 */ 336 rootfs.bo_fstype[0] = '\0'; 337 rootfs.bo_name[0] = '\0'; 338 } 339 340 /* 341 * This lookup will result in modloadonly-ing the root 342 * filesystem module - it gets _init-ed in rootconf() 343 */ 344 if ((vsw = getfstype("root", rootfs.bo_fstype, BO_MAXFSNAME)) == NULL) 345 return (ENXIO); /* in case we have no file system types */ 346 347 (void) strcpy(rootfs.bo_fstype, vsw->vsw_name); 348 349 vfs_unrefvfssw(vsw); 350 351 /* 352 * Load the favored drivers of the implementation. 353 * e.g. 'sbus' and possibly 'zs' (even). 354 * 355 * Called whilst boot is still loaded (because boot does 356 * the i/o for us), and DDI services are unavailable. 357 */ 358 BMDPRINTF(("loadrootmodules: impl_module_list\n")); 359 for (i = 0; (this = impl_module_list[i]) != NULL; i++) { 360 if ((err = load_boot_driver(this)) != 0) { 361 cmn_err(CE_WARN, "Cannot load drv/%s", this); 362 return (err); 363 } 364 } 365 /* 366 * Now load the platform modules (if any) 367 */ 368 BMDPRINTF(("loadrootmodules: platform_module_list\n")); 369 for (i = 0; (this = platform_module_list[i]) != NULL; i++) { 370 if ((err = load_boot_platform_modules(this)) != 0) { 371 cmn_err(CE_WARN, "Cannot load drv/%s", this); 372 return (err); 373 } 374 } 375 376 loop: 377 (void) getphysdev("root", rootfs.bo_name, BO_MAXOBJNAME); 378 379 /* 380 * Given a physical pathname, load the correct set of driver 381 * modules into memory, including all possible parents. 382 * 383 * NB: The code sets the variable 'name' for error reporting. 384 */ 385 err = 0; 386 BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name)); 387 if (root_is_svm == 0) { 388 BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name)); 389 name = rootfs.bo_name; 390 err = load_bootpath_drivers(rootfs.bo_name); 391 } 392 393 /* 394 * Load driver modules in obp_bootpath, this is always 395 * required for mountroot to succeed. obp_bootpath is 396 * is set if rootdev is set via /etc/system, which is 397 * the case if booting of a SVM/VxVM mirror. 398 */ 399 if ((err == 0) && obp_bootpath[0] != '\0') { 400 BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath)); 401 name = obp_bootpath; 402 err = load_bootpath_drivers(obp_bootpath); 403 } 404 405 if (err != 0) { 406 cmn_err(CE_CONT, "Cannot load drivers for %s\n", name); 407 goto out; 408 } 409 410 /* 411 * Check to see if the booter performed DHCP configuration 412 * ("bootp-response" boot property exists). If so, then before 413 * bootops disappears we need to save the value of this property 414 * such that the userland dhcpagent can adopt the DHCP management 415 * of our primary network interface. 416 */ 417 proplen = BOP_GETPROPLEN(bootops, "bootp-response"); 418 if (proplen > 0) { 419 dhcack = kmem_zalloc(proplen, KM_SLEEP); 420 if (BOP_GETPROP(bootops, "bootp-response", dhcack) == -1) { 421 cmn_err(CE_WARN, "BOP_GETPROP of " 422 "\"bootp-response\" failed\n"); 423 kmem_free(dhcack, dhcacklen); 424 dhcack = NULL; 425 goto out; 426 } 427 dhcacklen = proplen; 428 429 /* 430 * Fetch the "netdev-path" boot property (if it exists), and 431 * stash it for later use by sysinfo(SI_DHCP_CACHE, ...). 432 */ 433 proplen = BOP_GETPROPLEN(bootops, "netdev-path"); 434 if (proplen > 0) { 435 netdev_path = kmem_zalloc(proplen, KM_SLEEP); 436 if (BOP_GETPROP(bootops, "netdev-path", 437 (uchar_t *)netdev_path) == -1) { 438 cmn_err(CE_WARN, "BOP_GETPROP of " 439 "\"netdev-path\" failed\n"); 440 kmem_free(netdev_path, proplen); 441 goto out; 442 } 443 } 444 } 445 446 /* 447 * Preload (load-only, no init) all modules which 448 * were added to the /etc/system file with the 449 * FORCELOAD keyword. 450 */ 451 BMDPRINTF(("loadrootmodules: preload_module\n")); 452 (void) mod_sysctl_type(MOD_FORCELOAD, preload_module, NULL); 453 454 /* ONC_PLUS EXTRACT START */ 455 /* 456 * If we booted otw then load in the plumbing 457 * routine now while we still can. If we didn't 458 * boot otw then we will load strplumb in main(). 459 * 460 * NFS is actually a set of modules, the core routines, 461 * a diskless helper module, rpcmod, and the tli interface. Load 462 * them now while we still can. 463 * 464 * Because we glomb all versions of nfs into a single module 465 * we check based on the initial string "nfs". 466 * 467 * XXX: A better test for this is to see if device_type 468 * XXX: from the PROM is "network". 469 */ 470 471 if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) { 472 ++netboot; 473 474 /* 475 * Preload (load-only, no init) the dacf module. We cannot 476 * init the module because one of its requisite modules is 477 * dld whose _init function will call taskq_create(), which 478 * will panic the system at this point. 479 */ 480 if ((err = modloadonly("dacf", "net_dacf")) < 0) { 481 cmn_err(CE_CONT, "Cannot load dacf/net_dacf\n"); 482 goto out; 483 } 484 if ((err = modload("misc", "tlimod")) < 0) { 485 cmn_err(CE_CONT, "Cannot load misc/tlimod\n"); 486 goto out; 487 } 488 if ((err = modload("strmod", "rpcmod")) < 0) { 489 cmn_err(CE_CONT, "Cannot load strmod/rpcmod\n"); 490 goto out; 491 } 492 if ((err = modload("misc", "nfs_dlboot")) < 0) { 493 cmn_err(CE_CONT, "Cannot load misc/nfs_dlboot\n"); 494 goto out; 495 } 496 if ((err = modload("mac", "mac_ether")) < 0) { 497 cmn_err(CE_CONT, "Cannot load mac/mac_ether\n"); 498 goto out; 499 } 500 if ((err = modload("misc", "strplumb")) < 0) { 501 cmn_err(CE_CONT, "Cannot load misc/strplumb\n"); 502 goto out; 503 } 504 if ((err = strplumb_load()) < 0) { 505 goto out; 506 } 507 } 508 509 /* 510 * Preload modules needed for booting as a cluster. 511 */ 512 err = clboot_loadrootmodules(); 513 514 out: 515 if (err != 0 && (boothowto & RB_ASKNAME)) 516 goto loop; 517 518 return (err); 519 } 520 /* ONC_PLUS EXTRACT END */ 521 522 static int 523 get_bootpath_prop(char *bootpath) 524 { 525 if (root_is_ramdisk) { 526 if (BOP_GETPROP(bootops, "bootarchive", bootpath) == -1) 527 return (-1); 528 (void) strlcat(bootpath, ":a", BO_MAXOBJNAME); 529 } else { 530 /* 531 * Look for the 1275 compliant name 'bootpath' first, 532 * but make certain it has a non-NULL value as well. 533 */ 534 if ((BOP_GETPROP(bootops, "bootpath", bootpath) == -1) || 535 strlen(bootpath) == 0) { 536 if (BOP_GETPROP(bootops, 537 "boot-path", bootpath) == -1) 538 return (-1); 539 } 540 } 541 return (0); 542 } 543 544 static int 545 get_fstype_prop(char *fstype) 546 { 547 char *prop = (root_is_ramdisk) ? "archive-fstype" : "fstype"; 548 549 return (BOP_GETPROP(bootops, prop, fstype)); 550 } 551 552 /* 553 * Get the name of the root or swap filesystem type, and return 554 * the corresponding entry in the vfs switch. 555 * 556 * If we're not asking the user, and we're trying to find the 557 * root filesystem type, we ask boot for the filesystem 558 * type that it came from and use that. Similarly, if we're 559 * trying to find the swap filesystem, we try and derive it from 560 * the root filesystem type. 561 * 562 * If we are booting via NFS we currently have these options: 563 * nfs - dynamically choose NFS V2. V3, or V4 (default) 564 * nfs2 - force NFS V2 565 * nfs3 - force NFS V3 566 * nfs4 - force NFS V4 567 * Because we need to maintain backward compatibility with the naming 568 * convention that the NFS V2 filesystem name is "nfs" (see vfs_conf.c) 569 * we need to map "nfs" => "nfsdyn" and "nfs2" => "nfs". The dynamic 570 * nfs module will map the type back to either "nfs", "nfs3", or "nfs4". 571 * This is only for root filesystems, all other uses such as cachefs 572 * will expect that "nfs" == NFS V2. 573 * 574 * If the filesystem isn't already loaded, vfs_getvfssw() will load 575 * it for us, but if (at the time we call it) modrootloaded is 576 * still not set, it won't run the filesystems _init routine (and 577 * implicitly it won't run the filesystems vsw_init() entry either). 578 * We do that explicitly in rootconf(). 579 */ 580 static struct vfssw * 581 getfstype(char *askfor, char *fsname, size_t fsnamelen) 582 { 583 struct vfssw *vsw; 584 static char defaultfs[BO_MAXFSNAME]; 585 int root = 0; 586 587 if (strcmp(askfor, "root") == 0) { 588 (void) get_fstype_prop(defaultfs); 589 root++; 590 } else { 591 (void) strcpy(defaultfs, "swapfs"); 592 } 593 594 if (boothowto & RB_ASKNAME) { 595 for (*fsname = '\0'; *fsname == '\0'; *fsname = '\0') { 596 printf("%s filesystem type [%s]: ", askfor, defaultfs); 597 console_gets(fsname, fsnamelen); 598 if (*fsname == '\0') 599 (void) strcpy(fsname, defaultfs); 600 if (root) { 601 if (strcmp(fsname, "nfs2") == 0) 602 (void) strcpy(fsname, "nfs"); 603 else if (strcmp(fsname, "nfs") == 0) 604 (void) strcpy(fsname, "nfsdyn"); 605 } 606 if ((vsw = vfs_getvfssw(fsname)) != NULL) 607 return (vsw); 608 printf("Unknown filesystem type '%s'\n", fsname); 609 } 610 } else if (*fsname == '\0') { 611 fsname = defaultfs; 612 } 613 if (*fsname == '\0') { 614 return (NULL); 615 } 616 617 if (root) { 618 if (strcmp(fsname, "nfs2") == 0) 619 (void) strcpy(fsname, "nfs"); 620 else if (strcmp(fsname, "nfs") == 0) 621 (void) strcpy(fsname, "nfsdyn"); 622 } 623 624 return (vfs_getvfssw(fsname)); 625 } 626 627 628 /* 629 * Get a physical device name, and maybe load and attach 630 * the driver. 631 * 632 * XXX Need better checking of whether or not a device 633 * actually exists if the user typed in a pathname. 634 * 635 * XXX Are we sure we want to expose users to this sort 636 * of physical namespace gobbledygook (now there's 637 * a word to conjure with..) 638 * 639 * XXX Note that on an OBP machine, we can easily ask the 640 * prom and pretty-print some plausible set of bootable 641 * devices. We can also user the prom to verify any 642 * such device. Later tim.. later. 643 */ 644 static int 645 getphysdev(char *askfor, char *name, size_t namelen) 646 { 647 static char fmt[] = "Enter physical name of %s device\n[%s]: "; 648 dev_t dev; 649 static char defaultpath[BO_MAXOBJNAME]; 650 651 /* 652 * Establish 'default' values - we get the root device from 653 * boot, and we infer the swap device is the same but with 654 * a 'b' on the end instead of an 'a'. A first stab at 655 * ease-of-use .. 656 */ 657 if (strcmp(askfor, "root") == 0) { 658 if (get_bootpath_prop(defaultpath) == -1) 659 boothowto |= RB_ASKNAME | RB_VERBOSE; 660 } else { 661 (void) strcpy(defaultpath, rootfs.bo_name); 662 defaultpath[strlen(defaultpath) - 1] = 'b'; 663 } 664 665 retry: 666 if (boothowto & RB_ASKNAME) { 667 printf(fmt, askfor, defaultpath); 668 console_gets(name, namelen); 669 } 670 if (*name == '\0') 671 (void) strcpy(name, defaultpath); 672 673 if (strcmp(askfor, "swap") == 0) { 674 675 /* 676 * Try to load and install the swap device driver. 677 */ 678 dev = ddi_pathname_to_dev_t(name); 679 680 if (dev == (dev_t)-1) { 681 printf("Not a supported device for swap.\n"); 682 boothowto |= RB_ASKNAME | RB_VERBOSE; 683 goto retry; 684 } 685 686 /* 687 * Ensure that we're not trying to swap on the floppy. 688 */ 689 if (strncmp(ddi_major_to_name(getmajor(dev)), "fd", 2) == 0) { 690 printf("Too dangerous to swap on the floppy\n"); 691 if (boothowto & RB_ASKNAME) 692 goto retry; 693 return (-1); 694 } 695 } 696 697 return (0); 698 } 699 700 701 /* 702 * Load a driver needed to boot. 703 */ 704 static int 705 load_boot_driver(char *drv) 706 { 707 char *drvname; 708 major_t major; 709 #ifdef sparc 710 struct devnames *dnp; 711 ddi_prop_t *propp; 712 char *module; 713 char *dir, *mf; 714 int plen; 715 int mlen; 716 #endif /* sparc */ 717 718 if ((major = ddi_name_to_major(drv)) == (major_t)-1) { 719 cmn_err(CE_CONT, "%s: no major number\n", drv); 720 return (-1); 721 } 722 /* 723 * resolve aliases 724 */ 725 drvname = ddi_major_to_name(major); 726 727 #ifdef DEBUG 728 if (strcmp(drv, drvname) == 0) { 729 BMDPRINTF(("load_boot_driver: %s\n", drv)); 730 } else { 731 BMDPRINTF(("load_boot_driver: %s -> %s\n", drv, drvname)); 732 } 733 #endif /* DEBUG */ 734 735 if (modloadonly("drv", drvname) == -1) { 736 cmn_err(CE_CONT, "%s: cannot load driver\n", drvname); 737 return (-1); 738 } 739 740 #ifdef sparc 741 /* 742 * NOTE: this can be removed when newboot-sparc is delivered. 743 * 744 * Check to see if the driver had a 'ddi-forceload' global driver.conf 745 * property to identify additional modules that need to be loaded. 746 * The driver still needs to use ddi_modopen() to open these modules, 747 * but the 'ddi-forceload' property allows the modules to be loaded 748 * into memory prior to lights-out, so that driver ddi_modopen() 749 * calls during lights-out (when mounting root) will work correctly. 750 * Use of 'ddi-forceload' is only required for drivers involved in 751 * getting root mounted. 752 */ 753 dnp = &devnamesp[major]; 754 if (dnp->dn_global_prop_ptr && dnp->dn_global_prop_ptr->prop_list && 755 ((propp = i_ddi_prop_search(DDI_DEV_T_ANY, 756 "ddi-forceload", DDI_PROP_TYPE_STRING, 757 &dnp->dn_global_prop_ptr->prop_list)) != NULL)) { 758 759 module = (char *)propp->prop_val; 760 plen = propp->prop_len; 761 while (plen > 0) { 762 mlen = strlen(module); 763 mf = strrchr(module, '/'); 764 if (mf) { 765 dir = module; 766 *mf++ = '\0'; /* '/' -> '\0' */ 767 } else { 768 dir = "misc"; 769 mf = module; 770 } 771 if (modloadonly(dir, mf) == -1) 772 cmn_err(CE_CONT, 773 "misc/%s: can't load module\n", mf); 774 if (mf != module) 775 *(mf - 1) = '/'; /* '\0' -> '/' */ 776 777 module += mlen + 1; 778 plen -= mlen + 1; 779 } 780 } 781 #endif /* sparc */ 782 783 return (0); 784 } 785 786 787 /* 788 * For a given instance, load that driver and its parents 789 */ 790 static int 791 load_parent_drivers(dev_info_t *dip, char *path) 792 { 793 int rval = 0; 794 major_t major = (major_t)-1; 795 char *drv; 796 char *p; 797 798 while (dip) { 799 /* check for path-oriented alias */ 800 if (path) 801 major = ddi_name_to_major(path); 802 else 803 major = (major_t)-1; 804 805 if (major != (major_t)-1) 806 drv = ddi_major_to_name(major); 807 else 808 drv = ddi_binding_name(dip); 809 810 if (load_boot_driver(drv) != 0) 811 rval = -1; 812 813 dip = ddi_get_parent(dip); 814 if (path) { 815 p = strrchr(path, '/'); 816 if (p) 817 *p = 0; 818 } 819 } 820 821 return (rval); 822 } 823 824 825 /* 826 * For a given path to a boot device, 827 * load that driver and all its parents. 828 */ 829 static int 830 load_bootpath_drivers(char *bootpath) 831 { 832 dev_info_t *dip; 833 char *pathcopy; 834 int pathcopy_len; 835 int rval; 836 char *p; 837 838 if (bootpath == NULL || *bootpath == 0) 839 return (-1); 840 841 BMDPRINTF(("load_bootpath_drivers: %s\n", bootpath)); 842 843 pathcopy = i_ddi_strdup(bootpath, KM_SLEEP); 844 pathcopy_len = strlen(pathcopy) + 1; 845 846 dip = path_to_devinfo(pathcopy); 847 848 #if defined(__i386) || defined(__amd64) 849 /* 850 * i386 does not provide stub nodes for all boot devices, 851 * but we should be able to find the node for the parent, 852 * and the leaf of the boot path should be the driver name, 853 * which we go ahead and load here. 854 */ 855 if (dip == NULL) { 856 char *leaf; 857 858 /* 859 * Find last slash to build the full path to the 860 * parent of the leaf boot device 861 */ 862 p = strrchr(pathcopy, '/'); 863 *p++ = 0; 864 865 /* 866 * Now isolate the driver name of the leaf device 867 */ 868 leaf = p; 869 p = strchr(leaf, '@'); 870 *p = 0; 871 872 BMDPRINTF(("load_bootpath_drivers: parent=%s leaf=%s\n", 873 bootpath, leaf)); 874 875 dip = path_to_devinfo(pathcopy); 876 if (leaf) { 877 rval = load_boot_driver(leaf, NULL); 878 if (rval == -1) { 879 kmem_free(pathcopy, pathcopy_len); 880 return (NULL); 881 } 882 } 883 } 884 #endif 885 886 if (dip == NULL) { 887 cmn_err(CE_WARN, "can't bind driver for boot path <%s>", 888 bootpath); 889 kmem_free(pathcopy, pathcopy_len); 890 return (NULL); 891 } 892 893 /* 894 * Load IP over IB driver when netbooting over IB. 895 * As per IB 1275 binding, IP over IB is represented as 896 * service on the top of the HCA node. So, there is no 897 * PROM node and generic framework cannot pre-load 898 * IP over IB driver based on the bootpath. The following 899 * code preloads IP over IB driver when doing netboot over 900 * InfiniBand. 901 */ 902 if (netboot_over_ib(bootpath) && 903 modloadonly("drv", "ibd") == -1) { 904 cmn_err(CE_CONT, "ibd: cannot load platform driver\n"); 905 kmem_free(pathcopy, pathcopy_len); 906 return (NULL); 907 } 908 909 /* get rid of minor node at end of copy (if not already done above) */ 910 p = strrchr(pathcopy, '/'); 911 if (p) { 912 p = strchr(p, ':'); 913 if (p) 914 *p = 0; 915 } 916 917 rval = load_parent_drivers(dip, pathcopy); 918 kmem_free(pathcopy, pathcopy_len); 919 return (rval); 920 } 921 922 923 924 925 /* 926 * Load drivers required for a platform 927 * Since all hardware nodes should be available in the device 928 * tree, walk the per-driver list and load the parents of 929 * each node found. If not a hardware node, try to load it. 930 * Pseudo nexus is already loaded. 931 */ 932 static int 933 load_boot_platform_modules(char *drv) 934 { 935 major_t major; 936 dev_info_t *dip; 937 char *drvname; 938 int rval = 0; 939 940 if ((major = ddi_name_to_major(drv)) == (major_t)-1) { 941 cmn_err(CE_CONT, "%s: no major number\n", drv); 942 return (-1); 943 } 944 945 /* 946 * resolve aliases 947 */ 948 drvname = ddi_major_to_name(major); 949 if ((major = ddi_name_to_major(drvname)) == (major_t)-1) 950 return (-1); 951 952 #ifdef DEBUG 953 if (strcmp(drv, drvname) == 0) { 954 BMDPRINTF(("load_boot_platform_modules: %s\n", drv)); 955 } else { 956 BMDPRINTF(("load_boot_platform_modules: %s -> %s\n", 957 drv, drvname)); 958 } 959 #endif /* DEBUG */ 960 961 dip = devnamesp[major].dn_head; 962 if (dip == NULL) { 963 /* pseudo node, not-enumerated, needs to be loaded */ 964 if (modloadonly("drv", drvname) == -1) { 965 cmn_err(CE_CONT, "%s: cannot load platform driver\n", 966 drvname); 967 rval = -1; 968 } 969 } else { 970 while (dip) { 971 if (load_parent_drivers(dip, NULL) != 0) 972 rval = -1; 973 dip = ddi_get_next(dip); 974 } 975 } 976 977 return (rval); 978 } 979 980 981 /* 982 * i_find_node: Internal routine used by path_to_devinfo 983 * to locate a given nodeid in the device tree. 984 */ 985 struct i_path_findnode { 986 pnode_t nodeid; 987 dev_info_t *dip; 988 }; 989 990 static int 991 i_path_find_node(dev_info_t *dev, void *arg) 992 { 993 struct i_path_findnode *f = (struct i_path_findnode *)arg; 994 995 996 if (ddi_get_nodeid(dev) == (int)f->nodeid) { 997 f->dip = dev; 998 return (DDI_WALK_TERMINATE); 999 } 1000 return (DDI_WALK_CONTINUE); 1001 } 1002 1003 /* 1004 * Return the devinfo node to a boot device 1005 */ 1006 static dev_info_t * 1007 path_to_devinfo(char *path) 1008 { 1009 struct i_path_findnode fn; 1010 extern dev_info_t *top_devinfo; 1011 1012 /* 1013 * Get the nodeid of the given pathname, if such a mapping exists. 1014 */ 1015 fn.dip = NULL; 1016 fn.nodeid = prom_finddevice(path); 1017 if (fn.nodeid != OBP_BADNODE) { 1018 /* 1019 * Find the nodeid in our copy of the device tree and return 1020 * whatever name we used to bind this node to a driver. 1021 */ 1022 ddi_walk_devs(top_devinfo, i_path_find_node, (void *)(&fn)); 1023 } 1024 1025 #ifdef DEBUG 1026 /* 1027 * If we're bound to something other than the nodename, 1028 * note that in the message buffer and system log. 1029 */ 1030 if (fn.dip) { 1031 char *p, *q; 1032 1033 p = ddi_binding_name(fn.dip); 1034 q = ddi_node_name(fn.dip); 1035 if (p && q && (strcmp(p, q) != 0)) { 1036 BMDPRINTF(("path_to_devinfo: %s bound to %s\n", 1037 path, p)); 1038 } 1039 } 1040 #endif /* DEBUG */ 1041 1042 return (fn.dip); 1043 } 1044 1045 /* 1046 * This routine returns B_TRUE if the bootpath corresponds to 1047 * IP over IB driver. 1048 * 1049 * The format of the bootpath for the IP over IB looks like 1050 * /pci@1f,700000/pci@1/ib@0:port=1,pkey=8001,protocol=ip 1051 * 1052 * The minor node portion "port=1,pkey=8001,protocol=ip" represents 1053 * IP over IB driver. 1054 */ 1055 static boolean_t 1056 netboot_over_ib(char *bootpath) 1057 { 1058 1059 char *temp; 1060 boolean_t ret = B_FALSE; 1061 pnode_t node = prom_finddevice(bootpath); 1062 int len; 1063 char devicetype[OBP_MAXDRVNAME]; 1064 1065 /* Is this IB node ? */ 1066 len = prom_getproplen(node, OBP_DEVICETYPE); 1067 if (len <= 1 || len >= OBP_MAXDRVNAME) 1068 return (B_FALSE); 1069 1070 (void) prom_getprop(node, OBP_DEVICETYPE, (caddr_t)devicetype); 1071 1072 if (strncmp("ib", devicetype, 2) == 0) { 1073 /* Check for proper IP over IB string */ 1074 if ((temp = strstr(bootpath, ":port=")) != NULL) { 1075 if ((temp = strstr(temp, ",pkey=")) != NULL) 1076 if ((temp = strstr(temp, 1077 ",protocol=ip")) != NULL) { 1078 ret = B_TRUE; 1079 } 1080 } 1081 } 1082 return (ret); 1083 } 1084