📄 sddevice.cpp
字号:
if ((Device_SD_Memory == m_DeviceType || Device_SD_Combo == m_DeviceType ) && (m_sdSlot.Capabilities & SD_SLOT_SDMEM_4BIT_CAPABLE)!=0) {
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1;
}
// for print the spec version of SD Card.
#ifdef DEBUG
if ((Device_SD_Memory == m_DeviceType || Device_SD_Combo == m_DeviceType )) {
UCHAR uSCRRegister[SD_SCR_REGISTER_SIZE]; // SCR
PSD_REGISTER_SCR pSCRRegsiter;
memcpy(uSCRRegister, &(m_CachedRegisters.SCR),SD_SCR_REGISTER_SIZE );
pSCRRegsiter = (PSD_REGISTER_SCR)uSCRRegister;
if (pSCRRegsiter->SD_SPEC < 1) DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] SD Card Spec Version : 1.00~1.01\n")));
else if (pSCRRegsiter->SD_SPEC < 2) DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] SD Card Spec Version : 1.10\n")));
else if (pSCRRegsiter->SD_SPEC < 3) DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] SD Card Spec Version : 2.00\n")));
else DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] SD Card Spec Version : >2.00\n")));
}
#endif
#ifdef _MMC_SPEC_42_
/**
* Description : If SD Spec 1.x or 2.x card in HSMMC slot, set the card to enable the high speed
*/
if ( (Device_SD_Memory == m_DeviceType) && (m_sdSlot.Capabilities & SD_SLOT_HIGH_SPEED_CAPABLE)!=0 ) {
UCHAR uSCRRegister[SD_SCR_REGISTER_SIZE]; // SCR
PSD_REGISTER_SCR pSCRRegsiter;
memcpy(uSCRRegister, &(m_CachedRegisters.SCR),SD_SCR_REGISTER_SIZE );
SD_COMMAND_RESPONSE response;
pSCRRegsiter = (PSD_REGISTER_SCR)uSCRRegister;
if ( pSCRRegsiter->SD_SPEC !=0 ) // CMD6 (Switch function) is supported from SD Spec 1.1
{
unsigned int uBuffer[16]= {0};
status = SendSDCommand(SD_CMD_SET_BLOCKLEN,
64,
ResponseR1,
&response);
if (!SD_API_SUCCESS(status)) {
RETAILMSG(TRUE,(TEXT("[SDBUS-ERR] Switch Command failed. %x\r\n"),status));
return status;
}
status = SDSynchronousBusRequest_I( SD_ACMD_SET_BUS_WIDTH,
SD_ACMD_ARG_GET_TRANS_SPEED,
SD_READ,
ResponseR1,
&response,
1,
64,
(PUCHAR)uBuffer,
0);
if (!SD_API_SUCCESS(status)) {
RETAILMSG(TRUE,(TEXT("CMD6 Switch function failed.\r\n")));
} else {
if (uBuffer[3] & (1<<9)) {
RETAILMSG(TRUE,(TEXT("[SDBUS] SD/SDHC supports the high-speed mode.\r\n")));
m_CardInterfaceEx.ClockRate = SDHC_FULL_SPEED_RATE;
} else {
RETAILMSG(TRUE,(TEXT("[SDBUS] SD/SDHC doesn't support the high-speed mode.\r\n")));
m_CardInterfaceEx.ClockRate = SD_FULL_SPEED_RATE;
}
// CMD16 - set the block length to the 512
// If you don't set the block length to 512 in the card register,
// it cause an error when the next command issues.
status = SendSDCommand( SD_CMD_SET_BLOCKLEN,
512,
ResponseR1,
&response);
if (!SD_API_SUCCESS(status)) {
RETAILMSG(TRUE,(TEXT("[SDBUS-ERR] Switch Command failed. %x\r\n"),status));
return status;
}
}
} else {
RETAILMSG(TRUE,(TEXT("[SDBUS] This SD card is SPEC 1.0\r\n")));
m_CardInterfaceEx.ClockRate = SD_FULL_SPEED_RATE;
}
}
else
#endif
{
// try all cards at full speed
m_CardInterfaceEx.ClockRate = SD_FULL_SPEED_RATE;
}
} else {
// for print the spec version of SD Card.
#ifdef DEBUG
if (CSDRegister.SpecVersion < 1) DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] MMC Spec Version : 1.0/1.2\n")));
else if (CSDRegister.SpecVersion < 2) DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] MMC Spec Version : 1.4\n")));
else if (CSDRegister.SpecVersion < 3) DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] MMC Spec Version : 2.0/2.2\n")));
else if (CSDRegister.SpecVersion < 4) DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] MMC Spec Version : 3.1/3.2/3.31\n")));
else if (CSDRegister.SpecVersion < 5) DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] MMC Spec Version : 4.0/4.1/4.2\n")));
else DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("[SDBUS] MMC Spec Version : >4.2\n")));
#endif
#ifdef _MMC_SPEC_42_
/**
* Description : to distinguish the hsmmc slot from normal slot
*/
if ( m_dwMMCSpecVer == Device_HSMMC40 ) {
MMC_PARSED_REGISTER_EXTCSD ExtCSD;
SD_COMMAND_RESPONSE response;
// set data bus width as default.
// It is needed after wakeup.
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH,
MMC_ACMD_ARG_SET_BUS_1BIT,
ResponseR1 ,
&response);
if (!SD_API_SUCCESS(status)) {
RETAILMSG(TRUE,(TEXT("Switch Command is failed %x\n"),status));
return status;
}
// if the MMC card is on SPEC40, EXT_CSD value is needed.
status = GetEXTCSDFromHSMMC();
if (!SD_API_SUCCESS(status)) {
RETAILMSG(TRUE,(TEXT("Getting EXTCSD from HSMMC is failed %x\n"),status));
return status;
}
ExtCSD = *(MMC_PARSED_REGISTER_EXTCSD*)m_ucEXTCSD;
if ((m_sdSlot.Capabilities & SD_SLOT_HIGH_SPEED_CAPABLE)!=0) {
RETAILMSG(TRUE,(TEXT("[SDBUS] HSMMC card in HSMMC slot\n")));
// Because HSMMC Ch0 support only 4 data bus width,
// In order to distinguish the bus width, Read the capabilities of HostController!
if ((m_sdSlot.Capabilities & SD_SLOT_SD_8BIT_CAPABLE)!=0) {
m_CardInterfaceEx.InterfaceModeEx.bit.hsmmc8Bit = 1;
} else {
RETAILMSG(TRUE,(TEXT("[SDBUS] This MMC Card spec is 4.xx. But this slot support only 4bit\r\n")));
}
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1;
if ( ExtCSD.CardType != 0x1 ) {
RETAILMSG(TRUE,(TEXT("[SDBUS] This HSMMC card supports up to 52Mhz\n")));
m_CardInterfaceEx.ClockRate = HSMMC_FULL_SPEED_RATE;
} else {
RETAILMSG(TRUE,(TEXT("[SDBUS] This HSMMC card only supports up to 26Mhz\n")));
m_CardInterfaceEx.ClockRate = MMCPLUS_SPEED_RATE;
}
} else {
RETAILMSG(TRUE,(TEXT("[SDBUS] HSMMC card in **NOT** HSMMC slot\n")));
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1;
m_CardInterfaceEx.ClockRate = MMC_FULL_SPEED_RATE;
}
}
else
#endif
{
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 0;
m_CardInterfaceEx.ClockRate = MMC_FULL_SPEED_RATE;
}
}
// select the actual interface speed and type based on the card type
if (Device_SD_IO == m_DeviceType) {
CSDDevice * pParentDevice = m_sdSlot.GetFunctionDevice( 0 );
if (pParentDevice) {
// check for a low speed device
if (pParentDevice->m_SDCardInfo.SDIOInformation.pCommonInformation->CardCapability & SD_IO_CARD_CAP_LOW_SPEED) {
// drop it down to low speed
m_CardInterfaceEx.ClockRate = SD_LOW_SPEED_RATE;
// check for 4 bit support at low speed
if (!(pParentDevice->m_SDCardInfo.SDIOInformation.pCommonInformation->CardCapability & SD_IO_CARD_CAP_4_BIT_LOW_SPEED)) {
// drop to 1 bit mode if the low speed device doesn't support
// 4 bit operation
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 0 ;
}
}
pParentDevice->DeRef();
}
else {
ASSERT(FALSE);
status = SD_API_STATUS_UNSUCCESSFUL;
}
}
else if (Device_SD_Memory == m_DeviceType || Device_SD_Combo == m_DeviceType) {
// get the bus width bits from the SCR to check for 4 bit
// all cards must minimally support 1 bit mode
bitSlice = GetBitSlice(m_CachedRegisters.SCR, sizeof(m_CachedRegisters.SCR), SD_SCR_BUS_WIDTH_BIT_SLICE , SD_SCR_BUS_WIDTH_SLICE_SIZE);
if (!(bitSlice & SD_SCR_BUS_WIDTH_4_BIT)) {
// card only supports 1 bit mode
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: SD Memory Card only supports 1 bit mode! \n"),
m_FuncionIndex));
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 0 ;
}
// SD cards have their Max transfer rate set to 25 Mhz, we do not need to check the CSD register
} else if (Device_MMC == m_DeviceType) {
// for MMC cards we need to check the Max Transfer Rate reported by the card
// the data rate is in kbits/sec
if ((CSDRegister.MaxDataTransferRate * 1000) < MMC_FULL_SPEED_RATE) {
// set for a lower rate
m_CardInterfaceEx.ClockRate = CSDRegister.MaxDataTransferRate * 1000;
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: MMC Card Max Transfer Rate: %d Hz \n"),
m_CardInterfaceEx.ClockRate));
} else {
DEBUGCHK(FALSE);
return SD_API_STATUS_INVALID_PARAMETER;
}
if (SD_API_SUCCESS(status)) {
// get any interface overrides via the registry
GetInterfaceOverrides();
// sanity check the overrides
if ((!(m_sdSlot.Capabilities & SD_SLOT_SD_4BIT_CAPABLE)) && (m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit)) {
if ( (!(m_sdSlot.Capabilities & SD_SLOT_SDMEM_4BIT_CAPABLE)) &&(!( m_sdSlot.Capabilities & SD_SLOT_SDIO_4BIT_CAPABLE)) ) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: override to 4 bit on non-4-bit capable host, not allowed! \n")));
return SD_API_STATUS_INVALID_PARAMETER;
}
}
// get the write protect status
if (Device_SD_Memory == m_DeviceType) {
SD_CARD_INTERFACE sdCardInterface;
status = m_sdSlot.GetHost().SlotOptionHandler(m_sdSlot.GetSlotIndex(), SDHCDGetWriteProtectStatus, &sdCardInterface, sizeof(sdCardInterface));
m_CardInterfaceEx.InterfaceModeEx.bit.sdWriteProtected = (sdCardInterface.WriteProtected?1:0);
if (m_CardInterfaceEx.InterfaceModeEx.bit.sdWriteProtected) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Card in slot %d is write protected \n"),m_sdSlot.GetSlotIndex()));
}
}
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Interface for slot %d , Mode :%x, Clock:%d \n"),
m_sdSlot.GetSlotIndex(),m_CardInterfaceEx.InterfaceModeEx.uInterfaceMode,m_CardInterfaceEx.ClockRate));
ASSERT(SD_API_SUCCESS(status));
return status;
}
///////////////////////////////////////////////////////////////////////////////
// GetInterfaceOverrides - get card interface overrides from the user
// Input: pDevice - the device
//
// Output:
// Return:
// Notes: This function gets the overrides from the device path in the
// registry. This function only uses a path built from the card's
// OEM, MANF or CARDIDs. It will not search a class path. For multi-
// function and combo devices, overrides detected in the MANF and CARDID
// path ex:[HKLM\Drivers\SDCARD\ClientDrivers\Custom\MANF-xxxx-CARDID-xxxx]
// will override the interface settings for the entire card (all functions).
//
///////////////////////////////////////////////////////////////////////////////
VOID CSDDevice::GetInterfaceOverrides()
{
WCHAR regPath[MAX_KEY_PATH_LENGTH]; // regpath
DWORD clockRate; // clockrate override
DWORD interfaceMode; // interface mode override
// get the card registry path
if (!SD_API_SUCCESS(GetCustomRegPath(regPath, dim(regPath), TRUE))) {
return;
}
CReg regDevice(HKEY_LOCAL_MACHINE, regPath);
if (regDevice.IsOK()) {
// check for clock rate override
clockRate = regDevice.ValueDW(SDCARD_CLOCK_RATE_OVERRIDE, -1);
if (clockRate != -1) {
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: RegPath: %s overrides clock rate to : %d\n"),
regPath,clockRate));
m_CardInterfaceEx.ClockRate = clockRate;
}
// check for interface mode override
interfaceMode = regDevice.ValueDW(SDCARD_INTERFACE_MODE_OVERRIDE, -1);
if (interfaceMode != -1) {
if (interfaceMode == SDCARD_INTERFACE_OVERRIDE_1BIT) {
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 0 ;
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: RegPath: %s overrides inte
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -