/** @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
+ Copyright (c) 2011-2013, 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
**/\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
//\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
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
// 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
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
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
);\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