VirtualBox

Changeset 57273 in vbox


Ignore:
Timestamp:
Aug 11, 2015 1:38:08 PM (9 years ago)
Author:
vboxsync
Message:

USBProxyDevice-usbip: More updates

File:
1 edited

Legend:

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

    r57262 r57273  
    4545
    4646/** The USB version number used for the protocol. */
    47 #define USBIP_VERSION         UINT16_C(0x0100)
     47#define USBIP_VERSION         UINT16_C(0x0111)
    4848/** Request indicator in the command code. */
    4949#define USBIP_INDICATOR_REQ   RT_BIT(15)
     
    5656#define USBIP_CMD_SUBMIT      UINT32_C(1)
    5757/** USB submit status identifier. */
    58 #define USBIP_RET_SUBMIT      UINT32_C(2)
     58#define USBIP_RET_SUBMIT      UINT32_C(3)
    5959/** URB unlink (cancel) command identifier. */
    60 #define USBIP_CMD_UNLINK      UINT32_C(3)
     60#define USBIP_CMD_UNLINK      UINT32_C(2)
    6161/** URB unlink (cancel) reply identifier. */
    6262#define USBIP_RET_UNLINK      UINT32_C(4)
     
    7676#define USBIP_DIR_OUT                        UINT32_C(1)
    7777
     78/** @name USB/IP error codes.
     79 * @{ */
     80/** Success indicator. */
     81#define USBIP_STATUS_SUCCESS                 INT32_C(0)
     82/** Pipe stalled. */
     83#define USBIP_STATUS_PIPE_STALLED            INT32_C(-32)
     84/** @} */
     85
    7886/**
    7987 * Exported device entry in the OP_RET_DEVLIST reply.
     
    8391{
    8492    /** Path of the device, zero terminated string. */
    85     char    szPath[256];
     93    char     szPath[256];
    8694    /** Bus ID of the exported device, zero terminated string. */
    87     char    szBusId[32];
     95    char     szBusId[32];
    8896    /** Bus number. */
    8997    uint32_t u32BusNum;
     
    104112    /** Device protocol. */
    105113    uint8_t  bDeviceProtocol;
     114    /** Configuration value. */
     115    uint8_t  bConfigurationValue;
    106116    /** Current configuration value of the device. */
    107117    uint8_t  bNumConfigurations;
     
    112122typedef UsbIpExportedDevice *PUsbIpExportedDevice;
    113123#pragma pack()
     124AssertCompileSize(UsbIpExportedDevice, 312);
    114125
    115126/**
     
    143154    uint16_t     u16Cmd;
    144155    /** Status field, unused. */
    145     uint32_t     u32Status;
     156    int32_t      u32Status;
    146157    /** Bus Id of the device as zero terminated string. */
    147158    char         aszBusId[32];
     
    166177    uint16_t     u16Cmd;
    167178    /** Status field, unused. */
    168     uint32_t     u32Status;
     179    int32_t      u32Status;
    169180} UsbIpRetImport;
    170181/** Pointer to a import reply. */
     
    228239    UsbIpReqRetHdr Hdr;
    229240    /** Status code. */
    230     uint32_t       u32Status;
     241    int32_t        u32Status;
    231242    /** Actual length of the reply buffer. */
    232243    uint32_t       u32ActualLength;
     
    268279    UsbIpReqRetHdr Hdr;
    269280    /** Status of the request. */
    270     uint32_t       u32Status;
     281    int32_t        u32Status;
    271282} UsbIpRetUnlink;
    272283/** Pointer to a URB unlink request. */
     
    357368#define USBIP_POLL_ID_PIPE   1
    358369
     370/** USB/IP address prefix for identifcation. */
     371#define USBIP_URI_PREFIX     "usbip://"
     372/** USB/IP address prefix length. */
     373#define USBIP_URI_PREFIX_LEN (sizeof(USBIP_URI_PREFIX) - 1)
     374
    359375/**
    360376 * Converts a request/reply header from network to host endianness.
     
    460476
    461477/**
    462  * Converts a USB/IP status code to VBox status code.
    463  *
    464  * @returns VBox status code.
    465  * @param   u32Status    The USB/IP status code from the reply.
    466  */
    467 DECLINLINE(int) usbProxyUsbIpErrConvertFromStatus(uint32_t u32Status)
    468 {
    469     if (RT_LIKELY(u32Status == 0))
    470         return VINF_SUCCESS;
    471 
    472     return VERR_NOT_IMPLEMENTED;
    473 }
    474 
    475 /**
    476478 * Converts a USB/IP status code to a VUSB status code.
    477479 *
    478480 * @returns VUSB status code.
    479  * @param   u32Status    The USB/IP status code from the reply.
    480  */
    481 DECLINLINE(VUSBSTATUS) usbProxyUsbIpVUsbStatusConvertFromStatus(uint32_t u32Status)
    482 {
    483     if (RT_LIKELY(u32Status == 0))
     481 * @param   i32Status    The USB/IP status code from the reply.
     482 */
     483DECLINLINE(VUSBSTATUS) usbProxyUsbIpVUsbStatusConvertFromStatus(int32_t i32Status)
     484{
     485    if (RT_LIKELY(i32Status == USBIP_STATUS_SUCCESS))
    484486        return VUSBSTATUS_OK;
     487
     488    switch (i32Status)
     489    {
     490        case USBIP_STATUS_PIPE_STALLED:
     491            return VUSBSTATUS_STALL;
     492        default:
     493            return VUSBSTATUS_DNR;
     494    }
    485495
    486496    return VUSBSTATUS_DNR;
     
    564574{
    565575    int rc = VINF_SUCCESS;
    566     uint32_t uPort;
    567     char *pszPortStart = RTStrStr(pszAddress, ":");
    568     char *pszHost = NULL;
    569     if (pszPortStart)
    570     {
    571         size_t cbHost = pszPortStart - pszAddress;
    572         pszPortStart++;
    573         rc = RTStrToUInt32Ex(pszPortStart, NULL, 10 /* uBase */, &pProxyDevUsbIp->uPort);
    574         if (   rc == VINF_SUCCESS
    575             || cbHost == 0)
     576
     577    if (!RTStrNCmp(pszAddress, USBIP_URI_PREFIX, USBIP_URI_PREFIX_LEN))
     578    {
     579        pszAddress += USBIP_URI_PREFIX_LEN;
     580
     581        const char *pszPortStart = RTStrStr(pszAddress, ":");
     582        if (pszPortStart)
    576583        {
    577             rc = RTStrAllocEx(&pProxyDevUsbIp->pszHost, cbHost + 1);
    578             if (RT_SUCCESS(rc))
     584            pszPortStart++;
     585
     586            const char *pszBusIdStart = RTStrStr(pszPortStart, ":");
     587            if (pszBusIdStart)
    579588            {
    580                 rc = RTStrCopyEx(pProxyDevUsbIp->pszHost, cbHost + 1, pszAddress, cbHost);
    581                 AssertRC(rc);
    582                 return VINF_SUCCESS;
     589                size_t cbHost = pszPortStart - pszAddress - 1;
     590                size_t cbBusId = strlen(pszBusIdStart);
     591
     592                pszBusIdStart++;
     593
     594                rc = RTStrToUInt32Ex(pszPortStart, NULL, 10 /* uBase */, &pProxyDevUsbIp->uPort);
     595                if (   rc == VINF_SUCCESS
     596                    || rc == VWRN_TRAILING_CHARS)
     597                {
     598                    rc = RTStrAllocEx(&pProxyDevUsbIp->pszHost, cbHost + 1);
     599                    if (RT_SUCCESS(rc))
     600                        rc = RTStrAllocEx(&pProxyDevUsbIp->pszBusId, cbBusId + 1);
     601                    if (RT_SUCCESS(rc))
     602                    {
     603                        rc = RTStrCopyEx(pProxyDevUsbIp->pszHost, cbHost + 1, pszAddress, cbHost);
     604                        AssertRC(rc);
     605
     606                        rc = RTStrCopyEx(pProxyDevUsbIp->pszBusId, cbBusId + 1, pszBusIdStart, cbBusId);
     607                        AssertRC(rc);
     608
     609                        return VINF_SUCCESS;
     610                    }
     611                }
     612                else
     613                    rc = VERR_INVALID_PARAMETER;
    583614            }
     615            else
     616                rc = VERR_INVALID_PARAMETER;
    584617        }
    585618        else
     
    613646        ReqImport.u16Version = RT_H2N_U16(USBIP_VERSION);
    614647        ReqImport.u16Cmd     = RT_H2N_U16(USBIP_INDICATOR_REQ | USBIP_REQ_RET_IMPORT);
    615         ReqImport.u32Status  = RT_H2N_U32(0);
    616         rc = RTStrCopy(&ReqImport.aszBusId[0], sizeof(ReqImport.aszBusId[0]), pProxyDevUsbIp->pszBusId);
     648        ReqImport.u32Status  = RT_H2N_U32(USBIP_STATUS_SUCCESS);
     649        rc = RTStrCopy(&ReqImport.aszBusId[0], sizeof(ReqImport.aszBusId), pProxyDevUsbIp->pszBusId);
    617650        if (rc == VINF_SUCCESS)
    618651        {
     
    627660                    RetImport.u16Version = RT_N2H_U16(RetImport.u16Version);
    628661                    RetImport.u16Cmd     = RT_N2H_U16(RetImport.u16Cmd);
    629                     RetImport.u32Status  = RT_N2H_U16(RetImport.u32Status);
     662                    RetImport.u32Status  = RT_N2H_U32(RetImport.u32Status);
    630663                    if (   RetImport.u16Version == USBIP_VERSION
    631664                        && RetImport.u16Cmd == USBIP_REQ_RET_IMPORT
    632                         && RetImport.u32Status == 0)
     665                        && RetImport.u32Status == USBIP_STATUS_SUCCESS)
    633666                    {
    634667                        /* Read the device data. */
     
    664697        {
    665698            LogRel(("UsbIp: Given bus ID is exceeds permitted protocol length: %u vs %u\n",
    666                     strlen(pProxyDevUsbIp->pszBusId) + 1, sizeof(ReqImport.aszBusId[0])));
     699                    strlen(pProxyDevUsbIp->pszBusId) + 1, sizeof(ReqImport.aszBusId)));
    667700            rc = VERR_INVALID_PARAMETER;
    668701        }
     
    734767        {
    735768            usbProxyUsbIpRetSubmitN2H(&RetSubmit);
    736             rc = usbProxyUsbIpErrConvertFromStatus(RetSubmit.u32Status);
     769            rc = usbProxyUsbIpVUsbStatusConvertFromStatus(RetSubmit.u32Status);
    737770        }
    738771    }
     
    798831    pDevUsbIp->pszHost       = NULL;
    799832    pDevUsbIp->pszBusId      = NULL;
    800     pDevUsbIp->cbRecv        = 0;
    801     pDevUsbIp->cbLeft        = sizeof(UsbIpReqRetHdr);
    802     pDevUsbIp->fRecvData     = false;
    803 
    804     /* Setup wakeup pipe and poll set first. */
    805     rc = RTPipeCreate(&pDevUsbIp->hPipeR, &pDevUsbIp->hPipeW, 0);
     833    usbProxyUsbIpResetRecvState(pDevUsbIp);
     834
     835    rc = RTSemFastMutexCreate(&pDevUsbIp->hMtxLists);
    806836    if (RT_SUCCESS(rc))
    807837    {
    808         rc = RTPollSetCreate(&pDevUsbIp->hPollSet);
     838        /* Setup wakeup pipe and poll set first. */
     839        rc = RTPipeCreate(&pDevUsbIp->hPipeR, &pDevUsbIp->hPipeW, 0);
    809840        if (RT_SUCCESS(rc))
    810841        {
    811             rc = RTPollSetAddPipe(pDevUsbIp->hPollSet, pDevUsbIp->hPipeR,
    812                                   RTPOLL_EVT_READ, USBIP_POLL_ID_PIPE);
     842            rc = RTPollSetCreate(&pDevUsbIp->hPollSet);
    813843            if (RT_SUCCESS(rc))
    814844            {
    815                 /* Connect to the USB/IP host. */
    816                 rc = usbProxyUsbIpParseAddress(pDevUsbIp, pszAddress);
     845                rc = RTPollSetAddPipe(pDevUsbIp->hPollSet, pDevUsbIp->hPipeR,
     846                                      RTPOLL_EVT_READ, USBIP_POLL_ID_PIPE);
    817847                if (RT_SUCCESS(rc))
    818                     rc = usbProxyUsbIpConnect(pDevUsbIp);
     848                {
     849                    /* Connect to the USB/IP host. */
     850                    rc = usbProxyUsbIpParseAddress(pDevUsbIp, pszAddress);
     851                    if (RT_SUCCESS(rc))
     852                        rc = usbProxyUsbIpConnect(pDevUsbIp);
     853                }
     854
     855                if (RT_FAILURE(rc))
     856                {
     857                    RTPollSetRemove(pDevUsbIp->hPollSet, USBIP_POLL_ID_PIPE);
     858                    int rc2 = RTPollSetDestroy(pDevUsbIp->hPollSet);
     859                    AssertRC(rc2);
     860                }
    819861            }
    820862
    821863            if (RT_FAILURE(rc))
    822864            {
    823                 RTPollSetRemove(pDevUsbIp->hPollSet, USBIP_POLL_ID_PIPE);
    824                 int rc2 = RTPollSetDestroy(pDevUsbIp->hPollSet);
     865                int rc2 = RTPipeClose(pDevUsbIp->hPipeR);
     866                AssertRC(rc2);
     867                rc2 = RTPipeClose(pDevUsbIp->hPipeW);
    825868                AssertRC(rc2);
    826869            }
    827         }
    828 
    829         if (RT_FAILURE(rc))
    830         {
    831             int rc2 = RTPipeClose(pDevUsbIp->hPipeR);
    832             AssertRC(rc2);
    833             rc2 = RTPipeClose(pDevUsbIp->hPipeW);
    834             AssertRC(rc2);
    835870        }
    836871    }
     
    10431078    PUSBPROXYURBUSBIP pUrbUsbIp = NULL;
    10441079    PVUSBURB pUrb = NULL;
     1080    int rc = VINF_SUCCESS;
    10451081
    10461082    /* Any URBs pending delivery? */
    10471083    if (!RTListIsEmpty(&pDev->ListUrbsLanded))
    1048     {
    10491084        pUrbUsbIp = RTListGetFirst(&pDev->ListUrbsLanded, USBPROXYURBUSBIP, NodeList);
    1050         if (pUrbUsbIp)
    1051         {
    1052             /* unlink from the pending delivery list */
    1053             usbProxyUsbIpUnlinkUrb(pDev, pUrbUsbIp);
    1054         }
    1055     }
    1056 
    1057     if (!pUrbUsbIp)
     1085
     1086    while (!pUrbUsbIp && RT_SUCCESS(rc) && cMillies)
    10581087    {
    10591088        if (!ASMAtomicXchgBool(&pDev->fWokenUp, false))
    10601089        {
    1061             int rc = VINF_SUCCESS;
    10621090            uint32_t uIdReady = 0;
    10631091            uint32_t fEventsRecv = 0;
     1092            RTMSINTERVAL msStart = RTTimeMilliTS();
     1093            RTMSINTERVAL msNow;
    10641094
    10651095            rc = RTPoll(pDev->hPollSet, cMillies, &fEventsRecv, &uIdReady);
    10661096            Assert(RT_SUCCESS(rc) || rc == VERR_TIMEOUT);
     1097
     1098            msNow = RTTimeMilliTS();
     1099            cMillies = msNow - msStart >= cMillies ? 0 : cMillies - (msNow - msStart);
    10671100
    10681101            if (RT_SUCCESS(rc))
     
    11091142                                 * the complete reply header was received.
    11101143                                 */
    1111                                 switch (pDev->BufRet.Hdr.u32ReqRet)
     1144                                switch (RT_N2H_U32(pDev->BufRet.Hdr.u32ReqRet))
    11121145                                {
    11131146                                    case USBIP_RET_SUBMIT:
     
    11181151                                        break;
    11191152                                    default:
    1120                                         AssertLogRelMsgFailed(("Invalid reply header received: %d",
     1153                                        AssertLogRelMsgFailed(("Invalid reply header received: %d\n",
    11211154                                                               pDev->BufRet.Hdr.u32ReqRet));
    11221155                                        usbProxyUsbIpResetRecvState(pDev);
     
    11281161
    11291162                                /* Get the URB from the in flight list. */
    1130                                 pDev->pUrbUsbIp = usbProxyUsbIpGetUrbFromSeqNum(pDev, pDev->BufRet.Hdr.u32SeqNum);
     1163                                pDev->pUrbUsbIp = usbProxyUsbIpGetUrbFromSeqNum(pDev, RT_N2H_U32(pDev->BufRet.Hdr.u32SeqNum));
    11311164                                if (pDev->pUrbUsbIp)
    11321165                                {
    11331166                                    /** @todo: Verify that the directions match. */
    11341167
    1135                                     switch (pDev->BufRet.Hdr.u32ReqRet)
     1168                                    switch (RT_N2H_U32(pDev->BufRet.Hdr.u32ReqRet))
    11361169                                    {
    11371170                                        case USBIP_RET_SUBMIT:
     1171                                            usbProxyUsbIpRetSubmitN2H(&pDev->BufRet.RetSubmit);
    11381172                                            pDev->pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pDev->BufRet.RetSubmit.u32Status);
    1139                                             if (pDev->BufRet.Hdr.u32Direction == USBIP_DIR_IN)
     1173                                            if (   pDev->BufRet.Hdr.u32Direction == USBIP_DIR_IN
     1174                                                && pDev->pUrbUsbIp->pVUsbUrb->enmStatus == VUSBSTATUS_OK)
    11401175                                            {
    11411176                                                pDev->fRecvData = true;
     
    11451180                                            else
    11461181                                            {
    1147                                                 Assert(pDev->BufRet.Hdr.u32Direction == USBIP_DIR_OUT);
     1182                                                Assert(   pDev->BufRet.Hdr.u32Direction == USBIP_DIR_OUT
     1183                                                       || pDev->pUrbUsbIp->pVUsbUrb->enmStatus != VUSBSTATUS_OK);
    11481184                                                pUrbUsbIp = pDev->pUrbUsbIp;
    11491185                                                usbProxyUsbIpResetRecvState(pDev);
     
    11511187                                            break;
    11521188                                        case USBIP_RET_UNLINK:
     1189                                            usbProxyUsbIpRetUnlinkN2H(&pDev->BufRet.RetUnlink);
    11531190                                            pUrbUsbIp = pDev->pUrbUsbIp;
    11541191                                            pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pDev->BufRet.RetUnlink.u32Status);
     
    11841221    {
    11851222        pUrb = pUrbUsbIp->pVUsbUrb;
     1223
     1224        /* unlink from the pending delivery list */
     1225        usbProxyUsbIpUnlinkUrb(pDev, pUrbUsbIp);
    11861226        usbProxyUsbIpUrbFree(pDev, pUrbUsbIp);
    11871227    }
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