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 */ 21*e373b6e4SYuri Pankov 227c478bd9Sstevel@tonic-gate /* 231cfa752fSRamaswamy Tummala * Copyright (c) 1982, 2010, Oracle and/or its affiliates. All rights reserved. 24*e373b6e4SYuri Pankov * Copyright 2016 Nexenta Systems, Inc. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* 287c478bd9Sstevel@tonic-gate * Configure root, swap and dump devices. 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include <sys/types.h> 327c478bd9Sstevel@tonic-gate #include <sys/param.h> 337c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 347c478bd9Sstevel@tonic-gate #include <sys/signal.h> 357c478bd9Sstevel@tonic-gate #include <sys/cred.h> 367c478bd9Sstevel@tonic-gate #include <sys/proc.h> 377c478bd9Sstevel@tonic-gate #include <sys/user.h> 387c478bd9Sstevel@tonic-gate #include <sys/conf.h> 397c478bd9Sstevel@tonic-gate #include <sys/buf.h> 407c478bd9Sstevel@tonic-gate #include <sys/systm.h> 417c478bd9Sstevel@tonic-gate #include <sys/vm.h> 427c478bd9Sstevel@tonic-gate #include <sys/reboot.h> 437c478bd9Sstevel@tonic-gate #include <sys/file.h> 447c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 457c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 467c478bd9Sstevel@tonic-gate #include <sys/errno.h> 477c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 487c478bd9Sstevel@tonic-gate #include <sys/uio.h> 497c478bd9Sstevel@tonic-gate #include <sys/open.h> 507c478bd9Sstevel@tonic-gate #include <sys/mount.h> 517c478bd9Sstevel@tonic-gate #include <sys/kobj.h> 527c478bd9Sstevel@tonic-gate #include <sys/bootconf.h> 537c478bd9Sstevel@tonic-gate #include <sys/sysconf.h> 547c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 557c478bd9Sstevel@tonic-gate #include <sys/autoconf.h> 567c478bd9Sstevel@tonic-gate #include <sys/debug.h> 577c478bd9Sstevel@tonic-gate #include <sys/fs/snode.h> 587c478bd9Sstevel@tonic-gate #include <fs/fs_subr.h> 597c478bd9Sstevel@tonic-gate #include <sys/socket.h> 607c478bd9Sstevel@tonic-gate #include <net/if.h> 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate #include <sys/mkdev.h> 637c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 647c478bd9Sstevel@tonic-gate #include <sys/console.h> 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate #include <sys/conf.h> 677c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 687c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 697c478bd9Sstevel@tonic-gate #include <sys/hwconf.h> 707c478bd9Sstevel@tonic-gate #include <sys/dc_ki.h> 717c478bd9Sstevel@tonic-gate #include <sys/promif.h> 72dedec472SJack Meng #include <sys/bootprops.h> 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate /* 757c478bd9Sstevel@tonic-gate * Local routines 767c478bd9Sstevel@tonic-gate */ 777c478bd9Sstevel@tonic-gate static int preload_module(struct sysparam *, void *); 787c478bd9Sstevel@tonic-gate static struct vfssw *getfstype(char *, char *, size_t); 797c478bd9Sstevel@tonic-gate static int getphysdev(char *, char *, size_t); 807c478bd9Sstevel@tonic-gate static int load_bootpath_drivers(char *bootpath); 817c478bd9Sstevel@tonic-gate static int load_boot_driver(char *drv); 827c478bd9Sstevel@tonic-gate static int load_boot_platform_modules(char *drv); 837c478bd9Sstevel@tonic-gate static dev_info_t *path_to_devinfo(char *path); 847c478bd9Sstevel@tonic-gate static boolean_t netboot_over_ib(char *bootpath); 85dedec472SJack Meng static boolean_t netboot_over_iscsi(void); 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate /* 887c478bd9Sstevel@tonic-gate * Module linkage information for the kernel. 897c478bd9Sstevel@tonic-gate */ 907c478bd9Sstevel@tonic-gate static struct modlmisc modlmisc = { 91986fd29aSsetje &mod_miscops, "root and swap configuration" 927c478bd9Sstevel@tonic-gate }; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = { 957c478bd9Sstevel@tonic-gate MODREV_1, (void *)&modlmisc, NULL 967c478bd9Sstevel@tonic-gate }; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate int 997c478bd9Sstevel@tonic-gate _init(void) 1007c478bd9Sstevel@tonic-gate { 1017c478bd9Sstevel@tonic-gate return (mod_install(&modlinkage)); 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate int 1057c478bd9Sstevel@tonic-gate _fini(void) 1067c478bd9Sstevel@tonic-gate { 1077c478bd9Sstevel@tonic-gate return (mod_remove(&modlinkage)); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate int 1117c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop) 1127c478bd9Sstevel@tonic-gate { 1137c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 116dedec472SJack Meng extern ib_boot_prop_t *iscsiboot_prop; 1177c478bd9Sstevel@tonic-gate /* 1187c478bd9Sstevel@tonic-gate * Configure root file system. 1197c478bd9Sstevel@tonic-gate */ 1207c478bd9Sstevel@tonic-gate int 1217c478bd9Sstevel@tonic-gate rootconf(void) 1227c478bd9Sstevel@tonic-gate { 1237c478bd9Sstevel@tonic-gate int error; 1247c478bd9Sstevel@tonic-gate struct vfssw *vsw; 1257c478bd9Sstevel@tonic-gate extern void pm_init(void); 126dedec472SJack Meng int ret = -1; 1277c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: fstype %s\n", rootfs.bo_fstype)); 1287c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: name %s\n", rootfs.bo_name)); 1297c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: flags 0x%x\n", rootfs.bo_flags)); 1307c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: obp_bootpath %s\n", obp_bootpath)); 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate /* 1337c478bd9Sstevel@tonic-gate * Install cluster modules that were only loaded during 1347c478bd9Sstevel@tonic-gate * loadrootmodules(). 1357c478bd9Sstevel@tonic-gate */ 1367c478bd9Sstevel@tonic-gate if (error = clboot_rootconf()) 1377c478bd9Sstevel@tonic-gate return (error); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* 1407c478bd9Sstevel@tonic-gate * Run _init on the root filesystem (we already loaded it 1417c478bd9Sstevel@tonic-gate * but we've been waiting until now to _init it) which will 1427c478bd9Sstevel@tonic-gate * have the side-effect of running vsw_init() on this vfs. 1437c478bd9Sstevel@tonic-gate * Because all the nfs filesystems are lumped into one 1447c478bd9Sstevel@tonic-gate * module we need to special case it. 1457c478bd9Sstevel@tonic-gate */ 1467c478bd9Sstevel@tonic-gate if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) { 1477c478bd9Sstevel@tonic-gate if (modload("fs", "nfs") == -1) { 1487c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot initialize %s filesystem\n", 1497c478bd9Sstevel@tonic-gate rootfs.bo_fstype); 1507c478bd9Sstevel@tonic-gate return (ENXIO); 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate } else { 1537c478bd9Sstevel@tonic-gate if (modload("fs", rootfs.bo_fstype) == -1) { 1547c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot initialize %s filesystem\n", 1557c478bd9Sstevel@tonic-gate rootfs.bo_fstype); 1567c478bd9Sstevel@tonic-gate return (ENXIO); 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate RLOCK_VFSSW(); 1607c478bd9Sstevel@tonic-gate vsw = vfs_getvfsswbyname(rootfs.bo_fstype); 1617c478bd9Sstevel@tonic-gate RUNLOCK_VFSSW(); 16256c0b1daSPavel Filipensky if (vsw == NULL) { 16356c0b1daSPavel Filipensky cmn_err(CE_CONT, "Cannot find %s filesystem\n", 16456c0b1daSPavel Filipensky rootfs.bo_fstype); 16556c0b1daSPavel Filipensky return (ENXIO); 16656c0b1daSPavel Filipensky } 1677c478bd9Sstevel@tonic-gate VFS_INIT(rootvfs, &vsw->vsw_vfsops, (caddr_t)0); 1687c478bd9Sstevel@tonic-gate VFS_HOLD(rootvfs); 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* 1717c478bd9Sstevel@tonic-gate * This pm-releated call has to occur before root is mounted since we 1727c478bd9Sstevel@tonic-gate * need to power up all devices. It is placed after VFS_INIT() such 1737c478bd9Sstevel@tonic-gate * that opening a device via ddi_lyr_ interface just before root has 1747c478bd9Sstevel@tonic-gate * been mounted would work. 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate pm_init(); 1777c478bd9Sstevel@tonic-gate 178dedec472SJack Meng if (netboot && iscsiboot_prop) { 179dedec472SJack Meng cmn_err(CE_WARN, "NFS boot and iSCSI boot" 180dedec472SJack Meng " shouldn't happen in the same time"); 181dedec472SJack Meng return (EINVAL); 182dedec472SJack Meng } 183dedec472SJack Meng 184dedec472SJack Meng if (netboot || iscsiboot_prop) { 185dedec472SJack Meng ret = strplumb(); 186dedec472SJack Meng if (ret != 0) { 187dedec472SJack Meng cmn_err(CE_WARN, "Cannot plumb network device %d", ret); 188dedec472SJack Meng return (EFAULT); 189dedec472SJack Meng } 190dedec472SJack Meng } 191dedec472SJack Meng 192dedec472SJack Meng if ((ret == 0) && iscsiboot_prop) { 193dedec472SJack Meng ret = modload("drv", "iscsi"); 194dedec472SJack Meng /* -1 indicates fail */ 195dedec472SJack Meng if (ret == -1) { 196dedec472SJack Meng cmn_err(CE_WARN, "Failed to load iscsi module"); 197dedec472SJack Meng iscsi_boot_prop_free(); 198dedec472SJack Meng return (EINVAL); 199dedec472SJack Meng } else { 200dedec472SJack Meng if (!i_ddi_attach_pseudo_node("iscsi")) { 201dedec472SJack Meng cmn_err(CE_WARN, 202dedec472SJack Meng "Failed to attach iscsi driver"); 203dedec472SJack Meng iscsi_boot_prop_free(); 204dedec472SJack Meng return (ENODEV); 205dedec472SJack Meng } 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /* 2107c478bd9Sstevel@tonic-gate * ufs_mountroot() ends up calling getrootdev() 2117c478bd9Sstevel@tonic-gate * (below) which actually triggers the _init, identify, 2127c478bd9Sstevel@tonic-gate * probe and attach of the drivers that make up root device 2137c478bd9Sstevel@tonic-gate * bush; these are also quietly waiting in memory. 2147c478bd9Sstevel@tonic-gate */ 2157c478bd9Sstevel@tonic-gate BMDPRINTF(("rootconf: calling VFS_MOUNTROOT %s\n", rootfs.bo_fstype)); 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate error = VFS_MOUNTROOT(rootvfs, ROOT_INIT); 2187c478bd9Sstevel@tonic-gate vfs_unrefvfssw(vsw); 2197c478bd9Sstevel@tonic-gate rootdev = rootvfs->vfs_dev; 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate if (error) 2227c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot mount root on %s fstype %s\n", 2237c478bd9Sstevel@tonic-gate rootfs.bo_name, rootfs.bo_fstype); 2247c478bd9Sstevel@tonic-gate else 2257c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "?root on %s fstype %s\n", 2267c478bd9Sstevel@tonic-gate rootfs.bo_name, rootfs.bo_fstype); 2277c478bd9Sstevel@tonic-gate return (error); 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate /* 2317c478bd9Sstevel@tonic-gate * Under the assumption that our root file system is on a 2327c478bd9Sstevel@tonic-gate * disk partition, get the dev_t of the partition in question. 2337c478bd9Sstevel@tonic-gate * 2347c478bd9Sstevel@tonic-gate * By now, boot has faithfully loaded all our modules into memory, and 2357c478bd9Sstevel@tonic-gate * we've taken over resource management. Before we go any further, we 2367c478bd9Sstevel@tonic-gate * have to fire up the device drivers and stuff we need to mount the 2377c478bd9Sstevel@tonic-gate * root filesystem. That's what we do here. Fingers crossed. 2387c478bd9Sstevel@tonic-gate */ 2397c478bd9Sstevel@tonic-gate dev_t 2407c478bd9Sstevel@tonic-gate getrootdev(void) 2417c478bd9Sstevel@tonic-gate { 2427c478bd9Sstevel@tonic-gate dev_t d; 2437c478bd9Sstevel@tonic-gate 244dedec472SJack Meng d = ddi_pathname_to_dev_t(rootfs.bo_name); 245dedec472SJack Meng if ((d == NODEV) && (iscsiboot_prop != NULL)) { 246dedec472SJack Meng /* Give it another try with the 'disk' path */ 247dedec472SJack Meng get_iscsi_bootpath_phy(rootfs.bo_name); 248dedec472SJack Meng d = ddi_pathname_to_dev_t(rootfs.bo_name); 249dedec472SJack Meng } 250dedec472SJack Meng if (d == NODEV) 2517c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot assemble drivers for root %s\n", 2527c478bd9Sstevel@tonic-gate rootfs.bo_name); 2537c478bd9Sstevel@tonic-gate return (d); 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate /* 2577c478bd9Sstevel@tonic-gate * If booted with ASKNAME, prompt on the console for a filesystem 2587c478bd9Sstevel@tonic-gate * name and return it. 2597c478bd9Sstevel@tonic-gate */ 2607c478bd9Sstevel@tonic-gate void 2617c478bd9Sstevel@tonic-gate getfsname(char *askfor, char *name, size_t namelen) 2627c478bd9Sstevel@tonic-gate { 2637c478bd9Sstevel@tonic-gate if (boothowto & RB_ASKNAME) { 2647c478bd9Sstevel@tonic-gate printf("%s name: ", askfor); 2657c478bd9Sstevel@tonic-gate console_gets(name, namelen); 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 2707c478bd9Sstevel@tonic-gate static int 2717c478bd9Sstevel@tonic-gate preload_module(struct sysparam *sysp, void *p) 2727c478bd9Sstevel@tonic-gate { 2737c478bd9Sstevel@tonic-gate static char *wmesg = "forceload of %s failed"; 2747c478bd9Sstevel@tonic-gate char *name; 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate name = sysp->sys_ptr; 2777c478bd9Sstevel@tonic-gate BMDPRINTF(("preload_module: %s\n", name)); 2787c478bd9Sstevel@tonic-gate if (modloadonly(NULL, name) < 0) 2797c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, wmesg, name); 2807c478bd9Sstevel@tonic-gate return (0); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate /* 2847c478bd9Sstevel@tonic-gate * We want to load all the modules needed to mount the root filesystem, 2857c478bd9Sstevel@tonic-gate * so that when we start the ball rolling in 'getrootdev', every module 2867c478bd9Sstevel@tonic-gate * should already be in memory, just waiting to be init-ed. 2877c478bd9Sstevel@tonic-gate */ 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate int 2907c478bd9Sstevel@tonic-gate loadrootmodules(void) 2917c478bd9Sstevel@tonic-gate { 2927c478bd9Sstevel@tonic-gate struct vfssw *vsw; 2937c478bd9Sstevel@tonic-gate char *this; 2947c478bd9Sstevel@tonic-gate char *name; 2957c478bd9Sstevel@tonic-gate int err; 296986fd29aSsetje int i, proplen; 2977c478bd9Sstevel@tonic-gate extern char *impl_module_list[]; 2987c478bd9Sstevel@tonic-gate extern char *platform_module_list[]; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate /* Make sure that the PROM's devinfo tree has been created */ 3017c478bd9Sstevel@tonic-gate ASSERT(ddi_root_node()); 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: fstype %s\n", rootfs.bo_fstype)); 3047c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: name %s\n", rootfs.bo_name)); 3057c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: flags 0x%x\n", rootfs.bo_flags)); 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate /* 3087c478bd9Sstevel@tonic-gate * Get the root fstype and root device path from boot. 3097c478bd9Sstevel@tonic-gate */ 3107c478bd9Sstevel@tonic-gate rootfs.bo_fstype[0] = '\0'; 3117c478bd9Sstevel@tonic-gate rootfs.bo_name[0] = '\0'; 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate /* 3147c478bd9Sstevel@tonic-gate * This lookup will result in modloadonly-ing the root 3157c478bd9Sstevel@tonic-gate * filesystem module - it gets _init-ed in rootconf() 3167c478bd9Sstevel@tonic-gate */ 3177c478bd9Sstevel@tonic-gate if ((vsw = getfstype("root", rootfs.bo_fstype, BO_MAXFSNAME)) == NULL) 3187c478bd9Sstevel@tonic-gate return (ENXIO); /* in case we have no file system types */ 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate (void) strcpy(rootfs.bo_fstype, vsw->vsw_name); 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate vfs_unrefvfssw(vsw); 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate /* 3257c478bd9Sstevel@tonic-gate * Load the favored drivers of the implementation. 3267c478bd9Sstevel@tonic-gate * e.g. 'sbus' and possibly 'zs' (even). 3277c478bd9Sstevel@tonic-gate * 3287c478bd9Sstevel@tonic-gate * Called whilst boot is still loaded (because boot does 3297c478bd9Sstevel@tonic-gate * the i/o for us), and DDI services are unavailable. 3307c478bd9Sstevel@tonic-gate */ 3317c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: impl_module_list\n")); 3327c478bd9Sstevel@tonic-gate for (i = 0; (this = impl_module_list[i]) != NULL; i++) { 3337c478bd9Sstevel@tonic-gate if ((err = load_boot_driver(this)) != 0) { 3347c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "Cannot load drv/%s", this); 3357c478bd9Sstevel@tonic-gate return (err); 3367c478bd9Sstevel@tonic-gate } 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate /* 3397c478bd9Sstevel@tonic-gate * Now load the platform modules (if any) 3407c478bd9Sstevel@tonic-gate */ 3417c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: platform_module_list\n")); 3427c478bd9Sstevel@tonic-gate for (i = 0; (this = platform_module_list[i]) != NULL; i++) { 3437c478bd9Sstevel@tonic-gate if ((err = load_boot_platform_modules(this)) != 0) { 3447c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "Cannot load drv/%s", this); 3457c478bd9Sstevel@tonic-gate return (err); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate loop: 3507c478bd9Sstevel@tonic-gate (void) getphysdev("root", rootfs.bo_name, BO_MAXOBJNAME); 3517c478bd9Sstevel@tonic-gate /* 3527c478bd9Sstevel@tonic-gate * Given a physical pathname, load the correct set of driver 3537c478bd9Sstevel@tonic-gate * modules into memory, including all possible parents. 3547c478bd9Sstevel@tonic-gate * 3557c478bd9Sstevel@tonic-gate * NB: The code sets the variable 'name' for error reporting. 3567c478bd9Sstevel@tonic-gate */ 3577c478bd9Sstevel@tonic-gate err = 0; 3587c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name)); 3597c478bd9Sstevel@tonic-gate name = rootfs.bo_name; 3607c478bd9Sstevel@tonic-gate err = load_bootpath_drivers(rootfs.bo_name); 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate /* 3637c478bd9Sstevel@tonic-gate * Load driver modules in obp_bootpath, this is always 3647c478bd9Sstevel@tonic-gate * required for mountroot to succeed. obp_bootpath is 365*e373b6e4SYuri Pankov * is set if rootdev is set via /etc/system. 3667c478bd9Sstevel@tonic-gate */ 3677c478bd9Sstevel@tonic-gate if ((err == 0) && obp_bootpath[0] != '\0') { 3687c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath)); 3697c478bd9Sstevel@tonic-gate name = obp_bootpath; 3707c478bd9Sstevel@tonic-gate err = load_bootpath_drivers(obp_bootpath); 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate if (err != 0) { 3747c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load drivers for %s\n", name); 3757c478bd9Sstevel@tonic-gate goto out; 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate /* 3797c478bd9Sstevel@tonic-gate * Check to see if the booter performed DHCP configuration 3807c478bd9Sstevel@tonic-gate * ("bootp-response" boot property exists). If so, then before 3817c478bd9Sstevel@tonic-gate * bootops disappears we need to save the value of this property 3827c478bd9Sstevel@tonic-gate * such that the userland dhcpagent can adopt the DHCP management 383986fd29aSsetje * of our primary network interface. 3847c478bd9Sstevel@tonic-gate */ 3857c478bd9Sstevel@tonic-gate proplen = BOP_GETPROPLEN(bootops, "bootp-response"); 3867c478bd9Sstevel@tonic-gate if (proplen > 0) { 387986fd29aSsetje dhcack = kmem_zalloc(proplen, KM_SLEEP); 388986fd29aSsetje if (BOP_GETPROP(bootops, "bootp-response", dhcack) == -1) { 3897c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "BOP_GETPROP of " 3907c478bd9Sstevel@tonic-gate "\"bootp-response\" failed\n"); 3917c478bd9Sstevel@tonic-gate kmem_free(dhcack, dhcacklen); 3927c478bd9Sstevel@tonic-gate dhcack = NULL; 3937c478bd9Sstevel@tonic-gate goto out; 3947c478bd9Sstevel@tonic-gate } 395986fd29aSsetje dhcacklen = proplen; 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /* 3987c478bd9Sstevel@tonic-gate * Fetch the "netdev-path" boot property (if it exists), and 3997c478bd9Sstevel@tonic-gate * stash it for later use by sysinfo(SI_DHCP_CACHE, ...). 4007c478bd9Sstevel@tonic-gate */ 4017c478bd9Sstevel@tonic-gate proplen = BOP_GETPROPLEN(bootops, "netdev-path"); 4027c478bd9Sstevel@tonic-gate if (proplen > 0) { 4037c478bd9Sstevel@tonic-gate netdev_path = kmem_zalloc(proplen, KM_SLEEP); 4047c478bd9Sstevel@tonic-gate if (BOP_GETPROP(bootops, "netdev-path", 4057c478bd9Sstevel@tonic-gate (uchar_t *)netdev_path) == -1) { 4067c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "BOP_GETPROP of " 4077c478bd9Sstevel@tonic-gate "\"netdev-path\" failed\n"); 4087c478bd9Sstevel@tonic-gate kmem_free(netdev_path, proplen); 4097c478bd9Sstevel@tonic-gate goto out; 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate /* 4157c478bd9Sstevel@tonic-gate * Preload (load-only, no init) all modules which 4167c478bd9Sstevel@tonic-gate * were added to the /etc/system file with the 4177c478bd9Sstevel@tonic-gate * FORCELOAD keyword. 4187c478bd9Sstevel@tonic-gate */ 4197c478bd9Sstevel@tonic-gate BMDPRINTF(("loadrootmodules: preload_module\n")); 4207c478bd9Sstevel@tonic-gate (void) mod_sysctl_type(MOD_FORCELOAD, preload_module, NULL); 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate /* 4237c478bd9Sstevel@tonic-gate * If we booted otw then load in the plumbing 4247c478bd9Sstevel@tonic-gate * routine now while we still can. If we didn't 4257c478bd9Sstevel@tonic-gate * boot otw then we will load strplumb in main(). 4267c478bd9Sstevel@tonic-gate * 4277c478bd9Sstevel@tonic-gate * NFS is actually a set of modules, the core routines, 4287c478bd9Sstevel@tonic-gate * a diskless helper module, rpcmod, and the tli interface. Load 4297c478bd9Sstevel@tonic-gate * them now while we still can. 4307c478bd9Sstevel@tonic-gate * 4317c478bd9Sstevel@tonic-gate * Because we glomb all versions of nfs into a single module 4327c478bd9Sstevel@tonic-gate * we check based on the initial string "nfs". 4337c478bd9Sstevel@tonic-gate * 4347c478bd9Sstevel@tonic-gate * XXX: A better test for this is to see if device_type 4357c478bd9Sstevel@tonic-gate * XXX: from the PROM is "network". 4367c478bd9Sstevel@tonic-gate */ 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) { 4397c478bd9Sstevel@tonic-gate ++netboot; 4407c478bd9Sstevel@tonic-gate 441d62bc4baSyz147064 /* 442d62bc4baSyz147064 * Preload (load-only, no init) the dacf module. We cannot 443d62bc4baSyz147064 * init the module because one of its requisite modules is 444d62bc4baSyz147064 * dld whose _init function will call taskq_create(), which 445d62bc4baSyz147064 * will panic the system at this point. 446d62bc4baSyz147064 */ 447d62bc4baSyz147064 if ((err = modloadonly("dacf", "net_dacf")) < 0) { 448d62bc4baSyz147064 cmn_err(CE_CONT, "Cannot load dacf/net_dacf\n"); 449d62bc4baSyz147064 goto out; 450d62bc4baSyz147064 } 4517c478bd9Sstevel@tonic-gate if ((err = modload("misc", "tlimod")) < 0) { 4527c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load misc/tlimod\n"); 4537c478bd9Sstevel@tonic-gate goto out; 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate if ((err = modload("strmod", "rpcmod")) < 0) { 4567c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load strmod/rpcmod\n"); 4577c478bd9Sstevel@tonic-gate goto out; 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate if ((err = modload("misc", "nfs_dlboot")) < 0) { 4607c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load misc/nfs_dlboot\n"); 4617c478bd9Sstevel@tonic-gate goto out; 4627c478bd9Sstevel@tonic-gate } 46348aa2e6aSseb if ((err = modload("mac", "mac_ether")) < 0) { 46448aa2e6aSseb cmn_err(CE_CONT, "Cannot load mac/mac_ether\n"); 46548aa2e6aSseb goto out; 46648aa2e6aSseb } 4677c478bd9Sstevel@tonic-gate if ((err = modload("misc", "strplumb")) < 0) { 4687c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Cannot load misc/strplumb\n"); 4697c478bd9Sstevel@tonic-gate goto out; 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate if ((err = strplumb_load()) < 0) { 4727c478bd9Sstevel@tonic-gate goto out; 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate } 475dedec472SJack Meng if (netboot_over_iscsi() == B_TRUE) { 476dedec472SJack Meng /* iscsi boot */ 477dedec472SJack Meng if ((err = modloadonly("dacf", "net_dacf")) < 0) { 478dedec472SJack Meng cmn_err(CE_CONT, "Cannot load dacf/net_dacf\n"); 479dedec472SJack Meng goto out; 480dedec472SJack Meng } 481dedec472SJack Meng if ((err = modload("misc", "tlimod")) < 0) { 482dedec472SJack Meng cmn_err(CE_CONT, "Cannot load misc/tlimod\n"); 483dedec472SJack Meng goto out; 484dedec472SJack Meng } 485dedec472SJack Meng if ((err = modload("mac", "mac_ether")) < 0) { 486dedec472SJack Meng cmn_err(CE_CONT, "Cannot load mac/mac_ether\n"); 487dedec472SJack Meng goto out; 488dedec472SJack Meng } 489dedec472SJack Meng if ((err = modloadonly("drv", "iscsi")) < 0) { 490dedec472SJack Meng cmn_err(CE_CONT, "Cannot load drv/iscsi\n"); 491dedec472SJack Meng goto out; 492dedec472SJack Meng } 493dedec472SJack Meng if ((err = modloadonly("drv", "ssd")) < 0) { 494dedec472SJack Meng cmn_err(CE_CONT, "Cannot load drv/ssd\n"); 495dedec472SJack Meng goto out; 496dedec472SJack Meng } 497dedec472SJack Meng if ((err = modloadonly("drv", "sd")) < 0) { 498dedec472SJack Meng cmn_err(CE_CONT, "Cannot load drv/sd\n"); 499dedec472SJack Meng goto out; 500dedec472SJack Meng } 501dedec472SJack Meng if ((err = modload("misc", "strplumb")) < 0) { 502dedec472SJack Meng cmn_err(CE_CONT, "Cannot load misc/strplumb\n"); 503dedec472SJack Meng goto out; 504dedec472SJack Meng } 505dedec472SJack Meng if ((err = strplumb_load()) < 0) { 506dedec472SJack Meng goto out; 507dedec472SJack Meng } 508dedec472SJack Meng } 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 521986fd29aSsetje static int 522986fd29aSsetje get_bootpath_prop(char *bootpath) 523986fd29aSsetje { 524986fd29aSsetje if (root_is_ramdisk) { 525986fd29aSsetje if (BOP_GETPROP(bootops, "bootarchive", bootpath) == -1) 526986fd29aSsetje return (-1); 527986fd29aSsetje (void) strlcat(bootpath, ":a", BO_MAXOBJNAME); 528986fd29aSsetje } else { 529986fd29aSsetje /* 530986fd29aSsetje * Look for the 1275 compliant name 'bootpath' first, 531986fd29aSsetje * but make certain it has a non-NULL value as well. 532986fd29aSsetje */ 533986fd29aSsetje if ((BOP_GETPROP(bootops, "bootpath", bootpath) == -1) || 534986fd29aSsetje strlen(bootpath) == 0) { 535986fd29aSsetje if (BOP_GETPROP(bootops, 536986fd29aSsetje "boot-path", bootpath) == -1) 537986fd29aSsetje return (-1); 538986fd29aSsetje } 539dedec472SJack Meng if (memcmp(bootpath, BP_ISCSI_DISK, 540dedec472SJack Meng strlen(BP_ISCSI_DISK)) == 0) { 541dedec472SJack Meng /* iscsi boot */ 542dedec472SJack Meng get_iscsi_bootpath_vhci(bootpath); 543dedec472SJack Meng } 544986fd29aSsetje } 545986fd29aSsetje return (0); 546986fd29aSsetje } 547986fd29aSsetje 548986fd29aSsetje static int 549986fd29aSsetje get_fstype_prop(char *fstype) 550986fd29aSsetje { 551986fd29aSsetje char *prop = (root_is_ramdisk) ? "archive-fstype" : "fstype"; 552986fd29aSsetje 553986fd29aSsetje return (BOP_GETPROP(bootops, prop, fstype)); 554986fd29aSsetje } 555986fd29aSsetje 5567c478bd9Sstevel@tonic-gate /* 5577c478bd9Sstevel@tonic-gate * Get the name of the root or swap filesystem type, and return 5587c478bd9Sstevel@tonic-gate * the corresponding entry in the vfs switch. 5597c478bd9Sstevel@tonic-gate * 5607c478bd9Sstevel@tonic-gate * If we're not asking the user, and we're trying to find the 5617c478bd9Sstevel@tonic-gate * root filesystem type, we ask boot for the filesystem 5627c478bd9Sstevel@tonic-gate * type that it came from and use that. Similarly, if we're 5637c478bd9Sstevel@tonic-gate * trying to find the swap filesystem, we try and derive it from 5647c478bd9Sstevel@tonic-gate * the root filesystem type. 5657c478bd9Sstevel@tonic-gate * 5667c478bd9Sstevel@tonic-gate * If we are booting via NFS we currently have these options: 5677c478bd9Sstevel@tonic-gate * nfs - dynamically choose NFS V2. V3, or V4 (default) 5687c478bd9Sstevel@tonic-gate * nfs2 - force NFS V2 5697c478bd9Sstevel@tonic-gate * nfs3 - force NFS V3 5707c478bd9Sstevel@tonic-gate * nfs4 - force NFS V4 5717c478bd9Sstevel@tonic-gate * Because we need to maintain backward compatibility with the naming 5727c478bd9Sstevel@tonic-gate * convention that the NFS V2 filesystem name is "nfs" (see vfs_conf.c) 5737c478bd9Sstevel@tonic-gate * we need to map "nfs" => "nfsdyn" and "nfs2" => "nfs". The dynamic 5747c478bd9Sstevel@tonic-gate * nfs module will map the type back to either "nfs", "nfs3", or "nfs4". 575bd93c05dSAlexander Eremin * This is only for root filesystems, all other uses will expect 576bd93c05dSAlexander Eremin * that "nfs" == NFS V2. 5777c478bd9Sstevel@tonic-gate * 5787c478bd9Sstevel@tonic-gate * If the filesystem isn't already loaded, vfs_getvfssw() will load 5797c478bd9Sstevel@tonic-gate * it for us, but if (at the time we call it) modrootloaded is 5807c478bd9Sstevel@tonic-gate * still not set, it won't run the filesystems _init routine (and 5817c478bd9Sstevel@tonic-gate * implicitly it won't run the filesystems vsw_init() entry either). 5827c478bd9Sstevel@tonic-gate * We do that explicitly in rootconf(). 5837c478bd9Sstevel@tonic-gate */ 5847c478bd9Sstevel@tonic-gate static struct vfssw * 5857c478bd9Sstevel@tonic-gate getfstype(char *askfor, char *fsname, size_t fsnamelen) 5867c478bd9Sstevel@tonic-gate { 5877c478bd9Sstevel@tonic-gate struct vfssw *vsw; 5887c478bd9Sstevel@tonic-gate static char defaultfs[BO_MAXFSNAME]; 5897c478bd9Sstevel@tonic-gate int root = 0; 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate if (strcmp(askfor, "root") == 0) { 592986fd29aSsetje (void) get_fstype_prop(defaultfs); 5937c478bd9Sstevel@tonic-gate root++; 5947c478bd9Sstevel@tonic-gate } else { 5957c478bd9Sstevel@tonic-gate (void) strcpy(defaultfs, "swapfs"); 5967c478bd9Sstevel@tonic-gate } 5977c478bd9Sstevel@tonic-gate 5987c478bd9Sstevel@tonic-gate if (boothowto & RB_ASKNAME) { 5997c478bd9Sstevel@tonic-gate for (*fsname = '\0'; *fsname == '\0'; *fsname = '\0') { 6007c478bd9Sstevel@tonic-gate printf("%s filesystem type [%s]: ", askfor, defaultfs); 6017c478bd9Sstevel@tonic-gate console_gets(fsname, fsnamelen); 6027c478bd9Sstevel@tonic-gate if (*fsname == '\0') 6037c478bd9Sstevel@tonic-gate (void) strcpy(fsname, defaultfs); 6047c478bd9Sstevel@tonic-gate if (root) { 6057c478bd9Sstevel@tonic-gate if (strcmp(fsname, "nfs2") == 0) 6067c478bd9Sstevel@tonic-gate (void) strcpy(fsname, "nfs"); 6077c478bd9Sstevel@tonic-gate else if (strcmp(fsname, "nfs") == 0) 6087c478bd9Sstevel@tonic-gate (void) strcpy(fsname, "nfsdyn"); 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate if ((vsw = vfs_getvfssw(fsname)) != NULL) 6117c478bd9Sstevel@tonic-gate return (vsw); 6127c478bd9Sstevel@tonic-gate printf("Unknown filesystem type '%s'\n", fsname); 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate } else if (*fsname == '\0') { 6157c478bd9Sstevel@tonic-gate fsname = defaultfs; 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate if (*fsname == '\0') { 6187c478bd9Sstevel@tonic-gate return (NULL); 6197c478bd9Sstevel@tonic-gate } 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate if (root) { 6227c478bd9Sstevel@tonic-gate if (strcmp(fsname, "nfs2") == 0) 6237c478bd9Sstevel@tonic-gate (void) strcpy(fsname, "nfs"); 6247c478bd9Sstevel@tonic-gate else if (strcmp(fsname, "nfs") == 0) 6257c478bd9Sstevel@tonic-gate (void) strcpy(fsname, "nfsdyn"); 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate return (vfs_getvfssw(fsname)); 6297c478bd9Sstevel@tonic-gate } 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate /* 6337c478bd9Sstevel@tonic-gate * Get a physical device name, and maybe load and attach 6347c478bd9Sstevel@tonic-gate * the driver. 6357c478bd9Sstevel@tonic-gate * 6367c478bd9Sstevel@tonic-gate * XXX Need better checking of whether or not a device 6377c478bd9Sstevel@tonic-gate * actually exists if the user typed in a pathname. 6387c478bd9Sstevel@tonic-gate * 6397c478bd9Sstevel@tonic-gate * XXX Are we sure we want to expose users to this sort 6407c478bd9Sstevel@tonic-gate * of physical namespace gobbledygook (now there's 6417c478bd9Sstevel@tonic-gate * a word to conjure with..) 6427c478bd9Sstevel@tonic-gate * 6437c478bd9Sstevel@tonic-gate * XXX Note that on an OBP machine, we can easily ask the 6447c478bd9Sstevel@tonic-gate * prom and pretty-print some plausible set of bootable 6457c478bd9Sstevel@tonic-gate * devices. We can also user the prom to verify any 6467c478bd9Sstevel@tonic-gate * such device. Later tim.. later. 6477c478bd9Sstevel@tonic-gate */ 6487c478bd9Sstevel@tonic-gate static int 6497c478bd9Sstevel@tonic-gate getphysdev(char *askfor, char *name, size_t namelen) 6507c478bd9Sstevel@tonic-gate { 6517c478bd9Sstevel@tonic-gate static char fmt[] = "Enter physical name of %s device\n[%s]: "; 6527c478bd9Sstevel@tonic-gate dev_t dev; 6537c478bd9Sstevel@tonic-gate static char defaultpath[BO_MAXOBJNAME]; 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate /* 6567c478bd9Sstevel@tonic-gate * Establish 'default' values - we get the root device from 6577c478bd9Sstevel@tonic-gate * boot, and we infer the swap device is the same but with 6587c478bd9Sstevel@tonic-gate * a 'b' on the end instead of an 'a'. A first stab at 6597c478bd9Sstevel@tonic-gate * ease-of-use .. 6607c478bd9Sstevel@tonic-gate */ 6617c478bd9Sstevel@tonic-gate if (strcmp(askfor, "root") == 0) { 662986fd29aSsetje if (get_bootpath_prop(defaultpath) == -1) 6637c478bd9Sstevel@tonic-gate boothowto |= RB_ASKNAME | RB_VERBOSE; 6647c478bd9Sstevel@tonic-gate } else { 6657c478bd9Sstevel@tonic-gate (void) strcpy(defaultpath, rootfs.bo_name); 6667c478bd9Sstevel@tonic-gate defaultpath[strlen(defaultpath) - 1] = 'b'; 6677c478bd9Sstevel@tonic-gate } 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate retry: 6707c478bd9Sstevel@tonic-gate if (boothowto & RB_ASKNAME) { 6717c478bd9Sstevel@tonic-gate printf(fmt, askfor, defaultpath); 6727c478bd9Sstevel@tonic-gate console_gets(name, namelen); 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate if (*name == '\0') 6757c478bd9Sstevel@tonic-gate (void) strcpy(name, defaultpath); 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate if (strcmp(askfor, "swap") == 0) { 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate /* 6807c478bd9Sstevel@tonic-gate * Try to load and install the swap device driver. 6817c478bd9Sstevel@tonic-gate */ 6827c478bd9Sstevel@tonic-gate dev = ddi_pathname_to_dev_t(name); 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate if (dev == (dev_t)-1) { 6857c478bd9Sstevel@tonic-gate printf("Not a supported device for swap.\n"); 6867c478bd9Sstevel@tonic-gate boothowto |= RB_ASKNAME | RB_VERBOSE; 6877c478bd9Sstevel@tonic-gate goto retry; 6887c478bd9Sstevel@tonic-gate } 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate /* 6917c478bd9Sstevel@tonic-gate * Ensure that we're not trying to swap on the floppy. 6927c478bd9Sstevel@tonic-gate */ 6937c478bd9Sstevel@tonic-gate if (strncmp(ddi_major_to_name(getmajor(dev)), "fd", 2) == 0) { 6947c478bd9Sstevel@tonic-gate printf("Too dangerous to swap on the floppy\n"); 6957c478bd9Sstevel@tonic-gate if (boothowto & RB_ASKNAME) 6967c478bd9Sstevel@tonic-gate goto retry; 6977c478bd9Sstevel@tonic-gate return (-1); 6987c478bd9Sstevel@tonic-gate } 6997c478bd9Sstevel@tonic-gate } 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate return (0); 7027c478bd9Sstevel@tonic-gate } 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate /* 7067c478bd9Sstevel@tonic-gate * Load a driver needed to boot. 7077c478bd9Sstevel@tonic-gate */ 7087c478bd9Sstevel@tonic-gate static int 7097c478bd9Sstevel@tonic-gate load_boot_driver(char *drv) 7107c478bd9Sstevel@tonic-gate { 7117c478bd9Sstevel@tonic-gate char *drvname; 7127c478bd9Sstevel@tonic-gate major_t major; 7131e1ddd6cScth #ifdef sparc 7141e1ddd6cScth struct devnames *dnp; 7151e1ddd6cScth ddi_prop_t *propp; 7161e1ddd6cScth char *module; 7171e1ddd6cScth char *dir, *mf; 7181e1ddd6cScth int plen; 7191e1ddd6cScth int mlen; 7201e1ddd6cScth #endif /* sparc */ 7217c478bd9Sstevel@tonic-gate 722a204de77Scth if ((major = ddi_name_to_major(drv)) == DDI_MAJOR_T_NONE) { 7237c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "%s: no major number\n", drv); 7247c478bd9Sstevel@tonic-gate return (-1); 7257c478bd9Sstevel@tonic-gate } 7267c478bd9Sstevel@tonic-gate /* 7277c478bd9Sstevel@tonic-gate * resolve aliases 7287c478bd9Sstevel@tonic-gate */ 7297c478bd9Sstevel@tonic-gate drvname = ddi_major_to_name(major); 7307c478bd9Sstevel@tonic-gate 7317c478bd9Sstevel@tonic-gate #ifdef DEBUG 7327c478bd9Sstevel@tonic-gate if (strcmp(drv, drvname) == 0) { 7337c478bd9Sstevel@tonic-gate BMDPRINTF(("load_boot_driver: %s\n", drv)); 7347c478bd9Sstevel@tonic-gate } else { 7357c478bd9Sstevel@tonic-gate BMDPRINTF(("load_boot_driver: %s -> %s\n", drv, drvname)); 7367c478bd9Sstevel@tonic-gate } 7377c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate if (modloadonly("drv", drvname) == -1) { 7407c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "%s: cannot load driver\n", drvname); 7417c478bd9Sstevel@tonic-gate return (-1); 7427c478bd9Sstevel@tonic-gate } 7437c478bd9Sstevel@tonic-gate 7441e1ddd6cScth #ifdef sparc 7451e1ddd6cScth /* 7461e1ddd6cScth * NOTE: this can be removed when newboot-sparc is delivered. 7471e1ddd6cScth * 7481e1ddd6cScth * Check to see if the driver had a 'ddi-forceload' global driver.conf 7491e1ddd6cScth * property to identify additional modules that need to be loaded. 7501e1ddd6cScth * The driver still needs to use ddi_modopen() to open these modules, 7511e1ddd6cScth * but the 'ddi-forceload' property allows the modules to be loaded 7521e1ddd6cScth * into memory prior to lights-out, so that driver ddi_modopen() 7531e1ddd6cScth * calls during lights-out (when mounting root) will work correctly. 7541e1ddd6cScth * Use of 'ddi-forceload' is only required for drivers involved in 7551e1ddd6cScth * getting root mounted. 7561e1ddd6cScth */ 7571e1ddd6cScth dnp = &devnamesp[major]; 7581e1ddd6cScth if (dnp->dn_global_prop_ptr && dnp->dn_global_prop_ptr->prop_list && 7591e1ddd6cScth ((propp = i_ddi_prop_search(DDI_DEV_T_ANY, 7601e1ddd6cScth "ddi-forceload", DDI_PROP_TYPE_STRING, 7611e1ddd6cScth &dnp->dn_global_prop_ptr->prop_list)) != NULL)) { 7621e1ddd6cScth 7631e1ddd6cScth module = (char *)propp->prop_val; 7641e1ddd6cScth plen = propp->prop_len; 7651e1ddd6cScth while (plen > 0) { 7661e1ddd6cScth mlen = strlen(module); 7671e1ddd6cScth mf = strrchr(module, '/'); 7681e1ddd6cScth if (mf) { 7691e1ddd6cScth dir = module; 7701e1ddd6cScth *mf++ = '\0'; /* '/' -> '\0' */ 7711e1ddd6cScth } else { 7721e1ddd6cScth dir = "misc"; 7731e1ddd6cScth mf = module; 7741e1ddd6cScth } 7751e1ddd6cScth if (modloadonly(dir, mf) == -1) 7761e1ddd6cScth cmn_err(CE_CONT, 7771e1ddd6cScth "misc/%s: can't load module\n", mf); 7781e1ddd6cScth if (mf != module) 7791e1ddd6cScth *(mf - 1) = '/'; /* '\0' -> '/' */ 7801e1ddd6cScth 7811e1ddd6cScth module += mlen + 1; 7821e1ddd6cScth plen -= mlen + 1; 7831e1ddd6cScth } 7841e1ddd6cScth } 7851e1ddd6cScth #endif /* sparc */ 7861e1ddd6cScth 7877c478bd9Sstevel@tonic-gate return (0); 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate /* 7927c478bd9Sstevel@tonic-gate * For a given instance, load that driver and its parents 7937c478bd9Sstevel@tonic-gate */ 7947c478bd9Sstevel@tonic-gate static int 795f4da9be0Scth load_parent_drivers(dev_info_t *dip, char *path) 7967c478bd9Sstevel@tonic-gate { 7977c478bd9Sstevel@tonic-gate int rval = 0; 798a204de77Scth major_t major = DDI_MAJOR_T_NONE; 7997c478bd9Sstevel@tonic-gate char *drv; 800f4da9be0Scth char *p; 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate while (dip) { 803f4da9be0Scth /* check for path-oriented alias */ 804f4da9be0Scth if (path) 805f4da9be0Scth major = ddi_name_to_major(path); 806f4da9be0Scth else 807a204de77Scth major = DDI_MAJOR_T_NONE; 808f4da9be0Scth 809a204de77Scth if (major != DDI_MAJOR_T_NONE) 810f4da9be0Scth drv = ddi_major_to_name(major); 811f4da9be0Scth else 812f4da9be0Scth drv = ddi_binding_name(dip); 813f4da9be0Scth 8147c478bd9Sstevel@tonic-gate if (load_boot_driver(drv) != 0) 8157c478bd9Sstevel@tonic-gate rval = -1; 816f4da9be0Scth 8177c478bd9Sstevel@tonic-gate dip = ddi_get_parent(dip); 818f4da9be0Scth if (path) { 819f4da9be0Scth p = strrchr(path, '/'); 820f4da9be0Scth if (p) 821f4da9be0Scth *p = 0; 822f4da9be0Scth } 8237c478bd9Sstevel@tonic-gate } 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate return (rval); 8267c478bd9Sstevel@tonic-gate } 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate /* 8307c478bd9Sstevel@tonic-gate * For a given path to a boot device, 8317c478bd9Sstevel@tonic-gate * load that driver and all its parents. 8327c478bd9Sstevel@tonic-gate */ 8337c478bd9Sstevel@tonic-gate static int 8347c478bd9Sstevel@tonic-gate load_bootpath_drivers(char *bootpath) 8357c478bd9Sstevel@tonic-gate { 8367c478bd9Sstevel@tonic-gate dev_info_t *dip; 837f4da9be0Scth char *pathcopy; 838f4da9be0Scth int pathcopy_len; 839f4da9be0Scth int rval; 840f4da9be0Scth char *p; 841dedec472SJack Meng int proplen; 842dedec472SJack Meng char iscsi_network_path[BO_MAXOBJNAME]; 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate if (bootpath == NULL || *bootpath == 0) 8457c478bd9Sstevel@tonic-gate return (-1); 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate BMDPRINTF(("load_bootpath_drivers: %s\n", bootpath)); 848dedec472SJack Meng #ifdef _OBP 849dedec472SJack Meng if (netboot_over_iscsi()) { 850dedec472SJack Meng /* iscsi boot */ 851dedec472SJack Meng if (root_is_ramdisk) { 852b5267ad3SJack Meng if (modloadonly("drv", "ramdisk") < 0) 853b5267ad3SJack Meng return (-1); 854dedec472SJack Meng } 855dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_NETWORK_BOOTPATH); 856dedec472SJack Meng if (proplen > 0) { 857dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ISCSI_NETWORK_BOOTPATH, 858dedec472SJack Meng iscsi_network_path) > 0) { 859dedec472SJack Meng p = strchr(iscsi_network_path, ':'); 860dedec472SJack Meng if (p != NULL) { 861dedec472SJack Meng *p = '\0'; 862dedec472SJack Meng } 863dedec472SJack Meng pathcopy = i_ddi_strdup(iscsi_network_path, 864dedec472SJack Meng KM_SLEEP); 865dedec472SJack Meng pathcopy_len = strlen(pathcopy) + 1; 866dedec472SJack Meng } else { 867dedec472SJack Meng return (-1); 868dedec472SJack Meng } 869dedec472SJack Meng } else { 870dedec472SJack Meng return (-1); 871dedec472SJack Meng } 872dedec472SJack Meng } else { 873dedec472SJack Meng #endif 874f4da9be0Scth pathcopy = i_ddi_strdup(bootpath, KM_SLEEP); 875f4da9be0Scth pathcopy_len = strlen(pathcopy) + 1; 876dedec472SJack Meng #ifdef _OBP 877dedec472SJack Meng } 878dedec472SJack Meng #endif 879f4da9be0Scth dip = path_to_devinfo(pathcopy); 8807c478bd9Sstevel@tonic-gate 8817c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 8827c478bd9Sstevel@tonic-gate /* 8837c478bd9Sstevel@tonic-gate * i386 does not provide stub nodes for all boot devices, 8847c478bd9Sstevel@tonic-gate * but we should be able to find the node for the parent, 8857c478bd9Sstevel@tonic-gate * and the leaf of the boot path should be the driver name, 8867c478bd9Sstevel@tonic-gate * which we go ahead and load here. 8877c478bd9Sstevel@tonic-gate */ 8887c478bd9Sstevel@tonic-gate if (dip == NULL) { 889f4da9be0Scth char *leaf; 8907c478bd9Sstevel@tonic-gate 8917c478bd9Sstevel@tonic-gate /* 892f4da9be0Scth * Find last slash to build the full path to the 893f4da9be0Scth * parent of the leaf boot device 8947c478bd9Sstevel@tonic-gate */ 895f4da9be0Scth p = strrchr(pathcopy, '/'); 8967c478bd9Sstevel@tonic-gate *p++ = 0; 8977c478bd9Sstevel@tonic-gate 8987c478bd9Sstevel@tonic-gate /* 8997c478bd9Sstevel@tonic-gate * Now isolate the driver name of the leaf device 9007c478bd9Sstevel@tonic-gate */ 901f4da9be0Scth leaf = p; 902f4da9be0Scth p = strchr(leaf, '@'); 9037c478bd9Sstevel@tonic-gate *p = 0; 9047c478bd9Sstevel@tonic-gate 9057c478bd9Sstevel@tonic-gate BMDPRINTF(("load_bootpath_drivers: parent=%s leaf=%s\n", 906f4da9be0Scth bootpath, leaf)); 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate dip = path_to_devinfo(pathcopy); 909f4da9be0Scth if (leaf) { 910f4da9be0Scth rval = load_boot_driver(leaf, NULL); 911f4da9be0Scth if (rval == -1) { 912f4da9be0Scth kmem_free(pathcopy, pathcopy_len); 9137c478bd9Sstevel@tonic-gate return (NULL); 914f4da9be0Scth } 915f4da9be0Scth } 9167c478bd9Sstevel@tonic-gate } 9177c478bd9Sstevel@tonic-gate #endif 9187c478bd9Sstevel@tonic-gate 9197c478bd9Sstevel@tonic-gate if (dip == NULL) { 9207c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "can't bind driver for boot path <%s>", 9217c478bd9Sstevel@tonic-gate bootpath); 922f4da9be0Scth kmem_free(pathcopy, pathcopy_len); 9237c478bd9Sstevel@tonic-gate return (NULL); 9247c478bd9Sstevel@tonic-gate } 9257c478bd9Sstevel@tonic-gate 9267c478bd9Sstevel@tonic-gate /* 9277c478bd9Sstevel@tonic-gate * Load IP over IB driver when netbooting over IB. 9287c478bd9Sstevel@tonic-gate * As per IB 1275 binding, IP over IB is represented as 9297c478bd9Sstevel@tonic-gate * service on the top of the HCA node. So, there is no 9307c478bd9Sstevel@tonic-gate * PROM node and generic framework cannot pre-load 9317c478bd9Sstevel@tonic-gate * IP over IB driver based on the bootpath. The following 9327c478bd9Sstevel@tonic-gate * code preloads IP over IB driver when doing netboot over 9337c478bd9Sstevel@tonic-gate * InfiniBand. 9347c478bd9Sstevel@tonic-gate */ 9357c478bd9Sstevel@tonic-gate if (netboot_over_ib(bootpath) && 9361cfa752fSRamaswamy Tummala modloadonly("drv", "ibp") == -1) { 9371cfa752fSRamaswamy Tummala cmn_err(CE_CONT, "ibp: cannot load platform driver\n"); 938f4da9be0Scth kmem_free(pathcopy, pathcopy_len); 9397c478bd9Sstevel@tonic-gate return (NULL); 9407c478bd9Sstevel@tonic-gate } 9417c478bd9Sstevel@tonic-gate 942c29cc384Svikram /* 943c29cc384Svikram * The PROM node for hubs have incomplete compatible 944c29cc384Svikram * properties and therefore do not bind to the hubd driver. 945c29cc384Svikram * As a result load_bootpath_drivers() loads the usb_mid driver 946c29cc384Svikram * for hub nodes rather than the hubd driver. This causes 947c29cc384Svikram * mountroot failures when booting off USB storage. To prevent 948c29cc384Svikram * this, if we are booting via USB hubs, we preload the hubd driver. 949c29cc384Svikram */ 950c29cc384Svikram if (strstr(bootpath, "/hub@") && modloadonly("drv", "hubd") == -1) { 951c29cc384Svikram cmn_err(CE_WARN, "bootpath contains a USB hub, " 952c29cc384Svikram "but cannot load hubd driver"); 953c29cc384Svikram } 954c29cc384Svikram 955f4da9be0Scth /* get rid of minor node at end of copy (if not already done above) */ 956f4da9be0Scth p = strrchr(pathcopy, '/'); 957f4da9be0Scth if (p) { 958f4da9be0Scth p = strchr(p, ':'); 959f4da9be0Scth if (p) 960f4da9be0Scth *p = 0; 961f4da9be0Scth } 962f4da9be0Scth 963f4da9be0Scth rval = load_parent_drivers(dip, pathcopy); 964f4da9be0Scth kmem_free(pathcopy, pathcopy_len); 965f4da9be0Scth return (rval); 9667c478bd9Sstevel@tonic-gate } 9677c478bd9Sstevel@tonic-gate 9687c478bd9Sstevel@tonic-gate 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate /* 9727c478bd9Sstevel@tonic-gate * Load drivers required for a platform 9737c478bd9Sstevel@tonic-gate * Since all hardware nodes should be available in the device 9747c478bd9Sstevel@tonic-gate * tree, walk the per-driver list and load the parents of 9757c478bd9Sstevel@tonic-gate * each node found. If not a hardware node, try to load it. 9767c478bd9Sstevel@tonic-gate * Pseudo nexus is already loaded. 9777c478bd9Sstevel@tonic-gate */ 9787c478bd9Sstevel@tonic-gate static int 9797c478bd9Sstevel@tonic-gate load_boot_platform_modules(char *drv) 9807c478bd9Sstevel@tonic-gate { 9817c478bd9Sstevel@tonic-gate major_t major; 9827c478bd9Sstevel@tonic-gate dev_info_t *dip; 9837c478bd9Sstevel@tonic-gate char *drvname; 9847c478bd9Sstevel@tonic-gate int rval = 0; 9857c478bd9Sstevel@tonic-gate 986a204de77Scth if ((major = ddi_name_to_major(drv)) == DDI_MAJOR_T_NONE) { 9877c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "%s: no major number\n", drv); 9887c478bd9Sstevel@tonic-gate return (-1); 9897c478bd9Sstevel@tonic-gate } 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate /* 9927c478bd9Sstevel@tonic-gate * resolve aliases 9937c478bd9Sstevel@tonic-gate */ 9947c478bd9Sstevel@tonic-gate drvname = ddi_major_to_name(major); 995a204de77Scth if ((major = ddi_name_to_major(drvname)) == DDI_MAJOR_T_NONE) 9967c478bd9Sstevel@tonic-gate return (-1); 9977c478bd9Sstevel@tonic-gate 9987c478bd9Sstevel@tonic-gate #ifdef DEBUG 9997c478bd9Sstevel@tonic-gate if (strcmp(drv, drvname) == 0) { 10007c478bd9Sstevel@tonic-gate BMDPRINTF(("load_boot_platform_modules: %s\n", drv)); 10017c478bd9Sstevel@tonic-gate } else { 10027c478bd9Sstevel@tonic-gate BMDPRINTF(("load_boot_platform_modules: %s -> %s\n", 10037c478bd9Sstevel@tonic-gate drv, drvname)); 10047c478bd9Sstevel@tonic-gate } 10057c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate dip = devnamesp[major].dn_head; 10087c478bd9Sstevel@tonic-gate if (dip == NULL) { 10097c478bd9Sstevel@tonic-gate /* pseudo node, not-enumerated, needs to be loaded */ 10107c478bd9Sstevel@tonic-gate if (modloadonly("drv", drvname) == -1) { 10117c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "%s: cannot load platform driver\n", 10127c478bd9Sstevel@tonic-gate drvname); 10137c478bd9Sstevel@tonic-gate rval = -1; 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate } else { 10167c478bd9Sstevel@tonic-gate while (dip) { 1017f4da9be0Scth if (load_parent_drivers(dip, NULL) != 0) 10187c478bd9Sstevel@tonic-gate rval = -1; 10197c478bd9Sstevel@tonic-gate dip = ddi_get_next(dip); 10207c478bd9Sstevel@tonic-gate } 10217c478bd9Sstevel@tonic-gate } 10227c478bd9Sstevel@tonic-gate 10237c478bd9Sstevel@tonic-gate return (rval); 10247c478bd9Sstevel@tonic-gate } 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate 10277c478bd9Sstevel@tonic-gate /* 10287c478bd9Sstevel@tonic-gate * i_find_node: Internal routine used by path_to_devinfo 10297c478bd9Sstevel@tonic-gate * to locate a given nodeid in the device tree. 10307c478bd9Sstevel@tonic-gate */ 10317c478bd9Sstevel@tonic-gate struct i_path_findnode { 1032fa9e4066Sahrens pnode_t nodeid; 10337c478bd9Sstevel@tonic-gate dev_info_t *dip; 10347c478bd9Sstevel@tonic-gate }; 10357c478bd9Sstevel@tonic-gate 10367c478bd9Sstevel@tonic-gate static int 10377c478bd9Sstevel@tonic-gate i_path_find_node(dev_info_t *dev, void *arg) 10387c478bd9Sstevel@tonic-gate { 10397c478bd9Sstevel@tonic-gate struct i_path_findnode *f = (struct i_path_findnode *)arg; 10407c478bd9Sstevel@tonic-gate 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate if (ddi_get_nodeid(dev) == (int)f->nodeid) { 10437c478bd9Sstevel@tonic-gate f->dip = dev; 10447c478bd9Sstevel@tonic-gate return (DDI_WALK_TERMINATE); 10457c478bd9Sstevel@tonic-gate } 10467c478bd9Sstevel@tonic-gate return (DDI_WALK_CONTINUE); 10477c478bd9Sstevel@tonic-gate } 10487c478bd9Sstevel@tonic-gate 10497c478bd9Sstevel@tonic-gate /* 10507c478bd9Sstevel@tonic-gate * Return the devinfo node to a boot device 10517c478bd9Sstevel@tonic-gate */ 10527c478bd9Sstevel@tonic-gate static dev_info_t * 10537c478bd9Sstevel@tonic-gate path_to_devinfo(char *path) 10547c478bd9Sstevel@tonic-gate { 10557c478bd9Sstevel@tonic-gate struct i_path_findnode fn; 10567c478bd9Sstevel@tonic-gate extern dev_info_t *top_devinfo; 10577c478bd9Sstevel@tonic-gate 10587c478bd9Sstevel@tonic-gate /* 10597c478bd9Sstevel@tonic-gate * Get the nodeid of the given pathname, if such a mapping exists. 10607c478bd9Sstevel@tonic-gate */ 10617c478bd9Sstevel@tonic-gate fn.dip = NULL; 10627c478bd9Sstevel@tonic-gate fn.nodeid = prom_finddevice(path); 10637c478bd9Sstevel@tonic-gate if (fn.nodeid != OBP_BADNODE) { 10647c478bd9Sstevel@tonic-gate /* 10657c478bd9Sstevel@tonic-gate * Find the nodeid in our copy of the device tree and return 10667c478bd9Sstevel@tonic-gate * whatever name we used to bind this node to a driver. 10677c478bd9Sstevel@tonic-gate */ 10687c478bd9Sstevel@tonic-gate ddi_walk_devs(top_devinfo, i_path_find_node, (void *)(&fn)); 10697c478bd9Sstevel@tonic-gate } 10707c478bd9Sstevel@tonic-gate 10717c478bd9Sstevel@tonic-gate #ifdef DEBUG 10727c478bd9Sstevel@tonic-gate /* 10737c478bd9Sstevel@tonic-gate * If we're bound to something other than the nodename, 10747c478bd9Sstevel@tonic-gate * note that in the message buffer and system log. 10757c478bd9Sstevel@tonic-gate */ 10767c478bd9Sstevel@tonic-gate if (fn.dip) { 10777c478bd9Sstevel@tonic-gate char *p, *q; 10787c478bd9Sstevel@tonic-gate 10797c478bd9Sstevel@tonic-gate p = ddi_binding_name(fn.dip); 10807c478bd9Sstevel@tonic-gate q = ddi_node_name(fn.dip); 10817c478bd9Sstevel@tonic-gate if (p && q && (strcmp(p, q) != 0)) { 10827c478bd9Sstevel@tonic-gate BMDPRINTF(("path_to_devinfo: %s bound to %s\n", 10837c478bd9Sstevel@tonic-gate path, p)); 10847c478bd9Sstevel@tonic-gate } 10857c478bd9Sstevel@tonic-gate } 10867c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 10877c478bd9Sstevel@tonic-gate 10887c478bd9Sstevel@tonic-gate return (fn.dip); 10897c478bd9Sstevel@tonic-gate } 10907c478bd9Sstevel@tonic-gate 10917c478bd9Sstevel@tonic-gate /* 10927c478bd9Sstevel@tonic-gate * This routine returns B_TRUE if the bootpath corresponds to 10937c478bd9Sstevel@tonic-gate * IP over IB driver. 10947c478bd9Sstevel@tonic-gate * 10957c478bd9Sstevel@tonic-gate * The format of the bootpath for the IP over IB looks like 10967c478bd9Sstevel@tonic-gate * /pci@1f,700000/pci@1/ib@0:port=1,pkey=8001,protocol=ip 10977c478bd9Sstevel@tonic-gate * 10987c478bd9Sstevel@tonic-gate * The minor node portion "port=1,pkey=8001,protocol=ip" represents 10997c478bd9Sstevel@tonic-gate * IP over IB driver. 11007c478bd9Sstevel@tonic-gate */ 11017c478bd9Sstevel@tonic-gate static boolean_t 11027c478bd9Sstevel@tonic-gate netboot_over_ib(char *bootpath) 11037c478bd9Sstevel@tonic-gate { 11047c478bd9Sstevel@tonic-gate 11057c478bd9Sstevel@tonic-gate char *temp; 11067c478bd9Sstevel@tonic-gate boolean_t ret = B_FALSE; 1107fa9e4066Sahrens pnode_t node = prom_finddevice(bootpath); 11087c478bd9Sstevel@tonic-gate int len; 11097c478bd9Sstevel@tonic-gate char devicetype[OBP_MAXDRVNAME]; 11107c478bd9Sstevel@tonic-gate 11117c478bd9Sstevel@tonic-gate /* Is this IB node ? */ 1112dedec472SJack Meng if (node == OBP_BADNODE || node == OBP_NONODE) { 1113dedec472SJack Meng return (B_FALSE); 1114dedec472SJack Meng } 11157c478bd9Sstevel@tonic-gate len = prom_getproplen(node, OBP_DEVICETYPE); 11167c478bd9Sstevel@tonic-gate if (len <= 1 || len >= OBP_MAXDRVNAME) 11177c478bd9Sstevel@tonic-gate return (B_FALSE); 11187c478bd9Sstevel@tonic-gate 11197c478bd9Sstevel@tonic-gate (void) prom_getprop(node, OBP_DEVICETYPE, (caddr_t)devicetype); 11207c478bd9Sstevel@tonic-gate 11217c478bd9Sstevel@tonic-gate if (strncmp("ib", devicetype, 2) == 0) { 11227c478bd9Sstevel@tonic-gate /* Check for proper IP over IB string */ 11237c478bd9Sstevel@tonic-gate if ((temp = strstr(bootpath, ":port=")) != NULL) { 11247c478bd9Sstevel@tonic-gate if ((temp = strstr(temp, ",pkey=")) != NULL) 11257c478bd9Sstevel@tonic-gate if ((temp = strstr(temp, 11267c478bd9Sstevel@tonic-gate ",protocol=ip")) != NULL) { 11277c478bd9Sstevel@tonic-gate ret = B_TRUE; 11287c478bd9Sstevel@tonic-gate } 11297c478bd9Sstevel@tonic-gate } 11307c478bd9Sstevel@tonic-gate } 11317c478bd9Sstevel@tonic-gate return (ret); 11327c478bd9Sstevel@tonic-gate } 1133dedec472SJack Meng 1134dedec472SJack Meng static boolean_t 1135dedec472SJack Meng netboot_over_iscsi(void) 1136dedec472SJack Meng { 1137dedec472SJack Meng int proplen; 1138dedec472SJack Meng boolean_t ret = B_FALSE; 1139dedec472SJack Meng char bootpath[OBP_MAXPATHLEN]; 1140dedec472SJack Meng 1141dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_BOOTPATH); 1142dedec472SJack Meng if (proplen > 0) { 1143dedec472SJack Meng if (BOP_GETPROP(bootops, BP_BOOTPATH, bootpath) > 0) { 1144dedec472SJack Meng if (memcmp(bootpath, BP_ISCSI_DISK, 1145dedec472SJack Meng strlen(BP_ISCSI_DISK)) == 0) { 1146dedec472SJack Meng ret = B_TRUE; 1147dedec472SJack Meng } 1148dedec472SJack Meng } 1149dedec472SJack Meng } 1150dedec472SJack Meng return (ret); 1151dedec472SJack Meng } 1152