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

📄 cpipe.cpp

📁 Latest USB 802.3, HID printer and mass storage divers from Microsoft for Platform Builder 4.2.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        goto doneIssueTransfer;
    }
#ifdef DEBUG
    m_pCUhcd->CHCCAera::m_debug_TDMemoryAllocated += pTransfer->numTDsInList * GetTdSize(),
    DEBUGMSG( ZONE_TD, (TEXT("CPipe(%s)::IssueTransfer - alloc %d TDs, total bytes = %d\n"), GetPipeType(), pTransfer->numTDsInList, m_pCUhcd->CHCCAera::m_debug_TDMemoryAllocated ) );
#endif // DEBUG
    DEBUGCHK( (pTransfer->vaTDList.phys & 0x1F) == 0 ); // isoch TDs must have 32B alignment

#ifdef DEBUG
    if ( pTransfer->dwFlags & USB_IN_TRANSFER ) {
        // I am leaving this in for two reasons:
        //  1. The memset ought to work even on zero bytes to NULL.
        //  2. Why would anyone really want to do a zero length IN?
        DEBUGCHK( pTransfer->dwBufferSize > 0 &&
                  pTransfer->lpvClientBuffer != NULL );
        __try { // IN buffer, trash it
            memset( PUCHAR( pTransfer->lpvClientBuffer ), GARBAGE, pTransfer->dwBufferSize );
        } __except( EXCEPTION_EXECUTE_HANDLER ) {
        }
    }
#endif // DEBUG

    // allocate data buffer if needed
    DEBUGCHK( pTransfer->vaActualBuffer == PUCHAR( pTransfer->lpvClientBuffer ) &&
              pTransfer->paActualBuffer == pTransfer->paClientBuffer );

    if ( pTransfer->dwBufferSize > 0 &&
         pTransfer->paClientBuffer == 0 ) { 

        DEBUGCHK( pTransfer->lpvClientBuffer != NULL );

        // ok, there's data on this transfer and the client
        // did not specify a physical address for the
        // buffer. So, we need to allocate our own.

        if ( !m_pCUhcd->CHCCAera::m_pCPhysMem->AllocateMemory(
                                   DEBUG_PARAM( TEXT("IssueTransfer Buffer"), )
                                   pTransfer->dwBufferSize,
                                   &pTransfer->vaActualBuffer, 
                                   GetMemoryAllocationFlags() ) ) {
            DEBUGMSG( ZONE_WARNING, (TEXT("CPipe(%s)::IssueTransfer - no memory for TD buffer\n"), GetPipeType() ) );
            pTransfer->vaActualBuffer = NULL;
            pTransfer->paActualBuffer = 0;
            goto doneIssueTransfer;
        }
        pTransfer->paActualBuffer = m_pCUhcd->CHCCAera::m_pCPhysMem->VaToPa( pTransfer->vaActualBuffer );
        DEBUGCHK( pTransfer->vaActualBuffer != NULL &&
                  pTransfer->paActualBuffer != 0 );
#ifdef DEBUG
        m_pCUhcd->CHCCAera::m_debug_BufferMemoryAllocated += pTransfer->dwBufferSize;
        DEBUGMSG( ZONE_TD, (TEXT("CPipe(%s)::IssueTransfer - alloc buffer of %d, total bytes = %d\n"), GetPipeType(), pTransfer->dwBufferSize, m_pCUhcd->CHCCAera::m_debug_BufferMemoryAllocated ) );
#endif // DEBUG

        if ( !(pTransfer->dwFlags & USB_IN_TRANSFER) ) {
            __try { // copying client buffer for OUT transfer
                memcpy( pTransfer->vaActualBuffer, PUCHAR( pTransfer->lpvClientBuffer ), pTransfer->dwBufferSize );
            } __except( EXCEPTION_EXECUTE_HANDLER ) {
                  // bad lpvClientBuffer
                  goto doneIssueTransfer;
            }
        }
    }

#ifdef DEBUG
    if (m_fTransferInProgress) {
        DEBUGCHK( pTransfer != &m_transfer );
        DEBUGCHK( m_pLastTransfer != NULL && m_pLastTransfer->lpNextTransfer == NULL );
    } else {
        DEBUGCHK( pTransfer == &m_transfer );
        DEBUGCHK( m_pLastTransfer == NULL );
    }
#endif //DEBUG

    // fill in TDs but don't actually make it happen yet
    status = AddTransfer(pTransfer);
    
    if (status == requestOK) {
        if (m_fTransferInProgress)
            m_pLastTransfer->lpNextTransfer = pTransfer;
        else
            // tell the HC about it
            status = ScheduleTransfer();
    }

doneIssueTransfer:
    DEBUGCHK( (status != requestOK) ||
              (status == requestOK && m_fTransferInProgress) );
    if ( status != requestOK ) {
        FreeTransferMemory(pTransfer);
        if (pTransfer != &m_transfer)
            delete pTransfer;
    } else
        m_pLastTransfer = pTransfer;
    
    LeaveCriticalSection( &m_csPipeLock );

    DEBUGMSG( ZONE_TRANSFER, (TEXT("-CPipe(%s)::IssueTransfer - address = %d, xfr %08x can %08x returning STATUS %d\n"), GetPipeType(), address, pTransfer, lpvCancelId, status) );
    return status;
}

// ******************************************************************
// Scope: public
HCD_REQUEST_STATUS CPipe::IsPipeHalted( OUT LPBOOL const lpbHalted )
//
// Purpose: Return whether or not this pipe is halted (stalled)
//
// Parameters: lpbHalted - pointer to BOOL which receives
//                         TRUE if pipe halted, else FALSE
//
// Returns: requestOK 
//
// Notes:  Caller should check for lpbHalted to be non-NULL
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CPipe(%s)::IsPipeHalted\n"), GetPipeType()) );

    DEBUGCHK( lpbHalted ); // should be checked by CUhcd

    EnterCriticalSection( &m_csPipeLock );
    *lpbHalted = m_fIsHalted;
    LeaveCriticalSection( &m_csPipeLock );

    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CPipe(%s)::IsPipeHalted, *lpbHalted = %d, returning HCD_REQUEST_STATUS %d\n"), GetPipeType(), *lpbHalted, requestOK) );
    return requestOK;
}

// ******************************************************************
// Scope: public
void CPipe::ClearHaltedFlag( void )
//
// Purpose: Clears the pipe is halted flag
//
// Parameters: None
//
// Returns: Nothing 
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CPipe(%s)::ClearHaltedFlag\n"), GetPipeType() ) );

    EnterCriticalSection( &m_csPipeLock );
    DEBUGMSG( ZONE_WARNING && !m_fIsHalted, (TEXT("CPipe(%s)::ClearHaltedFlag - warning! Called on non-stalled pipe\n"), GetPipeType()) );
    m_fIsHalted = FALSE;
    m_pED->bfHalted = 0;
    m_pED->bfToggleCarry = 0;
    LeaveCriticalSection( &m_csPipeLock );

    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("-CPipe(%s)::ClearHaltedFlag\n"), GetPipeType()) );
}
// ******************************************************************               
// Scope: protected virtual
DWORD CPipe::GetMemoryAllocationFlags( void ) const
//
// Purpose: Get flags for allocating memory from the CPhysMem class.
//          Descended pipes can over-ride this if they want to
//          specify different memory alloc flags (i.e. block or not,
//          high priority or not, etc)
//
// Parameters: None
//
// Returns: DWORD representing memory allocation flags
//
// Notes: 
// ******************************************************************
{
    // default choice - not high priority, no blocking
    return CPHYSMEM_FLAG_NOBLOCK;
}

// ******************************************************************               
// Scope: protected 
void CPipe::FreeTransferMemory( STransfer *pTransfer )
//
// Purpose: Free all of the memory associated with the current transfer.
//          For this function, that would be:
//                  - Any TDs allocated to carry the transfer request
//                  - Any data buffer allocated if the client passed
//                    in paClientBuffer == 0
//                  - A SETUP buffer for control transfers
//
// Parameters: None - (all are in m_transfer)
//
// Returns: Nothing
//
// Notes: Should only be called when a transfer is NOT in progress!!
// ******************************************************************
{
    if (pTransfer == NULL)
        pTransfer = &m_transfer;
    
    DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("+CPipe(%s)::FreeTransferMemory\n"), GetPipeType() ) );
    EnterCriticalSection( &m_csPipeLock );

    if (pTransfer->lpvControlHeader != NULL) {
        DEBUGCHK( pTransfer->paControlHeader != 0 );
        DEBUGCHK( pTransfer->paControlHeader == m_pCUhcd->CHCCAera::m_pCPhysMem->VaToPa(PUCHAR(pTransfer->lpvControlHeader)) );
        m_pCUhcd->CHCCAera::m_pCPhysMem->FreeMemory( PUCHAR(pTransfer->lpvControlHeader),
                                 pTransfer->paControlHeader,
                                 GetMemoryAllocationFlags() );
    #ifdef DEBUG
        m_pCUhcd->CHCCAera::m_debug_ControlExtraMemoryAllocated -= sizeof( USB_DEVICE_REQUEST );
        DEBUGMSG( ZONE_TRANSFER, (TEXT("CPipe(Control)::FreeTransferMemory - free 1 control header, total bytes = %d\n"), m_pCUhcd->CHCCAera::m_debug_ControlExtraMemoryAllocated ));
    #endif // DEBUG
    }

    // Free Transfer Descriptor (TD) list
    if ( pTransfer->vaTDList.td != NULL ) {
        DEBUGCHK( pTransfer->numTDsInList > 0 );
        m_pCUhcd->CHCCAera::m_pCPhysMem->FreeMemory( (PUCHAR) pTransfer->vaTDList.td,
                                 m_pCUhcd->CHCCAera::m_pCPhysMem->VaToPa( (PUCHAR) pTransfer->vaTDList.td ),
                                 GetMemoryAllocationFlags() );
    #ifdef DEBUG
        m_pCUhcd->CHCCAera::m_debug_TDMemoryAllocated -= pTransfer->numTDsInList * GetTdSize();
        DEBUGMSG( ZONE_TD, (TEXT("CPipe(%s)::FreeTransferMemory - free %d TDs, total bytes = %d\n"), GetPipeType(), pTransfer->numTDsInList, m_pCUhcd->CHCCAera::m_debug_TDMemoryAllocated ) );
    #endif // DEBUG
    }
#ifdef DEBUG
    else {
        DEBUGCHK( pTransfer->numTDsInList == 0 );
    }
    pTransfer->vaTDList.td = P_TD( 0xdeadbeef );
    pTransfer->numTDsInList = 0xbeef;
#endif // DEBUG

    // Free data buffer, if we allocated one
    if ( pTransfer->paActualBuffer != 0 &&
         pTransfer->paActualBuffer != pTransfer->paClientBuffer ) {

        DEBUGCHK( pTransfer->vaActualBuffer != NULL &&
                  pTransfer->lpvClientBuffer != NULL &&
                  pTransfer->dwBufferSize > 0 );  // we didn't allocate memory if the xfer was 0 bytes

        m_pCUhcd->CHCCAera::m_pCPhysMem->FreeMemory( pTransfer->vaActualBuffer,
                                 pTransfer->paActualBuffer,
                                 GetMemoryAllocationFlags() );
    #ifdef DEBUG
        m_pCUhcd->CHCCAera::m_debug_BufferMemoryAllocated -= pTransfer->dwBufferSize;
        DEBUGMSG( ZONE_TD, (TEXT("CPipe(%s)::FreeTransferMemory - free buffer of %d, total bytes = %d\n"), GetPipeType(), pTransfer->dwBufferSize, m_pCUhcd->CHCCAera::m_debug_BufferMemoryAllocated ) );
        DEBUGCHK( m_pCUhcd->CHCCAera::m_debug_BufferMemoryAllocated >= 0 );
    #endif // DEBUG
    }
#ifdef DEBUG
    pTransfer->vaActualBuffer = PUCHAR( 0xdeadbeef );
    pTransfer->paActualBuffer = 0xdeadbeef;
#endif // DEBUG

    LeaveCriticalSection( &m_csPipeLock );
    DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("-CPipe(%s)::FreeTransferMemory\n"), GetPipeType() ) );
}


// ******************************************************************               
// Scope: protected static
void CPipe::InitializeTD( OUT P_TD const pTD,
                          IN       STransfer *pTransfer,
                          IN const P_TD vaNextTD,
                          IN const UCHAR InterruptOnComplete,
                          IN const UCHAR Isochronous,
                          IN const BOOL  /*LowSpeedControl*/,
                          IN const DWORD PID,
                          IN const UCHAR /*Address*/,
                          IN const UCHAR /*Endpoint*/,
                          IN const USHORT DataToggle,
                          IN const DWORD paBuffer,
                          IN const DWORD MaxLength,
                          IN const BOOL bShortPacketOk)
//
// Purpose: Fill in Transfer Descriptor fields
//
// Parameters: pTD - pointer to transfer descriptor to fill in
//
//             Rest of Params - various transfer descriptor fields
//
// Returns: Nothing
//
// Notes: MaxLength field should already be encoded by caller into 
//        (n-1) form
// ******************************************************************
{
    DEBUGCHK( !Isochronous );   // this method must be overridden for OHCI isoch pipes
    DEBUGCHK( pTransfer != NULL );
    UNREFERENCED_PARAMETER(Isochronous);
    // unused bits have already been zeroed by caller!

    // not really part of the TD
    pTD->pTransfer = pTransfer;
    pTD->pNextTd = vaNextTD;
    pTD->pPipe = this;
    pTD->bfIsIsoch = 0;
    pTD->bfDiscard = 0;

    // the actual TD (null is legal for the last TD)
    pTD->paNextTd.phys = vaNextTD ? m_pCUhcd->CHCCAera::m_pCPhysMem->VaToPa((PUCHAR)vaNextTD) : 0;

//    DEBUGCHK( InterruptOnComplete == 0 || InterruptOnComplete == 7 );
    pTD->bfShortPacketOk = bShortPacketOk;
    pTD->bfDelayInterrupt = InterruptOnComplete ? gcTdInterruptOnComplete : gcTdNoInterrupt;
    pTD->bfDataToggle = DataToggle;
    pTD->bfErrorCount = 0;
    pTD->bfConditionCode = USB_NOT_ACCESSED_ERROR;

    DEBUGCHK( PID == TD_IN_PID ||
              PID == TD_OUT_PID ||
              PID == TD_SETUP_PID );
    pTD->bfPID = PID;

⌨️ 快捷键说明

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