From a154f420147b0a3f449bb52da1e76dabef3478a5 Mon Sep 17 00:00:00 2001 From: Anthony PERARD Date: Wed, 29 Oct 2014 06:48:59 +0000 Subject: OvmfPkg/XenBusDxe: Add device state struct and create an ExitBoot services event. The ExitBoot event is used to disconnect from the device before the next operating system start using them. Change in V3: - use the variable mMyDevice to prevent the driver from starting twice (if there is two different PCI devices). - free(dev) on exit Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Anthony PERARD Reviewed-by: Jordan Justen git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16259 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/XenBusDxe/XenBusDxe.c | 56 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) (limited to 'OvmfPkg/XenBusDxe/XenBusDxe.c') diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c index 7f297bdeae..f3c74e1fbe 100644 --- a/OvmfPkg/XenBusDxe/XenBusDxe.c +++ b/OvmfPkg/XenBusDxe/XenBusDxe.c @@ -43,6 +43,9 @@ EFI_DRIVER_BINDING_PROTOCOL gXenBusDxeDriverBinding = { }; +STATIC EFI_LOCK mMyDeviceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_CALLBACK); +STATIC XENBUS_DEVICE *mMyDevice = NULL; + /** Unloads an image. @@ -216,6 +219,19 @@ XenBusDxeDriverBindingSupported ( return Status; } +VOID +EFIAPI +NotifyExitBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + XENBUS_DEVICE *Dev = Context; + + gBS->DisconnectController(Dev->ControllerHandle, + Dev->This->DriverBindingHandle, NULL); +} + /** Starts a bus controller. @@ -259,7 +275,37 @@ XenBusDxeDriverBindingStart ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + XENBUS_DEVICE *Dev; + + Dev = AllocateZeroPool (sizeof (*Dev)); + Dev->Signature = XENBUS_DEVICE_SIGNATURE; + Dev->This = This; + Dev->ControllerHandle = ControllerHandle; + + EfiAcquireLock (&mMyDeviceLock); + if (mMyDevice != NULL) { + EfiReleaseLock (&mMyDeviceLock); + // + // There is already a XenBus running, only one can be used at a time. + // + Status = EFI_ALREADY_STARTED; + goto ErrorAllocated; + } + mMyDevice = Dev; + EfiReleaseLock (&mMyDeviceLock); + + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK, + NotifyExitBoot, + (VOID*) Dev, + &Dev->ExitBootEvent); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; + +ErrorAllocated: + FreePool (Dev); + return Status; } /** @@ -297,5 +343,11 @@ XenBusDxeDriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ) { - return EFI_UNSUPPORTED; + XENBUS_DEVICE *Dev = mMyDevice; + + gBS->CloseEvent (Dev->ExitBootEvent); + + mMyDevice = NULL; + FreePool (Dev); + return EFI_SUCCESS; } -- cgit v1.2.3