* Ed Schouten <e...@80386.nl>, 20111031 11:26: > I think I'll take a closer look at this code more thoroughly sometime > this week.
Ugh. Too impatient. Please try the attached patch. It should build on 7.x and higher. I have only compile-tested it, because I am not a VirtualBox user (yet). | SUPDrv-freebsd.c | 153 ++++++----------------------------------------- | 1 file changed, 21 insertions(+), 132 deletions(-) -- Ed Schouten <e...@80386.nl> WWW: http://80386.nl/
--- src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c +++ src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c @@ -69,10 +69,9 @@ static int VBoxDrvFreeBSDModuleEvent(struct module *pMod, int enmEventType, void *pvArg); static int VBoxDrvFreeBSDLoad(void); static int VBoxDrvFreeBSDUnload(void); -static void VBoxDrvFreeBSDClone(void *pvArg, struct ucred *pCred, char *pachName, int cchName, struct cdev **ppDev); -static d_fdopen_t VBoxDrvFreeBSDOpen; -static d_close_t VBoxDrvFreeBSDClose; +static d_open_t VBoxDrvFreeBSDOpen; +static void VBoxDrvFreeBSDDtr(void *pData); static d_ioctl_t VBoxDrvFreeBSDIOCtl; static int VBoxDrvFreeBSDIOCtlSlow(PSUPDRVSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd); @@ -100,21 +99,13 @@ static struct cdevsw g_VBoxDrvFreeBSDChrDevSW = { .d_version = D_VERSION, -#if __FreeBSD_version > 800061 - .d_flags = D_PSEUDO | D_TRACKCLOSE | D_NEEDMINOR, -#else - .d_flags = D_PSEUDO | D_TRACKCLOSE, -#endif - .d_fdopen = VBoxDrvFreeBSDOpen, - .d_close = VBoxDrvFreeBSDClose, + .d_open = VBoxDrvFreeBSDOpen, .d_ioctl = VBoxDrvFreeBSDIOCtl, .d_name = "vboxdrv" }; /** List of cloned device. Managed by the kernel. */ -static struct clonedevs *g_pVBoxDrvFreeBSDClones; -/** The dev_clone event handler tag. */ -static eventhandler_tag g_VBoxDrvFreeBSDEHTag; +static struct cdev *g_pVBoxDrvFreeBSDChrDev; /** Reference counter. */ static volatile uint32_t g_cUsers; @@ -176,20 +167,10 @@ if (RT_SUCCESS(rc)) { /* - * Configure device cloning. + * Configure character device. */ - clone_setup(&g_pVBoxDrvFreeBSDClones); - g_VBoxDrvFreeBSDEHTag = EVENTHANDLER_REGISTER(dev_clone, VBoxDrvFreeBSDClone, 0, 1000); - if (g_VBoxDrvFreeBSDEHTag) - { - Log(("VBoxDrvFreeBSDLoad: returns successfully\n")); - return VINF_SUCCESS; - } - - printf("vboxdrv: EVENTHANDLER_REGISTER(dev_clone,,,) failed\n"); - clone_cleanup(&g_pVBoxDrvFreeBSDClones); - rc = VERR_ALREADY_LOADED; - supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt); + g_pVBoxDrvFreeBSDChrDev = make_dev(&g_VBoxDrvFreeBSDChrDevSW, 0, UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv"); + return VINF_SUCCESS; } else printf("vboxdrv: supdrvInitDevExt failed, rc=%d\n", rc); @@ -210,8 +191,7 @@ /* * Reserve what we did in VBoxDrvFreeBSDInit. */ - EVENTHANDLER_DEREGISTER(dev_clone, g_VBoxDrvFreeBSDEHTag); - clone_cleanup(&g_pVBoxDrvFreeBSDClones); + destroy_dev(g_pVBoxDrvFreeBSDChrDev); supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt); @@ -225,59 +205,6 @@ /** - * DEVFS event handler. - */ -static void VBoxDrvFreeBSDClone(void *pvArg, struct ucred *pCred, char *pszName, int cchName, struct cdev **ppDev) -{ - int iUnit; - int rc; - - Log(("VBoxDrvFreeBSDClone: pszName=%s ppDev=%p\n", pszName, ppDev)); - - /* - * One device node per user, si_drv1 points to the session. - * /dev/vboxdrv<N> where N = {0...255}. - */ - if (!ppDev) - return; - if (dev_stdclone(pszName, NULL, "vboxdrv", &iUnit) != 1) - return; - if (iUnit >= 256 || iUnit < 0) - { - Log(("VBoxDrvFreeBSDClone: iUnit=%d >= 256 - rejected\n", iUnit)); - return; - } - - Log(("VBoxDrvFreeBSDClone: pszName=%s iUnit=%d\n", pszName, iUnit)); - - rc = clone_create(&g_pVBoxDrvFreeBSDClones, &g_VBoxDrvFreeBSDChrDevSW, &iUnit, ppDev, 0); - Log(("VBoxDrvFreeBSDClone: clone_create -> %d; iUnit=%d\n", rc, iUnit)); - if (rc) - { -#if __FreeBSD_version > 800061 - *ppDev = make_dev(&g_VBoxDrvFreeBSDChrDevSW, iUnit, UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv%d", iUnit); -#else - *ppDev = make_dev(&g_VBoxDrvFreeBSDChrDevSW, unit2minor(iUnit), UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv%d", iUnit); -#endif - if (*ppDev) - { - dev_ref(*ppDev); - (*ppDev)->si_flags |= SI_CHEAPCLONE; - Log(("VBoxDrvFreeBSDClone: Created *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n", - *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2)); - (*ppDev)->si_drv1 = (*ppDev)->si_drv2 = NULL; - } - else - OSDBGPRINT(("VBoxDrvFreeBSDClone: make_dev iUnit=%d failed\n", iUnit)); - } - else - Log(("VBoxDrvFreeBSDClone: Existing *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n", - *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2)); -} - - - -/** * * @returns 0 on success, errno on failure. * EBUSY if the device is used by someone else. @@ -287,21 +214,11 @@ * @param pFd The file descriptor. FreeBSD 7.0 and later. * @param iFd The file descriptor index(?). Pre FreeBSD 7.0. */ -#if __FreeBSD__ >= 7 -static int VBoxDrvFreeBSDOpen(struct cdev *pDev, int fOpen, struct thread *pTd, struct file *pFd) -#else -static int VBoxDrvFreeBSDOpen(struct cdev *pDev, int fOpen, struct thread *pTd, int iFd) -#endif +static int VBoxDrvFreeBSDOpen(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd) { PSUPDRVSESSION pSession; int rc; -#if __FreeBSD_version < 800062 - Log(("VBoxDrvFreeBSDOpen: fOpen=%#x iUnit=%d\n", fOpen, minor2unit(minor(pDev)))); -#else - Log(("VBoxDrvFreeBSDOpen: fOpen=%#x iUnit=%d\n", fOpen, minor(dev2udev(pDev)))); -#endif - /* * Let's be a bit picky about the flags... */ @@ -312,12 +229,6 @@ } /* - * Try grab it (we don't grab the giant, remember). - */ - if (!ASMAtomicCmpXchgPtr(&pDev->si_drv1, (void *)0x42, NULL)) - return EBUSY; - - /* * Create a new session. */ rc = supdrvCreateSession(&g_VBoxDrvFreeBSDDevExt, true /* fUser */, &pSession); @@ -326,14 +237,10 @@ /** @todo get (r)uid and (r)gid. pSession->Uid = stuff; pSession->Gid = stuff; */ - if (ASMAtomicCmpXchgPtr(&pDev->si_drv1, pSession, (void *)0x42)) - { - ASMAtomicIncU32(&g_cUsers); - return 0; - } - - OSDBGPRINT(("VBoxDrvFreeBSDOpen: si_drv1=%p, expected 0x42!\n", pDev->si_drv1)); - supdrvCloseSession(&g_VBoxDrvFreeBSDDevExt, pSession); + devfs_set_cdevpriv(pSession, VBoxDrvFreeBSDDtr); + Log(("VBoxDrvFreeBSDOpen: pSession=%p\n", pSession)); + ASMAtomicIncU32(&g_cUsers); + return 0; } return RTErrConvertToErrno(rc); @@ -349,30 +256,16 @@ * @param DevType The device type (CHR. * @param pTd The calling thread. */ -static int VBoxDrvFreeBSDClose(struct cdev *pDev, int fFile, int DevType, struct thread *pTd) +static void VBoxDrvFreeBSDDtr(void *pData) { - PSUPDRVSESSION pSession = (PSUPDRVSESSION)pDev->si_drv1; -#if __FreeBSD_version < 800062 - Log(("VBoxDrvFreeBSDClose: fFile=%#x iUnit=%d pSession=%p\n", fFile, minor2unit(minor(pDev)), pSession)); -#else - Log(("VBoxDrvFreeBSDClose: fFile=%#x iUnit=%d pSession=%p\n", fFile, minor(dev2udev(pDev)), pSession)); -#endif + PSUPDRVSESSION pSession = pData; + Log(("VBoxDrvFreeBSDDtr: pSession=%p\n", pSession)); /* - * Close the session if it's still hanging on to the device... + * Close the session. */ - if (VALID_PTR(pSession)) - { - supdrvCloseSession(&g_VBoxDrvFreeBSDDevExt, pSession); - if (!ASMAtomicCmpXchgPtr(&pDev->si_drv1, NULL, pSession)) - OSDBGPRINT(("VBoxDrvFreeBSDClose: si_drv1=%p expected %p!\n", pDev->si_drv1, pSession)); - ASMAtomicDecU32(&g_cUsers); - /* Don't use destroy_dev here because it may sleep resulting in a hanging user process. */ - destroy_dev_sched(pDev); - } - else - OSDBGPRINT(("VBoxDrvFreeBSDClose: si_drv1=%p!\n", pSession)); - return 0; + supdrvCloseSession(&g_VBoxDrvFreeBSDDevExt, pSession); + ASMAtomicDecU32(&g_cUsers); } @@ -388,12 +281,8 @@ */ static int VBoxDrvFreeBSDIOCtl(struct cdev *pDev, u_long ulCmd, caddr_t pvData, int fFile, struct thread *pTd) { - /* - * Validate the input. - */ - PSUPDRVSESSION pSession = (PSUPDRVSESSION)pDev->si_drv1; - if (RT_UNLIKELY(!VALID_PTR(pSession))) - return EINVAL; + PSUPDRVSESSION pSession; + devfs_get_cdevpriv((void **)&pSession); /* * Deal with the fast ioctl path first.
pgpKxfFXUgyif.pgp
Description: PGP signature