VirtualBox

Changeset 52254 in vbox for trunk/src/VBox/Devices/USB/linux


Ignore:
Timestamp:
Aug 2, 2014 3:34:53 PM (10 years ago)
Author:
vboxsync
Message:

Devices/USB: Several fixes and misc cleanups, the VM crash when detaching a USB device while transfering data should be fixed, likewise several assertions in debug builds should be fixed now. Removed a bit dead code in the linux backend (timeout handling which wasn't active)

File:
1 edited

Legend:

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

    r50234 r52254  
    7676# define RTCRITSECT          void *
    7777static inline int rtcsNoop() { return VINF_SUCCESS; }
     78static inline bool rtcsTrue() { return true; }
    7879# define RTCritSectInit(a)   rtcsNoop()
    7980# define RTCritSectDelete(a) rtcsNoop()
    8081# define RTCritSectEnter(a)  rtcsNoop()
    8182# define RTCritSectLeave(a)  rtcsNoop()
     83# define RTCritSectIsOwner(a) rtcsTrue()
    8284#endif
    8385#include <VBox/err.h>
     
    9193#include <iprt/stream.h>
    9294#include <iprt/string.h>
     95#include <iprt/list.h>
    9396#if defined(NO_PORT_RESET) && !defined(NO_LOGICAL_RECONNECT)
    9497# include <iprt/thread.h>
     
    107110{
    108111    /** The kernel URB data */
    109     struct usbdevfs_urb     KUrb;
     112    struct usbdevfs_urb             KUrb;
    110113    /** Space filler for the isochronous packets. */
    111114    struct usbdevfs_iso_packet_desc aIsocPktsDonUseTheseUseTheOnesInKUrb[8];
    112     /** The millisecond timestamp when this URB was submitted. */
    113     uint64_t                u64SubmitTS;
    114     /** Pointer to the next linux URB. */
    115     struct USBPROXYURBLNX  *pNext;
    116     /** Pointer to the previous linux URB. */
    117     struct USBPROXYURBLNX  *pPrev;
     115    /** Node to link the URB in of the existing lists. */
     116    RTLISTNODE                      NodeList;
    118117    /** If we've split the VUSBURB up into multiple linux URBs, this is points to the head. */
    119     struct USBPROXYURBLNX  *pSplitHead;
     118    struct USBPROXYURBLNX           *pSplitHead;
    120119    /** The next linux URB if split up. */
    121     struct USBPROXYURBLNX  *pSplitNext;
    122     /** Whether it has timed out and should be shot down on the next failing reap call. */
    123     bool                    fTimedOut;
    124     /** Indicates that this URB has been canceled by timeout and should return an CRC error. */
    125     bool                    fCanceledByTimedOut;
     120    struct USBPROXYURBLNX           *pSplitNext;
    126121    /** Don't report these back. */
    127     bool                    fCanceledBySubmit;
     122    bool                             fCanceledBySubmit;
    128123    /** This split element is reaped. */
    129     bool                    fSplitElementReaped;
     124    bool                             fSplitElementReaped;
    130125    /** Size to transfer in remaining fragments of a split URB */
    131     uint32_t                cbSplitRemaining;
     126    uint32_t                         cbSplitRemaining;
    132127} USBPROXYURBLNX, *PUSBPROXYURBLNX;
    133128
     
    139134    /** The open file. */
    140135    RTFILE              hFile;
    141     /** Critical section protecting the two lists. */
     136    /** Critical section protecting the lists. */
    142137    RTCRITSECT          CritSect;
    143     /** The list of free linux URBs. Singly linked. */
    144     PUSBPROXYURBLNX     pFreeHead;
    145     /** The list of active linux URBs. Doubly linked.
     138    /** The list of free linux URBs (USBPROXYURBLNX). */
     139    RTLISTANCHOR        ListFree;
     140    /** The list of active linux URBs.
    146141     * We must maintain this so we can properly reap URBs of a detached device.
    147      * Only the split head will appear in this list. */
    148     PUSBPROXYURBLNX     pInFlightHead;
     142     * Only the split head will appear in this list. (USBPROXYURBLNX) */
     143    RTLISTANCHOR        ListInFlight;
    149144    /** The list of landed linux URBs. Doubly linked.
    150      * Only the split head will appear in this list. */
    151     PUSBPROXYURBLNX     pTaxingHead;
    152     /** The tail of the landed linux URBs. */
    153     PUSBPROXYURBLNX     pTaxingTail;
     145     * Only the split head will appear in this list. (USBPROXYURBLNX) */
     146    RTLISTANCHOR        ListTaxing;
    154147    /** Are we using sysfs to find the active configuration? */
    155148    bool                fUsingSysfs;
     
    233226    pProxyDev->fDetached = true;
    234227
    235     PUSBPROXYURBLNX pUrbTaxing = NULL;
    236     PUSBPROXYURBLNX pUrbLnx = pDevLnx->pInFlightHead;
    237     pDevLnx->pInFlightHead = NULL;
    238     while (pUrbLnx)
    239     {
    240         PUSBPROXYURBLNX pCur = pUrbLnx;
    241         pUrbLnx = pUrbLnx->pNext;
    242 
    243         ioctl(RTFileToNative(pDevLnx->hFile), USBDEVFS_DISCARDURB, &pCur->KUrb); /* not sure if this is required.. */
    244         if (!pCur->KUrb.status)
    245             pCur->KUrb.status = -ENODEV;
     228    PUSBPROXYURBLNX pUrbLnx;
     229    PUSBPROXYURBLNX pUrbLnxNext;
     230
     231    RTListForEachSafe(&pDevLnx->ListInFlight, pUrbLnx, pUrbLnxNext, USBPROXYURBLNX, NodeList)
     232    {
     233        RTListNodeRemove(&pUrbLnx->NodeList);
     234
     235        ioctl(RTFileToNative(pDevLnx->hFile), USBDEVFS_DISCARDURB, &pUrbLnx->KUrb); /* not sure if this is required.. */
     236        if (!pUrbLnx->KUrb.status)
     237            pUrbLnx->KUrb.status = -ENODEV;
    246238
    247239        /* insert into the taxing list. */
    248         pCur->pPrev = NULL;
    249         if (    !pCur->pSplitHead
    250             ||  pCur == pCur->pSplitHead)
    251         {
    252             pCur->pNext = pUrbTaxing;
    253             if (pUrbTaxing)
    254                 pUrbTaxing->pPrev = pCur;
    255             pUrbTaxing = pCur;
    256         }
    257         else
    258             pCur->pNext = NULL;
    259     }
    260 
    261     /* Append the URBs we shot down to the taxing queue. */
    262     if (pUrbTaxing)
    263     {
    264         pUrbTaxing->pPrev = pDevLnx->pTaxingTail;
    265         if (pUrbTaxing->pPrev)
    266             pUrbTaxing->pPrev->pNext = pUrbTaxing;
    267         else
    268             pDevLnx->pTaxingTail = pDevLnx->pTaxingHead = pUrbTaxing;
     240        if (    !pUrbLnx->pSplitHead
     241            ||  pUrbLnx == pUrbLnx->pSplitHead)
     242            RTListAppend(&pDevLnx->ListTaxing, &pUrbLnx->NodeList);
    269243    }
    270244
     
    299273
    300274/**
     275 * Links the given URB into the in flight list.
     276 *
     277 * @returns nothing.
     278 * @param   pDevLnx         The proxy device instance - Linux specific data.
     279 * @param   pUrbLnx         The URB to link into the in flight list.
     280 */
     281static void usbProxyLinuxUrbLinkInFlight(PUSBPROXYDEVLNX pDevLnx, PUSBPROXYURBLNX pUrbLnx)
     282{
     283    Assert(RTCritSectIsOwner(&pDevLnx->CritSect));
     284    Assert(!pUrbLnx->pSplitHead);
     285    RTListAppend(&pDevLnx->ListInFlight, &pUrbLnx->NodeList);
     286}
     287
     288/**
     289 * Unlinks the given URB from the in flight list.
     290 * @returns nothing.
     291 * @param   pDevLnx         The proxy device instance - Linux specific data.
     292 * @param   pUrbLnx         The URB to link into the in flight list.
     293 */
     294static void usbProxyLinuxUrbUnlinkInFlight(PUSBPROXYDEVLNX pDevLnx, PUSBPROXYURBLNX pUrbLnx)
     295{
     296    RTCritSectEnter(&pDevLnx->CritSect);
     297
     298    /*
     299     * Remove from the active list.
     300     */
     301    Assert(!pUrbLnx->pSplitHead || pUrbLnx->pSplitHead == pUrbLnx);
     302
     303    RTListNodeRemove(&pUrbLnx->NodeList);
     304    pUrbLnx->pSplitHead = pUrbLnx->pSplitNext = NULL;
     305
     306    RTCritSectLeave(&pDevLnx->CritSect);
     307}
     308
     309/**
    301310 * Allocates a linux URB request structure.
    302311 * @returns Pointer to an active URB request.
     
    315324     * Try remove a linux URB from the free list, if none there allocate a new one.
    316325     */
    317     pUrbLnx = pDevLnx->pFreeHead;
     326    pUrbLnx = RTListGetFirst(&pDevLnx->ListFree, USBPROXYURBLNX, NodeList);
    318327    if (pUrbLnx)
    319         pDevLnx->pFreeHead = pUrbLnx->pNext;
     328    {
     329        RTListNodeRemove(&pUrbLnx->NodeList);
     330        RTCritSectLeave(&pDevLnx->CritSect);
     331    }
    320332    else
    321333    {
     
    324336        if (!pUrbLnx)
    325337            return NULL;
    326         RTCritSectEnter(&pDevLnx->CritSect);
    327     }
     338    }
     339
    328340    pUrbLnx->pSplitHead = pSplitHead;
    329341    pUrbLnx->pSplitNext = NULL;
    330     pUrbLnx->fTimedOut = false;
    331     pUrbLnx->fCanceledByTimedOut = false;
    332342    pUrbLnx->fCanceledBySubmit = false;
    333343    pUrbLnx->fSplitElementReaped = false;
    334 
    335     /*
    336      * Link it into the active list
    337      */
    338     if (!pSplitHead)
    339     {
    340         pUrbLnx->pPrev = NULL;
    341         pUrbLnx->pNext = pDevLnx->pInFlightHead;
    342         if (pUrbLnx->pNext)
    343             pUrbLnx->pNext->pPrev = pUrbLnx;
    344         pDevLnx->pInFlightHead = pUrbLnx;
    345     }
    346     else
    347         pUrbLnx->pPrev = pUrbLnx->pNext = (PUSBPROXYURBLNX)0xdead;
    348 
    349     RTCritSectLeave(&pDevLnx->CritSect);
    350344    return pUrbLnx;
    351345}
     
    365359
    366360    /*
    367      * Remove from the active list.
    368      */
    369     if (    !pUrbLnx->pSplitHead
    370         ||  pUrbLnx->pSplitHead == pUrbLnx)
    371     {
    372         if (pUrbLnx->pNext)
    373             pUrbLnx->pNext->pPrev = pUrbLnx->pPrev;
    374         if (pUrbLnx->pPrev)
    375             pUrbLnx->pPrev->pNext = pUrbLnx->pNext;
    376         else
    377             pDevLnx->pInFlightHead  = pUrbLnx->pNext;
    378     }
    379     pUrbLnx->pSplitHead = pUrbLnx->pSplitNext = NULL;
    380 
    381     /*
    382361     * Link it into the free list.
    383362     */
    384     pUrbLnx->pPrev = NULL;
    385     pUrbLnx->pNext = pDevLnx->pFreeHead;
    386     pDevLnx->pFreeHead = pUrbLnx;
     363    RTListAppend(&pDevLnx->ListFree, &pUrbLnx->NodeList);
    387364
    388365    RTCritSectLeave(&pDevLnx->CritSect);
     
    409386        pUrbLnx = pUrbLnx->pSplitNext;
    410387        Assert(pFree->pSplitHead);
     388        pFree->pSplitHead = pFree->pSplitNext = NULL;
    411389        usbProxyLinuxUrbFree(pProxyDev, pFree);
    412390    }
     
    665643         */
    666644        PUSBPROXYDEVLNX pDevLnx = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVLNX);
     645
     646        RTListInit(&pDevLnx->ListFree);
     647        RTListInit(&pDevLnx->ListInFlight);
     648        RTListInit(&pDevLnx->ListTaxing);
    667649        pDevLnx->pszPath = RTStrDupN(pszPath, cchPath);
    668650        if (pDevLnx->pszPath)
     
    782764
    783765    PUSBPROXYURBLNX pUrbLnx;
    784     while ((pUrbLnx = pDevLnx->pInFlightHead) != NULL)
    785     {
    786         pDevLnx->pInFlightHead = pUrbLnx->pNext;
     766    PUSBPROXYURBLNX pUrbLnxNext;
     767    RTListForEachSafe(&pDevLnx->ListInFlight, pUrbLnx, pUrbLnxNext, USBPROXYURBLNX, NodeList)
     768    {
     769        RTListNodeRemove(&pUrbLnx->NodeList);
     770
    787771        if (    usbProxyLinuxDoIoCtl(pProxyDev, USBDEVFS_DISCARDURB, &pUrbLnx->KUrb, false, UINT32_MAX)
    788772            &&  errno != ENODEV
    789773            &&  errno != ENOENT)
    790774            AssertMsgFailed(("errno=%d\n", errno));
     775
    791776        if (pUrbLnx->pSplitHead)
    792777        {
     
    809794    }
    810795
    811     while ((pUrbLnx = pDevLnx->pFreeHead) != NULL)
    812     {
    813         pDevLnx->pFreeHead = pUrbLnx->pNext;
     796    RTListForEachSafe(&pDevLnx->ListFree, pUrbLnx, pUrbLnxNext, USBPROXYURBLNX, NodeList)
     797    {
     798        RTListNodeRemove(&pUrbLnx->NodeList);
    814799        RTMemFree(pUrbLnx);
    815800    }
     
    12991284             pUrb, errno, pCur->KUrb.type, pCur->KUrb.endpoint, pCur->KUrb.buffer_length, cTries));
    13001285        if (errno != EBUSY && ++cTries < 3) /* this doesn't work for the floppy :/ */
    1301         {
    1302             pCur->u64SubmitTS = RTTimeMilliTS();
    13031286            continue;
    1304         }
     1287
    13051288        return RTErrConvertFromErrno(errno);
    13061289    }
     
    13301313        return NULL;
    13311314    }
    1332     Assert(pHead->pNext != pNew); Assert(pHead->pPrev != pNew); Assert(pNew->pNext == pNew->pPrev);
    13331315    Assert(pNew->pSplitHead == pHead);
    13341316    Assert(pNew->pSplitNext == NULL);
     
    14331415            if (RT_FAILURE(rc))
    14341416                break;
     1417            usbProxyLinuxUrbLinkInFlight(USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVLNX), pCur);
    14351418        }
    14361419    }
     
    14391422    {
    14401423        pUrb->Dev.pvPrivate = pUrbLnx;
     1424        usbProxyLinuxUrbLinkInFlight(USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVLNX), pUrbLnx);
    14411425        LogFlow(("usbProxyLinuxUrbQueueSplit: ok\n"));
    14421426        return VINF_SUCCESS;
     
    15131497
    15141498    /*
     1499     * We have to serialize access by using the critial section here because this
     1500     * thread might be suspended after submitting the URB but before linking it into
     1501     * the in flight list. This would get us in trouble when reaping the URB on another
     1502     * thread while it isn't in the in flight list.
     1503     *
     1504     * Linking the URB into the list before submitting it like it was done in the past is not
     1505     * possible either because submitting the URB might fail here because the device gets
     1506     * detached. The reaper thread gets this event too and might race this thread before we
     1507     * can unlink the URB from the active list and the common code might end up freeing
     1508     * the common URB structure twice.
     1509     */
     1510    RTCritSectEnter(&pDevLnx->CritSect);
     1511    /*
    15151512     * Submit it.
    15161513     */
     
    15251522            if (pUrb->enmType == VUSBXFERTYPE_MSG)
    15261523                usbProxyLinuxUrbSwapSetup((PVUSBSETUP)pUrb->abData);
     1524
     1525            RTCritSectLeave(&pDevLnx->CritSect);
    15271526            usbProxyLinuxUrbFree(pProxyDev, pUrbLnx);
    1528 
    15291527            usbProxLinuxUrbUnplugged(pProxyDev);
    15301528            return RTErrConvertFromErrno(errno);
     
    15411539        if (    errno == EINVAL
    15421540            &&  pUrb->cbData >= 8*_1K)
     1541        {
     1542            RTCritSectLeave(&pDevLnx->CritSect);
    15431543            return usbProxyLinuxUrbQueueSplit(pProxyDev, pUrbLnx, pUrb);
     1544        }
    15441545
    15451546        Log(("usb-linux: Queue URB %p -> %d!!! type=%d ep=%#x buffer_length=%#x cTries=%d\n",
     
    15481549            continue;
    15491550
     1551        RTCritSectLeave(&pDevLnx->CritSect);
    15501552        rc = RTErrConvertFromErrno(errno);
    1551 
    1552 l_err:
    15531553        if (pUrb->enmType == VUSBXFERTYPE_MSG)
    15541554            usbProxyLinuxUrbSwapSetup((PVUSBSETUP)pUrb->abData);
     
    15561556        return rc;
    15571557    }
    1558     pUrbLnx->u64SubmitTS = RTTimeMilliTS();
     1558
     1559    usbProxyLinuxUrbLinkInFlight(pDevLnx, pUrbLnx);
     1560    RTCritSectLeave(&pDevLnx->CritSect);
    15591561
    15601562    LogFlow(("usbProxyLinuxUrbQueue: ok\n"));
    15611563    pUrb->Dev.pvPrivate = pUrbLnx;
    15621564    return rc;
    1563 }
    1564 
    1565 
    1566 /**
    1567  * Check if any or the in-flight URBs are taking too long and should be cancelled.
    1568  *
    1569  * Cancelling is done in three turns, first a URB is marked for timeout if it's
    1570  * exceeding a certain time limit. Then the next time it's encountered it is actually
    1571  * cancelled. The idea now is that it's supposed to be reaped and returned in the next
    1572  * round of calls.
    1573  *
    1574  * @param   pProxyDev   The proxy device.
    1575  * @param   pDevLnx     The linux backend data.
    1576  *
    1577  * @todo    Make the HCI do proper timeout handling! Current timeout is 3 min and 20 seconds
    1578  *          as not to break bloomberg which queues IN packages with 3 min timeouts.
    1579  */
    1580 static void vusbProxyLinuxUrbDoTimeouts(PUSBPROXYDEV pProxyDev, PUSBPROXYDEVLNX pDevLnx)
    1581 {
    1582     RTCritSectEnter(&pDevLnx->CritSect);
    1583     uint64_t u64MilliTS = RTTimeMilliTS();
    1584     PUSBPROXYURBLNX pCur;
    1585     for (pCur = pDevLnx->pInFlightHead;
    1586          pCur;
    1587          pCur = pCur->pNext)
    1588     {
    1589         if (pCur->fTimedOut)
    1590         {
    1591             if (pCur->pSplitHead)
    1592             {
    1593                 /* split */
    1594                 Assert(pCur == pCur->pSplitHead);
    1595                 unsigned cFailures = 0;
    1596                 PUSBPROXYURBLNX pCur2;
    1597                 for (pCur2 = pCur; pCur2; pCur2 = pCur2->pSplitNext)
    1598                 {
    1599                     if (pCur2->fSplitElementReaped)
    1600                         continue;
    1601 
    1602                     if (    !usbProxyLinuxDoIoCtl(pProxyDev, USBDEVFS_DISCARDURB, &pCur2->KUrb, true, UINT32_MAX)
    1603                         ||  errno == ENOENT)
    1604                         pCur2->fCanceledByTimedOut = true;
    1605                     else if (errno != ENODEV)
    1606                         Log(("vusbProxyLinuxUrbDoTimeouts: pUrb=%p failed errno=%d (!!split!!)\n", pCur2->KUrb.usercontext, errno));
    1607                     else
    1608                         goto l_leave; /* ENODEV means break and everything cancelled elsewhere. */
    1609                 }
    1610                 LogRel(("USB: Cancelled URB (%p) after %llums!! (cFailures=%d)\n",
    1611                         pCur->KUrb.usercontext, (long long unsigned) u64MilliTS - pCur->u64SubmitTS, cFailures));
    1612             }
    1613             else
    1614             {
    1615                 /* unsplit */
    1616                 if (    !usbProxyLinuxDoIoCtl(pProxyDev, USBDEVFS_DISCARDURB, &pCur->KUrb, true, UINT32_MAX)
    1617                     ||  errno == -ENOENT)
    1618                 {
    1619                     pCur->fCanceledByTimedOut = true;
    1620                     LogRel(("USB: Cancelled URB (%p) after %llums!!\n", pCur->KUrb.usercontext, (long long unsigned) u64MilliTS - pCur->u64SubmitTS));
    1621                 }
    1622                 else if (errno != ENODEV)
    1623                     LogFlow(("vusbProxyLinuxUrbDoTimeouts: pUrb=%p failed errno=%d\n", pCur->KUrb.usercontext, errno));
    1624                 else
    1625                     goto l_leave; /* ENODEV means break and everything cancelled elsewhere. */
    1626             }
    1627         }
    1628 #if 0
    1629         /* Disabled for the time being as some USB devices have URBs pending for an unknown amount of time.
    1630          * One example is the OmniKey CardMan 3821. */
    1631         else if (u64MilliTS - pCur->u64SubmitTS >= 200*1000 /* 200 sec (180 sec has been observed with XP) */)
    1632             pCur->fTimedOut = true;
    1633 #endif
    1634     }
    1635 
    1636 l_leave:
    1637     RTCritSectLeave(&pDevLnx->CritSect);
    16381565}
    16391566
     
    16951622static VUSBSTATUS vusbProxyLinuxUrbGetStatus(PUSBPROXYURBLNX pUrbLnx)
    16961623{
    1697     if (    pUrbLnx->fCanceledByTimedOut
    1698         &&  pUrbLnx->KUrb.status == 0)
    1699         return VUSBSTATUS_CRC;
    17001624    return vusbProxyLinuxStatusToVUsbStatus(pUrbLnx->KUrb.status);
    17011625}
     
    17181642     * Any URBs pending delivery?
    17191643     */
    1720     if (pDevLnx->pTaxingHead)
     1644    if (!RTListIsEmpty(&pDevLnx->ListTaxing))
    17211645    {
    17221646        RTCritSectEnter(&pDevLnx->CritSect);
    1723         pUrbLnx = pDevLnx->pTaxingHead;
     1647        pUrbLnx = RTListGetFirst(&pDevLnx->ListTaxing, USBPROXYURBLNX, NodeList);
    17241648        if (pUrbLnx)
    17251649        {
    17261650            /* unlink from the pending delivery list */
    1727             if (pUrbLnx->pNext)
    1728             {
    1729                 pUrbLnx->pNext->pPrev = NULL;
    1730                 pDevLnx->pTaxingHead = pUrbLnx->pNext;
    1731             }
    1732             else
    1733                 pDevLnx->pTaxingHead = pDevLnx->pTaxingTail = NULL;
     1651            RTListNodeRemove(&pDevLnx->ListTaxing);
    17341652
    17351653            /* temporarily into the active list, so free works right. */
    1736             pUrbLnx->pPrev = NULL;
    1737             pUrbLnx->pNext = pDevLnx->pInFlightHead;
    1738             if (pUrbLnx->pNext)
    1739                 pUrbLnx->pNext->pPrev = pUrbLnx;
    1740             pDevLnx->pInFlightHead = pUrbLnx;
     1654            RTListAppend(&pDevLnx->ListInFlight, &pUrbLnx->NodeList);
    17411655        }
    17421656        RTCritSectLeave(&pDevLnx->CritSect);
     
    17441658    if (!pUrbLnx)
    17451659    {
    1746         /*
    1747          * Don't block if nothing is in the air.
    1748          */
    1749         if (!pDevLnx->pInFlightHead)
    1750         {
    1751             int cMilliesWait = cMillies == RT_INDEFINITE_WAIT ? -1 : cMillies;
    1752 
    1753             LogFlow(("Nothing in flight, going to sleep\n"));
    1754 
    1755             struct pollfd pfd;
    1756 
    1757             pfd.fd = RTPipeToNative(pDevLnx->hPipeWakeupR);
    1758             pfd.events = POLLIN | POLLHUP;
    1759             pfd.revents = 0;
    1760 
    1761             int rc = poll(&pfd, 1, cMilliesWait);
    1762             Log(("usbProxyLinuxUrbReap: poll rc = %d\n", rc));
    1763             if (rc >= 1)
    1764             {
    1765                 /* Drain pipe. */
    1766                uint8_t bRead;
    1767                size_t cbIgnored = 0;
    1768                RTPipeRead(pDevLnx->hPipeWakeupR, &bRead, 1, &cbIgnored);
    1769             }
    1770             return NULL;
    1771         }
    1772 
    17731660        /*
    17741661         * Block for requested period.
     
    18071694                    break;
    18081695                }
    1809                 if (rc >= 0 /*|| errno == ETIMEOUT*/)
    1810                 {
    1811                     vusbProxyLinuxUrbDoTimeouts(pProxyDev, pDevLnx);
     1696                if (rc >= 0)
    18121697                    return NULL;
    1813                 }
     1698
    18141699                if (errno != EAGAIN)
    18151700                {
     
    18321717                    if (errno == ENODEV)
    18331718                        usbProxLinuxUrbUnplugged(pProxyDev);
    1834                     else if (errno == EAGAIN)
    1835                         vusbProxyLinuxUrbDoTimeouts(pProxyDev, pDevLnx);
    18361719                    else
    18371720                        Log(("usb-linux: Reap URB. errno=%d pProxyDev=%s\n", errno, usbProxyGetName(pProxyDev)));
     
    19221805                }
    19231806            }
     1807            usbProxyLinuxUrbUnlinkInFlight(pDevLnx, pUrbLnx);
    19241808            usbProxyLinuxUrbFree(pProxyDev, pUrbLnx);
    19251809        }
     
    19351819    else
    19361820    {
     1821        usbProxyLinuxUrbUnlinkInFlight(pDevLnx, pUrbLnx);
    19371822        usbProxyLinuxUrbFree(pProxyDev, pUrbLnx);
    19381823        pUrb = NULL;
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