[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 14/18] OvmfPkg/XenBusDxe: Indroduce XenBus support itself.
On Thu, Sep 11, 2014 at 01:10:14PM -0400, Konrad Rzeszutek Wilk wrote: > On Thu, Sep 04, 2014 at 05:51:09PM +0100, Anthony PERARD wrote: > > 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> > > > > --- > > Change in V2: > > - comment, file header > > - Fix comment style > > - Error handling in the main init function > > - coding style > > - Fix error path in add device. > > --- > > OvmfPkg/Include/Protocol/XenBus.h | 11 +- > > OvmfPkg/XenBusDxe/XenBus.c | 368 > > ++++++++++++++++++++++++++++++++++++++ > > OvmfPkg/XenBusDxe/XenBus.h | 67 +++++++ > > OvmfPkg/XenBusDxe/XenBusDxe.c | 71 ++++++++ > > OvmfPkg/XenBusDxe/XenBusDxe.h | 19 ++ > > OvmfPkg/XenBusDxe/XenBusDxe.inf | 3 + > > 6 files changed, 538 insertions(+), 1 deletion(-) > > 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 99e174b..f223be7 100644 > > --- a/OvmfPkg/Include/Protocol/XenBus.h > > +++ b/OvmfPkg/Include/Protocol/XenBus.h > > @@ -45,7 +45,7 @@ > > /// > > typedef struct _XENBUS_PROTOCOL XENBUS_PROTOCOL; > > > > -typedef enum xenbus_state XenbusState; > > +typedef enum xenbus_state XenBusState; > > > > typedef struct > > { > > @@ -138,6 +138,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, > > @@ -196,6 +204,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..2e1f939 > > --- /dev/null > > +++ b/OvmfPkg/XenBusDxe/XenBus.c > > @@ -0,0 +1,368 @@ > > +/** @file > > + XenBus Bus driver implemtation. > > + > > + This file implement the necessary to discover and enumerate Xen PV > > devices > > + through XenStore. > > + > > + 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 > > + Copyright (C) 2014, Citrix 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 <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 Node is known to the system. > > + > > + @param Dev The XENBUS_DEVICE instance to search for device children. > > + @param Node The XenStore node path for the device to find. > > + > > + @return The XENBUS_PRIVATE_DATA of the found device if any, or NULL. > > + */ > > +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 = NULL; > > + XENSTORE_STATUS Status; > > + > > + Status = XenStoreRead (XST_NIL, Path, "state", NULL, (VOID **)&Ptr); > > + if (Status != XENSTORE_STATUS_SUCCESS) { > > + State = XenbusStateClosed; > > + } else { > > + State = AsciiStrDecimalToUintn (Ptr); > > + } > > + > > + if (Ptr != NULL) { > > + FreePool (Ptr); > > + } > > + > > + return State; > > +} > > + > > Could you add a comment here saying that the callers should > ensure that they are the only ones calling this function - as this > function does not take a lock when adding in the Dev->ChildList Ok, will do. > > +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); > > + > > + 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); > > Could you move the 'InsertTailList' to be done after the 'Private' > has been fully populated? I know that the current caller of this function is > only called during initialization - but in the future this could be > extended to called multiple times - and if there are two threads - one > adding and another reading from Dev->ChildList - the second thread can > get incomplete data. Ok, will do. > > + FreePool (TempXenBusPath); > > + > > + Status = gBS->InstallMultipleProtocolInterfaces ( > > + &Private->Handle, > > + &gEfiDevicePathProtocolGuid, Private->DevicePath, > > + &gXenBusProtocolGuid, &Private->XenBusIo, > > + NULL); > > + if (EFI_ERROR (Status)) { > > + goto ErrorInstallProtocol; > > + } > > + > > + 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)); > > + goto ErrorOpenProtocolByChild; > > + } > > + } else { > > + DEBUG ((EFI_D_ERROR, "XenBus: does not exist: %a\n", DevicePath)); > > + Status = EFI_NOT_FOUND; > > + } > > + > > +out: > > + return Status; > > +ErrorOpenProtocolByChild: > > + gBS->UninstallMultipleProtocolInterfaces ( > > + &Private->Handle, > > + &gEfiDevicePathProtocolGuid, Private->DevicePath, > > + &gXenBusProtocolGuid, &Private->XenBusIo, > > + NULL); > > +ErrorInstallProtocol: > > + FreePool (Private->DevicePath); > > + FreePool ((VOID *) Private->XenBusIo.Backend); > > + FreePool ((VOID *) Private->XenBusIo.Node); > > + FreePool ((VOID *) Private->XenBusIo.Type); > > + RemoveEntryList (&Private->Link); > > + FreePool (Private); > > + return Status; > > +} > > + > > +/** > > + Enumerate all devices of the given type on this bus. > > + > > + @param Dev A XENBUS_DEVICE instance. > > + @param Type String indicating the device sub-tree (e.g. "vfb", "vif") > > + to enumerate. > > + > > + Devices that are found are been initialize via XenBusAddDevice (). > > + XenBusAddDevice () ignores duplicate detects and ignores duplicate > > devices, > > + so it can be called unconditionally for any device found in the XenStore. > > > .. And the caller needs to ensure it is the only one calling it - or > it holds a lock. Ok, will add something. > > + */ > > +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); > > +} > > + > > + > > +/** > > + Enumerate the devices on a XenBus bus and install a XenBus Protocol > > instance. > > + > > + @param Dev A XENBUS_DEVICE instance. > > + > > + @return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value > > + indicating the type of failure. > > Since this is public, I think it should also perculate the need to hold > a lock and not call this concurrently. Or that this function ought to not > be called at the same as XenBusDeviceInitialized Ok, will do something about it. > > + */ > > +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 Out; > > + } > > + CurrentState = AsciiStrDecimalToUintn (Temp); > > + FreePool (Temp); > > + if (CurrentState == NewState) { > > + goto Out; > > + } > > + > > + do { > > + Status = XenStoreSPrint (Transaction, This->Node, "state", "%d", > > NewState); > > + } while (Status == XENSTORE_STATUS_EAGAIN); > > + if (Status != XENSTORE_STATUS_SUCCESS) { > > + DEBUG ((EFI_D_ERROR, "XenBus: failed to write new state\n")); > > + goto Out; > > + } > > + DEBUG ((EFI_D_INFO, "XenBus: Set state to %d, done\n", NewState)); > > + > > +Out: > > + 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..48e0389 > > --- /dev/null > > +++ b/OvmfPkg/XenBusDxe/XenBus.h > > @@ -0,0 +1,67 @@ > > +/** @file > > + Core definitions and data structures shareable across OS platforms. > > + > > + Copyright (c) 2010 Spectra Logic Corporation > > + Copyright (C) 2008 Doug Rabson > > + All rights reserved. > > + Copyright (C) 2014, Citrix Ltd. > > + > > + 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. > > + > > +**/ > > +#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. > > Huh? That's an original comment, it was originaly a variable for the enumerate bus function. Maybe I should just replace the macro by "device" directly in the code and avoid the define and it's comment. > > +**/ > > +#define XENBUS_XENSTORE_NODE "device" > > + > > + > > +/** > > + Perform XenBus bus enumeration and install protocol for childs. > > childs? children? Yes, children... > > + > > + @param Dev The NewBus device representing this XenBus bus. > > + > > + @return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno > > value > > + indicating the type of failure. > > +**/ > > +XENSTORE_STATUS > > +XenBusEnumerateBus ( > > + XENBUS_DEVICE *Dev > > + ); > > + > > +#endif /* _XEN_XENBUS_XENBUSB_H */ > > diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c > > index 76ea67c..50090ba 100644 > > --- a/OvmfPkg/XenBusDxe/XenBusDxe.c > > +++ b/OvmfPkg/XenBusDxe/XenBusDxe.c > > @@ -48,6 +48,7 @@ > > #include "XenHypercall.h" > > #include "GrantTable.h" > > #include "XenStore.h" > > +#include "XenBus.h" > > > > > > /// > > @@ -301,6 +302,7 @@ XenBusDxeDriverBindingStart ( > > EFI_PCI_IO_PROTOCOL *PciIo; > > EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc; > > UINT64 MmioAddr; > > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > > > > Status = gBS->OpenProtocol ( > > ControllerHandle, > > @@ -314,12 +316,32 @@ XenBusDxeDriverBindingStart ( > > return Status; > > } > > > > + Status = gBS->OpenProtocol ( > > + ControllerHandle, > > + &gEfiDevicePathProtocolGuid, > > + (VOID **) &DevicePath, > > + This->DriverBindingHandle, > > + ControllerHandle, > > + EFI_OPEN_PROTOCOL_BY_DRIVER > > + ); > > + > > + if (EFI_ERROR (Status)) { > > + goto ErrorOpenningProtocol; > > + } > > + > > Dev = AllocateZeroPool (sizeof (*Dev)); > > Dev->Signature = XENBUS_DEVICE_SIGNATURE; > > Dev->This = This; > > Dev->ControllerHandle = ControllerHandle; > > Dev->PciIo = PciIo; > > + Dev->DevicePath = DevicePath; > > + InitializeListHead (&Dev->ChildList); > > > > + // > > + // The BAR1 of this PCI device is used for shared memory and is supposed > > to > > + // look like MMIO. The address space of the BAR1 will be used to map the > > + // Grant Table. > > + // > > Status = PciIo->GetBarAttributes (PciIo, PCI_BAR_IDX1, NULL, (VOID**) > > &BarDesc); > > ASSERT_EFI_ERROR (Status); > > ASSERT (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM); > > @@ -348,6 +370,8 @@ XenBusDxeDriverBindingStart ( > > Status = XenStoreInit (Dev); > > ASSERT_EFI_ERROR (Status); > > > > + XenBusEnumerateBus (Dev); > > + > > Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK, > > NotifyExitBoot, > > (VOID*) Dev, > > @@ -359,6 +383,9 @@ XenBusDxeDriverBindingStart ( > > > > ErrorNoHyperpage: > > FreePool (Dev); > > + gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, > > + This->DriverBindingHandle, ControllerHandle); > > +ErrorOpenningProtocol: > > gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid, > > This->DriverBindingHandle, ControllerHandle); > > return Status; > > @@ -399,12 +426,56 @@ 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 children protocol failed: > > %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); > > + } > > + if (NumberOfChildren > 0) { > > + return EFI_SUCCESS; > > + } > > + > > gBS->CloseEvent (Dev->ExitBootEvent); > > XenStoreDeinit (Dev); > > 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 dc48a46..7213184 100644 > > --- a/OvmfPkg/XenBusDxe/XenBusDxe.h > > +++ b/OvmfPkg/XenBusDxe/XenBusDxe.h > > @@ -98,6 +98,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; > > > > // Have the state of the driver. > > @@ -108,11 +109,29 @@ 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; > > }; > > > > +// There is one of this struct allocated for every child. > > +#define XENBUS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('X', 'B', 'p', 'd') > > +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 9052967..c326bcf 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 -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |