static int VBoxUSBMonSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred) { vboxusbmon_state_t *pState = NULL; LogFunc((DEVICE_NAME ":VBoxUSBMonSolarisClose\n")); pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, getminor(Dev)); if (!pState) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisClose: failed to get pState.\n")); return EFAULT; } mutex_enter(&g_VBoxUSBMonSolarisMtx); g_cVBoxUSBMonSolarisClient--; if (!g_cVBoxUSBMonSolarisClient) { if (RT_LIKELY(g_pDip)) { mutex_exit(&g_VBoxUSBMonSolarisMtx); usb_unregister_dev_driver(g_pDip); Log((DEVICE_NAME ":Successfully deregistered driver election callback\n")); } else { mutex_exit(&g_VBoxUSBMonSolarisMtx); LogRel((DEVICE_NAME ":Extreme error! Missing device info during close.\n")); } } else mutex_exit(&g_VBoxUSBMonSolarisMtx); /* * Remove all filters for this client process. */ VBoxUSBFilterRemoveOwner(pState->Process); ddi_soft_state_free(g_pVBoxUSBMonSolarisState, getminor(Dev)); pState = NULL; NOREF(fFlag); NOREF(fType); NOREF(pCred); return 0; }
/** * Detach entry point, to detach a device to the system or suspend it. * * @param pDip The module structure instance. * @param enmCmd Attach type (ddi_attach_cmd_t) * * @returns corresponding solaris error code. */ static int VBoxUSBMonSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd) { LogFunc((DEVICE_NAME ": VBoxUSBMonSolarisDetach\n")); switch (enmCmd) { case DDI_DETACH: { /* * Free all registered clients' info. */ mutex_enter(&g_VBoxUSBMonSolarisMtx); vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients; while (pCur) { vboxusbmon_client_t *pNext = pCur->pNext; RTMemFree(pCur); pCur = pNext; } mutex_exit(&g_VBoxUSBMonSolarisMtx); usb_unregister_dev_driver(g_pDip); ddi_remove_minor_node(pDip, NULL); g_pDip = NULL; return DDI_SUCCESS; } case DDI_SUSPEND: { /* We don't have to bother about power management. */ return DDI_SUCCESS; } default: return DDI_FAILURE; } }