* 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.

Attachment: pgpKxfFXUgyif.pgp
Description: PGP signature

Reply via email to