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

📄 cdevice.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        }
        
        fSuccess = (WaitForSingleObject(m_hHubSuspendBlockEvent,INFINITE) == WAIT_OBJECT_0);
        if (m_fHubThreadClosing || !fSuccess)
            break;
       
        dwForceDetach = 0;

        //RETAILMSG(1, (TEXT("+(%s):WaitForPortStatusChange\r\n"), GetUSBPortType()));
        fSuccess = WaitForPortStatusChange( port, hubStatus, &dwForceDetach );  
        //RETAILMSG(1, (TEXT("-(%s):WaitForPortStatusChange with fSuccess(%d)\r\n"), GetUSBPortType(), fSuccess));
        
        if ( m_fHubThreadClosing || !fSuccess ) {           
            if (!fSuccess && !m_fHubThreadClosing && (m_pCHcd->GetCapability() & HCD_SUSPEND_ON_REQUEST)!=0 ) { 
                // We need check to find out this hub need put into suspend mode.
                PREFAST_ASSERT(m_ppCDeviceOnPort!=NULL);
                EnterCriticalSection( &m_csDeviceLock );
                BOOL bDoSuspend = TRUE;
                for ( UCHAR port2 = 1; port2 <= m_usbHubDescriptor.bNumberOfPorts; port2++ ) {
                    if (m_ppCDeviceOnPort [port2 -1] != NULL) { // Can not.
                        bDoSuspend = FALSE;
                        break;
                    }
                }
                LeaveCriticalSection( &m_csDeviceLock );
                if (bDoSuspend) {
                    BOOL bSuspend =((m_pAttachedHub!=NULL)? 
                            (m_pAttachedHub->SuspendResumeOffStreamDevice(m_address, TRUE)==requestOK):
                            m_pCHcd->SuspendHC());
                    DEBUGMSG( ZONE_HUB, (TEXT("CHub(%s tier %d):: Suspend Device (%d) return %s!\n"), GetDeviceType(), m_tierNumber,m_address,bSuspend?TEXT("Success"):TEXT("FAIL")) );
                    if (bSuspend) {
                        m_fIsSuspend = TRUE;
                        ResetEvent(m_hHubSuspendBlockEvent);// Stop this thread.
                    }
                }
                
            }
            else
                DEBUGMSG( ZONE_ERROR && !m_fHubThreadClosing, (TEXT("CHub(%s tier %d)::HubStatusChangeThread - error reading port status change\n"), GetDeviceType(), m_tierNumber ));
            continue; // loop will exit if m_fHubThreadClosing is set
        }
        if ( port == 0 ) { // Port 0 indicate this is hub status.           
            if (hubStatus.change.hub.OverCurrentIndicatorChange ) {
                if ( hubStatus.status.hub.OverCurrentIndicator ) {
                    RETAILMSG(1, (TEXT("CHub(tier %d)::HubStatusChangeThread - addr %d port %d over current!\n"),
                                  m_tierNumber, m_address, port));
                } else {
                    // hub is no longer over current - re-enumerate all ports
                    // todo - re-enumerate all hub ports during hub over-current recovery
                }
            }
            continue;
        }

        // we will get here if the status of port # "port" has changed.
        // the status information will be in "hubStatus"
        DEBUGCHK( port <= m_usbHubDescriptor.bNumberOfPorts );
        DEBUGMSG( ZONE_ATTACH, (TEXT("CHub(%s tier %d)::HubStatusChangeThread - port %d, change = 0x%04x, status = 0x%04x\n"), GetDeviceType(), m_tierNumber, port, hubStatus.change.word, hubStatus.status.word ) );
        
        if (hubStatus.change.port.OverCurrentChange ) {
            if ( hubStatus.status.port.PortOverCurrent ) {
                RETAILMSG(1, (TEXT("CHub(tier %d)::HubStatusChangeThread - addr %d port %d over current!\n"),
                              m_tierNumber, m_address, port));
                DetachDevice( port );
#if 1   // the "correct" thing to do, according to my reading of the USB spec
                SetOrClearFeature( port, USB_REQUEST_CLEAR_FEATURE, USB_HUB_FEATURE_PORT_POWER );
#else   // another approach
                do {
                    Sleep( 500 );
                    GetStatus( port, hubStatus, &dwForceDetach);
                } while (hubStatus.status.port.PortOverCurrent && !m_fHubThreadClosing);
                hubStatus.change.port.ConnectStatusChange = 1;
#endif
            } else {
                // port is no longer over current - pretend this is a normal attach
                // simulate a connect status change. this has the undesirable but basically harmless
                // side effect of wasting 100 ms to needlessly debounce the power rail.
                hubStatus.change.port.ConnectStatusChange = 1;
            }
        }
        // Resume Notification.
        EnterCriticalSection( &m_csDeviceLock );
        if ( hubStatus.change.port.SuspendChange && !hubStatus.status.port.PortSuspended  && 
                m_ppCDeviceOnPort[port-1]!=NULL ) {
            m_ppCDeviceOnPort[port-1]->ResumeNotification();
        }
        LeaveCriticalSection( &m_csDeviceLock );        
        DEBUGMSG(ZONE_ATTACH, (TEXT("hubStatus PortEnableChange = %d\r\n"), hubStatus.change.port.PortEnableChange));
        DEBUGMSG(ZONE_ATTACH, (TEXT("hubStatus PortEnabled = %d\r\n"), hubStatus.status.port.PortEnabled));
        DEBUGMSG(ZONE_ATTACH, (TEXT("hubStatus PortConnected = %d\r\n"), hubStatus.status.port.PortConnected));     
        DEBUGMSG(ZONE_ATTACH, (TEXT("hubStatus ForceDetach = %d\r\n"), dwForceDetach));     
        DEBUGMSG(ZONE_ATTACH, (TEXT("hubStatus.change.port.ConnectStatusChange = %d\r\n"), hubStatus.change.port.ConnectStatusChange));


        if (( hubStatus.change.port.PortEnableChange &&
             !hubStatus.status.port.PortEnabled &&
             hubStatus.status.port.PortConnected ) || (dwForceDetach)){
            // Connected device has become disabled. If the device was
            // already successfully attached, let's try detach/reattach.
            // It is important to check that the device was successfully
            // attached - otherwise, we can get into an infinite loop
            // of try attach, fail, disable port, retry attach.
            BOOL fDeviceIsPresent;

            EnterCriticalSection( &m_csDeviceLock );
            DEBUGCHK( m_ppCDeviceOnPort != NULL );
            fDeviceIsPresent = ( m_ppCDeviceOnPort[ port - 1 ] != NULL );
            LeaveCriticalSection( &m_csDeviceLock );
            
            if ( fDeviceIsPresent ) {
                DEBUGMSG( ZONE_WARNING, (TEXT("CHub(%s tier %d)::HubStatusChangeThread - device on port %d is connected but has been disabled. Trying to detach & re-attach\n"), GetDeviceType(), m_tierNumber, port) );
                DetachDevice( port );
                // this will cause device attach below, since
                // hubStatus.status.port.PortConnected is already set
                // Be careful of that, it needs to handle in pure HUB mode
                hubStatus.change.port.ConnectStatusChange = 1;
                // We should remove DEBUGCHK since it can be resumed by detach
                // and there is a possibility the PortConnected state has changed.
                //DEBUGCHK( hubStatus.status.port.PortConnected );
            }
        } // we can ignore all other enabled changes
        
        if (( m_pPortState[port-1] == 3) && (hubStatus.change.port.ConnectStatusChange || dwForceDetach))
        {
            DetachDevice(port);
        }

        // now check for connect changes
        if (( hubStatus.change.port.ConnectStatusChange ) && (!dwForceDetach)) {
            EnterCriticalSection( &m_csDeviceLock );
            BOOL fDeviceAlreadyExists = (m_ppCDeviceOnPort[ port - 1 ] != NULL);
            LeaveCriticalSection( &m_csDeviceLock );

            m_pPortState[port-1] = 2; // Preset this i.e. we can handle those they are not ready to connect.
            // we got a connect status change notification on this port, so...
            if (fDeviceAlreadyExists) {
                // ... a change when the device is already here must be a detach;
                //     if there's still something connected then it must be new.
                DEBUGMSG( ZONE_ATTACH, (TEXT("CHub(%s tier %d)::HubStatusChangeThread - device detached on port %d\n"), GetDeviceType(), m_tierNumber, port ) );
                DetachDevice(port);
#ifdef DEBUG
                if ( hubStatus.status.port.PortConnected ) {
                    DEBUGMSG( (ZONE_WARNING && ZONE_VERBOSE) || ZONE_ATTACH,
                              (TEXT("CHub(%s tier %d)::HubStatusChangeThread -")
                               TEXT(" quick detach and re-attach on port %d\n"),
                               GetDeviceType(), m_tierNumber, port) );
                }
#endif // DEBUG
            }
            // ... a change with no device present must be an attach
            //     but section 7.1.7.1 of the USB 1.1 spec says we're
            //     responsible for de-bouncing the attach signalling.
            //
            // we do the de-bouncing by waiting until a 100 ms interval
            // (t3 on figure 7-19 in the spec) elapses with no connection
            // status change on the port. Then we can examine the current
            // connect status reliably.
            BOOL fPoll = TRUE;

            while (fPoll) {
                USB_HUB_AND_PORT_STATUS hubStatus2;                             
                Sleep( 200 );               
                if ( GetStatus( port, hubStatus2, NULL ) == FALSE ) {
                    // failed to get status; probably power-cycle or upper-level detach
                    hubStatus.status.port.PortConnected = FALSE;
                    fPoll = FALSE;
                }
                else if ( hubStatus2.change.port.ConnectStatusChange ) {
                    // ack the status change and wait again
                    //RETAILMSG(1, (TEXT("ConnectStatusChange and SetOrClearFeature\r\n")));
                    SetOrClearFeature( port, USB_REQUEST_CLEAR_FEATURE,
                                       USB_HUB_FEATURE_C_PORT_CONNECTION );
                }
                else {
                    // ah, stability.
                    hubStatus.status.word = hubStatus2.status.word;
                    fPoll = FALSE;
                }
            }
            // We have to reset port and get speed infomation.          
            ResetAndEnablePort( port );
            // Freescale, suppose to be smaller
            Sleep(20);
            GetStatus(port , hubStatus, NULL);
            if ( hubStatus.status.port.PortConnected ) {
                // device attach
                DEBUGMSG( ZONE_ATTACH, (TEXT("CHub(%s tier %d)::HubStatusChangeThread - device attached on port %d\n"), GetDeviceType(), m_tierNumber, port ) );
                //RETAILMSG(1, (TEXT("PortConnected\r\n")));                
                AttachDevice( port,
                              hubStatus.status.port.DeviceIsLowSpeed,
                              m_fIsHighSpeed?hubStatus.status.port.DeviceIsHighSpeed:FALSE );
            }
        } // end of ConnectStatusChange processing
        else if ((dwForceDetach) && (m_pPortState[port-1] == 0))
            m_pPortState[port-1] = 2;

    }
    //RETAILMSG(1, (TEXT("-HUBStatusChangeThread this(0x%x)\r\n"), this));
    DEBUGMSG( ZONE_HUB, (TEXT("-CHub(%s tier %d)::HubStatusChangeThread, THREAD EXITING, returning 0\n"), GetDeviceType(), m_tierNumber ) );
    return 0;
}
// ******************************************************************
HCD_REQUEST_STATUS CDevice::DisableDevice( IN const UINT address,
                                     IN const BOOL fReset )
//
// Purpose: Disable Downstream Device with address "address"
//
// Parameters: See description in CHcd::DisableDevice.
//
// Returns: requestOK - if Device Reset
//
//          requestFailed - if device exists, but unable to disable it.
//
//          requestIgnored - if no device found with matching address
//
// Notes:
// ******************************************************************
{
    DEBUGMSG( ZONE_HUB && ZONE_VERBOSE, (TEXT("CHub(%s tier %d)::DisableDevice - address = %d, pipeIndex = %d\n"), GetDeviceType(), m_tierNumber, address, fReset) );
    HCD_REQUEST_STATUS status = requestIgnored;
    if (address == m_address ) { // If it is this device
        m_pAttachedHub->DisableOffStreamDevice( address, fReset);
        status = requestOK;
    }
    return status;
}

// ******************************************************************
HCD_REQUEST_STATUS CDevice::SuspendResume( IN const UINT address,
                                     IN const BOOL fSuspend )
//
// Purpose: Suspend or Resume on device with address "address"
//
// Parameters: See description in CHcd::SuspendResume
//
// Returns: requestOK - if device suspend or resumed
//
//          requestFailed - if device exists, but unable to reset it
//
//          requestIgnored - if no device found with matching address
//
// Notes:
// ******************************************************************
{
    DEBUGMSG( ZONE_HUB && ZONE_VERBOSE, (TEXT("+CHub(%s tier %d)::SuspendResume - address = %d, fSuspend = %d\n"), GetDeviceType(), m_tierNumber, address, fSuspend) );

    HCD_REQUEST_STATUS status = requestIgnored;

    EnterCriticalSection( &m_csDeviceLock );
    if ( address == m_address ) {
        if (m_pAttachedHub->SuspendResumeOffStreamDevice(address, fSuspend)) {
            m_fIsSuspend=fSuspend;
            status = requestOK;
        }
        else
            status = requestFailed;
    }
    LeaveCriticalSection( &m_csDeviceLock );
    DEBUGMSG( ZONE_HUB && ZONE_VERBOSE, (TEXT("-CHub(%s tier %d)::SuspendResume - address = %d, returing HCD_REQUEST_STATUS %d\n"), GetDeviceType(), m_tierNumber, address, status) );
    return status;
}

#ifdef DEBUG
// ******************************************************************
void CHub::DumpHubDescriptor( IN const PUSB_HUB_DESCRIPTOR pDescriptor )
//
// Purpose: print out the contents of the descriptor via DEBUGMSG
//
// Parameters: pDescriptor - pointer to descriptor
//
// Returns: Nothing.
//
// Notes: Used in debug mode only
//
//        Refer to USB spec 1.1, Section 11.15.2.1
// ******************************************************************
{
    PREFAST_DEBUGCHK( pDescriptor != NULL );
    DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("+Dump USB_HUB_DESCRIPTOR\n")) );
    DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbDescriptorLength = 0x%02x\n"), pDescriptor->bDescriptorLength ));
    DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbDescriptorType = 0x%02x\n"), pDescriptor->bDescriptorType ));
    DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbNumberOfPorts = 0x%02x\

⌨️ 快捷键说明

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