?? socket.c
字號:
//
// 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.
Copyright (c) 2002. Samsung Electronics, co. ltd All rights reserved.
Module Name:
socket.c
Abstract:
Rev:
2001.12.21 : Bug Fixup (kwangyoon LEE, kwangyoon@samsung.com)
2001.12.12 : add S3C2400 Specific codes (kwangyoon LEE, kwangyoon@samsung.com)
Notes:
--*/
#include <windows.h>
#include <types.h>
#include <cardserv.h>
#include <sockserv.h>
#include <sockpd.h>
#include <memory.h>
#include <pc.h>
//#define FORCE_POLLING 1
//
// CEPC PCMCIA Socket Services Socket APIs:
// PDCardInquireSocket
// PDCardGetSocket
// PDCardSetSocket
// PDCardInquireAdapter
//
#define NUM_SOCKETS 1
#define NUM_POWER_ENTRIES 4
#define VCC_DEFAULT_INDEX 2
//
// @doc DRIVERS
//
PDCARD_ADAPTER_INFO v_AdapterInfo = {
1, // memory granularity (for production platforms, this should be 1)
0, // adapter capabilities
8, // cache line size in 32-bit words
NUM_POWER_ENTRIES
};
PDCARD_POWER_ENTRY v_PowerEntries[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 }
};
PDCARD_SOCKET_STATE v_SockState[NUM_SOCKETS] = {
{
SOCK_CAP_IO,
#ifdef FORCE_POLLING
EVENT_MASK_BATTERY_DEAD|EVENT_MASK_BATTERY_LOW|
#else
EVENT_MASK_BATTERY_DEAD|EVENT_MASK_BATTERY_LOW|EVENT_MASK_CARD_DETECT|
#endif
EVENT_MASK_WRITE_PROTECT, // status change interrupt mask
0, // present socket state
0, // control and indicators
0, // interface type
0, // Vcc
0, // Vpp1
0 // Vpp2
},
};
extern DWORD g_Irq; // PCMCIA IRQ set in init.c
//
// Set the socket controller registers to initial state with no card inserted.
//
VOID InitSocketNoCard(UINT32 uSocket, BOOL bUserMode)
{
UCHAR tmp;
UINT32 status;
UINT32 i;
UINT32 first, last;
PDCARD_WINDOW_STATE WinState;
DEBUGMSG (1,(TEXT("++InitSocketNoCard #%x\n\r"), uSocket));
PCICIndex(uSocket, REG_POWER_CONTROL);
PCICDataWrite(PWR_AUTO_POWER);
#if 0
tmp = CFG_CARD_DETECT_ENABLE | (UCHAR)(g_Irq << 4);
PCICIndex(uSocket, REG_STATUS_CHANGE_INT_CONFIG);
PCICDataWrite(tmp);
#else
// PD6710 specific code to enable management interrupt(routed to -INTR)
tmp = CFG_CARD_DETECT_ENABLE;
PCICIndex(uSocket, REG_STATUS_CHANGE_INT_CONFIG);
PCICDataWrite(tmp);
// Enable Manage Interrupt
PCICIndex(0, REG_INTERRUPT_AND_GENERAL_CONTROL);
tmp = PCICDataRead();
tmp |= INT_ENABLE_MANAGE_INT;
PCICDataWrite(tmp);
#endif
//
// Disable the I/O windows
//
first = (uSocket == 0) ? SOCKET0_FIRST_IO_WINDOW : SOCKET1_FIRST_IO_WINDOW;
last = first + 2;
for (i = first; i < last; i++) {
status = PDCardGetWindow(i, &WinState);
if (status == CERR_SUCCESS) {
WinState.fState &= ~WIN_STATE_ENABLED;
WinState.uOffset = 0;
// set the high bit in the window index if we are in kernel-mode
PDCardSetWindow(bUserMode ? i : (i|ADP_STATE_KERNEL_MODE), &WinState);
}
}
DEBUGMSG (1,(TEXT("--InitSocketNoCard\n\r")));
}
//
// PDCardGetSocket
//
// @func STATUS | PDCardGetSocket | Get the socket state of the specified socket.
// @rdesc Returns one of the CERR_* return codes in cardserv.h.
//
// @comm This function reads the specified socket's state and returns it in
// the PDCARD_SOCKET_STATE structure.
//
STATUS
PDCardGetSocket(
UINT32 uSocket, // @parm Socket number (first socket is 0)
PPDCARD_SOCKET_STATE pState // @parm Pointer to PDCARD_SOCKET_STATE structure
)
{
UINT8 tmp;
PPDCARD_SOCKET_STATE pPDDState;
if (uSocket >= NUM_SOCKETS) {
return CERR_BAD_SOCKET;
}
pPDDState = &v_SockState[uSocket];
EnterCriticalSection(&g_PCIC_Crit);
pPDDState->fNotifyEvents = 0; // Start off with nothing
//
// First acknowledge any status change interrupts
//
PCICIndex(uSocket, REG_CARD_STATUS_CHANGE);
tmp = PCICDataRead();
/*
DEBUGMSG(ZONE_PDD,
(TEXT("PDCardGetSocket(%d) REG_CARD_STATUS_CHANGE(0x%x) = 0x%x\r\n"),
uSocket, REG_CARD_STATUS_CHANGE, tmp));
*/
//
// Figure out the socket state
//
PCICIndex(uSocket, REG_INTERFACE_STATUS);
tmp = PCICDataRead();
/*
DEBUGMSG(ZONE_PDD,
(TEXT("PDCardGetSocket(%d) REG_INTERFACE_STATUS(0x%x) = 0x%x\r\n"),
uSocket, REG_INTERFACE_STATUS, tmp));
*/
if ((tmp & (STS_CD1|STS_CD2)) == (STS_CD1|STS_CD2)) {
pPDDState->fNotifyEvents |= EVENT_MASK_CARD_DETECT;
// DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) CARD_DETECT\r\n"), uSocket));
} else {
// DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) ~CARD_DETECT\r\n"), uSocket));
InitSocketNoCard(uSocket, FALSE);
goto pcgs_exit;
}
#ifdef NOT_IMPLEMENTED
switch (tmp & (STS_BVD1|STS_BVD2)) {
case STS_BVD1:
pPDDState->fNotifyEvents |= EVENT_MASK_BATTERY_LOW;
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) BATTERY_LOW\r\n"), uSocket));
break;
case STS_BVD2:
case 0:
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) BATTERY_DEAD\r\n"), uSocket));
pPDDState->fNotifyEvents |= EVENT_MASK_BATTERY_DEAD;
break;
}
#endif NOT_IMPLEMENTED
if (tmp & STS_WRITE_PROTECT) {
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) WRITE_PROTECT\r\n"), uSocket));
pPDDState->fNotifyEvents |= EVENT_MASK_WRITE_PROTECT;
}
if (tmp & STS_CARD_READY) {
// DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetSocket(%d) CARD_READY\r\n"), uSocket));
pPDDState->fNotifyEvents |= EVENT_MASK_CARD_READY;
}
pcgs_exit:
memcpy(pState, pPDDState, sizeof(PDCARD_SOCKET_STATE));
LeaveCriticalSection(&g_PCIC_Crit);
return CERR_SUCCESS;
} // PDDCardGetSocket
//
// PDCardSetSocket
//
// @func STATUS | PDCardSetSocket | Set the socket state of the specified socket.
// @rdesc Returns one of the CERR_* return codes in cardserv.h.
//
// @comm This function sets the specified socket's state and adjusts the socket
// controller appropriately.
// PDCardGetSocketState will usually be called first and adjustments will
// be made to the PDCARD_SOCKET_STATE structure before PDCardSetSocketState
// is called. This avoids duplicated socket state on different layers and
// it avoids unintentionally setting socket parameters.
//
// @xref <f PDCardGetSocketState>
//
STATUS
PDCardSetSocket(
UINT32 uSocket, // @parm Socket number (first socket is 0)
PPDCARD_SOCKET_STATE pState // @parm Pointer to PDCARD_SOCKET_STATE structure
)
{
UINT8 tmp, intctl;
PPDCARD_SOCKET_STATE pPDDState;
STATUS ret;
int t;
DEBUGMSG(ZONE_PDD, (TEXT("PDCardSetSocket(%d) entered\r\n"), uSocket));
if (uSocket >= NUM_SOCKETS) {
ret = CERR_BAD_SOCKET;
goto pcss_fail;
}
//
// Check socket power level indexes
//
if ((pState->fVcc & SOCK_VCC_LEVEL_MASK) >= NUM_POWER_ENTRIES ||
!(v_PowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].fSupply & PWR_SUPPLY_VCC)) {
ret = CERR_BAD_VCC;
goto pcss_fail;
}
if (pState->uVpp1 >= NUM_POWER_ENTRIES || pState->uVpp2 >= NUM_POWER_ENTRIES ||
!(v_PowerEntries[pState->uVpp1].fSupply & PWR_SUPPLY_VPP1) ||
!(v_PowerEntries[pState->uVpp2].fSupply & PWR_SUPPLY_VPP2)) {
ret = CERR_BAD_VPP;
goto pcss_fail;
}
EnterCriticalSection(&g_PCIC_Crit);
PCICIndex(uSocket, REG_INTERFACE_STATUS);
tmp = PCICDataRead();
if ((tmp & (STS_CD1|STS_CD2)) != (STS_CD1|STS_CD2)) {
DEBUGMSG(ZONE_PDD,
(TEXT("PDCardSetSocket(%d) No card inserted\r\n"), uSocket));
InitSocketNoCard(uSocket, FALSE);
goto pcss_exit;
}
pPDDState = &v_SockState[uSocket];
//
// Set the status change interrupt sources
//
#if 1
tmp = (UCHAR)(g_Irq << 4); // CFG_MANAGEMENT_IRQ_BIT* bits will be set
#else
tmp =0;
#endif
if (pState->fInterruptEvents & EVENT_MASK_CARD_DETECT) {
tmp |= CFG_CARD_DETECT_ENABLE;
}
if (pState->fInterruptEvents & EVENT_MASK_BATTERY_DEAD) {
tmp |= CFG_BATTERY_DEAD_ENABLE;
}
if (pState->fInterruptEvents & EVENT_MASK_BATTERY_LOW) {
tmp |= CFG_BATTERY_WARNING_ENABLE;
}
if (pState->fIREQRouting & SOCK_IREQ_ENABLE) {
// tmp |= CFG_READY_ENABLE;
}
PCICIndex(uSocket, REG_STATUS_CHANGE_INT_CONFIG);
PCICDataWrite(tmp);
DEBUGMSG(ZONE_PDD,
(TEXT("PDCardSetSocket(%d) REG_STATUS_CHANGE_INT_CONFIG(0x%x) = 0x%x\r\n"),
uSocket, REG_STATUS_CHANGE_INT_CONFIG, tmp));
#if 1
// PD6710 specific code to enable management interrupt(routed to -INTR)
PCICIndex(0, REG_INTERRUPT_AND_GENERAL_CONTROL);
tmp = PCICDataRead();
tmp |= INT_ENABLE_MANAGE_INT;
PCICDataWrite(tmp);
#endif
//
// Enable or disable IREQ interrupts
//
PCICIndex(uSocket, REG_INTERRUPT_AND_GENERAL_CONTROL);
tmp = PCICDataRead();
tmp &= (UCHAR)~g_Irq; // Turn off INT_IRQ_BIT* bits
if (pState->fIREQRouting & SOCK_IREQ_ENABLE) {
DEBUGMSG(1, (TEXT("Enable IREQ interrupts #%x\r\n"), g_Irq));
tmp |= ((UCHAR)g_Irq)|INT_CARD_NOT_RESET; // Turn on INT_IRQ_BIT* bits
} else {
tmp |= INT_CARD_NOT_RESET;
}
PCICDataWrite(tmp);
DEBUGMSG(1,
(TEXT("PDCardSetSocket voltage = %d\r\n"),
v_PowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel));
// ignore Vpp
if ((pState->fVcc & SOCK_VCC_LEVEL_MASK) != (pPDDState->fVcc & SOCK_VCC_LEVEL_MASK)) {
//
// Set socket power as requested.
//
switch (v_PowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel) {
case 0:
PCICIndex(uSocket, REG_POWER_CONTROL);
PCICDataWrite(0);
goto pcss_exit; // this is what it used to do so I won't change it
case 33:
PCICIndex(uSocket, 0x16);//REG_MISC_CONTROL_1);
PCICDataWrite(0x02); // enable 3.3V
DEBUGMSG(1, (TEXT("set to 3.3V\r\n")));
break;
case 50:
PCICIndex(uSocket, 0x16);//REG_MISC_CONTROL_1);
if (PCICDataRead() & 0x01) // i.e., if we detect a 5V card:
{
PCICDataWrite(0x00); // disable 3.3V (i.e., use 5V)
DEBUGMSG(1, (TEXT("set to 5V\r\n")));
}
else
{
// this is a 3.3V ONLY card and mustn't be powered at 5V
// so ignore the command; we'd assert here save that card
// services will attempt to apply 5V to read the CIS.
PCICDataWrite(0x02); // enable 3.3V
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -