Index: src/VBox/Devices/USB/DevOHCI.cpp
===================================================================
--- src/VBox/Devices/USB/DevOHCI.cpp	(revision 45034)
+++ src/VBox/Devices/USB/DevOHCI.cpp	(working copy)
@@ -303,9 +303,7 @@
     {
         /** Address of the transport descriptor. */
         uint32_t GCPhysTD;
-#if HC_ARCH_BITS == 64
-        uint32_t Alignment0; /**< Alignment pUrb correctly. */
-#endif
+        bool inactive;
         /** Pointer to the URB. */
         R3PTRTYPE(PVUSBURB) pUrb;
     } aInFlight[257];
@@ -3445,7 +3443,20 @@
             else
                 break;
         }
-
+        else
+        {
+            if (Ed.hwinfo & ED_HWINFO_SKIP)
+            {
+                LogFlow(("ohciServicePeriodicList: Ed=%#010RX32 Ed.TailP=%#010RX32 SKIP\n", EdAddr, Ed.TailP));
+                /* If the ED is in 'skip' state, no transactions on it are allowed and we must
+                 * cancel outstanding URBs, if any.
+                 */
+                uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK;
+                PVUSBURB pUrb = ohciTdInFlightUrb(pThis, TdAddr);
+                if (pUrb)
+                    pThis->RootHub.pIRhConn->pfnCancelUrbsEp(pThis->RootHub.pIRhConn, pUrb);
+            }
+        }
         /* next end point */
         EdAddr = Ed.NextED & ED_PTR_MASK;
     }
@@ -3521,7 +3532,71 @@
     pThis->uFrameRate         = u32FrameRate;
 }
 
+static void ohciPerformCancellations(POHCI pThis)
+{
+    bool fValidHCCA = !(    pThis->hcca >= OHCI_HCCA_MASK
+                        ||  pThis->hcca < ~OHCI_HCCA_MASK);
+    unsigned i, cLeft;
+    int j;
+    uint32_t EdAddr;
+    PVUSBURB pUrb;
 
+    if (!fValidHCCA)
+        return;
+
+    for (i = 0, cLeft = pThis->cInFlight; cLeft && i < RT_ELEMENTS(pThis->aInFlight); i++)
+        if (pThis->aInFlight[i].pUrb)
+        {
+            pThis->aInFlight[i].inactive = true;
+            cLeft--;
+        }
+    Assert(cLeft == 0);
+
+    for (i = 0; i < 2 + OHCI_HCCA_NUM_INTR; i++)
+    {
+        switch (i)
+        {
+        case OHCI_HCCA_NUM_INTR:
+            EdAddr = pThis->bulk_head;
+            break;
+        case OHCI_HCCA_NUM_INTR + 1:
+            EdAddr = pThis->ctrl_head;
+            break;
+        default:
+            ohciGetDWords(pThis, pThis->hcca + i * sizeof(EdAddr), &EdAddr, 1);
+            break;
+        }
+        while (EdAddr)
+        {
+            OHCIED Ed;
+            OHCITD Td;
+            ohciReadEd(pThis, EdAddr, &Ed);
+            uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK;
+            do
+            {
+                ohciReadTd(pThis, TdAddr, &Td);
+                j = ohci_in_flight_find(pThis, TdAddr);
+                if (j > -1)
+                    pThis->aInFlight[j].inactive = false;
+                TdAddr = Td.NextTD & ED_PTR_MASK;
+            } while (TdAddr != (Ed.TailP & ED_PTR_MASK));
+            EdAddr = Ed.NextED & ED_PTR_MASK;
+        }
+    }
+
+    for (i = 0, cLeft = pThis->cInFlight; cLeft && i < RT_ELEMENTS(pThis->aInFlight); i++)
+        if (pThis->aInFlight[i].pUrb)
+        {
+            cLeft--;
+            pUrb = pThis->aInFlight[i].pUrb;
+            if (pThis->aInFlight[i].inactive
+                && pUrb->enmState == VUSBURBSTATE_IN_FLIGHT
+                && !pUrb->enmType == VUSBXFERTYPE_CTRL)
+                pThis->RootHub.pIRhConn->pfnCancelUrbsEp(pThis->RootHub.pIRhConn, pUrb);
+        }
+    Assert(cLeft == 0);
+}
+
 /**
  * Generate a Start-Of-Frame event, and set a timer for End-Of-Frame.
  */
@@ -3700,6 +3775,9 @@
     if ( (pThis->dqic != 0x7) && (pThis->dqic != 0) )
         pThis->dqic--;
 
+    /* Clean up any URBs that have been removed */
+    ohciPerformCancellations(pThis);
+
     /* Start the next frame */
     ohciStartOfFrame(pThis);
 
