EmbeddedPkg/MmcDxe: Create a periodic function to check if a card is present
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 15 Aug 2011 16:04:14 +0000 (16:04 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 15 Aug 2011 16:04:14 +0000 (16:04 +0000)
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
EmbeddedPkg/Universal/MmcDxe/Mmc.h
EmbeddedPkg/Universal/MmcDxe/MmcBlockIo.c

index 468bb1d..cfa9a51 100644 (file)
@@ -44,6 +44,13 @@ EFI_BLOCK_IO_MEDIA mMmcMediaTemplate = {
 //\r
 LIST_ENTRY  mMmcHostPool;\r
 \r
+/**\r
+  Event triggered by the timer to check if any cards have been removed\r
+  or if new ones have been plugged in\r
+**/\r
+\r
+EFI_EVENT gCheckCardsEvent;\r
+\r
 /**\r
   Initialize the MMC Host Pool to support multiple MMC devices\r
 **/\r
@@ -125,7 +132,7 @@ MMC_HOST_INSTANCE* CreateMmcHostInstance (
   // Publish BlockIO protocol interface\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                 &MmcHostInstance->MmcHandle,\r
-                &gEfiBlockIoProtocolGuid,&(MmcHostInstance->BlockIo),\r
+                &gEfiBlockIoProtocolGuid,&MmcHostInstance->BlockIo,\r
                 &gEfiDevicePathProtocolGuid,MmcHostInstance->DevicePath,\r
                 NULL\r
                 );\r
@@ -290,6 +297,8 @@ MmcDriverBindingStart (
   if (MmcHostInstance != NULL) {\r
     // Add the handle to the pool\r
     InsertMmcHost (MmcHostInstance);\r
+\r
+    MmcHostInstance->Initialized = FALSE;\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -336,6 +345,43 @@ MmcDriverBindingStop (
   return Status;\r
 }\r
 \r
+VOID\r
+EFIAPI\r
+CheckCardsCallback (\r
+  IN  EFI_EVENT   Event,\r
+  IN  VOID        *Context\r
+  )\r
+{\r
+  LIST_ENTRY          *CurrentLink;\r
+  MMC_HOST_INSTANCE   *MmcHostInstance;\r
+  EFI_STATUS          Status;\r
+\r
+  CurrentLink = mMmcHostPool.ForwardLink;\r
+  while (CurrentLink != NULL && CurrentLink != &mMmcHostPool) {\r
+    MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK(CurrentLink);\r
+    ASSERT(MmcHostInstance != NULL);\r
+\r
+    if (MmcHostInstance->MmcHost->IsCardPresent() == !MmcHostInstance->Initialized) {\r
+      MmcHostInstance->State = MmcHwInitializationState;\r
+      MmcHostInstance->BlockIo.Media->MediaPresent = !MmcHostInstance->Initialized;\r
+      MmcHostInstance->Initialized = !MmcHostInstance->Initialized;\r
+\r
+      Status = gBS->ReinstallProtocolInterface (\r
+                    (MmcHostInstance->MmcHandle),\r
+                    &gEfiBlockIoProtocolGuid,\r
+                    &(MmcHostInstance->BlockIo),\r
+                    &(MmcHostInstance->BlockIo)\r
+                    );\r
+\r
+      if (EFI_ERROR(Status)) {\r
+        Print(L"MMC Card: Error reinstalling BlockIo interface\n");\r
+      }\r
+    }\r
+\r
+    CurrentLink = CurrentLink->ForwardLink;\r
+  }\r
+}\r
+\r
 EFI_DRIVER_BINDING_PROTOCOL gMmcDriverBinding = {\r
   MmcDriverBindingSupported,\r
   MmcDriverBindingStart,\r
@@ -383,5 +429,20 @@ MmcDxeInitialize (
                 );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  // Use a timer to detect if a card has been plugged in or removed\r
+  Status = gBS->CreateEvent (\r
+                EVT_NOTIFY_SIGNAL | EVT_TIMER,\r
+                TPL_CALLBACK,\r
+                CheckCardsCallback,\r
+                NULL,\r
+                &gCheckCardsEvent);\r
+  ASSERT_EFI_ERROR (Status);  \r
+              \r
+  Status = gBS->SetTimer(\r
+                gCheckCardsEvent,\r
+                TimerPeriodic,\r
+                (UINT64)(10*1000*200)); // 200 ms\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   return Status;\r
 }\r
index 542355f..d570be2 100644 (file)
@@ -146,6 +146,8 @@ typedef struct _MMC_HOST_INSTANCE {
   EFI_BLOCK_IO_PROTOCOL     BlockIo;\r
   CARD_INFO                 CardInfo;\r
   EFI_MMC_HOST_PROTOCOL     *MmcHost;\r
+  \r
+  BOOLEAN                   Initialized;\r
 } MMC_HOST_INSTANCE;\r
 \r
 #define MMC_HOST_INSTANCE_SIGNATURE                 SIGNATURE_32('m', 'm', 'c', 'h')\r
index 7341d9f..cd04369 100644 (file)
@@ -369,6 +369,28 @@ MmcReset (
   IN BOOLEAN                  ExtendedVerification\r
   )\r
 {\r
+  MMC_HOST_INSTANCE       *MmcHostInstance;\r
+\r
+  MmcHostInstance = MMC_HOST_INSTANCE_FROM_BLOCK_IO_THIS(This);\r
+\r
+  if (MmcHostInstance->MmcHost == NULL) {\r
+    // Nothing to do\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  // If a card is not present then clear all media settings\r
+  if (!MmcHostInstance->MmcHost->IsCardPresent()) {\r
+    MmcHostInstance->BlockIo.Media->MediaPresent = FALSE;\r
+    MmcHostInstance->BlockIo.Media->LastBlock    = 0;\r
+    MmcHostInstance->BlockIo.Media->BlockSize    = 512;  // Should be zero but there is a bug in DiskIo\r
+    MmcHostInstance->BlockIo.Media->ReadOnly     = FALSE;\r
+\r
+    // Indicate that the driver requires initialization\r
+    MmcHostInstance->State = MmcHwInitializationState;\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
   // Implement me. Either send a CMD0 (could not work for some MMC host) or just turn off/turn\r
   //      on power and restart Identification mode\r
   return EFI_SUCCESS;\r
@@ -419,11 +441,7 @@ MmcIoBlocks (
   }\r
 \r
   // Check if a Card is Present\r
-  if (!MmcHost->IsCardPresent()) {\r
-    MmcHostInstance->BlockIo.Media->MediaPresent = FALSE;\r
-    MmcHostInstance->BlockIo.Media->LastBlock    = 0;\r
-    MmcHostInstance->BlockIo.Media->BlockSize    = 512;  // Should be zero but there is a bug in DiskIo\r
-    MmcHostInstance->BlockIo.Media->ReadOnly     = FALSE;\r
+  if (!MmcHostInstance->BlockIo.Media->MediaPresent) {\r
     return EFI_NO_MEDIA;\r
   }\r
 \r