📄 sdbusrequest.cpp
字号:
pCardInfo,
sizeof(SD_HOST_BLOCK_CAPABILITY));
}
///////////////////////////////////////////////////////////////////////////////
// SDCardInfoQuery__X - Obtain Card information
// Input: hHandle - SD Device Handle
// InfoType - information to get
// StructureSize - size of info structure
// Output: pCardInfo - Information specific structure
// Return: SD_API_STATUS code
// Notes: pCardInfo must point to sufficient memory for the informtion type
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDCardInfoQuery__X( IN SD_DEVICE_HANDLE hDevice,
IN SD_INFO_TYPE InfoType,
OUT PVOID pCardInfo,
IN ULONG StructureSize)
{
struct InfoQuery {
ULONG cbTypeStructure;
SD_API_STATUS (*pfnInfoQuery)(PSDCARD_DEVICE_CONTEXT, PVOID, ULONG);
} static const rgiq[] = {
{ 0, NULL }, // SD_INFO_REGISTER_OCR is not supported
{ sizeof(SD_PARSED_REGISTER_CID), InfoQueryCID },
{ sizeof(SD_PARSED_REGISTER_CSD), InfoQueryCSD },
{ sizeof(SD_CARD_RCA), InfoQueryRCA },
{ 0, NULL }, // SD_INFO_REGISTER_IO_OCR is not supported
{ sizeof(SD_CARD_INTERFACE), InfoQueryCardInterface },
{ sizeof(SD_CARD_STATUS), InfoQueryStatus },
{ sizeof(SDIO_CARD_INFO), InfoQuerySDIOInfo },
{ sizeof(SD_CARD_INTERFACE), InfoQueryHostInterface },
{ sizeof(SD_HOST_BLOCK_CAPABILITY), InfoQueryBlockCaps },
};
DEBUGCHK(dim(rgiq) == SD_INFO_TYPE_COUNT);
SD_API_STATUS status = SD_API_STATUS_INVALID_PARAMETER;
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: +SDCardInfoQuery\n")));
PSDCARD_DEVICE_CONTEXT pDevice = (PSDCARD_DEVICE_CONTEXT) hDevice;
if (!ValidateClientHandle(pDevice)) {
return SD_API_STATUS_INVALID_HANDLE;
}
if( NULL == pCardInfo) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCardInfoQuery: NULL pCardInfo passed\nSDCard: -SDCardInfoQuery\n")));
}
else if (InfoType >= dim(rgiq)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCardInfoQuery: invalid info type : %d \n"),
InfoType));
}
else {
const InfoQuery *piq = &rgiq[InfoType];
if (StructureSize != piq->cbTypeStructure) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCardInfoQuery: invalid size\n")));
}
else if (piq->pfnInfoQuery == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCardInfoQuery: invalid info type : %d \n"),
InfoType));
}
else {
// Finally we can call the query-handling function.
status = (*piq->pfnInfoQuery)(pDevice, pCardInfo, StructureSize);
}
}
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: -SDCardInfoQuery\n")));
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDGetTupleBytes - Gets tuple bytes at the current tuple offset
// Input: hDevice - SD bus device handle
// Offset - offset from the CIS pointer
// NumberOfBytes - number of bytes to fetch
// CommonCIS - flag indicating that this is fetched from the common CIS
// Output: pBuffer - Tuple data is copied here (optional)
// Return: SD_API_STATUS code
//
// Notes:
// If the Buffer pointer is NULL, the function does not fetch the bytes
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDGetTupleBytes(PSDCARD_DEVICE_CONTEXT pDevice,
DWORD Offset,
PUCHAR pBuffer,
ULONG NumberOfBytes,
BOOL CommonCIS)
{
SD_API_STATUS status; // intermediate status
DWORD tupleAddress; // calculated tuple address
PREFAST_DEBUGCHK(pDevice);
status = SD_API_STATUS_SUCCESS;
if (pDevice->DeviceType!= Device_SD_IO) {
return SD_API_STATUS_INVALID_PARAMETER;
}
if (CommonCIS) {
DEBUGCHK(NULL != pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation);
DEBUGCHK(0 != pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CommonCISPointer);
// the tuple starting address is at the common CIS pointer
tupleAddress = pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CommonCISPointer;
} else {
DEBUGCHK(0 != pDevice->SDCardInfo.SDIOInformation.CISPointer);
// the tuple starting address is at the function CIS pointer
tupleAddress = pDevice->SDCardInfo.SDIOInformation.CISPointer;
}
// add the desired offset
tupleAddress += Offset;
if (NULL != pBuffer) {
status = SDReadWriteRegistersDirect__X( (SD_DEVICE_HANDLE) pDevice,
SD_IO_READ,
0, // always function 0
tupleAddress,
FALSE,
pBuffer,
NumberOfBytes);
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDGetTuple__X - Get tuple data from CIS
// Input: hDevice - SD bus device handle
// TupleCode - Tuple code
// pBufferSize - size of buffer to store Tuple Data
// CommonCIS - flag indicating common or function CIS
// Output: pBuffer - Tuple data is copied here (optional)
// pBufferSize - if pBuffer is NULL, this will store the size of the
// tuple
// Return: SD_API_STATUS code
//
// Notes: The caller should initially call this function with a NULL buffer
// to determine the size of the tuple. The variable pBufferSize points
// to the caller supplied storage for this result. If no bus errors occurs
// the function returns SD_API_STATUS_SUCCESS. The caller must check
// the value of the buffer size returned. If the value is non-zero, the
// tuple exists and can be fetched by calling this function again with a
// non-zero buffer.
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDGetTuple__X(SD_DEVICE_HANDLE hDevice,
UCHAR TupleCode,
PUCHAR pBuffer,
PULONG pBufferSize,
BOOL CommonCIS)
{
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
UCHAR tCode; // tuple code we've read so far
UCHAR tupleLink; // tuple link offset
ULONG currentOffset; // current offset
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: +SDGetTuple\n")));
PSDCARD_DEVICE_CONTEXT pDevice = (PSDCARD_DEVICE_CONTEXT) hDevice;
if (!ValidateClientHandle(pDevice)) {
return SD_API_STATUS_INVALID_HANDLE;
}
if (NULL == pBufferSize) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDGetTuple: NULL buffer size \n")));
return SD_API_STATUS_INVALID_PARAMETER;
}
if (pBuffer == NULL) {
// Initialize pBufferSize to zero to indicate that the tuple
// was not found
*pBufferSize = 0;
}
// acquire the device lock , only one thread can enter this call
SDAcquireDeviceLock(hDevice);
currentOffset = 0;
// walk through the CIS
while (TRUE) {
// get 1 byte at the current position
status = SDGetTupleBytes(pDevice , currentOffset, &tCode, 1, CommonCIS);
if (!SD_API_SUCCESS(status)) {
break;
}
// add the tCode
currentOffset += 1;
if(SD_CISTPL_END == tCode) {
// this is the End of chain Tuple
// break out of while loop
break;
} else {
// get the tuple link offset in the next byte, we always need this
// value, so we fetch it before we compare the tuple code
status = SDGetTupleBytes(pDevice, currentOffset, &tupleLink, 1, CommonCIS);
if (!SD_API_SUCCESS(status)) {
break;
}
// add the link
currentOffset += 1;
// check for the end link flag, this is the alternative method to stop
// tuple scanning
if (SD_TUPLE_LINK_END == tupleLink) {
// we reached an end of chain
break;
}
// go back and check the tuple code
if (tCode == TupleCode) {
// found it
// check to see if the caller is interested in the data
if (NULL != pBuffer) {
// if the user passed a buffer, they must pass the buffer size, double check the length
if (*pBufferSize < tupleLink) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDGetTuple, caller supplied buffer of size: %d bytes but tuple body (code=0x%02X) reports size of %d bytes\n"),
*pBufferSize, tCode, tupleLink));
status = SD_API_STATUS_INVALID_PARAMETER;
break;
}
// fetch the tuple body
status = SDGetTupleBytes(pDevice ,
currentOffset,
pBuffer,
tupleLink,
CommonCIS);
} else {
// return the size of the tuple body we just found, no need to fetch
*pBufferSize = tupleLink;
}
// break out of the while loop
break;
} else {
// add the value of the link
currentOffset += tupleLink;
}
}
}
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: -SDGetTuple\n")));
SDReleaseDeviceLock(hDevice);
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SubmitBusRequest - submit the bus request
// Input: pRequest
// Output:
// Return: SD_API_STATUS code
// Notes:
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDBusDriver::SubmitBusRequest(PSDBUS_BUS_REQUEST pRequest)
{
PSDBUS_HC_SLOT_CONTEXT pSlot; // the slot
PSDBUS_HC_CONTEXT pHostController; // the host controller
SD_API_STATUS status = SD_API_STATUS_PENDING; // status
// get the slot from the device
pSlot = (SDDCGetClientDeviceFromHandle(pRequest->hDevice))->pSlot;
pHostController = pSlot->pHostController;
// acquire the HC lock
SDHCDAcquireHCLock(pHostController);
// check to see if the slot is ready
status = CheckSlotReady(pSlot);
if (!SD_API_SUCCESS(status)) {
SDHCDReleaseHCLock(pHostController);
return status;
}
// queue the request
SDQueueBusRequest(&pSlot->RequestQueue, pRequest);
// check to see if the new request we just queued is the current one
// meaning that the queue was previously empty
if (SDGetCurrentRequest(&pSlot->RequestQueue) == pRequest) {
// before we submit to the host controller, mark this request as non-cancelable
// it is now up to the HC to determine if the request will remain cancelable
SD_REQUEST_MARK_NON_CANCELABLE(pRequest);
// mark that the request has been submitted and is now being worked on
SD_REQUEST_MARK_BUSY(pRequest);
SDHCDReleaseHCLock(pHostController);
status = SubmitToHC(pHostController, pSlot->SlotIndex, pRequest);
if (!SD_API_SUCCESS(status)) {
// acquire the HC lock
SDHCDAcquireHCLock(pHostController);
// if submission failed, dequeue the request
SDDequeueBusRequest(&pSlot->RequestQueue);
SDHCDReleaseHCLock(pHostCon
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -