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

📄 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 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft
// premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license
// agreement, you are not authorized to use this source code.
// For the terms of the license, please see the license agreement
// signed by you and Microsoft.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Module Name:
//     CDevice.cpp
// Abstract:
//     This file manages the USB devices
//
//                  CDevice (ADT)
//                /               \
//            CFunction        CHub (ADT)
//                            /          \
//                        CRootHub   CExternalHub
//
// Notes:
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2005-2006, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
//
//------------------------------------------------------------------------------



#include "cdevice.hpp"
#include "hcd.hpp"
#include <mx27_usbname.h>

#ifndef _PREFAST_
#pragma warning(disable: 4068) // Disable pragma warnings
#endif

#define STANDARD_REQUEST_TIMEOUT 500 // 500 Mili Second.
#define SPECIAL_REQUEST_TIMEOUT  1000*1*60 // 1 minutes 

// Global add for freescale
//DWORD DeviceAttachStatus = 0; // 0 - nothing, 1 - device attach, 2 - device detach, 3 - need to detach due to failure of recognition
HANDLE ghDetach;
extern "C" TCHAR *gfnGetOTGGroup(void);
extern "C" DWORD gfnIsOTGSupport(void);
//#ifdef DEBUG
//extern "C" TCHAR *GetUSBPortType(void);
//#endif
// address array variables - initially set to have address 0 used
// because it is reserved for the root hub (besides, no real device
// can permanently use addr0, since it is used at set address time)
// *******************************************************************
CDeviceGlobal::CDeviceGlobal( ):m_objCountdown(0)
//
// Purpose: Constructor for CDeviceGlobal
// 
// Parameters:
//
// Returns: Nothing
//
//********************************************************************
{

    m_dwFreeAddressArray[0]=0x00000001;
    m_dwFreeAddressArray[1] = m_dwFreeAddressArray[2] = m_dwFreeAddressArray[3] = 0x00000000;
    
    m_hUSBDInstance = NULL;
    m_pUSBDAttachProc = NULL;
    m_pUSBDDetachProc = NULL;
    m_pvHcdContext = NULL;
    m_pUSBDSelectConfigurationProc = NULL;
#ifdef DEBUG
    g_fAlreadyCalled = FALSE;
#endif // DEBUG
    //InitCritSec_Ex( &m_csAddress0Lock );
    InitializeCriticalSection( &m_csFreeAddressArrayLock );
};

//*******************************************************************
CDeviceGlobal::~CDeviceGlobal()
//
// Purpose: Destructor for CDeviceGlobal
// 
// Parameters:
//
// Returns: Nothing
//
//********************************************************************
{
    DeInitialize();
    // all devices, and hence all addresses, should have been freed by now
    DeleteCriticalSection( &m_csFreeAddressArrayLock );
    //DeleteCritSec_Ex( &m_csAddress0Lock );
}
// ******************************************************************
BOOL CDeviceGlobal::Initialize(IN PVOID pHcd)
//
// Purpose: Initialize any static variables associated with
//          CDevice, and establish link to USBD
//
// Parameters: pHcd - pointer to the Host Controller Driver object which
//                    we pass to USBD
//
// Returns: TRUE
//
// Notes: This function should be called only once from CHcd::Initialize
// ******************************************************************
{
    DEBUGMSG( ZONE_INIT, (TEXT("+CDeviceGlobal::Initialize\n")));
    m_pHcd=pHcd;
#ifdef DEBUG
    DEBUGCHK( !g_fAlreadyCalled );
    g_fAlreadyCalled = TRUE;
#endif // DEBUG

    DEBUGCHK( DWORD(8 * sizeof( m_dwFreeAddressArray )) == DWORD(USB_MAX_ADDRESS + 1) &&
              8 * sizeof( m_dwFreeAddressArray[0] ) == 32 &&
              m_dwFreeAddressArray[ 0 ] == 0x00000001 &&
              m_dwFreeAddressArray[ 1 ] == 0x00000000 &&
              m_dwFreeAddressArray[ 2 ] == 0x00000000 &&
              m_dwFreeAddressArray[ 3 ] == 0x00000000 );

    m_csAddress0Lock.Initialize();
    m_objCountdown.UnlockCountdown ();
    // establish links to USBD.dll
    {
        // this procedure is called to establish a link to USBD
        LPUSBD_HCD_ATTACH_PROC  lpHcdAttachProc = NULL;
        // this is defined in uhcddrv.cpp
        extern HCD_FUNCS gc_HcdFuncs;

        DEBUGCHK( m_pHcd != NULL &&
                  m_hUSBDInstance == NULL &&
                  m_pUSBDDetachProc == NULL &&
                  m_pUSBDAttachProc == NULL &&
                  m_pvHcdContext == NULL );

        m_hUSBDInstance = LoadDriver(TEXT("USBD.DLL"));
        if ( m_hUSBDInstance == NULL ) {
            DEBUGMSG(ZONE_ERROR,(TEXT("-CDevice::Initialize - Could not load USBD.DLL\r\n")));
            return FALSE;
        }
        lpHcdAttachProc = (LPUSBD_HCD_ATTACH_PROC) GetProcAddress(m_hUSBDInstance, TEXT("HcdAttach"));
        m_pUSBDAttachProc = (LPUSBD_ATTACH_PROC) GetProcAddress(m_hUSBDInstance, TEXT("HcdDeviceAttached"));
        m_pUSBDDetachProc = (LPUSBD_DETACH_PROC) GetProcAddress(m_hUSBDInstance, TEXT("HcdDeviceDetached"));
        m_pUSBDSelectConfigurationProc = (LPUSBD_SELECT_CONFIGURATION_PROC)GetProcAddress(m_hUSBDInstance, TEXT("HcdSelectConfiguration"));// Optional
        if ( m_pUSBDAttachProc == NULL ||
             m_pUSBDDetachProc == NULL ||
             lpHcdAttachProc == NULL ||
             (*lpHcdAttachProc)(m_pHcd, &gc_HcdFuncs,  &m_pvHcdContext) == FALSE ) {

            DEBUGMSG(ZONE_ERROR, (TEXT("-CDevice::Initialize - Could not establish USBD links\n")));
            return FALSE;
        }
        DEBUGCHK( m_pvHcdContext != NULL );
    }


    DEBUGMSG( ZONE_INIT, (TEXT("-CDevice::Initialize, success!\n")));
    return TRUE;
}

// ******************************************************************
void CDeviceGlobal::DeInitialize( )
//
// Purpose: Delete any static variables associated with CDevice
//
// Parameters: None
//
// Returns: Nothing
//
// Notes: This function should be called only once from CHcd::~CHcd
// ******************************************************************
{
    DEBUGMSG( ZONE_INIT, (TEXT("+CDevice::DeInitialize\n")));

#ifdef DEBUG
    DEBUGCHK(g_fAlreadyCalled == TRUE);
    g_fAlreadyCalled = FALSE;
#endif // DEBUG

    // wait for any stray detach threads
    // This can block waiting for a callback into a client driver to return.
    // Since callbacks aren't supposed to block this oughtn't cause deadlock,
    // but a misbehaving client driver can cause us serious grief.
    // Nonetheless, not waiting means we might free USBD.DLL while it's still in use.
    //DeleteCountdown(&m_objCountdown);
    m_objCountdown.WaitForCountdown( TRUE);

    // unload USBD.dll
    if ( m_hUSBDInstance ) {
        LPUSBD_HCD_DETACH_PROC lpHcdDetachProc;
        lpHcdDetachProc = (LPUSBD_HCD_DETACH_PROC) GetProcAddress(m_hUSBDInstance, TEXT("HcdDetach"));
        if ( lpHcdDetachProc != NULL ) {
            (*lpHcdDetachProc)(m_pvHcdContext);
        }
        FreeLibrary( m_hUSBDInstance );
        m_hUSBDInstance = NULL;
    }
    m_pUSBDAttachProc = NULL;
    m_pUSBDDetachProc = NULL;
    m_pvHcdContext = NULL;

    m_dwFreeAddressArray[0] = 0x00000001;
    m_dwFreeAddressArray[1] = m_dwFreeAddressArray[2] = m_dwFreeAddressArray[3] = 0x00000000;


    DEBUGMSG( ZONE_INIT, (TEXT("-CDevice::DeInitialize\n")));
}

// ******************************************************************
BOOL CDeviceGlobal::ReserveAddress( OUT UCHAR& rAddress )
//
// Purpose: Finds an unused USB address (1-127), marks it as used, and
//          returns the address
//
// Parameters: rAddress - OUT parameter, which is set to a free address
//
// Returns: TRUE if rAddress set to a valid free address, else FALSE
//
// Notes: Address 0 is permanently marked as used. This is reserved for
//        the root hub.
// ******************************************************************
{
    DEBUGMSG( ZONE_ATTACH && ZONE_VERBOSE, (TEXT("+CDeviceGlobal::ReserveAddress\n")) );

    BOOL fSuccess = FALSE;

    EnterCriticalSection( &m_csFreeAddressArrayLock );

    // the address has 7 bits:
    //
    // xxyyyyyb
    //
    // xxb is the index into the m_dwFreeAddressArray (0-3)
    // yyyyyb is the bit of the m_dwFreeAddressArray[xxb] DWORD
    // that the address corresponds to

    // address 0 should always be marked used
    DEBUGCHK(m_dwFreeAddressArray[0] & 1 );

    for ( UCHAR address = 1; address <= USB_MAX_ADDRESS; address++ ) {
        const UCHAR index = (address >> 5); // 5 == log base 2 of 32
        const UCHAR bit = address & (32 - 1); // 32 == # of bits in DWORD
        if ( (m_dwFreeAddressArray[ index ] & (1 << bit)) == 0 ) {
            // this address is free
            fSuccess = TRUE;
            rAddress = address;
            // mark address as used
            m_dwFreeAddressArray[ index ] |= (1 << bit);
            break;
        }
    }
    LeaveCriticalSection( &m_csFreeAddressArrayLock );

    DEBUGMSG( ZONE_ATTACH && ZONE_VERBOSE, (TEXT("-CDevice::ReserveAddress, returning rAddress %d, success = %d\n"), rAddress, fSuccess ) );
    return fSuccess;
}
// ******************************************************************
void CDeviceGlobal::FreeAddress( IN const UCHAR address )
//
// Purpose: Return address to the list of unused USB device addresses
//
// Parameters: address - address to free
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
{
    DEBUGMSG( ZONE_ATTACH && ZONE_VERBOSE, (TEXT("+CDeviceGlobal::FreeAddress - address = %d\n"), address) );

    EnterCriticalSection( &m_csFreeAddressArrayLock );

⌨️ 快捷键说明

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