//\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
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
}\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