📄 sdbusrequest.cpp
字号:
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);
DEBUGCELOGMSG(SDCARD_ZONESLOT_CELOG,(TEXT("+SDBusRequest__X(Command=%x,Argument=%x,NumBlocks=%x,BlockSize=%x)\r\n"),
(DWORD)Command,Argument,NumBlocks,BlockSize));
__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 = (DWORD)-1;//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;
pOptionalRequest = NULL;
UCHAR ucSDIOFlags = pDevice->SDCardInfo.SDIOInformation.Flags;
if (((SD_CMD_READ_MULTIPLE_BLOCK != pNewRequest->CommandCode) ||
(0 == (ucSDIOFlags & (SFTBLK_USE_FOR_CMD18 | SFTBLK_USE_ALWAYS)))) &&
((SD_CMD_WRITE_MULTIPLE_BLOCK != pNewRequest->CommandCode) ||
(0 == (ucSDIOFlags & (SFTBLK_USE_FOR_CMD25 | SFTBLK_USE_ALWAYS )))) &&
(0 == (ucSDIOFlags & SFTBLK_USE_ALWAYS)))
{
// check for optional request
pOptionalRequest = BuildOptionalRequest(pDevice,
pBusDriver,
#ifdef __MOVINAND_SUPPORT__
Flags,
pNewRequest->NumBlocks
#else
Flags
#endif
);
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);
}
}
// Determine if Fast-Path should be used for this request.
if ( 0 != ( Flags & SD_SYNCHRONOUS_REQUEST ))
{
// Use Fast-Path for this request.
pNewRequest->SystemFlags |= SD_FAST_PATH_AVAILABLE;
}
#ifdef ENABLE_SDIO_V1_1_SUPPORT
if ( 0 != (Flags & SD_SLOTRESET_REQUEST )) {
// mark this request as resetting slot request
// bus driver will only allow this type of request to pass
// when slot state is SlotResetting
pNewRequest->SystemFlags |= SD_BUS_REQUEST_SLOT_RESET;
}
#endif //ENABLE_SDIO_V1_1_SUPPORT
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDBusDriver: Submitting bus request:0x%08X to device %s \n"),pNewRequest,
SDDCGetClientName(pDevice)));
// submit the main request
#ifdef __MOVINAND_SUPPORT__
// send CMD23 before CMD18, CMD25 in pre-defined mode
if((pDevice->DeviceType == Device_MMC) && (pOptionalRequest != NULL) && (pDevice->dwWhatIsCardType == 0))
{
status = pBusDriver->SubmitBusRequest(pOptionalRequest);
}
else
status = pBusDriver->SubmitBusRequest(pNewRequest);
#else
status = pBusDriver->SubmitBusRequest(pNewRequest);
#endif
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)));
#ifdef __MOVINAND_SUPPORT__
// if the device type is MMC, pre-defined mode is used
if ((pDevice->DeviceType == Device_MMC) && (pDevice->dwWhatIsCardType == 0) )
{
if (!SD_API_SUCCESS(pBusDriver->SubmitBusRequest(pNewRequest))) {
// free the request, it didn't make it down
pBusDriver->FreeBusRequest(pNewRequest);
// 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
}
}
else
// if the device type is SD card, open-ended mode is used
{
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
}
}
#else
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
}
#endif
}
}
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);
}
}
DEBUGCELOGMSG(SDCARD_ZONESLOT_CELOG,(TEXT("-SDBusRequest__X:status=%x\r\n"),status));
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -