📄 sdcontrol.c
字号:
SDClockOff(pHc);
rate = *pRate;
if( rate > pHc->dwMaximumSDClockFrequency )
rate = pHc->dwMaximumSDClockFrequency;
// check to see if the rate is below the first entry in the table
if (rate <= SDClockTable[0].Frequency) {
ii = 0;
} else {
// scan through the table looking for a frequency that
// is close to the requested rate
for (ii = 0; ii < (NUM_CLOCK_ENTRIES - 1); ii++) {
if ((rate >= SDClockTable[ii].Frequency) &&
(rate < SDClockTable[ii+1].Frequency)) {
break;
}
}
}
DbgPrintZo(SDH_CLOCK_ZONE, (TEXT("SDClockOn - Requested Rate: %d, Setting clock rate to %d Hz \n"),
*pRate, SDClockTable[ii].Frequency ));
// return the actual fruency
*pRate = SDClockTable[ii].Frequency;
// set the clock rate
WRITE_MMC_REGISTER_DWORD(pHc, MMC_CLKRT, SDClockTable[ii].ControlValue);
pHc->dwSDClockFrequency = SDClockTable[ii].Frequency;
if( fClockRunning )
{
SDClockOn( pHc );
}
}
static BOOL IndicateBusRequestComplete(PSDCARD_HC_CONTEXT pHCContext,
PSD_BUS_REQUEST pRequest,
SD_API_STATUS Status)
{
BOOL fRet = FALSE;
PSDH_HARDWARE_CONTEXT pController = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);
if (pController && pController->pCurrentRequest == pRequest) {
DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("IndicateBusRequestComplete - pRequest = %x, Status = %d\n"),pRequest,Status));
pController->pCurrentRequest = NULL;
if (pController->fCurrentRequestFastPath ) {
if (Status == SD_API_STATUS_SUCCESS) {
Status = SD_API_STATUS_FAST_PATH_SUCCESS;
}
pController->FastPathStatus = Status ;
}
else
SDHCDIndicateBusRequestComplete(pHCContext,pRequest,Status);
fRet = TRUE;
}
ASSERT(fRet);
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
// SDDeInitialize - Deinitialize the the MMC Controller
// Input: pHCContext - Host controller context
//
// Output:
// Return: SD_API_STATUS code
// Notes:
//
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDDeinitialize(PSDCARD_HC_CONTEXT pHCContext)
{
PSDH_HARDWARE_CONTEXT pHardwareContext; // hardware context
PSD_BUS_REQUEST pRequest = NULL; // the request to complete
pHardwareContext = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);
// mark for shutdown
pHardwareContext->DriverShutdown = TRUE;
if( pHardwareContext->hControllerInterruptEvent )
{
// wake up the controller IST
SetEvent(pHardwareContext->hControllerInterruptEvent);
}
if (NULL != pHardwareContext->hDMAInterruptEvent)
{
// wake up the DMA IST
SetEvent(pHardwareContext->hDMAInterruptEvent);
}
// clean up controller IST
if (NULL != pHardwareContext->hControllerInterruptThread) {
// wait for the thread to exit
WaitForSingleObject(pHardwareContext->hControllerInterruptThread, INFINITE);
CloseHandle(pHardwareContext->hControllerInterruptThread);
pHardwareContext->hControllerInterruptThread = NULL;
}
// clean up DMA IST
if (NULL != pHardwareContext->hDmaInterruptThread) {
// wait for the thread to exit
WaitForSingleObject(pHardwareContext->hDmaInterruptThread, INFINITE);
CloseHandle(pHardwareContext->hDmaInterruptThread);
pHardwareContext->hDmaInterruptThread = NULL;
}
// free controller interrupt event
if (NULL != pHardwareContext->hControllerInterruptEvent) {
CloseHandle(pHardwareContext->hControllerInterruptEvent);
pHardwareContext->hControllerInterruptEvent = NULL;
}
// free the DMA interrupt event
if( pHardwareContext->hDMAInterruptEvent )
{
CloseHandle(pHardwareContext->hDMAInterruptEvent);
pHardwareContext->hDMAInterruptEvent = NULL;
}
// make sure all interrupt sources are disabled
if( pHardwareContext->dwSysintrSDMMC != SYSINTR_UNDEFINED )
{
InterruptDisable (pHardwareContext->dwSysintrSDMMC);
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pHardwareContext->dwSysintrSDMMC, sizeof(DWORD), NULL, 0, NULL);
pHardwareContext->dwSysintrSDMMC = SYSINTR_UNDEFINED;
}
if( pHardwareContext->dwDmaSysIntr != SYSINTR_UNDEFINED )
{
InterruptDisable (pHardwareContext->dwDmaSysIntr);
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pHardwareContext->dwDmaSysIntr, sizeof(DWORD), NULL, 0, NULL);
pHardwareContext->dwDmaSysIntr = SYSINTR_UNDEFINED;
}
// unload the DMA ISR DLL
if( pHardwareContext->hDMAIsrHandler )
{
FreeIntChainHandler(pHardwareContext->hDMAIsrHandler);
pHardwareContext->hDMAIsrHandler = NULL;
}
// free the DMA buffer
if( pHardwareContext->pDMABuffer )
{
HalFreeCommonBuffer( NULL, 0, pHardwareContext->pDMABufferPhys, pHardwareContext->pDMABuffer, FALSE );
pHardwareContext->pDMABuffer = NULL;
pHardwareContext->dwDmaBufferSize = 0;
}
// free the DMA descriptors buffer
if( pHardwareContext->pDMADescriptors )
{
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SHCDriver: - Unable to allocate memory for DMA descriptors!\r\n")));
HalFreeCommonBuffer( NULL, 0, pHardwareContext->pDMADescriptorsPhys, (PVOID)pHardwareContext->pDMADescriptors, FALSE );
pHardwareContext->pDMADescriptors = NULL;
}
// clean up card insertion IST and free card insertion interrupt
CleanupCardDetectIST();
// turn the hardware off
SDClockOff( pHardwareContext );
MMCPowerControl( FALSE );
// if there is a pending request, cancel it
if( pHardwareContext && (pRequest = pHardwareContext->pCurrentRequest) != NULL)
{
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:SHCDriver() - aborting current request!\r\n")));
IndicateBusRequestComplete(pHCContext, pRequest, SD_API_STATUS_SHUT_DOWN);
}
// If a card is inserted, signal that it was ejected...
if(pHardwareContext && pHardwareContext->DevicePresent)
{
// indicate the slot change
SDHCDIndicateSlotStateChange(pHCContext, 0, DeviceEjected);
pHardwareContext->DevicePresent = FALSE;
}
// free memory mapped resources
if (NULL != pHardwareContext->pSDMMCRegisters) {
MmUnmapIoSpace((PVOID)pHardwareContext->pSDMMCRegisters, sizeof(BULVERDE_MMC_REG));
pHardwareContext->pSDMMCRegisters = NULL;
}
if (NULL != pHardwareContext->pGPIORegisters) {
MmUnmapIoSpace((PVOID)pHardwareContext->pGPIORegisters, sizeof(BULVERDE_GPIO_REG));
pHardwareContext->pGPIORegisters = NULL;
}
if (NULL != pHardwareContext->pClkMgrRegisters) {
MmUnmapIoSpace((PVOID)pHardwareContext->pClkMgrRegisters, sizeof(BULVERDE_CLKMGR_REG));
pHardwareContext->pClkMgrRegisters = NULL;
}
if (NULL != pHardwareContext->pDMARegisters) {
MmUnmapIoSpace((PVOID)pHardwareContext->pDMARegisters, sizeof(BULVERDE_DMA_REG));
pHardwareContext->pDMARegisters = NULL;
}
if(NULL != pHardwareContext->hBusAccessHandle) {
CloseBusAccessHandle(pHardwareContext->hBusAccessHandle);
pHardwareContext->hBusAccessHandle = NULL;
}
UnInitializeHardware();
DeleteCriticalSection(&pHardwareContext->ControllerCriticalSection);
DeleteCriticalSection(&pHardwareContext->intrRegCriticalSection);
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// SDInitialize - Initialize the the MMC Controller
// Input: pHardwareContext - newly allocated hardware context
//
// Output:
// Return: SD_API_STATUS code
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDInitialize(PSDCARD_HC_CONTEXT pHCContext)
{
ULONG fInIOSpace;
DWORD dwSDIOIrq;
DWORD dwRegVal; // intermediate value
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
DWORD threadID; // thread ID
PSDH_HARDWARE_CONTEXT pHardwareContext; // hardware context
PHYSICAL_ADDRESS Bulverde_GPIO_Base = {BULVERDE_BASE_REG_PA_GPIO};
PHYSICAL_ADDRESS Bulverde_SDMMC_Base = {BULVERDE_BASE_REG_PA_MMC};
PHYSICAL_ADDRESS Bulverde_CLKMGR_Base = {BULVERDE_BASE_REG_PA_CLKMGR};
PHYSICAL_ADDRESS Bulverde_DMA_Base = {BULVERDE_BASE_REG_PA_DMAC};
pHardwareContext = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);
InitializeCriticalSection(&pHardwareContext->ControllerCriticalSection);
pHardwareContext->fSDIOEnabled = FALSE;
pHardwareContext->pCurrentRequest = NULL ;
pHardwareContext->fSDIOInterruptPending = FALSE;
pHardwareContext->f4BitMode = FALSE;
pHardwareContext->DevicePresent = FALSE;
pHardwareContext->hDMAInterruptEvent = NULL;
pHardwareContext->hDMAIsrHandler = NULL;
pHardwareContext->DriverShutdown = FALSE;
pHardwareContext->hDMAInterruptEvent = NULL;
pHardwareContext->hDmaInterruptThread = NULL;
pHardwareContext->pDMABuffer = NULL;
pHardwareContext->pDMADescriptors = NULL;
pHardwareContext->dwControllerIstTimeout = INFINITE;
InitializeCriticalSection(&pHardwareContext->intrRegCriticalSection);
#ifdef DEBUG
pHardwareContext->fDMATransferInProgress = FALSE;
#endif
GetSystemInfo( &pHardwareContext->systemInfo );
if( !InitializeHardware( pHardwareContext->hBusAccessHandle ) )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error initializing platform specific hardware\r\n")));
goto exitInit;
}
if( !BusTransBusAddrToVirtual( pHardwareContext->hBusAccessHandle, Internal, 0, Bulverde_GPIO_Base, sizeof(BULVERDE_GPIO_REG), &fInIOSpace, (PPVOID)&(pHardwareContext->pGPIORegisters) ) )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating Bulverde GPIO registers\r\n")));
goto exitInit;
}
if( !BusTransBusAddrToVirtual( pHardwareContext->hBusAccessHandle, Internal, 0, Bulverde_SDMMC_Base, sizeof(BULVERDE_MMC_REG), &fInIOSpace, (PPVOID)&(pHardwareContext->pSDMMCRegisters) ) )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating Bulverde SD/MMC registers\r\n")));
goto exitInit;
}
if( !BusTransBusAddrToVirtual( pHardwareContext->hBusAccessHandle, Internal, 0, Bulverde_CLKMGR_Base, sizeof(BULVERDE_CLKMGR_REG), &fInIOSpace, (PPVOID)&(pHardwareContext->pClkMgrRegisters) ) )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating Bulverde Clock control registers\r\n")));
goto exitInit;
}
if( !BusTransBusAddrToVirtual( pHardwareContext->hBusAccessHandle, Internal, 0, Bulverde_DMA_Base, sizeof(BULVERDE_DMA_REG), &fInIOSpace, (PPVOID)&(pHardwareContext->pDMARegisters) ) )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("InitializeHardware:: Error allocating Bulverde DMA control registers\r\n")));
goto exitInit;
}
// enable the MMC Unit Clock
dwRegVal = pHardwareContext->pClkMgrRegisters->cken;
dwRegVal |= (1 << 12);
pHardwareContext->pClkMgrRegisters->cken = dwRegVal;
//////////////////////////////////////////////////////////
// Configure GPIO_32 as Alternate Function 2 out (MMC_CLK)
// assume that the MMC_CLK is active-low signal driven
dwRegVal = pHardwareContext->pGPIORegisters->GPCR1;
dwRegVal |= 0x00000001;
pHardwareContext->pGPIORegisters->GPCR1 = dwRegVal;
// change the direction to OUT
dwRegVal = pHardwareContext->pGPIORegisters->GPDR1;
dwRegVal |= 0x00000001;
pHardwareContext->pGPIORegisters->GPDR1 = dwRegVal;
// change to Alternate Function 2
dwRegVal = pHardwareContext->pGPIORegisters->GAFR1_L;
dwRegVal = ( dwRegVal & 0xfffffffc ) | 0x00000002;
pHardwareContext->pGPIORegisters->GAFR1_L = dwRegVal;
//////////////////////////////////////////////////////////
// Configure GPIO_112 as Alternate Function 1 (MMC_CMD)
// assume that the MMC_CLK is active-high signal driven
dwRegVal = pHardwareContext->pGPIORegisters->GPSR3;
dwRegVal |= 0x00010000;
pHardwareContext->pGPIORegisters->GPSR3 = dwRegVal;
// change the direction to OUT
dwRegVal = pHardwareContext->pGPIORegisters->GPDR3;
dwRegVal |= 0x00010000;
pHardwareContext->pGPIORegisters->GPDR3 = dwRegVal;
// change to Alternate Function 1
dwRegVal = pHardwareContext->pGPIORegisters->GAFR3_U;
dwRegVal = ( dwRegVal & 0xfffffffc ) | 0x00000001;
pHardwareContext->pGPIORegisters->GAFR3_U = dwRegVal;
//////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -