📄 sdbusrequest.cpp
字号:
DWORD Argument,
SD_TRANSFER_CLASS TransferClass,
SD_RESPONSE_TYPE ResponseType,
ULONG NumBlocks,
ULONG BlockSize,
PUCHAR pBuffer,
PSD_BUS_REQUEST_CALLBACK pCallback,
DWORD RequestParam,
HBUS_REQUEST *phRequest,
DWORD Flags)
{
CSDBusDriver *pBusDriver; // the bus driver
PSDBUS_BUS_REQUEST pNewRequest; // the new request
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
PSDBUS_BUS_REQUEST pOptionalRequest = NULL; // optional request to send down
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SDBusRequest+ \n")));
PSDCARD_DEVICE_CONTEXT pDevice = (PSDCARD_DEVICE_CONTEXT) hDevice;
if (!ValidateClientHandle(pDevice)) {
return SD_API_STATUS_INVALID_HANDLE;
}
if( pCallback == NULL ) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- Callback missing \n")));
return SD_API_STATUS_INVALID_PARAMETER;;
}
if( phRequest == NULL ) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- caller supplied storage is NULL \n")));
return SD_API_STATUS_INVALID_PARAMETER;;
}
if( TransferClass == SD_READ || TransferClass == SD_WRITE ) {
if( NumBlocks == 0 ) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- No transfer buffers passed \n")));
return SD_API_STATUS_INVALID_PARAMETER;
}
// check pointer to see if block array ptr is non-NULL
if( pBuffer == NULL ) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- NULL buffer pointer passed \n")));
return SD_API_STATUS_INVALID_PARAMETER;
}
}
// pre-increment the reference count to keep the device object alive
SDDCIncrementRefCount(pDevice);
__try {
// get the bus driver
pBusDriver = SDDCGetBusDriver(pDevice);
// allocate a request
pNewRequest = pBusDriver->AllocateBusRequest();
if (pNewRequest == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- failed to allocate bus request \n")));
status = SD_API_STATUS_UNSUCCESSFUL;
} else {
pNewRequest->ListEntry.Flink = NULL;
pNewRequest->ListEntry.Blink = NULL;
pNewRequest->hDevice = hDevice;
pNewRequest->SystemFlags = 0;
pNewRequest->TransferClass = TransferClass;
pNewRequest->CommandCode = Command;
pNewRequest->CommandArgument = Argument;
pNewRequest->CommandResponse.ResponseType = ResponseType;
pNewRequest->RequestParam = RequestParam;
pNewRequest->NumBlocks = NumBlocks;
pNewRequest->BlockSize = BlockSize;
pNewRequest->HCParam = 0;
pNewRequest->pBlockBuffer = pBuffer;
pNewRequest->pCallback = pCallback;
pNewRequest->DataAccessClocks = 0; // reset data access clocks
pNewRequest->Flags = Flags;
// get the current thread permissions for the block buffer
pNewRequest->CurrentPermissions = GetCurrentPermissions();
// only memory cards have this property
if ((Device_SD_Memory == pDevice->DeviceType) ||
(Device_MMC == pDevice->DeviceType)) {
if (TransferClass == SD_READ) {
// set for read
pNewRequest->DataAccessClocks = pDevice->SDCardInfo.SDMMCInformation.DataAccessReadClocks;
} else if (TransferClass == SD_WRITE) {
// set write
pNewRequest->DataAccessClocks = pDevice->SDCardInfo.SDMMCInformation.DataAccessWriteClocks;
}
}
// set the retry count
SDRequestSetRetryCount(pNewRequest, pBusDriver->GetRetryCount());
// return the request to the caller
DEBUGCHK(ValidateRequest(pNewRequest));
*phRequest = pNewRequest;
// check for optional request
pOptionalRequest = BuildOptionalRequest(pDevice,
pBusDriver,
Flags);
if (pOptionalRequest != NULL) {
// increment ref count for the optional request
SDDCIncrementRefCount(pDevice);
// must interlock this request with the parent device
// so we can atomically add this in the queue
SDDCAcquireDeviceLock(pDevice->pParentDevice);
}
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDBusDriver: Submitting bus request:0x%08X to device %s \n"),pNewRequest,
SDDCGetClientName(pDevice)));
// submit the main request
status = pBusDriver->SubmitBusRequest(pNewRequest);
if (!SD_API_SUCCESS(status)) {
// free the request, it did not make it down
pBusDriver->FreeBusRequest(pNewRequest);
// free the optional request too
if (pOptionalRequest != NULL) {
pBusDriver->FreeBusRequest(pOptionalRequest);
}
} else {
// now submit the optional request if one is required
if (pOptionalRequest != NULL) {
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDBusDriver: Submitting optional request:0x%08X to device %s \n"),pOptionalRequest,
SDDCGetClientName(pDevice)));
// while we have the parent lock held add the optional
// request in behind this original request
if (!SD_API_SUCCESS(pBusDriver->SubmitBusRequest(pOptionalRequest))) {
// free the request, it didn't make it down
pBusDriver->FreeBusRequest(pOptionalRequest);
// decrement ref count
SDDCDecrementRefCount(pDevice);
// we leave status alone since the previous
// command succeeded we let that get processed normally
// nothing we can really do here
}
}
}
if (pOptionalRequest != NULL) {
// unlock
SDDCReleaseDeviceLock(pDevice->pParentDevice);
}
}
} __except (SDProcessException(GetExceptionInformation())) {
status = SD_API_STATUS_UNSUCCESSFUL;
}
if (!SD_API_SUCCESS(status)) {
// never made it down
SDDCDecrementRefCount(pDevice);
// if the main request never made it down, the optional request
// would not have either
if (pOptionalRequest != NULL) {
SDDCDecrementRefCount(pDevice);
}
}
DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SDBusRequest-\n")));
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDFreeBusRequest__X - free this request
// Input: pRequest - the request to free
// Output:
// Return:
// Notes:
// this function returns the bus request back to the memory look aside
// list
///////////////////////////////////////////////////////////////////////////////
VOID SDFreeBusRequest__X(HBUS_REQUEST hRequest)
{
PSDBUS_BUS_REQUEST pRequest = (PSDBUS_BUS_REQUEST) hRequest;
if ( !ValidateRequest(pRequest) || (pRequest->hDevice == NULL) ) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDFreeBusRequest: Invalid request\n")));
}
else {
PSDCARD_DEVICE_CONTEXT pDevice =
SDDCGetClientDeviceFromHandle(pRequest->hDevice);
DEBUGCHK(pDevice);
CSDBusDriver *pBusDriver = SDDCGetBusDriver(pDevice);
DEBUGCHK(pBusDriver);
pBusDriver->FreeBusRequest(pRequest);
}
}
///////////////////////////////////////////////////////////////////////////////
// SDCancelBusRequest__X - Cancel an outstanding bus request
// Input:
// pRequest - request to cancel (returned from SDBusRequest)
// Output:
// Return: TRUE if request was cancelled , FALSE if the request is still pending
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN SDCancelBusRequest__X(HBUS_REQUEST hRequest)
{
PSDBUS_BUS_REQUEST pRequest = (PSDBUS_BUS_REQUEST) hRequest;
PSDBUS_HC_SLOT_CONTEXT pSlot; // slot
PSDBUS_BUS_REQUEST pCurrentRequest; // current request
BOOL fRet = FALSE;
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: +SDCancelBusRequest\n")));
if (!ValidateRequest(pRequest)) {
goto EXIT;
}
// get some pointers
PSDCARD_DEVICE_CONTEXT pDevice;
pDevice = SDDCGetClientDeviceFromHandle(pRequest->hDevice);
PREFAST_DEBUGCHK(pDevice != NULL);
pSlot = pDevice->pSlot;
PREFAST_DEBUGCHK(pSlot != NULL);
SDHCDAcquireHCLock(pSlot->pHostController);
if (!IS_SD_REQUEST_CANCELABLE(pRequest)) {
// this request is not cancelable
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: Request 0x%08X on slot:%d is not cancelable \n"),
pRequest, pSlot->SlotIndex));
SDHCDReleaseHCLock(pSlot->pHostController);
goto EXIT;
}
// get the current request
pCurrentRequest = (PSDBUS_BUS_REQUEST) SDGetCurrentRequest(&pSlot->RequestQueue);
// is this the current request?
if (pRequest == pCurrentRequest) {
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: Request 0x%08X on slot:%d is the current request, calling HC to cancel \n"),
pRequest, pSlot->SlotIndex));
// NOTE: DO NOT RELEASE THE HC LOCK HERE!
// do not release the lock here, the host controller's cancel callback has to release the HC lock
fRet = pSlot->pHostController->pCancelIOHandler(pSlot->pHostController,
pSlot->SlotIndex, pRequest);
goto EXIT;
}
// make sure the caller didn't cancel a request that wasn't in a queue
if (NULL == pRequest->ListEntry.Flink) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCancelBusRequest: Request 0x%08X on slot:%d is not in a queue! \n"),
pRequest, pSlot->SlotIndex ));
SDHCDReleaseHCLock(pSlot->pHostController);
goto EXIT;
}
// remove the entry
SDRemoveEntryFromQueue(&pSlot->RequestQueue, pRequest);
// release the lock
SDHCDReleaseHCLock(pSlot->pHostController);
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: Request 0x%08X on slot:%d is in the queue, removing request, completing.... \n"),
pRequest, pSlot->SlotIndex));
// set the status
pRequest->Status = SD_API_STATUS_CANCELED;
// complete the request
SDCompleteBusRequest(pRequest);
fRet = TRUE;
EXIT:
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: -SDCancelBusRequest\n")));
return fRet;
}
#if DEBUG
///////////////////////////////////////////////////////////////////////////////
// DumpParsedCSDRegisters- dump parsed register data to the debugger
// Input: pParsedCSD - the Parsed CSD structure
// Output:
//
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID DumpParsedCSDRegisters(PSD_PARSED_REGISTER_CSD pParsedCSD)
{
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("\n\n\nSDCard: Dumping parsed Registers : \n")));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Version:%d \n"),pParsedCSD->CSDVersion));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" TAAC: %f ns \n"),pParsedCSD->DataAccessTime.TAAC));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" NSAC: %d clocks \n"),pParsedCSD->DataAccessTime.NSAC));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" MaxDataTransferRate: %d kb/s \n"),pParsedCSD->MaxDataTransferRate));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Card Command Classes: 0x%04X \n"),pParsedCSD->CardCommandClasses));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Max Read Block Length: %d bytes \n"),pParsedCSD->MaxReadBlockLength));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Read Block Partial? : %d \n"),pParsedCSD->ReadBlockPartial));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Max Write Block Length: %d bytes \n"),pParsedCSD->MaxWriteBlockLength));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Write Block Partial? : %d \n"),pParsedCSD->WriteBlockPartial));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Write Block Misaligned? : %d \n"),pParsedCSD->WriteBlockMisalign));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Read Block Misaligned? : %d \n"),pParsedCSD->ReadBlockMisalign));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" DSR Implemented? : %d \n"),pParsedCSD->DSRImplemented));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Device Size : %d bytes \n"),pParsedCSD->DeviceSize));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" VDD Read Current Min : %d mA \n"),pParsedCSD->VDDReadCurrentMin));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" VDD Read Current Max : %d mA \n"),pParsedCSD->VDDReadCurrentMax));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" VDD Write Current Min : %d mA \n"),pParsedCSD->VDDWriteCurrentMin));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" VDD Write Current Max : %d mA \n"),pParsedCSD->VDDWriteCurrentMax));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Erase Block Enabled?: %d \n"),pParsedCSD->EraseBlockEnable));
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Erase Sector Size: %d blocks \n"),pParsedCSD->EraseSectorSize));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -