コード例 #1
0
ファイル: VBoxUSBMon-solaris.c プロジェクト: jeppeter/vbox
/**
 * 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;
    }
}
コード例 #2
0
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;
}