xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Anthony PERARD <anthony.perard@citrix.com>
Cc: EDK2 devel <edk2-devel@lists.sourceforge.net>,
	Xen Devel <xen-devel@lists.xen.org>
Subject: Re: [PATCH v2 14/18] OvmfPkg/XenBusDxe: Indroduce XenBus support itself.
Date: Thu, 11 Sep 2014 13:10:14 -0400	[thread overview]
Message-ID: <20140911171014.GA9015@laptop.dumpdata.com> (raw)
In-Reply-To: <1409849473-9268-15-git-send-email-anthony.perard@citrix.com>

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@citrix.com>
> 
> ---
> 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

> +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.

> +    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.

> + */
> +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

> + */
> +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?
> +**/
> +#define XENBUS_XENSTORE_NODE "device"
> +
> +
> +/**
> +  Perform XenBus bus enumeration and install protocol for childs.

childs? 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@lists.xen.org
> http://lists.xen.org/xen-devel

  parent reply	other threads:[~2014-09-11 17:10 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1409849473-9268-1-git-send-email-anthony.perard@citrix.com>
2014-09-04 16:50 ` [PATCH v2 01/18] OvmfPkg: Add public headers from Xen Project Anthony PERARD
2014-09-04 16:50 ` [PATCH v2 02/18] OvmfPkg: Add basic skeleton for the XenBus bus driver Anthony PERARD
2014-09-04 16:50 ` [PATCH v2 03/18] OvmfPkg/XenBusDxe: Add device state struct and create an ExitBoot services event Anthony PERARD
2014-09-04 16:50 ` [PATCH v2 04/18] OvmfPkg/XenBusDxe: Add support to make Xen Hypercalls Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 05/18] OvmfPkg/XenBusDxe: Open PciIo protocol Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 06/18] OvmfPkg: Introduce XenBus Protocol Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 07/18] OvmfPkg/XenBusDxe: Add InterlockedCompareExchange16 Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 08/18] OvmfPkg/XenBusDxe: Add Grant Table functions Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 09/18] OvmfPkg/XenBusDxe: Add Event Channel Notify Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 10/18] OvmfPkg/XenBusDxe: Add TestAndClearBit Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 11/18] OvmfPkg/XenBusDxe: Add XenStore client implementation Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 12/18] OvmfPkg/XenBusDxe: Add an helper AsciiStrDup Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 13/18] OvmfPkg/XenBusDxe: Add XenStore function into the XenBus protocol Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 14/18] OvmfPkg/XenBusDxe: Indroduce XenBus support itself Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 15/18] OvmfPkg/XenBusDxe: Add Event Channel into XenBus protocol Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 16/18] OvmfPkg/XenPvBlkDxe: Xen PV Block device, initial skeleton Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 17/18] OvmfPkg/XenPvBlkDxe: Add BlockFront client Anthony PERARD
2014-09-04 16:51 ` [PATCH v2 18/18] OvmfPkg/XenPvBlkDxe: Add BlockIo Anthony PERARD
2014-09-04 18:01 ` [edk2] [PATCH v2 00/18] Introducing Xen PV block driver to OVMF Laszlo Ersek
     [not found] ` <5408A8E3.2020805@redhat.com>
2014-09-05 13:34   ` Anthony PERARD
     [not found]   ` <20140905133440.GB1654@perard.uk.xensource.com>
2014-09-05 19:30     ` Jordan Justen
2014-09-05 21:14     ` Laszlo Ersek
     [not found]     ` <CAFe8ug86UtwYQY-1P5wp6tQ_2Yi2fwgNU7+knHV0JH4SDz07jQ@mail.gmail.com>
2014-09-08 15:36       ` Anthony PERARD
     [not found] ` <1409849473-9268-2-git-send-email-anthony.perard@citrix.com>
2014-09-10 19:43   ` [PATCH v2 01/18] OvmfPkg: Add public headers from Xen Project Konrad Rzeszutek Wilk
     [not found] ` <1409849473-9268-3-git-send-email-anthony.perard@citrix.com>
2014-09-10 19:49   ` [PATCH v2 02/18] OvmfPkg: Add basic skeleton for the XenBus bus driver Konrad Rzeszutek Wilk
     [not found] ` <1409849473-9268-4-git-send-email-anthony.perard@citrix.com>
2014-09-10 19:58   ` [PATCH v2 03/18] OvmfPkg/XenBusDxe: Add device state struct and create an ExitBoot services event Konrad Rzeszutek Wilk
2014-09-18 10:33     ` Anthony PERARD
     [not found] ` <1409849473-9268-5-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:01   ` [PATCH v2 04/18] OvmfPkg/XenBusDxe: Add support to make Xen Hypercalls Konrad Rzeszutek Wilk
     [not found] ` <1409849473-9268-6-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:03   ` [PATCH v2 05/18] OvmfPkg/XenBusDxe: Open PciIo protocol Konrad Rzeszutek Wilk
     [not found] ` <1409849473-9268-7-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:05   ` [PATCH v2 06/18] OvmfPkg: Introduce XenBus Protocol Konrad Rzeszutek Wilk
     [not found] ` <1409849473-9268-8-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:09   ` [PATCH v2 07/18] OvmfPkg/XenBusDxe: Add InterlockedCompareExchange16 Konrad Rzeszutek Wilk
2014-09-18 10:55     ` Anthony PERARD
     [not found] ` <1409849473-9268-9-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:12   ` [PATCH v2 08/18] OvmfPkg/XenBusDxe: Add Grant Table functions Konrad Rzeszutek Wilk
     [not found] ` <1409849473-9268-10-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:15   ` [PATCH v2 09/18] OvmfPkg/XenBusDxe: Add Event Channel Notify Konrad Rzeszutek Wilk
2014-09-18 10:56     ` Anthony PERARD
     [not found] ` <1409849473-9268-11-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:18   ` [PATCH v2 10/18] OvmfPkg/XenBusDxe: Add TestAndClearBit Konrad Rzeszutek Wilk
     [not found] ` <1409849473-9268-12-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:48   ` [PATCH v2 11/18] OvmfPkg/XenBusDxe: Add XenStore client implementation Konrad Rzeszutek Wilk
2014-09-18 11:10     ` Anthony PERARD
     [not found] ` <1409849473-9268-13-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:50   ` [PATCH v2 12/18] OvmfPkg/XenBusDxe: Add an helper AsciiStrDup Konrad Rzeszutek Wilk
     [not found] ` <1409849473-9268-14-git-send-email-anthony.perard@citrix.com>
2014-09-10 20:54   ` [PATCH v2 13/18] OvmfPkg/XenBusDxe: Add XenStore function into the XenBus protocol Konrad Rzeszutek Wilk
     [not found] ` <1409849473-9268-15-git-send-email-anthony.perard@citrix.com>
2014-09-11 17:10   ` Konrad Rzeszutek Wilk [this message]
2014-09-18 11:26     ` [PATCH v2 14/18] OvmfPkg/XenBusDxe: Indroduce XenBus support itself Anthony PERARD
     [not found] ` <1409849473-9268-16-git-send-email-anthony.perard@citrix.com>
2014-09-12 13:58   ` [PATCH v2 15/18] OvmfPkg/XenBusDxe: Add Event Channel into XenBus protocol Konrad Rzeszutek Wilk
2014-09-18 11:28     ` Anthony PERARD
     [not found] ` <1409849473-9268-17-git-send-email-anthony.perard@citrix.com>
2014-09-12 14:03   ` [PATCH v2 16/18] OvmfPkg/XenPvBlkDxe: Xen PV Block device, initial skeleton Konrad Rzeszutek Wilk
2014-09-18 11:31     ` Anthony PERARD
     [not found] ` <1409849473-9268-18-git-send-email-anthony.perard@citrix.com>
2014-09-12 14:47   ` [PATCH v2 17/18] OvmfPkg/XenPvBlkDxe: Add BlockFront client Konrad Rzeszutek Wilk
2014-09-18 11:53     ` Anthony PERARD
     [not found] ` <1409849473-9268-19-git-send-email-anthony.perard@citrix.com>
2014-09-12 14:57   ` [PATCH v2 18/18] OvmfPkg/XenPvBlkDxe: Add BlockIo Konrad Rzeszutek Wilk
2014-09-18 15:00     ` Anthony PERARD

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140911171014.GA9015@laptop.dumpdata.com \
    --to=konrad.wilk@oracle.com \
    --cc=anthony.perard@citrix.com \
    --cc=edk2-devel@lists.sourceforge.net \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).