X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EmbeddedPkg%2FUniversal%2FMmcDxe%2FMmc.c;h=3b9dc187276ce190e8200c751b89aa3893a41871;hp=468bb1dae6051f9a5801ccdc2233859c242123b6;hb=7bb5fad566afa2dd9feef5ae1ecc658d627f5ac2;hpb=e8e95df41d44e4c49adcc1503e1e53e2dcab5733 diff --git a/EmbeddedPkg/Universal/MmcDxe/Mmc.c b/EmbeddedPkg/Universal/MmcDxe/Mmc.c index 468bb1dae6..3b9dc18727 100644 --- a/EmbeddedPkg/Universal/MmcDxe/Mmc.c +++ b/EmbeddedPkg/Universal/MmcDxe/Mmc.c @@ -1,27 +1,25 @@ /** @file Main file of the MMC Dxe driver. The driver entrypoint is defined into this file. - Copyright (c) 2011, ARM Limited. All rights reserved. - - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php + Copyright (c) 2011-2013, ARM Limited. All rights reserved. - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include -#include #include #include #include #include #include -#include #include "Mmc.h" @@ -44,6 +42,13 @@ EFI_BLOCK_IO_MEDIA mMmcMediaTemplate = { // LIST_ENTRY mMmcHostPool; +/** + Event triggered by the timer to check if any cards have been removed + or if new ones have been plugged in +**/ + +EFI_EVENT gCheckCardsEvent; + /** Initialize the MMC Host Pool to support multiple MMC devices **/ @@ -109,7 +114,7 @@ MMC_HOST_INSTANCE* CreateMmcHostInstance ( MmcHostInstance->MmcHost = MmcHost; // Create DevicePath for the new MMC Host - Status = MmcHost->BuildDevicePath(&NewDevicePathNode); + Status = MmcHost->BuildDevicePath (MmcHost, &NewDevicePathNode); if (EFI_ERROR (Status)) { goto FREE_MEDIA; } @@ -125,7 +130,7 @@ MMC_HOST_INSTANCE* CreateMmcHostInstance ( // Publish BlockIO protocol interface Status = gBS->InstallMultipleProtocolInterfaces ( &MmcHostInstance->MmcHandle, - &gEfiBlockIoProtocolGuid,&(MmcHostInstance->BlockIo), + &gEfiBlockIoProtocolGuid,&MmcHostInstance->BlockIo, &gEfiDevicePathProtocolGuid,MmcHostInstance->DevicePath, NULL ); @@ -166,6 +171,9 @@ EFI_STATUS DestroyMmcHostInstance ( if (MmcHostInstance->BlockIo.Media) { FreePool(MmcHostInstance->BlockIo.Media); } + if (MmcHostInstance->CardInfo.ECSDData) { + FreePages (MmcHostInstance->CardInfo.ECSDData, EFI_SIZE_TO_PAGES (sizeof (ECSD))); + } FreePool (MmcHostInstance); return Status; @@ -241,7 +249,7 @@ MmcDriverBindingSupported ( } /** - + **/ EFI_STATUS EFIAPI @@ -290,13 +298,18 @@ MmcDriverBindingStart ( if (MmcHostInstance != NULL) { // Add the handle to the pool InsertMmcHost (MmcHostInstance); + + MmcHostInstance->Initialized = FALSE; + + // Detect card presence now + CheckCardsCallback (NULL, NULL); } return EFI_SUCCESS; } /** - + **/ EFI_STATUS EFIAPI @@ -336,6 +349,48 @@ MmcDriverBindingStop ( return Status; } +VOID +EFIAPI +CheckCardsCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + LIST_ENTRY *CurrentLink; + MMC_HOST_INSTANCE *MmcHostInstance; + EFI_STATUS Status; + + CurrentLink = mMmcHostPool.ForwardLink; + while (CurrentLink != NULL && CurrentLink != &mMmcHostPool) { + MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK(CurrentLink); + ASSERT(MmcHostInstance != NULL); + + if (MmcHostInstance->MmcHost->IsCardPresent (MmcHostInstance->MmcHost) == !MmcHostInstance->Initialized) { + MmcHostInstance->State = MmcHwInitializationState; + MmcHostInstance->BlockIo.Media->MediaPresent = !MmcHostInstance->Initialized; + MmcHostInstance->Initialized = !MmcHostInstance->Initialized; + + if (MmcHostInstance->BlockIo.Media->MediaPresent) { + InitializeMmcDevice (MmcHostInstance); + } + + Status = gBS->ReinstallProtocolInterface ( + (MmcHostInstance->MmcHandle), + &gEfiBlockIoProtocolGuid, + &(MmcHostInstance->BlockIo), + &(MmcHostInstance->BlockIo) + ); + + if (EFI_ERROR(Status)) { + Print(L"MMC Card: Error reinstalling BlockIo interface\n"); + } + } + + CurrentLink = CurrentLink->ForwardLink; + } +} + + EFI_DRIVER_BINDING_PROTOCOL gMmcDriverBinding = { MmcDriverBindingSupported, MmcDriverBindingStart, @@ -346,7 +401,7 @@ EFI_DRIVER_BINDING_PROTOCOL gMmcDriverBinding = { }; /** - + **/ EFI_STATUS EFIAPI @@ -383,5 +438,20 @@ MmcDxeInitialize ( ); ASSERT_EFI_ERROR (Status); + // Use a timer to detect if a card has been plugged in or removed + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL | EVT_TIMER, + TPL_CALLBACK, + CheckCardsCallback, + NULL, + &gCheckCardsEvent); + ASSERT_EFI_ERROR (Status); + + Status = gBS->SetTimer( + gCheckCardsEvent, + TimerPeriodic, + (UINT64)(10*1000*200)); // 200 ms + ASSERT_EFI_ERROR (Status); + return Status; }