17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 548aa2e6aSseb * Common Development and Distribution License (the "License"). 648aa2e6aSseb * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* ONC_PLUS EXTRACT START */ 227c478bd9Sstevel@tonic-gate /* 23d62bc4baSyz147064 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate /* ONC_PLUS EXTRACT END */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* 317c478bd9Sstevel@tonic-gate * Configure root, swap and dump devices. 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include <sys/types.h> 357c478bd9Sstevel@tonic-gate #include <sys/param.h> 367c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 377c478bd9Sstevel@tonic-gate #include <sys/signal.h> 387c478bd9Sstevel@tonic-gate #include <sys/cred.h> 397c478bd9Sstevel@tonic-gate #include <sys/proc.h> 407c478bd9Sstevel@tonic-gate #include <sys/user.h> 417c478bd9Sstevel@tonic-gate #include <sys/conf.h> 427c478bd9Sstevel@tonic-gate #include <sys/buf.h> 437c478bd9Sstevel@tonic-gate #include <sys/systm.h> 447c478bd9Sstevel@tonic-gate #include <sys/vm.h> 457c478bd9Sstevel@tonic-gate #include <sys/reboot.h> 467c478bd9Sstevel@tonic-gate #include <sys/file.h> 477c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 487c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 497c478bd9Sstevel@tonic-gate #include <sys/errno.h> 507c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 517c478bd9Sstevel@tonic-gate #include <sys/uio.h> 527c478bd9Sstevel@tonic-gate #include <sys/open.h> 537c478bd9Sstevel@tonic-gate #include <sys/mount.h> 547c478bd9Sstevel@tonic-gate #include <sys/kobj.h> 557c478bd9Sstevel@tonic-gate #include <sys/bootconf.h> 567c478bd9Sstevel@tonic-gate #include <sys/sysconf.h> 577c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 587c478bd9Sstevel@tonic-gate #include <sys/autoconf.h> 597c478bd9Sstevel@tonic-gate #include <sys/debug.h> 607c478bd9Sstevel@tonic-gate #include <sys/fs/snode.h> 617c478bd9Sstevel@tonic-gate #include <fs/fs_subr.h> 627c478bd9Sstevel@tonic-gate #include <sys/socket.h> 637c478bd9Sstevel@tonic-gate #include <net/if.h> 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #include <sys/mkdev.h> 667c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 677c478bd9Sstevel@tonic-gate #include <sys/console.h> 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate #include <sys/conf.h> 707c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 717c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 727c478bd9Sstevel@tonic-gate #include <sys/hwconf.h> 737c478bd9Sstevel@tonic-gate #include <sys/dc_ki.h> 747c478bd9Sstevel@tonic-gate #include <sys/promif.h> 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate /* 787c478bd9Sstevel@tonic-gate * Local routines 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate static int preload_module(struct sysparam *, void *); 817c478bd9Sstevel@tonic-gate static struct vfssw *getfstype(char *, char *, size_t); 827c478bd9Sstevel@tonic-gate static int getphysdev(char *, char *, size_t); 837c478bd9Sstevel@tonic-gate static int load_bootpath_drivers(char *bootpath); 847c478bd9Sstevel@tonic-gate static int load_boot_driver(char *drv); 857c478bd9Sstevel@tonic-gate static int load_boot_platform_modules(char *drv); 867c478bd9Sstevel@tonic-gate static dev_info_t *path_to_devinfo(char *path); 877c478bd9Sstevel@tonic-gate static boolean_t netboot_over_ib(char *bootpath); 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate /* 917c478bd9Sstevel@tonic-gate * Module linkage information for the kernel. 927c478bd9Sstevel@tonic-gate */ 937c478bd9Sstevel@tonic-gate static struct modlmisc modlmisc = { 94986fd29aSsetje &mod_miscops, "root and swap configuration" 957c478bd9Sstevel@tonic-gate }; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = { 987c478bd9Sstevel@tonic-gate MODREV_1, (void *)&modlmisc, NULL 997c478bd9Sstevel@tonic-gate }; 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate int 1027c478bd9Sstevel@tonic-gate _init(void) 1037c478bd9Sstevel@tonic-gate { 1047c478bd9Sstevel@tonic-gate return (mod_install(&modlinkage)); 1057c478bd9Sstevel@tonic-gate } 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate int 1087c478bd9Sstevel@tonic-gate _fini(void) 1097c478bd9Sstevel@tonic-gate { 1107c478bd9Sstevel@tonic-gate return (mod_remove(&modlinkage)); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate int 1147c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop) 1157c478bd9Sstevel@tonic-gate { 1167c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate /* 1207c478bd9Sstevel@tonic-gate * Configure root file system. 1217c478bd9Sstevel@tonic-gate */ 1227c478bd9Sstevel@tonic-gate int 1237c478bd9Sstevel@tonic-gate rootconf(void) 1247c478bd9Sstevel@tonic-gate { 1257c478bd9Sstevel@tonic-gate int error; 1267c478bd9Sstevel@tonic-gate struct vfssw *vsw; 1277c478bd9Sstevel@tonic-gate extern void pm_init(void); 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: fstype %s\n", rootfs.bo_fstype)); 1307c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: name %s\n", rootfs.bo_name)); 1317c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: flags 0x%x\n", rootfs.bo_flags)); 1327c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: obp_bootpath %s\n", obp_bootpath)); 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * Install cluster modules that were only loaded during 1367c478bd9Sstevel@tonic-gate * loadrootmodules(). 1377c478bd9Sstevel@tonic-gate */ 1387c478bd9Sstevel@tonic-gate if (error = clboot_rootconf()) 1397c478bd9Sstevel@tonic-gate return (error); 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate if (root_is_svm) { 1427c478bd9Sstevel@tonic-gate (void) strncpy(rootfs.bo_name, obp_bootpath, BO_MAXOBJNAME); 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: svm: rootfs name %s\n", rootfs.bo_name)); 1457c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: svm: svm name %s\n", svm_bootpath)); 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate /* 1497c478bd9Sstevel@tonic-gate * Run _init on the root filesystem (we already loaded it 1507c478bd9Sstevel@tonic-gate * but we've been waiting until now to _init it) which will 1517c478bd9Sstevel@tonic-gate * have the side-effect of running vsw_init() on this vfs. 1527c478bd9Sstevel@tonic-gate * Because all the nfs filesystems are lumped into one 1537c478bd9Sstevel@tonic-gate * module we need to special case it. 1547c478bd9Sstevel@tonic-gate */ 1557c478bd9Sstevel@tonic-gate if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) { 1567c478bd9Sstevel@tonic-gate if (modload("fs", "nfs") == -1) { 1577c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot initialize %s filesystem\n", 1587c478bd9Sstevel@tonic-gate rootfs.bo_fstype); 1597c478bd9Sstevel@tonic-gate return (ENXIO); 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate } else { 1627c478bd9Sstevel@tonic-gate if (modload("fs", rootfs.bo_fstype) == -1) { 1637c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot initialize %s filesystem\n", 1647c478bd9Sstevel@tonic-gate rootfs.bo_fstype); 1657c478bd9Sstevel@tonic-gate return (ENXIO); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate RLOCK_VFSSW(); 1697c478bd9Sstevel@tonic-gate vsw = vfs_getvfsswbyname(rootfs.bo_fstype); 1707c478bd9Sstevel@tonic-gate RUNLOCK_VFSSW(); 1717c478bd9Sstevel@tonic-gate VFS_INIT(rootvfs, &vsw->vsw_vfsops, (caddr_t)0); 1727c478bd9Sstevel@tonic-gate VFS_HOLD(rootvfs); 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate if (root_is_svm) { 1757c478bd9Sstevel@tonic-gate rootvfs->vfs_flag |= VFS_RDONLY; 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate /* 1797c478bd9Sstevel@tonic-gate * This pm-releated call has to occur before root is mounted since we 1807c478bd9Sstevel@tonic-gate * need to power up all devices. It is placed after VFS_INIT() such 1817c478bd9Sstevel@tonic-gate * that opening a device via ddi_lyr_ interface just before root has 1827c478bd9Sstevel@tonic-gate * been mounted would work. 1837c478bd9Sstevel@tonic-gate */ 1847c478bd9Sstevel@tonic-gate pm_init(); 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate if (netboot) { 1877c478bd9Sstevel@tonic-gate if ((error = strplumb()) != 0) { 1887c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot plumb network device\n"); 1897c478bd9Sstevel@tonic-gate return (error); 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate /* 1947c478bd9Sstevel@tonic-gate * ufs_mountroot() ends up calling getrootdev() 1957c478bd9Sstevel@tonic-gate * (below) which actually triggers the _init, identify, 1967c478bd9Sstevel@tonic-gate * probe and attach of the drivers that make up root device 1977c478bd9Sstevel@tonic-gate * bush; these are also quietly waiting in memory. 1987c478bd9Sstevel@tonic-gate */ 1997c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: calling VFS_MOUNTROOT %s\n", rootfs.bo_fstype)); 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate error = VFS_MOUNTROOT(rootvfs, ROOT_INIT); 2027c478bd9Sstevel@tonic-gate vfs_unrefvfssw(vsw); 2037c478bd9Sstevel@tonic-gate rootdev = rootvfs->vfs_dev; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate if (error) 2067c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot mount root on %s fstype %s\n", 2077c478bd9Sstevel@tonic-gate rootfs.bo_name, rootfs.bo_fstype); 2087c478bd9Sstevel@tonic-gate else 2097c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "?root on %s fstype %s\n", 2107c478bd9Sstevel@tonic-gate rootfs.bo_name, rootfs.bo_fstype); 2117c478bd9Sstevel@tonic-gate return (error); 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate /* 2157c478bd9Sstevel@tonic-gate * Remount root on an SVM mirror root device 2167c478bd9Sstevel@tonic-gate * Only supported on UFS filesystems at present 2177c478bd9Sstevel@tonic-gate */ 2187c478bd9Sstevel@tonic-gate int 2197c478bd9Sstevel@tonic-gate svm_rootconf(void) 2207c478bd9Sstevel@tonic-gate { 2217c478bd9Sstevel@tonic-gate int error; 2227c478bd9Sstevel@tonic-gate extern int ufs_remountroot(struct vfs *vfsp); 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate ASSERT(root_is_svm == 1); 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate if (strcmp(rootfs.bo_fstype, "ufs") != 0) { 2277c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Mounting root on %s with filesystem " 2287c478bd9Sstevel@tonic-gate "type %s is not supported\n", 2297c478bd9Sstevel@tonic-gate rootfs.bo_name, rootfs.bo_fstype); 2307c478bd9Sstevel@tonic-gate return (EINVAL); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate (void) strncpy(rootfs.bo_name, svm_bootpath, BO_MAXOBJNAME); 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate BMDPRINTF(("svm_rootconf: rootfs %s\n", rootfs.bo_name)); 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate error = ufs_remountroot(rootvfs); 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate if (error) { 2407c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot remount root on %s fstype %s\n", 2417c478bd9Sstevel@tonic-gate rootfs.bo_name, rootfs.bo_fstype); 2427c478bd9Sstevel@tonic-gate } else { 2437c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "?root remounted on %s fstype %s\n", 2447c478bd9Sstevel@tonic-gate rootfs.bo_name, rootfs.bo_fstype); 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate return (error); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate /* 2507c478bd9Sstevel@tonic-gate * Under the assumption that our root file system is on a 2517c478bd9Sstevel@tonic-gate * disk partition, get the dev_t of the partition in question. 2527c478bd9Sstevel@tonic-gate * 2537c478bd9Sstevel@tonic-gate * By now, boot has faithfully loaded all our modules into memory, and 2547c478bd9Sstevel@tonic-gate * we've taken over resource management. Before we go any further, we 2557c478bd9Sstevel@tonic-gate * have to fire up the device drivers and stuff we need to mount the 2567c478bd9Sstevel@tonic-gate * root filesystem. That's what we do here. Fingers crossed. 2577c478bd9Sstevel@tonic-gate */ 2587c478bd9Sstevel@tonic-gate dev_t 2597c478bd9Sstevel@tonic-gate getrootdev(void) 2607c478bd9Sstevel@tonic-gate { 2617c478bd9Sstevel@tonic-gate dev_t d; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate if ((d = ddi_pathname_to_dev_t(rootfs.bo_name)) == NODEV) 2647c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot assemble drivers for root %s\n", 2657c478bd9Sstevel@tonic-gate rootfs.bo_name); 2667c478bd9Sstevel@tonic-gate return (d); 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* 2707c478bd9Sstevel@tonic-gate * If booted with ASKNAME, prompt on the console for a filesystem 2717c478bd9Sstevel@tonic-gate * name and return it. 2727c478bd9Sstevel@tonic-gate */ 2737c478bd9Sstevel@tonic-gate void 2747c478bd9Sstevel@tonic-gate getfsname(char *askfor, char *name, size_t namelen) 2757c478bd9Sstevel@tonic-gate { 2767c478bd9Sstevel@tonic-gate if (boothowto & RB_ASKNAME) { 2777c478bd9Sstevel@tonic-gate printf("%s name: ", askfor); 2787c478bd9Sstevel@tonic-gate console_gets(name, namelen); 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 2837c478bd9Sstevel@tonic-gate static int 2847c478bd9Sstevel@tonic-gate preload_module(struct sysparam *sysp, void *p) 2857c478bd9Sstevel@tonic-gate { 2867c478bd9Sstevel@tonic-gate static char *wmesg = "forceload of %s failed"; 2877c478bd9Sstevel@tonic-gate char *name; 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate name = sysp->sys_ptr; 2907c478bd9Sstevel@tonic-gate BMDPRINTF(("preload_module: %s\n", name)); 2917c478bd9Sstevel@tonic-gate if (modloadonly(NULL, name) < 0) 2927c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, wmesg, name); 2937c478bd9Sstevel@tonic-gate return (0); 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate /* ONC_PLUS EXTRACT START */ 2977c478bd9Sstevel@tonic-gate /* 2987c478bd9Sstevel@tonic-gate * We want to load all the modules needed to mount the root filesystem, 2997c478bd9Sstevel@tonic-gate * so that when we start the ball rolling in 'getrootdev', every module 3007c478bd9Sstevel@tonic-gate * should already be in memory, just waiting to be init-ed. 3017c478bd9Sstevel@tonic-gate */ 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate int 3047c478bd9Sstevel@tonic-gate loadrootmodules(void) 3057c478bd9Sstevel@tonic-gate { 3067c478bd9Sstevel@tonic-gate struct vfssw *vsw; 3077c478bd9Sstevel@tonic-gate char *this; 3087c478bd9Sstevel@tonic-gate char *name; 3097c478bd9Sstevel@tonic-gate int err; 3107c478bd9Sstevel@tonic-gate /* ONC_PLUS EXTRACT END */ 311986fd29aSsetje int i, proplen; 3127c478bd9Sstevel@tonic-gate extern char *impl_module_list[]; 3137c478bd9Sstevel@tonic-gate extern char *platform_module_list[]; 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate /* Make sure that the PROM's devinfo tree has been created */ 3167c478bd9Sstevel@tonic-gate ASSERT(ddi_root_node()); 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: fstype %s\n", rootfs.bo_fstype)); 3197c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: name %s\n", rootfs.bo_name)); 3207c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: flags 0x%x\n", rootfs.bo_flags)); 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate /* 3237c478bd9Sstevel@tonic-gate * zzz We need to honor what's in rootfs if it's not null. 3247c478bd9Sstevel@tonic-gate * non-null means use what's there. This way we can 3257c478bd9Sstevel@tonic-gate * change rootfs with /etc/system AND with tunetool. 3267c478bd9Sstevel@tonic-gate */ 3277c478bd9Sstevel@tonic-gate if (root_is_svm) { 3287c478bd9Sstevel@tonic-gate /* user replaced rootdev, record obp_bootpath */ 3297c478bd9Sstevel@tonic-gate obp_bootpath[0] = '\0'; 3307c478bd9Sstevel@tonic-gate (void) getphysdev("root", obp_bootpath, BO_MAXOBJNAME); 3317c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath)); 3327c478bd9Sstevel@tonic-gate } else { 3337c478bd9Sstevel@tonic-gate /* 3347c478bd9Sstevel@tonic-gate * Get the root fstype and root device path from boot. 3357c478bd9Sstevel@tonic-gate */ 3367c478bd9Sstevel@tonic-gate rootfs.bo_fstype[0] = '\0'; 3377c478bd9Sstevel@tonic-gate rootfs.bo_name[0] = '\0'; 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate /* 3417c478bd9Sstevel@tonic-gate * This lookup will result in modloadonly-ing the root 3427c478bd9Sstevel@tonic-gate * filesystem module - it gets _init-ed in rootconf() 3437c478bd9Sstevel@tonic-gate */ 3447c478bd9Sstevel@tonic-gate if ((vsw = getfstype("root", rootfs.bo_fstype, BO_MAXFSNAME)) == NULL) 3457c478bd9Sstevel@tonic-gate return (ENXIO); /* in case we have no file system types */ 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate (void) strcpy(rootfs.bo_fstype, vsw->vsw_name); 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate vfs_unrefvfssw(vsw); 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate /* 3527c478bd9Sstevel@tonic-gate * Load the favored drivers of the implementation. 3537c478bd9Sstevel@tonic-gate * e.g. 'sbus' and possibly 'zs' (even). 3547c478bd9Sstevel@tonic-gate * 3557c478bd9Sstevel@tonic-gate * Called whilst boot is still loaded (because boot does 3567c478bd9Sstevel@tonic-gate * the i/o for us), and DDI services are unavailable. 3577c478bd9Sstevel@tonic-gate */ 3587c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: impl_module_list\n")); 3597c478bd9Sstevel@tonic-gate for (i = 0; (this = impl_module_list[i]) != NULL; i++) { 3607c478bd9Sstevel@tonic-gate if ((err = load_boot_driver(this)) != 0) { 3617c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "Cannot load drv/%s", this); 3627c478bd9Sstevel@tonic-gate return (err); 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate } 3657c478bd9Sstevel@tonic-gate /* 3667c478bd9Sstevel@tonic-gate * Now load the platform modules (if any) 3677c478bd9Sstevel@tonic-gate */ 3687c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: platform_module_list\n")); 3697c478bd9Sstevel@tonic-gate for (i = 0; (this = platform_module_list[i]) != NULL; i++) { 3707c478bd9Sstevel@tonic-gate if ((err = load_boot_platform_modules(this)) != 0) { 3717c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "Cannot load drv/%s", this); 3727c478bd9Sstevel@tonic-gate return (err); 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate loop: 3777c478bd9Sstevel@tonic-gate (void) getphysdev("root", rootfs.bo_name, BO_MAXOBJNAME); 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate /* 3807c478bd9Sstevel@tonic-gate * Given a physical pathname, load the correct set of driver 3817c478bd9Sstevel@tonic-gate * modules into memory, including all possible parents. 3827c478bd9Sstevel@tonic-gate * 3837c478bd9Sstevel@tonic-gate * NB: The code sets the variable 'name' for error reporting. 3847c478bd9Sstevel@tonic-gate */ 3857c478bd9Sstevel@tonic-gate err = 0; 3867c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name)); 3877c478bd9Sstevel@tonic-gate if (root_is_svm == 0) { 3887c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name)); 3897c478bd9Sstevel@tonic-gate name = rootfs.bo_name; 3907c478bd9Sstevel@tonic-gate err = load_bootpath_drivers(rootfs.bo_name); 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate /* 3947c478bd9Sstevel@tonic-gate * Load driver modules in obp_bootpath, this is always 3957c478bd9Sstevel@tonic-gate * required for mountroot to succeed. obp_bootpath is 3967c478bd9Sstevel@tonic-gate * is set if rootdev is set via /etc/system, which is 3977c478bd9Sstevel@tonic-gate * the case if booting of a SVM/VxVM mirror. 3987c478bd9Sstevel@tonic-gate */ 3997c478bd9Sstevel@tonic-gate if ((err == 0) && obp_bootpath[0] != '\0') { 4007c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath)); 4017c478bd9Sstevel@tonic-gate name = obp_bootpath; 4027c478bd9Sstevel@tonic-gate err = load_bootpath_drivers(obp_bootpath); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate if (err != 0) { 4067c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load drivers for %s\n", name); 4077c478bd9Sstevel@tonic-gate goto out; 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate /* 4117c478bd9Sstevel@tonic-gate * Check to see if the booter performed DHCP configuration 4127c478bd9Sstevel@tonic-gate * ("bootp-response" boot property exists). If so, then before 4137c478bd9Sstevel@tonic-gate * bootops disappears we need to save the value of this property 4147c478bd9Sstevel@tonic-gate * such that the userland dhcpagent can adopt the DHCP management 415986fd29aSsetje * of our primary network interface. 4167c478bd9Sstevel@tonic-gate */ 4177c478bd9Sstevel@tonic-gate proplen = BOP_GETPROPLEN(bootops, "bootp-response"); 4187c478bd9Sstevel@tonic-gate if (proplen > 0) { 419986fd29aSsetje dhcack = kmem_zalloc(proplen, KM_SLEEP); 420986fd29aSsetje if (BOP_GETPROP(bootops, "bootp-response", dhcack) == -1) { 4217c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "BOP_GETPROP of " 4227c478bd9Sstevel@tonic-gate "\"bootp-response\" failed\n"); 4237c478bd9Sstevel@tonic-gate kmem_free(dhcack, dhcacklen); 4247c478bd9Sstevel@tonic-gate dhcack = NULL; 4257c478bd9Sstevel@tonic-gate goto out; 4267c478bd9Sstevel@tonic-gate } 427986fd29aSsetje dhcacklen = proplen; 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate /* 4307c478bd9Sstevel@tonic-gate * Fetch the "netdev-path" boot property (if it exists), and 4317c478bd9Sstevel@tonic-gate * stash it for later use by sysinfo(SI_DHCP_CACHE, ...). 4327c478bd9Sstevel@tonic-gate */ 4337c478bd9Sstevel@tonic-gate proplen = BOP_GETPROPLEN(bootops, "netdev-path"); 4347c478bd9Sstevel@tonic-gate if (proplen > 0) { 4357c478bd9Sstevel@tonic-gate netdev_path = kmem_zalloc(proplen, KM_SLEEP); 4367c478bd9Sstevel@tonic-gate if (BOP_GETPROP(bootops, "netdev-path", 4377c478bd9Sstevel@tonic-gate (uchar_t *)netdev_path) == -1) { 4387c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "BOP_GETPROP of " 4397c478bd9Sstevel@tonic-gate "\"netdev-path\" failed\n"); 4407c478bd9Sstevel@tonic-gate kmem_free(netdev_path, proplen); 4417c478bd9Sstevel@tonic-gate goto out; 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate /* 4477c478bd9Sstevel@tonic-gate * Preload (load-only, no init) all modules which 4487c478bd9Sstevel@tonic-gate * were added to the /etc/system file with the 4497c478bd9Sstevel@tonic-gate * FORCELOAD keyword. 4507c478bd9Sstevel@tonic-gate */ 4517c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: preload_module\n")); 4527c478bd9Sstevel@tonic-gate (void) mod_sysctl_type(MOD_FORCELOAD, preload_module, NULL); 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate /* ONC_PLUS EXTRACT START */ 4557c478bd9Sstevel@tonic-gate /* 4567c478bd9Sstevel@tonic-gate * If we booted otw then load in the plumbing 4577c478bd9Sstevel@tonic-gate * routine now while we still can. If we didn't 4587c478bd9Sstevel@tonic-gate * boot otw then we will load strplumb in main(). 4597c478bd9Sstevel@tonic-gate * 4607c478bd9Sstevel@tonic-gate * NFS is actually a set of modules, the core routines, 4617c478bd9Sstevel@tonic-gate * a diskless helper module, rpcmod, and the tli interface. Load 4627c478bd9Sstevel@tonic-gate * them now while we still can. 4637c478bd9Sstevel@tonic-gate * 4647c478bd9Sstevel@tonic-gate * Because we glomb all versions of nfs into a single module 4657c478bd9Sstevel@tonic-gate * we check based on the initial string "nfs". 4667c478bd9Sstevel@tonic-gate * 4677c478bd9Sstevel@tonic-gate * XXX: A better test for this is to see if device_type 4687c478bd9Sstevel@tonic-gate * XXX: from the PROM is "network". 4697c478bd9Sstevel@tonic-gate */ 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) { 4727c478bd9Sstevel@tonic-gate ++netboot; 4737c478bd9Sstevel@tonic-gate 474d62bc4baSyz147064 /* 475d62bc4baSyz147064 * Preload (load-only, no init) the dacf module. We cannot 476d62bc4baSyz147064 * init the module because one of its requisite modules is 477d62bc4baSyz147064 * dld whose _init function will call taskq_create(), which 478d62bc4baSyz147064 * will panic the system at this point. 479d62bc4baSyz147064 */ 480d62bc4baSyz147064 if ((err = modloadonly("dacf", "net_dacf")) < 0) { 481d62bc4baSyz147064 cmn_err(CE_CONT, "Cannot load dacf/net_dacf\n"); 482d62bc4baSyz147064 goto out; 483d62bc4baSyz147064 } 4847c478bd9Sstevel@tonic-gate if ((err = modload("misc", "tlimod")) < 0) { 4857c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load misc/tlimod\n"); 4867c478bd9Sstevel@tonic-gate goto out; 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate if ((err = modload("strmod", "rpcmod")) < 0) { 4897c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load strmod/rpcmod\n"); 4907c478bd9Sstevel@tonic-gate goto out; 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate if ((err = modload("misc", "nfs_dlboot")) < 0) { 4937c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load misc/nfs_dlboot\n"); 4947c478bd9Sstevel@tonic-gate goto out; 4957c478bd9Sstevel@tonic-gate } 49648aa2e6aSseb if ((err = modload("mac", "mac_ether")) < 0) { 49748aa2e6aSseb cmn_err(CE_CONT, "Cannot load mac/mac_ether\n"); 49848aa2e6aSseb goto out; 49948aa2e6aSseb } 5007c478bd9Sstevel@tonic-gate if ((err = modload("misc", "strplumb")) < 0) { 5017c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load misc/strplumb\n"); 5027c478bd9Sstevel@tonic-gate goto out; 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate if ((err = strplumb_load()) < 0) { 5057c478bd9Sstevel@tonic-gate goto out; 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate /* 5107c478bd9Sstevel@tonic-gate * Preload modules needed for booting as a cluster. 5117c478bd9Sstevel@tonic-gate */ 5127c478bd9Sstevel@tonic-gate err = clboot_loadrootmodules(); 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate out: 5157c478bd9Sstevel@tonic-gate if (err != 0 && (boothowto & RB_ASKNAME)) 5167c478bd9Sstevel@tonic-gate goto loop; 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate return (err); 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate /* ONC_PLUS EXTRACT END */ 5217c478bd9Sstevel@tonic-gate 522986fd29aSsetje static int 523986fd29aSsetje get_bootpath_prop(char *bootpath) 524986fd29aSsetje { 525986fd29aSsetje if (root_is_ramdisk) { 526986fd29aSsetje if (BOP_GETPROP(bootops, "bootarchive", bootpath) == -1) 527986fd29aSsetje return (-1); 528986fd29aSsetje (void) strlcat(bootpath, ":a", BO_MAXOBJNAME); 529986fd29aSsetje } else { 530986fd29aSsetje /* 531986fd29aSsetje * Look for the 1275 compliant name 'bootpath' first, 532986fd29aSsetje * but make certain it has a non-NULL value as well. 533986fd29aSsetje */ 534986fd29aSsetje if ((BOP_GETPROP(bootops, "bootpath", bootpath) == -1) || 535986fd29aSsetje strlen(bootpath) == 0) { 536986fd29aSsetje if (BOP_GETPROP(bootops, 537986fd29aSsetje "boot-path", bootpath) == -1) 538986fd29aSsetje return (-1); 539986fd29aSsetje } 540986fd29aSsetje } 541986fd29aSsetje return (0); 542986fd29aSsetje } 543986fd29aSsetje 544986fd29aSsetje static int 545986fd29aSsetje get_fstype_prop(char *fstype) 546986fd29aSsetje { 547986fd29aSsetje char *prop = (root_is_ramdisk) ? "archive-fstype" : "fstype"; 548986fd29aSsetje 549986fd29aSsetje return (BOP_GETPROP(bootops, prop, fstype)); 550986fd29aSsetje } 551986fd29aSsetje 5527c478bd9Sstevel@tonic-gate /* 5537c478bd9Sstevel@tonic-gate * Get the name of the root or swap filesystem type, and return 5547c478bd9Sstevel@tonic-gate * the corresponding entry in the vfs switch. 5557c478bd9Sstevel@tonic-gate * 5567c478bd9Sstevel@tonic-gate * If we're not asking the user, and we're trying to find the 5577c478bd9Sstevel@tonic-gate * root filesystem type, we ask boot for the filesystem 5587c478bd9Sstevel@tonic-gate * type that it came from and use that. Similarly, if we're 5597c478bd9Sstevel@tonic-gate * trying to find the swap filesystem, we try and derive it from 5607c478bd9Sstevel@tonic-gate * the root filesystem type. 5617c478bd9Sstevel@tonic-gate * 5627c478bd9Sstevel@tonic-gate * If we are booting via NFS we currently have these options: 5637c478bd9Sstevel@tonic-gate * nfs - dynamically choose NFS V2. V3, or V4 (default) 5647c478bd9Sstevel@tonic-gate * nfs2 - force NFS V2 5657c478bd9Sstevel@tonic-gate * nfs3 - force NFS V3 5667c478bd9Sstevel@tonic-gate * nfs4 - force NFS V4 5677c478bd9Sstevel@tonic-gate * Because we need to maintain backward compatibility with the naming 5687c478bd9Sstevel@tonic-gate * convention that the NFS V2 filesystem name is "nfs" (see vfs_conf.c) 5697c478bd9Sstevel@tonic-gate * we need to map "nfs" => "nfsdyn" and "nfs2" => "nfs". The dynamic 5707c478bd9Sstevel@tonic-gate * nfs module will map the type back to either "nfs", "nfs3", or "nfs4". 5717c478bd9Sstevel@tonic-gate * This is only for root filesystems, all other uses such as cachefs 5727c478bd9Sstevel@tonic-gate * will expect that "nfs" == NFS V2. 5737c478bd9Sstevel@tonic-gate * 5747c478bd9Sstevel@tonic-gate * If the filesystem isn't already loaded, vfs_getvfssw() will load 5757c478bd9Sstevel@tonic-gate * it for us, but if (at the time we call it) modrootloaded is 5767c478bd9Sstevel@tonic-gate * still not set, it won't run the filesystems _init routine (and 5777c478bd9Sstevel@tonic-gate * implicitly it won't run the filesystems vsw_init() entry either). 5787c478bd9Sstevel@tonic-gate * We do that explicitly in rootconf(). 5797c478bd9Sstevel@tonic-gate */ 5807c478bd9Sstevel@tonic-gate static struct vfssw * 5817c478bd9Sstevel@tonic-gate getfstype(char *askfor, char *fsname, size_t fsnamelen) 5827c478bd9Sstevel@tonic-gate { 5837c478bd9Sstevel@tonic-gate struct vfssw *vsw; 5847c478bd9Sstevel@tonic-gate static char defaultfs[BO_MAXFSNAME]; 5857c478bd9Sstevel@tonic-gate int root = 0; 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate if (strcmp(askfor, "root") == 0) { 588986fd29aSsetje (void) get_fstype_prop(defaultfs); 5897c478bd9Sstevel@tonic-gate root++; 5907c478bd9Sstevel@tonic-gate } else { 5917c478bd9Sstevel@tonic-gate (void) strcpy(defaultfs, "swapfs"); 5927c478bd9Sstevel@tonic-gate } 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate if (boothowto & RB_ASKNAME) { 5957c478bd9Sstevel@tonic-gate for (*fsname = '\0'; *fsname == '\0'; *fsname = '\0') { 5967c478bd9Sstevel@tonic-gate printf("%s filesystem type [%s]: ", askfor, defaultfs); 5977c478bd9Sstevel@tonic-gate console_gets(fsname, fsnamelen); 5987c478bd9Sstevel@tonic-gate if (*fsname == '\0') 5997c478bd9Sstevel@tonic-gate (void) strcpy(fsname, defaultfs); 6007c478bd9Sstevel@tonic-gate if (root) { 6017c478bd9Sstevel@tonic-gate if (strcmp(fsname, "nfs2") == 0) 6027c478bd9Sstevel@tonic-gate (void) strcpy(fsname, "nfs"); 6037c478bd9Sstevel@tonic-gate else if (strcmp(fsname, "nfs") == 0) 6047c478bd9Sstevel@tonic-gate (void) strcpy(fsname, "nfsdyn"); 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate if ((vsw = vfs_getvfssw(fsname)) != NULL) 6077c478bd9Sstevel@tonic-gate return (vsw); 6087c478bd9Sstevel@tonic-gate printf("Unknown filesystem type '%s'\n", fsname); 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate } else if (*fsname == '\0') { 6117c478bd9Sstevel@tonic-gate fsname = defaultfs; 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate if (*fsname == '\0') { 6147c478bd9Sstevel@tonic-gate return (NULL); 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate 6177c478bd9Sstevel@tonic-gate if (root) { 6187c478bd9Sstevel@tonic-gate if (strcmp(fsname, "nfs2") == 0) 6197c478bd9Sstevel@tonic-gate (void) strcpy(fsname, "nfs"); 6207c478bd9Sstevel@tonic-gate else if (strcmp(fsname, "nfs") == 0) 6217c478bd9Sstevel@tonic-gate (void) strcpy(fsname, "nfsdyn"); 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate return (vfs_getvfssw(fsname)); 6257c478bd9Sstevel@tonic-gate } 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate /* 6297c478bd9Sstevel@tonic-gate * Get a physical device name, and maybe load and attach 6307c478bd9Sstevel@tonic-gate * the driver. 6317c478bd9Sstevel@tonic-gate * 6327c478bd9Sstevel@tonic-gate * XXX Need better checking of whether or not a device 6337c478bd9Sstevel@tonic-gate * actually exists if the user typed in a pathname. 6347c478bd9Sstevel@tonic-gate * 6357c478bd9Sstevel@tonic-gate * XXX Are we sure we want to expose users to this sort 6367c478bd9Sstevel@tonic-gate * of physical namespace gobbledygook (now there's 6377c478bd9Sstevel@tonic-gate * a word to conjure with..) 6387c478bd9Sstevel@tonic-gate * 6397c478bd9Sstevel@tonic-gate * XXX Note that on an OBP machine, we can easily ask the 6407c478bd9Sstevel@tonic-gate * prom and pretty-print some plausible set of bootable 6417c478bd9Sstevel@tonic-gate * devices. We can also user the prom to verify any 6427c478bd9Sstevel@tonic-gate * such device. Later tim.. later. 6437c478bd9Sstevel@tonic-gate */ 6447c478bd9Sstevel@tonic-gate static int 6457c478bd9Sstevel@tonic-gate getphysdev(char *askfor, char *name, size_t namelen) 6467c478bd9Sstevel@tonic-gate { 6477c478bd9Sstevel@tonic-gate static char fmt[] = "Enter physical name of %s device\n[%s]: "; 6487c478bd9Sstevel@tonic-gate dev_t dev; 6497c478bd9Sstevel@tonic-gate static char defaultpath[BO_MAXOBJNAME]; 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate /* 6527c478bd9Sstevel@tonic-gate * Establish 'default' values - we get the root device from 6537c478bd9Sstevel@tonic-gate * boot, and we infer the swap device is the same but with 6547c478bd9Sstevel@tonic-gate * a 'b' on the end instead of an 'a'. A first stab at 6557c478bd9Sstevel@tonic-gate * ease-of-use .. 6567c478bd9Sstevel@tonic-gate */ 6577c478bd9Sstevel@tonic-gate if (strcmp(askfor, "root") == 0) { 658986fd29aSsetje if (get_bootpath_prop(defaultpath) == -1) 6597c478bd9Sstevel@tonic-gate boothowto |= RB_ASKNAME | RB_VERBOSE; 6607c478bd9Sstevel@tonic-gate } else { 6617c478bd9Sstevel@tonic-gate (void) strcpy(defaultpath, rootfs.bo_name); 6627c478bd9Sstevel@tonic-gate defaultpath[strlen(defaultpath) - 1] = 'b'; 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate retry: 6667c478bd9Sstevel@tonic-gate if (boothowto & RB_ASKNAME) { 6677c478bd9Sstevel@tonic-gate printf(fmt, askfor, defaultpath); 6687c478bd9Sstevel@tonic-gate console_gets(name, namelen); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate if (*name == '\0') 6717c478bd9Sstevel@tonic-gate (void) strcpy(name, defaultpath); 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate if (strcmp(askfor, "swap") == 0) { 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate /* 6767c478bd9Sstevel@tonic-gate * Try to load and install the swap device driver. 6777c478bd9Sstevel@tonic-gate */ 6787c478bd9Sstevel@tonic-gate dev = ddi_pathname_to_dev_t(name); 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate if (dev == (dev_t)-1) { 6817c478bd9Sstevel@tonic-gate printf("Not a supported device for swap.\n"); 6827c478bd9Sstevel@tonic-gate boothowto |= RB_ASKNAME | RB_VERBOSE; 6837c478bd9Sstevel@tonic-gate goto retry; 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate /* 6877c478bd9Sstevel@tonic-gate * Ensure that we're not trying to swap on the floppy. 6887c478bd9Sstevel@tonic-gate */ 6897c478bd9Sstevel@tonic-gate if (strncmp(ddi_major_to_name(getmajor(dev)), "fd", 2) == 0) { 6907c478bd9Sstevel@tonic-gate printf("Too dangerous to swap on the floppy\n"); 6917c478bd9Sstevel@tonic-gate if (boothowto & RB_ASKNAME) 6927c478bd9Sstevel@tonic-gate goto retry; 6937c478bd9Sstevel@tonic-gate return (-1); 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate } 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate return (0); 6987c478bd9Sstevel@tonic-gate } 6997c478bd9Sstevel@tonic-gate 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate /* 7027c478bd9Sstevel@tonic-gate * Load a driver needed to boot. 7037c478bd9Sstevel@tonic-gate */ 7047c478bd9Sstevel@tonic-gate static int 7057c478bd9Sstevel@tonic-gate load_boot_driver(char *drv) 7067c478bd9Sstevel@tonic-gate { 7077c478bd9Sstevel@tonic-gate char *drvname; 7087c478bd9Sstevel@tonic-gate major_t major; 7091e1ddd6cScth #ifdef sparc 7101e1ddd6cScth struct devnames *dnp; 7111e1ddd6cScth ddi_prop_t *propp; 7121e1ddd6cScth char *module; 7131e1ddd6cScth char *dir, *mf; 7141e1ddd6cScth int plen; 7151e1ddd6cScth int mlen; 7161e1ddd6cScth #endif /* sparc */ 7177c478bd9Sstevel@tonic-gate 7187c478bd9Sstevel@tonic-gate if ((major = ddi_name_to_major(drv)) == (major_t)-1) { 7197c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "%s: no major number\n", drv); 7207c478bd9Sstevel@tonic-gate return (-1); 7217c478bd9Sstevel@tonic-gate } 7227c478bd9Sstevel@tonic-gate /* 7237c478bd9Sstevel@tonic-gate * resolve aliases 7247c478bd9Sstevel@tonic-gate */ 7257c478bd9Sstevel@tonic-gate drvname = ddi_major_to_name(major); 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate #ifdef DEBUG 7287c478bd9Sstevel@tonic-gate if (strcmp(drv, drvname) == 0) { 7297c478bd9Sstevel@tonic-gate BMDPRINTF(("load_boot_driver: %s\n", drv)); 7307c478bd9Sstevel@tonic-gate } else { 7317c478bd9Sstevel@tonic-gate BMDPRINTF(("load_boot_driver: %s -> %s\n", drv, drvname)); 7327c478bd9Sstevel@tonic-gate } 7337c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate if (modloadonly("drv", drvname) == -1) { 7367c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "%s: cannot load driver\n", drvname); 7377c478bd9Sstevel@tonic-gate return (-1); 7387c478bd9Sstevel@tonic-gate } 7397c478bd9Sstevel@tonic-gate 7401e1ddd6cScth #ifdef sparc 7411e1ddd6cScth /* 7421e1ddd6cScth * NOTE: this can be removed when newboot-sparc is delivered. 7431e1ddd6cScth * 7441e1ddd6cScth * Check to see if the driver had a 'ddi-forceload' global driver.conf 7451e1ddd6cScth * property to identify additional modules that need to be loaded. 7461e1ddd6cScth * The driver still needs to use ddi_modopen() to open these modules, 7471e1ddd6cScth * but the 'ddi-forceload' property allows the modules to be loaded 7481e1ddd6cScth * into memory prior to lights-out, so that driver ddi_modopen() 7491e1ddd6cScth * calls during lights-out (when mounting root) will work correctly. 7501e1ddd6cScth * Use of 'ddi-forceload' is only required for drivers involved in 7511e1ddd6cScth * getting root mounted. 7521e1ddd6cScth */ 7531e1ddd6cScth dnp = &devnamesp[major]; 7541e1ddd6cScth if (dnp->dn_global_prop_ptr && dnp->dn_global_prop_ptr->prop_list && 7551e1ddd6cScth ((propp = i_ddi_prop_search(DDI_DEV_T_ANY, 7561e1ddd6cScth "ddi-forceload", DDI_PROP_TYPE_STRING, 7571e1ddd6cScth &dnp->dn_global_prop_ptr->prop_list)) != NULL)) { 7581e1ddd6cScth 7591e1ddd6cScth module = (char *)propp->prop_val; 7601e1ddd6cScth plen = propp->prop_len; 7611e1ddd6cScth while (plen > 0) { 7621e1ddd6cScth mlen = strlen(module); 7631e1ddd6cScth mf = strrchr(module, '/'); 7641e1ddd6cScth if (mf) { 7651e1ddd6cScth dir = module; 7661e1ddd6cScth *mf++ = '\0'; /* '/' -> '\0' */ 7671e1ddd6cScth } else { 7681e1ddd6cScth dir = "misc"; 7691e1ddd6cScth mf = module; 7701e1ddd6cScth } 7711e1ddd6cScth if (modloadonly(dir, mf) == -1) 7721e1ddd6cScth cmn_err(CE_CONT, 7731e1ddd6cScth "misc/%s: can't load module\n", mf); 7741e1ddd6cScth if (mf != module) 7751e1ddd6cScth *(mf - 1) = '/'; /* '\0' -> '/' */ 7761e1ddd6cScth 7771e1ddd6cScth module += mlen + 1; 7781e1ddd6cScth plen -= mlen + 1; 7791e1ddd6cScth } 7801e1ddd6cScth } 7811e1ddd6cScth #endif /* sparc */ 7821e1ddd6cScth 7837c478bd9Sstevel@tonic-gate return (0); 7847c478bd9Sstevel@tonic-gate } 7857c478bd9Sstevel@tonic-gate 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gate /* 7887c478bd9Sstevel@tonic-gate * For a given instance, load that driver and its parents 7897c478bd9Sstevel@tonic-gate */ 7907c478bd9Sstevel@tonic-gate static int 791f4da9be0Scth load_parent_drivers(dev_info_t *dip, char *path) 7927c478bd9Sstevel@tonic-gate { 7937c478bd9Sstevel@tonic-gate int rval = 0; 794f4da9be0Scth major_t major = (major_t)-1; 7957c478bd9Sstevel@tonic-gate char *drv; 796f4da9be0Scth char *p; 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate while (dip) { 799f4da9be0Scth /* check for path-oriented alias */ 800f4da9be0Scth if (path) 801f4da9be0Scth major = ddi_name_to_major(path); 802f4da9be0Scth else 803f4da9be0Scth major = (major_t)-1; 804f4da9be0Scth 805f4da9be0Scth if (major != (major_t)-1) 806f4da9be0Scth drv = ddi_major_to_name(major); 807f4da9be0Scth else 808f4da9be0Scth drv = ddi_binding_name(dip); 809f4da9be0Scth 8107c478bd9Sstevel@tonic-gate if (load_boot_driver(drv) != 0) 8117c478bd9Sstevel@tonic-gate rval = -1; 812f4da9be0Scth 8137c478bd9Sstevel@tonic-gate dip = ddi_get_parent(dip); 814f4da9be0Scth if (path) { 815f4da9be0Scth p = strrchr(path, '/'); 816f4da9be0Scth if (p) 817f4da9be0Scth *p = 0; 818f4da9be0Scth } 8197c478bd9Sstevel@tonic-gate } 8207c478bd9Sstevel@tonic-gate 8217c478bd9Sstevel@tonic-gate return (rval); 8227c478bd9Sstevel@tonic-gate } 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate /* 8267c478bd9Sstevel@tonic-gate * For a given path to a boot device, 8277c478bd9Sstevel@tonic-gate * load that driver and all its parents. 8287c478bd9Sstevel@tonic-gate */ 8297c478bd9Sstevel@tonic-gate static int 8307c478bd9Sstevel@tonic-gate load_bootpath_drivers(char *bootpath) 8317c478bd9Sstevel@tonic-gate { 8327c478bd9Sstevel@tonic-gate dev_info_t *dip; 833f4da9be0Scth char *pathcopy; 834f4da9be0Scth int pathcopy_len; 835f4da9be0Scth int rval; 836f4da9be0Scth char *p; 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate if (bootpath == NULL || *bootpath == 0) 8397c478bd9Sstevel@tonic-gate return (-1); 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate BMDPRINTF(("load_bootpath_drivers: %s\n", bootpath)); 8427c478bd9Sstevel@tonic-gate 843f4da9be0Scth pathcopy = i_ddi_strdup(bootpath, KM_SLEEP); 844f4da9be0Scth pathcopy_len = strlen(pathcopy) + 1; 845f4da9be0Scth 846f4da9be0Scth dip = path_to_devinfo(pathcopy); 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 8497c478bd9Sstevel@tonic-gate /* 8507c478bd9Sstevel@tonic-gate * i386 does not provide stub nodes for all boot devices, 8517c478bd9Sstevel@tonic-gate * but we should be able to find the node for the parent, 8527c478bd9Sstevel@tonic-gate * and the leaf of the boot path should be the driver name, 8537c478bd9Sstevel@tonic-gate * which we go ahead and load here. 8547c478bd9Sstevel@tonic-gate */ 8557c478bd9Sstevel@tonic-gate if (dip == NULL) { 856f4da9be0Scth char *leaf; 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate /* 859f4da9be0Scth * Find last slash to build the full path to the 860f4da9be0Scth * parent of the leaf boot device 8617c478bd9Sstevel@tonic-gate */ 862f4da9be0Scth p = strrchr(pathcopy, '/'); 8637c478bd9Sstevel@tonic-gate *p++ = 0; 8647c478bd9Sstevel@tonic-gate 8657c478bd9Sstevel@tonic-gate /* 8667c478bd9Sstevel@tonic-gate * Now isolate the driver name of the leaf device 8677c478bd9Sstevel@tonic-gate */ 868f4da9be0Scth leaf = p; 869f4da9be0Scth p = strchr(leaf, '@'); 8707c478bd9Sstevel@tonic-gate *p = 0; 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate BMDPRINTF(("load_bootpath_drivers: parent=%s leaf=%s\n", 873f4da9be0Scth bootpath, leaf)); 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate dip = path_to_devinfo(pathcopy); 876f4da9be0Scth if (leaf) { 877f4da9be0Scth rval = load_boot_driver(leaf, NULL); 878f4da9be0Scth if (rval == -1) { 879f4da9be0Scth kmem_free(pathcopy, pathcopy_len); 8807c478bd9Sstevel@tonic-gate return (NULL); 881f4da9be0Scth } 882f4da9be0Scth } 8837c478bd9Sstevel@tonic-gate } 8847c478bd9Sstevel@tonic-gate #endif 8857c478bd9Sstevel@tonic-gate 8867c478bd9Sstevel@tonic-gate if (dip == NULL) { 8877c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "can't bind driver for boot path <%s>", 8887c478bd9Sstevel@tonic-gate bootpath); 889f4da9be0Scth kmem_free(pathcopy, pathcopy_len); 8907c478bd9Sstevel@tonic-gate return (NULL); 8917c478bd9Sstevel@tonic-gate } 8927c478bd9Sstevel@tonic-gate 8937c478bd9Sstevel@tonic-gate /* 8947c478bd9Sstevel@tonic-gate * Load IP over IB driver when netbooting over IB. 8957c478bd9Sstevel@tonic-gate * As per IB 1275 binding, IP over IB is represented as 8967c478bd9Sstevel@tonic-gate * service on the top of the HCA node. So, there is no 8977c478bd9Sstevel@tonic-gate * PROM node and generic framework cannot pre-load 8987c478bd9Sstevel@tonic-gate * IP over IB driver based on the bootpath. The following 8997c478bd9Sstevel@tonic-gate * code preloads IP over IB driver when doing netboot over 9007c478bd9Sstevel@tonic-gate * InfiniBand. 9017c478bd9Sstevel@tonic-gate */ 9027c478bd9Sstevel@tonic-gate if (netboot_over_ib(bootpath) && 9037c478bd9Sstevel@tonic-gate modloadonly("drv", "ibd") == -1) { 9047c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "ibd: cannot load platform driver\n"); 905f4da9be0Scth kmem_free(pathcopy, pathcopy_len); 9067c478bd9Sstevel@tonic-gate return (NULL); 9077c478bd9Sstevel@tonic-gate } 9087c478bd9Sstevel@tonic-gate 909*c29cc384Svikram /* 910*c29cc384Svikram * The PROM node for hubs have incomplete compatible 911*c29cc384Svikram * properties and therefore do not bind to the hubd driver. 912*c29cc384Svikram * As a result load_bootpath_drivers() loads the usb_mid driver 913*c29cc384Svikram * for hub nodes rather than the hubd driver. This causes 914*c29cc384Svikram * mountroot failures when booting off USB storage. To prevent 915*c29cc384Svikram * this, if we are booting via USB hubs, we preload the hubd driver. 916*c29cc384Svikram */ 917*c29cc384Svikram if (strstr(bootpath, "/hub@") && modloadonly("drv", "hubd") == -1) { 918*c29cc384Svikram cmn_err(CE_WARN, "bootpath contains a USB hub, " 919*c29cc384Svikram "but cannot load hubd driver"); 920*c29cc384Svikram } 921*c29cc384Svikram 922f4da9be0Scth /* get rid of minor node at end of copy (if not already done above) */ 923f4da9be0Scth p = strrchr(pathcopy, '/'); 924f4da9be0Scth if (p) { 925f4da9be0Scth p = strchr(p, ':'); 926f4da9be0Scth if (p) 927f4da9be0Scth *p = 0; 928f4da9be0Scth } 929f4da9be0Scth 930f4da9be0Scth rval = load_parent_drivers(dip, pathcopy); 931f4da9be0Scth kmem_free(pathcopy, pathcopy_len); 932f4da9be0Scth return (rval); 9337c478bd9Sstevel@tonic-gate } 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate /* 9397c478bd9Sstevel@tonic-gate * Load drivers required for a platform 9407c478bd9Sstevel@tonic-gate * Since all hardware nodes should be available in the device 9417c478bd9Sstevel@tonic-gate * tree, walk the per-driver list and load the parents of 9427c478bd9Sstevel@tonic-gate * each node found. If not a hardware node, try to load it. 9437c478bd9Sstevel@tonic-gate * Pseudo nexus is already loaded. 9447c478bd9Sstevel@tonic-gate */ 9457c478bd9Sstevel@tonic-gate static int 9467c478bd9Sstevel@tonic-gate load_boot_platform_modules(char *drv) 9477c478bd9Sstevel@tonic-gate { 9487c478bd9Sstevel@tonic-gate major_t major; 9497c478bd9Sstevel@tonic-gate dev_info_t *dip; 9507c478bd9Sstevel@tonic-gate char *drvname; 9517c478bd9Sstevel@tonic-gate int rval = 0; 9527c478bd9Sstevel@tonic-gate 9537c478bd9Sstevel@tonic-gate if ((major = ddi_name_to_major(drv)) == (major_t)-1) { 9547c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "%s: no major number\n", drv); 9557c478bd9Sstevel@tonic-gate return (-1); 9567c478bd9Sstevel@tonic-gate } 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate /* 9597c478bd9Sstevel@tonic-gate * resolve aliases 9607c478bd9Sstevel@tonic-gate */ 9617c478bd9Sstevel@tonic-gate drvname = ddi_major_to_name(major); 9627c478bd9Sstevel@tonic-gate if ((major = ddi_name_to_major(drvname)) == (major_t)-1) 9637c478bd9Sstevel@tonic-gate return (-1); 9647c478bd9Sstevel@tonic-gate 9657c478bd9Sstevel@tonic-gate #ifdef DEBUG 9667c478bd9Sstevel@tonic-gate if (strcmp(drv, drvname) == 0) { 9677c478bd9Sstevel@tonic-gate BMDPRINTF(("load_boot_platform_modules: %s\n", drv)); 9687c478bd9Sstevel@tonic-gate } else { 9697c478bd9Sstevel@tonic-gate BMDPRINTF(("load_boot_platform_modules: %s -> %s\n", 9707c478bd9Sstevel@tonic-gate drv, drvname)); 9717c478bd9Sstevel@tonic-gate } 9727c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 9737c478bd9Sstevel@tonic-gate 9747c478bd9Sstevel@tonic-gate dip = devnamesp[major].dn_head; 9757c478bd9Sstevel@tonic-gate if (dip == NULL) { 9767c478bd9Sstevel@tonic-gate /* pseudo node, not-enumerated, needs to be loaded */ 9777c478bd9Sstevel@tonic-gate if (modloadonly("drv", drvname) == -1) { 9787c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "%s: cannot load platform driver\n", 9797c478bd9Sstevel@tonic-gate drvname); 9807c478bd9Sstevel@tonic-gate rval = -1; 9817c478bd9Sstevel@tonic-gate } 9827c478bd9Sstevel@tonic-gate } else { 9837c478bd9Sstevel@tonic-gate while (dip) { 984f4da9be0Scth if (load_parent_drivers(dip, NULL) != 0) 9857c478bd9Sstevel@tonic-gate rval = -1; 9867c478bd9Sstevel@tonic-gate dip = ddi_get_next(dip); 9877c478bd9Sstevel@tonic-gate } 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate return (rval); 9917c478bd9Sstevel@tonic-gate } 9927c478bd9Sstevel@tonic-gate 9937c478bd9Sstevel@tonic-gate 9947c478bd9Sstevel@tonic-gate /* 9957c478bd9Sstevel@tonic-gate * i_find_node: Internal routine used by path_to_devinfo 9967c478bd9Sstevel@tonic-gate * to locate a given nodeid in the device tree. 9977c478bd9Sstevel@tonic-gate */ 9987c478bd9Sstevel@tonic-gate struct i_path_findnode { 999fa9e4066Sahrens pnode_t nodeid; 10007c478bd9Sstevel@tonic-gate dev_info_t *dip; 10017c478bd9Sstevel@tonic-gate }; 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate static int 10047c478bd9Sstevel@tonic-gate i_path_find_node(dev_info_t *dev, void *arg) 10057c478bd9Sstevel@tonic-gate { 10067c478bd9Sstevel@tonic-gate struct i_path_findnode *f = (struct i_path_findnode *)arg; 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate 10097c478bd9Sstevel@tonic-gate if (ddi_get_nodeid(dev) == (int)f->nodeid) { 10107c478bd9Sstevel@tonic-gate f->dip = dev; 10117c478bd9Sstevel@tonic-gate return (DDI_WALK_TERMINATE); 10127c478bd9Sstevel@tonic-gate } 10137c478bd9Sstevel@tonic-gate return (DDI_WALK_CONTINUE); 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate /* 10177c478bd9Sstevel@tonic-gate * Return the devinfo node to a boot device 10187c478bd9Sstevel@tonic-gate */ 10197c478bd9Sstevel@tonic-gate static dev_info_t * 10207c478bd9Sstevel@tonic-gate path_to_devinfo(char *path) 10217c478bd9Sstevel@tonic-gate { 10227c478bd9Sstevel@tonic-gate struct i_path_findnode fn; 10237c478bd9Sstevel@tonic-gate extern dev_info_t *top_devinfo; 10247c478bd9Sstevel@tonic-gate 10257c478bd9Sstevel@tonic-gate /* 10267c478bd9Sstevel@tonic-gate * Get the nodeid of the given pathname, if such a mapping exists. 10277c478bd9Sstevel@tonic-gate */ 10287c478bd9Sstevel@tonic-gate fn.dip = NULL; 10297c478bd9Sstevel@tonic-gate fn.nodeid = prom_finddevice(path); 10307c478bd9Sstevel@tonic-gate if (fn.nodeid != OBP_BADNODE) { 10317c478bd9Sstevel@tonic-gate /* 10327c478bd9Sstevel@tonic-gate * Find the nodeid in our copy of the device tree and return 10337c478bd9Sstevel@tonic-gate * whatever name we used to bind this node to a driver. 10347c478bd9Sstevel@tonic-gate */ 10357c478bd9Sstevel@tonic-gate ddi_walk_devs(top_devinfo, i_path_find_node, (void *)(&fn)); 10367c478bd9Sstevel@tonic-gate } 10377c478bd9Sstevel@tonic-gate 10387c478bd9Sstevel@tonic-gate #ifdef DEBUG 10397c478bd9Sstevel@tonic-gate /* 10407c478bd9Sstevel@tonic-gate * If we're bound to something other than the nodename, 10417c478bd9Sstevel@tonic-gate * note that in the message buffer and system log. 10427c478bd9Sstevel@tonic-gate */ 10437c478bd9Sstevel@tonic-gate if (fn.dip) { 10447c478bd9Sstevel@tonic-gate char *p, *q; 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate p = ddi_binding_name(fn.dip); 10477c478bd9Sstevel@tonic-gate q = ddi_node_name(fn.dip); 10487c478bd9Sstevel@tonic-gate if (p && q && (strcmp(p, q) != 0)) { 10497c478bd9Sstevel@tonic-gate BMDPRINTF(("path_to_devinfo: %s bound to %s\n", 10507c478bd9Sstevel@tonic-gate path, p)); 10517c478bd9Sstevel@tonic-gate } 10527c478bd9Sstevel@tonic-gate } 10537c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 10547c478bd9Sstevel@tonic-gate 10557c478bd9Sstevel@tonic-gate return (fn.dip); 10567c478bd9Sstevel@tonic-gate } 10577c478bd9Sstevel@tonic-gate 10587c478bd9Sstevel@tonic-gate /* 10597c478bd9Sstevel@tonic-gate * This routine returns B_TRUE if the bootpath corresponds to 10607c478bd9Sstevel@tonic-gate * IP over IB driver. 10617c478bd9Sstevel@tonic-gate * 10627c478bd9Sstevel@tonic-gate * The format of the bootpath for the IP over IB looks like 10637c478bd9Sstevel@tonic-gate * /pci@1f,700000/pci@1/ib@0:port=1,pkey=8001,protocol=ip 10647c478bd9Sstevel@tonic-gate * 10657c478bd9Sstevel@tonic-gate * The minor node portion "port=1,pkey=8001,protocol=ip" represents 10667c478bd9Sstevel@tonic-gate * IP over IB driver. 10677c478bd9Sstevel@tonic-gate */ 10687c478bd9Sstevel@tonic-gate static boolean_t 10697c478bd9Sstevel@tonic-gate netboot_over_ib(char *bootpath) 10707c478bd9Sstevel@tonic-gate { 10717c478bd9Sstevel@tonic-gate 10727c478bd9Sstevel@tonic-gate char *temp; 10737c478bd9Sstevel@tonic-gate boolean_t ret = B_FALSE; 1074fa9e4066Sahrens pnode_t node = prom_finddevice(bootpath); 10757c478bd9Sstevel@tonic-gate int len; 10767c478bd9Sstevel@tonic-gate char devicetype[OBP_MAXDRVNAME]; 10777c478bd9Sstevel@tonic-gate 10787c478bd9Sstevel@tonic-gate /* Is this IB node ? */ 10797c478bd9Sstevel@tonic-gate len = prom_getproplen(node, OBP_DEVICETYPE); 10807c478bd9Sstevel@tonic-gate if (len <= 1 || len >= OBP_MAXDRVNAME) 10817c478bd9Sstevel@tonic-gate return (B_FALSE); 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate (void) prom_getprop(node, OBP_DEVICETYPE, (caddr_t)devicetype); 10847c478bd9Sstevel@tonic-gate 10857c478bd9Sstevel@tonic-gate if (strncmp("ib", devicetype, 2) == 0) { 10867c478bd9Sstevel@tonic-gate /* Check for proper IP over IB string */ 10877c478bd9Sstevel@tonic-gate if ((temp = strstr(bootpath, ":port=")) != NULL) { 10887c478bd9Sstevel@tonic-gate if ((temp = strstr(temp, ",pkey=")) != NULL) 10897c478bd9Sstevel@tonic-gate if ((temp = strstr(temp, 10907c478bd9Sstevel@tonic-gate ",protocol=ip")) != NULL) { 10917c478bd9Sstevel@tonic-gate ret = B_TRUE; 10927c478bd9Sstevel@tonic-gate } 10937c478bd9Sstevel@tonic-gate } 10947c478bd9Sstevel@tonic-gate } 10957c478bd9Sstevel@tonic-gate return (ret); 10967c478bd9Sstevel@tonic-gate } 1097