📄 sdhcenum.cpp
字号:
// Fast-Path prevents stack overflow by postponing the start of the
// next block until control returns to SubmitToHC.
if ( SD_API_STATUS_FAST_PATH_SUCCESS != Status )
{
// If Fast-Path is enabled for the next portion of the transfer
// the exit paths become too complex. Prevent Fast-Path for all
// future portions of this transfer.
pRequest->SystemFlags &= ~ SD_FAST_PATH_AVAILABLE;
// Transfer the next segment of data.
Status = pHost->pBusRequestHandler(pHost, pSlot->SlotIndex, pRequest);
}
if ( SD_API_SUCCESS ( Status ))
{
// The request is still being processed, or it is complete.
return;
}
}
}
// The Soft-Block request is complete.
// Restore the original request.
SD_REQUEST_NO_SOFT_BLOCK ( pRequest );
pRequest->CommandCode = pDevice->SDCardInfo.SDIOInformation.SoftBlockCommand;
pRequest->CommandArgument = pDevice->SDCardInfo.SDIOInformation.SoftBlockArgument;
pRequest->NumBlocks = pDevice->SDCardInfo.SDIOInformation.SoftBlockCount;
pRequest->BlockSize = pDevice->SDCardInfo.SDIOInformation.SoftBlockSize;
pRequest->pBlockBuffer = pDevice->SDCardInfo.SDIOInformation.pSoftBlockBuffer;
}
if ( SD_API_STATUS_FAST_PATH_SUCCESS != Status )
{
if (!SD_API_SUCCESS(Status)) {
// check for retry
if ((SD_API_STATUS_RESPONSE_TIMEOUT == Status) ||
(SD_API_STATUS_DATA_TIMEOUT == Status) ||
(SD_API_STATUS_CRC_ERROR == Status)) {
// issue a retry only if the client doesn't handle them
if (!(CLIENT_HANDLES_RETRY(
SDDCGetClientDeviceFromHandle(pRequest->hDevice)))) {
// only retry if the slot is still ready
// a device ejection may have caused the timeout error
if (SD_API_SUCCESS(CheckSlotReady(pSlot))) {
// check retry count
if (SDRequestGetRetryCount(pRequest) != 0) {
DbgPrintZo(SDCARD_ZONE_WARN,
(TEXT("SDBusDriver: Retrying request 0x%08X , Current retry count: %d \n"),
pRequest,SDRequestGetRetryCount(pRequest)));
// decrement retry count
SDDecrementRetryCount(pRequest);
pRequest->HCParam = 0;
// release the lock
SDHCDReleaseHCLock(pHCContext);
// Don't complicate the error processing by allowing a subsequent
// request to complete with Fast-Path. Disable Fast-Path during
// the retries of this I/O operation to prevent hanging.
pRequest->SystemFlags &= ~ SD_FAST_PATH_AVAILABLE;
// resubmit
if (SD_API_SUCCESS(pBusDriver->SubmitToHC(pHCContext,
pSlot->SlotIndex,
pRequest))) {
return;
}
// acquire the HC lock
SDHCDAcquireHCLock(pHCContext);
// re-submission failed, let it fall through to completion
}
}
}
}
}
}
// set the completion status
pRequest->Status = Status;
if ( SD_API_STATUS_FAST_PATH_SUCCESS == Status )
{
// release the lock
SDHCDReleaseHCLock(pHCContext);
// Determine if the requesting thread is actually waiting on an event.
if ( 0 != ( pRequest->SystemFlags & SD_SET_EVENT_FLAG ))
{
PSD_SYNCH_REQUEST_INFO pSynchInfo;
// Notify the upper layers (SDSynchronousBusRequest__X) to free
// this request and start another. Note that SubmitToHC is peaking
// at Fast-Path/Soft-Block requests for more processing.
pSynchInfo = (PSD_SYNCH_REQUEST_INFO)pRequest->RequestParam;
pSynchInfo->Status = SD_API_STATUS_FAST_PATH_SUCCESS;
// wake up the blocked thread
SetEvent(pSynchInfo->hWaitEvent);
}
// Don't wake-up the dispatcher thread.
return;
}
// dequeue the current request
if ((SDDequeueBusRequest(&pSlot->RequestQueue)) != pRequest) {
// the request we are completing should be the first request in the queue
DEBUG_CHECK(FALSE,(TEXT("SDHCDCompleteRequest- the HC is completing a request that is not the current request! \n")));
// release the lock
SDHCDReleaseHCLock(pHCContext);
return;
}
// mark that the request is completing
SD_REQUEST_MARK_COMPLETING(pRequest);
// queue the request to the bus driver's completion queue
pBusDriver->QueueCompletedRequest(pRequest);
// Start the next SDIO request.
// N.B. SDHCDStartNextRequest releases the pHCContext lock!
SDHCDStartNextRequest ( pHCContext, pBusDriver, pSlot );
// indicate a slot state change
// this will signal the dispatcher to examine the slot and
// complete the request from the completed request queue
SDHCDIndicateSlotStateChange__X(pHCContext,
pSlot->SlotIndex,
BusRequestComplete);
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDGetAndLockCurrentRequest - get the current request in the host controller
// slot and lock it to keep it from being cancelable
// Input: pExternalHCContext - host controller context
// SlotIndex - the slot number
// Output:
// Return: current bus request
// Notes:
// This function retrieves the current request and marks the
// request as NON-cancelable. To return the request back to the
// cancelable state the caller must call SDHCDUnlockRequest()
// This function returns the current request which can be NULL if
// the request was previously marked cancelable and the host controller's
// cancelIo Handler completed the request
///////////////////////////////////////////////////////////////////////////////
HBUS_REQUEST SDHCDGetAndLockCurrentRequest__X(PSDCARD_HC_CONTEXT pExternalHCContext, DWORD SlotIndex)
{
PSDBUS_BUS_REQUEST pRequest; // the current request
PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
if (pHCContext == NULL) {
RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
DEBUGCHK(FALSE);
return NULL;
}
DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);
SDHCDAcquireHCLock(pHCContext);
// get the current request
PSDBUS_HC_SLOT_CONTEXT pSlot = SDHCGetSlotContext(pHCContext, SlotIndex);
pRequest = (PSDBUS_BUS_REQUEST) SDGetCurrentRequest(&pSlot->RequestQueue);
if (NULL == pRequest) {
SDHCDReleaseHCLock(pHCContext);
return NULL;
}
if (IS_REQUEST_COMPLETING(pRequest)) {
DEBUGCHK(FALSE);
// the current request is completing in the dispatcher, this shouldn't happen
SDHCDReleaseHCLock(pHCContext);
return NULL;
}
// mark the request as non-cancelable
SD_REQUEST_MARK_NON_CANCELABLE(pRequest);
SDHCDReleaseHCLock(pHCContext);
return (HBUS_REQUEST) pRequest;
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDUnlockRequest - Unlock a request that was previous locked
//
// Input: pHCContext - host controller context
// pRequest - the request to lock
// Output:
// Return:
// Notes: This function unlocks the request that was returned from the
// function SDHCDGetAndLockCurrentRequest()
//
// This request can now be cancelled from any thread context
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDUnlockRequest__X(PSDCARD_HC_CONTEXT pExternalHCContext,
HBUS_REQUEST hRequest)
{
PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
PSDBUS_BUS_REQUEST pRequest = (PSDBUS_BUS_REQUEST) hRequest;
if (pHCContext == NULL) {
RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
DEBUGCHK(FALSE);
return;
}
DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);
if (pRequest == NULL) {
RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SD_BUS_REQUEST \n")));
DEBUGCHK(FALSE);
return;
}
SDHCDAcquireHCLock(pHCContext);
// mark the request as cancelable
SD_REQUEST_MARK_CANCELABLE(pRequest);
SDHCDReleaseHCLock(pHCContext);
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDPowerUpDown - Indicate a power up/down event
//
// Input: pHCContext - host controller context
// PowerUp - set to TRUE if powering up
// SlotKeepPower - set to TRUE if the slot maintains power to the
// slot during power down
// Output:
// Return:
// Notes: This function notifies the bus driver of a power up/down event.
// The host controller driver can indicate to the bus driver that power
// can be maintained for the slot. If power is removed, the bus driver
// will unload the device driver on the next power up event.
// This function can only be called from the host controller's XXX_PowerOn
// and XXX_PowerOff function.
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDPowerUpDown__X(PSDCARD_HC_CONTEXT pExternalHCContext,
BOOL PowerUp,
BOOL SlotKeepPower,
DWORD SlotIndex)
{
PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
if (pHCContext == NULL) {
RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
DEBUGCHK(FALSE);
return;
}
DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);
DEBUGCHK(SlotIndex < pHCContext->NumberOfSlots);
CSDBusDriver *pBusDriver = GetSDBusDriver(pHCContext);
PSDBUS_HC_SLOT_CONTEXT pSlot = SDHCGetSlotContext(pHCContext, SlotIndex);
if (PowerUp){
pBusDriver->PowerUp(pSlot);
} else {
pBusDriver->PowerDown(pSlot, SlotKeepPower);
}
}
///////////////////////////////////////////////////////////////////////////////
// DefaultChangeCardPower - Default power allocation/deallocation handler for the
// bus driver.
//
// Input: pHCCardContext - host controller context
// Slot - Slot number
// CurrentDelta- Change in Slot current
// Output:
// Return: SD_API_STATUS_INSUFFICIENT_HOST_POWER - the slot will exceeded is maximum
// current limit.
// SD_API_STATUS_SUCCESS - No current limit has been exceeded.
// Notes: If the Host Controller does not assign its own power allocation/deallocation
// handler. This function is called each time a client requests a change that
// affects the card's power state.
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS DefaultChangeCardPower(PSDCARD_HC_CONTEXT pHCCardContext,
DWORD Slot,
INT CurrentDelta)
{
USHORT SlotPower = 0;
INT NewSlotPower = 0;
PSDBUS_HC_CONTEXT pHCBusContext = (PSDBUS_HC_CONTEXT) pHCCardContext;
SlotPower = SDHCDGetSlotPower(pHCBusContext, Slot);
NewSlotPower = ((INT) SlotPower) + CurrentDelta;
if(NewSlotPower > DEFAULT_MAX_SLOT_CURRENT)
{
DbgPrintZo(SDCARD_ZONE_WARN,
(TEXT("SDBusDriver: Power change denied, current over limmit by %dmA\n"),
NewSlotPower - DEFAULT_MAX_SLOT_CURRENT));
return SD_API_STATUS_INSUFFICIENT_HOST_POWER;
}
if(NewSlotPower < 0)
{
DbgPrintZo(SDCARD_ZONE_WARN,
(TEXT("SDBusDriver: Power change math issue, current under limmit by %dmA\n"),
NewSlotPower));
}
// Do not change SlotPower in this function.
// It will be tracked by the bus driver's calling function.
return SD_API_STATUS_SUCCESS;
}
// DO NOT REMOVE --- END EXTERNALLY DEVELOPED SOURCE CODE ID --- DO NOT REMOVE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -