From 3de99375d289d2945192be9e38fce63224d27b21 Mon Sep 17 00:00:00 2001 From: oliviermartin Date: Mon, 15 Aug 2011 16:04:14 +0000 Subject: 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 --- EmbeddedPkg/Universal/MmcDxe/Mmc.c | 63 ++++++++++++++++++++++++++++++- EmbeddedPkg/Universal/MmcDxe/Mmc.h | 2 + EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c | 28 +++++++++++--- 3 files changed, 87 insertions(+), 6 deletions(-) (limited to 'EmbeddedPkg/Universal') 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 @@ -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; } 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; } -- cgit v1.2.3