⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdhc.cpp

📁 smdk2450 ce6 bsp,需要的朋友可以参考以下.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
//
// 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.
//
#endif

// 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

#if (BSP_TYPE == BSP_SMDK2443)
#include "SDCardDDK.h"

#elif (BSP_TYPE == BSP_SMDK2450)
#include "../../../SDDriver_INC/SDCardDDK.h"
#endif
#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),
#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
		MAKE_OPTION_STRING(SDHCDSetSlotInterfaceEx),    
#endif
	};
#endif


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 (BSP_TYPE == BSP_SMDK2443)
	if (m_cSlots == 0) {
		goto EXIT;
	}
	ValidateSlotCount();
	RETAILMSG(0,(TEXT("CSDHCBase::Init  m_cSlots=%d\n"),m_cSlots));

#elif (BSP_TYPE == BSP_SMDK2450)
	if (!CheckSlotCount(m_cSlots)) {
		goto EXIT;
	}
	PREFAST_ASSERT(m_cSlots <= SDHC_MAX_SLOTS);
#endif

	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;
	}
	RETAILMSG(0,(TEXT("AllocateSlotObjects\n")));
	// 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);

		RETAILMSG(0,(TEXT("pSlot->Init\n")));
		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("HSMMC"));

	// 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);
	RETAILMSG(0,(TEXT("SDHCDRegisterHostController\n")));
	// 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;
	RETAILMSG(0,(TEXT("CSDHCBase::Init Finished.\n")));
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;
										}

		case SDHCDSetSlotPowerState: {
										 if (cbData != sizeof(CEDEVICE_POWER_STATE)) {
											 status = SD_API_STATUS_INVALID_PARAMETER;
										 }

										 PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;

										 if (*pcps < m_cpsCurrent) {
											 // Move controller to higher power state initially since
											 // it will need to be powered for the slot to access
											 // registers.
											 SetControllerPowerState(*pcps);
										 }

										 status = pSlot->SlotOptionHandler(sdOption, pData, cbData);

										 // Set the power state based on current conditions. Note that 
										 // the slot may have gone to a state different from what was 
										 // requested.
										 CEDEVICE_POWER_STATE cps = DetermineRequiredControllerPowerState();
										 SetControllerPowerState(cps);
										 fCallSlotsHandler = FALSE;
										 break;
									 }

		case SDHCDGetSlotPowerState: {
										 if (cbData != sizeof(CEDEVICE_POWER_STATE)) {
											 status = SD_API_STATUS_INVALID_PARAMETER;
										 }
										 break;
									 }

		case SDHCDWakeOnSDIOInterrupts: {
											if (cbData != sizeof(BOOL)) {
												status = SD_API_STATUS_INVALID_PARAMETER;
											}
											break;
										}

		case SDHCDGetSlotInfo: {
								   if (cbData != sizeof(SDCARD_HC_SLOT_INFO)) {
									   status = SD_API_STATUS_INVALID_PARAMETER;
								   }
								   break;
							   }
#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
		case SDHCDSetSlotInterfaceEx: {
										  if (cbData != sizeof(SD_CARD_INTERFACE_EX)) {
											  status = SD_API_STATUS_INVALID_PARAMETER;
										  }
									  }
#endif
		default:
									  break;
	}

	if (SD_API_SUCCESS(status) && fCallSlotsHandler) {
		// Call the slots handler to do the real work.
		status = pSlot->SlotOptionHandler(sdOption, pData, cbData);
	}

	Unlock();

	return status;
}


VOID
CSDHCBase::PowerDown(
		)
{
	Validate();

	for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
		PCSDHCSlotBase pSlot = GetSlot(dwSlot);
		pSlot->PowerDown();
	}

	CEDEVICE_POWER_STATE cps = DetermineRequiredControllerPowerState();
	SetControllerPowerState(cps);
}


VOID
CSDHCBase::PowerUp(
		)
{
	Validate();

	for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
		PCSDHCSlotBase pSlot = GetSlot(dwSlot);

		CEDEVICE_POWER_STATE cpsRequired = pSlot->GetPowerUpRequirement();
		if (cpsRequired < m_cpsCurrent) {
			// Move controller to higher power state initially since
			// it will need to be powered for the slot to access
			// registers.
			SetControllerPowerState(cpsRequired);
		}

		pSlot->PowerUp();
	}
}


VOID
CSDHCBase::PreDeinit(
		)
{
	if (m_fRegisteredWithBusDriver) {
		if (m_fDriverShutdown == FALSE) {
			// Deregister the host controller
			SDHCDDeregisterHostController(m_pHCDContext);
		}
		// else the bus driver itself already deregistered us.

		m_fRegisteredWithBusDriver = FALSE;
	}
}


BOOL 
CSDHCBase::InitializeHardware(
		)
{
	SETFNAME(_T("InitializeHardware"));

	DEBUGCHK(m_hBusAccess);
	DEBUGCHK(m_regDevice.IsOK());
	PREFAST_DEBUGCHK(m_pSlotInfos);
	RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware\n")));
	ValidateSlotCount();

	BOOL fRet = FALSE;
	PHYSICAL_ADDRESS PortAddress;
	DWORD inIoSpace = 0;

	// Read window information
	DDKWINDOWINFO wini;
	wini.cbSize = sizeof(wini);
	DWORD dwStatus = DDKReg_GetWindowInfo(m_regDevice, &wini);
	if (dwStatus != ERROR_SUCCESS) {
		DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting window information\r\n"),
					pszFname));
		goto EXIT;
	}

	// Read ISR information
	DDKISRINFO isri;
	isri.cbSize = sizeof(isri);
	dwStatus = DDKReg_GetIsrInfo(m_regDevice, &isri);
	if (dwStatus != ERROR_SUCCESS) {
		DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting ISR information\r\n"),
					pszFname));
		goto EXIT;
	}

#ifdef SET_TI_BOARD_PCI_REG
	{
		DDKPCIINFO dpi;
		dpi.cbSize = sizeof(dpi);
		DDKReg_GetPciInfo(m_regDevice, &dpi);

		DWORD RetVal;
		PCI_SLOT_NUMBER SlotNumber;
		SlotNumber.u.AsULONG = 0;
		SlotNumber.u.bits.DeviceNumber = dpi.dwDeviceNumber;
		SlotNumber.u.bits.FunctionNumber = 1;

		HalGetBusDataByOffset( PCIConfiguration,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -