Changeset 45666 in vbox for trunk/src/VBox
- Timestamp:
- Apr 22, 2013 2:49:34 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/USB/DevOHCI.cpp
r45025 r45666 303 303 { 304 304 /** Address of the transport descriptor. */ 305 uint32_t GCPhysTD; 306 #if HC_ARCH_BITS == 64 307 uint32_t Alignment0; /**< Alignment pUrb correctly. */ 308 #endif 305 uint32_t GCPhysTD; 306 /** Flag indicating an inactive (not-linked) URB. */ 307 bool fInactive; 309 308 /** Pointer to the URB. */ 310 309 R3PTRTYPE(PVUSBURB) pUrb; … … 3446 3445 break; 3447 3446 } 3448 3447 else 3448 { 3449 if (Ed.hwinfo & ED_HWINFO_SKIP) 3450 { 3451 LogFlow(("ohciServicePeriodicList: Ed=%#010RX32 Ed.TailP=%#010RX32 SKIP\n", EdAddr, Ed.TailP)); 3452 /* If the ED is in 'skip' state, no transactions on it are allowed and we must 3453 * cancel outstanding URBs, if any. 3454 */ 3455 uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK; 3456 PVUSBURB pUrb = ohciTdInFlightUrb(pThis, TdAddr); 3457 if (pUrb) 3458 pThis->RootHub.pIRhConn->pfnCancelUrbsEp(pThis->RootHub.pIRhConn, pUrb); 3459 } 3460 } 3449 3461 /* next end point */ 3450 3462 EdAddr = Ed.NextED & ED_PTR_MASK; … … 3522 3534 } 3523 3535 3536 /** 3537 * Go over the in-flight URB list and cancel any URBs that are no longer in use. 3538 * This occurs when the host removes EDs or TDs from the lists and we don't notice 3539 * the sKip bit. Such URBs must be promptly canceled, otherwise there is a risk 3540 * they might "steal" data destined for another URB. 3541 */ 3542 static void ohciCancelOrphanedURBs(POHCI pThis) 3543 { 3544 bool fValidHCCA = !( pThis->hcca >= OHCI_HCCA_MASK 3545 || pThis->hcca < ~OHCI_HCCA_MASK); 3546 unsigned i, cLeft; 3547 int j; 3548 uint32_t EdAddr; 3549 PVUSBURB pUrb; 3550 3551 /* If the HCCA is not currently valid, there's nothing to do. */ 3552 if (!fValidHCCA) 3553 return; 3554 3555 /* Initially mark all in-flight URBs as inactive. */ 3556 for (i = 0, cLeft = pThis->cInFlight; cLeft && i < RT_ELEMENTS(pThis->aInFlight); i++) 3557 { 3558 if (pThis->aInFlight[i].pUrb) 3559 { 3560 pThis->aInFlight[i].fInactive = true; 3561 cLeft--; 3562 } 3563 } 3564 Assert(cLeft == 0); 3565 3566 /* Go over all bulk/control/interrupt endpoint lists; any URB found in these lists 3567 * is marked as active again. 3568 */ 3569 for (i = 0; i < OHCI_HCCA_NUM_INTR + 2; i++) 3570 { 3571 switch (i) 3572 { 3573 case OHCI_HCCA_NUM_INTR: 3574 EdAddr = pThis->bulk_head; 3575 break; 3576 case OHCI_HCCA_NUM_INTR + 1: 3577 EdAddr = pThis->ctrl_head; 3578 break; 3579 default: 3580 ohciGetDWords(pThis, pThis->hcca + i * sizeof(EdAddr), &EdAddr, 1); 3581 break; 3582 } 3583 while (EdAddr) 3584 { 3585 OHCIED Ed; 3586 OHCITD Td; 3587 ohciReadEd(pThis, EdAddr, &Ed); 3588 uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK; 3589 unsigned k = 0; 3590 do 3591 { 3592 ohciReadTd(pThis, TdAddr, &Td); 3593 j = ohci_in_flight_find(pThis, TdAddr); 3594 if (j > -1) 3595 pThis->aInFlight[j].fInactive = false; 3596 TdAddr = Td.NextTD & ED_PTR_MASK; 3597 /* Failsafe for temporarily looped lists. */ 3598 if (++k == 128) 3599 break; 3600 } while (TdAddr != (Ed.TailP & ED_PTR_MASK)); 3601 EdAddr = Ed.NextED & ED_PTR_MASK; 3602 } 3603 } 3604 3605 /* In-flight URBs still marked as inactive are not used anymore and need 3606 * to be canceled. 3607 */ 3608 for (i = 0, cLeft = pThis->cInFlight; cLeft && i < RT_ELEMENTS(pThis->aInFlight); i++) 3609 { 3610 if (pThis->aInFlight[i].pUrb) 3611 { 3612 cLeft--; 3613 pUrb = pThis->aInFlight[i].pUrb; 3614 if (pThis->aInFlight[i].fInactive 3615 && pUrb->enmState == VUSBURBSTATE_IN_FLIGHT 3616 && !pUrb->enmType == VUSBXFERTYPE_CTRL) 3617 pThis->RootHub.pIRhConn->pfnCancelUrbsEp(pThis->RootHub.pIRhConn, pUrb); 3618 } 3619 } 3620 Assert(cLeft == 0); 3621 } 3524 3622 3525 3623 /** … … 3700 3798 if ( (pThis->dqic != 0x7) && (pThis->dqic != 0) ) 3701 3799 pThis->dqic--; 3800 3801 /* Clean up any URBs that have been removed */ 3802 ohciCancelOrphanedURBs(pThis); 3702 3803 3703 3804 /* Start the next frame */
Note:
See TracChangeset
for help on using the changeset viewer.