📄 atapipcmcia.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:
atapipcmcia.c
Abstract:
WINCE driver code for PCMCIA ATA Disk cards
Functions:
Notes:
--*/
// TODO: Currently the PCMCIA also shows up as removable. This component probably needs to overload id or we have a flag in the Disk structure indicating that it is
// TODO: a PCMCIA disk
#include "atamain.h"
#include "atapipcmcia.h"
#if 0
#define TRY_FOR_8BIT
static TCHAR *g_szPCMCIAVolumeName = TEXT("Storage Card");
HMODULE g_hPcmciaDll = NULL;
REGISTERCLIENT g_pfnCardRegisterClient= NULL;
DEREGISTERCLIENT g_pfnCardDeregisterClient= NULL;
GETFIRSTTUPLE g_pfnCardGetFirstTuple= NULL;
GETNEXTTUPLE g_pfnCardGetNextTuple= NULL;
GETTUPLEDATA g_pfnCardGetTupleData= NULL;
GETPARSEDTUPLE g_pfnCardGetParsedTuple= NULL;
REQUESTWINDOW g_pfnCardRequestWindow= NULL;
RELEASEWINDOW g_pfnCardReleaseWindow= NULL;
MAPWINDOW g_pfnCardMapWindow= NULL;
REQUESTCONFIG g_pfnCardRequestConfiguration= NULL;
RELEASECONFIG g_pfnCardReleaseConfiguration= NULL;
REQUESTIRQ g_pfnCardRequestIRQ= NULL;
RELEASEIRQ g_pfnCardReleaseIRQ= NULL;
REQUESTSOCKETMASK g_pfnCardRequestSocketMask= NULL;
RELEASESOCKETMASK g_pfnCardReleaseSocketMask= NULL;
GETSTATUS g_pfnCardGetStatus= NULL;
DWORD g_dwMemGran; // memory granularity from CardMapMemory (usually 1)
typedef BOOL (WINAPI *GETSYSPOWER)(PSYSTEM_POWER_STATUS_EX pSystemPowerStatusEx, BOOL fUpdate);
GETSYSPOWER g_pfnGetSystemPowerStatusEx = NULL;
static BOOL isVoltageNear (USHORT supply, USHORT demand)
{
// Some cards don't report any power usage! They probably mean to be 5V.
if (demand == 0)
demand = 50;
// True iff demand is in [0.9*supply, supply]
// We need this because some cards ask for a nominal voltage of 3.0 V
// rather than 3.3 V, and then don't specify min and peak values.
// The 0.9 constant is arbitrary but sufficient for the 3.0/3.3 comparison
// without matching the 5 V entries.
return (demand <= supply && demand >= 9*supply/10);
}
//
// InitPcmciaDll - LoadLibrary(PCMCIA.DLL) and GetProcAddress necessary entrypoints
//
BOOL InitPcmciaDll(VOID)
{
HMODULE hCoreDll;
hCoreDll = (HMODULE)LoadLibrary(TEXT("COREDLL.DLL"));
if (hCoreDll != NULL) {
g_pfnGetSystemPowerStatusEx = (GETSYSPOWER)GetProcAddress(hCoreDll, TEXT("GetSystemPowerStatusEx"));
FreeLibrary(hCoreDll);
}
g_hPcmciaDll = LoadLibrary(TEXT("PCMCIA.DLL"));
if (g_hPcmciaDll) {
g_pfnCardRegisterClient = (REGISTERCLIENT)GetProcAddress(g_hPcmciaDll, TEXT("CardRegisterClient"));
g_pfnCardDeregisterClient = (DEREGISTERCLIENT)GetProcAddress(g_hPcmciaDll, TEXT("CardDeregisterClient"));
g_pfnCardGetFirstTuple = (GETFIRSTTUPLE)GetProcAddress(g_hPcmciaDll, TEXT("CardGetFirstTuple"));
g_pfnCardGetNextTuple = (GETNEXTTUPLE)GetProcAddress(g_hPcmciaDll, TEXT("CardGetNextTuple"));
g_pfnCardGetTupleData = (GETTUPLEDATA)GetProcAddress(g_hPcmciaDll, TEXT("CardGetTupleData"));
g_pfnCardGetParsedTuple = (GETPARSEDTUPLE)GetProcAddress(g_hPcmciaDll, TEXT("CardGetParsedTuple"));
g_pfnCardRequestWindow = (REQUESTWINDOW)GetProcAddress(g_hPcmciaDll, TEXT("CardRequestWindow"));
g_pfnCardReleaseWindow = (RELEASEWINDOW)GetProcAddress(g_hPcmciaDll, TEXT("CardReleaseWindow"));
g_pfnCardMapWindow = (MAPWINDOW)GetProcAddress(g_hPcmciaDll, TEXT("CardMapWindow"));
g_pfnCardRequestConfiguration = (REQUESTCONFIG)GetProcAddress(g_hPcmciaDll, TEXT("CardRequestConfiguration"));
g_pfnCardReleaseConfiguration = (RELEASECONFIG)GetProcAddress(g_hPcmciaDll, TEXT("CardReleaseConfiguration"));
g_pfnCardRequestIRQ = (REQUESTIRQ)GetProcAddress(g_hPcmciaDll, TEXT("CardRequestIRQ"));
g_pfnCardReleaseIRQ = (RELEASEIRQ)GetProcAddress(g_hPcmciaDll, TEXT("CardReleaseIRQ"));
g_pfnCardRequestSocketMask = (REQUESTSOCKETMASK)GetProcAddress(g_hPcmciaDll, TEXT("CardRequestSocketMask"));
g_pfnCardReleaseSocketMask = (RELEASESOCKETMASK)GetProcAddress(g_hPcmciaDll, TEXT("CardReleaseSocketMask"));
g_pfnCardGetStatus = (GETSTATUS)GetProcAddress(g_hPcmciaDll, TEXT("CardGetStatus"));
}
if ((g_hPcmciaDll == NULL) ||
(g_pfnCardRegisterClient == NULL) ||
(g_pfnCardDeregisterClient == NULL) ||
(g_pfnCardGetFirstTuple == NULL) ||
(g_pfnCardGetNextTuple == NULL) ||
(g_pfnCardGetTupleData == NULL) ||
(g_pfnCardGetParsedTuple == NULL) ||
(g_pfnCardRequestWindow == NULL) ||
(g_pfnCardReleaseWindow == NULL) ||
(g_pfnCardMapWindow == NULL) ||
(g_pfnCardRequestConfiguration == NULL) ||
(g_pfnCardReleaseConfiguration == NULL) ||
(g_pfnCardRequestIRQ == NULL) ||
(g_pfnCardReleaseIRQ == NULL) ||
(g_pfnCardRequestSocketMask == NULL) ||
(g_pfnCardReleaseSocketMask == NULL) ||
(g_pfnCardGetStatus == NULL)) {
DEBUGMSG(ZONE_INIT, (TEXT("ATAPIPCMCIA: InitPcmciaDll() failed!\r\n")));
return FALSE;
}
hCoreDll = (HMODULE)LoadLibrary(TEXT("COREDLL.DLL"));
if (hCoreDll != NULL) {
g_pfnGetSystemPowerStatusEx = (GETSYSPOWER)GetProcAddress(hCoreDll, TEXT("GetSystemPowerStatusEx"));
FreeLibrary(hCoreDll);
}
return TRUE;
} // InitPcmciaDll
//
// Function to detect an ATA device. This detection relies on the fact that
// device.exe has already determined there is a disk device in this socket by
// looking at the CISTPL_FUNCID tuple. This function will look at the CISTPL_FUNCE
// tuples to see if it is an ATA device.
//
// Return TRUE if there is an ATA device in the specified socket; FALSE if not.
BOOL ATADetect(CARD_SOCKET_HANDLE hSock)
{
DWORD status;
UCHAR buf[sizeof(CARD_DATA_PARMS) + 256];
PCARD_TUPLE_PARMS pParms;
PCARD_DATA_PARMS pTuple;
PUCHAR pData;
if (!g_hPcmciaDll) { // Check to se if we have already initialized our PCMCIA pointers
if (!InitPcmciaDll()) {
// If we can't initialize bail out
return FALSE;
}
}
//
// A type 1 CISTPL_FUNCE will tell if it is an ATA device.
//
pParms = (PCARD_TUPLE_PARMS)buf;
pParms->hSocket = hSock;
pParms->uDesiredTuple = CISTPL_FUNCE;
pParms->fAttributes = 0;
status = g_pfnCardGetFirstTuple(pParms);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_INIT, (TEXT("ATAPIPCMCIA:CardGetFirstTuple returned %d\r\n"), status));
return FALSE;
}
while (status == CERR_SUCCESS) {
pTuple = (PCARD_DATA_PARMS)buf;
pTuple->uBufLen = sizeof(buf) - sizeof(CARD_DATA_PARMS);
pTuple->uTupleOffset = 0;
status = g_pfnCardGetTupleData(pTuple);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_INIT, (TEXT("DEVLOAD: CardGetTupleData returned %d\r\n"), status));
return FALSE;
}
pData = buf + sizeof(CARD_DATA_PARMS);
//
// If the CISTPL_FUNCE is type 1 and its data is 1, then it is an ATA device
//
if ((pData[0] == 1) && (pData[1] == 1)) {
return TRUE;
}
status = g_pfnCardGetNextTuple(pParms);
} // while
return FALSE;
} // ATADetect
//
// Detection modules entrypoint. Device.exe will call here to give this
// driver a chance to detect a newly inserted card.
//
// Return NULL if undetected or device key name of driver to load.
//
EXTERN_C PTSTR PCMCIADetectATA(CARD_SOCKET_HANDLE hSock, UCHAR ucDevType, PTSTR szDevKey, DWORD dwKeyLen)
{
DEBUGMSG( ZONE_INIT, (TEXT("PCMCIADetectATA hSock=%08X ucDevType=%02X szDevKey=%s dwKeyLen=%ld\r\n"), hSock, ucDevType, szDevKey, dwKeyLen));
if (ucDevType == PCCARD_TYPE_FIXED_DISK) {
if (ATADetect(hSock) == TRUE) {
_tcscpy(szDevKey, TEXT("ATAPI"));
return szDevKey;
}
}
return NULL;
}
#ifdef DEBUG
typedef struct _EVENT_NAME_TBL {
CARD_EVENT EventCode;
PTSTR pEventName;
} EVENT_NAME_TBL, *PEVENT_NAME_TBL;
#define LAST_EVENT_CODE ((CARD_EVENT) -1)
//
// Table of callback event codes and their names.
// NOTE: The names with ! at the end are not expected.
//
EVENT_NAME_TBL g_EventNames[] = {
{ CE_BATTERY_DEAD, TEXT("CE_BATTERY_DEAD") },
{ CE_BATTERY_LOW, TEXT("CE_BATTERY_LOW") },
{ CE_CARD_LOCK, TEXT("CE_CARD_LOCK") },
{ CE_CARD_READY, TEXT("CE_CARD_READY") },
{ CE_CARD_REMOVAL, TEXT("CE_CARD_REMOVAL") },
{ CE_CARD_UNLOCK, TEXT("CE_CARD_UNLOCK") },
{ CE_EJECTION_COMPLETE, TEXT("CE_EJECTION_COMPLETE!") },
{ CE_EJECTION_REQUEST, TEXT("CE_EJECTION_REQUEST!") },
{ CE_INSERTION_COMPLETE, TEXT("CE_INSERTION_COMPLETE!") },
{ CE_INSERTION_REQUEST, TEXT("CE_INSERTION_REQUEST!") },
{ CE_PM_RESUME, TEXT("CE_PM_RESUME!") },
{ CE_PM_SUSPEND, TEXT("CE_PM_SUSPEND!") },
{ CE_EXCLUSIVE_COMPLETE, TEXT("CE_EXCLUSIVE_COMPLETE") },
{ CE_EXCLUSIVE_REQUEST, TEXT("CE_EXCLUSIVE_REQUEST") },
{ CE_RESET_PHYSICAL, TEXT("CE_RESET_PHYSICAL") },
{ CE_RESET_REQUEST, TEXT("CE_RESET_REQUEST") },
{ CE_CARD_RESET, TEXT("CE_CARD_RESET") },
{ CE_MTD_REQUEST, TEXT("CE_MTD_REQUEST!") },
{ CE_CLIENT_INFO, TEXT("CE_CLIENT_INFO!") },
{ CE_TIMER_EXPIRED, TEXT("CE_TIMER_EXPIRED!") },
{ CE_SS_UPDATED, TEXT("CE_SS_UPDATED!") },
{ CE_WRITE_PROTECT, TEXT("CE_WRITE_PROTECT") },
{ CE_CARD_INSERTION, TEXT("CE_CARD_INSERTION") },
{ CE_RESET_COMPLETE, TEXT("CE_RESET_COMPLETE") },
{ CE_ERASE_COMPLETE, TEXT("CE_ERASE_COMPLETE!") },
{ CE_REGISTRATION_COMPLETE, TEXT("CE_REGISTRATION_COMPLETE") },
{ LAST_EVENT_CODE, TEXT("Unknown Event!") },
};
PTSTR
FindEventName(
CARD_EVENT EventCode
)
{
PEVENT_NAME_TBL pEvent = g_EventNames;
while (pEvent->EventCode != LAST_EVENT_CODE) {
if (pEvent->EventCode == EventCode) {
return pEvent->pEventName;
}
pEvent++;
}
return pEvent->pEventName;
}
#endif // DEBUG
//
// This is the PCMCIA callback function specified in CardRegisterClient.
// PCMCIA indicates card insertions and removals by calling this function.
//
STATUS PcmciaCallBack(CARD_EVENT EventCode, CARD_SOCKET_HANDLE hSock, PCARD_EVENT_PARMS pParms)
{
CPCMCIADisk *pDisk = (CPCMCIADisk *)pParms->uClientData;
DebugBreak();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -