VirtualBox

Changeset 53411 in vbox


Ignore:
Timestamp:
Nov 28, 2014 1:53:56 PM (10 years ago)
Author:
vboxsync
Message:

USB: Continue work on USB/IP backend

File:
1 edited

Legend:

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

    r53260 r53411  
    3232#include <iprt/socket.h>
    3333#include <iprt/poll.h>
     34#include <iprt/tcp.h>
     35#include <iprt/pipe.h>
    3436#include <iprt/list.h>
    3537#include <iprt/semaphore.h>
     
    4547#define USBIP_VERSION         UINT16_C(0x0100)
    4648/** Request indicator in the command code. */
    47 #define USBIP_INDICATOR_REQ   RT_BIT_16(15)
     49#define USBIP_INDICATOR_REQ   RT_BIT(15)
    4850
    4951/** Command/Reply code for OP_REQ/RET_DEVLIST. */
     
    273275
    274276/**
     277 * Union of possible replies from the server during normal operation.
     278 */
     279#pragma pack(1)
     280typedef union UsbIpRet
     281{
     282    /** The header. */
     283    UsbIpReqRetHdr Hdr;
     284    /** Submit reply. */
     285    UsbIpRetSubmit RetSubmit;
     286    /** Unlink reply. */
     287    UsbIpRetUnlink RetUnlink;
     288    /** Byte view. */
     289    uint8_t        abReply[1];
     290} UsbIpRet;
     291/** Pointer to a reply union. */
     292typedef UsbIpRet *PUsbIpRet;
     293#pragma pack()
     294
     295/**
    275296 * USB/IP backend specific data for one URB.
    276297 * Required for tracking in flight and landed URBs.
     
    303324    /** Flag whether the reaper thread was woken up. */
    304325    volatile bool     fWokenUp;
    305     /** Flag whether the reaper thread is waiting in the select call. */
    306     volatile bool     fWaiting;
    307326    /** Next sequence number to use for identifying submitted URBs. */
    308327    volatile uint32_t u32SeqNumNext;
     
    382401DECLINLINE(void) usbProxyUsbIpRetSubmitN2H(PUsbIpRetSubmit pRetSubmit)
    383402{
    384     usbProxyUsbIpReqRetHdrN2H(&pReqSubmit->Hdr);
     403    usbProxyUsbIpReqRetHdrN2H(&pRetSubmit->Hdr);
    385404    pRetSubmit->u32Status       = RT_N2H_U32(pRetSubmit->u32Status);
    386405    pRetSubmit->u32ActualLength = RT_N2H_U32(pRetSubmit->u32ActualLength);
     
    388407    pRetSubmit->u32NumIsocPkts  = RT_N2H_U32(pRetSubmit->u32NumIsocPkts);
    389408    pRetSubmit->u32ErrorCount   = RT_N2H_U32(pRetSubmit->u32ErrorCount);
     409}
     410
     411/**
     412 * Converts a unlink request from host to network endianness.
     413 *
     414 * @returns nothing.
     415 * @param   pReqUnlink        The unlink request to convert.
     416 */
     417DECLINLINE(void) usbProxyUsbIpReqUnlinkH2N(PUsbIpReqUnlink pReqUnlink)
     418{
     419    usbProxyUsbIpReqRetHdrH2N(&pReqUnlink->Hdr);
     420    pReqUnlink->u32SeqNum = RT_H2N_U32(pReqUnlink->u32SeqNum);
     421}
     422
     423/**
     424 * Converts a unlink reply from network to host endianness.
     425 *
     426 * @returns nothing.
     427 * @param   pRetUnlink        The unlink reply to convert.
     428 */
     429DECLINLINE(void) usbProxyUsbIpRetUnlinkN2H(PUsbIpRetUnlink pRetUnlink)
     430{
     431    usbProxyUsbIpReqRetHdrN2H(&pRetUnlink->Hdr);
     432    pRetUnlink->u32Status = RT_N2H_U32(pRetUnlink->u32Status);
    390433}
    391434
     
    432475
    433476/**
     477 * Links a given URB into the given list.
     478 *
     479 * @returns nothing.
     480 * @param   pProxyDevUsbIp    The USB/IP proxy device data.
     481 * @param   pList             The list to link the URB into.
     482 * @param   pUrbUsbIp         The URB to link.
     483 */
     484DECLINLINE(void) usbProxyUsbIpLinkUrb(PUSBPROXYDEVUSBIP pProxyDevUsbIp, PRTLISTANCHOR pList, PUSBPROXYURBUSBIP pUrbUsbIp)
     485{
     486    int rc = RTSemFastMutexRequest(pProxyDevUsbIp->hMtxLists);
     487    AssertRC(rc);
     488    RTListAppend(pList, &pUrbUsbIp->NodeList);
     489    RTSemFastMutexRelease(pProxyDevUsbIp->hMtxLists);
     490}
     491
     492/**
     493 * Unlinks a given URB from the current assigned list.
     494 *
     495 * @returns nothing.
     496 * @param   pProxyDevUsbIp    The USB/IP proxy device data.
     497 * @param   pUrbUsbIp         The URB to unlink.
     498 */
     499DECLINLINE(void) usbProxyUsbIpUnlinkUrb(PUSBPROXYDEVUSBIP pProxyDevUsbIp, PUSBPROXYURBUSBIP pUrbUsbIp)
     500{
     501    int rc = RTSemFastMutexRequest(pProxyDevUsbIp->hMtxLists);
     502    AssertRC(rc);
     503    RTListNodeRemove(&pUrbUsbIp->NodeList);
     504    RTSemFastMutexRelease(pProxyDevUsbIp->hMtxLists);
     505}
     506
     507/**
     508 * Allocates a USB/IP proxy specific URB state.
     509 *
     510 * @returns Pointer to the USB/IP specific URB data or NULL on failure.
     511 * @param   pProxyDevUsbIp    The USB/IP proxy device data.
     512 */
     513static PUSBPROXYURBUSBIP usbProxyUsbIpUrbAlloc(PUSBPROXYDEVUSBIP pProxyDevUsbIp)
     514{
     515    NOREF(pProxyDevUsbIp);
     516    return (PUSBPROXYURBUSBIP)RTMemAllocZ(sizeof(USBPROXYURBUSBIP));
     517}
     518
     519/**
     520 * Frees the given USB/IP URB state.
     521 *
     522 * @returns nothing.
     523 * @param   pProxyDevUsbIp    The USB/IP proxy device data.
     524 * @param   pUrbUsbIp         The USB/IP speciic URB data.
     525 */
     526static void usbProxyUsbIpUrbFree(PUSBPROXYDEVUSBIP pProxyDevUsbIp, PUSBPROXYURBUSBIP pUrbUsbIp)
     527{
     528    NOREF(pProxyDevUsbIp);
     529    RTMemFree(pUrbUsbIp);
     530}
     531
     532/**
    434533 * Parse the string representation of the host address.
    435534 *
     
    450549        rc = RTStrToUInt32Ex(pszPortStart, NULL, 10 /* uBase */, &pProxyDevUsbIp->uPort);
    451550        if (   rc == VINF_SUCCESS
    452             || cbHost == 0)
     551            || cbHost == 0)
    453552        {
    454             rc = RTStrAllocEx(&pDevUsbIp->pszHost, cbHost + 1);
     553            rc = RTStrAllocEx(&pProxyDevUsbIp->pszHost, cbHost + 1);
    455554            if (RT_SUCCESS(rc))
    456555            {
    457                 rc = RTStrCopyEx(pDevUsbIp->pszHost, cbHost + 1, pszAddress, cbHost);
     556                rc = RTStrCopyEx(pProxyDevUsbIp->pszHost, cbHost + 1, pszAddress, cbHost);
    458557                AssertRC(rc);
    459558                return VINF_SUCCESS;
     
    478577{
    479578    int rc = VINF_SUCCESS;
    480     rc = RTTcpClientConnect(pDevUsbIp->pszHost, pDevUsbIp->uPort, &pDevUsbIp->hSocket);
     579    rc = RTTcpClientConnect(pProxyDevUsbIp->pszHost, pProxyDevUsbIp->uPort, &pProxyDevUsbIp->hSocket);
    481580    if (RT_SUCCESS(rc))
    482581    {
    483582        /* Disable send coalescing. */
    484         rc = RTTcpSetSendCoalescing(pDevUsbIp->hSocket, false);
     583        rc = RTTcpSetSendCoalescing(pProxyDevUsbIp->hSocket, false);
    485584        if (RT_FAILURE(rc))
    486585            LogRel(("UsbIp: Disabling send coalescing failed (rc=%Rrc), continuing nevertheless but expect reduced performance\n", rc));
     
    489588        UsbIpReqImport ReqImport;
    490589        ReqImport.u16Version = RT_H2N_U16(USBIP_VERSION);
    491         ReqImport.u16Cmd     = RT_H2N_U16(USBIP_INDICATOR_REQ | USBIP_REQ_RET_IMPORT);
     590        ReqImport.u16Cmd     = RT_H2N_U16(USBIP_INDICATOR_REQ | USBIP_REQ_RET_IMPORT);
    492591        ReqImport.u32Status  = RT_H2N_U32(0);
    493592        rc = RTStrCopy(&ReqImport.aszBusId[0], sizeof(ReqImport.aszBusId[0]), pProxyDevUsbIp->pszBusId);
    494         if (rc = VINF_SUCCESS)
     593        if (rc == VINF_SUCCESS)
    495594        {
    496             rc = RTTcpWrite(pDevUsbIp->hSocket, &ReqImport, sizeof(ReqImport));
     595            rc = RTTcpWrite(pProxyDevUsbIp->hSocket, &ReqImport, sizeof(ReqImport));
    497596            if (RT_SUCCESS(rc))
    498597            {
    499598                /* Read the reply. */
    500599                UsbIpRetImport RetImport;
    501                 rc = RTTcpRead(pDevUsbIp->hSocket, &RetImport, sizeof(RetImport));
     600                rc = RTTcpRead(pProxyDevUsbIp->hSocket, &RetImport, sizeof(RetImport), NULL);
    502601                if (RT_SUCCESS(rc))
    503602                {
     
    511610                        /* Read the device data. */
    512611                        UsbIpExportedDevice Device;
    513                         rc = RTTcpRead(pDevUsbIp->hSocket, &Device, sizeof(Device));
     612                        rc = RTTcpRead(pProxyDevUsbIp->hSocket, &Device, sizeof(Device), NULL);
    514613                        if (RT_SUCCESS(rc))
    515614                        {
    516615                            usbProxyUsbIpExportedDeviceN2H(&Device);
    517                             pProxyDevUsbIp->u32DevId = (Device.u32BusNum << 16) | Device.u32DevNum;
     616                            pProxyDevUsbIp->u32DevId = (Device.u32BusNum << 16) | Device.u32DevNum;
     617
     618                            rc = RTPollSetAddSocket(pProxyDevUsbIp->hPollSet, pProxyDevUsbIp->hSocket,
     619                                                    RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, USBIP_POLL_ID_SOCKET);
    518620                        }
    519621                    }
     
    543645
    544646        if (RT_FAILURE(rc))
    545             RTTcpClientCloseEx(pDevUsbIp->hSocket, false /*fGracefulShutdown*/);
     647            RTTcpClientCloseEx(pProxyDevUsbIp->hSocket, false /*fGracefulShutdown*/);
    546648    }
    547649    if (RT_FAILURE(rc))
    548         LogRel(("UsbIp: Connecting to the host %s failed with %Rrc\n", pDevUsbIp->pszHost, rc));
     650        LogRel(("UsbIp: Connecting to the host %s failed with %Rrc\n", pProxyDevUsbIp->pszHost, rc));
    549651    return rc;
    550652}
     
    560662    int rc = VINF_SUCCESS;
    561663
    562     rc = RTTcpClientCloseEx(pDevUsbIp->hSocket, false /*fGracefulShutdown*/);
     664    rc = RTTcpClientCloseEx(pProxyDevUsbIp->hSocket, false /*fGracefulShutdown*/);
    563665    if (RT_SUCCESS(rc))
    564         pDevUsbIp->hSocket = NIL_RTSOCKET;
     666        pProxyDevUsbIp->hSocket = NIL_RTSOCKET;
    565667    return rc;
    566668}
     
    581683{
    582684    int rc = VINF_SUCCESS;
    583     AssertMsg(!pProxyDevUsbIp->fWaiting, ("usbProxyUsbIpUrbReap is called on another thread\n"));
    584685
    585686    UsbIpReqSubmit ReqSubmit;
     
    605706        /** @todo: Don't wait indefinitely long. */
    606707        UsbIpRetSubmit RetSubmit;
    607         rc = RTTcpRead(pProxyDevUsbIp->hSocket, &RetSubmit, sizeof(RetSubmit));
     708        rc = RTTcpRead(pProxyDevUsbIp->hSocket, &RetSubmit, sizeof(RetSubmit), NULL);
    608709        if (RT_SUCCESS(rc))
    609710        {
     
    633734    pDevUsbIp->hPipeR        = NIL_RTPIPE;
    634735    pDevUsbIp->fWokenUp      = false;
    635     pDevUsbIp->fWaiting      = false;
    636736    pDevUsbIp->u32SeqNumNext = 0;
    637737    pDevUsbIp->pszHost       = NULL;
     
    652752                rc = usbProxyUsbIpParseAddress(pDevUsbIp, pszAddress);
    653753                if (RT_SUCCESS(rc))
    654                     rc = usbProxyUsbIpConnect(pProxyDevUsbIp);
     754                    rc = usbProxyUsbIpConnect(pDevUsbIp);
    655755            }
    656756
     
    677777static DECLCALLBACK(void) usbProxyUsbIpClose(PUSBPROXYDEV pProxyDev)
    678778{
     779    int rc = VINF_SUCCESS;
    679780    LogFlowFunc(("pProxyDev = %p\n", pProxyDev));
    680781
     
    706807
    707808    /* Clear the URB lists. */
    708     int rc = RTSemFastMutexRequest(pDevUsbIp->hMtxLists);
     809    rc = RTSemFastMutexRequest(pDevUsbIp->hMtxLists);
    709810    AssertRC(rc);
    710811    PUSBPROXYURBUSBIP pIter = NULL;
     
    730831
    731832    PUSBPROXYDEVUSBIP pDev = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
    732     return VERR_NOT_IMPLEMENTED;
     833    return VINF_SUCCESS; /* No way to reset the device with the current protocol. */
    733834}
    734835
    735836static DECLCALLBACK(int) usbProxyUsbIpSetConfig(PUSBPROXYDEV pProxyDev, int iCfg)
    736837{
    737     LogFlowFunc(("pProxyDev=%s cfg=%#x\n", pProxyDev->pUsbIns->pszName, cfg));
     838    LogFlowFunc(("pProxyDev=%s cfg=%#x\n", pProxyDev->pUsbIns->pszName, iCfg));
    738839
    739840    PUSBPROXYDEVUSBIP pDev = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
     
    777878static DECLCALLBACK(int) usbProxyUsbIpClearHaltedEp(PUSBPROXYDEV pProxyDev, unsigned int iEp)
    778879{
    779     LogFlowFunc(("pProxyDev=%s ep=%u\n", pProxyDev->pUsbIns->pszName, ep));
     880    LogFlowFunc(("pProxyDev=%s ep=%u\n", pProxyDev->pUsbIns->pszName, iEp));
    780881
    781882    PUSBPROXYDEVUSBIP pDev = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
     
    794895    LogFlowFunc(("pUrb=%p\n", pUrb));
    795896
     897    PUSBPROXYDEVUSBIP pProxyDevUsbIp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
     898
     899    /* Allocate a USB/IP Urb. */
     900    PUSBPROXYURBUSBIP pUrbUsbIp = usbProxyUsbIpUrbAlloc(pProxyDevUsbIp);
     901    if (!pUrbUsbIp)
     902        return VERR_NO_MEMORY;
     903
     904    pUrbUsbIp->u32SeqNumUrb = usbProxyUsbIpSeqNumGet(pProxyDevUsbIp);
     905
     906    UsbIpReqSubmit ReqSubmit;
     907    ReqSubmit.Hdr.u32ReqRet           = USBIP_CMD_SUBMIT;
     908    ReqSubmit.Hdr.u32SeqNum           = pUrbUsbIp->u32SeqNumUrb;
     909    ReqSubmit.Hdr.u32DevId            = pProxyDevUsbIp->u32DevId;
     910    ReqSubmit.Hdr.u32Endpoint         = pUrb->EndPt;
     911    ReqSubmit.Hdr.u32Direction        = pUrb->enmDir == VUSBDIRECTION_IN ? USBIP_DIR_IN : USBIP_DIR_OUT;
     912    ReqSubmit.u32XferFlags            = 0;
     913    if (pUrb->enmDir == VUSBDIRECTION_IN && pUrb->fShortNotOk)
     914        ReqSubmit.u32XferFlags |= USBIP_XFER_FLAGS_SHORT_NOT_OK;
     915
     916    ReqSubmit.u32TransferBufferLength = pUrb->cbData;
     917    ReqSubmit.u32StartFrame           = 0;
     918    ReqSubmit.u32NumIsocPkts          = 0;
     919    ReqSubmit.u32Interval             = 0;
     920
     921    switch (pUrb->enmType)
     922    {
     923        case VUSBXFERTYPE_MSG:
     924            memcpy(&ReqSubmit.Setup, &pUrb->abData, sizeof(ReqSubmit.Setup));
     925            LogFlowFunc(("Message (Control) URB\n"));
     926            break;
     927        case VUSBXFERTYPE_ISOC:
     928            ReqSubmit.u32XferFlags |= USBIP_XFER_FLAGS_ISO_ASAP;
     929            ReqSubmit.u32NumIsocPkts = pUrb->cIsocPkts;
     930#if 0
     931            for (unsigned i = 0; i < pUrb->cIsocPkts; i++)
     932            {
     933                pUrbLnx->KUrb.iso_frame_desc[i].length = pUrb->aIsocPkts[i].cb;
     934                pUrbLnx->KUrb.iso_frame_desc[i].actual_length = 0;
     935                pUrbLnx->KUrb.iso_frame_desc[i].status = 0x7fff;
     936            }
     937#else /** @todo: Implement isochronous support */
     938            usbProxyUsbIpUrbFree(pProxyDevUsbIp, pUrbUsbIp);
     939            return VERR_NOT_SUPPORTED;
     940#endif
     941            break;
     942        case VUSBXFERTYPE_BULK:
     943        case VUSBXFERTYPE_INTR:
     944            break;
     945        default:
     946            usbProxyUsbIpUrbFree(pProxyDevUsbIp, pUrbUsbIp);
     947            return VERR_INVALID_PARAMETER; /** @todo: better status code. */
     948    }
     949    usbProxyUsbIpReqSubmitH2N(&ReqSubmit);
     950
     951    /* Send the command. */
     952    RTSGBUF SgBufReq;
     953    RTSGSEG aSegReq[2];
     954    aSegReq[0].pvSeg = &ReqSubmit;
     955    aSegReq[0].cbSeg = sizeof(ReqSubmit);
     956    aSegReq[1].pvSeg = &pUrb->abData[0];
     957    aSegReq[1].cbSeg = pUrb->cbData;
     958    RTSgBufInit(&SgBufReq, &aSegReq[0], RT_ELEMENTS(aSegReq));
     959
     960    int rc = RTTcpSgWrite(pProxyDevUsbIp->hSocket, &SgBufReq);
     961    if (RT_SUCCESS(rc))
     962    {
     963        /* Link the URB into the list of in flight URBs. */
     964        pUrb->Dev.pvPrivate = pUrbUsbIp;
     965        pUrbUsbIp->pVUsbUrb = pUrb;
     966        usbProxyUsbIpLinkUrb(pProxyDevUsbIp, &pProxyDevUsbIp->ListUrbsInFlight, pUrbUsbIp);
     967    }
     968    else
     969        usbProxyUsbIpUrbFree(pProxyDevUsbIp, pUrbUsbIp);
     970
     971    return rc;
     972}
     973
     974static DECLCALLBACK(PVUSBURB) usbProxyUsbIpUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies)
     975{
     976    LogFlowFunc(("pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
     977
    796978    PUSBPROXYDEVUSBIP pDev = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
    797     return VERR_NOT_IMPLEMENTED;
    798 }
    799 
    800 static DECLCALLBACK(PVUSBURB) usbProxyUsbIpUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies)
    801 {
    802     LogFlowFunc(("pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
    803 
    804     PUSBPROXYDEVUSBIP pDev = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
    805     return NULL;
     979    PUSBPROXYURBUSBIP pUrbUsbIp = NULL;
     980    PVUSBURB pUrb = NULL;
     981
     982    /* Any URBs pending delivery? */
     983    if (!RTListIsEmpty(&pDev->ListUrbsLanded))
     984    {
     985        pUrbUsbIp = RTListGetFirst(&pDev->ListUrbsLanded, USBPROXYURBUSBIP, NodeList);
     986        if (pUrbUsbIp)
     987        {
     988            /* unlink from the pending delivery list */
     989            usbProxyUsbIpUnlinkUrb(pDev, pUrbUsbIp);
     990        }
     991    }
     992
     993    if (!pUrbUsbIp)
     994    {
     995        uint32_t uIdReady = 0;
     996        uint32_t fEventsRecv = 0;
     997
     998        if (!ASMAtomicXchgBool(&pDev->fWokenUp, false))
     999        {
     1000            int rc = RTPoll(pDev->hPollSet, cMillies, &fEventsRecv, &uIdReady);
     1001            Assert(RT_SUCCESS(rc) || rc == VERR_TIMEOUT);
     1002        }
     1003
     1004        UsbIpRet Reply;
     1005    }
     1006
     1007    if (pUrbUsbIp)
     1008    {
     1009       
     1010    }
     1011
     1012    return pUrb;
    8061013}
    8071014
     
    8101017    LogFlowFunc(("pUrb=%p\n", pUrb));
    8111018
    812     PUSBPROXYDEVUSBIP pDev = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
     1019    PUSBPROXYDEVUSBIP pProxyDevUsbIp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
    8131020    PUSBPROXYURBUSBIP pUrbUsbIp = (PUSBPROXYURBUSBIP)pUrb->Dev.pvPrivate;
    8141021    UsbIpReqUnlink ReqUnlink;
    8151022
    816     uint32_t u32SeqNum = usbProxyUsbIpSeqNumGet(pDev);
    817     ReqSubmit.Hdr.u32ReqRet           = USBIP_CMD_SUBMIT;
    818     ReqSubmit.Hdr.u32SeqNum           = u32SeqNum;
    819     ReqSubmit.Hdr.u32DevId            = pProxyDevUsbIp->u32DevId;
    820     ReqSubmit.Hdr.u32Direction        = USBIP_DIR_OUT;
    821     ReqSubmit.Hdr.u32Endpoint         = 0; /* Only default control endpoint is allowed for these kind of messages. */
    822     return VERR_NOT_IMPLEMENTED;
     1023    uint32_t u32SeqNum = usbProxyUsbIpSeqNumGet(pProxyDevUsbIp);
     1024    ReqUnlink.Hdr.u32ReqRet           = USBIP_CMD_UNLINK;
     1025    ReqUnlink.Hdr.u32SeqNum           = u32SeqNum;
     1026    ReqUnlink.Hdr.u32DevId            = pProxyDevUsbIp->u32DevId;
     1027    ReqUnlink.Hdr.u32Direction        = USBIP_DIR_OUT;
     1028    ReqUnlink.Hdr.u32Endpoint         = pUrb->EndPt;
     1029    ReqUnlink.u32SeqNum               = pUrbUsbIp->u32SeqNumUrb;
     1030
     1031    int rc = RTTcpWrite(pProxyDevUsbIp->hSocket, &ReqUnlink, sizeof(ReqUnlink));
     1032    /* Wait for the reply. */
     1033    return rc;
    8231034}
    8241035
     
    8291040    PUSBPROXYDEVUSBIP pDevUsbIp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
    8301041    int rc = VINF_SUCCESS;
    831     size_t cbWritten = 0;
    832 
    833     ASMAtomicXchgBool(&pDevUsbIp->fWokenUp, true);
    834 
    835     if (ASMAtomicReadBool(&pDevUsbIp->fWaiting))
    836     {
     1042
     1043    if (!ASMAtomicXchgBool(&pDevUsbIp->fWokenUp, true))
     1044    {
     1045        size_t cbWritten = 0;
     1046
    8371047        rc = RTPipeWrite(pDevUsbIp->hPipeW, "", 1, &cbWritten);
    8381048        Assert(RT_SUCCESS(rc) || cbWritten == 0);
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