[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v3 04/19] 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.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>

---
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
---
 OvmfPkg/XenBusDxe/XenBusDxe.c | 56 +++++++++++++++++++++++++++++++++++++++++--
 OvmfPkg/XenBusDxe/XenBusDxe.h | 11 +++++++++
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c
index a272204..8a04c8e 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.c
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.c
@@ -59,6 +59,9 @@ EFI_DRIVER_BINDING_PROTOCOL gXenBusDxeDriverBinding = {
 };
 
 
+STATIC EFI_LOCK       mMyDeviceLock = EFI_INITIALIZE_LOCK_VARIABLE 
(TPL_CALLBACK);
+STATIC XENBUS_DEVICE *mMyDevice = NULL;
+
 /**
   Unloads an image.
 
@@ -232,6 +235,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.
 
@@ -275,7 +291,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;
 }
 
 /**
@@ -313,5 +359,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;
 }
diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h
index 952591d..8d7fe89 100644
--- a/OvmfPkg/XenBusDxe/XenBusDxe.h
+++ b/OvmfPkg/XenBusDxe/XenBusDxe.h
@@ -90,4 +90,15 @@ extern EFI_COMPONENT_NAME_PROTOCOL  gXenBusDxeComponentName;
 #define PCI_DEVICE_ID_XEN_PLATFORM       0x0001
 
 
+typedef struct _XENBUS_DEVICE XENBUS_DEVICE;
+
+// Have the state of the driver.
+#define XENBUS_DEVICE_SIGNATURE SIGNATURE_32 ('X','B','s','t')
+struct _XENBUS_DEVICE {
+  UINT32                        Signature;
+  EFI_DRIVER_BINDING_PROTOCOL   *This;
+  EFI_HANDLE                    ControllerHandle;
+  EFI_EVENT                     ExitBootEvent;
+};
+
 #endif
-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.