📄 sdhceventhandlers.cpp
字号:
if (!SD_API_SUCCESS(status)){
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to turn off CD resistor in slot %d \n"), pSlot->SlotIndex));
return status;
}
}
// for SD I/O or SD Combo cards, write to the Bus Interface control register and clear the CD bit
if (fDisableSDIO) {
regValue = SD_IO_BUS_CONTROL_CD_DETECT_DISABLE;
status = SDReadWriteRegistersDirect__X(pSlot->hDevice,
SD_IO_WRITE,
0, // function 0
SD_IO_REG_BUS_CONTROL,
TRUE, // read after write
®Value,
1);
if (!SD_API_SUCCESS(status)){
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to turn off CD resistor for SDIO Device in slot %d \n"), pSlot->SlotIndex));
return status;
}
}
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// SetCardInterface - sets the interface for the card
// Input: pDevice - the device
// pInterface - alternate interface, can be NULL
// Output:
// Return: SD_API_STATUS code
// Notes: This function sets the card's interface by issuing appropriate SD commands
// to the card.
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SetCardInterface(PSDCARD_DEVICE_CONTEXT pDevice, PSD_CARD_INTERFACE pInterface)
{
UCHAR regValue; // register value
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
SD_COMMAND_RESPONSE response; // response
PSD_CARD_INTERFACE pInterfaceToUse; // interface to use
if (NULL != pInterface) {
pInterfaceToUse = pInterface;
} else {
// otherwise use the one set in the device
pInterfaceToUse = &pDevice->CardInterface;
}
// set the card interface
if (Device_SD_IO == pDevice->DeviceType) {
// read the bus control register to keep its current bits
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // function 0
SD_IO_REG_BUS_CONTROL,
FALSE,
®Value,
1);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to read Bus Interface Control \n")));
return status;
}
// write the bus control register to set for 4 bit mode
if (SD_INTERFACE_SD_4BIT == pInterfaceToUse->InterfaceMode) {
regValue |= SD_IO_BUS_CONTROL_BUS_WIDTH_4BIT;
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_WRITE,
0, // function 0
SD_IO_REG_BUS_CONTROL,
FALSE,
®Value,
1);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to set I/O Card Bus Width \n")));
return status;
}
// if the slot can detect interrupts during 4 bit multi-block transfers
// check to see if the card can handle it
if (pDevice->pSlot->Capabilities &
SD_SLOT_SDIO_INT_DETECT_4BIT_MULTI_BLOCK) {
// get the card capabilities register
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // all from function 0
SD_IO_REG_CARD_CAPABILITY,
FALSE,
®Value,
1);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to get CARD CAPABILITY register \n")));
return status;
}
// check the bit
if (regValue & SD_IO_CARD_CAP_SUPPORTS_INTS_4_BIT_MB_MODE) {
DEBUGMSG(SDBUS_ZONE_DEVICE,
(TEXT("SDBusDriver: Host and Card supports interrupts in 4bit Multi-block mode\n")));
// set the bit, it's in the same register
regValue |= SD_IO_CARD_CAP_ENABLE_INTS_4_BIT_MB_MODE;
// write out the card capabilities register
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_WRITE,
0, // all from function 0
SD_IO_REG_CARD_CAPABILITY,
FALSE,
®Value,
1);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to set CARD CAPABILITY register \n")));
return status;
}
DEBUGMSG(SDBUS_ZONE_DEVICE,
(TEXT("SDBusDriver: 4 Bit multi-block interrupts capability enabled \n")));
}
}
} else {
regValue &= ~SD_IO_BUS_CONTROL_BUS_WIDTH_4BIT;
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_WRITE,
0, // function 0
SD_IO_REG_BUS_CONTROL,
FALSE,
®Value,
1);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to set I/O Card Bus Width \n")));
return status;
}
}
} else if (Device_SD_Memory == pDevice->DeviceType) {
// bus width commands are only allowed if the card is unlocked
if (!pDevice->SDCardInfo.SDMMCInformation.CardIsLocked) {
// send the SET_BUS_WIDTH command to the device if 4 bit mode is used
if (SD_INTERFACE_SD_4BIT == pInterfaceToUse->InterfaceMode) {
// send command
status = SendSDAppCommand((SD_DEVICE_HANDLE)pDevice,
SD_ACMD_SET_BUS_WIDTH,
SD_ACMD_ARG_SET_BUS_4BIT,
ResponseR1,
&response);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to set Memory Card Bus Width in Slot \n")));
return status;
}
} else {
// send command
status = SendSDAppCommand((SD_DEVICE_HANDLE)pDevice,
SD_ACMD_SET_BUS_WIDTH,
0x00, // zero is 1 bit mode
ResponseR1,
&response);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to set Memory Card Bus Width in Slot \n")));
return status;
}
}
}
} else if (Device_MMC == pDevice->DeviceType) {
// nothing to do for MMC cards
} else {
DEBUGCHK(FALSE);
return SD_API_STATUS_INVALID_PARAMETER;
}
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// 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 GetInterfaceOverrides(PSDCARD_DEVICE_CONTEXT pDevice)
{
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(CSDBusDriver::GetCustomRegPath(pDevice, 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));
pDevice->CardInterface.ClockRate = clockRate;
}
// check for interface mode override
interfaceMode = regDevice.ValueDW(SDCARD_INTERFACE_MODE_OVERRIDE, -1);
if (interfaceMode != -1) {
if (interfaceMode == SDCARD_INTERFACE_OVERRIDE_1BIT) {
pDevice->CardInterface.InterfaceMode = SD_INTERFACE_SD_MMC_1BIT;
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: RegPath: %s overrides interface mode to 1 bit \n"),regPath));
} else if (interfaceMode == SDCARD_INTERFACE_OVERRIDE_4BIT) {
pDevice->CardInterface.InterfaceMode = SD_INTERFACE_SD_4BIT;
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: RegPath: %s overrides interface mode to 4 bit \n"),regPath));
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
// SelectCardInterface - select card interface based on information from the card,
// the host controller and whether this is a child device
// Input: pDevice - the device
// pSlot - the slot
//
// Output:
// Return: SD_API_STATUS code
// Notes: This function sets the card's interface in the device structure
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SelectCardInterface(PSDCARD_DEVICE_CONTEXT pDevice,
PSDBUS_HC_SLOT_CONTEXT pSlot)
{
DWORD bitSlice; // bit slice
SD_API_STATUS status; // intermediate status
PSD_PARSED_REGISTER_CSD pCSDRegister = NULL; // CSD registers
status = SD_API_STATUS_SUCCESS;
PREFAST_DEBUGCHK(pDevice);
PREFAST_DEBUGCHK(pDevice->pParentDevice != NULL);
// for MMC and SD cards allocate storage for the parsed CSD
if ( (Device_SD_Memory == pDevice->DeviceType) ||
(Device_MMC == pDevice->DeviceType) ) {
pCSDRegister = (PSD_PARSED_REGISTER_CSD)
SDAllocateMemoryWithTag(sizeof(SD_PARSED_REGISTER_CSD),
SD_BUS_DRIVER_TAG);
if (NULL == pCSDRegister) {
return SD_API_STATUS_INSUFFICIENT_RESOURCES;
}
// get the parsed CSD registers
status = SDCardInfoQuery__X((SD_DEVICE_HANDLE)pDevice,
SD_INFO_REGISTER_CSD,
pCSDRegister,
sizeof(SD_PARSED_REGISTER_CSD));
if (!SD_API_SUCCESS(status)) {
SDFreeMemory(pCSDRegister);
return status;
}
}
// check for parent device
if (IS_PARENT(pDevice)) {
// set the interface mode defaults
if (Device_MMC != pDevice->DeviceType) {
// check to see what the host is capable of doing
if (pSlot->Capabilities & SD_SLOT_SD_4BIT_CAPABLE) {
// try all cards at 4 bit
pDevice->CardInterface.InterfaceMode = SD_INTERFACE_SD_4BIT;
} else {
// host only supports 1 bit mode
pDevice->CardInterface.InterfaceMode = SD_INTERFACE_SD_MMC_1BIT;
}
// deal with special cases
// 1 bit SD memory + 4 bit SDIO
// SD_SLOT_SD_1BIT_CAPABLE | SD_SLOT_SDIO_CAPABLE | SD_SLOT_SDIO_4BIT_CAPABLE
if (Device_SD_IO == pDevice->DeviceType) {
if ( pSlot->Capabilities & SD_SLOT_SDIO_4BIT_CAPABLE) {
pDevice->CardInterface.InterfaceMode = SD_INTERFACE_SD_4BIT;
}
}
// 1 bit SDIO + 4 bit SD Memory
// SD_SLOT_SD_1BIT_CAPABLE | SD_SLOT_SDIO_CAPABLE | SD_SLOT_SDMEM_4BIT_CAPABLE
if (Device_SD_Memory == pDevice->DeviceType) {
if ( pSlot->Capabilities & SD_SLOT_SDMEM_4BIT_CAPABLE) {
pDevice->CardInterface.InterfaceMode = SD_INTERFACE_SD_4BIT;
}
}
// try all cards at full speed
pDevice->CardInterface.ClockRate = SD_FULL_SPEED_RATE;
} else {
// MMC cards are always 1 bit
#if USE_MMCPLUS
if ( g_bIsHSMMC == TRUE ) // if the card is HSMMC
{
if(wcscmp(GET_HC_NAME_FROM_SLOT(pSlot),TEXT("HSMMC"))==0)
{
//RETAILMSG(1,(TEXT("8Bit bus Enable for HSMMC\n")));
pDevice->CardI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -