⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 appleusbohci.cpp

📁 苹果公司的OHCI USB主机协议栈的代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                if ( _lowLatencyIsochTDsProcessed != 0 )        {            USBLog(6, "%s[%p]::ProcessCompletedITD: LowLatency isoch TD's proccessed: %d, framesUpdated: %d, framesError: %d",  getName(), this, _lowLatencyIsochTDsProcessed, _framesUpdated, _framesError);            USBLog(7, "%s[%p]::ProcessCompletedITD: delay in microsecs before callback (from hw interrupt time): %ld", getName(), this, (UInt32) timeElapsed / 1000);                        // SUB_ABSOLUTETIME(&_filterTimeStamp2, &_filterTimeStamp);             // absolutetime_to_nanoseconds(_filterTimeStamp2, &timeElapsed);             // USBLog(7, "%s[%p]::ProcessCompletedITD: filter interrupt duration: %ld", getName(), this, (UInt32) timeElapsed / 1000);        }                // These need to be updated only when we process a TD due to an interrupt        //        _lowLatencyIsochTDsProcessed = 0;        _framesUpdated = 0;        _framesError = 0;     }        for (i=0; i <= frameCount; i++)    {        // Need to process low latency isoch differently than other isoc, as the frameList has an extra parameter (use pLLFrame instead of pFrame )        //        if ( (pITD->pType == kOHCIIsochronousInLowLatencyType) || (pITD->pType == kOHCIIsochronousOutLowLatencyType) )        {            UInt16 offset = USBToHostWord(pITD->pShared->offset[i]);                        // Check to see if we really processed this itd before:            //             if ( (_filterInterruptCount != 0 ) &&                    ( (pITD->pType == kOHCIIsochronousInLowLatencyType) ||                     (pITD->pType == kOHCIIsochronousOutLowLatencyType) ) )            {                if ( (pLLFrames[pITD->frameNum + i].frStatus != (IOReturn) kUSBLowLatencyIsochTransferKey) )                 {                    // USBLog(7,"%s[%p]::ProcessCompletedITD: frame processed at hw interrupt time: frame: %d, frReqCount: %d, frActCount: %d, frStatus: 0x%x frTimeStamp.lo: 0x%x",  getName(), this, i, pLLFrames[pITD->frameNum + i].frReqCount, pLLFrames[pITD->frameNum + i].frActCount, pLLFrames[pITD->frameNum + i].frStatus, pLLFrames[pITD->frameNum + i].frTimeStamp.lo);                    USBLog(6,"%s[%p]::ProcessCompletedITD: frame processed at hw interrupt time: frame: %d,  frTimeStamp.lo: 0x%x",  getName(), this, i, pLLFrames[pITD->frameNum + i].frTimeStamp.lo);                                    }            }                                    if ( ((offset & kOHCIITDOffset_CC) >> kOHCIITDOffset_CCPhase) == kOHCIITDOffsetConditionNotAccessed)            {                USBLog(6,"%s[%p]::ProcessCompletedITD:  Isoch frame not accessed. Frame in request(1 based) %d, IsocFramePtr: %p, ITD: %p, Frames in this TD: %d, Relative frame in TD: %d",  getName(), this, pITD->frameNum + i + 1, pLLFrames, pITD, frameCount+1, i+1);                pLLFrames[pITD->frameNum + i].frActCount = 0;                pLLFrames[pITD->frameNum + i].frStatus = kOHCIITDConditionNotAccessedReturn;            }            else            {                pLLFrames[pITD->frameNum + i].frStatus = (offset & kOHCIITDPSW_CC) >> kOHCIITDPSW_CCPhase;                                // Successful isoch transmit sets the size field to zero,                // successful receive sets size to actual packet size received.                if ( (kIOReturnSuccess == pLLFrames[pITD->frameNum + i].frStatus) &&                     ( (pITD->pType == kOHCIIsochronousOutType) || (pITD->pType == kOHCIIsochronousOutLowLatencyType) ) )                    pLLFrames[pITD->frameNum + i].frActCount = pLLFrames[pITD->frameNum + i].frReqCount;                else                    pLLFrames[pITD->frameNum + i].frActCount = offset & kOHCIITDPSW_Size;            }                        // Translate the OHCI Condition to one of the appropriate USB errors.  We use aggregateStatus to determine            // later on whether there was an error in any of the frames.  If there was, then we set the completion error            // to that reported in the aggregateStatus.  There is no priority in the aggregateStatus except that if there            // is a data underrun AND another type of error, then we report the "other" error.            //            frameStatus = pLLFrames[pITD->frameNum + i].frStatus;                                    if ( frameStatus != kIOReturnSuccess )            {                pLLFrames[pITD->frameNum + i].frStatus =  TranslateStatusToUSBError(frameStatus);                                if ( pLLFrames[pITD->frameNum + i].frStatus == kIOReturnUnderrun )                    hadUnderrun = true;                else                    aggregateStatus = pLLFrames[pITD->frameNum + i].frStatus;            }        }            else        {            // Process non-low latency isoch             //            UInt16 offset = USBToHostWord(pITD->pShared->offset[i]);                        if ( ((offset & kOHCIITDOffset_CC) >> kOHCIITDOffset_CCPhase) == kOHCIITDOffsetConditionNotAccessed)            {                USBLog(6,"%s[%p]::ProcessCompletedITD:  Isoch frame not accessed. Frame in request(1 based) %d, IsocFramePtr: %p, ITD: %p, Frames in this TD: %d, Relative frame in TD: %d",  getName(), this, pITD->frameNum + i + 1, pFrames, pITD, frameCount+1, i+1);                pFrames[pITD->frameNum + i].frActCount = 0;                pFrames[pITD->frameNum + i].frStatus = kOHCIITDConditionNotAccessedReturn;            }            else            {                pFrames[pITD->frameNum + i].frStatus = (offset & kOHCIITDPSW_CC) >> kOHCIITDPSW_CCPhase;                                // Successful isoch transmit sets the size field to zero,                // successful receive sets size to actual packet size received.                if ( (kIOReturnSuccess == pFrames[pITD->frameNum + i].frStatus) &&                     ( (pITD->pType == kOHCIIsochronousOutType) || (pITD->pType == kOHCIIsochronousOutLowLatencyType) ) )                    pFrames[pITD->frameNum + i].frActCount = pFrames[pITD->frameNum + i].frReqCount;                else                    pFrames[pITD->frameNum + i].frActCount = offset & kOHCIITDPSW_Size;            }                        // Translate the OHCI Condition to one of the appropriate USB errors.  We use aggregateStatus to determine            // later on whether there was an error in any of the frames.  If there was, then we set the completion error            // to that reported in the aggregateStatus.  There is no priority in the aggregateStatus except that if there            // is a data underrun AND another type of error, then we report the "other" error.            //            frameStatus = pFrames[pITD->frameNum + i].frStatus;                                    if ( frameStatus != kIOReturnSuccess )            {                pFrames[pITD->frameNum + i].frStatus =  TranslateStatusToUSBError(frameStatus);                                if ( pFrames[pITD->frameNum + i].frStatus == kIOReturnUnderrun )                    hadUnderrun = true;                else                    aggregateStatus = pFrames[pITD->frameNum + i].frStatus;            }        }    }        // call callback    //    if (pITD->completion.action)    {        IOUSBIsocCompletionAction pHandler;               // If we had an error in any of the frames, then report that error as the status for this framelist        //        if ( (status == kIOReturnSuccess) && ( (aggregateStatus != kIOReturnSuccess) || hadUnderrun) )        {            // If we don't have an aggregateStatus but we did have an underrun, then report the underrun            //            if ( (aggregateStatus == kIOReturnSuccess) && hadUnderrun )                aggregateStatus = kIOReturnUnderrun;                            USBLog(6, "%s[%p]::ProcessCompletedITD: Changing isoc completion error from success to 0x%x", getName(), this, aggregateStatus);                        status = aggregateStatus;        }                // Zero out handler first than call it        //        // USBLog(7,"%s[%p]::ProcessCompletedITD: calling completion", getName(), this, pITD);                pHandler = pITD->completion.action;        pITD->completion.action = NULL;       (*pHandler) (pITD->completion.target,  pITD->completion.parameter, status, pFrames);    }}void AppleUSBOHCI::UIMProcessDoneQueue(IOUSBCompletionAction safeAction){    UInt32				interruptStatus;    IOPhysicalAddress			PhysAddr;    AppleOHCIGeneralTransferDescriptorPtr 	pHCDoneTD;    UInt32				cachedProducer;    IOPhysicalAddress			cachedWriteDoneQueueHead;    IOInterruptState			intState;        // Get the values of the Done Queue Head and the producer count.  We use a lock and disable interrupts    // so that the filter routine does not preempt us and updates the values while we're trying to read them.    //    intState = IOSimpleLockLockDisableInterrupt( _wdhLock );        cachedWriteDoneQueueHead = _savedDoneQueueHead;    cachedProducer = _producerCount;        IOSimpleLockUnlockEnableInterrupt( _wdhLock, intState );        // OK, now that we have a valid queue head in cachedWriteDoneQueueHead, let's process the list    //    DoDoneQueueProcessing( cachedWriteDoneQueueHead, cachedProducer, safeAction);    return;}IOReturnAppleUSBOHCI::DoDoneQueueProcessing(IOPhysicalAddress cachedWriteDoneQueueHead, UInt32 cachedProducer, IOUSBCompletionAction safeAction){    UInt32					control, transferStatus;    long					bufferSizeRemaining;    AppleOHCIGeneralTransferDescriptorPtr	pHCDoneTD, prevTD, nextTD;    IOPhysicalAddress				physicalAddress;    UInt32					pageMask;    AppleOHCIEndpointDescriptorPtr		tempED;    AppleOHCIIsochTransferDescriptorPtr		pITD, testITD;    volatile UInt32				cachedConsumer;    UInt32					numTDs = 0;    // This should never happen    //    if (cachedWriteDoneQueueHead == NULL)        return kIOReturnSuccess;    // Cache our consumer count    //    cachedConsumer = _consumerCount;        // If for some reason our cachedConsumer and cachedProducer are the same, then we need to bail out, as we    // don't have anything to process    //    if ( cachedConsumer == cachedProducer)    {        USBLog(3, "%s[%p]::DoDoneQueueProcessing  consumer (%d) == producer (%d) Filter count: %d", getName(), this, cachedConsumer, cachedProducer, _filterInterruptCount);        return kIOReturnSuccess;    }        // Get the logical address for our cachedQueueHead    //    pHCDoneTD = AppleUSBOHCIgtdMemoryBlock::GetGTDFromPhysical(cachedWriteDoneQueueHead);    	if ( pHCDoneTD == NULL )		return kIOReturnSuccess;		    // Now, reverse the queue.  We know how many TD's to process, not by the last one pointing to NULL,    // but by the fact that cachedConsumer != cachedProducer.  So, go through the loop and increment consumer    // until they are equal, taking care or the wraparound case.    //    prevTD = NULL;    while ( true )    {        pHCDoneTD->pLogicalNext = prevTD;        prevTD = pHCDoneTD;        numTDs++;                // Increment our consumer count.  If we wrap around, then increment again.  If we reach        // the end (both counts are equal, then brake out of the loop        //         cachedConsumer++;                   if ( cachedProducer == cachedConsumer)            break;            physicalAddress = USBToHostLong(pHCDoneTD->pShared->nextTD) & kOHCIHeadPMask;        nextTD = AppleUSBOHCIgtdMemoryBlock::GetGTDFromPhysical(physicalAddress);        if ( nextTD == NULL )        {            USBLog(5, "%s[%p]::DoDoneQueueProcessing nextTD = NULL.  (%p, %d, %d, %d)", getName(), this, physicalAddress, _filterInterruptCount, cachedProducer, cachedConsumer);            break;        }                pHCDoneTD = nextTD;                }    // New done queue head    //    pHCDoneTD = prevTD;        // Update our consumer count    //    _consumerCount = cachedConsumer;        // Now, we have a new done queue head.  Now process this reversed list in LOGICAL order.  That    // means that we can look for a NULL termination    //    while (pHCDoneTD != NULL)    {        // USBLog(6, "%s[%p]::DoDoneQueueProcessing", getName(), this); // print_td(pHCDoneTD);        IOReturn errStatus;                // find the next one        nextTD	= pHCDoneTD->pLogicalNext;        control = USBToHostLong(pHCDoneTD->pShared->ohciFlags);        transferStatus = (control & kOHCIGTDControl_CC) >> kOHCIGTDControl_CCPhase;        errStatus = TranslateStatusToUSBError(transferStatus);        if (_OptiOn && (pHCDoneTD->pType == kOHCIOptiLSBug))        {            // clear any bad errors            tempED = (AppleOHCIEndpointDescriptorPtr) pHCDoneTD->pEndpoint;            pHCDoneTD->pShared->ohciFlags = pHCDoneTD->pShared->ohciFlags & HostToUSBLong(kOHCIGTDClearErrorMask);            tempED->pShared->tdQueueHeadPtr &=  HostToUSBLong(kOHCIHeadPMask);            pHCDoneTD->pShared->nextTD = tempED->pShared->tdQueueTailPtr & HostToUSBLong(kOHCIHeadPMask);            tempED->pShared->tdQueueTailPtr = HostToUSBLong(pHCDoneTD->pPhysical);            _pOHCIRegisters->hcCommandStatus = HostToUSBLong (kOHCIHcCommandStatus_CLF);            // For CMD Buffer Underrun Errata        }        else if ((transferStatus == kOHCIGTDConditionBufferUnderrun) &&                 (pHCDoneTD->pType == kOHCIBulkTransferOutType) &&                 (_errataBits & kErrataRetryBufferUnderruns))        {            tempED = (AppleOHCIEndpointDescriptorPtr) pHCDoneTD->pEndpoint;            pHCDoneTD->pShared->ohciFlags = pHCDoneTD->pShared->ohciFlags & HostToUSBLong(kOHCIGTDClearErrorMask);            pHCDoneTD->pShared->nextTD = tempED->pShared->tdQueueHeadPtr & HostToUSBLong(kOHCIHeadPMask);            pHCDoneTD->pLogicalNext = AppleUSBOHCIgtdMemoryBlock::GetGTDFromPhysical(USBToHostLong(tempED->pShared->tdQueueHeadPtr) & kOHCIHeadPMask);            tempED->pShared->tdQueueHeadPtr = USBToHostLong(pHCDoneTD->pPhysical) | (tempED->pShared->tdQueueHeadPtr & HostToUSBLong( kOHCIEDToggleBitMask));            _pOHCIRegisters->hcCommandStatus = HostToUSBLong(kOHCIHcCommandStatus_BLF);        }        else if ( (pHCDoneTD->pType == kOHCIIsochronousInType) || (pHCDoneTD->pType == kOHCIIsochronousOutType) || (pHCDoneTD->pType == kOHCIIsochronousInLowLatencyType) || (pHCDoneTD->pType == kOHCIIsochronousOutLowLatencyType) )        {            // cast to a isoc type            pITD = (AppleOHCIIsochTransferDescriptorPtr) pHCDoneTD;            ProcessCompletedITD(pITD, errStatus);            // deallocate td            DeallocateITD(pITD);        }        else        {            bufferSizeRemaining = findBufferRemaining (pHCDoneTD);            // if (pHCDoneTD->completion.action != NULL)            if (pHCDoneTD->uimFlags & kUIMFlagsCallbackTD)            {                IOUSBCompletion completion = pHCDoneTD->command->GetUSLCompletion();                if(!safeAction || (safeAction == completion.action)) 		{                    // remove flag before completing                    pHCDoneTD->uimFlags &= ~kUIMFlagsCallbackTD;                    Complete(completion, errStatus, bufferSizeRemaining);                    DeallocateTD(pHCDoneTD);                }                else {                    if(_pendingHead)                        _pendingTail->pLogicalNext = pHCDoneTD;                    else                        _pendingHead = pHCDoneTD;                    _pendingTail = pHCDoneTD;                }            }            else	    {		if (errStatus != kIOReturnSuccess)                {                    USBLog(5, "AppleUSBOHCI::DoDoneQueueProcessing - processing a short packet");                    doCallback(pHCDoneTD, transferStatus, bufferSizeRemaining);                }                DeallocateTD(pHCDoneTD);            }        }        pHCDoneTD = nextTD;	/* New qHead */    }    return(kIOReturnSuccess);}void AppleUSBOHCI::finishPending(){    while(_pendingHead)     {        AppleOHCIGeneralTransferDescriptorPtr next = _pendingHead->pLogicalNext;        long bufferSizeRemaining = findBufferRemaining (_pendingHead);        UInt32 transferStatus = (USBToHostLong(_pendingHead->pShared->ohciFlags) & kOHCIGTDControl_CC) >> kOHCIGTDControl_CCPhase;	if (_pendingHead->uimFlags & kUIMFlagsCallbackTD)	{	    IOUSBCompletion completion = _pendingHead->command->GetUSLCompletion();	    _pendingHead->uimFlags &= ~kUIMFlagsCallbackTD;	    Complete(completion, TranslateStatusToUSBError(transferStatus), bufferSizeRemaining);	}        DeallocateTD(_pendingHead);        _pendingHead = next;    }}UInt32 AppleUSBOHCI::GetBandwidthAvailable(){    return _isochBandwidthAvail;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -