Changeset 57273 in vbox
- Timestamp:
- Aug 11, 2015 1:38:08 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/usbip/USBProxyDevice-usbip.cpp
r57262 r57273 45 45 46 46 /** The USB version number used for the protocol. */ 47 #define USBIP_VERSION UINT16_C(0x01 00)47 #define USBIP_VERSION UINT16_C(0x0111) 48 48 /** Request indicator in the command code. */ 49 49 #define USBIP_INDICATOR_REQ RT_BIT(15) … … 56 56 #define USBIP_CMD_SUBMIT UINT32_C(1) 57 57 /** USB submit status identifier. */ 58 #define USBIP_RET_SUBMIT UINT32_C( 2)58 #define USBIP_RET_SUBMIT UINT32_C(3) 59 59 /** URB unlink (cancel) command identifier. */ 60 #define USBIP_CMD_UNLINK UINT32_C( 3)60 #define USBIP_CMD_UNLINK UINT32_C(2) 61 61 /** URB unlink (cancel) reply identifier. */ 62 62 #define USBIP_RET_UNLINK UINT32_C(4) … … 76 76 #define USBIP_DIR_OUT UINT32_C(1) 77 77 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 78 86 /** 79 87 * Exported device entry in the OP_RET_DEVLIST reply. … … 83 91 { 84 92 /** Path of the device, zero terminated string. */ 85 char szPath[256];93 char szPath[256]; 86 94 /** Bus ID of the exported device, zero terminated string. */ 87 char szBusId[32];95 char szBusId[32]; 88 96 /** Bus number. */ 89 97 uint32_t u32BusNum; … … 104 112 /** Device protocol. */ 105 113 uint8_t bDeviceProtocol; 114 /** Configuration value. */ 115 uint8_t bConfigurationValue; 106 116 /** Current configuration value of the device. */ 107 117 uint8_t bNumConfigurations; … … 112 122 typedef UsbIpExportedDevice *PUsbIpExportedDevice; 113 123 #pragma pack() 124 AssertCompileSize(UsbIpExportedDevice, 312); 114 125 115 126 /** … … 143 154 uint16_t u16Cmd; 144 155 /** Status field, unused. */ 145 uint32_tu32Status;156 int32_t u32Status; 146 157 /** Bus Id of the device as zero terminated string. */ 147 158 char aszBusId[32]; … … 166 177 uint16_t u16Cmd; 167 178 /** Status field, unused. */ 168 uint32_tu32Status;179 int32_t u32Status; 169 180 } UsbIpRetImport; 170 181 /** Pointer to a import reply. */ … … 228 239 UsbIpReqRetHdr Hdr; 229 240 /** Status code. */ 230 uint32_tu32Status;241 int32_t u32Status; 231 242 /** Actual length of the reply buffer. */ 232 243 uint32_t u32ActualLength; … … 268 279 UsbIpReqRetHdr Hdr; 269 280 /** Status of the request. */ 270 uint32_tu32Status;281 int32_t u32Status; 271 282 } UsbIpRetUnlink; 272 283 /** Pointer to a URB unlink request. */ … … 357 368 #define USBIP_POLL_ID_PIPE 1 358 369 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 359 375 /** 360 376 * Converts a request/reply header from network to host endianness. … … 460 476 461 477 /** 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 /**476 478 * Converts a USB/IP status code to a VUSB status code. 477 479 * 478 480 * @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 */ 483 DECLINLINE(VUSBSTATUS) usbProxyUsbIpVUsbStatusConvertFromStatus(int32_t i32Status) 484 { 485 if (RT_LIKELY(i32Status == USBIP_STATUS_SUCCESS)) 484 486 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 } 485 495 486 496 return VUSBSTATUS_DNR; … … 564 574 { 565 575 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) 576 583 { 577 rc = RTStrAllocEx(&pProxyDevUsbIp->pszHost, cbHost + 1); 578 if (RT_SUCCESS(rc)) 584 pszPortStart++; 585 586 const char *pszBusIdStart = RTStrStr(pszPortStart, ":"); 587 if (pszBusIdStart) 579 588 { 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; 583 614 } 615 else 616 rc = VERR_INVALID_PARAMETER; 584 617 } 585 618 else … … 613 646 ReqImport.u16Version = RT_H2N_U16(USBIP_VERSION); 614 647 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); 617 650 if (rc == VINF_SUCCESS) 618 651 { … … 627 660 RetImport.u16Version = RT_N2H_U16(RetImport.u16Version); 628 661 RetImport.u16Cmd = RT_N2H_U16(RetImport.u16Cmd); 629 RetImport.u32Status = RT_N2H_U 16(RetImport.u32Status);662 RetImport.u32Status = RT_N2H_U32(RetImport.u32Status); 630 663 if ( RetImport.u16Version == USBIP_VERSION 631 664 && RetImport.u16Cmd == USBIP_REQ_RET_IMPORT 632 && RetImport.u32Status == 0)665 && RetImport.u32Status == USBIP_STATUS_SUCCESS) 633 666 { 634 667 /* Read the device data. */ … … 664 697 { 665 698 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))); 667 700 rc = VERR_INVALID_PARAMETER; 668 701 } … … 734 767 { 735 768 usbProxyUsbIpRetSubmitN2H(&RetSubmit); 736 rc = usbProxyUsbIp ErrConvertFromStatus(RetSubmit.u32Status);769 rc = usbProxyUsbIpVUsbStatusConvertFromStatus(RetSubmit.u32Status); 737 770 } 738 771 } … … 798 831 pDevUsbIp->pszHost = NULL; 799 832 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); 806 836 if (RT_SUCCESS(rc)) 807 837 { 808 rc = RTPollSetCreate(&pDevUsbIp->hPollSet); 838 /* Setup wakeup pipe and poll set first. */ 839 rc = RTPipeCreate(&pDevUsbIp->hPipeR, &pDevUsbIp->hPipeW, 0); 809 840 if (RT_SUCCESS(rc)) 810 841 { 811 rc = RTPollSetAddPipe(pDevUsbIp->hPollSet, pDevUsbIp->hPipeR, 812 RTPOLL_EVT_READ, USBIP_POLL_ID_PIPE); 842 rc = RTPollSetCreate(&pDevUsbIp->hPollSet); 813 843 if (RT_SUCCESS(rc)) 814 844 { 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); 817 847 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 } 819 861 } 820 862 821 863 if (RT_FAILURE(rc)) 822 864 { 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); 825 868 AssertRC(rc2); 826 869 } 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);835 870 } 836 871 } … … 1043 1078 PUSBPROXYURBUSBIP pUrbUsbIp = NULL; 1044 1079 PVUSBURB pUrb = NULL; 1080 int rc = VINF_SUCCESS; 1045 1081 1046 1082 /* Any URBs pending delivery? */ 1047 1083 if (!RTListIsEmpty(&pDev->ListUrbsLanded)) 1048 {1049 1084 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) 1058 1087 { 1059 1088 if (!ASMAtomicXchgBool(&pDev->fWokenUp, false)) 1060 1089 { 1061 int rc = VINF_SUCCESS;1062 1090 uint32_t uIdReady = 0; 1063 1091 uint32_t fEventsRecv = 0; 1092 RTMSINTERVAL msStart = RTTimeMilliTS(); 1093 RTMSINTERVAL msNow; 1064 1094 1065 1095 rc = RTPoll(pDev->hPollSet, cMillies, &fEventsRecv, &uIdReady); 1066 1096 Assert(RT_SUCCESS(rc) || rc == VERR_TIMEOUT); 1097 1098 msNow = RTTimeMilliTS(); 1099 cMillies = msNow - msStart >= cMillies ? 0 : cMillies - (msNow - msStart); 1067 1100 1068 1101 if (RT_SUCCESS(rc)) … … 1109 1142 * the complete reply header was received. 1110 1143 */ 1111 switch ( pDev->BufRet.Hdr.u32ReqRet)1144 switch (RT_N2H_U32(pDev->BufRet.Hdr.u32ReqRet)) 1112 1145 { 1113 1146 case USBIP_RET_SUBMIT: … … 1118 1151 break; 1119 1152 default: 1120 AssertLogRelMsgFailed(("Invalid reply header received: %d ",1153 AssertLogRelMsgFailed(("Invalid reply header received: %d\n", 1121 1154 pDev->BufRet.Hdr.u32ReqRet)); 1122 1155 usbProxyUsbIpResetRecvState(pDev); … … 1128 1161 1129 1162 /* 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)); 1131 1164 if (pDev->pUrbUsbIp) 1132 1165 { 1133 1166 /** @todo: Verify that the directions match. */ 1134 1167 1135 switch ( pDev->BufRet.Hdr.u32ReqRet)1168 switch (RT_N2H_U32(pDev->BufRet.Hdr.u32ReqRet)) 1136 1169 { 1137 1170 case USBIP_RET_SUBMIT: 1171 usbProxyUsbIpRetSubmitN2H(&pDev->BufRet.RetSubmit); 1138 1172 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) 1140 1175 { 1141 1176 pDev->fRecvData = true; … … 1145 1180 else 1146 1181 { 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); 1148 1184 pUrbUsbIp = pDev->pUrbUsbIp; 1149 1185 usbProxyUsbIpResetRecvState(pDev); … … 1151 1187 break; 1152 1188 case USBIP_RET_UNLINK: 1189 usbProxyUsbIpRetUnlinkN2H(&pDev->BufRet.RetUnlink); 1153 1190 pUrbUsbIp = pDev->pUrbUsbIp; 1154 1191 pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pDev->BufRet.RetUnlink.u32Status); … … 1184 1221 { 1185 1222 pUrb = pUrbUsbIp->pVUsbUrb; 1223 1224 /* unlink from the pending delivery list */ 1225 usbProxyUsbIpUnlinkUrb(pDev, pUrbUsbIp); 1186 1226 usbProxyUsbIpUrbFree(pDev, pUrbUsbIp); 1187 1227 }
Note:
See TracChangeset
for help on using the changeset viewer.