/* * Remove a scheduling class module. * * we only null out the init func and the class functions because * once a class has been loaded it has that slot in the class * array until the next reboot. We don't decrement loaded_classes * because this keeps count of the number of classes that have * been loaded for this session. It will have to be this way until * we implement the class array as a linked list and do true * dynamic allocation. */ static int mod_removesched(struct modlsched *modl, struct modlinkage *modlp) { int status; sclass_t *clp; struct modctl *mcp; char *modname; id_t cid; status = getcidbyname(modl->sched_class->cl_name, &cid); if (status != 0) { mcp = mod_getctl(modlp); ASSERT(mcp != NULL); modname = mcp->mod_modname; cmn_err(CE_WARN, uninstall_err, modname); return (EINVAL); } clp = &sclass[cid]; if (moddebug & MODDEBUG_NOAUL_SCHED || !rw_tryenter(clp->cl_lock, RW_WRITER)) return (EBUSY); clp->cl_init = NULL; clp->cl_funcs = NULL; rw_exit(clp->cl_lock); return (0); }
/* * Find a free sysent entry or check if the specified one is free. */ static struct sysent * mod_getsysent(struct modlinkage *modlp, struct sysent *se) { int sysnum; struct modctl *mcp; char *mod_name; if ((mcp = mod_getctl(modlp)) == NULL) { /* * This happens when we're looking up the module * pointer as part of a stub installation. So * there's no need to whine at this point. */ return (NULL); } mod_name = mcp->mod_modname; if ((sysnum = mod_getsysnum(mod_name)) == -1) { cmn_err(CE_WARN, "system call missing from bind file"); return (NULL); } if (sysnum > 0 && sysnum < NSYSCALL && (se[sysnum].sy_flags & (SE_LOADABLE | SE_NOUNLOAD))) return (se + sysnum); cmn_err(CE_WARN, "system call entry %d is already in use", sysnum); return (NULL); }
/** * Kernel entry points */ int _init(void) { LogFunc((DEVICE_NAME ":_init\n")); /* * Prevent module autounloading. */ modctl_t *pModCtl = mod_getctl(&g_VBoxNetAdpSolarisModLinkage); if (pModCtl) pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD; else LogRel((DEVICE_NAME ":failed to disable autounloading!\n")); /* * Initialize IPRT. */ int rc = RTR0Init(0); if (RT_SUCCESS(rc)) { rc = mod_install(&g_VBoxNetAdpSolarisModLinkage); if (!rc) return rc; LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc)); RTR0Term(); } else LogRel((DEVICE_NAME ":failed to initialize IPRT (rc=%d)\n", rc)); return RTErrConvertToErrno(rc); }
static int mod_installipp(struct modlipp *modl, struct modlinkage *modlp) { struct modctl *mcp = mod_getctl(modlp); ASSERT(mcp != NULL); return (ipp_mod_register(mcp->mod_modname, modl->ipp_ops)); }
static int mod_installdacf(struct modldacf *modl, struct modlinkage *modlp) { struct modctl *mcp; if ((mcp = mod_getctl(modlp)) == NULL) return (EINVAL); return (dacf_module_register(mcp->mod_modname, modl->dacf_dacfsw)); }
/*ARGSUSED*/ static int mod_removedacf(struct modldacf *modl, struct modlinkage *modlp) { struct modctl *mcp; if ((mcp = mod_getctl(modlp)) == NULL) return (EINVAL); return (dacf_module_unregister(mcp->mod_modname)); }
static int mod_installdev(struct modldev *modl, struct modlinkage *modlp) { struct modctl *mcp; if ((mcp = mod_getctl(modlp)) == NULL) return (EINVAL); return (sdev_module_register(mcp->mod_modname, modl->dev_ops)); }
/* * Get module name. */ char * mod_modname(struct modlinkage *modlp) { struct modctl *mcp; if ((mcp = mod_getctl(modlp)) == NULL) return (NULL); return (mcp->mod_modname); }
/*ARGSUSED*/ static int mod_infodev(struct modldev *modl, struct modlinkage *modlp, int *p0) { if (mod_getctl(modlp) == NULL) { *p0 = -1; return (0); /* module is not yet installed */ } *p0 = 0; return (0); }
/** * Kernel entry points */ int _init(void) { int rc; LogFunc((DEVICE_NAME ":_init\n")); g_pDip = NULL; /* * Prevent module autounloading. */ modctl_t *pModCtl = mod_getctl(&g_VBoxUSBMonSolarisModLinkage); if (pModCtl) pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD; else LogRel((DEVICE_NAME ":failed to disable autounloading!\n")); /* * Initialize IPRT R0 driver, which internally calls OS-specific r0 init. */ rc = RTR0Init(0); if (RT_SUCCESS(rc)) { /* * Initialize global mutex. */ mutex_init(&g_VBoxUSBMonSolarisMtx, NULL, MUTEX_DRIVER, NULL); rc = VBoxUSBFilterInit(); if (RT_SUCCESS(rc)) { rc = ddi_soft_state_init(&g_pVBoxUSBMonSolarisState, sizeof(vboxusbmon_state_t), 1); if (!rc) { rc = mod_install(&g_VBoxUSBMonSolarisModLinkage); if (!rc) return rc; LogRel((DEVICE_NAME ":mod_install failed! rc=%d\n", rc)); ddi_soft_state_fini(&g_pVBoxUSBMonSolarisState); } else LogRel((DEVICE_NAME ":ddi_soft_state_init failed! rc=%d\n", rc)); } else LogRel((DEVICE_NAME ":VBoxUSBFilterInit failed! rc=%d\n", rc)); mutex_destroy(&g_VBoxUSBMonSolarisMtx); RTR0Term(); } else LogRel((DEVICE_NAME ":RTR0Init failed! rc=%d\n", rc)); return -1; }
/*ARGSUSED*/ static int mod_infoipp(struct modlipp *modl, struct modlinkage *modlp, int *p0) { struct modctl *mcp = mod_getctl(modlp); ipp_mod_id_t mid; if (mcp == NULL) { *p0 = -1; return (0); /* module is not yet installed */ } mid = ipp_mod_lookup(mcp->mod_modname); *p0 = mid; return (0); }
/*ARGSUSED*/ static int mod_infodrv(struct modldrv *modl, struct modlinkage *modlp, int *p0) { struct modctl *mcp; char *mod_name; if ((mcp = mod_getctl(modlp)) == NULL) { *p0 = -1; return (0); /* driver is not yet installed */ } mod_name = mcp->mod_modname; *p0 = ddi_name_to_major(mod_name); return (0); }
/*ARGSUSED*/ static int mod_removeipp(struct modlipp *modl, struct modlinkage *modlp) { struct modctl *mcp = mod_getctl(modlp); extern kthread_id_t mod_aul_thread; ipp_mod_id_t mid; ASSERT(mcp != NULL); if ((moddebug & MODDEBUG_NOAUL_IPP) && (mod_aul_thread == curthread)) return (EBUSY); mid = ipp_mod_lookup(mcp->mod_modname); ASSERT(mid != IPP_MOD_INVAL); return (ipp_mod_unregister(mid)); }
/** * Kernel entry points */ int _init(void) { /* * Initialize IPRT R0 driver, which internally calls OS-specific r0 init. */ int rc = RTR0Init(0); if (RT_SUCCESS(rc)) { PRTLOGGER pRelLogger; static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; rc = RTLogCreate(&pRelLogger, 0 /* fFlags */, "all", "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER, NULL); if (RT_SUCCESS(rc)) RTLogRelSetDefaultInstance(pRelLogger); else cmn_err(CE_NOTE, "failed to initialize driver logging rc=%d!\n", rc); mutex_init(&g_LdiMtx, NULL, MUTEX_DRIVER, NULL); /* * Prevent module autounloading. */ modctl_t *pModCtl = mod_getctl(&g_VBoxGuestSolarisModLinkage); if (pModCtl) pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD; else LogRel((DEVICE_NAME ":failed to disable autounloading!\n")); rc = ddi_soft_state_init(&g_pVBoxGuestSolarisState, sizeof(vboxguest_state_t), 1); if (!rc) { rc = mod_install(&g_VBoxGuestSolarisModLinkage); if (rc) ddi_soft_state_fini(&g_pVBoxGuestSolarisState); } } else { cmn_err(CE_NOTE, "_init: RTR0Init failed. rc=%d\n", rc); return EINVAL; } return rc; }
/* * Remove a filesystem */ static int mod_removefs(struct modlfs *modl, struct modlinkage *modlp) { struct vfssw *vswp; struct modctl *mcp; char *modname; if (moddebug & MODDEBUG_NOAUL_FS) return (EBUSY); WLOCK_VFSSW(); if ((vswp = vfs_getvfsswbyname(modl->fs_vfsdef->name)) == NULL) { mcp = mod_getctl(modlp); ASSERT(mcp != NULL); modname = mcp->mod_modname; WUNLOCK_VFSSW(); cmn_err(CE_WARN, uninstall_err, modname); return (EINVAL); } if (vswp->vsw_count != 1) { vfs_unrefvfssw(vswp); WUNLOCK_VFSSW(); return (EBUSY); } /* XXX - Shouldn't the refcount be sufficient? */ if (vfs_opsinuse(&vswp->vsw_vfsops)) { vfs_unrefvfssw(vswp); WUNLOCK_VFSSW(); return (EBUSY); } vfs_freeopttbl(&vswp->vsw_optproto); vswp->vsw_optproto.mo_count = 0; vswp->vsw_flag = 0; vswp->vsw_init = NULL; vfs_unrefvfssw(vswp); WUNLOCK_VFSSW(); return (0); }
/* * Remove a loadable system call entry from a sysent table. */ static int mod_removesys_sysent( struct modlsys *modl, struct modlinkage *modlp, struct sysent table[]) { struct sysent *sysp; if ((sysp = mod_getsysent(modlp, table)) == NULL || (sysp->sy_flags & (SE_LOADABLE | SE_NOUNLOAD)) == 0 || sysp->sy_call != modl->sys_sysent->sy_call) { struct modctl *mcp = mod_getctl(modlp); char *modname = mcp->mod_modname; cmn_err(CE_WARN, uninstall_err, modname); return (EINVAL); } /* If we can't get the write lock, we can't unlink from the system */ if (!(moddebug & MODDEBUG_NOAUL_SYS) && rw_tryenter(sysp->sy_lock, RW_WRITER)) { /* * Check the flags to be sure the syscall is still * (un)loadable. * If SE_NOUNLOAD is set, SE_LOADABLE will not be. */ if ((sysp->sy_flags & (SE_LOADED | SE_LOADABLE)) == (SE_LOADED | SE_LOADABLE)) { sysp->sy_flags &= ~SE_LOADED; sysp->sy_callc = loadable_syscall; sysp->sy_call = (int (*)())nosys; rw_exit(sysp->sy_lock); return (0); } rw_exit(sysp->sy_lock); } return (EBUSY); }
/* * Install an exec module. */ static int mod_installexec(struct modlexec *modl, struct modlinkage *modlp) { struct execsw *eswp; struct modctl *mcp; char *modname; char *magic; size_t magic_size; /* * See if execsw entry is already allocated. Can't use findexectype() * because we may get a recursive call to here. */ if ((eswp = findexecsw(modl->exec_execsw->exec_magic)) == NULL) { mcp = mod_getctl(modlp); ASSERT(mcp != NULL); modname = mcp->mod_modname; magic = modl->exec_execsw->exec_magic; magic_size = modl->exec_execsw->exec_maglen; if ((eswp = allocate_execsw(modname, magic, magic_size)) == NULL) { printf("no unused entries in 'execsw'\n"); return (ENOSPC); } } if (eswp->exec_func != NULL) { printf("exec type %x is already installed\n", *eswp->exec_magic); return (EBUSY); /* it's already there! */ } rw_enter(eswp->exec_lock, RW_WRITER); eswp->exec_func = modl->exec_execsw->exec_func; eswp->exec_core = modl->exec_execsw->exec_core; rw_exit(eswp->exec_lock); return (0); }
/* * Remove an exec module. */ static int mod_removeexec(struct modlexec *modl, struct modlinkage *modlp) { struct execsw *eswp; struct modctl *mcp; char *modname; eswp = findexecsw(modl->exec_execsw->exec_magic); if (eswp == NULL) { mcp = mod_getctl(modlp); ASSERT(mcp != NULL); modname = mcp->mod_modname; cmn_err(CE_WARN, uninstall_err, modname); return (EINVAL); } if (moddebug & MODDEBUG_NOAUL_EXEC || !rw_tryenter(eswp->exec_lock, RW_WRITER)) return (EBUSY); eswp->exec_func = NULL; eswp->exec_core = NULL; rw_exit(eswp->exec_lock); return (0); }
/** * Kernel entry points */ int _init(void) { LogFlowFunc((VIRTIOLOGNAME ":_init\n")); /* * Prevent module autounloading. */ modctl_t *pModCtl = mod_getctl(&g_VirtioNetModLinkage); if (pModCtl) pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD; else LogRel((VIRTIOLOGNAME ":failed to disable autounloading!\n")); /* * Initialize IPRT. */ int rc = RTR0Init(0); if (RT_SUCCESS(rc)) { /* * Initialize Solaris specific globals here. */ mac_init_ops(&g_VirtioNetDevOps, DEVICE_NAME); rc = mod_install(&g_VirtioNetModLinkage); if (!rc) return rc; LogRel((VIRTIOLOGNAME ":mod_install failed. rc=%d\n", rc)); mac_fini_ops(&g_VirtioNetDevOps); RTR0Term(); return rc; } else LogRel((VIRTIOLOGNAME ":failed to initialize IPRT (rc=%d)\n", rc)); return RTErrConvertToErrno(rc); }
/** * Kernel entry points */ int _init(void) { #if 0 /* No IPRT logging before RTR0Init() is done! */ LogFlowFunc(("vboxdrv:_init\n")); #endif /* * Prevent module autounloading. */ modctl_t *pModCtl = mod_getctl(&g_VBoxDrvSolarisModLinkage); if (pModCtl) pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD; else cmn_err(CE_NOTE, "vboxdrv: failed to disable autounloading!\n"); /* * Initialize IPRT R0 driver, which internally calls OS-specific r0 init. */ int rc = RTR0Init(0); if (RT_SUCCESS(rc)) { /* * Initialize the device extension */ rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION)); if (RT_SUCCESS(rc)) { cmn_err(CE_CONT, "!tsc::mode %s @ tentative %lu Hz\n", SUPGetGIPModeName(g_DevExt.pGip), g_DevExt.pGip->u64CpuHz); /* * Initialize the session hash table. */ memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab)); rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvSol"); if (RT_SUCCESS(rc)) { rc = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof(vbox_devstate_t), 8); if (!rc) { rc = mod_install(&g_VBoxDrvSolarisModLinkage); if (!rc) return rc; /* success */ ddi_soft_state_fini(&g_pVBoxDrvSolarisState); LogRel(("vboxdrv: mod_install failed! rc=%d\n", rc)); } else LogRel(("vboxdrv: failed to initialize soft state.\n")); RTSpinlockDestroy(g_Spinlock); g_Spinlock = NIL_RTSPINLOCK; } else { LogRel(("VBoxDrvSolarisAttach: RTSpinlockCreate failed\n")); rc = RTErrConvertToErrno(rc); } supdrvDeleteDevExt(&g_DevExt); } else { LogRel(("VBoxDrvSolarisAttach: supdrvInitDevExt failed\n")); rc = EINVAL; } RTR0TermForced(); } else { LogRel(("VBoxDrvSolarisAttach: failed to init R0Drv\n")); rc = RTErrConvertToErrno(rc); } memset(&g_DevExt, 0, sizeof(g_DevExt)); return rc; }
/*ARGSUSED1*/ static int mod_installfs(struct modlfs *modl, struct modlinkage *modlp) { struct vfssw *vswp; struct modctl *mcp; char *fsname; char ksname[KSTAT_STRLEN + 1]; int fstype; /* index into vfssw[] and vsanchor_fstype[] */ int allocated; int err; int vsw_stats_enabled; /* Not for public consumption so these aren't in a header file */ extern int vopstats_enabled; extern vopstats_t **vopstats_fstype; extern kstat_t *new_vskstat(char *, vopstats_t *); extern void initialize_vopstats(vopstats_t *); if (modl->fs_vfsdef->def_version == VFSDEF_VERSION) { /* Version matched */ fsname = modl->fs_vfsdef->name; } else { if ((modl->fs_vfsdef->def_version > 0) && (modl->fs_vfsdef->def_version < VFSDEF_VERSION)) { /* Older VFSDEF_VERSION */ fsname = modl->fs_vfsdef->name; } else if ((mcp = mod_getctl(modlp)) != NULL) { /* Pre-VFSDEF_VERSION */ fsname = mcp->mod_modname; } else { /* If all else fails... */ fsname = "<unknown file system type>"; } cmn_err(CE_WARN, "file system '%s' version mismatch", fsname); return (ENXIO); } allocated = 0; WLOCK_VFSSW(); if ((vswp = vfs_getvfsswbyname(fsname)) == NULL) { if ((vswp = allocate_vfssw(fsname)) == NULL) { WUNLOCK_VFSSW(); /* * See 1095689. If this message appears, then * we either need to make the vfssw table bigger * statically, or make it grow dynamically. */ cmn_err(CE_WARN, "no room for '%s' in vfssw!", fsname); return (ENXIO); } allocated = 1; } ASSERT(vswp != NULL); fstype = vswp - vfssw; /* Pointer arithmetic to get the fstype */ /* Turn on everything by default *except* VSW_STATS */ vswp->vsw_flag = modl->fs_vfsdef->flags & ~(VSW_STATS); if (modl->fs_vfsdef->flags & VSW_HASPROTO) { vfs_mergeopttbl(&vfs_mntopts, modl->fs_vfsdef->optproto, &vswp->vsw_optproto); } else { vfs_copyopttbl(&vfs_mntopts, &vswp->vsw_optproto); } if (modl->fs_vfsdef->flags & VSW_CANRWRO) { /* * This obviously implies VSW_CANREMOUNT. */ vswp->vsw_flag |= VSW_CANREMOUNT; } /* * If stats are enabled system wide and for this fstype, then * set the VSW_STATS flag in the proper vfssw[] table entry. */ if (vopstats_enabled && modl->fs_vfsdef->flags & VSW_STATS) { vswp->vsw_flag |= VSW_STATS; } if (modl->fs_vfsdef->init == NULL) err = EFAULT; else err = (*(modl->fs_vfsdef->init))(fstype, fsname); if (err != 0) { if (allocated) { kmem_free(vswp->vsw_name, strlen(vswp->vsw_name)+1); vswp->vsw_name = ""; } vswp->vsw_flag = 0; vswp->vsw_init = NULL; } /* We don't want to hold the vfssw[] write lock over a kmem_alloc() */ vsw_stats_enabled = vswp->vsw_flag & VSW_STATS; vfs_unrefvfssw(vswp); WUNLOCK_VFSSW(); /* If everything is on, set up the per-fstype vopstats */ if (vsw_stats_enabled && vopstats_enabled && vopstats_fstype && vopstats_fstype[fstype] == NULL) { (void) strlcpy(ksname, VOPSTATS_STR, sizeof (ksname)); (void) strlcat(ksname, vfssw[fstype].vsw_name, sizeof (ksname)); vopstats_fstype[fstype] = kmem_alloc(sizeof (vopstats_t), KM_SLEEP); initialize_vopstats(vopstats_fstype[fstype]); (void) new_vskstat(ksname, vopstats_fstype[fstype]); } return (err); }
static int mod_removedrv(struct modldrv *modl, struct modlinkage *modlp) { struct modctl *mcp; struct dev_ops *ops; struct devnames *dnp; struct dev_ops *dp; major_t major; char *modname; extern kthread_id_t mod_aul_thread; struct streamtab *str; cdevsw_impl_t *cdp; int err = 0; /* Don't auto unload modules on if moddebug flag is set */ if ((moddebug & MODDEBUG_NOAUL_DRV) && (mod_aul_thread == curthread)) { err = EBUSY; goto done; } /* Verify modname has a driver major */ mcp = mod_getctl(modlp); ASSERT(mcp != NULL); modname = mcp->mod_modname; if ((major = ddi_name_to_major(modname)) == -1) { cmn_err(CE_WARN, uninstall_err, modname); err = EINVAL; goto done; } ops = modl->drv_dev_ops; dnp = &(devnamesp[major]); LOCK_DEV_OPS(&(dnp->dn_lock)); dp = devopsp[major]; if (dp != ops) { cmn_err(CE_NOTE, "mod_removedrv: mismatched driver for %s", modname); err = EBUSY; goto unlock; } /* * A driver is not unloadable if its dev_ops are held */ if (!DRV_UNLOADABLE(dp)) { mod_dprintf(DRV_DBG, "Cannot unload device driver <%s>," " refcnt %d\n", modname, dp->devo_refcnt); err = EBUSY; goto unlock; } /* * OK to unload. */ if ((str = STREAMSTAB(major)) != NULL) { /* streams driver */ cdp = &devimpl[major]; ASSERT(cdp->d_str == str); cdp->d_str = NULL; /* check for reference to per-dev syncq */ if (cdp->d_dmp != NULL) { rele_dm(cdp->d_dmp); cdp->d_dmp = NULL; } } devopsp[major] = &mod_nodev_ops; dnp->dn_flags &= ~(DN_DRIVER_HELD|DN_NO_AUTODETACH); unlock: UNLOCK_DEV_OPS(&(dnp->dn_lock)); done: return (err); }
/* * Install a new driver */ static int mod_installdrv(struct modldrv *modl, struct modlinkage *modlp) { struct modctl *mcp; struct dev_ops *ops; char *modname; major_t major; struct dev_ops *dp; struct devnames *dnp; struct streamtab *str; cdevsw_impl_t *cdp; uint_t sqtype; uint_t qflag; uint_t flag; int err = 0; /* sanity check module */ if ((mcp = mod_getctl(modlp)) == NULL) { cmn_err(CE_WARN, "mod_install: bad module linkage data"); err = ENXIO; goto done; } modname = mcp->mod_modname; /* Sanity check modname */ if ((major = ddi_name_to_major(modname)) == (major_t)-1) { #ifdef DEBUG cmn_err(CE_WARN, "mod_installdrv: no major number for %s", modname); #endif err = ENXIO; goto done; } /* Verify MP safety flag */ ops = modl->drv_dev_ops; if (ops->devo_bus_ops == NULL && ops->devo_cb_ops != NULL && !(ops->devo_cb_ops->cb_flag & D_MP)) { cmn_err(CE_WARN, "mod_installdrv: MT-unsafe driver '%s' rejected", modname); err = ENXIO; goto done; } /* Is bus_map_fault signature correct (version 8 and higher)? */ if (ops->devo_bus_ops != NULL && ops->devo_bus_ops->bus_map_fault != NULL && ops->devo_bus_ops->bus_map_fault != i_ddi_map_fault && ops->devo_bus_ops->busops_rev < BUSO_REV_8) { cmn_err(CE_WARN, "mod_installdrv: busops' revision of '%s' is too low" " (must be at least 8)", modname); err = ENXIO; goto done; } /* Make sure the driver is uninstalled */ dnp = &devnamesp[major]; LOCK_DEV_OPS(&dnp->dn_lock); dp = devopsp[major]; if (dnp->dn_flags & DN_DRIVER_REMOVED) { #ifdef DEBUG cmn_err(CE_NOTE, "mod_installdrv: driver has been removed %s", modname); #endif err = ENXIO; goto unlock; } if (dp != &nodev_ops && dp != &mod_nodev_ops) { cmn_err(CE_WARN, "mod_installdrv: driver already installed %s", modname); err = EALREADY; goto unlock; } devopsp[major] = ops; /* setup devopsp */ if ((str = STREAMSTAB(major)) != NULL) { /* streams driver */ flag = CBFLAG(major); if ((err = devflg_to_qflag(str, flag, &qflag, &sqtype)) != 0) goto unlock; cdp = &devimpl[major]; ASSERT(cdp->d_str == NULL); cdp->d_str = str; cdp->d_qflag = qflag | QISDRV; cdp->d_sqtype = sqtype; } if (ops->devo_bus_ops == NULL) dnp->dn_flags |= DN_LEAF_DRIVER; unlock: UNLOCK_DEV_OPS(&dnp->dn_lock); done: return (err); }
/** * Kernel entry points */ int _init(void) { LogFlowFunc((DEVICE_NAME ":_init\n")); /* * Prevent module autounloading. */ modctl_t *pModCtl = mod_getctl(&g_VBoxDrvSolarisModLinkage); if (pModCtl) pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD; else LogRel((DEVICE_NAME ":failed to disable autounloading!\n")); /* * Initialize IPRT R0 driver, which internally calls OS-specific r0 init. */ int rc = RTR0Init(0); if (RT_SUCCESS(rc)) { /* * Initialize the device extension */ rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION)); if (RT_SUCCESS(rc)) { /* * Initialize the session hash table. */ memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab)); rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvSol"); if (RT_SUCCESS(rc)) { rc = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof(vbox_devstate_t), 8); if (!rc) { rc = mod_install(&g_VBoxDrvSolarisModLinkage); if (!rc) return rc; /* success */ ddi_soft_state_fini(&g_pVBoxDrvSolarisState); LogRel((DEVICE_NAME ":mod_install failed! rc=%d\n", rc)); } else LogRel((DEVICE_NAME ":failed to initialize soft state.\n")); RTSpinlockDestroy(g_Spinlock); g_Spinlock = NIL_RTSPINLOCK; } else { LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: RTSpinlockCreate failed\n")); rc = RTErrConvertToErrno(rc); } supdrvDeleteDevExt(&g_DevExt); } else { LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: supdrvInitDevExt failed\n")); rc = RTErrConvertToErrno(rc); } RTR0TermForced(); } else { LogRel((DEVICE_NAME ":VBoxDrvSolarisAttach: failed to init R0Drv\n")); rc = RTErrConvertToErrno(rc); } memset(&g_DevExt, 0, sizeof(g_DevExt)); return rc; }