📄 sdhceventhandlers.cpp
字号:
// now 0x10-0xFF are available as device code extensions
pDevice->SDCardInfo.SDIOInformation.DeviceCode = regValue[0];
}
}
// get the CIS and CSA pointers, we do a multi-byte read here
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // all from function 0
FBROffset + SD_IO_FBR_CISP_BYTE_0,
FALSE,
CSA_CISBuffer,
CIS_CSA_BYTES);
if (!SD_API_SUCCESS(status)) {
return status;
}
pDevice->SDCardInfo.SDIOInformation.CISPointer = CSA_CISBuffer[CIS_OFFSET_BYTE_0] |
(CSA_CISBuffer[CIS_OFFSET_BYTE_1] << 8) |
(CSA_CISBuffer[CIS_OFFSET_BYTE_2] << 16);
pDevice->SDCardInfo.SDIOInformation.CSAPointer = CSA_CISBuffer[CSA_OFFSET_BYTE_0] |
(CSA_CISBuffer[CSA_OFFSET_BYTE_1] << 8) |
(CSA_CISBuffer[CSA_OFFSET_BYTE_2] << 16);
// allocate a product information tuple and fill it will some sort of
// friendly name string
pDevice->SDCardInfo.SDIOInformation.pFunctionInformation =
(PWCHAR)SDAllocateMemoryWithTag((sizeof(CHAR)) * (UNKNOWN_PRODUCT_INFO_STRING_LENGTH + 1),
SD_BUS_DRIVER_TAG);
if (NULL == pDevice->SDCardInfo.SDIOInformation.pFunctionInformation) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to allocate product information string \n")));
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
return status;
}
// get the power control infomation via the Function FUNCE Tuple
status = SDGetFunctionPowerControlTuples(pDevice);
// form the product name using the device class
swprintf(pDevice->SDCardInfo.SDIOInformation.pFunctionInformation,
TEXT("Device of Class Type: %d"),
pDevice->SDCardInfo.SDIOInformation.DeviceCode);
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Device 0x%08X , Function String: %s \n"),
pDevice,
pDevice->SDCardInfo.SDIOInformation.pFunctionInformation));
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Common Product String: %s \n"),
pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->pProductInformation));
//*******************************************************************************************************
//2008.01.09
RETAILMSG(1,(TEXT("Block Size = 0x%x\r\n"),pDevice->SDCardInfo.SDIOInformation.SoftBlockSize));
RETAILMSG(1,(TEXT("Block length in bytes = 0x%x\r\n"),pDevice->SDCardInfo.SDIOInformation.SoftBlockLengthInBytes));
//*******************************************************************************************************
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDIOSupportsWakeup - Look at CISTPL_FUNCE for the function to see if
// wakeup is supported
// Input: pDevice - the device
//
// Return: TRUE if wakeup is supported
///////////////////////////////////////////////////////////////////////////////
static
BOOL SDIOSupportsWakeup(PSDCARD_DEVICE_CONTEXT pDevice)
{
PREFAST_DEBUGCHK(pDevice);
BOOL fRet = FALSE;
BYTE rgbFunce[SD_CISTPLE_MAX_BODY_SIZE];
PSD_CISTPL_FUNCE_FUNCTION pFunce = (PSD_CISTPL_FUNCE_FUNCTION) rgbFunce;
DWORD cbTuple;
SD_API_STATUS status = SDGetTuple__X((SD_DEVICE_HANDLE)pDevice,
SD_CISTPL_FUNCE, NULL, &cbTuple, FALSE);
if ( SD_API_SUCCESS(status) && (cbTuple <= sizeof(rgbFunce)) ) {
status = SDGetTuple__X((SD_DEVICE_HANDLE)pDevice,
SD_CISTPL_FUNCE, rgbFunce, &cbTuple, FALSE);
if ( SD_API_SUCCESS(status) && (pFunce->bType == SD_CISTPL_FUNCE_FUNCTION_TYPE) ) {
// Valid FUNCE tuple. Check the wake up support bit.
if (pFunce->FN_WUS) {
fRet = TRUE;
}
}
}
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
// SDCreateChildDevice - create a child device for a multifunction parent device
// Input: pParent - the parent device
// DeviceType - the device type
// FunctionNumber - function number
//
// Output: ppChildDevice - the new child device
// Return: SD_API_STATUS code
// Notes:
// This function adds a child device to a parent device. This
// allows us to keep track of multifunction devices.
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDCreateChildDevice(PSDCARD_DEVICE_CONTEXT pParent,
SDCARD_DEVICE_TYPE DeviceType,
UCHAR FunctionNumber,
PSDCARD_DEVICE_CONTEXT *ppChildDevice)
{
PSDCARD_DEVICE_CONTEXT pNewDevice;
// allocate a device
pNewDevice = ((CSDBusDriver *)pParent->pSystemContext)->AllocateDeviceContext();
if (NULL == pNewDevice) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: SDCreateChildDevice- , Failed to create device. \n")));
return SD_API_STATUS_INSUFFICIENT_RESOURCES;
}
// copy some parameters inherited from the parent device
pNewDevice->pSlot = pParent->pSlot;
pNewDevice->RelativeAddress = pParent->RelativeAddress;
pNewDevice->OperatingVoltage = pParent->OperatingVoltage;
if (Device_SD_IO == DeviceType) {
pNewDevice->SDCardInfo.SDIOInformation.Function = FunctionNumber;
}
// set the parent device
pNewDevice->pParentDevice = pParent;
// set new device type
pNewDevice->DeviceType = DeviceType;
if (Device_SD_IO == DeviceType) {
// copy the I/O Ocr
memcpy(&pNewDevice->CachedRegisters.IO_OCR,
&pParent->CachedRegisters.IO_OCR,
sizeof(pParent->CachedRegisters.IO_OCR));
} else if (Device_SD_Memory == DeviceType) {
// copy all the shadowed registers from the parent
memcpy(&pNewDevice->CachedRegisters,
&pParent->CachedRegisters,
sizeof(pParent->CachedRegisters));
} else {
DEBUGCHK(FALSE);
((CSDBusDriver *)pParent->pSystemContext)->DeleteClientDevice(pNewDevice);
return SD_API_STATUS_INVALID_PARAMETER;
}
// insert the device into the list
if (NULL == pParent->pNext) {
pNewDevice->pNext = NULL;
pParent->pNext = pNewDevice;
} else {
// insert at the head of the list
pNewDevice->pNext = pParent->pNext;
pParent->pNext = pNewDevice;
}
// return the device
*ppChildDevice = pNewDevice;
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// SDGetOperationalVoltageRange - Get the operation voltage range
// Input: OcrValue - OCR bit mask to determine the voltage range
// pSlot - the slot
//
// Output:
// Return: DWORD bit mask for optimal operational voltage
// Notes:
// This function compares the OcrValue against the desired
// voltage range of the slot and the capabilities of the slot
// the operational value (also encoded as an OCR value) is returned
// A value of zero indicates no usable voltage range.
///////////////////////////////////////////////////////////////////////////////
DWORD SDGetOperationalVoltageRange(DWORD OcrValue, PSDBUS_HC_SLOT_CONTEXT pSlot)
{
ULONG i; // loop variable
// check to see if the voltages can be supported
if (OcrValue & pSlot->VoltageWindowMask) {
// check to see if the voltage meets the desired voltage range
if (OcrValue & pSlot->DesiredVoltageMask) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Device Power Range:0x%08X matches HC desired power: 0x%08X \n"),
OcrValue, pSlot->DesiredVoltageMask));
// returned desired voltage range suggested by host controller
return pSlot->DesiredVoltageMask;
} else {
// walk through the voltage mask starting at the low end looking for
// a voltage that will work with the OCR value
for (i = 0; i < 32; i++) {
if (OcrValue & pSlot->VoltageWindowMask & (1 << i)) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Device Power Range:0x%08X does not match HC desired power 0x%08X \n"),
OcrValue, pSlot->DesiredVoltageMask));
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("Using negotiated power range: 0x%08X \n"),
(1 << i)));
// found a match
return (1 << i);
}
}
// this should never happen,
DEBUGCHK(FALSE);
return 0;
}
} else {
return 0;
}
}
///////////////////////////////////////////////////////////////////////////////
// SendSDAppCmd - send an SD App Command synchronously (sends CMD55 followed by command)
// Input: hDevice - device handle
// Command - command to send
// Argument - argument for command
// TransferClass - transfer class
// ResponseType - expected response
// NumberOfBlocks - number of blocks
// BlockSize - number of blocks
// pBlockBuffer - buffer size
// Output:
// pResponse - response buffer
// Return: SD_API_STATUS code
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SendSDAppCmd(SD_DEVICE_HANDLE hDevice,
UCHAR Command,
DWORD Argument,
SD_TRANSFER_CLASS TransferClass,
SD_RESPONSE_TYPE ResponseType,
PSD_COMMAND_RESPONSE pResponse,
DWORD NumberOfBlocks,
ULONG BlockSize,
PUCHAR pBlockBuffer)
{
SD_API_STATUS status; // intermediate status
PSDCARD_DEVICE_CONTEXT pDevice; // the device context
CSDBusDriver *pBusDriver; // the bus driver
ULONG retryCount; // retry count
ULONG i; // loop variable
DWORD clientFlags; // client flags backup
// send the APP Command primer (CMD 55)
status = SendSDCommand(hDevice,
SD_CMD_APP_CMD,
((DWORD)(((PSDCARD_DEVICE_CONTEXT)hDevice)->RelativeAddress)) << 16,
ResponseR1,
pResponse);
if (!SD_API_SUCCESS(status)){
return status;
}
// CMD55 did not timeout so send the command
if (CLIENT_HANDLES_RETRY(SDDCGetClientDeviceFromHandle(hDevice))) {
status = SDSynchronousBusRequest__X(hDevice,
Command,
Argument,
TransferClass,
ResponseType,
pResponse,
NumberOfBlocks,
BlockSize,
pBlockBuffer,
#ifdef ENABLE_SDIO_V1_1_SUPPORT
SD_SLOTRESET_REQUEST);
#else
0);
#endif //ENABLE_SDIO_V1_1_SUPPORT
}
else {
// handle app cmd retry here if client does not handle it,
// tell bus driver do not handle retry
pDevice = SDDCGetClientDeviceFromHandle(hDevice);
// save original ClientFlags
clientFlags = pDevice->ClientFlags;
pDevice->ClientFlags |= SD_CLIENT_HANDLES_RETRY;
pDevice = SDDCGetClientDeviceFromHandle(hDevice);
status = SDSynchronousBusRequest__X(hDevice,
Command,
Argument,
TransferClass,
ResponseType,
pResponse,
NumberOfBlocks,
BlockSize,
pBlockBuffer,
#ifdef ENABLE_SDIO_V1_1_SUPPORT
SD_SLOTRESET_REQUEST);
#else
0);
#endif //ENABLE_SDIO_V1_1_SUPPORT
if (!SD_API_SUCCESS(status)) {
pBusDriver = SDDCGetBusDriver((PSDCARD_DEVICE_CONTEXT)hDevice);
retryCount = pBusDriver->GetRetryCount();
for (i = 0; i < retryCount; i++) {
// check for retry
if ( !( (SD_API_STATUS_RESPONSE_TIMEOUT == status) ||
(SD_API_STATUS_DATA_TIMEOUT == status) ||
(SD_API_STATUS_CRC_ERROR == status) ) ) {
break;
}
// send the APP Command primer (CMD55)
status = SendSDCommand(hDevice,
SD_CMD_APP_CMD,
((DWORD)(((PSDCARD_DEVICE_CONTEXT)hDevice)->RelativeAddress)) << 16,
ResponseR1,
pResponse);
if (!SD_API_SUCCESS(status)){
break;
}
// send the command again
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -