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

📄 cdevice.cpp

📁 嵌入式操作系统WINCE5.0下的USB驱动程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        }
        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;
                }
            }
            // We have to reset port and get speed infomation.
            ResetAndEnablePort( port );
            Sleep(20);
            GetStatus(port , hubStatus);
            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,
                              m_fIsHighSpeed?hubStatus.status.port.DeviceIsHighSpeed:FALSE );
            }
        } // end of ConnectStatusChange processing
    }
    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\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 ,
                         IN const BOOL fIsHighSpeed )
//
// 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:
        {
            // Create TT if it is neccessary.
            if (m_fIsHighSpeed && !fIsHighSpeed &&  !m_pAddedTT[port-1]) { // Hi-Speed Hub and Low Speed device.
                m_pAddedTT[port-1] = m_pDeviceGlobal->AddedTt(m_address,port);
            }
            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;
            UCHAR uTTHubAddr= m_address;
            UCHAR uTTHubPort= port;
            GetUSB2TT(&uTTHubAddr,&uTTHubPort);
            pControlPipe = CreateControlPipe( &usbEndpointZeroDescriptor,
                                             fIsLowSpeed, fIsHighSpeed ,0,
                                             uTTHubAddr,uTTHubPort,
                                             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 pi

⌨️ 快捷键说明

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