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 <anthony.perard@citrix.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16259 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Anthony PERARD
2014-10-29 06:48:59 +00:00
committed by jljusten
parent e65e8802e5
commit a154f42014
2 changed files with 65 additions and 2 deletions

View File

@@ -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;
}