📄 sdhcenum.cpp
字号:
status = SD_API_STATUS_UNSUCCESSFUL;
}
}
}
return status;
}
SD_API_STATUS
DoDeregisterHostController(PSDBUS_HC_CONTEXT pHCContext, BOOL fExternalCall)
{
PREFAST_DEBUGCHK(pHCContext);
SD_API_STATUS status = SD_API_STATUS_SUCCESS;
__try {
// call the deinit handler of the host controller
pHCContext->pDeinitHandler(pHCContext);
status = SD_API_STATUS_SUCCESS;
} __except (SDProcessException(GetExceptionInformation())) {
// exception caught
status = SD_API_STATUS_UNSUCCESSFUL;
}
if (!SD_API_SUCCESS(status)) {
return status;
}
if (SDGetSystemContext() == NULL && fExternalCall) {
// this should never happen
DEBUG_CHECK(FALSE, (TEXT("SDBusDriver: No System Context! \n")));
return SD_API_STATUS_BUS_DRIVER_NOT_READY;
}
pHCContext->dwSig = DEREGISTERED_HC_CONTEXT_SIG;
CSDBusDriver *pBusDriver = GetSDBusDriver(pHCContext);
// lock the bus driver
pBusDriver->AcquireLock();
__try {
// clean up slot work items
CleanUpSlotWorkItems(pHCContext);
status = pBusDriver->DeregisterHostController(pHCContext);
pBusDriver->ReleaseLock();
} __except (SDProcessException(GetExceptionInformation())) {
pBusDriver->ReleaseLock();
// exception caught
status = SD_API_STATUS_UNSUCCESSFUL;
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDDeregisterHostController - Deregister a host controller
//
// Input: pExternalHCContext - Host controller context that was previously registered
//
// Output:
// Return: SD_API_STATUS
// Notes:
// A host controller must call this api before deleting the HC context
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDHCDDeregisterHostController__X(PSDCARD_HC_CONTEXT pExternalHCContext)
{
PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
if (pHCContext == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
return SD_API_STATUS_INVALID_PARAMETER;
}
DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);
return DoDeregisterHostController(pHCContext, TRUE);
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDIndicateSlotStateChange - indicate a change in the SD Slot
//
// Input: pExternalHCContext - Host controller context that was previously registered
// SlotNumber - Slot Number
// Event - new event
// Output:
// Return: SD_API_STATUS
// Notes:
// A host controller driver calls this api when the slot changes state (i.e.
// device insertion/deletion).
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDIndicateSlotStateChange__X(PSDCARD_HC_CONTEXT pExternalHCContext,
DWORD SlotNumber,
SD_SLOT_EVENT Event)
{
PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
PSDBUS_HC_SLOT_CONTEXT pSlotContext; // the slot context
CSDBusDriver *pBusDriver; // the bus driver
if (pHCContext == NULL) {
RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
DEBUGCHK(FALSE);
return;
}
DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);
if (SlotNumber > pHCContext->NumberOfSlots) {
DEBUG_CHECK(FALSE, (TEXT("SDHCDIndicateSlotStateChange, Slot number exceeds number of slots! \n")));
return;
}
// get the slot context for this slot number and host controller
pSlotContext = SDHCGetSlotContext(pHCContext, SlotNumber);
if (DeviceEjected == Event) {
// immediately mark the slot for ejection
pSlotContext->SlotState = SlotDeviceEjected;
if (NULL == pSlotContext->hDevice) {
// This can happen on very fast suspend-resume-suspend sequence because
// the DeviceInserted message is still in the WorkItem queue.
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("Host Controller:%s indicated device eject on an empty slot \n"),
SDHCDGetHCName(pHCContext)));
return;
}
} else if (DeviceInterrupting == Event) {
if (NULL == pSlotContext->hDevice) {
DEBUG_CHECK(FALSE,(TEXT("Host Controller:%s indicated an interrupt on an empty slot \n"),
SDHCDGetHCName(pHCContext)));
return;
}
}
// get the bus driver object
pBusDriver = GetSDBusDriver(pHCContext);
PREFAST_DEBUGCHK(pBusDriver != NULL);
switch (Event) {
case DeviceInserted:
case DeviceEjected:
case DeviceInterrupting:
#ifdef ENABLE_SDIO_V1_1_SUPPORT
case SlotDeselectRequest:
case SlotSelectRequest:
case SlotResetRequest:
#endif //ENABLE_SDIO_V1_1_SUPPORT
DEBUGCHK(pSlotContext->pWorkItem != NULL);
// post this message to the work item for each slot
pBusDriver->PostSlotEvent(Event, pSlotContext, (CSDWorkItem *)pSlotContext->pWorkItem);
break;
case BusRequestComplete:
// wake up bus request complete dispatcher
pBusDriver->WakeUpBusRequestCompleteDispatcher();
break;
default:
DEBUGCHK(FALSE);
}
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDStartNextRequest - Start the next SDIO request.
// Input: pHCContext - host controller context
// pBusDriver - Bus driver structure address
// pSlot - Slot structure address
// Output:
// Return:
// Notes:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDStartNextRequest(PSDBUS_HC_CONTEXT pHCContext,
CSDBusDriver * pBusDriver,
PSDBUS_HC_SLOT_CONTEXT pSlot)
{
PSDBUS_BUS_REQUEST pNextRequest; // the next request
SD_API_STATUS submitStatus; // intermediate status
// start up the next request(s) in the queue
while (1) {
// get the next request
pNextRequest = (PSDBUS_BUS_REQUEST) SDGetCurrentRequest(&pSlot->RequestQueue);
// release the lock
SDHCDReleaseHCLock(pHCContext);
if (NULL == pNextRequest) {
// nothing to start up
break;
}
// check the slot, we might have gotten a removal
submitStatus = CheckSlotReady(pSlot);
if (SD_API_SUCCESS(submitStatus)) {
// Remember that the client thread is waiting on the event flag
// and that the completion code needs to set the event flag.
pNextRequest->SystemFlags |= SD_SET_EVENT_FLAG;
// submit the next request
submitStatus = pBusDriver->SubmitToHC(pHCContext, pSlot->SlotIndex, pNextRequest);
}
if (SD_API_SUCCESS(submitStatus)) {
// break out of the loop, we've already submitted one
break;
}
// set the error status
pNextRequest->Status = submitStatus;
// re-acquire the HC lock
SDHCDAcquireHCLock(pHCContext);
// remove this one from the queue because it failed
SDDequeueBusRequest(&pSlot->RequestQueue);
// queue the request for completion
pBusDriver->QueueCompletedRequest(pNextRequest);
// we stay in this loop
}
}
///////////////////////////////////////////////////////////////////////////////
// SDHCDIndicateBusRequestComplete - indicate to the bus driver that
// the request is complete
// Input: pExternalHCContext - host controller context
// pRequest - the request to indicate
// Status - the ending status of the request
// Output:
// Return:
// Notes:
//
//
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDIndicateBusRequestComplete__X(PSDCARD_HC_CONTEXT pExternalHCContext,
HBUS_REQUEST hRequest,
SD_API_STATUS Status)
{
PSDBUS_HC_SLOT_CONTEXT pSlot; // the slot
CSDBusDriver *pBusDriver;
PSDBUS_BUS_REQUEST pRequest = (PSDBUS_BUS_REQUEST) hRequest;
PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);
// get the slot
PREFAST_DEBUGCHK(pRequest);
DEBUGCHK(pRequest->dwSig == VALID_BUS_REQUEST_SIG);
PSDCARD_DEVICE_CONTEXT pDevice = SDDCGetClientDeviceFromHandle(pRequest->hDevice);
PREFAST_DEBUGCHK(pDevice);
pSlot = pDevice->pSlot;
PREFAST_DEBUGCHK(pSlot);
pBusDriver = (CSDBusDriver *) pDevice->pSystemContext;
// acquire the HC lock
SDHCDAcquireHCLock(pHCContext);
// mark that the request is non-cancelable
SD_REQUEST_MARK_NON_CANCELABLE(pRequest);
// Determine if this is a Soft-Block request.
if (IS_REQUEST_USING_SOFT_BLOCK (pRequest))
{
PSDCARD_HC_CONTEXT pHost; // the host controller
// This is a Soft-Block request.
// The request is defined as complete if there was an error.
pDevice = SDDCGetClientDeviceFromHandle(pRequest->hDevice);
pHost = pSlot -> pHostController;
if ( SD_API_SUCCESS ( Status ))
{
// Account for the data that was transferred.
pDevice->SDCardInfo.SDIOInformation.pSoftBlockData += pDevice->SDCardInfo.SDIOInformation.SoftBlockLengthInBytes;
// Determine if all of the blocks were sent.
if ( pDevice->SDCardInfo.SDIOInformation.pSoftBlockEndOfBuffer
> pDevice->SDCardInfo.SDIOInformation.pSoftBlockData )
{
// Another block needs to be sent.
// Update the command argument.
if ( SD_CMD_IO_RW_EXTENDED == pRequest->CommandCode )
{
if ( 0 != ( pRequest->CommandArgument & SD_CMD53_OPCODE ))
{
// Increasing addresses being used, update the register address.
pRequest->CommandArgument = ( pRequest->CommandArgument & ( ~ SD_CMD53_REGISTER_ADDRESS ))
| (( pRequest->CommandArgument + ( pDevice->SDCardInfo.SDIOInformation.SoftBlockLengthInBytes
<< SD_CMD53_REGISTER_ADDRESS_POS ))
& SD_CMD53_REGISTER_ADDRESS );
}
}
else
{
// Increasing address being used.
pRequest->CommandArgument += pDevice->SDCardInfo.SDIOInformation.SoftBlockLengthInBytes;
}
// Update the request structure.
pRequest->pBlockBuffer = pDevice->SDCardInfo.SDIOInformation.pSoftBlockData;
pRequest->BlockSize = pDevice->SDCardInfo.SDIOInformation.SoftBlockLengthInBytes;
pRequest->NumBlocks = 1;
pRequest->HCParam = 0;
// Display the next segment of the Soft-Block request.
DEBUGMSG ( SDBUS_SOFT_BLOCK, ( TEXT ( " CMD%d, %d blocks of %d bytes, Argument: %08x\r\n" ), pRequest->CommandCode, pRequest->NumBlocks, pRequest->BlockSize, pRequest->CommandArgument ));
// Release the lock
SDHCDReleaseHCLock(pHCContext);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -