Changeset 57262 in vbox for trunk/src/VBox/Devices/USB
- Timestamp:
- Aug 10, 2015 12:50:53 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 102017
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/usbip/USBProxyDevice-usbip.cpp
r56292 r57262 340 340 /** The device ID to use to identify the device. */ 341 341 uint32_t u32DevId; 342 /** Temporary buffer for the next reply header */ 343 UsbIpRet BufRet; 344 /** Number of bytes received so far. */ 345 size_t cbRecv; 346 /** Number of bytes left to receive. */ 347 size_t cbLeft; 348 /** Flag whether we are currently receiving data for an URB. */ 349 bool fRecvData; 350 /** The URB we currently receive a response for. */ 351 PUSBPROXYURBUSBIP pUrbUsbIp; 342 352 } USBPROXYDEVUSBIP, *PUSBPROXYDEVUSBIP; 343 353 … … 461 471 462 472 return VERR_NOT_IMPLEMENTED; 473 } 474 475 /** 476 * Converts a USB/IP status code to a VUSB status code. 477 * 478 * @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)) 484 return VUSBSTATUS_OK; 485 486 return VUSBSTATUS_DNR; 463 487 } 464 488 … … 716 740 } 717 741 742 /** 743 * Returns the URB matching the given sequence number from the in flight list. 744 * 745 * @returns pointer to the URB matching the given sequence number or NULL 746 * @param pProxyDevUsbIp The USB/IP proxy device data. 747 * @param u32SeqNum The sequence number to search for. 748 */ 749 static PUSBPROXYURBUSBIP usbProxyUsbIpGetUrbFromSeqNum(PUSBPROXYDEVUSBIP pProxyDevUsbIp, uint32_t u32SeqNum) 750 { 751 bool fFound = false; 752 PUSBPROXYURBUSBIP pIt; 753 754 RTListForEach(&pProxyDevUsbIp->ListUrbsInFlight, pIt, USBPROXYURBUSBIP, NodeList) 755 { 756 if (pIt->u32SeqNumUrb == u32SeqNum) 757 { 758 fFound = true; 759 break; 760 } 761 } 762 763 return fFound ? pIt : NULL; 764 } 765 766 /** 767 * Resets the receive state for a new reply. 768 * 769 * @returns nothing. 770 * @param pProxyDevUsbIp The USB/IP proxy device data. 771 */ 772 static void usbProxyUsbIpResetRecvState(PUSBPROXYDEVUSBIP pProxyDevUsbIp) 773 { 774 pProxyDevUsbIp->fRecvData = false; 775 pProxyDevUsbIp->cbRecv = 0; 776 pProxyDevUsbIp->cbLeft = sizeof(UsbIpReqRetHdr); 777 } 778 718 779 /* 719 780 * The USB proxy device functions. … … 737 798 pDevUsbIp->pszHost = NULL; 738 799 pDevUsbIp->pszBusId = NULL; 800 pDevUsbIp->cbRecv = 0; 801 pDevUsbIp->cbLeft = sizeof(UsbIpReqRetHdr); 802 pDevUsbIp->fRecvData = false; 739 803 740 804 /* Setup wakeup pipe and poll set first. */ … … 993 1057 if (!pUrbUsbIp) 994 1058 { 995 uint32_t uIdReady = 0;996 uint32_t fEventsRecv = 0;997 998 1059 if (!ASMAtomicXchgBool(&pDev->fWokenUp, false)) 999 1060 { 1000 int rc = RTPoll(pDev->hPollSet, cMillies, &fEventsRecv, &uIdReady); 1061 int rc = VINF_SUCCESS; 1062 uint32_t uIdReady = 0; 1063 uint32_t fEventsRecv = 0; 1064 1065 rc = RTPoll(pDev->hPollSet, cMillies, &fEventsRecv, &uIdReady); 1001 1066 Assert(RT_SUCCESS(rc) || rc == VERR_TIMEOUT); 1067 1068 if (RT_SUCCESS(rc)) 1069 { 1070 if (uIdReady == USBIP_POLL_ID_SOCKET) 1071 { 1072 size_t cbRead = 0; 1073 1074 if (pDev->fRecvData) 1075 { 1076 /* Read data into the URB. */ 1077 rc = RTTcpReadNB(pDev->hSocket, &pDev->pUrbUsbIp->pVUsbUrb->abData[pDev->cbRecv], pDev->cbLeft, &cbRead); 1078 if (RT_SUCCESS(rc)) 1079 { 1080 if (!pDev->cbLeft) 1081 { 1082 pUrbUsbIp = pDev->pUrbUsbIp; 1083 usbProxyUsbIpResetRecvState(pDev); 1084 } 1085 } 1086 else 1087 { 1088 pUrbUsbIp = pDev->pUrbUsbIp; 1089 pUrbUsbIp->pVUsbUrb->enmStatus = VUSBSTATUS_DNR; 1090 usbProxyUsbIpResetRecvState(pDev); 1091 } 1092 } 1093 else 1094 { 1095 rc = RTTcpReadNB(pDev->hSocket, &pDev->BufRet.abReply[pDev->cbRecv], pDev->cbLeft, &cbRead); 1096 if (RT_SUCCESS(rc)) 1097 { 1098 pDev->cbRecv += cbRead; 1099 pDev->cbLeft -= cbRead; 1100 } 1101 1102 /* Check whether we received a complete header. */ 1103 if (!pDev->cbLeft) 1104 { 1105 if (pDev->cbRecv == sizeof(UsbIpReqRetHdr)) 1106 { 1107 /* 1108 * Determine the residual amount of data to receive until 1109 * the complete reply header was received. 1110 */ 1111 switch (pDev->BufRet.Hdr.u32ReqRet) 1112 { 1113 case USBIP_RET_SUBMIT: 1114 pDev->cbLeft = sizeof(UsbIpRetSubmit) - sizeof(UsbIpReqRetHdr); 1115 break; 1116 case USBIP_RET_UNLINK: 1117 pDev->cbLeft = sizeof(UsbIpRetUnlink) - sizeof(UsbIpReqRetHdr); 1118 break; 1119 default: 1120 AssertLogRelMsgFailed(("Invalid reply header received: %d", 1121 pDev->BufRet.Hdr.u32ReqRet)); 1122 usbProxyUsbIpResetRecvState(pDev); 1123 } 1124 } 1125 else 1126 { 1127 AssertMsg(pDev->cbRecv > sizeof(UsbIpReqRetHdr), ("Invalid state\n")); 1128 1129 /* Get the URB from the in flight list. */ 1130 pDev->pUrbUsbIp = usbProxyUsbIpGetUrbFromSeqNum(pDev, pDev->BufRet.Hdr.u32SeqNum); 1131 if (pDev->pUrbUsbIp) 1132 { 1133 /** @todo: Verify that the directions match. */ 1134 1135 switch (pDev->BufRet.Hdr.u32ReqRet) 1136 { 1137 case USBIP_RET_SUBMIT: 1138 pDev->pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pDev->BufRet.RetSubmit.u32Status); 1139 if (pDev->BufRet.Hdr.u32Direction == USBIP_DIR_IN) 1140 { 1141 pDev->fRecvData = true; 1142 pDev->cbRecv = 0; 1143 pDev->cbLeft = pDev->BufRet.RetSubmit.u32ActualLength; 1144 } 1145 else 1146 { 1147 Assert(pDev->BufRet.Hdr.u32Direction == USBIP_DIR_OUT); 1148 pUrbUsbIp = pDev->pUrbUsbIp; 1149 usbProxyUsbIpResetRecvState(pDev); 1150 } 1151 break; 1152 case USBIP_RET_UNLINK: 1153 pUrbUsbIp = pDev->pUrbUsbIp; 1154 pUrbUsbIp->pVUsbUrb->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pDev->BufRet.RetUnlink.u32Status); 1155 usbProxyUsbIpResetRecvState(pDev); 1156 break; 1157 } 1158 } 1159 else 1160 { 1161 LogRel(("USB/IP: Received reply with sequence number doesn't match any local URB\n", pDev->BufRet.Hdr.u32SeqNum)); 1162 usbProxyUsbIpResetRecvState(pDev); 1163 } 1164 } 1165 } 1166 } 1167 } 1168 else 1169 { 1170 uint8_t bRead = 0; 1171 1172 AssertLogRelMsg(uIdReady == USBIP_POLL_ID_PIPE, ("Invalid pollset ID given\n")); 1173 AssertMsg(pDev->fWokenUp, ("Pipe is not empty but no one woke the reaper thread\n")); 1174 1175 rc = RTPipeRead(pDev->hPipeR, &bRead, 1, NULL); 1176 AssertRC(rc); 1177 ASMAtomicXchgBool(&pDev->fWokenUp, false); 1178 } 1179 } 1002 1180 } 1003 1004 UsbIpRet Reply;1005 1181 } 1006 1182 1007 1183 if (pUrbUsbIp) 1008 1184 { 1009 1185 pUrb = pUrbUsbIp->pVUsbUrb; 1186 usbProxyUsbIpUrbFree(pDev, pUrbUsbIp); 1010 1187 } 1011 1188 … … 1029 1206 ReqUnlink.u32SeqNum = pUrbUsbIp->u32SeqNumUrb; 1030 1207 1031 int rc = RTTcpWrite(pProxyDevUsbIp->hSocket, &ReqUnlink, sizeof(ReqUnlink)); 1032 /* Wait for the reply. */ 1033 return rc; 1208 return RTTcpWrite(pProxyDevUsbIp->hSocket, &ReqUnlink, sizeof(ReqUnlink)); 1034 1209 } 1035 1210
Note:
See TracChangeset
for help on using the changeset viewer.