summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/USB/DrvVUSBRootHub.cpp')
-rw-r--r--src/VBox/Devices/USB/DrvVUSBRootHub.cpp59
1 files changed, 48 insertions, 11 deletions
diff --git a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
index 7088390c..c1d5ab9d 100644
--- a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
+++ b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
@@ -1109,17 +1109,52 @@ static DECLCALLBACK(int) vusbRhAbortEpWorker(PVUSBDEV pDev, int EndPt, VUSBDIREC
}
-/** @interface_method_impl{VUSBIROOTHUBCONNECTOR,pfnAbortEp} */
-static DECLCALLBACK(int) vusbRhAbortEp(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort, int EndPt, VUSBDIRECTION enmDir)
+/** @interface_method_impl{VUSBIROOTHUBCONNECTOR,pfnAbortEpByPort} */
+static DECLCALLBACK(int) vusbRhAbortEpByPort(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t uPort, int EndPt, VUSBDIRECTION enmDir)
{
PVUSBROOTHUB pRh = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
- PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pRh, uPort, "vusbRhAbortEp");
+ PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pRh, uPort, "vusbRhAbortEpByPort");
+
+ /* We expect to be called from a device like xHCI which keeps good track
+ * of device <--> port correspondence. Being called for a nonexistent
+ * device is an error.
+ */
+ AssertPtrReturn(pDev, VERR_INVALID_PARAMETER);
if (pDev->pHub != pRh)
AssertFailedReturn(VERR_INVALID_PARAMETER);
vusbDevIoThreadExecSync(pDev, (PFNRT)vusbRhAbortEpWorker, 3, pDev, EndPt, enmDir);
- vusbDevRelease(pDev, "vusbRhAbortEp");
+ vusbDevRelease(pDev, "vusbRhAbortEpByPort");
+
+ /* The reaper thread will take care of completing the URB. */
+
+ return VINF_SUCCESS;
+}
+
+
+/** @interface_method_impl{VUSBIROOTHUBCONNECTOR,pfnAbortEpByAddr} */
+static DECLCALLBACK(int) vusbRhAbortEpByAddr(PVUSBIROOTHUBCONNECTOR pInterface, uint8_t DstAddress, int EndPt, VUSBDIRECTION enmDir)
+{
+ PVUSBROOTHUB pRh = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
+ PVUSBDEV pDev = vusbR3RhGetVUsbDevByAddrRetain(pRh, DstAddress, "vusbRhAbortEpByAddr");
+
+ /* We expect to be called from a device like OHCI which does not
+ * keep track of device <--> address correspondence and may try to
+ * cancel an address that does not correspond to a device. If there's
+ * no device, just do nothing.
+ */
+ if (!pDev)
+ return VINF_SUCCESS;
+
+ if (pDev->pHub != pRh)
+ AssertFailedReturn(VERR_INVALID_PARAMETER);
+
+ /* This method is the same as vusbRhAbortEp[ByPort], intended for old controllers
+ * which don't have a defined port <-> device relationship.
+ */
+ vusbDevIoThreadExecSync(pDev, (PFNRT)vusbRhAbortEpWorker, 3, pDev, EndPt, enmDir);
+ vusbDevRelease(pDev, "vusbRhAbortEpByAddr");
/* The reaper thread will take care of completing the URB. */
@@ -1206,7 +1241,8 @@ static DECLCALLBACK(uint32_t) vusbRhUpdateIsocFrameDelta(PVUSBIROOTHUBCONNECTOR
{
PVUSBROOTHUB pRh = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
AssertReturn(pRh, 0);
- PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pRh, uPort, "vusbRhUpdateIsocFrameDelta"); AssertPtr(pDev);
+ PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pRh, uPort, "vusbRhUpdateIsocFrameDelta");
+ AssertPtrReturn(pDev, 0);
PVUSBPIPE pPipe = &pDev->aPipes[EndPt];
uint32_t *puLastFrame;
int32_t uFrameDelta;
@@ -1243,7 +1279,7 @@ static DECLCALLBACK(int) vusbR3RhDevPowerOn(PVUSBIROOTHUBCONNECTOR pInterface, u
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevPowerOn");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, VERR_VUSB_DEVICE_NOT_ATTACHED);
int rc = VUSBIDevPowerOn(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevPowerOn");
@@ -1256,7 +1292,7 @@ static DECLCALLBACK(int) vusbR3RhDevPowerOff(PVUSBIROOTHUBCONNECTOR pInterface,
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevPowerOff");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, VERR_VUSB_DEVICE_NOT_ATTACHED);
int rc = VUSBIDevPowerOff(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevPowerOff");
@@ -1269,7 +1305,7 @@ static DECLCALLBACK(VUSBDEVICESTATE) vusbR3RhDevGetState(PVUSBIROOTHUBCONNECTOR
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevGetState");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, VUSB_DEVICE_STATE_DETACHED);
VUSBDEVICESTATE enmState = VUSBIDevGetState(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevGetState");
@@ -1282,7 +1318,7 @@ static DECLCALLBACK(bool) vusbR3RhDevIsSavedStateSupported(PVUSBIROOTHUBCONNECTO
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevIsSavedStateSupported");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, false);
bool fSavedStateSupported = VUSBIDevIsSavedStateSupported(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevIsSavedStateSupported");
@@ -1295,7 +1331,7 @@ static DECLCALLBACK(VUSBSPEED) vusbR3RhDevGetSpeed(PVUSBIROOTHUBCONNECTOR pInter
{
PVUSBROOTHUB pThis = VUSBIROOTHUBCONNECTOR_2_VUSBROOTHUB(pInterface);
PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, uPort, "vusbR3RhDevGetSpeed");
- AssertPtr(pDev);
+ AssertPtrReturn(pDev, VUSB_SPEED_UNKNOWN);
VUSBSPEED enmSpeed = pDev->IDevice.pfnGetSpeed(&pDev->IDevice);
vusbDevRelease(pDev, "vusbR3RhDevGetSpeed");
@@ -1609,7 +1645,8 @@ static DECLCALLBACK(int) vusbRhConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
pThis->IRhConnector.pfnReapAsyncUrbs = vusbRhReapAsyncUrbs;
pThis->IRhConnector.pfnCancelUrbsEp = vusbRhCancelUrbsEp;
pThis->IRhConnector.pfnCancelAllUrbs = vusbRhCancelAllUrbs;
- pThis->IRhConnector.pfnAbortEp = vusbRhAbortEp;
+ pThis->IRhConnector.pfnAbortEpByPort = vusbRhAbortEpByPort;
+ pThis->IRhConnector.pfnAbortEpByAddr = vusbRhAbortEpByAddr;
pThis->IRhConnector.pfnSetPeriodicFrameProcessing = vusbRhSetFrameProcessing;
pThis->IRhConnector.pfnGetPeriodicFrameRate = vusbRhGetPeriodicFrameRate;
pThis->IRhConnector.pfnUpdateIsocFrameDelta = vusbRhUpdateIsocFrameDelta;