📄 sdhceventhandlers.cpp
字号:
pDevice->SDCardInfo.SDIOInformation.Function));
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT(" OpMinPower %d mA\r\n"), pDevice->SDCardInfo.SDIOInformation.PowerDrawData.OpMinPower));
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT(" OpAvePower %d mA\r\n"), pDevice->SDCardInfo.SDIOInformation.PowerDrawData.OpAvePower));
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT(" OpMaxPower %d mA\r\n"), pDevice->SDCardInfo.SDIOInformation.PowerDrawData.OpMaxPower));
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT(" SpAvePower33 %d mA\r\n"), pDevice->SDCardInfo.SDIOInformation.PowerDrawData.SpAvePower33));
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT(" SpAvePower33 %d mA\r\n"), pDevice->SDCardInfo.SDIOInformation.PowerDrawData.SpMaxPower33));
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT(" HpAvePower33 %d mA\r\n"), pDevice->SDCardInfo.SDIOInformation.PowerDrawData.HpAvePower33));
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT(" HpMaxPower33 %d mA\r\n"), pDevice->SDCardInfo.SDIOInformation.PowerDrawData.HpMaxPower33));
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT(" LpAvePower33 %d mA\r\n"), pDevice->SDCardInfo.SDIOInformation.PowerDrawData.LpAvePower33));
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT(" LpMaxPower33 %d mA\r\n"), pDevice->SDCardInfo.SDIOInformation.PowerDrawData.LpMaxPower33));
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// SDGetSDIOPnpInformation - Get SDIO PnP information for an SDIO device function
// Input: pDevice - the device context
// Parent - this is the parent device
// Output:
// Return: SD_API_STATUS code
// Notes:
// This function collects SDIO Pnp information for the device.
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDGetSDIOPnpInformation(PSDCARD_DEVICE_CONTEXT pDevice, BOOL Parent)
{
SD_API_STATUS status; // intermediate status
UCHAR regValue[4]; // most tuples are 4 bytes
UCHAR CSA_CISBuffer[CIS_CSA_BYTES]; // CIS and CSA are in contiguous locations
DWORD FBROffset; // calculated FBR offset
DWORD manFid; // manufacturer ID
ULONG length; // buffer length
BOOL found; // CIS found flag
PCHAR pVersionBuffer; // tuple buffer for vers1 info
status = SD_API_STATUS_SUCCESS;
// for the parent device save the common information
if (Parent) {
// allocate the common information
pDevice->SDCardInfo.SDIOInformation.pCommonInformation = (PSDIO_COMMON_INFORMATION)
SDAllocateMemoryWithTag(sizeof(SDIO_COMMON_INFORMATION),
SD_BUS_DRIVER_TAG);
if (NULL == pDevice->SDCardInfo.SDIOInformation.pCommonInformation) {
return SD_API_STATUS_INSUFFICIENT_RESOURCES;
}
// get the CCCR
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // all from function 0
SD_IO_REG_CCCR,
FALSE,
regValue,
1);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to get CCCR \n")));
return status;
}
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRRev = regValue[0];
// 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,
regValue,
1);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to get CARD CAPABILITY register \n")));
return status;
}
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CardCapability = regValue[0];
// get the SD Spec rev
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // all from function 0
SD_IO_REG_SPEC_REV,
FALSE,
regValue,
1);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to get SD Spec revision \n")));
return status;
}
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->SDSpec = regValue[0];
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: SDIO Card Function %d, CCCR 0x%02X , Card Caps: 0x%02X, Spec Ver: %d \n"),
pDevice->SDCardInfo.SDIOInformation.Function,
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRRev,
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CardCapability,
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->SDSpec));
// get the CIS pointer
// function 0 only has a CIS, no CSA
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // all from function 0
SD_IO_REG_COMMON_CIS_POINTER,
FALSE,
CSA_CISBuffer,
SD_IO_CIS_PTR_BYTES);
if (!SD_API_SUCCESS(status)) {
return status;
}
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CommonCISPointer = CSA_CISBuffer[CIS_OFFSET_BYTE_0] |
(CSA_CISBuffer[CIS_OFFSET_BYTE_1] << 8) |
(CSA_CISBuffer[CIS_OFFSET_BYTE_2] << 16);
#if 0
// for Debugging a bad CIS only
{
UCHAR tupleBuffer[256];
status = SDReadWriteRegistersDirect((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // all from function 0
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CommonCISPointer,
FALSE,
tupleBuffer,
256);
if (SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Common CIS Pointer: 0x%08X \n"),
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CommonCISPointer));
SDOutputBuffer(tupleBuffer, 256);
}
}
#endif
length = SD_CISTPL_MANFID_BODY_SIZE;
// for function 0 get the Manufacturer ID (this is not the same as the VER1 string)
status = SDGetTuple__X((SD_DEVICE_HANDLE)pDevice,
SD_CISTPL_MANFID,
(PUCHAR)&manFid,
&length,
TRUE);
if (!SD_API_SUCCESS(status)) {
return status;
}
if (0 == length) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Card is missing CISTPL_MANFID \n")));
status = SD_API_STATUS_DEVICE_UNSUPPORTED;
return status;
}
// set Manufacturer and CardID
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID = (USHORT)manFid;
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CardID = (USHORT)(manFid >> 16);
// retrieve the ver_1 tuple to retrieve the manufacturer string
length = 0;
// query the size of the tuple from the common CIS
// the VERS_1 tuple is a variable length tuple
status = SDGetTuple__X((SD_DEVICE_HANDLE)pDevice,
SD_CISTPL_VERS_1,
NULL,
&length,
TRUE);
if (!SD_API_SUCCESS(status)) {
return status;
}
if (0 != length ) {
found = TRUE;
} else {
// the VER_1 tuple is optional, so if we could not find it, we
// allocate the string identifying it as unknown
found = FALSE;
length = UNKNOWN_PRODUCT_INFO_STRING_LENGTH;
}
// allocate the string (include NULL) even if no tuple
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->pProductInformation =
(PWCHAR)SDAllocateMemoryWithTag((sizeof(WCHAR)) * (length + 1),
SD_BUS_DRIVER_TAG);
if (NULL == pDevice->SDCardInfo.SDIOInformation.pCommonInformation->pProductInformation) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to allocate product information string \n")));
return SD_API_STATUS_INSUFFICIENT_RESOURCES;
}
if (found) {
pVersionBuffer = (PCHAR)SDAllocateMemoryWithTag((sizeof(CHAR)) * (length + 1),
SD_BUS_DRIVER_TAG);
if (NULL == pVersionBuffer) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to allocate product information string \n")));
return SD_API_STATUS_INSUFFICIENT_RESOURCES;
}
// retrieve the tuple from the common CIS
status = SDGetTuple__X((SD_DEVICE_HANDLE)pDevice,
SD_CISTPL_VERS_1,
(PUCHAR)pVersionBuffer,
&length,
TRUE);
if (!SD_API_SUCCESS(status)) {
SDFreeMemory(pVersionBuffer);
return status;
}
// make sure the string is null terminated
pVersionBuffer[length] = NULL;
// bump past the binary version info,
// and format the string to wide char
FormatProductString(&pVersionBuffer[2],
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->pProductInformation);
// free the version buffer
SDFreeMemory(pVersionBuffer);
} else {
// form the product name based on the required MANF and CARDID instead of the
// ver1 string
swprintf( pDevice->SDCardInfo.SDIOInformation.pCommonInformation->pProductInformation,
TEXT("Manufacturer ID:0x%04X, Card ID:0x%04X"),
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID,
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CardID);
}
// enable power control on the card if available
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->fCardSupportsPowerControl = FALSE;
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->fPowerControlEnabled = FALSE;
if((pDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRRev //only attempt on 1.1 cards
& SDIO_CCCR_SPEC_REV_MASK) == SDIO_CCCR_SPEC_REV_1_1)
{
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // all from function 0
SD_IO_REG_POWER_CONTROL,
FALSE,
regValue,
1);
if (SD_API_SUCCESS(status) &&
(*regValue & SD_IO_CARD_POWER_CONTROL_SUPPORT))
{
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->fCardSupportsPowerControl = TRUE;
if(SDHCDGetSlotEnablePowerControl(pDevice->pSlot->pHostController, pDevice->pSlot->SlotIndex))
{
*regValue |= SD_IO_CARD_POWER_CONTROL_ENABLE;
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_WRITE,
0, // function 0
SD_IO_REG_POWER_CONTROL,
FALSE,
regValue,
1);
if (SD_API_SUCCESS(status))
{
DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Power Control Enabled for SDIO Card.\n")));
pDevice->SDCardInfo.SDIOInformation.pCommonInformation->fPowerControlEnabled = TRUE;
}
}
}
}
}
// function 0 is a fictitious function
DEBUGCHK(0 != pDevice->SDCardInfo.SDIOInformation.Function);
// calculate the FBR offset
FBROffset = SD_IO_FBR_1_OFFSET + (pDevice->SDCardInfo.SDIOInformation.Function - 1) *
SD_IO_FBR_LENGTH;
// fetch the device code
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // all from function 0
FBROffset + SD_IO_FBR_DEVICE_CODE,
FALSE,
regValue,
1);
if (!SD_API_SUCCESS(status)) {
return status;
}
// save the device code, 1.0 style
pDevice->SDCardInfo.SDIOInformation.DeviceCode =
(regValue[0] & SDIO_DEV_CODE_MASK);
// check to see if we are using the special device code extension token
if (SDIO_DEV_CODE_USES_EXTENSION ==
pDevice->SDCardInfo.SDIOInformation.DeviceCode) {
if (NULL == pDevice->pParentDevice) {
status = SD_API_STATUS_UNSUCCESSFUL;
return status;
}
// check the CCCR revision for 1.1
if ((pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRRev
& SDIO_CCCR_SPEC_REV_MASK) == SDIO_CCCR_SPEC_REV_1_1) {
// fetch the device code extension
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0,
FBROffset + SD_IO_FBR_DEVICE_CODE_EXT,
FALSE,
regValue,
1);
if (!SD_API_SUCCESS(status)) {
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -