📄 sdclient.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.
//
// Copyright (c) 2002 BSQUARE Corporation. All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE
// SD Client Driver api implementation
#include "SDCardDDK.h"
#include <creg.hxx>
#include "SDBusDriver.h"
#include "devload.h"
///////////////////////////////////////////////////////////////////////////////
// DeleteClientDevice - deletes the client device
// Input: pDevice - the device
// Output:
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
VOID CSDBusDriver::DeleteClientDevice(PSDCARD_DEVICE_CONTEXT pDevice)
{
DeleteCriticalSection(&pDevice->DeviceCritSection);
if (Device_SD_IO == pDevice->DeviceType) {
// check for the product information string
if (NULL != pDevice->SDCardInfo.SDIOInformation.pFunctionInformation) {
SDFreeMemory(pDevice->SDCardInfo.SDIOInformation.pFunctionInformation);
}
// check for common information
if (NULL != pDevice->SDCardInfo.SDIOInformation.pCommonInformation) {
if (NULL != pDevice->SDCardInfo.SDIOInformation.pCommonInformation->pProductInformation) {
// cleanup the product information
SDFreeMemory(pDevice->SDCardInfo.SDIOInformation.pCommonInformation->pProductInformation);
}
SDFreeMemory(pDevice->SDCardInfo.SDIOInformation.pCommonInformation);
}
}
pDevice->dwSig = 0xbadbad;
// delete the device
SDFreeMemory(pDevice);
}
///////////////////////////////////////////////////////////////////////////////
// RegisterClientDevice - register a client device
// Input: pDevice - the device being registered
// pContext - device specific context
// pInfo - client registration information
//
// Output: pDevice
// Notes:
// returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDBusDriver::RegisterClientDevice(PSDCARD_DEVICE_CONTEXT pDevice,
PVOID pContext,
PSDCARD_CLIENT_REGISTRATION_INFO pInfo)
{
PREFAST_DEBUGCHK(pDevice);
PREFAST_DEBUGCHK(pInfo);
// save the registration information
_tcsncpy(pDevice->ClientName, pInfo->ClientName, dim(pDevice->ClientName) - 1);
pDevice->ClientName[dim(pDevice->ClientName) - 1] = 0; // Null-terminate
pDevice->pDeviceContext = pContext;
pDevice->pSlotEventCallBack = pInfo->pSlotEventCallBack;
pDevice->ClientFlags = pInfo->ClientFlags;
return SD_API_STATUS_SUCCESS;
}
extern "C"
SD_API_STATUS
SDGetClientFunctions(
PSDCARD_API_FUNCTIONS pFunctions
)
{
SD_API_STATUS status = SD_API_STATUS_INVALID_PARAMETER;
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDGetClientFunctions: +Init\n")));
if ( pFunctions && (pFunctions->dwSize == sizeof(*pFunctions)) ) {
pFunctions->pSDRegisterClient = SDRegisterClient__X;
pFunctions->pSDSynchronousBusRequest = SDSynchronousBusRequest__X;
pFunctions->pSDBusRequest = SDBusRequest__X;
pFunctions->pSDFreeBusRequest = SDFreeBusRequest__X;
pFunctions->pSDCardInfoQuery = SDCardInfoQuery__X;
pFunctions->pSDReadWriteRegistersDirect = SDReadWriteRegistersDirect__X;
pFunctions->pSDCancelBusRequest = SDCancelBusRequest__X;
pFunctions->pSDGetTuple = SDGetTuple__X;
pFunctions->pSDIOConnectInterrupt = SDIOConnectInterrupt__X;
pFunctions->pSDIODisconnectInterrupt = SDIODisconnectInterrupt__X;
pFunctions->pSDSetCardFeature = SDSetCardFeature__X;
status = SD_API_STATUS_SUCCESS;
}
else {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDGetClientFunctions: Invalid parameter\n")));
}
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDGetClientFunctions: -Init\n")));
return status;
}
///////////////////////////////////////////////////////////////////////////////
// GetDeviceFunctionPtrs - Get Device function pointers
// Input:
// Output: pFunctions - funtions
// Notes:
// Deprecated. Only legacy client drivers will call this function from
// the legacy SDRegisterClient function.
///////////////////////////////////////////////////////////////////////////////
static VOID GetLegacyDeviceFunctionPtrs(PSDCARD_API_FUNCTIONS pFunctions)
{
// Legacy SD Card Api function structure definition
typedef struct LEGACY_SDCARD_API_FUNCTIONS {
PSD_REGISTER_CLIENT pSDRegisterClient;
PSD_SYNCHRONOUS_BUS_REQUEST pSDSynchronousBusRequest;
PSDBUS_REQUEST pSDBusRequest;
PSD_FREE_BUS_REQUEST pSDFreeBusRequest;
PSD_CARD_INFO_QUERY pSDCardInfoQuery;
PSD_READ_WRITE_REGISTER_DIRECT pSDReadWriteRegistersDirect;
PSD_CANCEL_BUS_REQUEST pSDCancelBusRequest;
PSD_GET_TUPLE pSDGetTuple;
PSD_IO_CONNECT_INTERRUPT pSDIOConnectInterrupt;
PSD_IO_DISCONNECT_INTERRUPT pSDIODisconnectInterrupt;
PSD_SET_CARD_FEATURE pSDSetCardFeature;
} *PLEGACY_SDCARD_API_FUNCTIONS;
// Convert to legacy structure.
PLEGACY_SDCARD_API_FUNCTIONS pLegacyFunctions =
(PLEGACY_SDCARD_API_FUNCTIONS) pFunctions;
if (pLegacyFunctions) {
pLegacyFunctions->pSDRegisterClient = SDRegisterClient__X;
pLegacyFunctions->pSDSynchronousBusRequest = SDSynchronousBusRequest__X;
pLegacyFunctions->pSDBusRequest = SDBusRequest__X;
pLegacyFunctions->pSDFreeBusRequest = SDFreeBusRequest__X;
pLegacyFunctions->pSDCardInfoQuery = SDCardInfoQuery__X;
pLegacyFunctions->pSDReadWriteRegistersDirect = SDReadWriteRegistersDirect__X;
pLegacyFunctions->pSDCancelBusRequest = SDCancelBusRequest__X;
pLegacyFunctions->pSDGetTuple = SDGetTuple__X;
pLegacyFunctions->pSDIOConnectInterrupt = SDIOConnectInterrupt__X;
pLegacyFunctions->pSDIODisconnectInterrupt = SDIODisconnectInterrupt__X;
pLegacyFunctions->pSDSetCardFeature = SDSetCardFeature__X;
}
else {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("GetLegacyDeviceFunctionPtrs: Invalid parameter\n")));
}
}
///////////////////////////////////////////////////////////////////////////////
// NotifyClient - notify the device of a slot event
// Input: pDevice - the device
// Event - the event
// Output:
// Notes:
// returns PSDCARD_DEVICE_CONTEXT
///////////////////////////////////////////////////////////////////////////////
VOID NotifyClient(PSDCARD_DEVICE_CONTEXT pDevice, SD_SLOT_EVENT_TYPE Event)
{
PVOID pEventData = NULL; // event data (defaults to NULL)
DWORD eventDataLength = 0; // event data length
switch (Event) {
case SDCardEjected :
break;
default:
DEBUGCHK(FALSE);
}
__try {
// make sure this callback can be called
if (NULL != pDevice->pDeviceFolder) {
if (NULL != pDevice->pSlotEventCallBack) {
pDevice->pSlotEventCallBack ((SD_DEVICE_HANDLE)pDevice,
pDevice->pDeviceContext,
Event,
pEventData,
eventDataLength);
}
}
} __except (SDProcessException(GetExceptionInformation())) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: slot event callback resulted in an exception \n")));
}
}
///////////////////////////////////////////////////////////////////////////////
// ValidateClientHandle - validate the client's device handle
//
// Notes: No need to reference count since the client cannot delete the
// object.
///////////////////////////////////////////////////////////////////////////////
BOOL ValidateClientHandle(PSDCARD_DEVICE_CONTEXT pDevice)
{
BOOL fRet = TRUE;
__try {
if (pDevice->dwSig != VALID_DEVICE_CONTEXT_SIG) {
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBus: Invalid device handle 0x%X (sig 0x%X)\r\n"),
pDevice, pDevice->dwSig));
fRet = FALSE;
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDBus: Exception checking device handle 0x%X\r\n"),
pDevice));
fRet = FALSE;
}
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
// AllocateDeviceContext - allocate a new device context
// Input:
// Output:
// Notes:
// returns PSDCARD_DEVICE_CONTEXT
///////////////////////////////////////////////////////////////////////////////
PSDCARD_DEVICE_CONTEXT CSDBusDriver::AllocateDeviceContext()
{
PSDCARD_DEVICE_CONTEXT pDevice;
pDevice = (PSDCARD_DEVICE_CONTEXT)SDAllocateMemoryWithTag(sizeof(SDCARD_DEVICE_CONTEXT),
SD_BUS_DRIVER_TAG);
if (NULL != pDevice) {
// The use of pGetDeviceFunctions is deprecated, but we still set
// it for legacy reasons.
pDevice->pvReserved = GetLegacyDeviceFunctionPtrs;
pDevice->dwSig = VALID_DEVICE_CONTEXT_SIG;
InitializeCriticalSection(&pDevice->DeviceCritSection);
pDevice->pSystemContext = (PVOID)this;
// set default access clocks
pDevice->SDCardInfo.SDMMCInformation.DataAccessReadClocks = SD_UNSPECIFIED_ACCESS_CLOCKS;
pDevice->SDCardInfo.SDMMCInformation.DataAccessWriteClocks = SD_UNSPECIFIED_ACCESS_CLOCKS;
DEBUGCHK(ValidateClientHandle(pDevice));
}
return pDevice;
}
///////////////////////////////////////////////////////////////////////////////
// GetNewHCNumber - get a unique host controller number
// Input:
// Output:
// Notes:
// returns the first unique number.
///////////////////////////////////////////////////////////////////////////////
DWORD CSDBusDriver::GetNewHCNumber()
{
DWORD dwNumber;
AcquireLock();
// Start looking at 0
for (dwNumber = 0; dwNumber <= MAXDWORD; ++dwNumber) {
PLIST_ENTRY pListEntry = m_HostControllerListHead.Flink;
while (pListEntry != &m_HostControllerListHead) {
PSDBUS_HC_CONTEXT pHCContext =
CONTAINING_RECORD(pListEntry, SDBUS_HC_CONTEXT, ListEntry);
if (pHCContext->dwHCNumber == dwNumber) {
// This number is not unique. Continue to next dwNumber.
break;
}
pListEntry = pListEntry->Flink;
}
if (pListEntry == &m_HostControllerListHead) {
// This number is unique.
break;
}
}
ReleaseLock();
return dwNumber;
}
///////////////////////////////////////////////////////////////////////////////
// GetCustomRegPath - get a device's custom registry path
// Input: pDevice - the device instance
// cchPath - number of characters in pPath
// BasePath - if TRUE return only the card's base path not
// its function path (single or multifunction I/O cards)
// this parameter is ignored for memory cards
// Output: pPath - the path returned
// Notes:
// returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -