/** * Attach entry point, to attach a device to the system or resume it. * * @param pDip The module structure instance. * @param enmCmd Attach type (ddi_attach_cmd_t) * * @returns corresponding solaris error code. */ static int VBoxUSBMonSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd) { LogFunc((DEVICE_NAME ": VBoxUSBMonSolarisAttach: pDip=%p enmCmd=%d\n", pDip, enmCmd)); switch (enmCmd) { case DDI_ATTACH: { if (RT_UNLIKELY(g_pDip)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisAttach: Global instance already initialized\n")); return DDI_FAILURE; } g_pDip = pDip; int instance = ddi_get_instance(pDip); int rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0, "none", "none", 0660); if (rc == DDI_SUCCESS) { rc = usb_register_dev_driver(g_pDip, VBoxUSBMonSolarisElectDriver); if (rc == DDI_SUCCESS) { ddi_report_dev(pDip); return DDI_SUCCESS; } LogRel((DEVICE_NAME ": VBoxUSBMonSolarisAttach: Failed to register driver election callback! rc=%d\n", rc)); } else LogRel((DEVICE_NAME ": VBoxUSBMonSolarisAttach: ddi_create_minor_node failed! rc=%d\n", rc)); return DDI_FAILURE; } case DDI_RESUME: { /* We don't have to bother about power management. */ return DDI_SUCCESS; } default: return DDI_FAILURE; } }
static int VBoxUSBMonSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred) { vboxusbmon_state_t *pState = NULL; unsigned iOpenInstance; LogFunc((DEVICE_NAME ":VBoxUSBMonSolarisOpen\n")); /* * Verify we are being opened as a character device. */ if (fType != OTYP_CHR) return EINVAL; /* * Verify that we're called after attach. */ if (!g_pDip) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisOpen invalid state for opening.\n")); return ENXIO; } mutex_enter(&g_VBoxUSBMonSolarisMtx); if (!g_cVBoxUSBMonSolarisClient) { mutex_exit(&g_VBoxUSBMonSolarisMtx); int rc = usb_register_dev_driver(g_pDip, VBoxUSBMonSolarisElectDriver); if (RT_UNLIKELY(rc != DDI_SUCCESS)) { LogRel((DEVICE_NAME ":Failed to register driver election callback with USBA rc=%d\n", rc)); return EINVAL; } Log((DEVICE_NAME ":Successfully registered election callback with USBA\n")); mutex_enter(&g_VBoxUSBMonSolarisMtx); } g_cVBoxUSBMonSolarisClient++; mutex_exit(&g_VBoxUSBMonSolarisMtx); for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++) { if ( !ddi_get_soft_state(g_pVBoxUSBMonSolarisState, iOpenInstance) /* faster */ && ddi_soft_state_zalloc(g_pVBoxUSBMonSolarisState, iOpenInstance) == DDI_SUCCESS) { pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, iOpenInstance); break; } } if (!pState) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisOpen: too many open instances.")); mutex_enter(&g_VBoxUSBMonSolarisMtx); g_cVBoxUSBMonSolarisClient--; mutex_exit(&g_VBoxUSBMonSolarisMtx); return ENXIO; } pState->Process = RTProcSelf(); *pDev = makedevice(getmajor(*pDev), iOpenInstance); NOREF(fFlag); NOREF(pCred); return 0; }