?? pdsocket.cpp
字號:
//
// 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.
Module Name:
Abstract:
Platform dependent PCMCIA initialization functions
Notes:
--*/
#include <windows.h>
#include <types.h>
#include <socksv2.h>
#include <memory.h>
#include <ceddk.h>
#include <nkintr.h>
#include "PDSocket.h"
//
// @doc DRIVERS
//
#define REG_CHIP_REVISION 0x00
#define REG_INTERFACE_STATUS 0x01
#define REG_POWER_CONTROL 0x02
#define REG_INTERRUPT_AND_GENERAL_CONTROL 0x03
#define REG_CARD_STATUS_CHANGE 0x04
#define REG_STATUS_CHANGE_INT_CONFIG 0x05
#define REG_GENERAL_CONTROL 0x16
#define REG_GLOBAL_CONTROL 0x1E
#define REG_FIFO_CTRL 0x17
//
// Interface status register 0x01
//
#define STS_BVD1 0x01
#define STS_BVD2 0x02
#define STS_CD1 0x04
#define STS_CD2 0x08
#define STS_WRITE_PROTECT 0x10
#define STS_CARD_READY 0x20
#define STS_CARD_POWER_ON 0x40
#define STS_GPI 0x80
//
// Power and RESETDRV control register 0x02
//
#define PWR_VPP1_BIT0 0x01
#define PWR_VPP1_BIT1 0x02
#define PWR_VPP2_BIT0 0x04
#define PWR_VPP2_BIT1 0x08
#define PWR_VCC_POWER 0x10
#define PWR_AUTO_POWER 0x20
#define PWR_RESUME_RESET 0x40
#define PWR_OUTPUT_ENABLE 0x80
//
// Interrupt and general control register 0x03
//
#define INT_IRQ_BIT0 0x01
#define INT_IRQ_BIT1 0x02
#define INT_IRQ_BIT2 0x04
#define INT_IRQ_BIT3 0x08
#define INT_ENABLE_MANAGE_INT 0x10
#define INT_CARD_IS_IO 0x20
#define INT_CARD_NOT_RESET 0x40
#define INT_RING_INDICATE_ENABLE 0x80
//
// Card Status change register 0x04
//
#define CSC_BATTERY_DEAD_OR_STS_CHG 0x01
#define CSC_BATTERY_WARNING 0x02
#define CSC_READY_CHANGE 0x04
#define CSC_DETECT_CHANGE 0x08
#define CSC_GPI_CHANGE 0x10
//
// Card Status change interrupt configuration register 0x05
//
#define CFG_BATTERY_DEAD_ENABLE 0x01
#define CFG_BATTERY_WARNING_ENABLE 0x02
#define CFG_READY_ENABLE 0x04
#define CFG_CARD_DETECT_ENABLE 0x08
#define CFG_MANAGEMENT_IRQ_BIT0 0x10
#define CFG_MANAGEMENT_IRQ_BIT1 0x20
#define CFG_MANAGEMENT_IRQ_BIT2 0x40
#define CFG_MANAGEMENT_IRQ_BIT3 0x80
//
// MISC Control 1 register 0x16
//
#define MISC1_5V_DETECT 0x01
#define MISC1_VCC_33 0x02
#define MISC1_PM_IRQ 0x04
#define MISC1_PS_IRQ 0x08
#define MISC1_SPK_ENABLE 0x10
#define MISC1_INPACK_ENABLE 0x80
//
// FIFO Control register 0x17
//
#define FIFO_EMPTY_WRITE 0x80
//
// MISC Control 2 register 0x1E
//
#define MISC2_BFS 0x01
#define MISC2_LOW_POWER_MODE 0x02
#define MISC2_SUSPEND 0x04
#define MISC2_5V_CORE 0x08
#define MISC2_LED_ENABLE 0x10
#define MISC2_3STATE_BIT7 0x20
#define MISC2_IRQ15_RIOUT 0x80
//
// Global control register 0x1E
//
#define GCR_POWER_DOWN 0x01
#define GCR_LEVEL_MODE_INT 0x02
#define GCR_WRITE_BACK_ACK 0x04
#define GCR_PULSE_IRQ14 0x08
// more PD6710 specific flags
#define REG_CARD_IO_MAP0_OFFSET_L 0x36
#define REG_CARD_IO_MAP0_OFFSET_H 0x37
#define REG_CARD_IO_MAP1_OFFSET_L 0x38
#define REG_CARD_IO_MAP1_OFFSET_H 0x39
#define REG_SETUP_TIMING0 0x3a
#define REG_CMD_TIMING0 0x3b
#define REG_RECOVERY_TIMING0 0x3c
#define REG_SETUP_TIMING1 0x3d
#define REG_CMD_TIMING1 0x3e
#define REG_RECOVERY_TIMING1 0x3f
#define REG_LAST_INDEX REG_RECOVERY_TIMING1
#define EVENT_MASK_WRITE_PROTECT 0x0001 // write protect change
#define EVENT_MASK_CARD_LOCK 0x0002 // card lock change
#define EVENT_MASK_EJECT_REQ 0x0004 // ejection request
#define EVENT_MASK_INSERT_REQ 0x0008 // insertion request
#define EVENT_MASK_BATTERY_DEAD 0x0010 // battery dead
#define EVENT_MASK_BATTERY_LOW 0x0020 // battery low
#define EVENT_MASK_CARD_READY 0x0040 // ready change
#define EVENT_MASK_CARD_DETECT 0x0080 // card detect change
#define EVENT_MASK_POWER_MGMT 0x0100 // power management change
#define EVENT_MASK_RESET 0x0200 // card resets
#define EVENT_MASK_STATUS_CHANGE 0x0400 // card generated status change interrupts
//////////////////////////////////////////////////////////////////////////
//#define PCMCIA_DRIVER_KEY TEXT("Drivers\\PCMCIA")
#define IRQ_VALUE_NAME TEXT("Irq")
#define CHIPSET_VALUE_NAME TEXT("Chipset")
#define DEVICEID_VALUE_NAME TEXT("DeviceID")
#define POLLEDDEVICES_VALUE_NAME TEXT("PolledDevices")
#define CSC_SYSINTR_VALUE_NAME TEXT("CSCSysIntr")
#define CSC_IRQ_VALUE_NAME TEXT("CSCIrq")
#define POLL_TIMEOUT_NAME TEXT("PollTimeout")
#define POLLING_MODE_NAME TEXT("PollingMode")
#define DISABLE_SOCKET_NAME TEXT("DisableSocket")
#define CHIPSET_ID_CNT 32
#define CHIPSET_ID_LEN ((CHIPSET_ID_CNT * 9) + 1)
const SS_POWER_ENTRY CPcmciaCardSocket::m_rgPowerEntries[NUM_POWER_ENTRIES] =
{
{ 0, PWR_SUPPLY_VCC | PWR_SUPPLY_VPP1 | PWR_SUPPLY_VPP2 },
{ 33, PWR_SUPPLY_VCC },
{ 50, PWR_SUPPLY_VCC | PWR_SUPPLY_VPP1 | PWR_SUPPLY_VPP2 },
{ 120, PWR_SUPPLY_VPP1 | PWR_SUPPLY_VPP2 }
};
DWORD CPcmciaCardSocket::ms_dwSocketLastIndex = 1;
CPcmciaCardSocket::CPcmciaCardSocket( CPcmciaBusBridge* pBridge )
{
m_pBridge = pBridge;
m_dwSocketIndex = 0;
while( m_dwSocketIndex == 0 )
{
m_dwSocketIndex = ( DWORD )
InterlockedIncrement( ( LONG * ) &ms_dwSocketLastIndex );
//Make it is it does not exist.
CPcmciaCardSocket* pSocket = GetSocket( ( HANDLE ) m_dwSocketIndex );
if( pSocket != NULL )
{
// Duplicated , Retry.
m_dwSocketIndex = 0;
pSocket->DeRef();
}
}
DEBUGCHK( m_pBridge );
while( m_pBridge->LockOwner( 1000 ) != TRUE )
{
DEBUGCHK( FALSE );
}
DEBUGMSG( ZONE_INIT,
( TEXT( "CARDBUS: CPcmciaCardSocket (Socket=%d Index=%d) Created\r\n" ),
GetSlotNumber(),
GetSocketHandle() ) );
}
CPcmciaCardSocket::~CPcmciaCardSocket()
{
m_pBridge->ReleaseOwner();
DEBUGMSG( ZONE_INIT,
( TEXT( "CARDBUS: CPcmciaCardSocket (Socket=%d Index=%d) Deleted\r\n" ),
GetSlotNumber(),
GetSocketHandle() ) );
}
STATUS CPcmciaCardSocket::GetPowerEntry( PDWORD pdwNumOfEnery,
PSS_POWER_ENTRY pPowerEntry )
{
STATUS status = CERR_BAD_ARGS;
if( pdwNumOfEnery != NULL && pPowerEntry != NULL )
{
DWORD dwNumOfCopied = min( *pdwNumOfEnery, NUM_POWER_ENTRIES );
if( dwNumOfCopied != 0 )
{
memcpy( pPowerEntry,
m_rgPowerEntries,
dwNumOfCopied * sizeof( SS_POWER_ENTRY ) );
*pdwNumOfEnery = dwNumOfCopied;
status = CERR_SUCCESS;
}
}
return status;
}
UINT16 CPcmciaCardSocket::GetSocketNo()
{
return m_pBridge->GetSocketNo( GetSlotNumber() );
};
CPcmciaBusBridge::CPcmciaBusBridge( LPCTSTR RegPath ) : CPCCardBusBridgeBase( RegPath ),
CMiniThread( 0,
TRUE )
{
m_fPCICCritSecInitialized = false;
m_pCardBusResource = NULL;
m_hISTEvent = NULL;
m_dwSocketLowBound = 0;
m_dwSocketHighBound = NUM_SLOTS - 1;
for( UINT8 nSocket = m_dwSocketLowBound;
nSocket <= m_dwSocketHighBound;
nSocket++ )
{
m_rguSocketNum[nSocket] = ( WORD ) - 1;
m_prgCardSocket[nSocket] = NULL;
m_rgfPowerCycleEvent[nSocket] = FALSE;
m_rgfCardInjectEvent[nSocket] = FALSE;
}
m_fPollingMode = TRUE;
};
CPcmciaBusBridge::~CPcmciaBusBridge()
{
// Terminate IST
m_bTerminated = TRUE;
if( m_hISTEvent )
{
SetEvent( m_hISTEvent );
ThreadTerminated( 1000 );
if( !m_fPollingMode )
{
InterruptDisable( m_dwCSCSysIntr );
}
CloseHandle( m_hISTEvent );
};
for( UINT8 nSocket = GetSocketLowBound();
nSocket <= GetSocketHighBound();
nSocket++ )
{
if( m_rguSocketNum[nSocket] != ( UINT16 ) - 1 )
{
GetSocketNumberFromCS( nSocket, FALSE );
m_rguSocketNum[nSocket] = ( UINT16 ) - 1;
}
RemovePcmciaCardSocket( nSocket );
}
if( m_pCardBusResource != NULL )
{
delete m_pCardBusResource;
}
if( m_fPCICCritSecInitialized )
{
DeleteCriticalSection( &m_PCICCritSec );
}
}
BOOL CPcmciaBusBridge::InstallIsr()
{
UINT8 tmp;
for( UINT8 nSocket = GetSocketLowBound();
nSocket <= GetSocketHighBound();
nSocket++ )
{
//
// Disable interrupts
//
WritePCICRegister( nSocket, REG_INTERRUPT_AND_GENERAL_CONTROL, 0 );
// Management int -> edge triggering(PULSE), System int -> LEVEL triggering
WritePCICRegister( nSocket, REG_GENERAL_CONTROL, MISC1_VCC_33|MISC1_PM_IRQ|MISC1_SPK_ENABLE );
UINT8 bPat = ReadPCICRegister( nSocket, REG_GENERAL_CONTROL );
// 25Mhz_bypass,low_power_dynamic,IRQ12=drive_LED
WritePCICRegister( nSocket, REG_GLOBAL_CONTROL, MISC2_LOW_POWER_MODE|MISC2_LED_ENABLE);
// before configuring timing register, FIFO should be cleared.
WritePCICRegister( nSocket, REG_FIFO_CTRL, FIFO_EMPTY_WRITE); //Flush FIFO
//default access time is 300ns
WritePCICRegister( nSocket, REG_SETUP_TIMING0, 5); //80ns(no spec)
WritePCICRegister( nSocket, REG_CMD_TIMING0, 20); //320ns(by spec,25Mhz clock)
WritePCICRegister( nSocket, REG_RECOVERY_TIMING0, 5); //80ns(no spec)
//default access time is 300ns
WritePCICRegister( nSocket, REG_SETUP_TIMING1, 2); //80ns(no spec)
WritePCICRegister( nSocket, REG_CMD_TIMING1, 8); //320ns(by spec,25Mhz clock)
WritePCICRegister( nSocket, REG_RECOVERY_TIMING1, 2); //80ns(no spec)
if( !m_fPollingMode )
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -