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

📄 cdevice.cpp

📁 可在VMWare workstation中的运行的wince 5 bsp
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // 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 );
                } 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 );
        if ( hubStatus.change.port.PortEnableChange &&
             !hubStatus.status.port.PortEnabled &&
             hubStatus.status.port.PortConnected ) {
            // 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
                hubStatus.change.port.ConnectStatusChange = 1;
                DEBUGCHK( hubStatus.status.port.PortConnected );
            }
        } // we can ignore all other enabled changes

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

            // 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( 100 );
                if ( GetStatus( port, hubStatus2 ) == 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
                    SetOrClearFeature( port, USB_REQUEST_CLEAR_FEATURE,
                                       USB_HUB_FEATURE_C_PORT_CONNECTION );
                }
                else {
                    // ah, stability.
                    hubStatus.status.word = hubStatus2.status.word;
                    fPoll = FALSE;
                }
            }

            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 ) );
                AttachDevice( port,
                              hubStatus.status.port.DeviceIsLowSpeed );
            }
        } // end of ConnectStatusChange processing
    }
    DEBUGMSG( ZONE_HUB, (TEXT("-CHub(%s tier %d)::HubStatusChangeThread, THREAD EXITING, returning 0\n"), GetDeviceType(), m_tierNumber ) );
    return 0;
}
#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\n"), pDescriptor->bNumberOfPorts ));
    DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\twHubCharacteristics = 0x%04x\n"), pDescriptor->wHubCharacteristics ));
    if ( pDescriptor->wHubCharacteristics & USB_HUB_CHARACTERISTIC_NO_POWER_SWITCHING ) {
        DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\twHubCharacteristics, No Port Power Switching\n")));
    } else if ( pDescriptor->wHubCharacteristics & USB_HUB_CHARACTERISTIC_INDIVIDUAL_POWER_SWITCHING ) {
        DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\twHubCharacteristics, Individual Port Power Switching\n")));
    } else {
        DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\twHubCharacteristics, Ganged Port Power Switching\n")));
    }
    DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\twHubCharacteristics, Hub %s part of compound device\n"), ((pDescriptor->wHubCharacteristics & USB_HUB_CHARACTERISTIC_PART_OF_COMPOUND_DEVICE) ? TEXT("IS") : TEXT("IS NOT")) ));
    if ( pDescriptor->wHubCharacteristics & USB_HUB_CHARACTERISTIC_NO_OVER_CURRENT_PROTECTION ) {
        DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\twHubCharacteristics, No Over Current Protection\n")));
    } else if ( pDescriptor->wHubCharacteristics & USB_HUB_CHARACTERISTIC_INDIVIDUAL_OVER_CURRENT_PROTECTION ) {
        DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\twHubCharacteristics, Individual Over Current Protection\n")));
    } else {
        DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\t\twHubCharacteristics, Global Over Current Protection\n")));
    }
    DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbPowerOnToPowerGood = 0x%02x\n"), pDescriptor->bPowerOnToPowerGood ));
    DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tbHubControlCurrent = 0x%02x\n"), pDescriptor->bHubControlCurrent ));
    const UCHAR numBytes = 1 + (pDescriptor->bNumberOfPorts >> 3);
    for ( UCHAR offset = 0; offset < numBytes; offset++  ) {
        DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tDeviceRemovable bitmask byte #%d = 0x%02x\n"), offset + 1, pDescriptor->bRemoveAndPowerMask[ offset ] ) );
    }
    for ( offset = numBytes; offset < 2 * numBytes; offset++ ) {
        DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("\tPortPwrCtrlMask bitmask byte #%d = 0x%02x\n"), offset - numBytes + 1, pDescriptor->bRemoveAndPowerMask[ offset ] ) );
    }
    DEBUGMSG( ZONE_DESCRIPTORS, (TEXT("-Dump USB_HUB_DESCRIPTOR\n")) );
}
#endif // DEBUG

// ******************************************************************
void CHub::AttachDevice( IN const UCHAR port,
                         IN const BOOL fIsLowSpeed )
//
// Purpose: This function is called when a new device is attached
//          on port "port". After this procedure finishes, a configured
//          device will be added to the hub's port array
//
// Parameters: port - indicates hub port on which device was attached
//
//             fIsLowSpeed - indicates if new device is low speed
//
// Returns: Nothing
//
// Notes: If this function fails, the port will be disabled
// ******************************************************************
{
    DEBUGMSG( ZONE_ATTACH, (TEXT("+CHub(%s tier %d)::AttachDevice - port = %d, fIsLowSpeed = %d\n"), GetDeviceType(), m_tierNumber, port, fIsLowSpeed ) );

    DEBUGCHK( port > 0 && port <= m_usbHubDescriptor.bNumberOfPorts );

    // device related variables
    CDevice*                pNewDevice = NULL;
    UCHAR                   address = 0xff; // illegal address
    USB_DEVICE_INFO         deviceInfo;
    USB_HUB_DESCRIPTOR      usbHubDescriptor;
    CPipeAbs*               pControlPipe = NULL; // pipe to device's endpoint 0

    // setup process related varibles
    BOOL                    fUsingAddr0 = FALSE;
    DEVICE_CONFIG_STATUS   configStatus = DEVICE_CONFIG_STATUS_OPENING_ENDPOINT0_PIPE;
    UCHAR                   configFailures = 0;
    UINT                    currentConfigDescriptorIndex = 0;
    BOOL                    fPipeHalted = FALSE;

    deviceInfo.dwCount = sizeof( USB_DEVICE_INFO );
    deviceInfo.lpActiveConfig = NULL;
    deviceInfo.lpConfigs = NULL;

    if ( !ReserveAddress( address ) ) {
        DEBUGMSG( ZONE_WARNING, (TEXT("CHub(%s tier %d)::AttachDevice - all USB addresses are in use!\n"), GetDeviceType(), m_tierNumber) );
        // don't do any attach processing
        configStatus = DEVICE_CONFIG_STATUS_DONE;
    }
    while ( configStatus != DEVICE_CONFIG_STATUS_DONE ) {
        if ( m_fHubThreadClosing || fPipeHalted || configFailures > 2 ) {
            configStatus = DEVICE_CONFIG_STATUS_FAILED;
        }
        DEBUGMSG( ZONE_ATTACH, (TEXT("CHub(%s tier %d)::AttachDevice - status = %s, failures = %d\n"), GetDeviceType(), m_tierNumber, STATUS_TO_STRING( configStatus ), configFailures ) );
        switch ( configStatus ) {
        case DEVICE_CONFIG_STATUS_OPENING_ENDPOINT0_PIPE:
        {
            DEBUGCHK( pControlPipe == NULL );
            USB_ENDPOINT_DESCRIPTOR usbEndpointZeroDescriptor;
            usbEndpointZeroDescriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE;
            usbEndpointZeroDescriptor.bEndpointAddress = 0;
            // usbEndpointZeroDescriptor.bInterval = ; <- ignored for control pipes
            usbEndpointZeroDescriptor.bLength = sizeof( USB_ENDPOINT_DESCRIPTOR );
            usbEndpointZeroDescriptor.bmAttributes = USB_ENDPOINT_TYPE_CONTROL;
            usbEndpointZeroDescriptor.wMaxPacketSize = ENDPOINT_ZERO_MIN_MAXPACKET_SIZE;

            pControlPipe = CreateControlPipe( &usbEndpointZeroDescriptor,
                                             fIsLowSpeed,0,
                                             m_pCHcd);
            if ( pControlPipe != NULL && pControlPipe->OpenPipe() == requestOK ) {
                // success
                configStatus = DEVICE_CONFIG_STATUS_USING_ADDRESS0;
            } else {
                DEBUGMSG( ZONE_ATTACH && ZONE_ERROR, (TEXT("CHub(%s tier %d)::AttachDevice - failure on %s step, unable to open control pipe\n"), GetDeviceType(), m_tierNumber, STATUS_TO_STRING( configStatus ) ) );
                configFailures++;
                delete pControlPipe;
                pControlPipe = NULL;
            }
            break;
        }
        case DEVICE_CONFIG_STATUS_USING_ADDRESS0:
        {
            DEBUGCHK( !fUsingAddr0 );
            fUsingAddr0 = TRUE;
            //if (EnterCritSec_Ex( &m_csAddress0Lock, INFINITE ) != CSS_SUCCESS) {
            if (m_pDeviceGlobal->Addr0LockEntry(INFINITE )!= CSS_SUCCESS) {
                DEBUGMSG( ZONE_ATTACH, (TEXT("CHub(%s tier %d)::AttachDevice - shutdown signalled during enumeration\n"), GetDeviceType(), m_tierNumber) );
                fUsingAddr0 = FALSE;
                configStatus = DEVICE_CONFIG_STATUS_FAILED;
            } else
                // successfully acquired the Address0Lock
                configStatus = DEVICE_CONFIG_STATUS_RESET_AND_ENABLE_PORT;
            break;
        }
        case DEVICE_CONFIG_STATUS_RESET_AND_ENABLE_PORT:
        {
            DEBUGCHK( fUsingAddr0 );
            if ( ResetAndEnablePort( port ) ) {
                configStatus = DEVICE_CONFIG_STATUS_SCHEDULING_GET_DEVICE_DESCRIPTOR_TEST;
            } else {
                DEBUGMSG( ZONE_ATTACH && ZONE_ERROR, (TEXT("CHub(%s tier %d)::AttachDevice - failure on %s step, unable to reset/enable port\n"), GetDeviceType(), m_tierNumber, STATUS_TO_STRING( configStatus ) ) );
                configFailures++;
            }
            break;
        }
        case DEVICE_CONFIG_STATUS_SCHEDULING_GET_DEVICE_DESCRIPTOR_TEST: {
            if ( GetDescriptor( pControlPipe,
                                0,
                                USB_DEVICE_DESCRIPTOR_TYPE,
                                0, // descriptor index
                                ENDPOINT_ZERO_MIN_MAXPACKET_SIZE,
                                &deviceInfo.Descriptor ) ) {
                // success
                configStatus = DEVICE_CONFIG_STATUS_

⌨️ 快捷键说明

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