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

📄 cpipe.cpp

📁 Latest USB 802.3, HID printer and mass storage divers from Microsoft for Platform Builder 4.2.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//        The TD is not deleted or freed - it is just removed from the
//        schedule. The caller still needs to ensure that HW is not
//        accessing the TD before it can be freed.
// ******************************************************************
{

    DEBUGCHK( pTD != NULL &&
              pTD->Isochronous == 1 );
    DEBUGCHK( dwFrameIndex >= 0 &&
              dwFrameIndex < FRAME_LIST_LENGTH );
#ifdef DEBUG
{
    // first make sure that this TD is in the given frame
    DEBUGCHK( !(m_vaFrameList[ dwFrameIndex ] & FRAME_LIST_POINTER_QH) );
    P_TD pDebugTD = (P_TD) m_pCPhysMem->PaToVa( m_vaFrameList[ dwFrameIndex ] & FRAME_LIST_POINTER_MASK );
    BOOL fFoundTD = FALSE;
    while ( pDebugTD != NULL ) {
        DEBUGCHK( pDebugTD->vaPrevIsochTD == NULL ||
                  pDebugTD->vaPrevIsochTD->vaNextTD == pDebugTD );
        DEBUGCHK( pDebugTD->vaNextTD == NULL ||
                  pDebugTD->vaNextTD->vaPrevIsochTD == pDebugTD );
        if ( pDebugTD == pTD ) {
            fFoundTD = TRUE;
        }
        pDebugTD = pDebugTD->vaNextTD;
    }
    DEBUGCHK( fFoundTD );
}
#endif // DEBUG

    if ( pTD->vaNextTD != NULL ) {
        DEBUGCHK( pTD->vaNextTD->Isochronous == 1 );
        DEBUGCHK( pTD->vaNextTD->vaPrevIsochTD == pTD );
        DEBUGCHK( pTD->HW_paLink == ( GetTDPhysAddr( pTD->vaNextTD )
                                            | TD_LINK_POINTER_TD
                                            | TD_LINK_POINTER_VALID ) );
        pTD->vaNextTD->vaPrevIsochTD = pTD->vaPrevIsochTD;
    }
#ifdef DEBUG
    else {
        // this TD should point into the QH tree
        DEBUGCHK( pTD->HW_paLink == ( GetQHPhysAddr( m_interruptQHTree[ QHTreeEntry( dwFrameIndex ) ] )
                                            | TD_LINK_POINTER_QH
                                            | TD_LINK_POINTER_VALID ) );
    } 
#endif // DEBUG

    if ( pTD->vaPrevIsochTD != NULL ) {
        // this TD is after another Isoch TD
        DEBUGCHK( pTD->vaPrevIsochTD->Isochronous == 1 );
        DEBUGCHK( pTD->vaPrevIsochTD->vaNextTD == pTD );
        DEBUGCHK( pTD->vaPrevIsochTD->HW_paLink == ( GetTDPhysAddr( pTD )
                                                        | TD_LINK_POINTER_VALID
                                                        | TD_LINK_POINTER_TD ) );
        pTD->vaPrevIsochTD->vaNextTD = pTD->vaNextTD;
        pTD->vaPrevIsochTD->HW_paLink = pTD->HW_paLink;
    } else {
        // this TD is right after the frame list
        DEBUGCHK( m_vaFrameList[ dwFrameIndex ] == ( GetTDPhysAddr( pTD )
                                                         | FRAME_LIST_POINTER_TD
                                                         | FRAME_LIST_POINTER_VALID ) );
        m_vaFrameList[ dwFrameIndex ] = pTD->HW_paLink;
    }

    pTD->vaPrevIsochTD = NULL;
    pTD->vaNextTD = NULL;
    // don't change pTD->HW_paLink because the host controller
    // may still be accessing this TD. Caller will take care of
    // this issue.
}
#endif //JEFFRO

// ******************************************************************
// Scope: public 
CPipe::CPipe( IN const LPCUSB_ENDPOINT_DESCRIPTOR lpEndpointDescriptor,
              IN const BOOL fIsLowSpeed,
              IN const UCHAR bDeviceAddress,
              IN CUhcd * const pCUhcd)
//
// Purpose: constructor for CPipe
//
// Parameters: lpEndpointDescriptor - pointer to endpoint descriptor for
//                                    this pipe (assumed non-NULL)
//
//             fIsLowSpeed - indicates if this pipe is low speed
//
// Returns: Nothing.
//
// Notes: Most of the work associated with setting up the pipe
//        should be done via OpenPipe. The constructor actually
//        does very minimal work.
//
//        Do not modify static variables here!!!!!!!!!!!
// ******************************************************************
: CPipeAbs(lpEndpointDescriptor->bEndpointAddress )
, m_usbEndpointDescriptor( *lpEndpointDescriptor )
, m_pCUhcd(pCUhcd)
, m_fIsLowSpeed( !!fIsLowSpeed ) // want to ensure m_fIsLowSpeed is 0 or 1
, m_fIsHalted( FALSE )
, m_fTransferInProgress( FALSE )
, m_pLastTransfer ( NULL )
, m_bEndpointAddress( lpEndpointDescriptor->bEndpointAddress )
, m_private_address( bDeviceAddress )
, m_bBusAddress( m_private_address )
, m_pED( NULL )
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CPipe::CPipe\n")) );
    // CPipe::Initialize should already have been called by now
    // to set up the schedule and init static variables
    DEBUGCHK( m_pCUhcd->CHCCAera::m_debug_fInitializeAlreadyCalled );

    InitializeCriticalSection( &m_csPipeLock );

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

// ******************************************************************
// Scope: public virtual 
CPipe::~CPipe( )
//
// Purpose: Destructor for CPipe
//
// Parameters: None
//
// Returns: Nothing.
//
// Notes:   Most of the work associated with destroying the Pipe
//          should be done via ClosePipe
//
//          Do not delete static variables here!!!!!!!!!!!
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CPipe::~CPipe\n")) );
    // transfers should be aborted or closed before deleting object
    DEBUGCHK( m_fTransferInProgress == FALSE );
    DeleteCriticalSection( &m_csPipeLock );
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CPipe::~CPipe\n")) );
}
inline ULONG CPipe::GetQHPhysAddr( IN P_ED virtAddr ) {
        DEBUGCHK( virtAddr != NULL &&
                  m_pCUhcd->CHCCAera::m_pCPhysMem->VaToPa( PUCHAR(virtAddr) ) % 16 == 0 );
        return m_pCUhcd->m_pCPhysMem->VaToPa( PUCHAR(virtAddr) );
}

inline ULONG CPipe::GetTDPhysAddr( IN const P_TD virtAddr ) {
        DEBUGCHK( virtAddr != NULL );
        return m_pCUhcd->CHCCAera::m_pCPhysMem->VaToPa( PUCHAR(virtAddr) );
    };

inline ULONG CPipe::GetTDPhysAddr( IN const P_ITD virtAddr ) {
        DEBUGCHK( virtAddr != NULL );
        return m_pCUhcd->CHCCAera::m_pCPhysMem->VaToPa( PUCHAR(virtAddr) );
};

// ******************************************************************               
// Scope: public 
HCD_REQUEST_STATUS CPipe::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 *pTransfer;
    HCD_REQUEST_STATUS  status = requestFailed;

    EnterCriticalSection( &m_csPipeLock );
    if ( m_fTransferInProgress ) {
        pTransfer = new STransfer;
        if (pTransfer == NULL) {
            DEBUGMSG( ZONE_ERROR, (TEXT("-CPipe(%s)::IssueTransfer cannot allocate transfer params!")
                                   TEXT(" returning Failed\n"), GetPipeType() ) );
            LeaveCriticalSection( &m_csPipeLock );
            return requestFailed;
        }
    } else
        pTransfer = &m_transfer;

    if (m_bBusAddress == 0) {
        if (address != 0) {
            // Following assertion is not required by USB but if it's not true then
            // there are synchronization issues between here and ScheduleTransfer.
            DEBUGCHK( m_fTransferInProgress == FALSE );
            // This is the non-const private member to which m_bBusAddress is a reference:
            m_private_address = address;
        }
    } else
        DEBUGCHK( m_bBusAddress == address );

#ifdef DEBUG
    memset( pTransfer, GARBAGE, sizeof( *pTransfer ) );
#endif // DEBUG
    // IssueTransfer params
    pTransfer->address = m_bBusAddress;
    pTransfer->lpfnCallback = lpStartAddress;
    pTransfer->lpvCallbackParameter = lpvNotifyParameter;
    pTransfer->dwFlags = dwFlags;
    pTransfer->lpvControlHeader = lpvControlHeader;
    pTransfer->dwStartingFrame = dwStartingFrame;
    pTransfer->dwFrames = dwFrames;
    pTransfer->aLengths = aLengths;
    pTransfer->dwBufferSize = dwBufferSize;
    pTransfer->lpvClientBuffer = lpvClientBuffer;
    pTransfer->paClientBuffer = paBuffer;
    pTransfer->lpvCancelId = lpvCancelId;
    pTransfer->adwIsochErrors = adwIsochErrors;
    pTransfer->adwIsochLengths = adwIsochLengths;
    pTransfer->lpfComplete = lpfComplete;
    pTransfer->lpdwBytesTransferred = lpdwBytesTransferred;
    pTransfer->lpdwError = lpdwError;
    // non IssueTransfer params
    pTransfer->rPipe = this;
    pTransfer->vaTDList.td = NULL;
    pTransfer->numTDsInList = 0;
    pTransfer->numTDsComplete = 0;
    pTransfer->vaActualBuffer = PUCHAR( pTransfer->lpvClientBuffer );
    pTransfer->paActualBuffer = pTransfer->paClientBuffer;
    pTransfer->dwCurrentPermissions = GetCurrentPermissions();
    pTransfer->lpNextTransfer = NULL;

    // We must allocate the control header memory here so that cleanup works later.
    if (pTransfer->lpvControlHeader != NULL) {
        PUCHAR pSetup;
        // This must be a control transfer. It is asserted elsewhere,
        // but the worst case is we needlessly allocate some physmem.
        if ( !m_pCUhcd->CHCCAera::m_pCPhysMem->AllocateMemory(
                                   DEBUG_PARAM( TEXT("IssueTransfer SETUP Buffer"), )
                                   sizeof(USB_DEVICE_REQUEST),
                                   &pSetup,
                                   GetMemoryAllocationFlags() ) ) {
            DEBUGMSG( ZONE_WARNING, (TEXT("CPipe(%s)::IssueTransfer - no memory for SETUP buffer\n"), GetPipeType() ) );
            pTransfer->lpvControlHeader = NULL;
            pTransfer->paControlHeader = 0;
            goto doneIssueTransfer;
        }
        pTransfer->paControlHeader = m_pCUhcd->CHCCAera::m_pCPhysMem->VaToPa( pSetup );
        DEBUGCHK( pSetup != NULL && pTransfer->paControlHeader != 0 );
    #ifdef DEBUG
        m_pCUhcd->CHCCAera::m_debug_ControlExtraMemoryAllocated += sizeof( USB_DEVICE_REQUEST );
        DEBUGMSG( ZONE_TRANSFER, (TEXT("CPipe(Control)::IssueTransfer - alloc 1 control header, total bytes = %d\n"), m_pCUhcd->CHCCAera::m_debug_ControlExtraMemoryAllocated ));
    #endif // DEBUG

        __try {
            memcpy( pSetup, PUCHAR( pTransfer->lpvControlHeader ), sizeof(USB_DEVICE_REQUEST) );
            pTransfer->lpvControlHeader = pSetup;
        } __except( EXCEPTION_EXECUTE_HANDLER ) {
            // bad lpvControlHeader
            pTransfer->lpvControlHeader = pSetup;  // so we can free what we allocated
            goto doneIssueTransfer;
        }
    }

    if ( AreTransferParametersValid(pTransfer) ) {
        __try { // initializing transfer status parameters
            *pTransfer->lpfComplete = FALSE;
            *pTransfer->lpdwBytesTransferred = 0;
            *pTransfer->lpdwError = USB_NOT_COMPLETE_ERROR;
        } __except( EXCEPTION_EXECUTE_HANDLER ) {
              goto doneIssueTransfer;
        }
    } else {
        DEBUGCHK( 0 ); // either we're checking params wrong,
                       // or the caller is passing bad arguments
        goto doneIssueTransfer;
    }

    // allocate Transfer Descriptors 
    DEBUGCHK( pTransfer->numTDsInList == 0 &&
              pTransfer->vaTDList.td == NULL );
    pTransfer->numTDsInList = GetNumTDsNeeded(pTransfer);
    DEBUGCHK( pTransfer->numTDsInList > 0 );
    if ( !m_pCUhcd->CHCCAera::m_pCPhysMem->AllocateMemory(
                            DEBUG_PARAM( TEXT("IssueTransfer TDs"), )
                            pTransfer->numTDsInList * GetTdSize(),
                            (PUCHAR *) &pTransfer->vaTDList.td,
                            GetMemoryAllocationFlags() ) ) {
        DEBUGMSG( ZONE_WARNING, (TEXT("CPipe(%s)::IssueTransfer - no memory for TD list\n"), GetPipeType() ) );
        pTransfer->numTDsInList = 0;
        pTransfer->vaTDList.td = NULL;

⌨️ 快捷键说明

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