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

📄 cpipe.cpp

📁 嵌入式操作系统WINCE5.0下的USB驱动程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Notes: not used for OHCI
// ******************************************************************
{
    DEBUGMSG( ZONE_TRANSFER, (TEXT("+CQueuedPipe(%s)::AbortQueue \n"), GetPipeType()) );
    EnterCriticalSection( &m_csPipeLock );
    if ( m_pUnQueuedTransfer) {      // ptr to last transfer in queue
        while ( m_pUnQueuedTransfer) {
            m_pUnQueuedTransfer ->AbortTransfer();
            m_pUnQueuedTransfer ->DoneTransfer();
            CQTransfer * pCurTransfer= (CQTransfer *) m_pUnQueuedTransfer->GetNextTransfer();
            delete m_pUnQueuedTransfer;
            m_pUnQueuedTransfer = pCurTransfer;
        }       
    }
    ASSERT( m_pUnQueuedTransfer == NULL);
    if (m_pQueuedTransfer) {
        RemoveQHeadFromQueue();
        m_pQueuedTransfer;
        m_pQueuedTransfer ->AbortTransfer();
        GetQHead()->InvalidNextTD();  
        m_pCEhcd->AsyncBell();// Ask HC update internal structure.
        Sleep(2);// this sleep is for Interrupt Pipe;
        m_pQueuedTransfer->DoneTransfer();
        m_pQueuedTransfer =  NULL;
        delete m_pQueuedTransfer;
        m_pQueuedTransfer = NULL;
        InsertQHeadToQueue() ;
    }
    ASSERT(m_pQueuedTransfer == NULL);

    LeaveCriticalSection( &m_csPipeLock );
    DEBUGMSG( ZONE_TRANSFER, (TEXT("-CQueuedPipe(%s)::AbortQueue - %d\n"), GetPipeType()) );
}

// ******************************************************************               
// Scope: public 
HCD_REQUEST_STATUS  CQueuedPipe::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) );

    STransfer sTransfer = {
    // These are the IssueTransfer parameters
        lpStartAddress,lpvNotifyParameter, dwFlags,lpvControlHeader, dwStartingFrame,dwFrames,
        aLengths,dwBufferSize,lpvClientBuffer,paBuffer,lpvCancelId,adwIsochErrors, adwIsochLengths,
        lpfComplete,lpdwBytesTransferred,lpdwError};
    HCD_REQUEST_STATUS  status = requestFailed;
    if (AreTransferParametersValid(&sTransfer) && GetQHead() && m_bDeviceAddress == address ) {
        EnterCriticalSection( &m_csPipeLock );
#pragma prefast(disable: 322, "Recover gracefully from hardware failure")
        __try { // initializing transfer status parameters
            *sTransfer.lpfComplete = FALSE;
            *sTransfer.lpdwBytesTransferred = 0;
            *sTransfer.lpdwError = USB_NOT_COMPLETE_ERROR;
            CQTransfer * pTransfer = new CQTransfer(this,m_pCEhcd->GetPhysMem(),sTransfer);
            if (pTransfer && pTransfer->Init()) {
                CQTransfer * pCur = m_pUnQueuedTransfer;
                if (pCur) {
                    while (pCur->GetNextTransfer()!=NULL)
                         pCur = (CQTransfer * )pCur->GetNextTransfer();
                    pCur->SetNextTransfer( pTransfer);
                }
                else
                    m_pUnQueuedTransfer=pTransfer;
                status=requestOK ;
            }
            else
                if (pTransfer) { // We return fails here so do not need callback;
                    pTransfer->DoNotCallBack() ;
                    delete pTransfer;    
                }
        } __except( EXCEPTION_EXECUTE_HANDLER ) {
        }
#pragma prefast(pop)
        LeaveCriticalSection( &m_csPipeLock );
        ScheduleTransfer( );
    }
    else
        ASSERT(FALSE);
    DEBUGMSG( ZONE_TRANSFER, (TEXT("-CPipe(%s)::IssueTransfer - address = %d, returing HCD_REQUEST_STATUS %d\n"), GetPipeType(), address, status) );
    return status;
}
// ******************************************************************               
// Scope: public 
HCD_REQUEST_STATUS   CQueuedPipe::ScheduleTransfer( void )
//
// Purpose: Schedule a Transfer on this pipe
//
// Returns: requestOK if transfer issued ok, else requestFailed
//
// Notes:   
// ******************************************************************
{
    HCD_REQUEST_STATUS  status = requestFailed;
    EnterCriticalSection( &m_csPipeLock );
    if ( m_pQueuedTransfer == NULL && m_pUnQueuedTransfer!=NULL  && 
            m_pPipeQHead && m_pPipeQHead->IsActive()==FALSE) { // We need cqueue new Transfer.
        CQTransfer * pCurTransfer = m_pUnQueuedTransfer;
        ASSERT(pCurTransfer!=NULL);
        m_pUnQueuedTransfer = (CQTransfer * )pCurTransfer->GetNextTransfer();
        pCurTransfer->SetNextTransfer(NULL);
        if (GetQHead()->QueueTD(pCurTransfer->GetCQTDList())==TRUE) {
            m_pQueuedTransfer = pCurTransfer;
            ASSERT(pCurTransfer->GetCQTDList()->GetTransfer()== pCurTransfer);
            status=requestOK ;
        }
        else {
            ASSERT(FALSE);
            // Can not Queue. 
            m_fIsHalted = TRUE;
            m_pQueuedTransfer = pCurTransfer;
            m_pQueuedTransfer ->AbortTransfer();
            CheckForDoneTransfers();
        }
    }
    else 
        DEBUGMSG( ZONE_TRANSFER, (TEXT("-CPipe(%s)::ScheduleTransfer - Schedule called during QHead Busy or nothing to schedule! \n"), GetPipeType()) );
    LeaveCriticalSection( &m_csPipeLock );
    return status;
}
// ******************************************************************               
// Scope: protected (Implements CPipe::CheckForDoneTransfers = 0)
BOOL CQueuedPipe::CheckForDoneTransfers( void )
//
// Purpose: Check if the transfer on this pipe is finished, and 
//          take the appropriate actions - i.e. remove the transfer
//          data structures and call any notify routines
//
// Parameters: None
//
// Returns: TRUE if transfer is done, else FALSE
//
// Notes:
// ******************************************************************
{
    BOOL bReturn = FALSE;
    EnterCriticalSection( &m_csPipeLock );
    
    if (m_pQueuedTransfer!=NULL && m_pPipeQHead!=NULL) {
        // Check All the transfer done or not.
        CQTransfer * pCurTransfer = m_pQueuedTransfer;
        if (pCurTransfer->IsTransferDone() == TRUE) {
            ASSERT(m_pPipeQHead->IsActive() == FALSE) ;// Pipe Stopped.
            m_fIsHalted = (pCurTransfer->DoneTransfer()!=TRUE);
            // Put it into done Queue.
            delete pCurTransfer;
            if (m_fIsHalted)
                m_pPipeQHead->ResetOverlayDataToggle();
            // Excute Next one if there is any.
            m_pQueuedTransfer =NULL;
            m_pPipeQHead->InvalidNextTD();
            bReturn = TRUE;
        }
    }
    if (m_pQueuedTransfer==NULL)
        ScheduleTransfer();
    LeaveCriticalSection( &m_csPipeLock );
    return bReturn;   
}

// ******************************************************************               
// Scope: public
CBulkPipe::CBulkPipe( IN const LPCUSB_ENDPOINT_DESCRIPTOR lpEndpointDescriptor,
                 IN const BOOL fIsLowSpeed,IN const BOOL fIsHighSpeed,
                 IN const UCHAR bDeviceAddress,
                 IN const UCHAR bHubAddress,IN const UCHAR bHubPort,
                 IN CEhcd *const pCEhcd)
//
// Purpose: Constructor for CBulkPipe
//
// Parameters: See CQueuedPipe::CQueuedPipe
//
// Returns: Nothing
//
// Notes: Do not modify static variables here!!
// ******************************************************************
: CQueuedPipe(lpEndpointDescriptor,fIsLowSpeed, fIsHighSpeed,bDeviceAddress, bHubAddress, bHubPort,  pCEhcd ) // constructor for base class
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CBulkPipe::CBulkPipe\n")) );
    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_BULK );

    DEBUGCHK( !fIsLowSpeed ); // bulk pipe must be high speed

    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CBulkPipe::CBulkPipe\n")) );
}

// ******************************************************************               
// Scope: public
CBulkPipe::~CBulkPipe( )
//
// Purpose: Destructor for CBulkPipe
//
// Parameters: None
//
// Returns: Nothing
//
// Notes: Do not modify static variables here!!
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CBulkPipe::~CBulkPipe\n")) );
    ClosePipe();
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CBulkPipe::~CBulkPipe\n")) );
}
BOOL CBulkPipe::RemoveQHeadFromQueue() 
{
    ASSERT(m_pPipeQHead);
    return (m_pCEhcd->AsyncDequeueQH( m_pPipeQHead )!=NULL);
}
BOOL CBulkPipe::InsertQHeadToQueue() 
{
    ASSERT(m_pPipeQHead);
    return (m_pCEhcd->AsyncQueueQH( m_pPipeQHead )!=NULL);
}
// ******************************************************************               
// Scope: public (Implements CPipe::OpenPipe = 0)
HCD_REQUEST_STATUS CBulkPipe::OpenPipe( void )
//
// Purpose: Create the data structures necessary to conduct
//          transfers on this pipe
//
// Parameters: None
//
// Returns: requestOK - if pipe opened
//
//          requestFailed - if pipe was not opened
//
// Notes: 
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE, (TEXT("+CBulkPipe::OpenPipe\n") ) );

    HCD_REQUEST_STATUS status = requestFailed;
    m_pUnQueuedTransfer=NULL;      // ptr to last transfer in queue
    m_pQueuedTransfer=NULL;
    PREFAST_DEBUGCHK( m_pCEhcd!=NULL );
    EnterCriticalSection( &m_csPipeLock );

    // if this fails, someone is trying to open
    // an already opened pipe
    DEBUGCHK( m_pPipeQHead  == NULL );
    ASSERT(m_pCEhcd !=NULL);
    // if this fails, we have a low speed Bulk device
    // which is not allowed by the UHCI spec (sec 1.3)
    DEBUGCHK( !m_fIsLowSpeed );
    if (m_pPipeQHead == NULL ) {
        m_pPipeQHead = new( m_pCEhcd->GetPhysMem()) CQH (this);
        if (m_pPipeQHead) {
            m_pPipeQHead->SetDTC(FALSE); // Auto Data Toggle for Bulk.
            if (m_pCEhcd->AsyncQueueQH( m_pPipeQHead )) {
                status = requestOK;
            }
            else {
                ASSERT(FALSE);
                delete m_pPipeQHead;
                m_pPipeQHead=NULL;
            }
        }
        else {
            ASSERT(FALSE);
        }
    }
    LeaveCriticalSection( &m_csPipeLock );
    ASSERT(m_pPipeQHead  != NULL);
    if (status == requestOK) {
        BOOL bReturn = m_pCEhcd->AddToBusyPipeList(this, FALSE);
        ASSERT(bReturn == TRUE);
    }
    DEBUGMSG( ZONE_PIPE, (TEXT("-CBulkPipe::OpenPipe, returning HCD_REQUEST_STATUS %d\n"), status) );
    return status;
}
// ******************************************************************               
// Scope: public (Implements CPipe::ClosePipe = 0)
HCD_REQUEST_STATUS CBulkPipe::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("+CBulkPipe(%s)::ClosePipe\n"), GetPipeType() ) );

⌨️ 快捷键说明

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