?? sdhc.cpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
// Copyright (c) 2002 BSQUARE Corporation. All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE
// SDHC controller driver implementation
#include "SDCardDDK.h"
#include "SDHC.h"
#ifndef SHIP_BUILD
#define STR_MODULE _T("CSDHCBase::")
#define SETFNAME(name) LPCTSTR pszFname = STR_MODULE name _T(":")
#else
#define SETFNAME(name)
#endif
#ifdef DEBUG
#define MAKE_OPTION_STRING(x) _T(#x)
const LPCTSTR CSDHCBase::sc_rgpszOptions[SDHCDSlotOptionCount] = {
MAKE_OPTION_STRING(SDHCDSetSlotPower),
MAKE_OPTION_STRING(SDHCDSetSlotInterface),
MAKE_OPTION_STRING(SDHCDEnableSDIOInterrupts),
MAKE_OPTION_STRING(SDHCDDisableSDIOInterrupts),
MAKE_OPTION_STRING(SDHCDAckSDIOInterrupt),
MAKE_OPTION_STRING(SDHCDGetWriteProtectStatus),
MAKE_OPTION_STRING(SDHCDQueryBlockCapability),
MAKE_OPTION_STRING(SDHCDSetClockStateDuringIdle),
MAKE_OPTION_STRING(SDHCDSetSlotPowerState),
MAKE_OPTION_STRING(SDHCDGetSlotPowerState),
MAKE_OPTION_STRING(SDHCDWakeOnSDIOInterrupts),
MAKE_OPTION_STRING(SDHCDGetSlotInfo),
MAKE_OPTION_STRING(SDHCDSetSlotInterfaceEx),
MAKE_OPTION_STRING(SDHCAllocateDMABuffer),
MAKE_OPTION_STRING(SDHCFreeDMABuffer),
};
#endif
extern LPCTSTR HostControllerName;
CSDHCBase::CSDHCBase(
)
: m_regDevice()
{
m_hBusAccess = NULL;
m_cSlots = 0;
m_pSlots = NULL;
m_pSlotInfos = NULL;
m_pHCDContext = NULL;
m_interfaceType = InterfaceTypeUndefined;
m_dwBusNumber = INVALID_BUS_NUMBER;
m_hISRHandler = NULL;
m_dwSysIntr = SYSINTR_UNDEFINED;
m_dwPriority = 0;
m_hevInterrupt = NULL;
m_htIST = NULL;
m_cpsCurrent = D0;
m_fHardwareInitialized = FALSE;
m_fRegisteredWithBusDriver = FALSE;
m_fDriverShutdown = FALSE;
m_fInterruptInitialized = FALSE;
}
CSDHCBase::~CSDHCBase(
)
{
// We call PreDeinit just in case we are not being destroyed by
// a call to SHC_PreDeinit.
PreDeinit();
if (m_fHardwareInitialized) {
DeinitializeHardware();
}
if (m_pHCDContext) {
// Cleanup the host context
SDHCDDeleteContext(m_pHCDContext);
}
if (m_pSlots) delete [] m_pSlots;
if (m_pSlotInfos) LocalFree(m_pSlotInfos);
if (m_hBusAccess) CloseBusAccessHandle(m_hBusAccess);
}
BOOL
CSDHCBase::Init(
LPCTSTR pszActiveKey
)
{
BOOL fRet = FALSE;
SD_API_STATUS status;
HKEY hkDevice = NULL;
hkDevice = OpenDeviceKey(pszActiveKey);
if (!hkDevice || !m_regDevice.Open(hkDevice, _T(""))) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Failed to open device key\n")));
goto EXIT;
}
// Get a handle to our parent bus.
m_hBusAccess = CreateBusAccessHandle(pszActiveKey);
if (m_hBusAccess == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Could not get handle to parent\n")));
goto EXIT;
}
m_cSlots = DetermineSlotCount();
if (!CheckSlotCount(m_cSlots)) {
goto EXIT;
}
PREFAST_ASSERT(m_cSlots <= SDHC_MAX_SLOTS);
m_pSlotInfos = (PSDHC_SLOT_INFO) LocalAlloc(LPTR,
sizeof(SDHC_SLOT_INFO) * m_cSlots);
if (m_pSlotInfos == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate slot info objects\n")));
goto EXIT;
}
status = SDHCDAllocateContext(m_cSlots, &m_pHCDContext);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate context : 0x%08X \n"),
status));
goto EXIT;
}
// Set our extension
m_pHCDContext->pHCSpecificContext = this;
if (!InitializeHardware()) {
goto EXIT;
}
// Allocate slot objects
m_pSlots = AllocateSlotObjects(m_cSlots);
if (m_pSlots == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate slot objects\n")));
goto EXIT;
}
// Initialize the slots
for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
PSDHC_SLOT_INFO pSlotInfo = &m_pSlotInfos[dwSlot];
PCSDHCSlotBase pSlot = GetSlot(dwSlot);
if (!pSlot->Init(dwSlot, pSlotInfo->pucRegisters, m_pHCDContext,
m_dwSysIntr, m_hBusAccess, m_interfaceType, m_dwBusNumber, &m_regDevice)) {
goto EXIT;
}
}
// set the host controller name
SDHCDSetHCName(m_pHCDContext, TEXT("HostControllerName"));
// set init handler
SDHCDSetControllerInitHandler(m_pHCDContext, CSDHCBase::SDHCInitialize);
// set deinit handler
SDHCDSetControllerDeinitHandler(m_pHCDContext, CSDHCBase::SDHCDeinitialize);
// set the Send packet handler
SDHCDSetBusRequestHandler(m_pHCDContext, CSDHCBase::SDHCBusRequestHandler);
// set the cancel I/O handler
SDHCDSetCancelIOHandler(m_pHCDContext, CSDHCBase::SDHCCancelIoHandler);
// set the slot option handler
SDHCDSetSlotOptionHandler(m_pHCDContext, CSDHCBase::SDHCSlotOptionHandler);
// These values must be set before calling SDHCDRegisterHostController()
// because they are used during that call.
m_dwPriority = m_regDevice.ValueDW(SDHC_PRIORITY_KEY,
SDHC_CARD_CONTROLLER_PRIORITY);
// now register the host controller
status = SDHCDRegisterHostController(m_pHCDContext);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to register host controller: %0x08X \n"),
status));
goto EXIT;
}
m_fRegisteredWithBusDriver = TRUE;
fRet = TRUE;
EXIT:
if (hkDevice) RegCloseKey(hkDevice);
return fRet;
}
SD_API_STATUS
CSDHCBase::Start()
{
SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
m_fDriverShutdown = FALSE;
// allocate the interrupt event
m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE,NULL);
if (NULL == m_hevInterrupt) {
goto EXIT;
}
// initialize the interrupt event
if (!InterruptInitialize (m_dwSysIntr, m_hevInterrupt, NULL, 0)) {
goto EXIT;
}
m_fInterruptInitialized = TRUE;
// create the interrupt thread for controller interrupts
m_htIST = CreateThread(NULL, 0, ISTStub, this, 0, NULL);
if (NULL == m_htIST) {
goto EXIT;
}
for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
PCSDHCSlotBase pSlot = GetSlot(dwSlot);
status = pSlot->Start();
if (!SD_API_SUCCESS(status)) {
goto EXIT;
}
}
// wake up the interrupt thread to check the slot
::SetInterruptEvent(m_dwSysIntr);
status = SD_API_STATUS_SUCCESS;
EXIT:
if (!SD_API_SUCCESS(status)) {
// Clean up
Stop();
}
return status;
}
SD_API_STATUS
CSDHCBase::Stop()
{
// Mark for shutdown
m_fDriverShutdown = TRUE;
if (m_fInterruptInitialized) {
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &m_dwSysIntr, sizeof(m_dwSysIntr),
NULL, 0, NULL);
InterruptDisable(m_dwSysIntr);
}
// Clean up controller IST
if (m_htIST) {
// Wake up the IST
SetEvent(m_hevInterrupt);
WaitForSingleObject(m_htIST, INFINITE);
CloseHandle(m_htIST);
m_htIST = NULL;
}
// free controller interrupt event
if (m_hevInterrupt) {
CloseHandle(m_hevInterrupt);
m_hevInterrupt = NULL;
}
for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
PCSDHCSlotBase pSlot = GetSlot(dwSlot);
pSlot->Stop();
}
return SD_API_STATUS_SUCCESS;
}
SD_API_STATUS
CSDHCBase::SlotOptionHandler(
DWORD dwSlot,
SD_SLOT_OPTION_CODE sdOption,
PVOID pData,
DWORD cbData
)
{
SD_API_STATUS status = SD_API_STATUS_SUCCESS;
BOOL fCallSlotsHandler = TRUE;
Lock();
Validate();
PCSDHCSlotBase pSlot = GetSlot(dwSlot);
DEBUGCHK(sdOption < dim(sc_rgpszOptions));
DEBUGCHK(sc_rgpszOptions[sdOption] != NULL);
DEBUGMSG(SDCARD_ZONE_INFO, (_T("CSDHCBase::SlotOptionHandler(%u, %s)\n"),
dwSlot, sc_rgpszOptions[sdOption]));
switch (sdOption) {
case SDHCDSetSlotPower: {
if (cbData != sizeof(DWORD)) {
status = SD_API_STATUS_INVALID_PARAMETER;
}
break;
}
case SDHCDSetSlotInterface: {
if (cbData != sizeof(SD_CARD_INTERFACE)) {
status = SD_API_STATUS_INVALID_PARAMETER;
}
break;
}
case SDHCDEnableSDIOInterrupts:
case SDHCDDisableSDIOInterrupts:
case SDHCDAckSDIOInterrupt:
if (pData || cbData != 0) {
status = SD_API_STATUS_INVALID_PARAMETER;
}
break;
case SDHCDGetWriteProtectStatus: {
if (cbData != sizeof(SD_CARD_INTERFACE)) {
status = SD_API_STATUS_INVALID_PARAMETER;
}
break;
}
case SDHCDQueryBlockCapability: {
if (cbData != sizeof(SD_HOST_BLOCK_CAPABILITY)) {
status = SD_API_STATUS_INVALID_PARAMETER;
}
break;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -