📄 sdhcenum.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
// Host Controller Enumeration and APIs
#include "SDBusDriver.h"
///////////////////////////////////////////////////////////////////////////////
// SDHCDAllocateContext - Allocate an HCD Context
//
// Input: NumberOfSlots - Number of slots
// Output:
// ppExternalHCContext - caller supplied storage for the host context
// Return: SD_API_STATUS
// Notes:
// Host controller drivers must allocate an HC context for the bus driver.
// When a host controller driver is unloaded it must free this context
// returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDHCDAllocateContext__X(DWORD NumberOfSlots,
PSDCARD_HC_CONTEXT *ppExternalHCContext)
{
PSDBUS_HC_CONTEXT pHCContext; // new host context
// check parameters, at least one slot must be allocated
if ((ppExternalHCContext == NULL) || (NumberOfSlots == 0)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCDAllocateContext: invalid parameter \n")));
return SD_API_STATUS_INVALID_PARAMETER;
}
// allocate host context
DWORD cbHCContext = sizeof(SDBUS_HC_CONTEXT) +
(sizeof(SDBUS_HC_SLOT_CONTEXT)) * (NumberOfSlots - 1);
pHCContext = (PSDBUS_HC_CONTEXT) LocalAlloc(LPTR, cbHCContext);
if (pHCContext == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCDAllocateContext: Failed to allocate memory \n")));
return SD_API_STATUS_NO_MEMORY;
}
pHCContext->dwSig = VALID_HC_CONTEXT_SIG;
// set the number of slots
pHCContext->NumberOfSlots = NumberOfSlots;
// initialize critical section
InitializeCriticalSection(&pHCContext->HCCritSection);
// return the context
*ppExternalHCContext = (PSDCARD_HC_CONTEXT) pHCContext;
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDDeleteContext - Delete an HCD context
//
// Input: pExternalHCContext - Host Context to delete
// Output:
// Return:
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDDeleteContext__X(PSDCARD_HC_CONTEXT pExternalHCContext)
{
PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
if (pHCContext == NULL) {
DEBUG_CHECK(FALSE, (TEXT("SDHCDDeleteContext - NULL host context!")));
return;
}
DEBUGCHK( pHCContext->dwSig == VALID_HC_CONTEXT_SIG ||
pHCContext->dwSig == DEREGISTERED_HC_CONTEXT_SIG );
// delete the critical section
DeleteCriticalSection(&pHCContext->HCCritSection);
pHCContext->dwSig = 0xbadbad;
// free the context
LocalFree(pHCContext);
}
///////////////////////////////////////////////////////////////////////////////
// CleanUpSlotWorkItems - Clean up slot work items
//
// Input: pExternalHCContext - host context
//
// Output:
// Return:
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID CleanUpSlotWorkItems(PSDBUS_HC_CONTEXT pHCContext)
{
ULONG ii; // loop count
volatile SDBUS_HC_SLOT_CONTEXT *pSlotContext; // slot
// clean up work item objects
for (ii = 0; ii < pHCContext->NumberOfSlots; ii++) {
pSlotContext = SDHCGetSlotContext(pHCContext, ii);
if (pSlotContext->pWorkItem != NULL) {
// check to see if the device has been cleaned up yet
// the work item cleans up the device in another thread
// context
while (pSlotContext->hDevice != NULL) {
// sleep to allow device cleanup to proceed before we
// kill the work item.
// only when the work item clears this variable can
// we cleanup the work item.
Sleep(DEVICE_CLEANUP_POLLING_INTERVAL);
}
delete (CSDWorkItem *)pSlotContext->pWorkItem;
pSlotContext->pWorkItem = NULL;
}
}
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDRegisterHostController - Register a host controller with the bus driver
//
// Input: pExternalHCContext - Allocated Host controller context
//
// Output:
// Return: SD_API_STATUS
// Notes:
//
// the caller must allocate a host controller context and
// initialize the various parameters
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDHCDRegisterHostController__X(PSDCARD_HC_CONTEXT pExternalHCContext)
{
SD_API_STATUS status; // intermediate status
CSDBusDriver *pBusDriver; // the bus driver
PSDBUS_HC_SLOT_CONTEXT pSlotContext; // the slot context
CSDWorkItem *pDispatcher; // new work item for each slot
BOOL initFailed = FALSE; // initialization flag
PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
status = SD_API_STATUS_UNSUCCESSFUL;
if (pHCContext == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
return SD_API_STATUS_INVALID_PARAMETER;
}
if (pHCContext->dwVersion != SDCARD_HC_BUS_INTERFACE_VERSION) {
DEBUGMSG(SDCARD_ZONE_ERROR,
(TEXT("SDBusDriver: Host controller interface version (%x) does not match bus driver (%x)\n"),
pHCContext->dwVersion, SDCARD_HC_BUS_INTERFACE_VERSION));
return SD_API_STATUS_INVALID_PARAMETER;
}
DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);
// set the system context
pHCContext->pSystemContext = SDGetSystemContext();
if (pHCContext->pSystemContext == NULL) {
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDBusDriver: No System Context, bus driver may not have started \n")));
return SD_API_STATUS_BUS_DRIVER_NOT_READY;
}
pBusDriver = GetSDBusDriver(pHCContext);
// lock the bus
pBusDriver->AcquireLock();
// catch any exceptions in case the caller passed a bad structure
__try {
DWORD dwSlot;
// Note: Getting a new HC Number is protected by the critical section.
pHCContext->dwHCNumber = pBusDriver->GetNewHCNumber();
DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDBusDriver: Host Controller \"%s\" assigned number %d\n"),
pHCContext->HostControllerName, pHCContext->dwHCNumber));
// fill in the rest of the host controller context
for (dwSlot = 0; dwSlot < pHCContext->NumberOfSlots; dwSlot++) {
// get the slot context for this slot number and host controller
pSlotContext = SDHCGetSlotContext(pHCContext, dwSlot);
pSlotContext->SlotIndex = dwSlot;
pSlotContext->SlotState = SlotInactive;
pSlotContext->pHostController = pHCContext;
SDInitializeQueue(&pSlotContext->RequestQueue);
// get the capabilities of this slot
PSDCARD_HC_SLOT_INFO pSlotInfo = pSlotContext;
status = pHCContext->pSlotOptionHandler(pHCContext,
dwSlot, SDHCDGetSlotInfo, pSlotInfo, sizeof(*pSlotInfo));
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR,
(TEXT("SDBusDriver: Failed to get slot info for slot %u\n"), dwSlot));
initFailed = TRUE;
break;
}
// create work item object for each slot
pDispatcher = new CSDWorkItem(pBusDriver,
(PSD_WORK_ITEM_FUNC)CSDBusDriver::SlotStatusChange,
pBusDriver->GetDispatchPriority() + 1,
DEFAULT_MESSAGE_ENTRIES,
sizeof(SDCARD_HC_SLOT_EVENT));
if (NULL == pDispatcher) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to allocate event dispatcher \n")));
initFailed = TRUE;
break;
}
// start the work item
status = pDispatcher->StartWorkItem();
if (!SD_API_SUCCESS(status)){
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Dispatcher work item failed \n")));
initFailed = TRUE;
break;
}
pSlotContext->pWorkItem = (PVOID)pDispatcher;
}
if (initFailed) {
// clean up what we've initialized so far
CleanUpSlotWorkItems(pHCContext);
status = SD_API_STATUS_UNSUCCESSFUL;
} else {
// really register the host controller
status = pBusDriver->RegisterHostController(pHCContext);
}
pBusDriver->ReleaseLock();
} __except (SDProcessException(GetExceptionInformation())) {
pBusDriver->ReleaseLock();
// exception caught
status = SD_API_STATUS_UNSUCCESSFUL;
}
if (SD_API_SUCCESS(status)) {
// call the init handler of the host controller, now that the controller is
// registered
__try {
// call init handler
// at this point we can receive any asynch notifications from the host
// controller driver
status = pHCContext->pInitHandler(pHCContext);
} __except (SDProcessException(GetExceptionInformation())) {
// exception caught
status = SD_API_STATUS_UNSUCCESSFUL;
}
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Host Controller: %s Init Handler failed: 0x%08X \n"),
SDHCDGetHCName(pHCContext), status));
// lock the bus
pBusDriver->AcquireLock();
__try {
// clean up slot work items
CleanUpSlotWorkItems(pHCContext);
// deregister the controller
pBusDriver->DeregisterHostController(pHCContext);
pBusDriver->ReleaseLock();
} __except (SDProcessException(GetExceptionInformation())) {
pBusDriver->ReleaseLock();
// exception caught
status = SD_API_STATUS_UNSUCCESSFUL;
}
}
}
return status;
}
SD_API_STATUS
DoDeregisterHostController(PSDBUS_HC_CONTEXT pHCContext, BOOL fExternalCall)
{
PREFAST_DEBUGCHK(pHCContext);
SD_API_STATUS status = SD_API_STATUS_SUCCESS;
__try {
// call the deinit handler of the host controller
pHCContext->pDeinitHandler(pHCContext);
status = SD_API_STATUS_SUCCESS;
} __except (SDProcessException(GetExceptionInformation())) {
// exception caught
status = SD_API_STATUS_UNSUCCESSFUL;
}
if (!SD_API_SUCCESS(status)) {
return status;
}
if (SDGetSystemContext() == NULL && fExternalCall) {
// this should never happen
DEBUG_CHECK(FALSE, (TEXT("SDBusDriver: No System Context! \n")));
return SD_API_STATUS_BUS_DRIVER_NOT_READY;
}
pHCContext->dwSig = DEREGISTERED_HC_CONTEXT_SIG;
CSDBusDriver *pBusDriver = GetSDBusDriver(pHCContext);
// lock the bus driver
pBusDriver->AcquireLock();
__try {
// clean up slot work items
CleanUpSlotWorkItems(pHCContext);
status = pBusDriver->DeregisterHostController(pHCContext);
pBusDriver->ReleaseLock();
} __except (SDProcessException(GetExceptionInformation())) {
pBusDriver->ReleaseLock();
// exception caught
status = SD_API_STATUS_UNSUCCESSFUL;
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDDeregisterHostController - Deregister a host controller
//
// Input: pExternalHCContext - Host controller context that was previously registered
//
// Output:
// Return: SD_API_STATUS
// Notes:
// A host controller must call this api before deleting the HC context
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDHCDDeregisterHostController__X(PSDCARD_HC_CONTEXT pExternalHCContext)
{
PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
if (pHCContext == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
return SD_API_STATUS_INVALID_PARAMETER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -