//\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
// 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
\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->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
);\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