예제 #1
0
/**
 * Stop the kernel module.
 */
static kern_return_t vgdrvDarwinStop(struct kmod_info *pKModInfo, void *pvData)
{
    RTR0TermForced();

    printf("VBoxGuest: driver unloaded\n");
    return KMOD_RETURN_SUCCESS;
}
/**
 * Stop the kernel module.
 */
static kern_return_t VbgdDarwinStop(struct kmod_info *pKModInfo, void *pvData)
{
    RTR0TermForced();
#ifdef DEBUG
    printf("VbgdDarwinStop - done\n");
#endif
    return KMOD_RETURN_SUCCESS;
}
예제 #3
0
/**
 * Unload the module.
 */
static void __exit VBoxDrvLinuxUnload(void)
{
    int                 rc;
    Log(("VBoxDrvLinuxUnload\n"));
    NOREF(rc);

#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
    platform_device_unregister(&gPlatformDevice);
    platform_driver_unregister(&gPlatformDriver);
#endif

    /*
     * I Don't think it's possible to unload a driver which processes have
     * opened, at least we'll blindly assume that here.
     */
#ifdef CONFIG_VBOXDRV_AS_MISC
    rc = misc_deregister(&gMiscDeviceUsr);
    if (rc < 0)
    {
        Log(("misc_deregister failed with rc=%#x on vboxdrvu\n", rc));
    }
    rc = misc_deregister(&gMiscDeviceSys);
    if (rc < 0)
    {
        Log(("misc_deregister failed with rc=%#x on vboxdrv\n", rc));
    }
#else  /* !CONFIG_VBOXDRV_AS_MISC */
# ifdef CONFIG_DEVFS_FS
    /*
     * Unregister a device entry
     */
    devfs_remove(DEVICE_NAME_USR);
    devfs_remove(DEVICE_NAME_SYS);
# endif /* devfs */
    unregister_chrdev(g_iModuleMajorUsr, DEVICE_NAME_USR);
    unregister_chrdev(g_iModuleMajorSys, DEVICE_NAME_SYS);
#endif /* !CONFIG_VBOXDRV_AS_MISC */

    /*
     * Destroy GIP, delete the device extension and terminate IPRT.
     */
    supdrvDeleteDevExt(&g_DevExt);
    RTR0TermForced();
}
static int VBoxDrvFreeBSDUnload(void)
{
    Log(("VBoxDrvFreeBSDUnload:\n"));

    if (g_cUsers > 0)
        return VERR_RESOURCE_BUSY;

    /*
     * Reserve what we did in VBoxDrvFreeBSDInit.
     */
    destroy_dev(g_pVBoxDrvFreeBSDChrDevUsr);
    destroy_dev(g_pVBoxDrvFreeBSDChrDevSys);

    supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt);

    RTR0TermForced();

    memset(&g_VBoxDrvFreeBSDDevExt, 0, sizeof(g_VBoxDrvFreeBSDDevExt));
    return VINF_SUCCESS;
}
예제 #5
0
/**
 * Stop the kernel module.
 */
static kern_return_t    VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData)
{
    int rc;
    LogFlow(("VBoxDrvDarwinStop\n"));

    /** @todo I've got a nagging feeling that we'll have to keep track of users and refuse
     * unloading if we're busy. Investigate and implement this! */

    /*
     * Undo the work done during start (in reverse order).
     */
    if (g_pSleepNotifier)
    {
        g_pSleepNotifier->remove();
        g_pSleepNotifier = NULL;
    }

    devfs_remove(g_hDevFsDeviceUsr);
    g_hDevFsDeviceUsr = NULL;

    devfs_remove(g_hDevFsDeviceSys);
    g_hDevFsDeviceSys = NULL;

    rc = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
    Assert(rc == g_iMajorDeviceNo);
    g_iMajorDeviceNo = -1;

    supdrvDeleteDevExt(&g_DevExt);

    rc = RTSpinlockDestroy(g_Spinlock);
    AssertRC(rc);
    g_Spinlock = NIL_RTSPINLOCK;

    RTR0TermForced();

    memset(&g_DevExt, 0, sizeof(g_DevExt));
#ifdef DEBUG
    printf("VBoxDrvDarwinStop - done\n");
#endif
    return KMOD_RETURN_SUCCESS;
}
int _fini(void)
{
    LogFlowFunc(("vboxdrv:_fini\n"));

    /*
     * Undo the work we did at start (in the reverse order).
     */
    int rc = mod_remove(&g_VBoxDrvSolarisModLinkage);
    if (rc != 0)
        return rc;

    supdrvDeleteDevExt(&g_DevExt);

    rc = RTSpinlockDestroy(g_Spinlock);
    AssertRC(rc);
    g_Spinlock = NIL_RTSPINLOCK;

    RTR0TermForced();

    memset(&g_DevExt, 0, sizeof(g_DevExt));

    ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
    return 0;
}
/**
 * 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;
}
예제 #8
0
/**
 * Initialize module.
 *
 * @returns appropriate status code.
 */
static int __init VBoxDrvLinuxInit(void)
{
    int       rc;

    /*
     * Check for synchronous/asynchronous TSC mode.
     */
    printk(KERN_DEBUG "vboxdrv: Found %u processor cores\n", (unsigned)RTMpGetOnlineCount());
#ifdef CONFIG_VBOXDRV_AS_MISC
    rc = misc_register(&gMiscDeviceSys);
    if (rc)
    {
        printk(KERN_ERR "vboxdrv: Can't register system misc device! rc=%d\n", rc);
        return rc;
    }
    rc = misc_register(&gMiscDeviceUsr);
    if (rc)
    {
        printk(KERN_ERR "vboxdrv: Can't register user misc device! rc=%d\n", rc);
        misc_deregister(&gMiscDeviceSys);
        return rc;
    }
#else  /* !CONFIG_VBOXDRV_AS_MISC */
    /*
     * Register character devices and save the returned major numbers.
     */
    /* /dev/vboxdrv */
    g_iModuleMajorSys = DEVICE_MAJOR_SYS;
    rc = register_chrdev((dev_t)g_iModuleMajorSys, DEVICE_NAME_SYS, &gFileOpsVBoxDrvSys);
    if (rc < 0)
    {
        Log(("register_chrdev() failed with rc=%#x for vboxdrv!\n", rc));
        return rc;
    }
    if (DEVICE_MAJOR_SYS != 0)
        g_iModuleMajorSys = DEVICE_MAJOR_SYS;
    else
        g_iModuleMajorSys = rc;

    /* /dev/vboxdrvu */
    /** @todo Use a minor number of this bugger (not sure if this code is used
     *        though, so not bothering right now.) */
    g_iModuleMajorUsr = DEVICE_MAJOR_USR;
    rc = register_chrdev((dev_t)g_iModuleMajorUsr, DEVICE_NAME_USR, &gFileOpsVBoxDrvUsr);
    if (rc < 0)
    {
        Log(("register_chrdev() failed with rc=%#x for vboxdrv!\n", rc));
        return rc;
    }
    if (DEVICE_MAJOR_USR != 0)
        g_iModuleMajorUsr = DEVICE_MAJOR_USR;
    else
        g_iModuleMajorUsr = rc;
    rc = 0;

# ifdef CONFIG_DEVFS_FS
    /*
     * Register a device entry
     */
    if (   devfs_mk_cdev(MKDEV(DEVICE_MAJOR_SYS, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME_SYS) != 0
        || devfs_mk_cdev(MKDEV(DEVICE_MAJOR_USR, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME_USR) != 0)
    {
        Log(("devfs_register failed!\n"));
        rc = -EINVAL;
    }
# endif
#endif /* !CONFIG_VBOXDRV_AS_MISC */
    if (!rc)
    {
        /*
         * Initialize the runtime.
         * On AMD64 we'll have to donate the high rwx memory block to the exec allocator.
         */
        rc = RTR0Init(0);
        if (RT_SUCCESS(rc))
        {
#if (defined(RT_ARCH_AMD64) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)) || defined(VBOX_WITH_TEXT_MODMEM_HACK)
# ifdef VBOX_WITH_TEXT_MODMEM_HACK
            set_memory_x(&g_abExecMemory[0], sizeof(g_abExecMemory) / PAGE_SIZE);
            set_memory_rw(&g_abExecMemory[0], sizeof(g_abExecMemory) / PAGE_SIZE);
# endif
            rc = RTR0MemExecDonate(&g_abExecMemory[0], sizeof(g_abExecMemory));
            printk(KERN_DEBUG "VBoxDrv: dbg - g_abExecMemory=%p\n", (void *)&g_abExecMemory[0]);
#endif
            Log(("VBoxDrv::ModuleInit\n"));

            /*
             * Initialize the device extension.
             */
            if (RT_SUCCESS(rc))
                rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
            if (RT_SUCCESS(rc))
            {
#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
                rc = platform_driver_register(&gPlatformDriver);
                if (rc == 0)
                {
                    rc = platform_device_register(&gPlatformDevice);
                    if (rc == 0)
#endif
                    {
                        printk(KERN_INFO "vboxdrv: TSC mode is %s, tentative frequency %llu Hz\n",
                               SUPGetGIPModeName(g_DevExt.pGip), g_DevExt.pGip->u64CpuHz);
                        LogFlow(("VBoxDrv::ModuleInit returning %#x\n", rc));
                        printk(KERN_DEBUG "vboxdrv: Successfully loaded version "
                                VBOX_VERSION_STRING " (interface " RT_XSTR(SUPDRV_IOC_VERSION) ")\n");
                        return rc;
                    }
#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
                    else
                        platform_driver_unregister(&gPlatformDriver);
                }
#endif
            }

            rc = -EINVAL;
            RTR0TermForced();
        }
        else
            rc = -EINVAL;

        /*
         * Failed, cleanup and return the error code.
         */
#if defined(CONFIG_DEVFS_FS) && !defined(CONFIG_VBOXDRV_AS_MISC)
        devfs_remove(DEVICE_NAME_SYS);
        devfs_remove(DEVICE_NAME_USR);
#endif
    }
#ifdef CONFIG_VBOXDRV_AS_MISC
    misc_deregister(&gMiscDeviceSys);
    misc_deregister(&gMiscDeviceUsr);
    Log(("VBoxDrv::ModuleInit returning %#x (minor:%d & %d)\n", rc, gMiscDeviceSys.minor, gMiscDeviceUsr.minor));
#else
    unregister_chrdev(g_iModuleMajorUsr, DEVICE_NAME_USR);
    unregister_chrdev(g_iModuleMajorSys, DEVICE_NAME_SYS);
    Log(("VBoxDrv::ModuleInit returning %#x (major:%d & %d)\n", rc, g_iModuleMajorSys, g_iModuleMajorUsr));
#endif
    return rc;
}
예제 #9
0
/**
 * Start the kernel module.
 */
static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData)
{
    int rc;
#ifdef DEBUG
    printf("VBoxDrvDarwinStart\n");
#endif

    /*
     * Initialize IPRT.
     */
    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)); /* paranoia */
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvDarwin");
            if (RT_SUCCESS(rc))
            {
                /*
                 * Registering ourselves as a character device.
                 */
                g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
                if (g_iMajorDeviceNo >= 0)
                {
#ifdef VBOX_WITH_HARDENING
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME_SYS);
#else
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
#endif
                    if (g_hDevFsDeviceSys)
                    {
                        g_hDevFsDeviceUsr = devfs_make_node(makedev(g_iMajorDeviceNo, 1), DEVFS_CHAR,
                                                            UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_USR);
                        if (g_hDevFsDeviceUsr)
                        {
                            LogRel(("VBoxDrv: version " VBOX_VERSION_STRING " r%d; IOCtl version %#x; IDC version %#x; dev major=%d\n",
                                    VBOX_SVN_REV, SUPDRV_IOC_VERSION, SUPDRV_IDC_VERSION, g_iMajorDeviceNo));

                            /* Register a sleep/wakeup notification callback */
                            g_pSleepNotifier = registerPrioritySleepWakeInterest(&VBoxDrvDarwinSleepHandler, &g_DevExt, NULL);
                            if (g_pSleepNotifier == NULL)
                                LogRel(("VBoxDrv: register for sleep/wakeup events failed\n"));

                            /* Find kernel symbols that are kind of optional. */
                            vboxdrvDarwinResolveSymbols();
                            return KMOD_RETURN_SUCCESS;
                        }

                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,1),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_USR));
                        devfs_remove(g_hDevFsDeviceSys);
                        g_hDevFsDeviceSys = NULL;
                    }
                    else
                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_SYS));

                    cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
                    g_iMajorDeviceNo = -1;
                }
                else
                    LogRel(("VBoxDrv: cdevsw_add failed (%d)\n", g_iMajorDeviceNo));
                RTSpinlockDestroy(g_Spinlock);
                g_Spinlock = NIL_RTSPINLOCK;
            }
            else
                LogRel(("VBoxDrv: RTSpinlockCreate failed (rc=%d)\n", rc));
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
            printf("VBoxDrv: failed to initialize device extension (rc=%d)\n", rc);
        RTR0TermForced();
    }
    else
        printf("VBoxDrv: failed to initialize IPRT (rc=%d)\n", rc);

    memset(&g_DevExt, 0, sizeof(g_DevExt));
    return KMOD_RETURN_FAILURE;
}
예제 #10
0
/**
 * 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;
}
예제 #11
0
/**
 * Initialize module.
 *
 * @returns appropriate status code.
 */
static int __init VBoxDrvLinuxInit(void)
{
    int       rc;

    /*
     * Check for synchronous/asynchronous TSC mode.
     */
    printk(KERN_DEBUG DEVICE_NAME ": Found %u processor cores.\n", (unsigned)RTMpGetOnlineCount());
#ifdef CONFIG_VBOXDRV_AS_MISC
    rc = misc_register(&gMiscDevice);
    if (rc)
    {
        printk(KERN_ERR DEVICE_NAME ": Can't register misc device! rc=%d\n", rc);
        return rc;
    }
#else  /* !CONFIG_VBOXDRV_AS_MISC */
    /*
     * Register character device.
     */
    g_iModuleMajor = DEVICE_MAJOR;
    rc = register_chrdev((dev_t)g_iModuleMajor, DEVICE_NAME, &gFileOpsVBoxDrv);
    if (rc < 0)
    {
        Log(("register_chrdev() failed with rc=%#x!\n", rc));
        return rc;
    }

    /*
     * Save returned module major number
     */
    if (DEVICE_MAJOR != 0)
        g_iModuleMajor = DEVICE_MAJOR;
    else
        g_iModuleMajor = rc;
    rc = 0;

# ifdef CONFIG_DEVFS_FS
    /*
     * Register a device entry
     */
    if (devfs_mk_cdev(MKDEV(DEVICE_MAJOR, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME) != 0)
    {
        Log(("devfs_register failed!\n"));
        rc = -EINVAL;
    }
# endif
#endif /* !CONFIG_VBOXDRV_AS_MISC */
    if (!rc)
    {
        /*
         * Initialize the runtime.
         * On AMD64 we'll have to donate the high rwx memory block to the exec allocator.
         */
        rc = RTR0Init(0);
        if (RT_SUCCESS(rc))
        {
#if defined(RT_ARCH_AMD64) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
            rc = RTR0MemExecDonate(&g_abExecMemory[0], sizeof(g_abExecMemory));
            printk(KERN_DEBUG "VBoxDrv: dbg - g_abExecMemory=%p\n", (void *)&g_abExecMemory[0]);
#endif
            Log(("VBoxDrv::ModuleInit\n"));

            /*
             * Initialize the device extension.
             */
            if (RT_SUCCESS(rc))
                rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
            if (RT_SUCCESS(rc))
            {
#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
                rc = platform_driver_register(&gPlatformDriver);
                if (rc == 0)
                {
                    rc = platform_device_register(&gPlatformDevice);
                    if (rc == 0)
#endif
                    {
                        printk(KERN_INFO DEVICE_NAME ": TSC mode is %s, kernel timer mode is 'normal'.\n",
                               g_DevExt.pGip->u32Mode == SUPGIPMODE_SYNC_TSC ? "'synchronous'" : "'asynchronous'");
                        LogFlow(("VBoxDrv::ModuleInit returning %#x\n", rc));
                        printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version "
                                VBOX_VERSION_STRING " (interface " RT_XSTR(SUPDRV_IOC_VERSION) ").\n");
                        return rc;
                    }
#ifdef VBOX_WITH_SUSPEND_NOTIFICATION
                    else
                        platform_driver_unregister(&gPlatformDriver);
                }
#endif
            }

            rc = -EINVAL;
            RTR0TermForced();
        }
        else
            rc = -EINVAL;

        /*
         * Failed, cleanup and return the error code.
         */
#if defined(CONFIG_DEVFS_FS) && !defined(CONFIG_VBOXDRV_AS_MISC)
        devfs_remove(DEVICE_NAME);
#endif
    }
#ifdef CONFIG_VBOXDRV_AS_MISC
    misc_deregister(&gMiscDevice);
    Log(("VBoxDrv::ModuleInit returning %#x (minor:%d)\n", rc, gMiscDevice.minor));
#else
    unregister_chrdev(g_iModuleMajor, DEVICE_NAME);
    Log(("VBoxDrv::ModuleInit returning %#x (major:%d)\n", rc, g_iModuleMajor));
#endif
    return rc;
}