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

📄 sdhc.cpp

📁 smdk2450 ce6 bsp,需要的朋友可以参考以下.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				wini.dwBusNumber,
				SlotNumber.u.AsULONG,
				&RetVal,
				0x84,
				sizeof( RetVal ) );

		if (!(RetVal & 0x00200000)) {
			RetVal |= 0x00200000;
			HalSetBusDataByOffset( PCIConfiguration,
					wini.dwBusNumber,
					SlotNumber.u.AsULONG,
					&RetVal,
					0x84,
					sizeof( RetVal ) );
		}
	}
#endif

	// Sanity check ISR
	if (isri.dwSysintr == SYSINTR_NOP) {
		RETAILMSG(0,(TEXT("%s No sysintr specified in registry\r\n"),pszFname));
		DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s No sysintr specified in registry\r\n"),
					pszFname));
		// 08.03.23	by KYS
		// For HSMMC driver request OAL a SYSINTR instead of ststic SYSINTR mapping, Below KernelIoControl function is called.
		if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &(isri.dwIrq), sizeof(DWORD), &(isri.dwSysintr), sizeof(DWORD), NULL))
		{
			RETAILMSG(1, (TEXT("[HSMMC1] %s IOCTL_HAL_REQUEST_SYSINTR HSMMC1 Failed \n\r"), pszFname));
			goto EXIT;
		}
	}

	if (isri.szIsrDll[0] != 0) {
		if ( (isri.szIsrHandler[0] == 0) || (isri.dwIrq == IRQ_UNSPECIFIED) ) {
			DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Invalid installable ISR information in registry\r\n"),
						pszFname));
			goto EXIT;
		}
	}

	m_interfaceType = (INTERFACE_TYPE) wini.dwInterfaceType;
	m_dwBusNumber = wini.dwBusNumber;

	DWORD dwSlotZeroWindow;
	dwSlotZeroWindow = DetermineFirstSlotWindow(&wini);

	DEBUGCHK(dwSlotZeroWindow < wini.dwNumMemWindows);
	DEBUGCHK( (dwSlotZeroWindow + m_cSlots) <= wini.dwNumMemWindows );

	// Use the slot zero window for the ISR
	PDEVICEWINDOW pWindowSlotZero = &wini.memWindows[dwSlotZeroWindow];
	PortAddress.LowPart = pWindowSlotZero->dwBase;
	PortAddress.HighPart = 0;

	RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware go on...\n")));

	// Install an ISR, if present
	if (isri.szIsrDll[0] != 0) {
		m_hISRHandler = LoadIntChainHandler(isri.szIsrDll, isri.szIsrHandler, 
				(BYTE) isri.dwIrq);

		if (m_hISRHandler == NULL) {
			DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error installing ISR\r\n"), pszFname));
			goto EXIT;
		} 
		else {
			GIISR_INFO  Info;
			DWORD       dwPhysAddr;

			fRet = BusTransBusAddrToStatic(m_hBusAccess, 
					(INTERFACE_TYPE) wini.dwInterfaceType,
					wini.dwBusNumber, PortAddress, pWindowSlotZero->dwLen,
					&inIoSpace, (PVOID *) &dwPhysAddr);
			if (fRet == FALSE) {
				DEBUGMSG(SDCARD_ZONE_ERROR,
						(_T("%s Error translating bus address to static address\r\n"), 
						 pszFname));
				goto EXIT;
			}

			// Initialize ISR
			Info.SysIntr = isri.dwSysintr;
			Info.CheckPort = TRUE;
			Info.PortIsIO = (inIoSpace != 0);
			Info.UseMaskReg = FALSE;
			Info.PortAddr = dwPhysAddr + SDHC_SLOT_INT_STATUS;
			Info.PortSize = sizeof(USHORT);
			Info.Mask = 0xFF;

			fRet = KernelLibIoControl(m_hISRHandler, IOCTL_GIISR_INFO, &Info, 
					sizeof(Info), NULL, 0, NULL);
			if (fRet == FALSE) {
				DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error setting up ISR\r\n"), pszFname));
				goto EXIT;
			}
		}
	}

	m_dwSysIntr = isri.dwSysintr;
	DEBUGMSG(SDCARD_ZONE_INIT, (_T("%s IRQ 0x%X mapped to SYS_INTR 0x%X\r\n"), 
				pszFname, isri.dwIrq, m_dwSysIntr));

	const DWORD dwEndWindow = dwSlotZeroWindow + m_cSlots;

	for (DWORD dwWindow = dwSlotZeroWindow; dwWindow < dwEndWindow; ++dwWindow) {
		DEBUGCHK(dwWindow < wini.dwNumMemWindows);
		PDEVICEWINDOW pWindowSD = &wini.memWindows[dwWindow];

		DEBUGMSG(SDCARD_ZONE_INIT,
				(_T("%s Base address -> 0x%x; length -> 0x%x \r\n"),
				 pszFname, pWindowSD->dwBase, pWindowSD->dwLen));

		PortAddress.LowPart = pWindowSD->dwBase;
		PortAddress.HighPart = 0;

		inIoSpace = 0;
		PVOID pvRegisters;
		DEBUGCHK(pWindowSlotZero->dwLen >= sizeof(SSDHC_REGISTERS));

		RETAILMSG(0,(TEXT("BusTransBusAddrToVirtual. 0x%X\n"),PortAddress));
		fRet = BusTransBusAddrToVirtual(m_hBusAccess, 
				(INTERFACE_TYPE) wini.dwInterfaceType,
				wini.dwBusNumber, PortAddress, pWindowSD->dwLen, &inIoSpace, 
				&pvRegisters);
		if (fRet == FALSE) {
			RETAILMSG(0,(TEXT("%s error translating SD address \r\n"),pszFname));
			DEBUGMSG(SDCARD_ZONE_ERROR,
					(_T("%s error translating SD address \r\n"),
					 pszFname));
			goto EXIT;
		}

		DEBUGCHK(inIoSpace == 0); // Will not work for I/O mappings.

		DWORD dwSlot = dwWindow - dwSlotZeroWindow;
		DEBUGCHK(dwSlot < m_cSlots);
		m_pSlotInfos[dwSlot].pucRegisters = (volatile UCHAR*) pvRegisters;
		m_pSlotInfos[dwSlot].dwExtraInfo = pWindowSD->dwLen;
	}

	m_fHardwareInitialized = TRUE;
	fRet = TRUE;
	RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware finished.\n")));
EXIT:
	return fRet;
}


BOOL 
CSDHCBase::DeinitializeHardware(
		)
{
	DEBUGCHK(m_hBusAccess);
	PREFAST_DEBUGCHK(m_pSlotInfos);
	ValidateSlotCount();

	for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
		PVOID pvRegisters = (PVOID) m_pSlotInfos[dwSlot].pucRegisters;
		DWORD dwLen = m_pSlotInfos[dwSlot].dwExtraInfo;
		if (pvRegisters) MmUnmapIoSpace(pvRegisters, dwLen);
	}

	if (m_hISRHandler) FreeIntChainHandler(m_hISRHandler);

	return TRUE;
}


	DWORD
CSDHCBase::IST()
{
	SETFNAME(_T("IST"));

	DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("%s Thread Starting\n"), pszFname));

	if (!CeSetThreadPriority(GetCurrentThread(), m_dwPriority)) {
		DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("%s Failed to set CEThreadPriority\n"),
					pszFname));
	}

	while (TRUE) {
		DEBUGCHK(m_hevInterrupt);
		DWORD dwWaitStatus = WaitForSingleObject(m_hevInterrupt, INFINITE);
		Validate();
       	// 08.07.11 by KYS
       	// Because the InterruptDone afer interrupt handling can clear the IRQ during interrupt handling,
       	// the InterruptDone must be here, before interrupt handling.
		InterruptDone(m_dwSysIntr);

		if (WAIT_OBJECT_0 != dwWaitStatus) {
			DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("%s Wait Failed! 0x%08X\n"), 
						pszFname, dwWaitStatus));
			// bail out
			break;
		}
		else if (m_fDriverShutdown) {
			break;
		}
		else {
			RETAILMSG(0,(TEXT("CSDHCBase::IST()\n")));			
			HandleInterrupt();
		}
	}

	DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("%s Thread Exiting\n"), pszFname));

	return 0;
}


VOID 
CSDHCBase::HandleInterrupt(
		) 
{
	Lock();

	// Use slot zero to get the shared global interrupt register
	PCSDHCSlotBase pSlotZero = GetSlot(0);
	DWORD dwIntStatus = pSlotZero->ReadControllerInterrupts();

	do {
		DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("CSDHCBase::HandleInterrupt: Slot Interrupt_Status=0x%X\n"), 
					dwIntStatus));

		for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
			PCSDHCSlotBase pSlot = GetSlot(dwSlot);
#if (BSP_TYPE == BSP_SMDK2443)
			//if ( ((1 << dwSlot) & dwIntStatus) || pSlot->NeedsServicing() ) {
			pSlot->HandleInterrupt();
			//}

#elif (BSP_TYPE == BSP_SMDK2450)
			// 08.07.09 by KYS
			// It is not needed to use slot number because we use NORMAL_INT_STATUS instead of SLOT_INT_STATUS
			//if ( ((1 << dwSlot) & dwIntStatus) || pSlot->NeedsServicing() ) {
			if ( (dwIntStatus) || pSlot->NeedsServicing() ) {
				pSlot->HandleInterrupt();
			}
#endif
		}

		dwIntStatus = pSlotZero->ReadControllerInterrupts();

#if (BSP_TYPE == BSP_SMDK2443)
		if(dwIntStatus && pSlotZero->IsOnlySDIOInterrupt()) break;

#elif (BSP_TYPE == BSP_SMDK2450)
		// 08.01.28 by KYS
		// In order to prevent infinite CARD INT occuring, below code is needed because of the architecture of HSMMC on s3c2450.
		if(dwIntStatus && pSlotZero->IsOnlySDIOInterrupt()) break;       
#endif
	} while (dwIntStatus);

	//InterruptDone(m_dwSysIntr);

	Unlock();
}


DWORD
CSDHCBase::DetermineSlotCount(
		)
{
	SETFNAME(_T("DetermineSlotCount"));

	DWORD cSlots = 0;

	// Read window information
	DDKWINDOWINFO wini = { 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;
	}

	cSlots = wini.dwNumMemWindows;

	if (cSlots == 0) {
		DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s There were not any reported slots.\r\n"),
					pszFname));
		goto EXIT;
	}

EXIT:
	return cSlots;
}




DWORD 
CSDHCBase::DetermineFirstSlotWindow(
		PDDKWINDOWINFO pwini
		)
{
	PREFAST_DEBUGCHK(pwini);
	DEBUGCHK(pwini->dwNumMemWindows >= m_cSlots);
	DEBUGCHK(pwini->dwNumMemWindows > 0);

	DWORD dwSlotZeroWindow = 0;

	return dwSlotZeroWindow;
}


CEDEVICE_POWER_STATE
CSDHCBase::DetermineRequiredControllerPowerState(
		)
{
#if (BSP_TYPE == BSP_SMDK2443)
	CEDEVICE_POWER_STATE cps = D4;

#elif (BSP_TYPE == BSP_SMDK2450)
	CEDEVICE_POWER_STATE cps = (CEDEVICE_POWER_STATE)D4;    
#endif
	for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
		PCSDHCSlotBase pSlot = GetSlot(dwSlot);
		cps = min(cps, pSlot->GetPowerState());
	}

	return cps;
}


SD_API_STATUS
CSDHCBase::SetControllerPowerState(
		CEDEVICE_POWER_STATE cpsNew
		)
{
	if (cpsNew != m_cpsCurrent) {
		switch (cpsNew) {
			case D0:
			case D4:
				KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &m_dwSysIntr, 
						sizeof(m_dwSysIntr), NULL, 0, NULL);
				break;

			case D3:
				KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &m_dwSysIntr, 
						sizeof(m_dwSysIntr), NULL, 0, NULL);
				break;
		}

		SetDevicePowerState(m_hBusAccess, cpsNew, NULL);
		m_cpsCurrent = cpsNew;
	}

	return SD_API_STATUS_SUCCESS;
}


#ifdef DEBUG
VOID 
CSDHCBase::Validate(
		)
{
	DEBUGCHK(m_regDevice.IsOK());
	DEBUGCHK(m_hBusAccess);
	ValidateSlotCount();
	DEBUGCHK(m_pSlots);
	DEBUGCHK(m_pSlotInfos);
	DEBUGCHK(m_pHCDContext);
	DEBUGCHK(m_dwBusNumber != INVALID_BUS_NUMBER);
	DEBUGCHK(m_interfaceType != InterfaceTypeUndefined);
	DEBUGCHK(m_dwSysIntr != SYSINTR_UNDEFINED);
	DEBUGCHK(VALID_DX(m_cpsCurrent));

	if (m_fRegisteredWithBusDriver && !m_fDriverShutdown) {
		DEBUGCHK(m_htIST);
		DEBUGCHK(m_fHardwareInitialized);
		DEBUGCHK(m_fInterruptInitialized);
	}
}
#endif


// Get the creation proc address and call it
PCSDHCBase
CSDHCBase::CreateSDHCControllerObject(
		LPCTSTR pszActiveKey
		)
{
	PCSDHCBase pSDHC = NULL;
	HKEY hkDevice = OpenDeviceKey(pszActiveKey);

	if (hkDevice) {
		CReg regDevice(hkDevice, _T(""));
		DEBUGCHK(regDevice.IsOK());
		TCHAR szDll[MAX_PATH];

		if (regDevice.ValueSZ(DEVLOAD_DLLNAME_VALNAME, szDll, dim(szDll))) {
			szDll[dim(szDll) - 1] = 0; // Null-terminate

			TCHAR szProc[MAX_PATH];

			if (regDevice.ValueSZ(SDHC_CREATION_PROC_KEY, szProc, dim(szProc))) {
				szProc[dim(szProc) - 1] = 0; // Null-terminate

				HMODULE hMod = LoadLibrary(szDll);
				if (hMod) {
					LPSDHC_CREATION_PROC pfnCreate = (LPSDHC_CREATION_PROC)
						GetProcAddress(hMod, szProc);
					if (pfnCreate) {
						pSDHC = (*pfnCreate)();
					}

					FreeLibrary(hMod);
				}
			}
		}

		RegCloseKey(hkDevice);
	}

	return pSDHC;
}


///////////////////////////////////////////////////////////////////////////////
//  SDHCInitialize - Initialize the the controller
//  Input:  pHCContext -  host controller context
//          
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  
//          
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDHCBase::SDHCInitialize(PSDCARD_HC_CONTEXT pHCContext)
{
	DEBUGMSG(SDCARD_ZONE_INIT,(TEXT("SDHCInitialize++\n")));

	PREFAST_DEBUGCHK(pHCContext);
	PCSDHCBase pController = GET_PCONTROLLER_FROM_HCD(pHCContext);
	PREFAST_DEBUGCHK(pController);
	SD_API_STATUS status = pController->Start();

	DEBUGMSG(SDCARD_ZONE_INIT,(TEXT("SDHCInitialize--\n")));

	return status;
}


///////////////////////////////////////////////////////////////////////////////
//  SDHCDeinitialize - Deinitialize the SDHC Controller
//  Input:  pHCContext - HC context
//          
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  
//          
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDHCBase::SDHCDeinitialize(PSDCARD_HC_CONTEXT pHCContext)
{
	DEBUGMSG(SDCARD_ZONE_INIT,(TEXT("SDHCDeinitialize++\n")));

	PREFAST_DEBUGCHK(pHCContext);
	PCSDHCBase pController = GET_PCONTROLLER_FROM_HCD(pHCContext);
	PREFAST_DEBUGCHK(pController);
	SD_API_STATUS status = pController->Stop();

	DEBUGMSG(SDCARD_ZONE_INIT,(TEXT("SDHCDeinitialize--\n")));

	return status;
}


///////////////////////////////////////////////////////////////////////////////
//  SDHCSDCancelIoHandler - io cancel handler 
//  Input:  pHostContext - host controller context
//          dwSlot - slot the request is going on
//          pRequest - the request to be cancelled
//          
//  Output: 
//  Return: TRUE if I/O was cancelled
//  Notes:  
//          the HC lock is taken before entering this cancel handler
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN 
CSDHCBase::SDHCCancelIoHandler(
		PSDCARD_HC_CONTEXT  pHCContext,
		DWORD               dwSlot,
		PSD_BUS_REQUEST     pRequest
		)
{
	PREFAST_DEBUGCHK(pHCContext);
	PCSDHCBase pController = GET_PCONTROLLER_FROM_HCD(pHCContext);
	PREFAST_DEBUGCHK(pController);
	return pController->CancelIoHandler(dwSlot, pRequest);
}


///////////////////////////////////////////////////////////////////////////////
//  SDHCBusRequestHandler - bus request handler 
//  Input:  pHostContext - host controller context
//          dwSlot - slot the request is going to
//          pRequest - the request
//          
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  The request passed in is marked as uncancelable, this function
//          has the option of making the outstanding request cancelable    
//          returns status pending
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS 
CSDHCBase::SDHCBusRequestHandler(
		PSDCARD_HC_CONTEXT pHCContext, 
		DWORD              dwSlot, 
		PSD_BUS_REQUEST    pRequest
		) 
{
	PREFAST_DEBUGCHK(pHCContext);
	PCSDHCBase pController = GET_PCONTROLLER_FROM_HCD(pHCContext);
	PREFAST_DEBUGCHK(pController);
	return pController->BusRequestHandler(dwSlot, pRequest);
}


///////////////////////////////////////////////////////////////////////////////
//  SDHCSlotOptionHandler - handler for slot option changes
//  Input:  pHostContext - host controller context
//          dwSlot       - the slot the change is being applied to
//          Option       - the option code
//          pData        - data associaSHC with the option
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS 
CSDHCBase::SDHCSlotOptionHandler(
		PSDCARD_HC_CONTEXT    pHCContext,
		DWORD                 dwSlot, 
		SD_SLOT_OPTION_CODE   sdOption, 
		PVOID                 pData,
		ULONG                 ulOptionSize
		)
{
	PCSDHCBase pController = GET_PCONTROLLER_FROM_HCD(pHCContext);
	PREFAST_DEBUGCHK(pController);
	return pController->SlotOptionHandler(dwSlot, sdOption, pData, ulOptionSize);
}


// DO NOT REMOVE --- END EXTERNALLY DEVELOPED SOURCE CODE ID --- DO NOT REMOVE

⌨️ 快捷键说明

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