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

📄 chw.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}
// ******************************************************************
ULONG CALLBACK CBusyPipeList::CheckForDoneTransfersThreadStub( IN PVOID pContext)
{
    return ((CBusyPipeList *)pContext)->CheckForDoneTransfersThread( );
}
// Scope: private static
ULONG CBusyPipeList::CheckForDoneTransfersThread( )
//
// Purpose: Thread for checking whether busy pipes are done their
//          transfers. This thread should be activated whenever we
//          get a USB transfer complete interrupt (this can be
//          requested by the InterruptOnComplete field of the TD)
//
// Parameters: 32 bit pointer passed when instantiating thread (ignored)
//                       
// Returns: 0 on thread exit
//
// Notes: 
// ******************************************************************
{
    DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("+CPipe::CheckForDoneTransfersThread\n")) );

    PPIPE_LIST_ELEMENT pPrev = NULL;
    PPIPE_LIST_ELEMENT pCurrent = NULL;

    DEBUGCHK( m_hCheckForDoneTransfersEvent != NULL );

    while ( !m_fCheckTransferThreadClosing ) {
        WaitForSingleObject( m_hCheckForDoneTransfersEvent, m_FrameListSize/2 );
        if ( m_fCheckTransferThreadClosing ) {
            break;
        }
        Lock();
    #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 ) {
            pCurrent->pPipe->CheckForDoneTransfers();
                // 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) );
        Unlock();
    }
    DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("-CPipe::CheckForDoneTransfersThread\n")) );
    return 0;
}
// ******************************************************************
// Scope: protected static 
BOOL CBusyPipeList::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 ));

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

    // make sure there nothing on the pipe already (it only gets officially added after this function succeeds).
    Lock();
#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
    }
    Unlock();
//    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 CBusyPipeList::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 ) );
    Lock();
#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;
        }
    }
    Unlock();
//    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 ));
}

#ifdef ASYNC_PARK_MODE
#undef ASYNC_PARK_MODE
#endif
#define ASYNC_PARK_MODE 1
#define FRAME_LIST_SIZE 0x400

// ************************************CHW ******************************  

//*************************************************************
CHW::CHW( IN const REGISTER portBase,
                              IN const DWORD dwSysIntr,
                              IN CPhysMem * const pCPhysMem,
                              //IN CUhcd * const pHcd,
                              IN LPVOID pvUhcdPddObject,
                              IN LPCTSTR lpDeviceRegistry)
: m_cBusyPipeList(FRAME_LIST_SIZE)
, m_cPeriodicMgr (pCPhysMem,FRAME_LIST_SIZE)
, m_cAsyncMgr(pCPhysMem)
, m_deviceReg(HKEY_LOCAL_MACHINE,lpDeviceRegistry)
//
// Purpose: Constructor for CHW
//
// Parameters:  
//
// Returns: Nothing
//
// Notes: 
// ******************************************************************
{
// definitions for static variables
    DEBUGMSG( ZONE_INIT, (TEXT("+CHW::CHW base=0x%x, intr=0x%x\n"), portBase, dwSysIntr));
    //RETAILMSG(1, (TEXT("CHW::CHW created 0x%x\r\n"), this));
    g_fPowerUpFlag = FALSE;
    g_fPowerResuming = FALSE;
    m_capBase = portBase;
        m_portBase = portBase+Read_CapLength();//EHCI 2.2.1   
    m_NumOfPort=Read_HCSParams().bit.N_PORTS;
    
    //m_pHcd = pHcd;
    m_pMem = pCPhysMem;
    m_pPddContext = pvUhcdPddObject;
    m_frameCounterHighPart = 0;
    m_frameCounterLowPart = 0;
    m_FrameListMask = FRAME_LIST_SIZE-1;  
    m_pFrameList = 0;
    m_dwSysIntr = dwSysIntr;
    m_hUsbInterruptEvent = NULL;
    m_hUsbHubChangeEvent = NULL;
    m_hUsbInterruptThread = NULL;
    m_fUsbInterruptThreadClosing = FALSE;

    m_fFrameLengthIsBeingAdjusted = FALSE;
    m_fStopAdjustingFrameLength = FALSE;
    m_hAdjustDoneCallbackEvent = NULL;
    m_uNewFrameLength = 0;
    m_dwCapability = 0;
    m_bDoResume=FALSE;  
    m_bUSBClockStop = FALSE;
    m_bUSBPanicMode = TRUE;
    m_bUSBIdleSuspend = FALSE;
    SetForceReAttach(0);
   

    m_dwOTGSupport = ((SEHCDPdd *)(pvUhcdPddObject))->dwOTGSupport;
    DEBUGMSG(1, (TEXT("OTG Support = %d\r\n"), m_dwOTGSupport));

    StringCbCopy(m_szOTGGroup, sizeof(m_szOTGGroup), ((SEHCDPdd *)(pvUhcdPddObject))->szOTGGroup);

    m_hAsyncDoorBell=CreateEvent(NULL, FALSE,FALSE,NULL);
    InitializeCriticalSection( &m_csFrameCounter );
}

//*********************************************************
CHW::~CHW()
//
// Purpose: Destructor of CHW object
//
// Parameters:  
//
// Returns: Nothing
//
// Notes: 
// ******************************************************************
{
    if (m_dwSysIntr)
        KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &m_dwSysIntr, sizeof(m_dwSysIntr), NULL, 0, NULL);
    DeInitialize();
    if (m_hAsyncDoorBell)
        CloseHandle(m_hAsyncDoorBell);
    DeleteCriticalSection( &m_csFrameCounter );
    //RETAILMSG(1, (TEXT("CHW::~CHW created 0x%x\r\n"), this));
}

// **************************************************************
BOOL CHW::DisableAsyncSchedule()
//
// Purpose: Request controller to skip the process of asynchronous scheduling
//          This is used during the setup.
//
// Parameters:  
//
// Returns: TRUE - success, FALSE - failure
//
// Notes: 
// ******************************************************************
{
    USBCMD usbcmd=Read_USBCMD();
    // Follow the rule in 4.8 EHCI
    while (usbcmd.bit.ASchedEnable!= Read_USBSTS().bit.ASStatus)
         Sleep(1);

    if (usbcmd.bit.ASchedEnable ==1) {
        usbcmd.bit.ASchedEnable=0;
        Write_USBCMD(usbcmd);
    }

    while (usbcmd.bit.ASchedEnable!= Read_USBSTS().bit.ASStatus)
         Sleep(1);

    return TRUE;
}

//*********************************************************************
BOOL CHW::EnableAsyncSchedule()
//
// Purpose: Request controller to enable the process of asynchronous scheduling
//          This is used during the setup and necessary for Asynchronous Transfer.
//
// Parameters:  
//
// Returns: TRUE - success, FALSE - failure
//
// Notes: 
// ******************************************************************
{
#ifdef ASYNC_PARK_MODE
    if (Read_HHCCP_CAP().bit.Async_Park) {
            USBCMD usbcmd=Read_USBCMD();
            usbcmd.bit.ASchedPMEnable=1;
            usbcmd.bit.ASchedPMCount =3;
            Write_USBCMD(usbcmd);
    }
#endif

    USBCMD usbcmd=Read_USBCMD();
    // Follow the rule in 4.8 EHCI
    while (usbcmd.bit.ASchedEnable!= Read_USBSTS().bit.ASStatus)
         Sleep(1);

    if (usbcmd.bit.ASchedEnable!=1) {
        usbcmd.bit.ASchedEnable=1;
        Write_USBCMD(usbcmd);
    }

    return TRUE;
}

//******************************************************************
BOOL CHW::PowerOnAllPorts()
//
// Purpose: Power on all the USB ports on the controller
//
// Parameters:  
//
// Returns: TRUE - success, FALSE - failure
//
// Notes: 
// ******************************************************************
{
    //Write_EHCIRegister(CONFIGFLAG,1);
    // Power On all the port.
    for (DWORD dwPort=1; dwPort <= m_NumOfPort ; dwPort ++ ) {
        PORTSC portSc = Read_PORTSC( dwPort);
        portSc.bit.Power=1;
        portSc.bit.Owner=0;
        // Do not touch write to clean register
        portSc.bit.ConnectStatusChange=0;
        portSc.bit.EnableChange=0;
        portSc.bit.OverCurrentChange=0;

⌨️ 快捷键说明

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