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

📄 cpipe.cpp

📁 Latest USB 802.3, HID printer and mass storage divers from Microsoft for Platform Builder 4.2.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    PPIPE_LIST_ELEMENT pCurrent = NULL;

    DEBUGCHK( m_hCheckForDoneTransfersEvent != NULL );

    while ( !m_fCheckTransferThreadClosing ) {
        WaitForSingleObject( m_hCheckForDoneTransfersEvent, INFINITE );
        if ( m_fCheckTransferThreadClosing ) {
            break;
        }

        EnterCriticalSection( &m_csBusyPipeListLock );
    #ifdef DEBUG // make sure m_debug_numItemsOnBusyPipeList is accurate
        {
            int debugCount = 0;
            PPIPE_LIST_ELEMENT pDebugElement = m_pBusyPipeList;
            while ( pDebugElement != NULL ) {
                pDebugElement = pDebugElement->pNext;
                debugCount++;
            }
            DEBUGCHK( debugCount == m_debug_numItemsOnBusyPipeList );
        }
        BOOL fDebugNeedProcessing = m_debug_numItemsOnBusyPipeList > 0;
        DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE && fDebugNeedProcessing, (TEXT("CPipe::CheckForDoneTransfersThread - #pipes to check = %d\n"), m_debug_numItemsOnBusyPipeList) );
        DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE && !fDebugNeedProcessing, (TEXT("CPipe::CheckForDoneTransfersThread - warning! Called when no pipes were busy\n")) );
    #endif // DEBUG
        pPrev = NULL;
        pCurrent = m_pBusyPipeList;
        while ( pCurrent != NULL ) {
            if ( pCurrent->pPipe->CheckForDoneTransfers() ) {
                // I was printing pPipe->GetPipeType() in the past
                // but, after this thread's priority was accidentally
                // set too low, it happened that the pipe was closed
                // at exactly this point. That is completely legitimate.
                // So, don't access pPipe->Anything past this point!!
                DEBUGMSG( ZONE_PIPE, (TEXT("CPipe::CheckForDoneTransfersThread - removing pipe 0x%x from busy list\n"), pCurrent->pPipe) );
            #ifdef DEBUG
                pCurrent->pPipe = NULL;
            #endif // DEBUG
                // this pipe is not busy any more. Remove it from the linked list,
                // and move to next item
                if ( pCurrent == m_pBusyPipeList ) {
                    DEBUGCHK( pPrev == NULL );
                    m_pBusyPipeList = m_pBusyPipeList->pNext;
                    delete pCurrent;
                    pCurrent = m_pBusyPipeList;
                } else {
                    DEBUGCHK( pPrev != NULL && pPrev->pNext == pCurrent );
                    pPrev->pNext = pCurrent->pNext;
                    delete pCurrent;
                    pCurrent = pPrev->pNext;
                }
                DEBUGCHK( --m_debug_numItemsOnBusyPipeList >= 0 );
            } else {
                // this pipe is still busy. Move to next item
                pPrev = pCurrent;
                pCurrent = pPrev->pNext;
            }
        }
        DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE && fDebugNeedProcessing, (TEXT("CPipe::CheckForDoneTransfersThread - #pipes still busy = %d\n"), m_debug_numItemsOnBusyPipeList) );
        LeaveCriticalSection( &m_csBusyPipeListLock );
    }
    DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("-CPipe::CheckForDoneTransfersThread\n")) );
    return 0;
}
// ******************************************************************
// Scope: protected static 
BOOL CUHCIFrame::AddToBusyPipeList( IN CPipe * const pPipe,
                               IN const BOOL fHighPriority )
//
// Purpose: Add the pipe indicated by pPipe to our list of busy pipes.
//          This allows us to check for completed transfers after 
//          getting an interrupt, and being signaled via 
//          SignalCheckForDoneTransfers
//
// Parameters: pPipe - pipe to add to busy list
//
//             fHighPriority - if TRUE, add pipe to start of busy list,
//                             else add pipe to end of list.
//
// Returns: TRUE if pPipe successfully added to list, else FALSE
//
// Notes: 
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE, (TEXT("+CPipe::AddToBusyPipeList - new pipe(%s) 0x%x, pri %d\n"), pPipe->GetPipeType(), pPipe, fHighPriority ));

    DEBUGCHK( pPipe != NULL );
    BOOL fSuccess = FALSE;

    // make sure there nothing on the pipe already (it only gets officially added after this function succeeds).
    DEBUGCHK( !pPipe->m_fTransferInProgress );

    EnterCriticalSection( &m_csBusyPipeListLock );
#ifdef DEBUG
{
    // make sure this pipe isn't already in the list. That should never happen.
    // also check that our m_debug_numItemsOnBusyPipeList is correct
    PPIPE_LIST_ELEMENT pBusy = m_pBusyPipeList;
    int count = 0;
    while ( pBusy != NULL ) {
        DEBUGCHK( pBusy->pPipe != NULL &&
                  pBusy->pPipe != pPipe );
        pBusy = pBusy->pNext;
        count++;
    }
    DEBUGCHK( m_debug_numItemsOnBusyPipeList == count );
}
#endif // DEBUG
    
    PPIPE_LIST_ELEMENT pNewBusyElement = new PIPE_LIST_ELEMENT;
    if ( pNewBusyElement != NULL ) {
        pNewBusyElement->pPipe = pPipe;
        if ( fHighPriority || m_pBusyPipeList == NULL ) {
            // add pipe to start of list
            pNewBusyElement->pNext = m_pBusyPipeList;
            m_pBusyPipeList = pNewBusyElement;
        } else {
            // add pipe to end of list
            PPIPE_LIST_ELEMENT pLastElement = m_pBusyPipeList;
            while ( pLastElement->pNext != NULL ) {
                pLastElement = pLastElement->pNext;
            }
            pNewBusyElement->pNext = NULL;
            pLastElement->pNext = pNewBusyElement;
        }
        fSuccess = TRUE;
    #ifdef DEBUG
        m_debug_numItemsOnBusyPipeList++;
    #endif // DEBUG
    }
    LeaveCriticalSection( &m_csBusyPipeListLock );

    DEBUGMSG( ZONE_PIPE, (TEXT("-CPipe::AddToBusyPipeList - new pipe(%s) 0x%x, pri %d, returning BOOL %d\n"), pPipe->GetPipeType(), pPipe, fHighPriority, fSuccess) );
    return fSuccess;
}

// ******************************************************************
// Scope: protected static
void CUHCIFrame::RemoveFromBusyPipeList( IN CPipe * const pPipe )
//
// Purpose: Remove this pipe from our busy pipe list. This happens if
//          the pipe is suddenly aborted or closed while a transfer
//          is in progress
//
// Parameters: pPipe - pipe to remove from busy list
//
// Returns: Nothing
//
// Notes: 
// ******************************************************************
{
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE, (TEXT("+CPipe::RemoveFromBusyPipeList - pipe(%s) 0x%x\n"), pPipe->GetPipeType(), pPipe ) );

    EnterCriticalSection( &m_csBusyPipeListLock );
#ifdef DEBUG
    BOOL debug_fRemovedPipe = FALSE;
{
    // check m_debug_numItemsOnBusyPipeList
    PPIPE_LIST_ELEMENT pBusy = m_pBusyPipeList;
    int count = 0;
    while ( pBusy != NULL ) {
        DEBUGCHK( pBusy->pPipe != NULL );
        pBusy = pBusy->pNext;
        count++;
    }
    DEBUGCHK( m_debug_numItemsOnBusyPipeList == count );
}
#endif // DEBUG
    PPIPE_LIST_ELEMENT pPrev = NULL;
    PPIPE_LIST_ELEMENT pCurrent = m_pBusyPipeList;
    while ( pCurrent != NULL ) {
        if ( pCurrent->pPipe == pPipe ) {
            // Remove item from the linked list
            if ( pCurrent == m_pBusyPipeList ) {
                DEBUGCHK( pPrev == NULL );
                m_pBusyPipeList = m_pBusyPipeList->pNext;
            } else {
                DEBUGCHK( pPrev != NULL &&
                          pPrev->pNext == pCurrent );
                pPrev->pNext = pCurrent->pNext;
            }
            delete pCurrent;
            pCurrent = NULL;
        #ifdef DEBUG
            debug_fRemovedPipe = TRUE;
            DEBUGCHK( --m_debug_numItemsOnBusyPipeList >= 0 );
        #endif // DEBUG
            break;
        } else {
            // Check next item
            pPrev = pCurrent;
            pCurrent = pPrev->pNext;
        }
    }
    LeaveCriticalSection( &m_csBusyPipeListLock );

    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE && debug_fRemovedPipe, (TEXT("-CPipe::RemoveFromBusyPipeList, removed pipe(%s) 0x%x\n"), pPipe->GetPipeType(), pPipe));
    DEBUGMSG( ZONE_PIPE && ZONE_VERBOSE && !debug_fRemovedPipe, (TEXT("-CPipe::RemoveFromBusyPipeList, pipe(%s) 0x%x was not on busy list\n"), pPipe->GetPipeType(), pPipe ));
}


// ******************************************************************               
// Scope: private static
void CUHCIFrame::InsertIsochTDIntoFrameList( IN_OUT PUHCD_TD pTD,
                                                   IN const DWORD dwFrameIndex )
//
// Purpose: Inserts an isochronous transfer descriptor (TD) into the schedule
//          
//
// Parameters: pTD - pointer to TD to insert into schedule. This
//                   TD will have some of its fields changed by this function.
//
//             dwFrameIndex - indicates frame index in which to schedule this TD.
//                            Caller should ensure 0 <= index < FRAME_LIST_LENGTH
//
// Returns: Nothing
//
// Notes: Assumes m_csFrameListLock is held
// ******************************************************************
{
    DEBUGCHK( pTD != NULL &&
              pTD->Isochronous == 1 );
    DEBUGCHK( dwFrameIndex >= 0 &&
              dwFrameIndex < FRAME_LIST_LENGTH );

    if ( m_vaFrameList[ dwFrameIndex ] & FRAME_LIST_POINTER_QH ) {
        // there are no isoch TDs presently scheduled in this frame
        DEBUGCHK( m_vaFrameList[ dwFrameIndex ] == ( GetQHPhysAddr( m_interruptQHTree[ QHTreeEntry( dwFrameIndex ) ] )
                                                                         | FRAME_LIST_POINTER_QH
                                                                         | FRAME_LIST_POINTER_VALID ) );
        pTD->vaNextTD = NULL;
    } else {
        // there are already isoch TDs scheduled in this frame
        PUHCD_TD vaNextIsochTD = (PUHCD_TD) m_pCPhysMem->PaToVa( m_vaFrameList[ dwFrameIndex ] & FRAME_LIST_POINTER_MASK );

        DEBUGCHK( m_vaFrameList[ dwFrameIndex ] == ( GetTDPhysAddr( vaNextIsochTD )
                                                         | FRAME_LIST_POINTER_TD
                                                         | FRAME_LIST_POINTER_VALID ) );
        DEBUGCHK( vaNextIsochTD->Isochronous == 1 &&
                  vaNextIsochTD->vaPrevIsochTD == NULL );

        pTD->vaNextTD = vaNextIsochTD;
        vaNextIsochTD->vaPrevIsochTD = pTD;
    }

    // now insert pTD after the frame list
    pTD->vaPrevIsochTD = NULL;
    pTD->HW_paLink = m_vaFrameList[ dwFrameIndex ];
    m_vaFrameList[ dwFrameIndex ] = GetTDPhysAddr( pTD )
                                        | FRAME_LIST_POINTER_TD
                                        | FRAME_LIST_POINTER_VALID;
}

// ******************************************************************               
// Scope: private static
void CUHCIFrame::RemoveIsochTDFromFrameList( IN_OUT PUHCD_TD pTD,
                                                   IN const DWORD dwFrameIndex )
//
// Purpose: Removes an isochronous transfer descriptor (TD) from the schedule
//          
//
// Parameters: pTD - pointer to TD to remove from schedule. This
//                   TD will have some of its fields changed by this function.
//
//             dwFrameIndex - frame index of this TD. Indicates which frame
//                            the TD is scheduled in. Caller must ensure that
//                            0 <= dwFrameIndex < FRAME_LIST_LENGTH
//
// Returns: Nothing
//
// Notes: Assumes m_csFrameListLock is held
//
//        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) );
    PUHCD_TD pDebugTD = (PUHCD_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;
    }

⌨️ 快捷键说明

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