VirtualBox

Ignore:
Timestamp:
May 3, 2016 8:53:41 AM (9 years ago)
Author:
vboxsync
Message:

ValidationKit/UsbTestService: Fixes to support testing super-speed devices. The gadget functions hard code the maximum supported USB speed. When the dummy HCD is enabled for super

speed devices we can't control the desired speed of the device so it is always super speed now breaking testing of lower speeds. As a workaround
the USB test server has a modified kernel with a new dummy HCD driver using a slightly different naming for super-speed devices only. The original
driver will be used for the remaining speeds. Add support for this configuration in the UsbTestService.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/usb/UsbTestServicePlatform-linux.cpp

    r60793 r60801  
    6464    /** Index of the dummy hcd entry. */
    6565    uint32_t                   idxDummyHcd;
     66    /** Name for the dummy HCD. */
     67    const char                 *pszHcdName;
     68    /** Name for the accompanying dummy HCD. */
     69    const char                 *pszUdcName;
    6670    /** Flag whether this HCD is free for use. */
    6771    bool                       fAvailable;
     72    /** Flag whether this HCD contains a super speed capable bus. */
     73    bool                       fSuperSpeed;
    6874    /** Number of busses this HCD instance serves. */
    6975    unsigned                   cBusses;
     
    94100 * @returns IPRT status code.
    95101 * @param   pHcd              The dummy HCD bus instance.
    96  */
    97 static int utsPlatformLnxDummyHcdQueryBusses(PUTSPLATFORMLNXDUMMYHCD pHcd)
     102 * @param   pszHcdName        The base HCD name.
     103 */
     104static int utsPlatformLnxDummyHcdQueryBusses(PUTSPLATFORMLNXDUMMYHCD pHcd, const char *pszHcdName)
    98105{
    99106    int rc = VINF_SUCCESS;
     
    102109    unsigned idxBusMax = 0;
    103110
    104     size_t cchPath = RTStrPrintf(&aszPath[0], RT_ELEMENTS(aszPath), UTS_PLATFORM_LNX_DUMMY_HCD_PATH "/dummy_hcd.%u/usb*", pHcd->idxDummyHcd);
     111    size_t cchPath = RTStrPrintf(&aszPath[0], RT_ELEMENTS(aszPath), UTS_PLATFORM_LNX_DUMMY_HCD_PATH "/%s.%u/usb*",
     112                                 pszHcdName, pHcd->idxDummyHcd);
    105113    if (cchPath == RT_ELEMENTS(aszPath))
    106114        return VERR_BUFFER_OVERFLOW;
     
    125133                    int64_t iSpeed = 0;
    126134                    bool fSuperSpeed = false;
    127                     rc = RTLinuxSysFsReadIntFile(10, &iSpeed, UTS_PLATFORM_LNX_DUMMY_HCD_PATH "/dummy_hcd.%u/%s/speed",
    128                                                  pHcd->idxDummyHcd, DirFolderContent.szName);
     135                    rc = RTLinuxSysFsReadIntFile(10, &iSpeed, UTS_PLATFORM_LNX_DUMMY_HCD_PATH "/%s.%u/%s/speed",
     136                                                 pszHcdName, pHcd->idxDummyHcd, DirFolderContent.szName);
    129137                    if (   RT_SUCCESS(rc)
    130138                        && (iSpeed == 5000 || iSpeed == 10000))
     139                    {
    131140                        fSuperSpeed = true;
     141                        pHcd->fSuperSpeed = true;
     142                    }
    132143
    133144                    /* Add to array of available busses for this HCD. */
     
    167178
    168179
     180/**
     181 * Scans all available HCDs with the given name.
     182 *
     183 * @returns IPRT status code.
     184 * @param   pszHcdName        The base HCD name.
     185 * @param   pszUdcName        The base UDC name.
     186 */
     187static int utsPlatformLnxHcdScanByName(const char *pszHcdName, const char *pszUdcName)
     188{
     189    char aszPath[RTPATH_MAX + 1];
     190    size_t cchPath = RTStrPrintf(&aszPath[0], RT_ELEMENTS(aszPath),
     191                                 UTS_PLATFORM_LNX_DUMMY_HCD_PATH "/%s.*", pszHcdName);
     192    if (cchPath == RT_ELEMENTS(aszPath))
     193        return VERR_BUFFER_OVERFLOW;
     194
     195    /* Enumerate the available HCD and their bus numbers. */
     196    PRTDIR pDir = NULL;
     197    int rc = RTDirOpenFiltered(&pDir, aszPath, RTDIRFILTER_WINNT, 0);
     198    if (RT_SUCCESS(rc))
     199    {
     200        unsigned idxHcdCur = g_cDummyHcd;
     201        unsigned idxHcdMax = g_cDummyHcd;
     202
     203        do
     204        {
     205            RTDIRENTRY DirFolderContent;
     206            rc = RTDirRead(pDir, &DirFolderContent, NULL);
     207            if (RT_SUCCESS(rc))
     208            {
     209                /*
     210                 * Get the HCD index and assigned bus number form the sysfs entries,
     211                 * Any error here is silently ignored and results in the HCD not being
     212                 * added to the list of available controllers.
     213                 */
     214                const char *pszIdx = RTStrStr(DirFolderContent.szName, ".");
     215                if (pszIdx)
     216                {
     217                    /* Skip the separator and convert number to index. */
     218                    pszIdx++;
     219
     220                    uint32_t idxHcd = 0;
     221                    rc = RTStrToUInt32Ex(pszIdx, NULL, 10, &idxHcd);
     222                    if (RT_SUCCESS(rc))
     223                    {
     224                        /* Add to array of available HCDs. */
     225                        if (idxHcdCur == idxHcdMax)
     226                        {
     227                            size_t cbNew = (idxHcdMax + 10) * sizeof(UTSPLATFORMLNXDUMMYHCD);
     228                            PUTSPLATFORMLNXDUMMYHCD pNew = (PUTSPLATFORMLNXDUMMYHCD)RTMemRealloc(g_paDummyHcd, cbNew);
     229                            if (pNew)
     230                            {
     231                                idxHcdMax += 10;
     232                                g_paDummyHcd = pNew;
     233                            }
     234                        }
     235
     236                        if (idxHcdCur < idxHcdMax)
     237                        {
     238                            g_paDummyHcd[idxHcdCur].idxDummyHcd = idxHcd;
     239                            g_paDummyHcd[idxHcdCur].pszHcdName  = pszHcdName;
     240                            g_paDummyHcd[idxHcdCur].pszUdcName  = pszUdcName;
     241                            g_paDummyHcd[idxHcdCur].fAvailable  = true;
     242                            g_paDummyHcd[idxHcdCur].fSuperSpeed = false;
     243                            g_paDummyHcd[idxHcdCur].cBusses     = 0;
     244                            g_paDummyHcd[idxHcdCur].paBusses    = NULL;
     245                            rc = utsPlatformLnxDummyHcdQueryBusses(&g_paDummyHcd[idxHcdCur], pszHcdName);
     246                            if (RT_SUCCESS(rc))
     247                                idxHcdCur++;
     248                        }
     249                        else
     250                            rc = VERR_NO_MEMORY;
     251                    }
     252                }
     253            }
     254        } while (RT_SUCCESS(rc));
     255
     256        g_cDummyHcd = idxHcdCur;
     257
     258        if (rc == VERR_NO_MORE_FILES)
     259            rc = VINF_SUCCESS;
     260
     261        RTDirClose(pDir);
     262    }
     263
     264    return rc;
     265}
     266
    169267DECLHIDDEN(int) utsPlatformInit(void)
    170268{
     
    173271    if (RT_SUCCESS(rc))
    174272    {
    175         const char *apszArg[] = { "num=2", "is_super_speed=1" }; /** @todo: Make configurable from config. */
     273        const char *apszArg[] = { "num=20" }; /** @todo: Make configurable from config. */
    176274        rc = utsPlatformModuleLoad("dummy_hcd", &apszArg[0], RT_ELEMENTS(apszArg));
    177275        if (RT_SUCCESS(rc))
    178         {
    179             /* Enumerate the available HCD and their bus numbers. */
    180             PRTDIR pDir = NULL;
    181             rc = RTDirOpenFiltered(&pDir, UTS_PLATFORM_LNX_DUMMY_HCD_PATH "/dummy_hcd.*", RTDIRFILTER_WINNT, 0);
    182             if (RT_SUCCESS(rc))
    183             {
    184                 unsigned idxHcdCur = 0;
    185                 unsigned idxHcdMax = 0;
    186 
    187                 do
    188                 {
    189                     RTDIRENTRY DirFolderContent;
    190                     rc = RTDirRead(pDir, &DirFolderContent, NULL);
    191                     if (RT_SUCCESS(rc))
    192                     {
    193                         /*
    194                          * Get the HCD index and assigned bus number form the sysfs entries,
    195                          * Any error here is silently ignored and results in the HCD not being
    196                          * added to the list of available controllers.
    197                          */
    198                         const char *pszIdx = RTStrStr(DirFolderContent.szName, ".");
    199                         if (pszIdx)
    200                         {
    201                             /* Skip the separator and convert number to index. */
    202                             pszIdx++;
    203 
    204                             uint32_t idxHcd = 0;
    205                             rc = RTStrToUInt32Ex(pszIdx, NULL, 10, &idxHcd);
    206                             if (RT_SUCCESS(rc))
    207                             {
    208                                 /* Add to array of available HCDs. */
    209                                 if (idxHcdCur == idxHcdMax)
    210                                 {
    211                                     size_t cbNew = (idxHcdMax + 10) * sizeof(UTSPLATFORMLNXDUMMYHCD);
    212                                     PUTSPLATFORMLNXDUMMYHCD pNew = (PUTSPLATFORMLNXDUMMYHCD)RTMemRealloc(g_paDummyHcd, cbNew);
    213                                     if (pNew)
    214                                     {
    215                                         idxHcdMax += 10;
    216                                         g_paDummyHcd = pNew;
    217                                     }
    218                                 }
    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;
    232                             }
    233                         }
    234                     }
    235                 } while (RT_SUCCESS(rc));
    236 
    237                 g_cDummyHcd = idxHcdCur;
    238 
    239                 if (rc == VERR_NO_MORE_FILES)
    240                     rc = VINF_SUCCESS;
    241 
    242                 RTDirClose(pDir);
    243             }
    244         }
     276            rc = utsPlatformModuleLoad("dummy_hcd_ss", &apszArg[0], RT_ELEMENTS(apszArg));
     277        if (RT_SUCCESS(rc))
     278            rc = utsPlatformLnxHcdScanByName("dummy_hcd", "dummy_udc");
     279        if (RT_SUCCESS(rc))
     280            rc = utsPlatformLnxHcdScanByName("dummy_hcd_ss", "dummy_udc_ss");
    245281    }
    246282
     
    253289    /* Unload dummy HCD. */
    254290    utsPlatformModuleUnload("dummy_hcd");
     291    utsPlatformModuleUnload("dummy_hcd_ss");
    255292
    256293    RTMemFree(g_paDummyHcd);
     
    328365        PUTSPLATFORMLNXDUMMYHCD pHcd = &g_paDummyHcd[i];
    329366
    330         if (pHcd->fAvailable)
     367        /*
     368         * We can't use a super speed capable UDC for gadgets with lower speeds
     369         * because they hardcode the maximum speed to SuperSpeed most of the time
     370         * which will make it unusable for lower speeds.
     371         */
     372        if (   pHcd->fAvailable
     373            && pHcd->fSuperSpeed == fSuperSpeed)
    331374        {
    332375            /* Check all assigned busses for a speed match. */
     
    336379                {
    337380                    rc = VINF_SUCCESS;
    338                     int cbRet = RTStrAPrintf(ppszUdc, "dummy_udc.%u", pHcd->idxDummyHcd);
     381                    int cbRet = RTStrAPrintf(ppszUdc, "%s.%u", pHcd->pszUdcName, pHcd->idxDummyHcd);
    339382                    if (cbRet == -1)
    340383                        rc = VERR_NO_STR_MEMORY;
     
    360403    if (pszIdx)
    361404    {
     405        size_t cchUdcName = pszIdx - pszUdc;
    362406        pszIdx++;
    363407        uint32_t idxHcd = 0;
     
    369413            for (unsigned i = 0; i < g_cDummyHcd; i++)
    370414            {
    371                 if (g_paDummyHcd[i].idxDummyHcd == idxHcd)
     415                if (   g_paDummyHcd[i].idxDummyHcd == idxHcd
     416                    && !RTStrNCmp(g_paDummyHcd[i].pszUdcName, pszUdc, cchUdcName))
    372417                {
    373418                    AssertReturn(!g_paDummyHcd[i].fAvailable, VERR_INVALID_PARAMETER);
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