]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Universal/MmcDxe/Mmc.c
EmbeddedPkg/MmcDxe: Align the ExtCSD buffer
[mirror_edk2.git] / EmbeddedPkg / Universal / MmcDxe / Mmc.c
index 468bb1dae6051f9a5801ccdc2233859c242123b6..3b9dc187276ce190e8200c751b89aa3893a41871 100644 (file)
@@ -1,27 +1,25 @@
 /** @file\r
   Main file of the MMC Dxe driver. The driver entrypoint is defined into this file.\r
 \r
-  Copyright (c) 2011, ARM Limited. All rights reserved.\r
-  \r
-  This program and the accompanying materials                          \r
-  are licensed and made available under the terms and conditions of the BSD License         \r
-  which accompanies this distribution.  The full text of the license may be found at        \r
-  http://opensource.org/licenses/bsd-license.php                                            \r
+  Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
 \r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
 \r
 #include <Protocol/DevicePath.h>\r
-#include <Protocol/MmcHost.h>\r
 \r
 #include <Library/BaseLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/DevicePathLib.h>\r
-#include <Library/DebugLib.h>\r
 \r
 #include "Mmc.h"\r
 \r
@@ -44,6 +42,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
@@ -109,7 +114,7 @@ MMC_HOST_INSTANCE* CreateMmcHostInstance (
   MmcHostInstance->MmcHost = MmcHost;\r
 \r
   // Create DevicePath for the new MMC Host\r
-  Status = MmcHost->BuildDevicePath(&NewDevicePathNode);\r
+  Status = MmcHost->BuildDevicePath (MmcHost, &NewDevicePathNode);\r
   if (EFI_ERROR (Status)) {\r
     goto FREE_MEDIA;\r
   }\r
@@ -125,7 +130,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
@@ -166,6 +171,9 @@ EFI_STATUS DestroyMmcHostInstance (
   if (MmcHostInstance->BlockIo.Media) {\r
     FreePool(MmcHostInstance->BlockIo.Media);\r
   }\r
+  if (MmcHostInstance->CardInfo.ECSDData) {\r
+    FreePages (MmcHostInstance->CardInfo.ECSDData, EFI_SIZE_TO_PAGES (sizeof (ECSD)));\r
+  }\r
   FreePool (MmcHostInstance);\r
 \r
   return Status;\r
@@ -241,7 +249,7 @@ MmcDriverBindingSupported (
 }\r
 \r
 /**\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -290,13 +298,18 @@ MmcDriverBindingStart (
   if (MmcHostInstance != NULL) {\r
     // Add the handle to the pool\r
     InsertMmcHost (MmcHostInstance);\r
+\r
+    MmcHostInstance->Initialized = FALSE;\r
+\r
+    // Detect card presence now\r
+    CheckCardsCallback (NULL, NULL);\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -336,6 +349,48 @@ 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->MmcHost) == !MmcHostInstance->Initialized) {\r
+      MmcHostInstance->State = MmcHwInitializationState;\r
+      MmcHostInstance->BlockIo.Media->MediaPresent = !MmcHostInstance->Initialized;\r
+      MmcHostInstance->Initialized = !MmcHostInstance->Initialized;\r
+\r
+      if (MmcHostInstance->BlockIo.Media->MediaPresent) {\r
+        InitializeMmcDevice (MmcHostInstance);\r
+      }\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
+\r
 EFI_DRIVER_BINDING_PROTOCOL gMmcDriverBinding = {\r
   MmcDriverBindingSupported,\r
   MmcDriverBindingStart,\r
@@ -346,7 +401,7 @@ EFI_DRIVER_BINDING_PROTOCOL gMmcDriverBinding = {
 };\r
 \r
 /**\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -383,5 +438,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