VirtualBox

Changeset 57406 in vbox for trunk/src/VBox/Devices/USB


Ignore:
Timestamp:
Aug 18, 2015 9:33:44 AM (9 years ago)
Author:
vboxsync
Message:

USB/IP: Updates and fixes, implement support for isochronous transfers (not quite working yet)

File:
1 edited

Legend:

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

    r57358 r57406  
    305305
    306306/**
     307 * Isochronous packet descriptor.
     308*/
     309#pragma pack(1)
     310typedef struct UsbIpIsocPktDesc
     311{
     312    /** Offset */
     313    uint32_t       u32Offset;
     314    /** Length of the packet including padding. */
     315    uint32_t       u32Length;
     316    /** Size of the transmitted data. */
     317    uint32_t       u32ActualLength;
     318    /** Completion status for this packet. */
     319    int32_t        i32Status;
     320} UsbIpIsocPktDesc;
     321/** Pointer to a isochronous packet descriptor. */
     322typedef UsbIpIsocPktDesc *PUsbIpIsocPktDesc;
     323#pragma pack()
     324
     325/**
    307326 * USB/IP backend specific data for one URB.
    308327 * Required for tracking in flight and landed URBs.
     
    321340
    322341/**
     342 * USB/IP data receive states.
     343 */
     344typedef enum USBPROXYUSBIPRECVSTATE
     345{
     346    /** Invalid receive state. */
     347    USBPROXYUSBIPRECVSTATE_INVALID = 0,
     348    /** Currently receiving the common header structure. */
     349    USBPROXYUSBIPRECVSTATE_HDR_COMMON,
     350    /** Currently receieving the rest of the header structure. */
     351    USBPROXYUSBIPRECVSTATE_HDR_RESIDUAL,
     352    /** Currently receiving data into the URB buffer. */
     353    USBPROXYUSBIPRECVSTATE_URB_BUFFER,
     354    /** Currently receiving the isochronous packet descriptors. */
     355    USBPROXYUSBIPRECVSTATE_ISOC_PKT_DESCS,
     356    /** Usual 32bit hack. */
     357    USBPROXYUSBIPRECVSTATE_32BIT_HACK = 0x7fffffff
     358} USBPROXYUSBIPRECVSTATE;
     359/** Pointer to an receive state. */
     360typedef USBPROXYUSBIPRECVSTATE *PUSBPROXYUSBIPRECVSTATE;
     361
     362/**
    323363 * Backend data for the USB/IP USB Proxy device backend.
    324364 */
     
    326366{
    327367    /** IPRT socket handle. */
    328     RTSOCKET          hSocket;
     368    RTSOCKET                  hSocket;
    329369    /** Pollset with the wakeup pipe and socket. */
    330     RTPOLLSET         hPollSet;
     370    RTPOLLSET                 hPollSet;
    331371    /** Pipe endpoint - read (in the pollset). */
    332     RTPIPE            hPipeR;
     372    RTPIPE                    hPipeR;
    333373    /** Pipe endpoint - write. */
    334     RTPIPE            hPipeW;
     374    RTPIPE                    hPipeW;
    335375    /** Next sequence number to use for identifying submitted URBs. */
    336     volatile uint32_t u32SeqNumNext;
     376    volatile uint32_t         u32SeqNumNext;
    337377    /** Fast mutex protecting the lists below against concurrent access. */
    338     RTSEMFASTMUTEX    hMtxLists;
     378    RTSEMFASTMUTEX            hMtxLists;
    339379    /** List of in flight URBs. */
    340     RTLISTANCHOR      ListUrbsInFlight;
     380    RTLISTANCHOR              ListUrbsInFlight;
    341381    /** List of landed URBs. */
    342     RTLISTANCHOR      ListUrbsLanded;
     382    RTLISTANCHOR              ListUrbsLanded;
    343383    /** List of URBs to submit. */
    344     RTLISTANCHOR      ListUrbsToQueue;
     384    RTLISTANCHOR              ListUrbsToQueue;
    345385    /** Port of the USB/IP host to connect to. */
    346     uint32_t          uPort;
     386    uint32_t                  uPort;
    347387    /** USB/IP host address. */
    348     char             *pszHost;
     388    char                     *pszHost;
    349389    /** USB Bus ID of the device to capture. */
    350     char             *pszBusId;
     390    char                     *pszBusId;
    351391    /** The device ID to use to identify the device. */
    352     uint32_t          u32DevId;
     392    uint32_t                  u32DevId;
    353393    /** Temporary buffer for the next reply header */
    354     UsbIpRet          BufRet;
     394    UsbIpRet                  BufRet;
     395    /** Temporary buffer to hold all isochronous packet descriptors. */
     396    UsbIpIsocPktDesc          aIsocPktDesc[8];
     397    /** Pointer to the current buffer to write received data to. */
     398    uint8_t                  *pbRecv;
    355399    /** Number of bytes received so far. */
    356     size_t            cbRecv;
    357     /** Number of bytes left to receive. */
    358     size_t            cbLeft;
    359     /** Flag whether we are currently receiving data for an URB. */
    360     bool              fRecvData;
     400    size_t                    cbRecv;
     401    /** Number of bytes left to receive. until we advance the state machine and process the data */
     402    size_t                    cbLeft;
     403    /** The current receiving state. */
     404    USBPROXYUSBIPRECVSTATE    enmRecvState;
    361405    /** The URB we currently receive a response for. */
    362     PUSBPROXYURBUSBIP pUrbUsbIp;
     406    PUSBPROXYURBUSBIP         pUrbUsbIp;
    363407} USBPROXYDEVUSBIP, *PUSBPROXYDEVUSBIP;
    364408
     
    441485
    442486/**
     487 * Converts a isochronous packet descriptor from host to network endianness.
     488 *
     489 * @returns nothing.
     490 * @param   pIsocPktDesc      The packet descriptor to convert.
     491 */
     492DECLINLINE(void) usbProxyUsbIpIsocPktDescH2N(PUsbIpIsocPktDesc pIsocPktDesc)
     493{
     494    pIsocPktDesc->u32Offset       = RT_H2N_U32(pIsocPktDesc->u32Offset);
     495    pIsocPktDesc->u32Length       = RT_H2N_U32(pIsocPktDesc->u32Length);
     496    pIsocPktDesc->u32ActualLength = RT_H2N_U32(pIsocPktDesc->u32ActualLength);
     497    pIsocPktDesc->i32Status       = RT_H2N_U32(pIsocPktDesc->i32Status);
     498}
     499
     500/**
     501 * Converts a isochronous packet descriptor from network to host endianness.
     502 *
     503 * @returns nothing.
     504 * @param   pIsocPktDesc      The packet descriptor to convert.
     505 */
     506DECLINLINE(void) usbProxyUsbIpIsocPktDescN2H(PUsbIpIsocPktDesc pIsocPktDesc)
     507{
     508    pIsocPktDesc->u32Offset       = RT_N2H_U32(pIsocPktDesc->u32Offset);
     509    pIsocPktDesc->u32Length       = RT_N2H_U32(pIsocPktDesc->u32Length);
     510    pIsocPktDesc->u32ActualLength = RT_N2H_U32(pIsocPktDesc->u32ActualLength);
     511    pIsocPktDesc->i32Status       = RT_N2H_U32(pIsocPktDesc->i32Status);
     512}
     513
     514/**
    443515 * Converts a unlink request from host to network endianness.
    444516 *
     
    478550    pDevice->u16ProductId = RT_N2H_U16(pDevice->u16ProductId);
    479551    pDevice->u16BcdDevice = RT_N2H_U16(pDevice->u16BcdDevice);
     552}
     553
     554/**
     555 * Converts a USB/IP status code to a VBox status code.
     556 *
     557 * @returns VUSB status code.
     558 * @param   i32Status    The USB/IP status code from the reply.
     559 */
     560DECLINLINE(int) usbProxyUsbIpStatusConvertFromStatus(int32_t i32Status)
     561{
     562    if (RT_LIKELY(i32Status == USBIP_STATUS_SUCCESS))
     563        return VINF_SUCCESS;
     564
     565    switch (i32Status)
     566    {
     567        case USBIP_STATUS_PIPE_STALLED:
     568            return VINF_SUCCESS;
     569        default:
     570            return VERR_INVALID_STATE;
     571    }
     572
     573    return VERR_INVALID_STATE;
    480574}
    481575
     
    772866        {
    773867            usbProxyUsbIpRetSubmitN2H(&RetSubmit);
    774             rc = usbProxyUsbIpVUsbStatusConvertFromStatus(RetSubmit.u32Status);
     868            rc = usbProxyUsbIpStatusConvertFromStatus(RetSubmit.u32Status);
    775869        }
    776870    }
     
    810904static void usbProxyUsbIpResetRecvState(PUSBPROXYDEVUSBIP pProxyDevUsbIp)
    811905{
    812     pProxyDevUsbIp->fRecvData = false;
    813     pProxyDevUsbIp->cbRecv    = 0;
    814     pProxyDevUsbIp->cbLeft    = sizeof(UsbIpReqRetHdr);
     906    pProxyDevUsbIp->enmRecvState = USBPROXYUSBIPRECVSTATE_HDR_COMMON;
     907    pProxyDevUsbIp->pbRecv       = (uint8_t *)&pProxyDevUsbIp->BufRet;
     908    pProxyDevUsbIp->cbRecv       = 0;
     909    pProxyDevUsbIp->cbLeft       = sizeof(UsbIpReqRetHdr);
     910}
     911
     912static void usbProxyUsbIpRecvStateAdvance(PUSBPROXYDEVUSBIP pProxyDevUsbIp, USBPROXYUSBIPRECVSTATE enmState,
     913                                          uint8_t *pbData, size_t cbData)
     914{
     915    pProxyDevUsbIp->enmRecvState = enmState;
     916    pProxyDevUsbIp->cbRecv = 0;
     917    pProxyDevUsbIp->cbLeft = cbData;
     918    pProxyDevUsbIp->pbRecv = pbData;
    815919}
    816920
     
    830934    PUSBPROXYURBUSBIP pUrbUsbIp = NULL;
    831935
    832     if (pProxyDevUsbIp->fRecvData)
    833     {
    834         /* Read data into the URB. */
    835         rc = RTTcpReadNB(pProxyDevUsbIp->hSocket, &pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->abData[pProxyDevUsbIp->cbRecv], pProxyDevUsbIp->cbLeft, &cbRead);
    836         if (RT_SUCCESS(rc))
    837         {
    838             pProxyDevUsbIp->cbRecv += cbRead;
    839             pProxyDevUsbIp->cbLeft -= cbRead;
    840 
    841             if (!pProxyDevUsbIp->cbLeft)
    842             {
    843                 pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp;
    844                 usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
    845             }
    846         }
    847         else
    848         {
    849             pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp;
    850             pUrbUsbIp->pVUsbUrb->enmStatus = VUSBSTATUS_DNR;
    851             usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
    852         }
    853     }
    854     else
    855     {
    856         rc = RTTcpReadNB(pProxyDevUsbIp->hSocket, &pProxyDevUsbIp->BufRet.abReply[pProxyDevUsbIp->cbRecv], pProxyDevUsbIp->cbLeft, &cbRead);
    857         if (RT_SUCCESS(rc))
    858         {
    859             pProxyDevUsbIp->cbRecv += cbRead;
    860             pProxyDevUsbIp->cbLeft -= cbRead;
    861         }
    862 
    863         /* Check whether we received a complete header. */
     936    Assert(pProxyDevUsbIp->cbLeft);
     937
     938    /* Read any available data first. */
     939    rc = RTTcpReadNB(pProxyDevUsbIp->hSocket, pProxyDevUsbIp->pbRecv, pProxyDevUsbIp->cbLeft, &cbRead);
     940    if (RT_SUCCESS(rc))
     941    {
     942        pProxyDevUsbIp->cbRecv += cbRead;
     943        pProxyDevUsbIp->cbLeft -= cbRead;
     944        pProxyDevUsbIp->pbRecv += cbRead;
     945
     946        /* Process the received data if there is nothing to receive left for the current state. */
    864947        if (!pProxyDevUsbIp->cbLeft)
    865948        {
    866             if (pProxyDevUsbIp->cbRecv == sizeof(UsbIpReqRetHdr))
     949            switch (pProxyDevUsbIp->enmRecvState)
    867950            {
    868                 /*
    869                  * Determine the residual amount of data to receive until
    870                  * the complete reply header was received.
    871                  */
    872                 switch (RT_N2H_U32(pProxyDevUsbIp->BufRet.Hdr.u32ReqRet))
     951                case USBPROXYUSBIPRECVSTATE_HDR_COMMON:
    873952                {
    874                     case USBIP_RET_SUBMIT:
    875                         pProxyDevUsbIp->cbLeft = sizeof(UsbIpRetSubmit) - sizeof(UsbIpReqRetHdr);
    876                         break;
    877                     case USBIP_RET_UNLINK:
    878                         pProxyDevUsbIp->cbLeft = sizeof(UsbIpRetUnlink) - sizeof(UsbIpReqRetHdr);
    879                         break;
    880                     default:
    881                         AssertLogRelMsgFailed(("Invalid reply header received: %d\n",
    882                                                pProxyDevUsbIp->BufRet.Hdr.u32ReqRet));
    883                         usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
    884                 }
    885             }
    886             else
    887             {
    888                 AssertMsg(pProxyDevUsbIp->cbRecv > sizeof(UsbIpReqRetHdr), ("Invalid state\n"));
    889 
    890                 /* Get the URB from the in flight list. */
    891                 pProxyDevUsbIp->pUrbUsbIp = usbProxyUsbIpGetUrbFromSeqNum(pProxyDevUsbIp, RT_N2H_U32(pProxyDevUsbIp->BufRet.Hdr.u32SeqNum));
    892                 if (pProxyDevUsbIp->pUrbUsbIp)
    893                 {
    894                     /** @todo: Verify that the directions match, verify that the length doesn't exceed the buffer. */
    895 
     953                    Assert(pProxyDevUsbIp->cbRecv == sizeof(UsbIpReqRetHdr));
     954
     955                    /*
     956                     * Determine the residual amount of data to receive until
     957                     * the complete reply header was received.
     958                     */
    896959                    switch (RT_N2H_U32(pProxyDevUsbIp->BufRet.Hdr.u32ReqRet))
    897960                    {
    898961                        case USBIP_RET_SUBMIT:
    899                             usbProxyUsbIpRetSubmitN2H(&pProxyDevUsbIp->BufRet.RetSubmit);
    900                             pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pProxyDevUsbIp->BufRet.RetSubmit.u32Status);
    901                             if (   pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmDir == VUSBDIRECTION_IN
    902                                 && pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmStatus == VUSBSTATUS_OK)
    903                             {
    904                                 pProxyDevUsbIp->fRecvData = true;
    905                                 if (pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmType == VUSBXFERTYPE_MSG)
     962                            pProxyDevUsbIp->cbLeft = sizeof(UsbIpRetSubmit) - sizeof(UsbIpReqRetHdr);
     963                            pProxyDevUsbIp->enmRecvState = USBPROXYUSBIPRECVSTATE_HDR_RESIDUAL;
     964                            break;
     965                        case USBIP_RET_UNLINK:
     966                            pProxyDevUsbIp->cbLeft = sizeof(UsbIpRetUnlink) - sizeof(UsbIpReqRetHdr);
     967                            pProxyDevUsbIp->enmRecvState = USBPROXYUSBIPRECVSTATE_HDR_RESIDUAL;
     968                            break;
     969                        default:
     970                            AssertLogRelMsgFailed(("Invalid reply header received: %d\n",
     971                                                   pProxyDevUsbIp->BufRet.Hdr.u32ReqRet));
     972                            usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
     973                    }
     974
     975                    break;
     976                }
     977                case USBPROXYUSBIPRECVSTATE_HDR_RESIDUAL:
     978                {
     979                    /* Get the URB from the in flight list. */
     980                    pProxyDevUsbIp->pUrbUsbIp = usbProxyUsbIpGetUrbFromSeqNum(pProxyDevUsbIp, RT_N2H_U32(pProxyDevUsbIp->BufRet.Hdr.u32SeqNum));
     981                    if (pProxyDevUsbIp->pUrbUsbIp)
     982                    {
     983                        /** @todo: Verify that the directions match, verify that the length doesn't exceed the buffer. */
     984
     985                        switch (RT_N2H_U32(pProxyDevUsbIp->BufRet.Hdr.u32ReqRet))
     986                        {
     987                            case USBIP_RET_SUBMIT:
     988                                usbProxyUsbIpRetSubmitN2H(&pProxyDevUsbIp->BufRet.RetSubmit);
     989
     990                                pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pProxyDevUsbIp->BufRet.RetSubmit.u32Status);
     991                                if (   pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmDir == VUSBDIRECTION_IN
     992                                    && pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmStatus == VUSBSTATUS_OK)
    906993                                {
    907                                     /* Preserve the setup request. */
    908                                     pProxyDevUsbIp->cbRecv = sizeof(VUSBSETUP);
    909                                     pProxyDevUsbIp->cbLeft = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength;
    910                                     pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength + sizeof(VUSBSETUP);
     994                                    uint8_t *pbData = NULL;
     995
     996                                    if (pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmType == VUSBXFERTYPE_MSG)
     997                                    {
     998                                        /* Preserve the setup request. */
     999                                        pbData = &pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->abData[sizeof(VUSBSETUP)];
     1000                                        pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength + sizeof(VUSBSETUP);
     1001                                    }
     1002                                    else
     1003                                    {
     1004                                        pbData = &pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->abData[0];
     1005                                        pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength;
     1006                                    }
     1007
     1008                                    usbProxyUsbIpRecvStateAdvance(pProxyDevUsbIp, USBPROXYUSBIPRECVSTATE_URB_BUFFER,
     1009                                                                  pbData, pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength);
    9111010                                }
    9121011                                else
    9131012                                {
    914                                     pProxyDevUsbIp->cbRecv = 0;
    915                                     pProxyDevUsbIp->cbLeft = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength;
    916                                     pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength;
     1013                                    Assert(   pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmDir == VUSBDIRECTION_OUT
     1014                                           || pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmStatus != VUSBSTATUS_OK);
     1015                                    pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp;
     1016                                    usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
    9171017                                }
    918                             }
    919                             else
    920                             {
    921                                 Assert(   pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmDir == VUSBDIRECTION_OUT
    922                                        || pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmStatus != VUSBSTATUS_OK);
     1018                                break;
     1019                            case USBIP_RET_UNLINK:
     1020                                usbProxyUsbIpRetUnlinkN2H(&pProxyDevUsbIp->BufRet.RetUnlink);
    9231021                                pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp;
     1022                                pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pProxyDevUsbIp->BufRet.RetUnlink.u32Status);
    9241023                                usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
    925                             }
    926                             break;
    927                         case USBIP_RET_UNLINK:
    928                             usbProxyUsbIpRetUnlinkN2H(&pProxyDevUsbIp->BufRet.RetUnlink);
    929                             pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp;
    930                             pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pProxyDevUsbIp->BufRet.RetUnlink.u32Status);
    931                             usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
    932                             break;
     1024                                break;
     1025                        }
    9331026                    }
     1027                    else
     1028                    {
     1029                        LogRel(("USB/IP: Received reply with sequence number doesn't match any local URB\n", pProxyDevUsbIp->BufRet.Hdr.u32SeqNum));
     1030                        usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
     1031                    }
     1032
     1033                    break;
    9341034                }
    935                 else
    936                 {
    937                     LogRel(("USB/IP: Received reply with sequence number doesn't match any local URB\n", pProxyDevUsbIp->BufRet.Hdr.u32SeqNum));
     1035                case USBPROXYUSBIPRECVSTATE_URB_BUFFER:
     1036                    if (pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->enmType == VUSBXFERTYPE_ISOC)
     1037                        usbProxyUsbIpRecvStateAdvance(pProxyDevUsbIp, USBPROXYUSBIPRECVSTATE_ISOC_PKT_DESCS,
     1038                                                      (uint8_t *)&pProxyDevUsbIp->aIsocPktDesc[0],
     1039                                                      pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cIsocPkts * sizeof(UsbIpIsocPktDesc));
     1040                    else
     1041                    {
     1042                        pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp;
     1043                        usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
     1044                    }
     1045                    break;
     1046                case USBPROXYUSBIPRECVSTATE_ISOC_PKT_DESCS:
     1047                    /* Process all received isochronous packet descriptors. */
     1048                    for (unsigned i = 0; i < pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cIsocPkts; i++)
     1049                    {
     1050                        PVUSBURBISOCPTK pIsocPkt = &pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->aIsocPkts[i];
     1051                        usbProxyUsbIpIsocPktDescN2H(&pProxyDevUsbIp->aIsocPktDesc[i]);
     1052                        pIsocPkt->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pProxyDevUsbIp->aIsocPktDesc[i].i32Status);
     1053                        pIsocPkt->off       = pProxyDevUsbIp->aIsocPktDesc[i].u32Offset;
     1054                        pIsocPkt->cb        = pProxyDevUsbIp->aIsocPktDesc[i].u32ActualLength;
     1055                    }
     1056
     1057                    pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp;
    9381058                    usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
    939                 }
     1059                    break;
     1060                default:
     1061                    AssertLogRelMsgFailed(("USB/IP: Invalid receive state %d\n", pProxyDevUsbIp->enmRecvState));
    9401062            }
    9411063        }
     1064    }
     1065    else
     1066    {
     1067        /** @todo: Complete all URBs with DNR error and mark device as unplugged. */
     1068#if 0
     1069        pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp;
     1070        pUrbUsbIp->pVUsbUrb->enmStatus = VUSBSTATUS_DNR;
     1071        usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
     1072#endif
    9421073    }
    9431074
     
    9571088static int usbProxyUsbIpUrbQueueWorker(PUSBPROXYDEVUSBIP pProxyDevUsbIp, PUSBPROXYURBUSBIP pUrbUsbIp)
    9581089{
    959     size_t cbData = 0;
    960     void  *pvData = NULL;
    9611090    PVUSBURB pUrb = pUrbUsbIp->pVUsbUrb;
    9621091
     
    9781107    ReqSubmit.u32Interval             = 0;
    9791108
     1109    RTSGSEG          aSegReq[3]; /* Maximum number of segments used for a Isochronous transfer. */
     1110    UsbIpIsocPktDesc aIsocPktsDesc[8];
     1111    unsigned cSegsUsed = 1;
     1112    aSegReq[0].pvSeg = &ReqSubmit;
     1113    aSegReq[0].cbSeg = sizeof(ReqSubmit);
     1114
     1115
    9801116    switch (pUrb->enmType)
    9811117    {
     
    9841120            if (pUrb->enmDir == VUSBDIRECTION_OUT)
    9851121            {
    986                 cbData = pUrb->cbData - sizeof(VUSBSETUP);
    987                 pvData = pUrb->abData + sizeof(VUSBSETUP);
     1122                ReqSubmit.u32TransferBufferLength -= sizeof(VUSBSETUP);
     1123                aSegReq[cSegsUsed].cbSeg = pUrb->cbData - sizeof(VUSBSETUP);
     1124                aSegReq[cSegsUsed].pvSeg = pUrb->abData + sizeof(VUSBSETUP);
     1125                cSegsUsed++;
    9881126            }
    989             else
    990                 cbData = 0;
    9911127            LogFlowFunc(("Message (Control) URB\n"));
    9921128            break;
    9931129        case VUSBXFERTYPE_ISOC:
    994             cbData = pUrb->cbData;
    995             pvData = pUrb->abData;
    996 
    9971130            ReqSubmit.u32XferFlags |= USBIP_XFER_FLAGS_ISO_ASAP;
    9981131            ReqSubmit.u32NumIsocPkts = pUrb->cIsocPkts;
    999 #if 0
     1132            if (pUrb->enmDir == VUSBDIRECTION_OUT)
     1133            {
     1134                aSegReq[cSegsUsed].cbSeg = pUrb->cbData;
     1135                aSegReq[cSegsUsed].pvSeg = pUrb->abData;
     1136                cSegsUsed++;
     1137            }
     1138
    10001139            for (unsigned i = 0; i < pUrb->cIsocPkts; i++)
    10011140            {
    1002                 pUrbLnx->KUrb.iso_frame_desc[i].length = pUrb->aIsocPkts[i].cb;
    1003                 pUrbLnx->KUrb.iso_frame_desc[i].actual_length = 0;
    1004                 pUrbLnx->KUrb.iso_frame_desc[i].status = 0x7fff;
     1141                aIsocPktsDesc[i].u32Offset       = pUrb->aIsocPkts[i].off;
     1142                aIsocPktsDesc[i].u32Length       = pUrb->aIsocPkts[i].cb;
     1143                aIsocPktsDesc[i].u32ActualLength = 0; /** @todo */
     1144                aIsocPktsDesc[i].i32Status       = pUrb->aIsocPkts[i].enmStatus;
     1145                usbProxyUsbIpIsocPktDescH2N(&aIsocPktsDesc[i]);
    10051146            }
    1006 #else /** @todo: Implement isochronous support */
    1007             usbProxyUsbIpUrbFree(pProxyDevUsbIp, pUrbUsbIp);
    1008             return VERR_NOT_SUPPORTED;
    1009 #endif
     1147
     1148            if (pUrb->cIsocPkts)
     1149            {
     1150                aSegReq[cSegsUsed].cbSeg = pUrb->cIsocPkts * sizeof(UsbIpIsocPktDesc);
     1151                aSegReq[cSegsUsed].pvSeg = &aIsocPktsDesc[0];
     1152                cSegsUsed++;
     1153            }
     1154
    10101155            break;
    10111156        case VUSBXFERTYPE_BULK:
     
    10131158            if (pUrb->enmDir == VUSBDIRECTION_OUT)
    10141159            {
    1015                 cbData = pUrb->cbData;
    1016                 pvData = pUrb->abData;
     1160                aSegReq[cSegsUsed].cbSeg = pUrb->cbData;
     1161                aSegReq[cSegsUsed].pvSeg = pUrb->abData;
     1162                cSegsUsed++;
    10171163            }
    1018             else
    1019                 cbData = 0;
    10201164            break;
    10211165        default:
     
    10261170    usbProxyUsbIpReqSubmitH2N(&ReqSubmit);
    10271171
     1172    Assert(cSegsUsed <= RT_ELEMENTS(aSegReq));
     1173
    10281174    /* Send the command. */
    10291175    RTSGBUF SgBufReq;
    1030     RTSGSEG aSegReq[2];
    1031     aSegReq[0].pvSeg = &ReqSubmit;
    1032     aSegReq[0].cbSeg = sizeof(ReqSubmit);
    1033     aSegReq[1].pvSeg = pvData;
    1034     aSegReq[1].cbSeg = cbData;
    1035     RTSgBufInit(&SgBufReq, &aSegReq[0], RT_ELEMENTS(aSegReq));
     1176    RTSgBufInit(&SgBufReq, &aSegReq[0], cSegsUsed);
    10361177
    10371178    int rc = RTTcpSgWrite(pProxyDevUsbIp->hSocket, &SgBufReq);
     
    11341275    pDevUsbIp->pszBusId      = NULL;
    11351276    usbProxyUsbIpResetRecvState(pDevUsbIp);
     1277
     1278    pProxyDev->iActiveCfg = 1; /** @todo that may not be always true. */
     1279    pProxyDev->cIgnoreSetConfigs = 1;
    11361280
    11371281    rc = RTSemFastMutexCreate(&pDevUsbIp->hMtxLists);
     
    12311375    LogFlowFunc(("pProxyDev = %p\n", pProxyDev));
    12321376
     1377    int rc = VINF_SUCCESS;
    12331378    PUSBPROXYDEVUSBIP pProxyDevUsbIp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
    1234     return VINF_SUCCESS; /* No way to reset the device with the current protocol. */
     1379    VUSBSETUP Setup;
     1380
     1381    if (fResetOnLinux)
     1382    {
     1383        Setup.bmRequestType = RT_BIT(5) | 0x03; /* Port request. */
     1384        Setup.bRequest      = 0x03; /* SET_FEATURE */
     1385        Setup.wValue        = 4; /* Port feature: Reset */
     1386        Setup.wIndex        = 0; /* Port number, irrelevant */
     1387        Setup.wLength       = 0;
     1388        rc =  usbProxyUsbIpCtrlUrbExchangeSync(pProxyDevUsbIp, &Setup);
     1389        if (RT_SUCCESS(rc))
     1390        {
     1391            pProxyDev->iActiveCfg = -1;
     1392            pProxyDev->cIgnoreSetConfigs = 2;
     1393        }
     1394    }
     1395
     1396    return rc;
    12351397}
    12361398
     
    12701432
    12711433    Setup.bmRequestType = 0x1;
    1272     Setup.bRequest      = 0x11; /* SET_INTERFACE */
     1434    Setup.bRequest      = 0x0b; /* SET_INTERFACE */
    12731435    Setup.wValue        = setting;
    12741436    Setup.wIndex        = ifnum;
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