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

📄 cpipe.cpp

📁 嵌入式操作系统WINCE5.0下的USB驱动程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    HCD_REQUEST_STATUS status = requestFailed;
    m_pCEhcd->RemoveFromBusyPipeList(this );
    EnterCriticalSection( &m_csPipeLock );
    if ( m_pPipeQHead) {
        AbortQueue();
        m_pCEhcd->AsyncDequeueQH( m_pPipeQHead );
        DWORD dwPhysMem = m_pPipeQHead->GetPhysAddr();
        m_pPipeQHead->~CQH();
        m_pCEhcd->GetPhysMem()->FreeMemory((PBYTE)m_pPipeQHead, dwPhysMem , CPHYSMEM_FLAG_HIGHPRIORITY |CPHYSMEM_FLAG_NOBLOCK);
        m_pPipeQHead = NULL;
        status = requestOK;
    }
    LeaveCriticalSection( &m_csPipeLock );
    return status;
}
// ******************************************************************               
// Scope: private (Implements CPipe::AreTransferParametersValid = 0)
BOOL CBulkPipe::AreTransferParametersValid( const STransfer *pTransfer ) const 
//
// Purpose: Check whether this class' transfer parameters are valid.
//          This includes checking m_transfer, m_pPipeQH, etc
//
// Parameters: None (all parameters are vars of class)
//
// Returns: TRUE if parameters valid, else FALSE
//
// Notes: Assumes m_csPipeLock already held
// ******************************************************************
{
    if (pTransfer == NULL) {
        ASSERT(FALSE);
        return FALSE;
    }
        
    
    //DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("+CBulkPipe::AreTransferParametersValid\n")) );

    // these parameters aren't used by CBulkPipe, so if they are non NULL,
    // it doesn't present a serious problem. But, they shouldn't have been
    // passed in as non-NULL by the calling driver.
    DEBUGCHK( pTransfer->adwIsochErrors == NULL && // ISOCH
              pTransfer->adwIsochLengths == NULL && // ISOCH
              pTransfer->aLengths == NULL && // ISOCH
              pTransfer->lpvControlHeader == NULL ); // CONTROL
    // this is also not a serious problem, but shouldn't happen in normal
    // circumstances. It would indicate a logic error in the calling driver.
    DEBUGCHK( !(pTransfer->lpStartAddress == NULL && pTransfer->lpvNotifyParameter != NULL) );
    // DWORD                     pTransfer->dwStartingFrame (ignored - ISOCH)
    // DWORD                     pTransfer->dwFrames (ignored - ISOCH)

    BOOL fValid = ( m_pPipeQHead!=NULL &&
                    (pTransfer->lpvBuffer != NULL || pTransfer->dwBufferSize == 0) &&
                    // paClientBuffer could be 0 or !0
                    m_bDeviceAddress > 0 && m_bDeviceAddress <= USB_MAX_ADDRESS &&
                    pTransfer->lpfComplete != NULL &&
                    pTransfer->lpdwBytesTransferred != NULL &&
                    pTransfer->lpdwError != NULL );

    DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE && !fValid, (TEXT("!CBulkPipe::AreTransferParametersValid, returning BOOL %d\n"), fValid) );
    ASSERT(fValid);
    return fValid;
}

// ******************************************************************               
// Scope: public
CControlPipe::CControlPipe( 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 CControlPipe
//
// 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("+CControlPipe::CControlPipe\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_CONTROL );

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

// ******************************************************************               
// Scope: public
CControlPipe::~CControlPipe( )
//
// Purpose: Destructor for CControlPipe
//
// Parameters: None
//
// Returns: Nothing
//
// Notes: Do not modify static variables here!!
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CControlPipe::~CControlPipe\n")) );
    ClosePipe();
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CControlPipe::~CControlPipe\n")) );
}

// ******************************************************************               
// Scope: public (Implements CPipe::OpenPipe = 0)
HCD_REQUEST_STATUS CControlPipe::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("+CControlPipe::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)
    if (m_pPipeQHead == NULL ) {
        m_pPipeQHead = new( m_pCEhcd->GetPhysMem()) CQH (this);
        if (m_pPipeQHead ) {
            m_pPipeQHead->SetDTC(TRUE); // Self Data Toggle for Control 
            if (!m_fIsHighSpeed)
                m_pPipeQHead->SetControlEnpt(TRUE) ; 
            if (m_pCEhcd->AsyncQueueQH( m_pPipeQHead ) ) {
                status = requestOK;
            }
            else {
                delete m_pPipeQHead;
                m_pPipeQHead=NULL;
                ASSERT(FALSE);
            }
                
        }
        else {
            ASSERT(FALSE);
        }
    }
    LeaveCriticalSection( &m_csPipeLock );

    if (status == requestOK) {
        BOOL bReturn = m_pCEhcd->AddToBusyPipeList(this, FALSE);
        ASSERT(bReturn == TRUE);
    }
    DEBUGMSG( ZONE_PIPE, (TEXT("-CControlPipe::OpenPipe\n") ) );
    return status;
}
// ******************************************************************               
// Scope: public (Implements CPipe::ClosePipe = 0)
HCD_REQUEST_STATUS CControlPipe::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() ) );
    HCD_REQUEST_STATUS status = requestFailed;
    m_pCEhcd->RemoveFromBusyPipeList(this );
    EnterCriticalSection( &m_csPipeLock );
    if ( m_pPipeQHead) {
        AbortQueue();
        m_pCEhcd->AsyncDequeueQH( m_pPipeQHead );
        //delete m_pPipeQHead;
        DWORD dwPhysMem = m_pPipeQHead->GetPhysAddr();
        m_pPipeQHead->~CQH();
        m_pCEhcd->GetPhysMem()->FreeMemory((PBYTE)m_pPipeQHead, dwPhysMem ,CPHYSMEM_FLAG_HIGHPRIORITY | CPHYSMEM_FLAG_NOBLOCK);        
        m_pPipeQHead = NULL;
        status = requestOK;
    }
    LeaveCriticalSection( &m_csPipeLock );
    return status;
}
BOOL CControlPipe::RemoveQHeadFromQueue() 
{
    ASSERT(m_pPipeQHead);
    return( m_pCEhcd->AsyncDequeueQH( m_pPipeQHead )!=NULL);
}
BOOL CControlPipe::InsertQHeadToQueue() 
{
    ASSERT(m_pPipeQHead);
    return (m_pCEhcd->AsyncQueueQH( m_pPipeQHead )!=NULL);
}
// ******************************************************************               
// Scope: public 
HCD_REQUEST_STATUS  CControlPipe::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("+CControlPipe::IssueTransfer, address = %d\n"), address) );
    if (m_bDeviceAddress ==0 && address !=0) { // Address Changed.
        if ( m_pQueuedTransfer == NULL &&  m_pPipeQHead && m_pPipeQHead->IsActive()==FALSE) { // We need cqueue new Transfer.
            m_bDeviceAddress = address;
            m_pPipeQHead ->SetDeviceAddress(m_bDeviceAddress);
        }
        else {
            ASSERT(FALSE);
            return requestFailed;
        }
    }
    HCD_REQUEST_STATUS status = CQueuedPipe::IssueTransfer( address, lpStartAddress,lpvNotifyParameter,
            dwFlags,lpvControlHeader, dwStartingFrame, dwFrames, aLengths, dwBufferSize, lpvClientBuffer,
            paBuffer, lpvCancelId, adwIsochErrors, adwIsochLengths, lpfComplete, lpdwBytesTransferred, lpdwError );
    DEBUGMSG( ZONE_TRANSFER, (TEXT("-CControlPipe::::IssueTransfer - address = %d, returing HCD_REQUEST_STATUS %d\n"), address, status) );
    return status;
};
// ******************************************************************
// Scope: public
void CControlPipe::ChangeMaxPacketSize( IN const USHORT wMaxPacketSize )
//
// Purpose: Update the max packet size for this pipe. This should
//          ONLY be done for control endpoint 0 pipes. When the endpoint0
//          pipe is first opened, it has a max packet size of 
//          ENDPOINT_ZERO_MIN_MAXPACKET_SIZE. After reading the device's
//          descriptor, the device attach procedure can update the size.
//
// Parameters: wMaxPacketSize - new max packet size for this pipe
//
// Returns: Nothing
//
// Notes:   This function should only be called by the Hub AttachDevice
//          procedure
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CControlPipe::ChangeMaxPacketSize - new wMaxPacketSize = %d\n"), wMaxPacketSize) );

    EnterCriticalSection( &m_csPipeLock );

    // this pipe should be for endpoint 0, control pipe
    DEBUGCHK( (m_usbEndpointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_CONTROL &&
              (m_usbEndpointDescriptor.bEndpointAddress & TD_ENDPOINT_MASK) == 0 );
    // update should only be called if the old address was ENDPOINT_ZERO_MIN_MAXPACKET_SIZE
    DEBUGCHK( m_usbEndpointDescriptor.wMaxPacketSize == ENDPOINT_ZERO_MIN_MAXPACKET_SIZE );
    // this function should only be called if we are increasing the max packet size.
    // in addition, the USB spec 1.0 section 9.6.1 states only the following
    // wMaxPacketSize are allowed for endpoint 0
    DEBUGCHK( wMaxPacketSize > ENDPOINT_ZERO_MIN_MAXPACKET_SIZE &&
              (wMaxPacketSize == 16 ||
               wMaxPacketSize == 32 ||
               wMaxPacketSize == 64) );
    
    m_usbEndpointDescriptor.wMaxPacketSize = wMaxPacketSize;
    if ( m_pQueuedTransfer == NULL &&  m_pPipeQHead && m_pPipeQHead->IsActive()==FALSE) { // We need cqueue new Transfer.
        m_pPipeQHead ->SetMaxPacketLength(wMaxPacketSize);
    }
    else {
        ASSERT(FALSE);
    } 

    LeaveCriticalSection( &m_csPipeLock );

    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CControlPipe::ChangeMaxPacketSize - new wMaxPacketSize = %d\n"), wMaxPacketSize) );
}
// ******************************************************************               
// Scope: private (Implements CPipe::AreTransferParametersValid = 0)
BOOL CControlPipe::AreTransferParametersValid( const STransfer *pTransfer ) const 
//
// Purpose: Check whether this class' transfer parameters are valid.
//          This includes checking m_transfer, m_pPipeQH, etc
//
// Parameters: None (all parameters are vars of class)
//
// Returns: TRUE if parameters valid, else FALSE
//
// Notes: Assumes m_csPipeLock already held
// ******************************************************************

⌨️ 快捷键说明

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