|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 14/18] OvmfPkg/XenbusDxe: Indroduce XenBus support itself.
This is a bus-like on top of Xenstore. It will look for advertised
ParaVirtualized devices and initialize them by producing XenBus
protocol.
Origin: FreeBSD 10.0
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
OvmfPkg/Include/Protocol/Xenbus.h | 9 +
OvmfPkg/XenbusDxe/XenBus.c | 360 ++++++++++++++++++++++++++++++++++++++
OvmfPkg/XenbusDxe/XenBus.h | 76 ++++++++
OvmfPkg/XenbusDxe/XenbusDxe.c | 61 +++++++
OvmfPkg/XenbusDxe/XenbusDxe.h | 18 ++
OvmfPkg/XenbusDxe/XenbusDxe.inf | 3 +
6 files changed, 527 insertions(+)
create mode 100644 OvmfPkg/XenbusDxe/XenBus.c
create mode 100644 OvmfPkg/XenbusDxe/XenBus.h
diff --git a/OvmfPkg/Include/Protocol/Xenbus.h
b/OvmfPkg/Include/Protocol/Xenbus.h
index ef4d0c2..25408c1 100644
--- a/OvmfPkg/Include/Protocol/Xenbus.h
+++ b/OvmfPkg/Include/Protocol/Xenbus.h
@@ -113,6 +113,14 @@ XENSTORE_STATUS
);
typedef
+XENSTORE_STATUS
+(EFIAPI *XENBUS_SET_STATE)(
+ IN XENBUS_PROTOCOL *This,
+ IN XENSTORE_TRANSACTION Transaction,
+ IN XenbusState State
+ );
+
+typedef
EFI_STATUS
(EFIAPI *XENBUS_GRANT_ACCESS)(
IN XENBUS_PROTOCOL *This,
@@ -171,6 +179,7 @@ struct _XENBUS_PROTOCOL {
XENBUS_XS_REMOVE XsRemove;
XENBUS_XS_TRANSACTION_START XsTransactionStart;
XENBUS_XS_TRANSACTION_END XsTransactionEnd;
+ XENBUS_SET_STATE SetState;
XENBUS_GRANT_ACCESS GrantAccess;
XENBUS_GRANT_END_ACCESS GrantEndAccess;
diff --git a/OvmfPkg/XenbusDxe/XenBus.c b/OvmfPkg/XenbusDxe/XenBus.c
new file mode 100644
index 0000000..b0cf1ba
--- /dev/null
+++ b/OvmfPkg/XenbusDxe/XenBus.c
@@ -0,0 +1,360 @@
+/******************************************************************************
+ * Copyright (C) 2010 Spectra Logic Corporation
+ * Copyright (C) 2008 Doug Rabson
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * Copyright (C) 2005 Mike Wray, Hewlett-Packard
+ * Copyright (C) 2005 XenSource Ltd
+ *
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "XenbusDxe.h"
+
+#include <Library/PrintLib.h>
+
+#include "XenBus.h"
+#include "GrantTable.h"
+#include "Xenstore.h"
+#include "EventChannel.h"
+
+#include <IndustryStandard/Xen/io/xenbus.h>
+
+STATIC XENBUS_PRIVATE_DATA gXenbusPrivateData;
+
+STATIC XENBUS_DEVICE_PATH gXenbusDevicePathTemplate = {
+ .Vendor.Header.Type = HARDWARE_DEVICE_PATH,
+ .Vendor.Header.SubType = HW_VENDOR_DP,
+ .Vendor.Header.Length[0] = (UINT8) sizeof (XENBUS_DEVICE_PATH),
+ .Vendor.Header.Length[1] = (UINT8) (sizeof (XENBUS_DEVICE_PATH) >> 8),
+ .Vendor.Guid = XENBUS_PROTOCOL_GUID,
+ .Type = 0,
+ .DeviceId = 0
+};
+
+
+/**
+ * Search our internal record of configured devices (not the XenStore)
+ * to determine if the XenBus device indicated by \a node is known to
+ * the system.
+ *
+ * \param Dev The XenBus bus instance to search for device children.
+ * \param node The XenStore node path for the device to find.
+ *
+ * \return The device_t of the found device if any, or NULL.
+ *
+ * \note device_t is a pointer type, so it can be compared against
+ * NULL for validity.
+ */
+STATIC
+XENBUS_PRIVATE_DATA *
+XenbusDeviceInitialized (
+ IN XENBUS_DEVICE *Dev,
+ IN CONST CHAR8 *Node
+ )
+{
+ LIST_ENTRY *Entry;
+ XENBUS_PRIVATE_DATA *Child;
+ XENBUS_PRIVATE_DATA *Result;
+
+ if (IsListEmpty (&Dev->ChildList)) {
+ return NULL;
+ }
+
+ Result = NULL;
+ for (Entry = GetFirstNode (&Dev->ChildList);
+ !IsNodeAtEnd (&Dev->ChildList, Entry);
+ Entry = GetNextNode (&Dev->ChildList, Entry)) {
+ Child = XENBUS_PRIVATE_DATA_FROM_LINK (Entry);
+ if (!AsciiStrCmp (Child->XenbusIo.Node, Node)) {
+ Result = Child;
+ break;
+ }
+ }
+
+ return (Result);
+}
+
+STATIC
+XenbusState
+XenbusReadDriverState (
+ IN CONST CHAR8 *Path
+ )
+{
+ XenbusState State;
+ CHAR8 *Ptr;
+ XENSTORE_STATUS Status;
+
+ Status = XenstoreRead (XST_NIL, Path, "state", NULL, (VOID **)&Ptr);
+ if (Status != XENSTORE_STATUS_SUCCESS) {
+ State = XenbusStateClosed;
+ } else {
+ State = AsciiStrDecimalToUintn (Ptr);
+ FreePool (Ptr);
+ }
+
+ return State;
+}
+
+STATIC
+EFI_STATUS
+XenbusAddDevice (
+ XENBUS_DEVICE *Dev,
+ CONST CHAR8 *Type,
+ CONST CHAR8 *Id)
+{
+ CHAR8 DevicePath[XENSTORE_ABS_PATH_MAX];
+ XENSTORE_STATUS StatusXenstore;
+ XENBUS_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ XENBUS_DEVICE_PATH *TempXenbusPath;
+ VOID *ChildPciIo;
+
+ AsciiSPrint (DevicePath, sizeof (DevicePath),
+ XENBUS_XENSTORE_NODE "/%a/%a", Type, Id);
+
+ Status = EFI_NOT_STARTED; //ENXIO; // Device not configured
+
+ if (XenstorePathExists (XST_NIL, DevicePath, "")) {
+ XENBUS_PRIVATE_DATA *Child;
+ enum xenbus_state State;
+ CHAR8 *BackendPath;
+
+ Child = XenbusDeviceInitialized (Dev, DevicePath);
+ if (Child != NULL) {
+ /*
+ * We are already tracking this node
+ */
+ Status = EFI_SUCCESS;
+ goto out;
+ }
+
+ State = XenbusReadDriverState (DevicePath);
+ if (State != XenbusStateInitialising) {
+ /*
+ * Device is not new, so ignore it. This can
+ * happen if a device is going away after
+ * switching to Closed.
+ */
+ DEBUG ((EFI_D_INFO, "Xenbus: Device %a ignored. "
+ "State %d\n", DevicePath, State));
+ Status = EFI_SUCCESS;
+ goto out;
+ }
+
+ StatusXenstore = XenstoreRead (XST_NIL, DevicePath, "backend",
+ NULL, (VOID **) &BackendPath);
+ if (StatusXenstore != XENSTORE_STATUS_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "xenbus: %a no backend path.\n", DevicePath));
+ Status = EFI_NOT_FOUND;
+ goto out;
+ }
+
+ Private = AllocateCopyPool (sizeof *Private, &gXenbusPrivateData);
+ InsertTailList (&Dev->ChildList, &Private->Link);
+
+ Private->XenbusIo.Type = AsciiStrDup (Type);
+ Private->XenbusIo.Node = AsciiStrDup (DevicePath);
+ Private->XenbusIo.Backend = BackendPath;
+ Private->XenbusIo.DeviceId = AsciiStrDecimalToUintn (Id);
+ Private->Dev = Dev;
+
+ TempXenbusPath = AllocateCopyPool (sizeof (XENBUS_DEVICE_PATH),
+ &gXenbusDevicePathTemplate);
+ if (!AsciiStrCmp (Private->XenbusIo.Type, "vbd")) {
+ TempXenbusPath->Type = XENBUS_DEVICE_PATH_TYPE_VBD;
+ }
+ TempXenbusPath->DeviceId = Private->XenbusIo.DeviceId;
+ Private->DevicePath = (XENBUS_DEVICE_PATH *)AppendDevicePathNode (
+ Dev->DevicePath,
+ &TempXenbusPath->Vendor.Header);
+ FreePool (TempXenbusPath);
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->Handle,
+ &gEfiDevicePathProtocolGuid, Private->DevicePath,
+ &gXenbusProtocolGuid, &Private->XenbusIo,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol (Dev->ControllerHandle,
+ &gEfiPciIoProtocolGuid,
+ &ChildPciIo, Dev->This->DriverBindingHandle,
+ Private->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "open by child controller fail (%r)\n",
+ Status));
+ }
+ } else {
+ DEBUG ((EFI_D_INFO, "Xenbus: does not exist: %a\n", DevicePath));
+ }
+
+out:
+ return Status;
+}
+
+/**
+ * \brief Enumerate all devices of the given type on this bus.
+ *
+ * \param Dev NewBus device_t for this XenBus front bus instance.
+ * \param type String indicating the device sub-tree (e.g. "vfb", "vif")
+ * to enumerate.
+ *
+ * Devices that are found are entered into the NewBus hierarchy via
+ * xenbusb_add_device(). xenbusb_add_device() ignores duplicate detects
+ * and ignores duplicate devices, so it can be called unconditionally
+ * for any device found in the XenStore.
+ */
+STATIC
+VOID
+XenbusEnumerateDeviceType (
+ XENBUS_DEVICE *Dev,
+ CONST CHAR8 *Type
+ )
+{
+ CONST CHAR8 **Directory;
+ UINTN Index;
+ UINT32 Count;
+ XENSTORE_STATUS Status;
+
+ Status = XenstoreListDirectory (XST_NIL,
+ XENBUS_XENSTORE_NODE, Type,
+ &Count, &Directory);
+ if (Status != XENSTORE_STATUS_SUCCESS) {
+ return;
+ }
+ for (Index = 0; Index < Count; Index++) {
+ XenbusAddDevice (Dev, Type, Directory[Index]);
+ }
+
+ FreePool (Directory);
+}
+
+
+/**
+ * \brief Enumerate the devices on a XenBus bus and register them with
+ * the NewBus device tree.
+ *
+ * xenbusb_enumerate_bus() will create entries (in state DS_NOTPRESENT)
+ * for nodes that appear in the XenStore, but will not invoke probe/attach
+ * operations on drivers. Probe/Attach processing must be separately
+ * performed via an invocation of xenbusb_probe_children(). This is usually
+ * done via the xbs_probe_children task.
+ *
+ * \param Dev XenBus Bus device softc of the owner of the bus to enumerate.
+ *
+ * \return On success, 0. Otherwise an errno value indicating the
+ * type of failure.
+ */
+XENSTORE_STATUS
+XenbusEnumerateBus (
+ XENBUS_DEVICE *Dev
+ )
+{
+ CONST CHAR8 **Types;
+ UINTN Index;
+ UINT32 Count;
+ XENSTORE_STATUS Status;
+
+ Status = XenstoreListDirectory (XST_NIL,
+ XENBUS_XENSTORE_NODE, "",
+ &Count, &Types);
+ if (Status != XENSTORE_STATUS_SUCCESS) {
+ return Status;
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ XenbusEnumerateDeviceType (Dev, Types[Index]);
+ }
+
+ FreePool (Types);
+
+ return XENSTORE_STATUS_SUCCESS;
+}
+
+STATIC
+XENSTORE_STATUS
+EFIAPI
+XenbusSetState (
+ IN XENBUS_PROTOCOL *This,
+ IN XENSTORE_TRANSACTION Transaction,
+ IN enum xenbus_state NewState
+ )
+{
+ XENBUS_PRIVATE_DATA *Private;
+ enum xenbus_state CurrentState;
+ XENSTORE_STATUS Status;
+ CHAR8 *Temp;
+
+ DEBUG ((EFI_D_INFO, "Xenbus: Set state to %d\n", NewState));
+
+ Private = XENBUS_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = XenstoreRead (Transaction, This->Node, "state", NULL, (VOID
**)&Temp);
+ if (Status != XENSTORE_STATUS_SUCCESS) {
+ goto Error;
+ }
+ CurrentState = AsciiStrDecimalToUintn (Temp);
+ FreePool (Temp);
+ if (CurrentState == NewState) {
+ DEBUG ((EFI_D_INFO, "%a %d, same state\n", __func__, __LINE__));
+ goto Error;
+ }
+
+ do {
+ Status = XenstoreSPrint (Transaction, This->Node, "state", "%d", NewState);
+ } while (Status == XENSTORE_STATUS_EAGAIN);
+ if (Status != XENSTORE_STATUS_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Xenbus: fail to writing new state\n"));
+ goto Error;
+ }
+ DEBUG ((EFI_D_INFO, "Xenbus: Set state to %d, done\n", NewState));
+
+Error:
+ return Status;
+}
+
+STATIC XENBUS_PRIVATE_DATA gXenbusPrivateData = {
+ .Signature = XENBUS_PRIVATE_DATA_SIGNATURE,
+
+ .XenbusIo.XsRead = XenbusXenstoreRead,
+ .XenbusIo.XsBackendRead = XenbusXenstoreBackendRead,
+ .XenbusIo.XsPrintf = XenbusXenstoreSPrint,
+ .XenbusIo.XsRemove = XenbusXenstoreRemove,
+ .XenbusIo.XsTransactionStart = XenbusXenstoreTransactionStart,
+ .XenbusIo.XsTransactionEnd = XenbusXenstoreTransactionEnd,
+ .XenbusIo.SetState = XenbusSetState,
+ .XenbusIo.GrantAccess = XenbusGrantAccess,
+ .XenbusIo.GrantEndAccess = XenbusGrantEndAccess,
+ .XenbusIo.RegisterWatch = XenbusRegisterWatch,
+ .XenbusIo.RegisterWatchBackend = XenbusRegisterWatchBackend,
+ .XenbusIo.UnregisterWatch = XenbusUnregisterWatch,
+ .XenbusIo.WaitForWatch = XenbusWaitForWatch,
+
+ .XenbusIo.Type = NULL,
+ .XenbusIo.Node = NULL,
+ .XenbusIo.Backend = NULL,
+
+ .Dev = NULL
+};
diff --git a/OvmfPkg/XenbusDxe/XenBus.h b/OvmfPkg/XenbusDxe/XenBus.h
new file mode 100644
index 0000000..63d0815
--- /dev/null
+++ b/OvmfPkg/XenbusDxe/XenBus.h
@@ -0,0 +1,76 @@
+/*-
+ * Core definitions and data structures shareable across OS platforms.
+ *
+ * Copyright (c) 2010 Spectra Logic Corporation
+ * Copyright (C) 2008 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD: release/10.0.0/sys/xen/xenbus/xenbusb.h 222975 2011-06-11
04:59:01Z gibbs $
+ */
+#ifndef _XEN_XENBUS_XENBUSB_H
+#define _XEN_XENBUS_XENBUSB_H
+
+#include "XenbusDxe.h"
+
+#define XENBUS_DEVICE_PATH_TYPE_VBD 0x1
+struct _XENBUS_DEVICE_PATH {
+ VENDOR_DEVICE_PATH Vendor;
+ UINT8 Type;
+ UINT16 DeviceId;
+};
+
+/**
+ * The VM relative path to the XenStore subtree this
+ * bus attachment manages.
+ *
+ * OR
+ *
+ * The XenStore path to the XenStore subtree for this XenBus bus.
+ */
+#define XENBUS_XENSTORE_NODE "device"
+
+
+/**
+ * \brief Perform common XenBus bus attach processing.
+ *
+ * \param Dev The NewBus device representing this XenBus bus.
+ *
+ * \return On success, 0. Otherwise an errno value indicating the
+ * type of failure.
+ *
+ * Intiailizes the softc for this bus, installs an interrupt driven
+ * configuration hook to block boot processing until XenBus devices fully
+ * configure, performs an initial probe/attach of the bus, and registers
+ * a XenStore watch so we are notified when the bus topology changes.
+ */
+XENSTORE_STATUS
+XenbusEnumerateBus (
+ XENBUS_DEVICE *Dev
+ );
+
+#endif /* _XEN_XENBUS_XENBUSB_H */
diff --git a/OvmfPkg/XenbusDxe/XenbusDxe.c b/OvmfPkg/XenbusDxe/XenbusDxe.c
index 2c85d5e..56225c4 100644
--- a/OvmfPkg/XenbusDxe/XenbusDxe.c
+++ b/OvmfPkg/XenbusDxe/XenbusDxe.c
@@ -19,6 +19,7 @@
#include "XenHypercall.h"
#include "GrantTable.h"
#include "Xenstore.h"
+#include "XenBus.h"
///
/// Driver Binding Protocol instance
@@ -295,6 +296,7 @@ XenbusDxeDriverBindingStart (
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
UINT64 MmioAddr;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
Status = gBS->OpenProtocol (
ControllerHandle,
@@ -308,11 +310,26 @@ XenbusDxeDriverBindingStart (
return Status;
}
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
Dev = AllocateZeroPool (sizeof (*Dev));
Dev->Signature = XENBUS_DEVICE_SIGNATURE;
Dev->This = This;
Dev->ControllerHandle = ControllerHandle;
Dev->PciIo = PciIo;
+ Dev->DevicePath = DevicePath;
+ InitializeListHead (&Dev->ChildList);
Status = PciIo->GetBarAttributes (PciIo, PCI_BAR_IDX1, NULL, (VOID**)
&BarDesc);
ASSERT_EFI_ERROR (Status);
@@ -334,6 +351,8 @@ XenbusDxeDriverBindingStart (
Status = XenstoreInit (Dev);
ASSERT_EFI_ERROR (Status);
+ XenbusEnumerateBus (Dev);
+
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
NotifyExitBoot,
(VOID*) Dev,
@@ -379,12 +398,54 @@ XenbusDxeDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
+ UINTN Index;
+ XENBUS_PROTOCOL *XenbusIo;
+ XENBUS_PRIVATE_DATA *ChildData;
+ EFI_STATUS Status;
XENBUS_DEVICE *Dev = mMyDevice;
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+ Status = gBS->OpenProtocol (
+ ChildHandleBuffer[Index],
+ &gXenbusProtocolGuid,
+ (VOID **) &XenbusIo,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "XenbusDxe: get childre proto: %r\n", Status));
+ continue;
+ }
+ ChildData = XENBUS_PRIVATE_DATA_FROM_THIS(XenbusIo);
+ Status = gBS->DisconnectController(ChildData->Handle, NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "XenbusDxe: error disconnecting child: %r\n",
+ Status));
+ continue;
+ }
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildData->Handle,
+ &gEfiDevicePathProtocolGuid, ChildData->DevicePath,
+ &gXenbusProtocolGuid, &ChildData->XenbusIo,
+ NULL);
+ ASSERT_EFI_ERROR (Status);
+
+ FreePool ((VOID*)ChildData->XenbusIo.Type);
+ FreePool ((VOID*)ChildData->XenbusIo.Node);
+ FreePool ((VOID*)ChildData->XenbusIo.Backend);
+ FreePool (ChildData->DevicePath);
+ RemoveEntryList (&ChildData->Link);
+ FreePool (ChildData);
+ }
+
gBS->CloseEvent (Dev->ExitBootEvent);
+ // XXX xenbus cleanup
// XXX xenstore cleanup
XenGrantTableDeinit (Dev);
+ gBS->CloseProtocol(ControllerHandle, &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle, ControllerHandle);
gBS->CloseProtocol(ControllerHandle, &gEfiPciIoProtocolGuid,
This->DriverBindingHandle, ControllerHandle);
return EFI_SUCCESS;
diff --git a/OvmfPkg/XenbusDxe/XenbusDxe.h b/OvmfPkg/XenbusDxe/XenbusDxe.h
index 4d9db72..3ff08dd 100644
--- a/OvmfPkg/XenbusDxe/XenbusDxe.h
+++ b/OvmfPkg/XenbusDxe/XenbusDxe.h
@@ -80,6 +80,7 @@ extern EFI_COMPONENT_NAME_PROTOCOL gXenbusDxeComponentName;
#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
+typedef struct _XENBUS_DEVICE_PATH XENBUS_DEVICE_PATH;
typedef struct _XENBUS_DEVICE XENBUS_DEVICE;
#define XENBUS_DEVICE_SIGNATURE SIGNATURE_32 ('X','B','b','d')
@@ -89,11 +90,28 @@ struct _XENBUS_DEVICE {
EFI_HANDLE ControllerHandle;
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_EVENT ExitBootEvent;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ LIST_ENTRY ChildList;
VOID *Hyperpage;
shared_info_t *SharedInfo;
};
+#define XENBUS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('X', 'B', 'u', 's')
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+ EFI_HANDLE Handle;
+ XENBUS_PROTOCOL XenbusIo;
+ XENBUS_DEVICE *Dev;
+ XENBUS_DEVICE_PATH *DevicePath;
+} XENBUS_PRIVATE_DATA;
+
+#define XENBUS_PRIVATE_DATA_FROM_THIS(a) \
+ CR (a, XENBUS_PRIVATE_DATA, XenbusIo, XENBUS_PRIVATE_DATA_SIGNATURE)
+#define XENBUS_PRIVATE_DATA_FROM_LINK(a) \
+ CR (a, XENBUS_PRIVATE_DATA, Link, XENBUS_PRIVATE_DATA_SIGNATURE)
+
/*
* Helpers
*/
diff --git a/OvmfPkg/XenbusDxe/XenbusDxe.inf b/OvmfPkg/XenbusDxe/XenbusDxe.inf
index 6c8260f..708fae6 100644
--- a/OvmfPkg/XenbusDxe/XenbusDxe.inf
+++ b/OvmfPkg/XenbusDxe/XenbusDxe.inf
@@ -40,6 +40,9 @@
EventChannel.h
Xenstore.c
Xenstore.h
+ XenBus.c
+ XenBus.h
+ Helpers.c
[Sources.X64]
X64/hypercall.S
--
Anthony PERARD
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |