Changeset 57406 in vbox for trunk/src/VBox/Devices/USB
- Timestamp:
- Aug 18, 2015 9:33:44 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/usbip/USBProxyDevice-usbip.cpp
r57358 r57406 305 305 306 306 /** 307 * Isochronous packet descriptor. 308 */ 309 #pragma pack(1) 310 typedef 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. */ 322 typedef UsbIpIsocPktDesc *PUsbIpIsocPktDesc; 323 #pragma pack() 324 325 /** 307 326 * USB/IP backend specific data for one URB. 308 327 * Required for tracking in flight and landed URBs. … … 321 340 322 341 /** 342 * USB/IP data receive states. 343 */ 344 typedef 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. */ 360 typedef USBPROXYUSBIPRECVSTATE *PUSBPROXYUSBIPRECVSTATE; 361 362 /** 323 363 * Backend data for the USB/IP USB Proxy device backend. 324 364 */ … … 326 366 { 327 367 /** IPRT socket handle. */ 328 RTSOCKET hSocket;368 RTSOCKET hSocket; 329 369 /** Pollset with the wakeup pipe and socket. */ 330 RTPOLLSET hPollSet;370 RTPOLLSET hPollSet; 331 371 /** Pipe endpoint - read (in the pollset). */ 332 RTPIPE hPipeR;372 RTPIPE hPipeR; 333 373 /** Pipe endpoint - write. */ 334 RTPIPE hPipeW;374 RTPIPE hPipeW; 335 375 /** Next sequence number to use for identifying submitted URBs. */ 336 volatile uint32_t u32SeqNumNext;376 volatile uint32_t u32SeqNumNext; 337 377 /** Fast mutex protecting the lists below against concurrent access. */ 338 RTSEMFASTMUTEX hMtxLists;378 RTSEMFASTMUTEX hMtxLists; 339 379 /** List of in flight URBs. */ 340 RTLISTANCHOR ListUrbsInFlight;380 RTLISTANCHOR ListUrbsInFlight; 341 381 /** List of landed URBs. */ 342 RTLISTANCHOR ListUrbsLanded;382 RTLISTANCHOR ListUrbsLanded; 343 383 /** List of URBs to submit. */ 344 RTLISTANCHOR ListUrbsToQueue;384 RTLISTANCHOR ListUrbsToQueue; 345 385 /** Port of the USB/IP host to connect to. */ 346 uint32_t uPort;386 uint32_t uPort; 347 387 /** USB/IP host address. */ 348 char *pszHost;388 char *pszHost; 349 389 /** USB Bus ID of the device to capture. */ 350 char *pszBusId;390 char *pszBusId; 351 391 /** The device ID to use to identify the device. */ 352 uint32_t u32DevId;392 uint32_t u32DevId; 353 393 /** 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; 355 399 /** 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; 361 405 /** The URB we currently receive a response for. */ 362 PUSBPROXYURBUSBIP pUrbUsbIp;406 PUSBPROXYURBUSBIP pUrbUsbIp; 363 407 } USBPROXYDEVUSBIP, *PUSBPROXYDEVUSBIP; 364 408 … … 441 485 442 486 /** 487 * Converts a isochronous packet descriptor from host to network endianness. 488 * 489 * @returns nothing. 490 * @param pIsocPktDesc The packet descriptor to convert. 491 */ 492 DECLINLINE(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 */ 506 DECLINLINE(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 /** 443 515 * Converts a unlink request from host to network endianness. 444 516 * … … 478 550 pDevice->u16ProductId = RT_N2H_U16(pDevice->u16ProductId); 479 551 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 */ 560 DECLINLINE(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; 480 574 } 481 575 … … 772 866 { 773 867 usbProxyUsbIpRetSubmitN2H(&RetSubmit); 774 rc = usbProxyUsbIp VUsbStatusConvertFromStatus(RetSubmit.u32Status);868 rc = usbProxyUsbIpStatusConvertFromStatus(RetSubmit.u32Status); 775 869 } 776 870 } … … 810 904 static void usbProxyUsbIpResetRecvState(PUSBPROXYDEVUSBIP pProxyDevUsbIp) 811 905 { 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 912 static 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; 815 919 } 816 920 … … 830 934 PUSBPROXYURBUSBIP pUrbUsbIp = NULL; 831 935 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. */ 864 947 if (!pProxyDevUsbIp->cbLeft) 865 948 { 866 if (pProxyDevUsbIp->cbRecv == sizeof(UsbIpReqRetHdr))949 switch (pProxyDevUsbIp->enmRecvState) 867 950 { 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: 873 952 { 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 */ 896 959 switch (RT_N2H_U32(pProxyDevUsbIp->BufRet.Hdr.u32ReqRet)) 897 960 { 898 961 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) 906 993 { 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); 911 1010 } 912 1011 else 913 1012 { 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); 917 1017 } 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); 923 1021 pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp; 1022 pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pProxyDevUsbIp->BufRet.RetUnlink.u32Status); 924 1023 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 } 933 1026 } 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; 934 1034 } 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; 938 1058 usbProxyUsbIpResetRecvState(pProxyDevUsbIp); 939 } 1059 break; 1060 default: 1061 AssertLogRelMsgFailed(("USB/IP: Invalid receive state %d\n", pProxyDevUsbIp->enmRecvState)); 940 1062 } 941 1063 } 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 942 1073 } 943 1074 … … 957 1088 static int usbProxyUsbIpUrbQueueWorker(PUSBPROXYDEVUSBIP pProxyDevUsbIp, PUSBPROXYURBUSBIP pUrbUsbIp) 958 1089 { 959 size_t cbData = 0;960 void *pvData = NULL;961 1090 PVUSBURB pUrb = pUrbUsbIp->pVUsbUrb; 962 1091 … … 978 1107 ReqSubmit.u32Interval = 0; 979 1108 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 980 1116 switch (pUrb->enmType) 981 1117 { … … 984 1120 if (pUrb->enmDir == VUSBDIRECTION_OUT) 985 1121 { 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++; 988 1126 } 989 else990 cbData = 0;991 1127 LogFlowFunc(("Message (Control) URB\n")); 992 1128 break; 993 1129 case VUSBXFERTYPE_ISOC: 994 cbData = pUrb->cbData;995 pvData = pUrb->abData;996 997 1130 ReqSubmit.u32XferFlags |= USBIP_XFER_FLAGS_ISO_ASAP; 998 1131 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 1000 1139 for (unsigned i = 0; i < pUrb->cIsocPkts; i++) 1001 1140 { 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]); 1005 1146 } 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 1010 1155 break; 1011 1156 case VUSBXFERTYPE_BULK: … … 1013 1158 if (pUrb->enmDir == VUSBDIRECTION_OUT) 1014 1159 { 1015 cbData = pUrb->cbData; 1016 pvData = pUrb->abData; 1160 aSegReq[cSegsUsed].cbSeg = pUrb->cbData; 1161 aSegReq[cSegsUsed].pvSeg = pUrb->abData; 1162 cSegsUsed++; 1017 1163 } 1018 else1019 cbData = 0;1020 1164 break; 1021 1165 default: … … 1026 1170 usbProxyUsbIpReqSubmitH2N(&ReqSubmit); 1027 1171 1172 Assert(cSegsUsed <= RT_ELEMENTS(aSegReq)); 1173 1028 1174 /* Send the command. */ 1029 1175 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); 1036 1177 1037 1178 int rc = RTTcpSgWrite(pProxyDevUsbIp->hSocket, &SgBufReq); … … 1134 1275 pDevUsbIp->pszBusId = NULL; 1135 1276 usbProxyUsbIpResetRecvState(pDevUsbIp); 1277 1278 pProxyDev->iActiveCfg = 1; /** @todo that may not be always true. */ 1279 pProxyDev->cIgnoreSetConfigs = 1; 1136 1280 1137 1281 rc = RTSemFastMutexCreate(&pDevUsbIp->hMtxLists); … … 1231 1375 LogFlowFunc(("pProxyDev = %p\n", pProxyDev)); 1232 1376 1377 int rc = VINF_SUCCESS; 1233 1378 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; 1235 1397 } 1236 1398 … … 1270 1432 1271 1433 Setup.bmRequestType = 0x1; 1272 Setup.bRequest = 0x 11; /* SET_INTERFACE */1434 Setup.bRequest = 0x0b; /* SET_INTERFACE */ 1273 1435 Setup.wValue = setting; 1274 1436 Setup.wIndex = ifnum;
Note:
See TracChangeset
for help on using the changeset viewer.