📄 sddevice.cpp
字号:
#ifdef _MMC_SPEC_42_
/*************************************************************************/
/****** Date : 07.05.04 ******/
/****** Developer : HS.JANG ******/
/****** Description : to distinguish the hsmmc slot from normal slot******/
/*************************************************************************/
if ( m_dwMMCSpecVer == Device_HSMMC40 )
{
MMC_PARSED_REGISTER_EXTCSD temp;
SD_COMMAND_RESPONSE response;
// set data bus width as default.
// It is needed after wakeup. hsjang 070822
status = SendSDCommand( SD_ACMD_SET_BUS_WIDTH,
(3<<24) | (183<<16) | (0<<8) ,
ResponseR1b,
&response);
if (!SD_API_SUCCESS(status))
{
RETAILMSG(1,(TEXT("[SDBUS-ERR] SelectCardInterface:Switch Command is failed %x\n"),status));
return status;
}
// if the MMC card is on SPEC40, EXT_CSD value is needed.
GetEXTCSDFromHSMMC();
memcpy(&temp,m_ucEXTCSD,MMC_EXTCSD_REGISTER_SIZE);
if((m_sdSlot.Capabilities & SD_SLOT_HIGH_SPEED_CAPABLE)!=0)
{
RETAILMSG(1,(TEXT("[SDBUS] HSMMC card in HSMMC slot\n")));
// 08.04.04 by KYS
// 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(1,(TEXT("[SDBUS] This MMC Card spec is 4.xx. But this slot support only 4bit\r\n")));
}
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1;
if ( temp.CardType != 0x1 )
{
RETAILMSG(1,(TEXT("[SDBUS] This HSMMC card supports up to 52Mhz\n")));
m_CardInterfaceEx.ClockRate = HSMMC_FULL_SPEED_RATE;
}
else
{
RETAILMSG(1,(TEXT("[SDBUS] This HSMMC card only supports up to 26Mhz\n")));
#if (BSP_TYPE == BSP_SMDK2443)
m_CardInterfaceEx.ClockRate = SD_FULL_SPEED_RATE;
#elif (BSP_TYPE == BSP_SMDK2450)
m_CardInterfaceEx.ClockRate = MMCPLUS_SPEED_RATE;
#endif
}
}
else
{
RETAILMSG(1,(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 interface mode to 1 bit \n"),regPath));
} else if (interfaceMode == SDCARD_INTERFACE_OVERRIDE_4BIT) {
m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1;
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: RegPath: %s overrides interface mode to 4 bit \n"),regPath));
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
// GetCustomRegPath - get a device's custom registry path
// Input: pDevice - the device instance
// cchPath - number of characters in pPath
// BasePath - if TRUE return only the card's base path not
// its function path (single or multifunction I/O cards)
// this parameter is ignored for memory cards
// Output: pPath - the path returned
// Notes:
// returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::GetCustomRegPath(LPTSTR pPath,
DWORD cchPath,
BOOL BasePath)
{
SD_PARSED_REGISTER_CID ParsedRegisters; // parsed registers
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
DEBUGCHK(pPath);
// for Memory or MMC get the CID
if ( (Device_SD_Memory == m_DeviceType) ||(Device_MMC == m_DeviceType) || (Device_SD_Combo==m_DeviceType) ) {
// get the parsed CID registers
status = SDCardInfoQuery_I( SD_INFO_REGISTER_CID,&ParsedRegisters, sizeof(ParsedRegisters));
#define TEMP_CHAR_BUFFER_SIZE 3
if (SD_API_SUCCESS(status)) {
TCHAR szOEMID0[TEMP_CHAR_BUFFER_SIZE];
TCHAR szOEMID1[TEMP_CHAR_BUFFER_SIZE];
TCHAR szProductName0[TEMP_CHAR_BUFFER_SIZE];
TCHAR szProductName1[TEMP_CHAR_BUFFER_SIZE];
TCHAR szProductName2[TEMP_CHAR_BUFFER_SIZE];
TCHAR szProductName3[TEMP_CHAR_BUFFER_SIZE];
TCHAR szProductName4[TEMP_CHAR_BUFFER_SIZE];
// the OEM application ID and product name should only contain 7 bit ASCII characters,
// but some cards use other characters in the 127-255 range). This causes a problem because
// the registry path is made up of these characters, and should not contain any characters
// outside of the 32-126 range.
// the following code will check each of the characters, and replace them with two digit
// hexadecimal string representation if necessary
if( ParsedRegisters.OEMApplicationID[0] >= 32 && ParsedRegisters.OEMApplicationID[0] < 127 )
StringCchPrintf( szOEMID0, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.OEMApplicationID[0] );
else
StringCchPrintf( szOEMID0, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.OEMApplicationID[0] );
if( ParsedRegisters.OEMApplicationID[1] >= 32 && ParsedRegisters.OEMApplicationID[1] < 127 )
StringCchPrintf( szOEMID1, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.OEMApplicationID[1] );
else
StringCchPrintf( szOEMID1, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.OEMApplicationID[1] );
if( ParsedRegisters.ProductName[0] >= 32 && ParsedRegisters.ProductName[0] < 127 )
StringCchPrintf( szProductName0, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[0] );
else
StringCchPrintf( szProductName0, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[0] );
if( ParsedRegisters.ProductName[1] >= 32 && ParsedRegisters.ProductName[1] < 127 )
StringCchPrintf( szProductName1, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[1] );
else
StringCchPrintf( szProductName1, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[1] );
if( ParsedRegisters.ProductName[2] >= 32 && ParsedRegisters.ProductName[2] < 127 )
StringCchPrintf( szProductName2, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[2] );
else
StringCchPrintf( szProductName2, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[2] );
if( ParsedRegisters.ProductName[3] >= 32 && ParsedRegisters.ProductName[3] < 127 )
StringCchPrintf( szProductName3, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[3] );
else
StringCchPrintf( szProductName3, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[3] );
if( ParsedRegisters.ProductName[4] >= 32 && ParsedRegisters.ProductName[4] < 127 )
StringCchPrintf( szProductName4, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[4] );
else
StringCchPrintf( szProductName4, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[4] );
// build up the string
HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\CID-%d-%s%s-%s%s%s%s%s"),
SDCARD_CUSTOM_DEVICE_REG_PATH,
ParsedRegisters.ManufacturerID,
szOEMID0, szOEMID1,
szProductName0, szProductName1, szProductName2, szProductName3, szProductName4 );
DEBUGCHK(SUCCEEDED(hr));
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: built custom MMC/SD path: %s \n"),pPath));
}
}
else if (Device_SD_IO == m_DeviceType) {
if (BasePath) {
// build the custom registry path for the card as a whole
HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\MANF-%04X-CARDID-%04X"),
SDCARD_CUSTOM_DEVICE_REG_PATH,
m_SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID,
m_SDCardInfo.SDIOInformation.pCommonInformation->CardID);
DEBUGCHK(SUCCEEDED(hr));
} else {
// build the custom registry path for the SDIO card function
HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\MANF-%04X-CARDID-%04X-FUNC-%d"),
SDCARD_CUSTOM_DEVICE_REG_PATH,
m_SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID,
m_SDCardInfo.SDIOInformation.pCommonInformation->CardID,
m_SDCardInfo.SDIOInformation.Function);
DEBUGCHK(SUCCEEDED(hr));
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: built custom SDIO path: %s \n"),pPath));
}
else {
DEBUG_ASSERT(FALSE);
status = SD_API_STATUS_INVALID_PARAMETER;
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDLoadDevice - load the associated device driver
// Input: pDevice - the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -