VirtualBox

Changeset 60793 in vbox for trunk/src/VBox/ValidationKit


Ignore:
Timestamp:
May 2, 2016 4:12:43 PM (9 years ago)
Author:
vboxsync
Message:

ValidationKit/UsbTestService: Updates, implement the protocol bits for passing extended configuration from the client to the gadget, detect multiple busses from dummy_hcd which creates a separate bus for high-speed and super-speed gadgets, some smaller fixes

Location:
trunk/src/VBox/ValidationKit/utils/usb
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestService.cpp

    r60548 r60793  
    542542
    543543/**
     544 * Parses an unsigned integer from the given value string.
     545 *
     546 * @returns IPRT status code.
     547 * @retval  VERR_OUT_OF_RANGE if the parsed value exceeds the given maximum.
     548 * @param   uMax                The maximum value.
     549 * @param   pu64                Where to store the parsed number on success.
     550 */
     551static int utsDoGadgetCreateCfgParseUInt(const char *pszVal, uint64_t uMax, uint64_t *pu64)
     552{
     553    int rc = RTStrToUInt64Ex(pszVal, NULL, 0, pu64);
     554    if (RT_SUCCESS(rc))
     555    {
     556        if (*pu64 > uMax)
     557            rc = VERR_OUT_OF_RANGE;
     558    }
     559
     560    return rc;
     561}
     562
     563/**
     564 * Parses a signed integer from the given value string.
     565 *
     566 * @returns IPRT status code.
     567 * @retval  VERR_OUT_OF_RANGE if the parsed value exceeds the given range.
     568 * @param   iMin                The minimum value.
     569 * @param   iMax                The maximum value.
     570 * @param   pi64                Where to store the parsed number on success.
     571 */
     572static int utsDoGadgetCreateCfgParseInt(const char *pszVal, int64_t iMin, int64_t iMax, int64_t *pi64)
     573{
     574    int rc = RTStrToInt64Ex(pszVal, NULL, 0, pi64);
     575    if (RT_SUCCESS(rc))
     576    {
     577        if (   *pi64 < iMin
     578            || *pi64 > iMax)
     579            rc = VERR_OUT_OF_RANGE;
     580    }
     581
     582    return rc;
     583}
     584
     585/**
     586 * Parses the given config item and fills in the value according to the given type.
     587 *
     588 * @returns IPRT status code.
     589 * @param   pCfgItem            The config item to parse.
     590 * @param   u32Type             The config type.
     591 * @param   pszVal              The value encoded as a string.
     592 */
     593static int utsDoGadgetCreateCfgParseItem(PUTSGADGETCFGITEM pCfgItem, uint32_t u32Type,
     594                                         const char *pszVal)
     595{
     596    int rc = VINF_SUCCESS;
     597
     598    switch (u32Type)
     599    {
     600        case UTSPKT_GDGT_CFG_ITEM_TYPE_BOOLEAN:
     601        {
     602            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_BOOLEAN;
     603            if (   RTStrICmp(pszVal, "enabled")
     604                || RTStrICmp(pszVal, "1")
     605                || RTStrICmp(pszVal, "true"))
     606                pCfgItem->Val.u.f = true;
     607            else if (   RTStrICmp(pszVal, "disabled")
     608                     || RTStrICmp(pszVal, "0")
     609                     || RTStrICmp(pszVal, "false"))
     610                pCfgItem->Val.u.f = false;
     611            else
     612                rc = VERR_INVALID_PARAMETER;
     613            break;
     614        }
     615        case UTSPKT_GDGT_CFG_ITEM_TYPE_STRING:
     616        {
     617            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_STRING;
     618            pCfgItem->Val.u.psz = RTStrDup(pszVal);
     619            if (!pCfgItem->Val.u.psz)
     620                rc = VERR_NO_STR_MEMORY;
     621            break;
     622        }
     623        case UTSPKT_GDGT_CFG_ITEM_TYPE_UINT8:
     624        {
     625            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_UINT8;
     626
     627            uint64_t u64;
     628            rc = utsDoGadgetCreateCfgParseUInt(pszVal, UINT8_MAX, &u64);
     629            if (RT_SUCCESS(rc))
     630                pCfgItem->Val.u.u8 = (uint8_t)u64;
     631            break;
     632        }
     633        case UTSPKT_GDGT_CFG_ITEM_TYPE_UINT16:
     634        {
     635            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_UINT16;
     636
     637            uint64_t u64;
     638            rc = utsDoGadgetCreateCfgParseUInt(pszVal, UINT16_MAX, &u64);
     639            if (RT_SUCCESS(rc))
     640                pCfgItem->Val.u.u16 = (uint16_t)u64;
     641            break;
     642        }
     643        case UTSPKT_GDGT_CFG_ITEM_TYPE_UINT32:
     644        {
     645            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_UINT32;
     646
     647            uint64_t u64;
     648            rc = utsDoGadgetCreateCfgParseUInt(pszVal, UINT32_MAX, &u64);
     649            if (RT_SUCCESS(rc))
     650                pCfgItem->Val.u.u32 = (uint32_t)u64;
     651            break;
     652        }
     653        case UTSPKT_GDGT_CFG_ITEM_TYPE_UINT64:
     654        {
     655            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_UINT64;
     656            rc = utsDoGadgetCreateCfgParseUInt(pszVal, UINT64_MAX, &pCfgItem->Val.u.u64);
     657            break;
     658        }
     659        case UTSPKT_GDGT_CFG_ITEM_TYPE_INT8:
     660        {
     661            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_INT8;
     662
     663            int64_t i64;
     664            rc = utsDoGadgetCreateCfgParseInt(pszVal, INT8_MIN, INT8_MAX, &i64);
     665            if (RT_SUCCESS(rc))
     666                pCfgItem->Val.u.i8 = (int8_t)i64;
     667            break;
     668        }
     669        case UTSPKT_GDGT_CFG_ITEM_TYPE_INT16:
     670        {
     671            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_INT16;
     672
     673            int64_t i64;
     674            rc = utsDoGadgetCreateCfgParseInt(pszVal, INT16_MIN, INT16_MAX, &i64);
     675            if (RT_SUCCESS(rc))
     676                pCfgItem->Val.u.i16 = (int16_t)i64;
     677            break;
     678        }
     679        case UTSPKT_GDGT_CFG_ITEM_TYPE_INT32:
     680        {
     681            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_INT32;
     682
     683            int64_t i64;
     684            rc = utsDoGadgetCreateCfgParseInt(pszVal, INT32_MIN, INT32_MAX, &i64);
     685            if (RT_SUCCESS(rc))
     686                pCfgItem->Val.u.i32 = (int32_t)i64;
     687            break;
     688        }
     689        case UTSPKT_GDGT_CFG_ITEM_TYPE_INT64:
     690        {
     691            pCfgItem->Val.enmType = UTSGADGETCFGTYPE_INT64;
     692            rc = utsDoGadgetCreateCfgParseInt(pszVal, INT64_MIN, INT64_MAX, &pCfgItem->Val.u.i64);
     693            break;
     694        }
     695        default:
     696            rc = VERR_INVALID_PARAMETER;
     697    }
     698
     699    return rc;
     700}
     701
     702/**
    544703 * Creates the configuration from the given GADGET CREATE packet.
    545704 *
    546705 * @returns IPRT status code.
    547  * @param   pReq                The gadget create request.
    548  * @param   paCfg               The array of configuration items.
    549  */
    550 static int utsDoGadgetCreateFillCfg(PUTSPKTREQGDGTCTOR pReq, PUTSGADGETCFGITEM paCfg)
    551 {
    552     return VERR_NOT_IMPLEMENTED;
     706 * @param   pCfgItem            The first config item header in the request packet.
     707 * @param   cCfgItems           Number of config items in the packet to parse.
     708 * @param   cbPkt               Number of bytes left in the packet for the config data.
     709 * @param   paCfg               The array of configuration items to fill.
     710 */
     711static int utsDoGadgetCreateFillCfg(PUTSPKTREQGDGTCTORCFGITEM pCfgItem, unsigned cCfgItems,
     712                                    size_t cbPkt, PUTSGADGETCFGITEM paCfg)
     713{
     714    int rc = VINF_SUCCESS;
     715    unsigned idxCfg = 0;
     716
     717    while (   RT_SUCCESS(rc)
     718           && cCfgItems
     719           && cbPkt)
     720    {
     721        if (cbPkt >= sizeof(UTSPKTREQGDGTCTORCFGITEM))
     722        {
     723            cbPkt -= sizeof(UTSPKTREQGDGTCTORCFGITEM);
     724            if (pCfgItem->u32KeySize + pCfgItem->u32ValSize >= cbPkt)
     725            {
     726                const char *pszKey = (const char *)(pCfgItem + 1);
     727                const char *pszVal = pszKey + pCfgItem->u32KeySize;
     728
     729                /* Validate termination. */
     730                if (   *(pszKey + pCfgItem->u32KeySize - 1) != '\0'
     731                    || *(pszVal + pCfgItem->u32ValSize - 1) != '\0')
     732                    rc = VERR_INVALID_PARAMETER;
     733                else
     734                {
     735                    paCfg[idxCfg].pszKey = RTStrDup(pszKey);
     736
     737                    rc = utsDoGadgetCreateCfgParseItem(&paCfg[idxCfg], pCfgItem->u32Type, pszVal);
     738                    if (RT_SUCCESS(rc))
     739                    {
     740                        cbPkt -= pCfgItem->u32KeySize + pCfgItem->u32ValSize;
     741                        cCfgItems--;
     742                        idxCfg++;
     743                        pCfgItem = (PUTSPKTREQGDGTCTORCFGITEM)(pszVal + pCfgItem->u32ValSize);
     744                    }
     745                }
     746            }
     747            else
     748                rc = VERR_INVALID_PARAMETER;
     749        }
     750        else
     751            rc = VERR_INVALID_PARAMETER;
     752    }
     753
     754    return rc;
    553755}
    554756
     
    688890            return utsReplyRC(pClient, pPktHdr, VERR_NO_MEMORY, "Failed to allocate memory for configration items");
    689891
    690         rc = utsDoGadgetCreateFillCfg(pReq, paCfg);
     892        rc = utsDoGadgetCreateFillCfg((PUTSPKTREQGDGTCTORCFGITEM)(pReq + 1), pReq->u32CfgItems,
     893                                      pPktHdr->cb - sizeof(UTSPKTREQGDGTCTOR), paCfg);
    691894        if (RT_FAILURE(rc))
    692895        {
     
    10791282        }
    10801283        else
    1081         {
    1082             if (RTErrInfoIsSet(pErrInfo))
    1083             {
    1084                 RTMsgError("Failed to parse config with detailed error: %s (%Rrc)\n",
    1085                            pErrInfo->pszMsg, pErrInfo->rc);
    1086                 RTErrInfoFree(pErrInfo);
    1087             }
    1088             else
    1089                 RTMsgError("Faield to parse config with unknown error (%Rrc)\n", rc);
    1090             return rc;
    1091         }
     1284            RTMsgError("Initializing the platform failed with %Rrc\n", rc);
     1285    }
     1286    else
     1287    {
     1288        if (RTErrInfoIsSet(pErrInfo))
     1289        {
     1290            RTMsgError("Failed to parse config with detailed error: %s (%Rrc)\n",
     1291                       pErrInfo->pszMsg, pErrInfo->rc);
     1292            RTErrInfoFree(pErrInfo);
     1293        }
     1294        else
     1295            RTMsgError("Failed to parse config with unknown error (%Rrc)\n", rc);
    10921296    }
    10931297
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetCfg.cpp

    r60493 r60793  
    8989
    9090    if (   !pCfgItem
    91         || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_STRING)
     91        || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_BOOLEAN)
     92    {
    9293        *pf = pCfgItem ? pCfgItem->Val.u.f : fDef;
     94        rc = VINF_SUCCESS;
     95    }
    9396
    9497    return rc;
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetClassTest.cpp

    r60522 r60793  
    291291            char *pszManufacturer = NULL;
    292292            char *pszProduct = NULL;
     293            bool fSuperSpeed = false;
    293294
    294295            /* Get basic device config. */
     
    304305            if (RT_SUCCESS(rc))
    305306                rc = utsGadgetCfgQueryStringDef(paCfg, "Gadget/Product",      &pszProduct,      UTS_GADGET_TEST_PRODUCT_DEF);
     307            if (RT_SUCCESS(rc))
     308                rc = utsGadgetCfgQueryBoolDef(paCfg,   "Gadget/SuperSpeed",   &fSuperSpeed,     false);
    306309
    307310            if (RT_SUCCESS(rc))
     
    357360                    pClass->pszUdc = NULL;
    358361
    359                     rc = utsPlatformLnxAcquireUDC(&pClass->pszUdc, &pClass->uBusId);
     362                    rc = utsPlatformLnxAcquireUDC(fSuperSpeed, &pClass->pszUdc, &pClass->uBusId);
    360363                    if (RT_SUCCESS(rc))
    361364                        rc = RTLinuxSysFsWriteStrFile(pClass->pszUdc, 0, NULL, "%s/UDC", pClass->pszGadgetPath);
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServicePlatform-linux.cpp

    r60522 r60793  
    4545
    4646/**
    47  * A dummy UDC descriptor.
    48  */
    49 typedef struct UTSPLATFORMLNXDUMMYHCD
    50 {
    51     /* Index of the dummy hcd entry. */
    52     uint32_t                  idxDummyHcd;
     47 * A USB bus provided by the dummy HCD.
     48 */
     49typedef struct UTSPLATFORMLNXDUMMYHCDBUS
     50{
    5351    /** The bus ID on the host the dummy HCD is serving. */
    5452    uint32_t                  uBusId;
     53    /** Flag whether this is a super speed bus. */
     54    bool                      fSuperSpeed;
     55} UTSPLATFORMLNXDUMMYHCDBUS;
     56/** Pointer to a Dummy HCD bus. */
     57typedef UTSPLATFORMLNXDUMMYHCDBUS *PUTSPLATFORMLNXDUMMYHCDBUS;
     58
     59/**
     60 * A dummy UDC descriptor.
     61 */
     62typedef struct UTSPLATFORMLNXDUMMYHCD
     63{
     64    /** Index of the dummy hcd entry. */
     65    uint32_t                   idxDummyHcd;
    5566    /** Flag whether this HCD is free for use. */
    56     bool                      fAvailable;
     67    bool                       fAvailable;
     68    /** Number of busses this HCD instance serves. */
     69    unsigned                   cBusses;
     70    /** Bus structures the HCD serves.*/
     71    PUTSPLATFORMLNXDUMMYHCDBUS paBusses;
    5772} UTSPLATFORMLNXDUMMYHCD;
    5873/** Pointer to a dummy HCD entry. */
     
    7590
    7691/**
    77  * Queries the assigned bus ID for the given dummy HCD index.
     92 * Queries the assigned busses for the given dummy HCD instance.
    7893 *
    7994 * @returns IPRT status code.
    80  * @param   idxHcd            The HCD index to query the bus number for.
    81  * @param   puBusId           Where to store the bus number on success.
    82  */
    83 static int utsPlatformLnxDummyHcdQueryBusId(uint32_t idxHcd, uint32_t *puBusId)
     95 * @param   pHcd              The dummy HCD bus instance.
     96 */
     97static int utsPlatformLnxDummyHcdQueryBusses(PUTSPLATFORMLNXDUMMYHCD pHcd)
    8498{
    8599    int rc = VINF_SUCCESS;
    86100    char aszPath[RTPATH_MAX + 1];
    87 
    88     size_t cchPath = RTStrPrintf(&aszPath[0], RT_ELEMENTS(aszPath), UTS_PLATFORM_LNX_DUMMY_HCD_PATH "/dummy_hcd.%u/usb*", idxHcd);
     101    unsigned idxBusCur = 0;
     102    unsigned idxBusMax = 0;
     103
     104    size_t cchPath = RTStrPrintf(&aszPath[0], RT_ELEMENTS(aszPath), UTS_PLATFORM_LNX_DUMMY_HCD_PATH "/dummy_hcd.%u/usb*", pHcd->idxDummyHcd);
    89105    if (cchPath == RT_ELEMENTS(aszPath))
    90106        return VERR_BUFFER_OVERFLOW;
     
    94110    if (RT_SUCCESS(rc))
    95111    {
    96         RTDIRENTRY DirFolderContent;
    97         rc = RTDirRead(pDir, &DirFolderContent, NULL);
    98         if (RT_SUCCESS(rc))
    99         {
    100             /* Extract the bus number - it is after "usb", i.e. "usb9" indicates a bus ID of 9. */
    101             rc = RTStrToUInt32Ex(&DirFolderContent.szName[3], NULL, 10, puBusId);
     112        do
     113        {
     114            RTDIRENTRY DirFolderContent;
     115            rc = RTDirRead(pDir, &DirFolderContent, NULL);
    102116            if (RT_SUCCESS(rc))
    103117            {
    104                 /* Make sure there is no other entry or something screwed us up. */
    105                 rc = RTDirRead(pDir, &DirFolderContent, NULL);
     118                uint32_t uBusId = 0;
     119
     120                /* Extract the bus number - it is after "usb", i.e. "usb9" indicates a bus ID of 9. */
     121                rc = RTStrToUInt32Ex(&DirFolderContent.szName[3], NULL, 10, &uBusId);
    106122                if (RT_SUCCESS(rc))
    107                     rc = VERR_INVALID_STATE;
    108                 else if (rc == VERR_NO_MORE_FILES)
    109                     rc = VINF_SUCCESS;
     123                {
     124                    /* Check whether this is a super speed bus. */
     125                    int64_t iSpeed = 0;
     126                    bool fSuperSpeed = false;
     127                    rc = RTLinuxSysFsReadIntFile(10, &iSpeed, UTS_PLATFORM_LNX_DUMMY_HCD_PATH "/dummy_hcd.%u/%s/speed",
     128                                                 pHcd->idxDummyHcd, DirFolderContent.szName);
     129                    if (   RT_SUCCESS(rc)
     130                        && (iSpeed == 5000 || iSpeed == 10000))
     131                        fSuperSpeed = true;
     132
     133                    /* Add to array of available busses for this HCD. */
     134                    if (idxBusCur == idxBusMax)
     135                    {
     136                        size_t cbNew = (idxBusMax + 10) * sizeof(UTSPLATFORMLNXDUMMYHCDBUS);
     137                        PUTSPLATFORMLNXDUMMYHCDBUS pNew = (PUTSPLATFORMLNXDUMMYHCDBUS)RTMemRealloc(pHcd->paBusses, cbNew);
     138                        if (pNew)
     139                        {
     140                            idxBusMax += 10;
     141                            pHcd->paBusses = pNew;
     142                        }
     143                    }
     144
     145                    if (idxBusCur < idxBusMax)
     146                    {
     147                        pHcd->paBusses[idxBusCur].uBusId      = uBusId;
     148                        pHcd->paBusses[idxBusCur].fSuperSpeed = fSuperSpeed;
     149                        idxBusCur++;
     150                    }
     151                    else
     152                        rc = VERR_NO_MEMORY;
     153                }
    110154            }
    111         }
     155        } while (RT_SUCCESS(rc));
     156
     157        pHcd->cBusses = idxBusCur;
     158
     159        if (rc == VERR_NO_MORE_FILES)
     160            rc = VINF_SUCCESS;
    112161
    113162        RTDirClose(pDir);
     
    124173    if (RT_SUCCESS(rc))
    125174    {
    126         const char *pszArg = "num=2"; /** @todo: Make configurable from config. */
    127         rc = utsPlatformModuleLoad("dummy_hcd", &pszArg, 1);
     175        const char *apszArg[] = { "num=2", "is_super_speed=1" }; /** @todo: Make configurable from config. */
     176        rc = utsPlatformModuleLoad("dummy_hcd", &apszArg[0], RT_ELEMENTS(apszArg));
    128177        if (RT_SUCCESS(rc))
    129178        {
     
    157206                            if (RT_SUCCESS(rc))
    158207                            {
    159                                 uint32_t uBusId = 0;
    160                                 rc = utsPlatformLnxDummyHcdQueryBusId(idxHcd, &uBusId);
    161                                 if (RT_SUCCESS(rc))
     208                                /* Add to array of available HCDs. */
     209                                if (idxHcdCur == idxHcdMax)
    162210                                {
    163                                     /* Add to array of available HCDs. */
    164                                     if (idxHcdCur == idxHcdMax)
     211                                    size_t cbNew = (idxHcdMax + 10) * sizeof(UTSPLATFORMLNXDUMMYHCD);
     212                                    PUTSPLATFORMLNXDUMMYHCD pNew = (PUTSPLATFORMLNXDUMMYHCD)RTMemRealloc(g_paDummyHcd, cbNew);
     213                                    if (pNew)
    165214                                    {
    166                                         size_t cbNew = (idxHcdMax + 10) * sizeof(UTSPLATFORMLNXDUMMYHCD);
    167                                         PUTSPLATFORMLNXDUMMYHCD pNew = (PUTSPLATFORMLNXDUMMYHCD)RTMemRealloc(g_paDummyHcd, cbNew);
    168                                         if (pNew)
    169                                         {
    170                                             idxHcdMax += 10;
    171                                             g_paDummyHcd = pNew;
    172                                         }
    173                                     }
    174 
    175                                     if (idxHcdCur < idxHcdMax)
    176                                     {
    177                                         g_paDummyHcd[idxHcdCur].idxDummyHcd = idxHcd;
    178                                         g_paDummyHcd[idxHcdCur].uBusId      = uBusId;
    179                                         g_paDummyHcd[idxHcdCur].fAvailable  = true;
    180                                         idxHcdCur++;
     215                                        idxHcdMax += 10;
     216                                        g_paDummyHcd = pNew;
    181217                                    }
    182218                                }
     219
     220                                if (idxHcdCur < idxHcdMax)
     221                                {
     222                                    g_paDummyHcd[idxHcdCur].idxDummyHcd = idxHcd;
     223                                    g_paDummyHcd[idxHcdCur].fAvailable  = true;
     224                                    g_paDummyHcd[idxHcdCur].cBusses     = 0;
     225                                    g_paDummyHcd[idxHcdCur].paBusses    = NULL;
     226                                    rc = utsPlatformLnxDummyHcdQueryBusses(&g_paDummyHcd[idxHcdCur]);
     227                                    if (RT_SUCCESS(rc))
     228                                        idxHcdCur++;
     229                                }
     230                                else
     231                                    rc = VERR_NO_MEMORY;
    183232                            }
    184233                        }
     
    222271    unsigned idx;
    223272    for (idx = 0; idx < cArgv; idx++)
    224         papszArgs[2+idx] = papszArgs[idx];
     273        papszArgs[2+idx] = papszArgv[idx];
    225274    papszArgs[2+idx] = NULL;
    226275
     
    271320
    272321
    273 DECLHIDDEN(int) utsPlatformLnxAcquireUDC(char **ppszUdc, uint32_t *puBusId)
     322DECLHIDDEN(int) utsPlatformLnxAcquireUDC(bool fSuperSpeed, char **ppszUdc, uint32_t *puBusId)
    274323{
    275324    int rc = VERR_NOT_FOUND;
     
    277326    for (unsigned i = 0; i < g_cDummyHcd; i++)
    278327    {
    279         if (g_paDummyHcd[i].fAvailable)
    280         {
    281             rc = VINF_SUCCESS;
    282             int cbRet = RTStrAPrintf(ppszUdc, "dummy_udc.%u", g_paDummyHcd[i].idxDummyHcd);
    283             if (cbRet == -1)
    284                 rc = VERR_NO_STR_MEMORY;
    285             *puBusId = g_paDummyHcd[i].uBusId;
    286             g_paDummyHcd[i].fAvailable = false;
    287             break;
     328        PUTSPLATFORMLNXDUMMYHCD pHcd = &g_paDummyHcd[i];
     329
     330        if (pHcd->fAvailable)
     331        {
     332            /* Check all assigned busses for a speed match. */
     333            for (unsigned idxBus = 0; idxBus < pHcd->cBusses; idxBus++)
     334            {
     335                if (pHcd->paBusses[idxBus].fSuperSpeed == fSuperSpeed)
     336                {
     337                    rc = VINF_SUCCESS;
     338                    int cbRet = RTStrAPrintf(ppszUdc, "dummy_udc.%u", pHcd->idxDummyHcd);
     339                    if (cbRet == -1)
     340                        rc = VERR_NO_STR_MEMORY;
     341                    *puBusId = pHcd->paBusses[idxBus].uBusId;
     342                    pHcd->fAvailable = false;
     343                    break;
     344                }
     345            }
     346
     347            if (rc != VERR_NOT_FOUND)
     348                break;
    288349        }
    289350    }
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServicePlatform.h

    r60518 r60793  
    7070 *
    7171 * @returns IPRT status code.
     72 * @param   fSuperSpeed       Flag whether a super speed bus is required.
    7273 * @param   ppszUdc           Where to store the pointer to the name of the UDC on success.
    7374 *                            Free with RTStrFree().
    7475 * @param   puBusId           Where to store the bus ID the UDC is attached to on the host side.
    7576 */
    76 DECLHIDDEN(int) utsPlatformLnxAcquireUDC(char **ppszUdc, uint32_t *puBusId);
     77DECLHIDDEN(int) utsPlatformLnxAcquireUDC(bool fSuperSpeed, char **ppszUdc, uint32_t *puBusId);
    7778
    7879/**
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