Index: trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
===================================================================
--- trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c	(revision 4835)
+++ trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c	(revision 4851)
@@ -134,4 +134,14 @@
 };
 
+#ifndef USE_SESSION_HASH
+/**
+ * State info for each open file handle.
+ */
+typedef struct
+{
+    /**< Pointer to the session data. */
+    PSUPDRVSESSION pSession;
+} vbox_devstate_t;
+#else
 /** State info. for each driver instance. */
 typedef struct
@@ -139,4 +149,5 @@
     dev_info_t     *pDip;   /* Device handle */
 } vbox_devstate_t;
+#endif
 
 /** Opaque pointer to state */
@@ -159,21 +170,24 @@
  * Kernel entry points
  */
-int _init (void)
+int _init(void)
 {
     cmn_err(CE_CONT, "VBoxDrvSolaris _init");
 
-    int e = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof (vbox_devstate_t), 1);
-    if (e != 0)
-        return e;
-
-    e = mod_install(&g_VBoxDrvSolarisModLinkage);
-    if (e != 0)
+    int rc = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof(vbox_devstate_t), 8);
+    if (!rc)
+    {
+        rc = mod_install(&g_VBoxDrvSolarisModLinkage);
+        if (!rc)
+            return 0; /* success */
+
         ddi_soft_state_fini(&g_pVBoxDrvSolarisState);
-
-    cmn_err(CE_CONT, "VBoxDrvSolaris _init returns %d", e);
-    return e;
-}
-
-int _fini (void)
+    }
+
+    cmn_err(CE_CONT, "VBoxDrvSolaris _init failed with rc=%d", rc);
+    return rc;
+}
+
+
+int _fini(void)
 {
     cmn_err(CE_CONT, "VBoxDrvSolaris _fini");
@@ -187,8 +201,9 @@
 }
 
-int _info (struct modinfo *pModInfo)
+
+int _info(struct modinfo *pModInfo)
 {
     cmn_err(CE_CONT, "VBoxDrvSolaris _info");
-    int e = mod_info (&g_VBoxDrvSolarisModLinkage, pModInfo);
+    int e = mod_info(&g_VBoxDrvSolarisModLinkage, pModInfo);
     cmn_err(CE_CONT, "VBoxDrvSolaris _info returns %d", e);
     return e;
@@ -200,9 +215,48 @@
 static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
 {
-    cmn_err(CE_CONT, "VBoxDrvSolarisOpen");
-
     int                 rc;
     PSUPDRVSESSION      pSession;
-
+    dprintf(("VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev));
+
+#ifndef USE_SESSION_HASH
+    /*
+     * Locate a new device open instance.
+     *
+     * For each open call we'll allocate an item in the soft state of the device.
+     * The item index is stored in the dev_t. I hope this is ok...
+     */
+    vbox_devstate_t *pState = NULL;
+    unsigned iOpenInstance;
+    for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)
+    {
+        if (    !ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance) /* faster */
+            &&  ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, iOpenInstance) == DDI_SUCCESS)
+        {
+            pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance);
+            break;
+        }
+    }
+    if (!pState)
+    {
+        cmn_err(CE_NOTE,"VBoxDrvSolarisOpen: too many open instances.");
+        return ENXIO;
+    }
+
+    /*
+     * Create a new session.
+     */
+    rc = supdrvCreateSession(&g_DevExt, &pSession);
+    if (RT_SUCCESS(rc))
+    {
+        pState->pSession = pSession;
+        *pDev = makedevice(getmajor(*pDev), iOpenInstance);
+        dprintf(("VBoxDrvSolarisOpen: returns pDev=%#x pSession=%p pState=%p\n", *pDev, pSession, pState));
+        return 0;
+    }
+
+    /* failed - clean up */
+    ddi_soft_state_free(g_pVBoxDrvSolarisState, iOpenInstance);
+
+#else
     /*
      * Create a new session.
@@ -235,5 +289,5 @@
     for (instance = 0; instance < DEVICE_MAXINSTANCES; instance++)
     {
-        vbox_devstate_t *pState = ddi_get_soft_state (g_pVBoxDrvSolarisState, instance);
+        vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
         if (pState)
             break;
@@ -249,10 +303,33 @@
 
     return VBoxSupDrvErr2SolarisErr(rc);
-}
-
-static int VBoxDrvSolarisClose(dev_t pDev, int flag, int otyp, cred_t *cred)
-{
-    cmn_err(CE_CONT, "VBoxDrvSolarisClose");
-
+#endif
+}
+
+
+static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)
+{
+    dprintf(("VBoxDrvSolarisClose: Dev=%#x\n", Dev));
+#ifndef USE_SESSION_HASH
+    /*
+     * Get the session and free the soft state item.
+     */
+    vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev));
+    if (!pState)
+    {
+        OSDBGPRINT(("VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev)));
+        return DDI_SUCCESS;
+    }
+
+    PSUPDRVSESSION pSession = pState->pSession;
+    pState->pSession = NULL;
+    ddi_soft_state_free(g_pVBoxDrvSolarisState, getminor(Dev));
+
+    if (!pSession)
+    {
+        OSDBGPRINT(("VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
+        return DDI_SUCCESS;
+    }
+
+#else
     RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER;
     const RTPROCESS Process = RTProcSelf();
@@ -298,4 +375,5 @@
         return DDI_FAILURE;
     }
+#endif
 
     /*
@@ -306,4 +384,5 @@
 }
 
+
 static int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
 {
@@ -312,4 +391,5 @@
 }
 
+
 static int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
 {
@@ -329,7 +409,4 @@
 {
     cmn_err(CE_CONT, "VBoxDrvSolarisAttach");
-    int rc = VINF_SUCCESS;
-    int instance = 0;
-    vbox_devstate_t *pState;
 
     switch (enmCmd)
@@ -337,5 +414,8 @@
         case DDI_ATTACH:
         {
-            instance = ddi_get_instance (pDip);
+            int rc;
+            int instance = ddi_get_instance(pDip);
+#ifdef USE_SESSION_HASH
+            vbox_devstate_t *pState;
 
             if (ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, instance) != DDI_SUCCESS)
@@ -346,4 +426,5 @@
 
             pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
+#endif
 
             /*
@@ -369,8 +450,9 @@
                          * Register ourselves as a character device, pseudo-driver
                          */
-                        if (ddi_create_minor_node(pDip, "0", S_IFCHR,
-                                instance, DDI_PSEUDO, 0) == DDI_SUCCESS)
+                        if (ddi_create_minor_node(pDip, "0", S_IFCHR, instance, DDI_PSEUDO, 0) == DDI_SUCCESS)
                         {
+#ifdef USE_SESSION_HASH
                             pState->pDip = pDip;
+#endif
                             ddi_report_dev(pDip);
                             return DDI_SUCCESS;
@@ -416,6 +498,5 @@
 {
     int rc = VINF_SUCCESS;
-    int instance;
-    register vbox_devstate_t *pState;
+
 
     cmn_err(CE_CONT, "VBoxDrvSolarisDetach");
@@ -424,9 +505,12 @@
         case DDI_DETACH:
         {
-            instance = ddi_get_instance(pDip);
-            pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
-
+            int instance = ddi_get_instance(pDip);
+#ifndef USE_SESSION_HASH
+            ddi_remove_minor_node(pDip, NULL);
+#else
+            vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
             ddi_remove_minor_node(pDip, NULL);
             ddi_soft_state_free(g_pVBoxDrvSolarisState, instance);
+#endif
 
             supdrvDeleteDevExt(&g_DevExt);
@@ -460,6 +544,24 @@
  * @return  corresponding solaris error code.
  */
-static int VBoxDrvSolarisIOCtl (dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cred_t* pCred, int* pVal)
-{
+static int VBoxDrvSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cred_t *pCred, int *pVal)
+{
+#ifndef USE_SESSION_HASH
+    /*
+     * Get the session from the soft state item.
+     */
+    vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev));
+    if (!pState)
+    {
+        OSDBGPRINT(("VBoxDrvSolarisIOCtl: no state data for %#x (%d)\n", Dev, getminor(Dev)));
+        return EINVAL;
+    }
+
+    PSUPDRVSESSION  pSession = pState->pSession;
+    if (!pSession)
+    {
+        OSDBGPRINT(("VBoxDrvSolarisIOCtl: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));
+        return DDI_SUCCESS;
+    }
+#else
     RTSPINLOCKTMP       Tmp = RTSPINLOCKTMP_INITIALIZER;
     const RTPROCESS     Process = RTProcSelf();
@@ -467,5 +569,4 @@
     PSUPDRVSESSION      pSession;
 
-    cmn_err(CE_CONT, "VBoxDrvSolarisIOCtl\n");
     /*
      * Find the session.
@@ -485,4 +586,5 @@
         return EINVAL;
     }
+#endif
 
     /*
@@ -493,5 +595,8 @@
         ||  Cmd == SUP_IOCTL_FAST_DO_HWACC_RUN
         ||  Cmd == SUP_IOCTL_FAST_DO_NOP)
-        return supdrvIOCtlFast(Cmd, &g_DevExt, pSession);
+    {
+        *pVal = supdrvIOCtlFast(Cmd, &g_DevExt, pSession);
+        return 0;
+    }
 
     return VBoxDrvSolarisIOCtlSlow(pSession, Cmd, Mode, pArgs);
@@ -670,4 +775,6 @@
     szMsg[sizeof(szMsg) - 1] = '\0';
     uprintf("SUPR0Printf: %s", szMsg);
+//    cmn_err(CE_CONT, "VBoxDrv: %s", szMsg);
+
     return 0;
 }
