📄 sdhc.cpp
字号:
status = SD_API_STATUS_INVALID_PARAMETER;
}
break;
}
case SDHCDGetSlotInfo: {
if (cbData != sizeof(SDCARD_HC_SLOT_INFO)) {
status = SD_API_STATUS_INVALID_PARAMETER;
}
break;
}
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;
}
#ifdef NEW_POWER_MANAGEMENT
// for wakeup problem. hsjang 070823
DWORD CSDHCBase::IOControl(DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn,
PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
{
BOOL RetVal = TRUE;
DWORD dwErr = ERROR_SUCCESS;
switch (dwCode)
{
//-----------------------------------------------------------------------------------------
case IOCTL_POWER_CAPABILITIES:
{
PPOWER_CAPABILITIES ppc;
RETAILMSG(1, (TEXT("[HSMMC] IOCTL_POWER_CAPABILITIES\r\n")));
if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(POWER_CAPABILITIES)) ) {
RetVal = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
break;
}
ppc = (PPOWER_CAPABILITIES)pBufOut;
memset(ppc, 0, sizeof(POWER_CAPABILITIES));
// support D0, D4
ppc->DeviceDx = 0x11;
// Report our power consumption in uAmps rather than mWatts.
ppc->Flags = POWER_CAP_PREFIX_MICRO | POWER_CAP_UNIT_AMPS;
// 25 m = 25000 uA
// TODO: find out a more accurate value
ppc->Power[D0] = 25000;
*pdwActualOut = sizeof(POWER_CAPABILITIES);
} break;
case IOCTL_POWER_SET:
{
CEDEVICE_POWER_STATE NewDx;
if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) ) {
RetVal = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
break;
}
NewDx = *(PCEDEVICE_POWER_STATE)pBufOut;
if ( VALID_DX(NewDx) ) {
switch ( NewDx ) {
case D0:
if (m_Dx != D0) {
PowerUp();
m_Dx = D0;
}
break;
default:
if (m_Dx != (_CEDEVICE_POWER_STATE)D4) {
PowerDown();
m_Dx = (_CEDEVICE_POWER_STATE)D4;
}
break;
}
// return our state
*(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;
RETAILMSG(1, (TEXT("[HSMMC] IOCTL_POWER_SET : D%u \r\n"), NewDx));
*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
} else {
RetVal = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
}
} break;
case IOCTL_POWER_GET:
if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) ) {
RetVal = FALSE;
dwErr = ERROR_INVALID_PARAMETER;
break;
}
*(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;
RETAILMSG(1, (TEXT("[HSMMC] IOCTL_POWER_GET : D%u \r\n"), m_Dx));
*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
break;
default:
RETAILMSG(1, (TEXT("[HSMMC] This IOControl is not supported\r\n")));
dwErr = ERROR_INVALID_PARAMETER;
}
return dwErr;
}
#endif
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,
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));
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -