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

📄 cpipe.cpp

📁 嵌入式操作系统WINCE5.0下的USB驱动程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        }
        ASSERT(m_pArrayOfCSITD);
        ASSERT(m_dwNumOfTDAvailable == NUM_OF_PRE_ALLOCATED_TD);
        
        m_EndptBuget.period = (1<< ( bInterval-1));
    }
    m_EndptBuget.ep_type = isoch ;
    m_EndptBuget.type= lpEndpointDescriptor->bDescriptorType;
    m_EndptBuget.direction =(USB_ENDPOINT_DIRECTION_OUT(lpEndpointDescriptor->bEndpointAddress)?OUTDIR:INDIR);
    m_EndptBuget.speed=(fIsHighSpeed?HSSPEED:(fIsLowSpeed?LSSPEED:FSSPEED));

    m_bSuccess=pCEhcd->AllocUsb2BusTime(bHubAddress,bHubPort,&m_EndptBuget);
    ASSERT(m_bSuccess);
    if (m_bSuccess ) {
        
        if (fIsHighSpeed) { // Update SMask and CMask for Slit Interrupt Endpoitt
            m_bFrameSMask=pCEhcd->GetSMASK(&m_EndptBuget);
            m_bFrameCMask=0;
        }
        else {
            m_bFrameSMask=pCEhcd->GetSMASK(&m_EndptBuget);
            m_bFrameCMask=pCEhcd->GetCMASK(&m_EndptBuget);
        }
    }
    else {
        ASSERT(FALSE);
    }
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CIsochronousPipe::CIsochronousPipe\n")) );
}

// ******************************************************************               
// Scope: public
CIsochronousPipe::~CIsochronousPipe( )
//
// Purpose: Destructor for CIsochronousPipe
//
// Parameters: None
//
// Returns: Nothing
//
// Notes: Do not modify static variables here!!
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CIsochronousPipe::~CIsochronousPipe\n")) );
    // m_pWakeupTD should have been freed by the time we get here
    if (m_bSuccess)
        m_pCEhcd->FreeUsb2BusTime( m_bHubAddress, m_bHubPort,&m_EndptBuget);
    ClosePipe();
    if (m_pArrayOfCITD) {
        for (m_dwNumOfTDAvailable=0;m_dwNumOfTDAvailable<NUM_OF_PRE_ALLOCATED_TD;m_dwNumOfTDAvailable++) {
            if ( *(m_pArrayOfCITD + m_dwNumOfTDAvailable) !=NULL) {
                 (*(m_pArrayOfCITD + m_dwNumOfTDAvailable))->~CITD();
                 m_pCEhcd->GetPhysMem()->FreeMemory((PBYTE)*(m_pArrayOfCITD + m_dwNumOfTDAvailable),
                    m_pCEhcd->GetPhysMem()->VaToPa((PBYTE)*(m_pArrayOfCITD + m_dwNumOfTDAvailable)),
                    CPHYSMEM_FLAG_HIGHPRIORITY |CPHYSMEM_FLAG_NOBLOCK );                                
            }
        }
        delete (m_pArrayOfCITD);
    }
    if (m_pArrayOfCSITD) {
        for (m_dwNumOfTDAvailable=0;m_dwNumOfTDAvailable<NUM_OF_PRE_ALLOCATED_TD;m_dwNumOfTDAvailable++) {
            if ( *(m_pArrayOfCSITD + m_dwNumOfTDAvailable) != NULL) {
                 (*(m_pArrayOfCSITD + m_dwNumOfTDAvailable))->~CSITD();
                 m_pCEhcd->GetPhysMem()->FreeMemory((PBYTE)*(m_pArrayOfCSITD + m_dwNumOfTDAvailable),
                    m_pCEhcd->GetPhysMem()->VaToPa((PBYTE)*(m_pArrayOfCSITD + m_dwNumOfTDAvailable)),
                    CPHYSMEM_FLAG_HIGHPRIORITY |CPHYSMEM_FLAG_NOBLOCK );                                
            }
        }
        delete (m_pArrayOfCSITD);
    }
    
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CIsochronousPipe::~CIsochronousPipe\n")) );
}

CITD *  CIsochronousPipe::AllocateCITD( CITransfer *  pTransfer)
{
    EnterCriticalSection( &m_csPipeLock );
    ASSERT(m_pArrayOfCITD!=NULL) ;
    CITD * pReturn = NULL;
    if (m_pArrayOfCITD!=NULL ) {
        ASSERT(m_dwNumOfTDAvailable <= NUM_OF_PRE_ALLOCATED_TD);
        for (DWORD dwIndex=m_dwNumOfTDAvailable;dwIndex!=0;dwIndex--) {
            if ((pReturn = *(m_pArrayOfCITD + dwIndex -1))!=NULL) {
                m_dwNumOfTDAvailable = dwIndex-1;
                *(m_pArrayOfCITD + m_dwNumOfTDAvailable) = NULL;
                pReturn->ReInit(pTransfer);
                break;
            }
        }
    }
    LeaveCriticalSection( &m_csPipeLock );
    DEBUGMSG( ZONE_WARNING && (pReturn==NULL) , (TEXT("CIsochronousPipe::AllocateCITD: return NULL, run out of pre-allocated ITD\r\n")) );
    return pReturn;
}
CSITD * CIsochronousPipe::AllocateCSITD( CSITransfer * pTransfer,CSITD * pPrev)
{
    EnterCriticalSection( &m_csPipeLock );
    ASSERT(m_pArrayOfCSITD!=NULL) ;
    CSITD * pReturn = NULL;
    if (m_pArrayOfCSITD!=NULL ) {
        ASSERT(m_dwNumOfTDAvailable <= NUM_OF_PRE_ALLOCATED_TD);
        for (DWORD dwIndex=m_dwNumOfTDAvailable;dwIndex!=0;dwIndex--) {
            if ((pReturn = *(m_pArrayOfCSITD + dwIndex -1))!=NULL) {
                m_dwNumOfTDAvailable = dwIndex -1;
                *(m_pArrayOfCSITD + m_dwNumOfTDAvailable) = NULL;
                pReturn->ReInit(pTransfer,pPrev);
                break;
            }
        }
    }
    LeaveCriticalSection( &m_csPipeLock );
    DEBUGMSG( ZONE_WARNING && (pReturn==NULL) , (TEXT("CIsochronousPipe::AllocateCSITD: return NULL, run out of pre-allocated CITD\r\n")) );
    return pReturn;

}
void    CIsochronousPipe::FreeCITD(CITD *  pITD)
{
    EnterCriticalSection( &m_csPipeLock );
    ASSERT(m_pArrayOfCITD!=NULL);
    ASSERT(m_dwNumOfTDAvailable< NUM_OF_PRE_ALLOCATED_TD);
    if (m_pArrayOfCITD && pITD && m_dwNumOfTDAvailable< NUM_OF_PRE_ALLOCATED_TD) {
        ASSERT(*(m_pArrayOfCITD+m_dwNumOfTDAvailable)==NULL);
        pITD->~CITD();
        *(m_pArrayOfCITD+m_dwNumOfTDAvailable)= pITD;
        m_dwNumOfTDAvailable ++;
    }
    LeaveCriticalSection( &m_csPipeLock );
}
void    CIsochronousPipe::FreeCSITD(CSITD * pSITD)
{
    EnterCriticalSection( &m_csPipeLock );
    ASSERT(m_pArrayOfCSITD );
    ASSERT(m_dwNumOfTDAvailable< NUM_OF_PRE_ALLOCATED_TD);
    if (m_pArrayOfCSITD && pSITD && m_dwNumOfTDAvailable< NUM_OF_PRE_ALLOCATED_TD ) {
        ASSERT(*(m_pArrayOfCSITD+m_dwNumOfTDAvailable)==NULL);
        pSITD->~CSITD();
        *(m_pArrayOfCSITD+m_dwNumOfTDAvailable)= pSITD;
        m_dwNumOfTDAvailable ++;
    }
    LeaveCriticalSection( &m_csPipeLock );
}

// ******************************************************************               
// Scope: public (Implements CPipe::OpenPipe = 0)
HCD_REQUEST_STATUS CIsochronousPipe::OpenPipe( void )
//
// Purpose: Inserting the necessary (empty) items into the
//          schedule to permit future transfers
//
// Parameters: None
//
// Returns: requestOK if pipe opened successfuly
//          requestFailed if pipe not opened
//
// Notes: 
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE, (TEXT("+CIsochronousPipe::OpenPipe\n")) );

    HCD_REQUEST_STATUS status = requestFailed;
    m_pQueuedTransfer=NULL;

    EnterCriticalSection( &m_csPipeLock );

    DEBUGCHK( m_usbEndpointDescriptor.bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE &&
              m_usbEndpointDescriptor.bLength >= sizeof( USB_ENDPOINT_DESCRIPTOR ) &&
              (m_usbEndpointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_ISOCHRONOUS );

    m_dwLastValidFrame = 0;
    m_pCEhcd->GetFrameNumber(&m_dwLastValidFrame);
    
    // if this fails, someone is trying to open an already opened pipe
    if ( m_pQueuedTransfer == NULL && m_bSuccess == TRUE) {
        status = requestOK;
    }
    else
        ASSERT(FALSE);
    LeaveCriticalSection( &m_csPipeLock );
    if (status == requestOK ) {
        BOOL bReturn = m_pCEhcd->AddToBusyPipeList(this, TRUE);
        ASSERT(bReturn == TRUE);
    }
    DEBUGMSG( ZONE_PIPE, (TEXT("-CIsochronousPipe::OpenPipe, returning HCD_REQUEST_STATUS %d\n"), status ) );
    return status;
}
// ******************************************************************               
// Scope: public (Implements CPipe::ClosePipe = 0)
HCD_REQUEST_STATUS CIsochronousPipe::ClosePipe( void )
//
// Purpose: Abort any transfers associated with this pipe, and
//          remove its data structures from the schedule
//
// Parameters: None
//
// Returns: requestOK
//
// Notes: 
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE, (TEXT("+CIsochronousPipe::ClosePipe\n")) );

    m_pCEhcd->RemoveFromBusyPipeList( this );
    EnterCriticalSection( &m_csPipeLock );
    CIsochTransfer *  pCurTransfer = m_pQueuedTransfer;
    m_pQueuedTransfer = NULL;
    while ( pCurTransfer ) {
         pCurTransfer->AbortTransfer();
         CIsochTransfer *  pNext = (CIsochTransfer *)pCurTransfer ->GetNextTransfer();
         delete pCurTransfer;
         pCurTransfer = pNext;
    }
    LeaveCriticalSection( &m_csPipeLock );

    DEBUGMSG( ZONE_PIPE, (TEXT("-CIsochronousPipe::ClosePipe\n")) );
    return requestOK;
}
// ******************************************************************               
// Scope: public (Implements CPipe::AbortTransfer = 0)
HCD_REQUEST_STATUS CIsochronousPipe::AbortTransfer( 
                                    IN const LPTRANSFER_NOTIFY_ROUTINE lpCancelAddress,
                                    IN const LPVOID lpvNotifyParameter,
                                    IN LPCVOID lpvCancelId )
//
// Purpose: Abort any transfer on this pipe if its cancel ID matches
//          that which is passed in.
//
// Parameters: lpCancelAddress - routine to callback after aborting transfer
//
//             lpvNotifyParameter - parameter for lpCancelAddress callback
//
//             lpvCancelId - identifier for transfer to abort
//
// Returns: requestOK if transfer aborted
//          requestFailed if lpvCancelId doesn't match currently executing
//                 transfer, or if there is no transfer in progress
//
// Notes:
// ******************************************************************
{
    DEBUGMSG( ZONE_TRANSFER, (TEXT("+CIsochronousPipe::AbortTransfer\n")));

    HCD_REQUEST_STATUS status = requestFailed;

    EnterCriticalSection( &m_csPipeLock );
    // Find this transfer.
    if (m_pQueuedTransfer!=NULL) {
        CIsochTransfer *  pCur=m_pQueuedTransfer;
        CIsochTransfer *  pPrev=NULL;
        while (pCur!=NULL && (pCur ->GetSTransfer()).lpvCancelId != lpvCancelId) {
            pPrev = pCur;
            pCur =(CIsochTransfer *  )pCur ->GetNextTransfer();
        };
        if (pCur!=NULL) { // We found it
            if (pPrev!=NULL) 
                pPrev->SetNextTransfer(pCur->GetNextTransfer());
            else // It is Locate at header
                m_pQueuedTransfer = (CIsochTransfer * )m_pQueuedTransfer->GetNextTransfer();
            pCur->AbortTransfer();
            // Do not need call DoneTransfer here because AboutTransfer Called DoneTransfer already.
            delete pCur;  
            if ( lpCancelAddress ) {
                __try { // calling the Cancel function
                    ( *lpCancelAddress )( lpvNotifyParameter );
                } __except( EXCEPTION_EXECUTE_HANDLER ) {
                      DEBUGMSG( ZONE_ERROR, (TEXT("CIsochronousPipe::AbortTransfer - exception executing cancellation callback function\n")) );
                }
            }
            status=requestOK;
        }
    }
    LeaveCriticalSection( &m_csPipeLock );
    return status;
}
// ******************************************************************               
// Scope: public 
HCD_REQUEST_STATUS  CIsochronousPipe::IssueTransfer( 
                                    IN const UCHAR address,
                                    IN LPTRANSFER_NOTIFY_ROUTINE const lpStartAddress,
                                    IN LPVOID const lpvNotifyParameter,
                                    IN const DWORD dwFlags,
                                    IN LPCVOID const lpvControlHeader,
                                    IN const DWORD dwStartingFrame,
                                    IN const DWORD dwFrames,
                                    IN LPCDWORD const aLengths,
                                    IN const DWORD dwBufferSize,     
                                    IN_OUT LPVOID const lpvClientBuffer,
                                    IN const ULONG paBuffer,
                                    IN LPCVOID const lpvCancelId,
                                    OUT LPDWORD const adwIsochErrors,
                                    OUT LPDWORD const adwIsochLengths,
                                    OUT LPBOOL const lpfComplete,
                                    OUT LPDWORD const lpdwBytesTransferred,
                                    OUT LPDWORD const lpdwError )
//
// Purpose: Issue a Transfer on this pipe
//
// Parameters: address - USB address to send transfer to
//
//             OTHER PARAMS - see comment in CUhcd::IssueTransfer
//
// Returns: requestOK if transfer issued ok, else requestFailed
//
// Notes:   
// ******************************************************************
{
    DEBUGMSG( ZONE_TRANSFER, (TEXT("+CPipe(%s)::IssueTransfer, address = %d\n"), GetPipeType(), address) );
    
    DWORD dwEarliestFrame=0;
    m_pCEhcd->GetFrameNumber(&dwEarliestFrame);
    dwEarliestFrame = max(m_dwLastValidFrame,dwEarliestFrame+MIN_ADVANCED_FRAME);
    DWORD

⌨️ 快捷键说明

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