VirtualBox

Changeset 61246 in vbox for trunk


Ignore:
Timestamp:
May 27, 2016 2:30:58 PM (9 years ago)
Author:
vboxsync
Message:

VUSB: Retry after most errors during device enumeration in order to better support flaky devices. Thanks Dennis Wassenberg / secunet.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/USB/USBProxyDevice.cpp

    r59704 r61246  
    5555static void *GetStdDescSync(PUSBPROXYDEV pProxyDev, uint8_t iDescType, uint8_t iIdx, uint16_t LangId, uint16_t cbHint)
    5656{
    57 #define VUSBSTATUS_DNR_RETRIES 5
     57#define GET_DESC_RETRIES 6
    5858    int cRetries = 0;
     59    uint16_t cbInitialHint = cbHint;
    5960
    6061    LogFlow(("GetStdDescSync: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
     
    9192        pSetup->wLength = cbHint;
    9293
     94        uint8_t *pbDesc = (uint8_t *)(pSetup + 1);
     95        uint32_t cbDesc = 0;
     96        PVUSBURB pUrbReaped = NULL;
     97
    9398        rc = pProxyDev->pOps->pfnUrbQueue(pProxyDev, &Urb);
    9499        if (RT_FAILURE(rc))
    95             break;
     100        {
     101            Log(("GetStdDescSync: pfnUrbReap failed, rc=%d\n", rc));
     102            goto err;
     103        }
    96104
    97105        /* Don't wait forever, it's just a simple request that should
    98106           return immediately. Since we're executing in the EMT thread
    99107           it's important not to get stuck here. (Some of the builtin
    100            iMac devices may not refuse respond for instance.) */
    101         PVUSBURB pUrbReaped = pProxyDev->pOps->pfnUrbReap(pProxyDev, 10000 /* ms */);
     108           iMac devices may refuse to respond for instance.) */
     109        pUrbReaped = pProxyDev->pOps->pfnUrbReap(pProxyDev, 10000 /* ms */);
    102110        if (!pUrbReaped)
    103111        {
     
    110118        {
    111119            Log(("GetStdDescSync: pfnUrbReap failed, pUrbReaped=%p\n", pUrbReaped));
    112             break;
     120            goto err;
    113121        }
    114122
     
    116124        {
    117125            Log(("GetStdDescSync: Urb.enmStatus=%d\n", Urb.enmStatus));
    118 
    119             if (Urb.enmStatus == VUSBSTATUS_DNR)
    120             {
    121                 cRetries++;
    122                 if (cRetries < VUSBSTATUS_DNR_RETRIES)
    123                 {
    124                     Log(("GetStdDescSync: Retrying %u/%u\n", cRetries, VUSBSTATUS_DNR_RETRIES));
    125                     continue;
    126                 }
    127             }
    128 
    129             break;
     126            goto err;
    130127        }
    131128
     
    133130         * Check the length, config descriptors have total_length field
    134131         */
    135         uint8_t *pbDesc = (uint8_t *)(pSetup + 1);
    136         uint32_t cbDesc;
    137132        if (iDescType == VUSB_DT_CONFIG)
    138133        {
     
    140135            {
    141136                Log(("GetStdDescSync: Urb.cbData=%#x (min 4)\n", Urb.cbData));
    142                 break;
     137                goto err;
    143138            }
    144139            cbDesc = RT_LE2H_U16(((uint16_t *)pbDesc)[1]);
     
    149144            {
    150145                Log(("GetStdDescSync: Urb.cbData=%#x (min 1)\n", Urb.cbData));
    151                 break;
     146                goto err;
    152147            }
    153148            cbDesc = ((uint8_t *)pbDesc)[0];
     
    160155        {
    161156            cbHint = cbDesc;
     157            Log(("GetStdDescSync: Part descriptor, Urb.cbData=%u, cbDesc=%u cbHint=%u\n", Urb.cbData, cbDesc, cbHint));
     158
    162159            if (cbHint > sizeof(Urb.abData))
    163             {
    164                 AssertMsgFailed(("cbHint=%u\n", cbHint));
    165                 break;
    166             }
    167             continue;
    168         }
    169         Assert(cbDesc <= Urb.cbData - sizeof(VUSBSETUP));
     160                Log(("GetStdDescSync: cbHint=%u, Urb.abData=%u\n", cbHint, sizeof(Urb.abData)));
     161
     162            goto err;
     163        }
     164
     165        if ((cbDesc > (Urb.cbData - sizeof(VUSBSETUP))))
     166        {
     167            Log(("GetStdDescSync: Descriptor length too short, cbDesc=%u, Urb.cbData=%u\n", cbDesc, Urb.cbData));
     168            goto err;
     169        }
     170
     171        if ((cbInitialHint != cbHint) &&
     172                ((cbDesc != cbHint) || (Urb.cbData < cbInitialHint)))
     173        {
     174            Log(("GetStdDescSync: Descriptor length incorrect, cbDesc=%u, Urb.cbData=%u, cbHint=%u\n", cbDesc, Urb.cbData, cbHint));
     175            goto err;
     176        }
     177
    170178#ifdef LOG_ENABLED
    171179        vusbUrbTrace(&Urb, "GetStdDescSync", true);
     
    176184         */
    177185        return RTMemDup(pbDesc, cbDesc);
    178     }
     186
     187err:
     188        cRetries++;
     189        if (cRetries < GET_DESC_RETRIES)
     190        {
     191            Log(("GetStdDescSync: Retrying %u/%u\n", cRetries, GET_DESC_RETRIES));
     192            RTThreadSleep(100);
     193            continue;
     194        }
     195        else
     196        {
     197            Log(("GetStdDescSync: Retries exceeded %u/%u. Giving up.\n", cRetries, GET_DESC_RETRIES));
     198            break;
     199        }
     200    }
     201
    179202    return NULL;
    180203}
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