summaryrefslogtreecommitdiff
path: root/EmbeddedPkg/Universal
diff options
context:
space:
mode:
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2011-08-15 16:04:14 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2011-08-15 16:04:14 +0000
commit3de99375d289d2945192be9e38fce63224d27b21 (patch)
tree0112c7377c202d40078979b4634aac2cb28d143f /EmbeddedPkg/Universal
parent569224f9de1d19e323c685839a0653136fcb0dea (diff)
downloadedk2-platforms-3de99375d289d2945192be9e38fce63224d27b21.tar.xz
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
Diffstat (limited to 'EmbeddedPkg/Universal')
-rw-r--r--EmbeddedPkg/Universal/MmcDxe/Mmc.c63
-rw-r--r--EmbeddedPkg/Universal/MmcDxe/Mmc.h2
-rw-r--r--EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c28
3 files changed, 87 insertions, 6 deletions
diff --git a/EmbeddedPkg/Universal/MmcDxe/Mmc.c b/EmbeddedPkg/Universal/MmcDxe/Mmc.c
index 468bb1dae6..cfa9a51f50 100644
--- a/EmbeddedPkg/Universal/MmcDxe/Mmc.c
+++ b/EmbeddedPkg/Universal/MmcDxe/Mmc.c
@@ -45,6 +45,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
**/
VOID
@@ -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;
}
diff --git a/EmbeddedPkg/Universal/MmcDxe/Mmc.h b/EmbeddedPkg/Universal/MmcDxe/Mmc.h
index 542355f1ad..d570be299f 100644
--- a/EmbeddedPkg/Universal/MmcDxe/Mmc.h
+++ b/EmbeddedPkg/Universal/MmcDxe/Mmc.h
@@ -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')
diff --git a/EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c b/EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c
index 7341d9f9b8..cd04369652 100644
--- a/EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c
+++ b/EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c
@@ -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;
}