📄 appleusbohci.cpp
字号:
USBLog(1, "%s[%p]::AllocateTD - unable to allocate a new memory block!", getName(), this); return NULL; } // link it in to my list of ED memory blocks memBlock->SetNextBlock(_itdMBHead); _itdMBHead = memBlock; numTDs = memBlock->NumITDs(); _pLastFreeITD = memBlock->GetITD(0); _pFreeITD = _pLastFreeITD; _pFreeITD->pPhysical = memBlock->GetSharedPhysicalPtr(0); _pFreeITD->pShared = memBlock->GetSharedLogicalPtr(0); USBLog(7, "%s[%p]::AllocateITD - _pFreeITD (%p), _pFreeITD->pPhysical(%p), _pFreeITD->pShared (%p), GetITDFromPhysical(%p)", getName(), this, _pFreeITD, _pFreeITD->pPhysical, _pFreeITD->pShared, AppleUSBOHCIitdMemoryBlock::GetITDFromPhysical(_pFreeITD->pPhysical)); for (i=1; i < numTDs; i++) { freeITD = memBlock->GetITD(i); if (!freeITD) { USBLog(1, "%s[%p]::AllocateTD - hmm. ran out of TDs in a memory block", getName(), this); freeITD = _pFreeITD; break; } freeITD->pLogicalNext = _pFreeITD; freeITD->pPhysical = memBlock->GetSharedPhysicalPtr(i); freeITD->pShared = memBlock->GetSharedLogicalPtr(i); _pFreeITD = freeITD; // in a normal loop termination, freeQH and _pFreeQH are the same, just like when we don't use this code } } _pFreeITD = freeITD->pLogicalNext; freeITD->pLogicalNext = NULL; freeITD->uimFlags = 0; return freeITD;}AppleOHCIGeneralTransferDescriptorPtr AppleUSBOHCI::AllocateTD(void){ AppleOHCIGeneralTransferDescriptorPtr freeTD; // pop a TD off of FreeTD list //if FreeTD == NULL return NULL // should we check if ED is full and if not access that???? freeTD = _pFreeTD; if (freeTD == NULL) { // i need to allocate another page of EDs AppleUSBOHCIgtdMemoryBlock *memBlock; UInt32 numTDs, i; memBlock = AppleUSBOHCIgtdMemoryBlock::NewMemoryBlock(); if (!memBlock) { USBLog(1, "%s[%p]::AllocateTD - unable to allocate a new memory block!", getName(), this); return NULL; } // link it in to my list of ED memory blocks memBlock->SetNextBlock(_gtdMBHead); _gtdMBHead = memBlock; numTDs = memBlock->NumGTDs(); _pLastFreeTD = memBlock->GetGTD(0); _pFreeTD = _pLastFreeTD; _pFreeTD->pPhysical = memBlock->GetSharedPhysicalPtr(0); _pFreeTD->pShared = memBlock->GetSharedLogicalPtr(0); USBLog(7, "%s[%p]::AllocateTD - _pFreeTD (%p), _pFreeTD->pPhysical(%p), _pFreeTD->pShared (%p), GetGTDFromPhysical(%p)", getName(), this, _pFreeTD, _pFreeTD->pPhysical, _pFreeTD->pShared, AppleUSBOHCIgtdMemoryBlock::GetGTDFromPhysical(_pFreeTD->pPhysical)); for (i=1; i < numTDs; i++) { freeTD = memBlock->GetGTD(i); if (!freeTD) { USBLog(1, "%s[%p]::AllocateTD - hmm. ran out of TDs in a memory block", getName(), this); freeTD = _pFreeTD; break; } freeTD->pLogicalNext = _pFreeTD; freeTD->pPhysical = memBlock->GetSharedPhysicalPtr(i); freeTD->pShared = memBlock->GetSharedLogicalPtr(i); _pFreeTD = freeTD; // in a normal loop termination, freeQH and _pFreeQH are the same, just like when we don't use this code } } _pFreeTD = freeTD->pLogicalNext; freeTD->pLogicalNext = NULL; freeTD->uimFlags = 0; freeTD->lastFrame = 0; // used in timeout logic freeTD->lastRemaining = 0; // used in timeout logic return freeTD;}AppleOHCIEndpointDescriptorPtr AppleUSBOHCI::AllocateED(void){ AppleOHCIEndpointDescriptorPtr freeED; // Pop a ED off the FreeED list // If FreeED == NULL return Error freeED = _pFreeED; if (freeED == NULL) { // i need to allocate another page of EDs AppleUSBOHCIedMemoryBlock *memBlock; UInt32 numEDs, i; memBlock = AppleUSBOHCIedMemoryBlock::NewMemoryBlock(); if (!memBlock) { USBLog(1, "%s[%p]::AllocateED - unable to allocate a new memory block!", getName(), this); return NULL; } // link it in to my list of ED memory blocks memBlock->SetNextBlock(_edMBHead); _edMBHead = memBlock; numEDs = memBlock->NumEDs(); _pLastFreeED = memBlock->GetED(0); _pFreeED = _pLastFreeED; _pFreeED->pPhysical = memBlock->GetSharedPhysicalPtr(0); _pFreeED->pShared = memBlock->GetSharedLogicalPtr(0); USBLog(7, "%s[%p]::AllocateED - _pFreeED (%p), _pFreeED->pPhysical(%p), _pFreeED->pShared (%p)", getName(), this, _pFreeED, _pFreeED->pPhysical, _pFreeED->pShared); for (i=1; i < numEDs; i++) { freeED = memBlock->GetED(i); if (!freeED) { USBLog(1, "%s[%p]::AllocateED - hmm. ran out of EDs in a memory block", getName(), this); freeED = _pFreeED; break; } freeED->pLogicalNext = _pFreeED; freeED->pPhysical = memBlock->GetSharedPhysicalPtr(i); freeED->pShared = memBlock->GetSharedLogicalPtr(i); _pFreeED = freeED; // in a normal loop termination, freeQH and _pFreeQH are the same, just like when we don't use this code } } _pFreeED = freeED->pLogicalNext; freeED->pLogicalNext = NULL; return freeED;}IOReturn AppleUSBOHCI::DeallocateITD (AppleOHCIIsochTransferDescriptorPtr pTD){ UInt32 physical; // zero out all unnecessary fields physical = pTD->pPhysical; //bzero(pTD, sizeof(*pTD)); pTD->pLogicalNext = NULL; pTD->pPhysical = physical; if (_pFreeITD) { _pLastFreeITD->pLogicalNext = pTD; _pLastFreeITD = pTD; } else { // list is currently empty _pLastFreeITD = pTD; _pFreeITD = pTD; } return (kIOReturnSuccess);}IOReturn AppleUSBOHCI::DeallocateTD (AppleOHCIGeneralTransferDescriptorPtr pTD){ UInt32 physical; //zero out all unnecessary fields physical = pTD->pPhysical; //bzero(pTD, sizeof(*pTD)); pTD->pLogicalNext = NULL; pTD->pPhysical = physical; if (_pFreeTD) { _pLastFreeTD->pLogicalNext = pTD; _pLastFreeTD = pTD; } else { // list is currently empty _pLastFreeTD = pTD; _pFreeTD = pTD; } return (kIOReturnSuccess);}IOReturn AppleUSBOHCI::DeallocateED (AppleOHCIEndpointDescriptorPtr pED){ UInt32 physical; //zero out all unnecessary fields physical = pED->pPhysical; //bzero(pED, sizeof(*pED)); pED->pPhysical = physical; pED->pLogicalNext = NULL; if (_pFreeED){ _pLastFreeED->pLogicalNext = pED; _pLastFreeED = pED; } else { // list is currently empty _pLastFreeED = pED; _pFreeED = pED; } return (kIOReturnSuccess);}int GetEDType(AppleOHCIEndpointDescriptorPtr pED){ return ((USBToHostLong(pED->pShared->flags) & kOHCIEDControl_F) >> kOHCIEDControl_FPhase);}IOReturn AppleUSBOHCI::RemoveAllTDs (AppleOHCIEndpointDescriptorPtr pED){ RemoveTDs(pED); if (GetEDType(pED) == kOHCIEDFormatGeneralTD) { // remove the last "dummy" TD DeallocateTD( (AppleOHCIGeneralTransferDescriptorPtr) pED->pLogicalTailP); } else { DeallocateITD( (AppleOHCIIsochTransferDescriptorPtr) pED->pLogicalTailP); } pED->pLogicalTailP = NULL; return (0);}//removes all but the last of the TDsIOReturn AppleUSBOHCI::RemoveTDs(AppleOHCIEndpointDescriptorPtr pED){ AppleOHCIGeneralTransferDescriptorPtr pCurrentTD, lastTD; UInt32 bufferSizeRemaining = 0; AppleOHCIIsochTransferDescriptorPtr pITD, pITDLast; if (GetEDType(pED) == kOHCIEDFormatGeneralTD) { //process and deallocate GTD's pCurrentTD = (AppleOHCIGeneralTransferDescriptorPtr) (USBToHostLong(pED->pShared->tdQueueHeadPtr) & kOHCIHeadPMask); pCurrentTD = AppleUSBOHCIgtdMemoryBlock::GetGTDFromPhysical((IOPhysicalAddress) pCurrentTD); lastTD = (AppleOHCIGeneralTransferDescriptorPtr) pED->pLogicalTailP; pED->pLogicalHeadP = pED->pLogicalTailP; while (pCurrentTD != lastTD) { if (pCurrentTD == NULL) return (-1); //take out TD from list pED->pShared->tdQueueHeadPtr = pCurrentTD->pShared->nextTD; pED->pLogicalHeadP = pCurrentTD->pLogicalNext; bufferSizeRemaining += findBufferRemaining(pCurrentTD); // if (pCurrentTD->completion.action != NULL) if (pCurrentTD->uimFlags & kUIMFlagsCallbackTD) { IOUSBCompletion completion = pCurrentTD->command->GetUSLCompletion(); // remove callback flag before calling pCurrentTD->uimFlags &= ~kUIMFlagsCallbackTD; Complete(completion, kIOReturnAborted, bufferSizeRemaining); bufferSizeRemaining = 0; } DeallocateTD(pCurrentTD); pCurrentTD = (AppleOHCIGeneralTransferDescriptorPtr) pED->pLogicalHeadP; } } else { UInt32 phys; phys = (USBToHostLong(pED->pShared->tdQueueHeadPtr) & kOHCIHeadPMask); pITD = AppleUSBOHCIitdMemoryBlock::GetITDFromPhysical(phys); pITDLast = (AppleOHCIIsochTransferDescriptorPtr)pED->pLogicalTailP; while (pITD != pITDLast) { AppleOHCIIsochTransferDescriptorPtr pPrevITD; if (pITD == NULL) return (-1); //take out TD from list pED->pShared->tdQueueHeadPtr = pITD->pShared->nextTD; pED->pLogicalHeadP = pITD->pLogicalNext; ProcessCompletedITD (pITD, kIOReturnAborted); pPrevITD = pITD; pITD = pITD->pLogicalNext; // deallocate td DeallocateITD(pPrevITD); } } return (0);}void AppleUSBOHCI::ProcessCompletedITD (AppleOHCIIsochTransferDescriptorPtr pITD, IOReturn status){ IOUSBIsocFrame * pFrames; IOUSBLowLatencyIsocFrame * pLLFrames; int i; int frameCount; IOReturn aggregateStatus = kIOReturnSuccess; IOReturn frameStatus; UInt32 itdConditionCode; bool hadUnderrun = false; UInt32 delta; UInt32 curFrame; AbsoluteTime timeStop, timeStart; UInt64 timeElapsed; pFrames = pITD->pIsocFrame; pLLFrames = (IOUSBLowLatencyIsocFrame *) pITD->pIsocFrame; frameCount = (USBToHostLong(pITD->pShared->flags) & kOHCIITDControl_FC) >> kOHCIITDControl_FCPhase; itdConditionCode = (USBToHostLong(pITD->pShared->flags) & kOHCIITDControl_CC) >> kOHCIITDControl_CCPhase; // USBLog(3, "%s[%p]::ProcessCompletedITD: filter interrupt duration: %ld", getName(), this, (UInt32) timeElapsed); if (itdConditionCode == kOHCIITDConditionDataOverrun) { // The OHCI controller sets the status to DATAOVERRUN in this case. However, we translate it to kIOReturnIsoTooOld // so that a client need not look at every frame list to determine that they were not sent. If it gets a // kIOReturnIsoTooOld, then it can assume that all the frames have a not sent error. // status = kIOReturnIsoTooOld; USBLog(5,"%s[%p]::ProcessCompletedITD: Data Overrun in Isoch xfer. Entire TD (%p) was too late, will return kIOReturnIsoTooOld (0x%x)", getName(), this,pITD, status); } // Do some calculations related to the low latency isoch TDs: // if ( (_filterInterruptCount != 0 ) && ( (pITD->pType == kOHCIIsochronousInLowLatencyType) || (pITD->pType == kOHCIIsochronousOutLowLatencyType) ) ) { clock_get_uptime (&timeStop); timeStart = pLLFrames[pITD->frameNum].frTimeStamp; SUB_ABSOLUTETIME(&timeStop, &timeStart); absolutetime_to_nanoseconds(timeStop, &timeElapsed);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -