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