EmbeddedPkg/MmcDxe: Create a periodic function to check if a card is present

In the former version, the check was done for every BlockIo operation.
By using a periodical function, we check less time in consequence performance
are better.



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12128 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
oliviermartin 2011-08-15 16:04:14 +00:00
parent 569224f9de
commit 3de99375d2
3 changed files with 87 additions and 6 deletions

View File

@ -44,6 +44,13 @@ EFI_BLOCK_IO_MEDIA mMmcMediaTemplate = {
//
LIST_ENTRY mMmcHostPool;
/**
Event triggered by the timer to check if any cards have been removed
or if new ones have been plugged in
**/
EFI_EVENT gCheckCardsEvent;
/**
Initialize the MMC Host Pool to support multiple MMC devices
**/
@ -125,7 +132,7 @@ MMC_HOST_INSTANCE* CreateMmcHostInstance (
// Publish BlockIO protocol interface
Status = gBS->InstallMultipleProtocolInterfaces (
&MmcHostInstance->MmcHandle,
&gEfiBlockIoProtocolGuid,&(MmcHostInstance->BlockIo),
&gEfiBlockIoProtocolGuid,&MmcHostInstance->BlockIo,
&gEfiDevicePathProtocolGuid,MmcHostInstance->DevicePath,
NULL
);
@ -290,6 +297,8 @@ MmcDriverBindingStart (
if (MmcHostInstance != NULL) {
// Add the handle to the pool
InsertMmcHost (MmcHostInstance);
MmcHostInstance->Initialized = FALSE;
}
return EFI_SUCCESS;
@ -336,6 +345,43 @@ MmcDriverBindingStop (
return Status;
}
VOID
EFIAPI
CheckCardsCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
LIST_ENTRY *CurrentLink;
MMC_HOST_INSTANCE *MmcHostInstance;
EFI_STATUS Status;
CurrentLink = mMmcHostPool.ForwardLink;
while (CurrentLink != NULL && CurrentLink != &mMmcHostPool) {
MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK(CurrentLink);
ASSERT(MmcHostInstance != NULL);
if (MmcHostInstance->MmcHost->IsCardPresent() == !MmcHostInstance->Initialized) {
MmcHostInstance->State = MmcHwInitializationState;
MmcHostInstance->BlockIo.Media->MediaPresent = !MmcHostInstance->Initialized;
MmcHostInstance->Initialized = !MmcHostInstance->Initialized;
Status = gBS->ReinstallProtocolInterface (
(MmcHostInstance->MmcHandle),
&gEfiBlockIoProtocolGuid,
&(MmcHostInstance->BlockIo),
&(MmcHostInstance->BlockIo)
);
if (EFI_ERROR(Status)) {
Print(L"MMC Card: Error reinstalling BlockIo interface\n");
}
}
CurrentLink = CurrentLink->ForwardLink;
}
}
EFI_DRIVER_BINDING_PROTOCOL gMmcDriverBinding = {
MmcDriverBindingSupported,
MmcDriverBindingStart,
@ -383,5 +429,20 @@ MmcDxeInitialize (
);
ASSERT_EFI_ERROR (Status);
// Use a timer to detect if a card has been plugged in or removed
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL | EVT_TIMER,
TPL_CALLBACK,
CheckCardsCallback,
NULL,
&gCheckCardsEvent);
ASSERT_EFI_ERROR (Status);
Status = gBS->SetTimer(
gCheckCardsEvent,
TimerPeriodic,
(UINT64)(10*1000*200)); // 200 ms
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@ -146,6 +146,8 @@ typedef struct _MMC_HOST_INSTANCE {
EFI_BLOCK_IO_PROTOCOL BlockIo;
CARD_INFO CardInfo;
EFI_MMC_HOST_PROTOCOL *MmcHost;
BOOLEAN Initialized;
} MMC_HOST_INSTANCE;
#define MMC_HOST_INSTANCE_SIGNATURE SIGNATURE_32('m', 'm', 'c', 'h')

View File

@ -369,6 +369,28 @@ MmcReset (
IN BOOLEAN ExtendedVerification
)
{
MMC_HOST_INSTANCE *MmcHostInstance;
MmcHostInstance = MMC_HOST_INSTANCE_FROM_BLOCK_IO_THIS(This);
if (MmcHostInstance->MmcHost == NULL) {
// Nothing to do
return EFI_SUCCESS;
}
// If a card is not present then clear all media settings
if (!MmcHostInstance->MmcHost->IsCardPresent()) {
MmcHostInstance->BlockIo.Media->MediaPresent = FALSE;
MmcHostInstance->BlockIo.Media->LastBlock = 0;
MmcHostInstance->BlockIo.Media->BlockSize = 512; // Should be zero but there is a bug in DiskIo
MmcHostInstance->BlockIo.Media->ReadOnly = FALSE;
// Indicate that the driver requires initialization
MmcHostInstance->State = MmcHwInitializationState;
return EFI_SUCCESS;
}
// Implement me. Either send a CMD0 (could not work for some MMC host) or just turn off/turn
// on power and restart Identification mode
return EFI_SUCCESS;
@ -419,11 +441,7 @@ MmcIoBlocks (
}
// Check if a Card is Present
if (!MmcHost->IsCardPresent()) {
MmcHostInstance->BlockIo.Media->MediaPresent = FALSE;
MmcHostInstance->BlockIo.Media->LastBlock = 0;
MmcHostInstance->BlockIo.Media->BlockSize = 512; // Should be zero but there is a bug in DiskIo
MmcHostInstance->BlockIo.Media->ReadOnly = FALSE;
if (!MmcHostInstance->BlockIo.Media->MediaPresent) {
return EFI_NO_MEDIA;
}