VirtualBox

Changeset 48234 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 2, 2013 5:09:24 PM (11 years ago)
Author:
vboxsync
Message:

VMM: PDMR3UsbCreateEmulatedDevice

Location:
trunk/src/VBox/VMM/VMMR3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp

    r46788 r48234  
    462462 * @param   iInstance       -1 if not called by pdmR3UsbInstantiateDevices().
    463463 * @param   pUuid           The UUID for this device.
    464  * @param   pInstanceNode   The instance CFGM node. NULL if not called by pdmR3UsbInstantiateDevices().
    465  * @param   ppConfig        Pointer to the device configuration pointer. This is set to NULL if inserted
     464 * @param   ppInstanceNode  Pointer to the device instance pointer. This is set to NULL if inserted
    466465 *                          into the tree or cleaned up.
    467466 *
    468  *                          In the pdmR3UsbInstantiateDevices() case (pInstanceNode != NULL) this is
    469  *                          the actual config node and will not be cleaned up.
     467 *                          In the pdmR3UsbInstantiateDevices() case (iInstance != -1) this is
     468 *                          the actual instance node and will not be cleaned up.
    470469 *
    471470 * @parma   iUsbVersion     The USB version preferred by the device.
    472471 */
    473472static int pdmR3UsbCreateDevice(PVM pVM, PPDMUSBHUB pHub, PPDMUSB pUsbDev, int iInstance, PCRTUUID pUuid,
    474                                 PCFGMNODE pInstanceNode, PCFGMNODE *ppConfig, uint32_t iUsbVersion)
    475 {
    476     const bool fAtRuntime = pInstanceNode == NULL;
     473                                PCFGMNODE *ppInstanceNode, uint32_t iUsbVersion)
     474{
     475    const bool fAtRuntime = iInstance == -1;
    477476    int rc;
    478     NOREF(iUsbVersion);
     477
     478    AssertPtrReturn(ppInstanceNode, VERR_INVALID_POINTER);
     479    AssertPtrReturn(*ppInstanceNode, VERR_INVALID_POINTER);
    479480
    480481    /*
     
    491492
    492493    /* The instance node and number. */
    493     if (!pInstanceNode)
    494     {
     494    PCFGMNODE pInstanceToDelete = NULL;
     495    PCFGMNODE pInstanceNode = NULL;
     496    if (fAtRuntime)
     497    {
     498        /** @todo r=bird: This code is bogus as it ASSUMES that all USB devices are
     499         *        capable of infinite number of instances. */
    495500        for (unsigned c = 0; c < _2M; c++)
    496501        {
     
    501506        }
    502507        AssertRCReturn(rc, rc);
     508
     509        rc = CFGMR3ReplaceSubTree(pInstanceNode, *ppInstanceNode);
     510        AssertRCReturn(rc, rc);
     511        *ppInstanceNode = NULL;
     512        pInstanceToDelete = pInstanceNode;
    503513    }
    504514    else
     
    507517        if (iInstance >= (int)pUsbDev->iNextInstance)
    508518            pUsbDev->iNextInstance = iInstance + 1;
    509     }
    510 
    511     /* The instance config node. */
    512     PCFGMNODE pConfigToDelete = NULL;
    513     PCFGMNODE pConfig = NULL;
    514     if (!ppConfig || !*ppConfig)
     519        pInstanceNode = *ppInstanceNode;
     520    }
     521
     522    /* Make sure the instance config node exists. */
     523    PCFGMNODE pConfig = CFGMR3GetChild(pInstanceNode, "Config");
     524    if (!pConfig)
    515525    {
    516526        rc = CFGMR3InsertNode(pInstanceNode, "Config", &pConfig);
    517527        AssertRCReturn(rc, rc);
    518528    }
    519     else if (fAtRuntime)
    520     {
    521         rc = CFGMR3InsertSubTree(pInstanceNode, "Config", *ppConfig, &pConfig);
    522         AssertRCReturn(rc, rc);
    523         *ppConfig = NULL;
    524         pConfigToDelete = pConfig;
    525     }
    526     else
    527         pConfig = *ppConfig;
    528529    Assert(CFGMR3GetChild(pInstanceNode, "Config") == pConfig);
    529530
     
    535536        if (RT_FAILURE(rc))
    536537        {
    537             CFGMR3RemoveNode(pConfigToDelete);
     538            CFGMR3RemoveNode(pInstanceToDelete);
    538539            AssertRCReturn(rc, rc);
    539540        }
     
    551552        AssertMsgFailed(("Failed to allocate %d bytes of instance data for USB device '%s'. rc=%Rrc\n",
    552553                         cb, pUsbDev->pReg->szName, rc));
    553         CFGMR3RemoveNode(pConfigToDelete);
     554        CFGMR3RemoveNode(pInstanceToDelete);
    554555        return rc;
    555556    }
     
    565566    //pUsbIns->Internal.s.pLuns               = NULL;
    566567    pUsbIns->Internal.s.pCfg                = pInstanceNode;
    567     pUsbIns->Internal.s.pCfgDelete          = pConfigToDelete;
     568    pUsbIns->Internal.s.pCfgDelete          = pInstanceToDelete;
    568569    pUsbIns->Internal.s.pCfgGlobal          = pGlobalConfig;
    569570    pUsbIns->Internal.s.Uuid                = *pUuid;
     
    835836        rc = RTUuidCreate(&Uuid);
    836837        AssertRCReturn(rc, rc);
    837         rc = pdmR3UsbCreateDevice(pVM, pHub, paUsbDevs[i].pUsbDev, paUsbDevs[i].iInstance, &Uuid, paUsbDevs[i].pNode, &pConfigNode, iUsbVersion);
     838        rc = pdmR3UsbCreateDevice(pVM, pHub, paUsbDevs[i].pUsbDev, paUsbDevs[i].iInstance, &Uuid, &paUsbDevs[i].pNode, iUsbVersion);
    838839        if (RT_FAILURE(rc))
    839840            return rc;
     
    841842
    842843    return VINF_SUCCESS;
     844}
     845
     846
     847/**
     848 * Creates an emulated USB device instance at runtime.
     849 *
     850 * This will find an appropriate HUB for the USB device
     851 * and try instantiate the emulated device.
     852 *
     853 * @returns VBox status code.
     854 * @param   pUVM            The user mode VM handle.
     855 * @param   pszDeviceName   The name of the PDM device to instantiate.
     856 * @param   pInstanceNode   The instance CFGM node.
     857 * @param   pUuid           Where to store the UUID of the created device.
     858 *
     859 * @thread EMT
     860 */
     861VMMR3DECL(int) PDMR3UsbCreateEmulatedDevice(PUVM pUVM, const char *pszDeviceName, PCFGMNODE pInstanceNode, PRTUUID pUuid)
     862{
     863    /*
     864     * Validate input.
     865     */
     866    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
     867    PVM pVM = pUVM->pVM;
     868    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     869    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
     870    AssertPtrReturn(pszDeviceName, VERR_INVALID_POINTER);
     871    AssertPtrReturn(pInstanceNode, VERR_INVALID_POINTER);
     872
     873    /*
     874     * Find the device.
     875     */
     876    PPDMUSB pUsbDev = pdmR3UsbLookup(pVM, pszDeviceName);
     877    if (!pUsbDev)
     878    {
     879        LogRel(("PDMR3UsbCreateEmulatedDevice: The '%s' device wasn't found\n", pszDeviceName));
     880        return VERR_PDM_NO_USBPROXY;
     881    }
     882
     883    /*
     884     * Every device must support USB 1.x hubs; optionally, high-speed USB 2.0 hubs
     885     * might be also supported. This determines where to attach the device.
     886     */
     887    uint32_t iUsbVersion = VUSB_STDVER_11;
     888    if (pUsbDev->pReg->fFlags & PDM_USBREG_HIGHSPEED_CAPABLE)
     889        iUsbVersion |= VUSB_STDVER_20;
     890
     891    /*
     892     * Find a suitable hub with free ports.
     893     */
     894    PPDMUSBHUB pHub;
     895    int rc = pdmR3UsbFindHub(pVM, iUsbVersion, &pHub);
     896    if (RT_FAILURE(rc))
     897    {
     898        Log(("pdmR3UsbFindHub: failed %Rrc\n", rc));
     899        return rc;
     900    }
     901
     902    /*
     903     * This is how we inform the device what speed it's communicating at, and hence
     904     * which descriptors it should present to the guest.
     905     */
     906    iUsbVersion &= pHub->fVersions;
     907
     908    /*
     909     * Create and attach the device.
     910     */
     911    rc = RTUuidCreate(pUuid);
     912    AssertRCReturn(rc, rc);
     913
     914    rc = pdmR3UsbCreateDevice(pVM, pHub, pUsbDev, -1, pUuid, &pInstanceNode, iUsbVersion);
     915    AssertRCReturn(rc, rc);
     916
     917    return rc;
    843918}
    844919
     
    868943    PVM pVM = pUVM->pVM;
    869944    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    870     VM_ASSERT_EMT(pVM);
     945    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    871946    AssertPtrReturn(pUuid, VERR_INVALID_POINTER);
    872947    AssertPtrReturn(pszAddress, VERR_INVALID_POINTER);
     
    896971
    897972    /*
    898      * Create the CFGM configuration node.
    899      */
    900     PCFGMNODE pConfig = CFGMR3CreateTree(pUVM);
    901     AssertReturn(pConfig, VERR_NO_MEMORY);
     973     * Create the CFGM instance node.
     974     */
     975    PCFGMNODE pInstance = CFGMR3CreateTree(pUVM);
     976    AssertReturn(pInstance, VERR_NO_MEMORY);
    902977    do /* break loop */
    903978    {
     979        PCFGMNODE pConfig;
     980        rc = CFGMR3InsertNode(pInstance, "Config", &pConfig);                   AssertRCBreak(rc);
    904981        rc = CFGMR3InsertString(pConfig,  "Address", pszAddress);               AssertRCBreak(rc);
    905982        char szUuid[RTUUID_STR_LENGTH];
     
    914991    if (RT_FAILURE(rc))
    915992    {
    916         CFGMR3RemoveNode(pConfig);
     993        CFGMR3RemoveNode(pInstance);
    917994        LogRel(("PDMR3UsbCreateProxyDevice: failed to setup CFGM config, rc=%Rrc\n", rc));
    918995        return rc;
     
    922999     * Finally, try to create it.
    9231000     */
    924     rc = pdmR3UsbCreateDevice(pVM, pHub, pUsbDev, -1, pUuid, NULL, &pConfig, iUsbVersion);
    925     if (RT_FAILURE(rc) && pConfig)
    926         CFGMR3RemoveNode(pConfig);
     1001    rc = pdmR3UsbCreateDevice(pVM, pHub, pUsbDev, -1, pUuid, &pInstance, iUsbVersion);
     1002    if (RT_FAILURE(rc) && pInstance)
     1003        CFGMR3RemoveNode(pInstance);
    9271004    return rc;
    9281005}
  • trunk/src/VBox/VMM/VMMR3/VMMR3.def

    r46792 r48234  
    187187    PDMR3ThreadSuspend
    188188
     189    PDMR3UsbCreateEmulatedDevice
    189190    PDMR3UsbCreateProxyDevice
    190191    PDMR3UsbDetachDevice
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette