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

📄 pcmciabridge.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 *
 * Copyright (C) 2003-2004, MOTOROLA, INC. All Rights Reserved
 * THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
 * BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
 * MOTOROLA, INC.
 *
 * Copyright (C) 2004, Freescale Semiconductor, Inc. All Rights Reserved
 * THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
 * BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
 * FREESCALE SEMICONDUCTOR, INC.
 *
 * Copyright (C) 2006, Freescale Semiconductor, Inc. All Rights Reserved
 * THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
 * BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
 * FREESCALE SEMICONDUCTOR, INC.
 //
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
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.
//
//
 *
 * 	File:			drivers/pccard/pcmciabridge.cpp
 * 	Purpose:		PCMCIA Controller Codes 
 *
 * 	Notes:		
 *
 * 	Author:	    	Kok Choon Kiat
 * 	Date:		10/01/2004
 *
 * 	Modifications:
 *  MM/DD/YYYY      Initials     	Change description 
 *  02/20/2006        ASH             Modifications done for MX31 BSP 
 */

#define __PCMCIABRIDGE_CPP__
#include "pcmciabridge.h"

// workaround for daughter card: PC_POE_B signal is inverted on TO2 and above
#undef PCMCIA_PC_POE_B_WORKAROUND

#define PCMCIA_DELAY_MULTIPLIER        1000

#define PCMCIADelay(delayTime)      \
{                                                               \
    volatile UINT32 delay = delayTime * PCMCIA_DELAY_MULTIPLIER;   \
    while(delay--);                                             \
}

PCSP_PCCARD_REGS g_vPcmciaReg;

//Main Control Class Constructor: Provides interface between card service and socket service layer
CPcmciaBusBridge::CPcmciaBusBridge( LPCTSTR RegPath ) : CPCCardBusBridgeBase( RegPath ),
					                CMiniThread( 0, TRUE )
{
	m_hISTEvent = NULL;
	m_uSocketNum = ( WORD ) - 1;
	m_pCardSocket = NULL;
	m_fPowerCycleEvent = FALSE;
	m_fCardInjectEvent = FALSE;
	m_fPollingMode = TRUE;
}

//Destructor
CPcmciaBusBridge::~CPcmciaBusBridge()
{
    // Terminate IST
    m_bTerminated = TRUE;
    if( m_hISTEvent )
    {
        SetEvent( m_hISTEvent );
        ThreadTerminated( 1000 );
        if( !m_fPollingMode )
        {
            InterruptDisable( m_dwCSCSysIntr );
        }
        CloseHandle( m_hISTEvent );
    };

	if( m_uSocketNum != ( UINT16 ) - 1 )
	{
	    GetSocketNumberFromCardService( FALSE );
	    m_uSocketNum = ( UINT16 ) - 1;
	}
	
	RemovePcmciaCardSocket();
}

BOOL CPcmciaBusBridge::InstallIsr()
{    
    // CreateIST Event
    m_hISTEvent = CreateEvent( 0, FALSE, FALSE, NULL );

    if( !m_fPollingMode )
    {
        // Run IST
        BOOL r = InterruptInitialize( m_dwCSCSysIntr, m_hISTEvent, 0, 0 );
        ASSERT( r );
    }
    return TRUE;
}


//------------------------------------------------------------------------------
//
// Function: GetRegistryConfig
//
// This function retrieves the initial settings from the registry
// NOTE: lpRegPath is assumed to be under HKEY_LOCAL_MACHINE
//
// Parameters:
//      None
//
// Returns:
//     ERROR_SUCCESS on success or a Win32 error code on failure
//
//------------------------------------------------------------------------------
DWORD CPcmciaBusBridge::GetRegistryConfig()
{
    DWORD dwRet = 1;
    DWORD dwSize, dwType, dwData;

    // get the PCMCIA windows configuration
    
    if( !LoadWindowsSettings() )
    {
        dwRet = ERROR_INVALID_DATA;
        goto grc_fail;
    }
    
    // get the polling mode value
    dwSize = sizeof( DWORD );
    if( !RegQueryValueEx( POLLING_MODE_NAME,
                          &dwType,
                          ( PUCHAR ) & dwData,
                          &dwSize ) )
    {
        m_fPollingMode = FALSE; // RegQueryValueEx failed, default to FALSE
    }
    else
    {
        m_fPollingMode = dwData ? TRUE : FALSE;
    }

    // get client interrupt configuration
    dwSize = sizeof( DWORD );
    if( RegQueryValueEx( CLIENT_IRQ_VALUE_NAME,
                          &dwType,
                          ( PUCHAR ) & dwData,
                          &dwSize ) )
    {
        m_dwClientSysIntr = SYSINTR_UNDEFINED;
        m_dwClientIrq = dwData;
        
        // check if we should automatically convert the IRQ to SYSINTR value
        dwSize = sizeof( DWORD );
        if( RegQueryValueEx( FORCE_CLIENT_SYSINTR_NAME,
                              &dwType,
                              ( PUCHAR ) & dwData,
                              &dwSize ) )
        {
            if( dwData )
            {
                // Convert the interrupt to a logical sysintr value.
                if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &m_dwClientIrq, sizeof(DWORD), &m_dwClientSysIntr, sizeof(DWORD), NULL))
                {
                    DEBUGMSG(1, (TEXT("PCMCIA: Failed to IOCTL_HAL_REQUEST_SYSINTR for client interrupt!\r\n")));
                    m_dwClientSysIntr = SYSINTR_UNDEFINED;
                    dwRet = ERROR_INVALID_DATA;
                    goto grc_fail;
                }
                m_dwClientIrq = (DWORD)-1;
            }
        }
    }
    else
    {  	
        // IRQ value was not specified, try to get the SYSINTR value
        dwSize = sizeof( DWORD );
        if( RegQueryValueEx( CLIENT_SYSINTR_VALUE_NAME,
                              &dwType,
                              ( PUCHAR ) & dwData,
                              &dwSize ) )
        {
            m_dwClientSysIntr = dwData;
            m_dwClientIrq = (DWORD)-1;
        }
        else
        {
            DEBUGMSG(1, (TEXT("PCMCIA: Failed to obtain client interrupt information!\r\n")));
            dwRet = ERROR_INVALID_DATA;
            goto grc_fail;
        }
    }

    m_dwCSCSysIntr = SYSINTR_UNDEFINED;
    m_dwCSCIrq = (DWORD)-1;

    dwSize = sizeof( DWORD );
    if( RegQueryValueEx( CSC_SYSINTR_VALUE_NAME,
                            &dwType,
                            ( PUCHAR ) & dwData,
                            &dwSize ) )
    {
        m_dwCSCSysIntr = dwData;
    }
    else
    {
        dwSize = sizeof( DWORD );
        if( !RegQueryValueEx( CSC_IRQ_VALUE_NAME,
                                &dwType,
                                ( PUCHAR ) & dwData,
                                &dwSize ) )
        {
            m_fPollingMode = TRUE;
        }
        else
        {
            m_dwCSCIrq = dwData;
		   	
            // Convert the interrupt to a logical sysintr value.
            if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &m_dwCSCIrq, sizeof(DWORD), &m_dwCSCSysIntr, sizeof(DWORD), NULL))
            {
                m_dwCSCSysIntr = SYSINTR_UNDEFINED;
                m_fPollingMode = TRUE;
            }
        }
    }

    // get the pooling timeout value
    dwSize = sizeof( DWORD );
    if( !RegQueryValueEx( POLL_TIMEOUT_NAME,
                          &dwType,
                          ( PUCHAR ) & dwData,
                          &dwSize ) )
    {
        // RegQueryValueEx failed; if pooling, set the timeout to 0.5 sec, otherwise set to INFINITE
        m_dwPollTimeout = m_fPollingMode ? 500 : INFINITE;
    }
    else
    {
        m_dwPollTimeout = dwData;
    }

    dwRet = ERROR_SUCCESS;

    grc_fail : 
		DEBUGMSG( ZONE_PDD, (TEXT("m_fPollingMode=0x%X m_dwCSCIrq=0x%X m_dwCSCSysIntr=0x%X\r\n"), m_fPollingMode, m_dwCSCIrq, m_dwCSCSysIntr));	

		return dwRet;
}   // GetRegistryConfig

//------------------------------------------------------------------------------
//
// Function: InitCardBusBridge
//
// This function initializes the PCMCIA socket controller after getting the registry settings
// service layer
//
// Parameters:
//      None
//
// Returns:
//    TRUE on success or a FALSE on failure
//
//------------------------------------------------------------------------------
BOOL CPcmciaBusBridge::InitCardBusBridge( void )
{
    DWORD dwRet;

    // Get registry information
    if( ( dwRet = GetRegistryConfig() ) != ERROR_SUCCESS )
    {
        DEBUGMSG( ZONE_PDD,
                  ( TEXT( "PDCardInitServices GetRegistryConfig failed %d\r\n" ),
                    dwRet ) );
        return FALSE;
    }

    PHYSICAL_ADDRESS phyAddr;

    phyAddr.QuadPart = CSP_BASE_REG_PA_PCMCIA;
    g_vPcmciaReg = (PCSP_PCCARD_REGS)MmMapIoSpace(phyAddr, sizeof(CSP_PCCARD_REGS), FALSE);
    if(g_vPcmciaReg  ==  NULL)   
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("\tVirtualCopy failed to map g_vPcmciaReg\n\r")));
	goto err_initialize;
    }
        
    // Initialize GPIO
    if(!InitGpio())
        goto err_initialize;
		

	// Do software reset - then clear bit after it's done 
	PCMCIA_RESET_SOCKET();
	PCMCIADelay(100);
	PCMCIA_SET_SOCKET();

	g_vPcmciaReg->PER = 0;	// Disable all the interrupts
	
	// Invalidate all the windows
	for(int num_win= 0; num_win < PCMCIA_NUM_WINDOWS; num_win++) 
	{
		g_vPcmciaReg->PBR[num_win]  = 0;
		g_vPcmciaReg->POR[num_win]  = 0;
		g_vPcmciaReg->POFR[num_win] = 0;
	}
	
	SetPccPower(0, FALSE);	// Set GPIO pins to 0 volt	
	
	g_vPcmciaReg->PGCR = PCMCIA_PGCR_LOWPWRMODE;	// Set to Lower Power mode

   	InstallIsr();
	
	return TRUE;

err_initialize:
	
	DeinitGpio();
	
	if(g_vPcmciaReg) {
		MmUnmapIoSpace((void *)g_vPcmciaReg, 0);
		g_vPcmciaReg = NULL;
	}
	return FALSE;
 
}

//------------------------------------------------------------------------------
//
// Function: Init
//
// This function initializes the socket service driver and establishes the connection with card
// service layer
//
// Parameters:
//      None
//
// Returns:
//    TRUE on success or a FALSE on failure
//
//------------------------------------------------------------------------------
BOOL CPcmciaBusBridge::Init()
{
	//DebugBreak();
	
    if( !loadPcCardEntry() )
    {
        return FALSE;
    }
	
    if( !InitCardBusBridge() )
    {
        return FALSE;
    }

    if( !GetSocketNumberFromCardService(TRUE ) )
    {
	m_uSocketNum = ( UINT16 ) - 1;
	return FALSE;
    }
   
    m_uPriority = DEFAULT_PRIORITY;	 // Set Tread Priority.
	
    DWORD dwRegPriority = 0;
	
    if( GetRegValue( RegPriority256,
                     ( PBYTE ) & dwRegPriority,
                     sizeof( dwRegPriority ) ) )
    {
        m_uPriority = ( UINT ) dwRegPriority;
    }	
    
    CeSetPriority( m_uPriority );	// Get Thread Priority from Registry and Set it
	
    m_bTerminated = FALSE;

    ThreadStart();

    return TRUE;
}

//------------------------------------------------------------------------------
//
// Function: CreatePCMCIASocket
//
// This function creates an object of type CPcmciaSocket which virtually maps to the PCMCIA
// socket/slot. This object keeps track of socket state and related events, also socket service
// API implementations
//
// Parameters:
//      None
//
// Returns:
//    Pointer to CPcmciaObject on success or  NULL on failure
//
//------------------------------------------------------------------------------
CPcmciaSocket* CPcmciaBusBridge::CreatePCMCIASocket(  )
{
    CPcmciaSocket* pNewSocket = new CPcmciaSocket( this );
	
    if( pNewSocket != NULL )
    {	
        if( pNewSocket->CardInitWindow( pNewSocket ) )
        {
            return pNewSocket;
        }
        else
        {
            delete pNewSocket;
        }

		return pNewSocket;
    }
	
    return NULL;
}

//------------------------------------------------------------------------------
//
// Function: ObjectBySocket
//
// This function returns a reference to an esicting object of type CPcmciaSocket 
// withe the help of handle information
//
// Parameters:
//      hSocket
//          [in]   Handle which reference to a PCMCIA slot
//
// Returns:
//    Pointer to CPcmciaObject on success or  NULL on failure
//
//------------------------------------------------------------------------------
CPcmciaSocket* CPcmciaBusBridge::ObjectBySocket( HANDLE hSocket )
{
	CPcmciaSocket*  pObject = NULL;
	
	DEBUGMSG( 1, ( TEXT( "CPcmciaBusBridge::ObjectBySocket  m_dwArraySize=0x%x\r\n" ), m_dwArraySize) );
	    
	Lock();
	for( DWORD dwIndex = 0; dwIndex < m_dwArraySize; dwIndex++ )
	{

⌨️ 快捷键说明

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