REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the OvmfPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			414 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			414 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  XenBus Bus driver implementation.
 | 
						|
 | 
						|
  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:
 | 
						|
 | 
						|
  SPDX-License-Identifier: MIT
 | 
						|
**/
 | 
						|
 | 
						|
#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
 | 
						|
    {                                               // Vendor.Header
 | 
						|
      HARDWARE_DEVICE_PATH,                         // Vendor.Header.Type
 | 
						|
      HW_VENDOR_DP,                                 // Vendor.Header.SubType
 | 
						|
      {
 | 
						|
        (UINT8)(sizeof (XENBUS_DEVICE_PATH)),       // Vendor.Header.Length[0]
 | 
						|
        (UINT8)(sizeof (XENBUS_DEVICE_PATH) >> 8),  // Vendor.Header.Length[1]
 | 
						|
      }
 | 
						|
    },
 | 
						|
    XENBUS_PROTOCOL_GUID,                           // Vendor.Guid
 | 
						|
  },
 | 
						|
  0,                                                // Type
 | 
						|
  0                                                 // DeviceId
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  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;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// Callers should ensure that they are only one calling XenBusAddDevice.
 | 
						|
//
 | 
						|
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                 *ChildXenIo;
 | 
						|
 | 
						|
  AsciiSPrint (
 | 
						|
    DevicePath,
 | 
						|
    sizeof (DevicePath),
 | 
						|
    "device/%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 ((
 | 
						|
        DEBUG_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 ((DEBUG_ERROR, "xenbus: %a no backend path.\n", DevicePath));
 | 
						|
      Status = EFI_NOT_FOUND;
 | 
						|
      goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    Private                    = AllocateCopyPool (sizeof (*Private), &gXenBusPrivateData);
 | 
						|
    Private->XenBusIo.Type     = AsciiStrDup (Type);
 | 
						|
    Private->XenBusIo.Node     = AsciiStrDup (DevicePath);
 | 
						|
    Private->XenBusIo.Backend  = BackendPath;
 | 
						|
    Private->XenBusIo.DeviceId = (UINT16)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);
 | 
						|
 | 
						|
    InsertTailList (&Dev->ChildList, &Private->Link);
 | 
						|
 | 
						|
    Status = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                    &Private->Handle,
 | 
						|
                    &gEfiDevicePathProtocolGuid,
 | 
						|
                    Private->DevicePath,
 | 
						|
                    &gXenBusProtocolGuid,
 | 
						|
                    &Private->XenBusIo,
 | 
						|
                    NULL
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      goto ErrorInstallProtocol;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = gBS->OpenProtocol (
 | 
						|
                    Dev->ControllerHandle,
 | 
						|
                    &gXenIoProtocolGuid,
 | 
						|
                    &ChildXenIo,
 | 
						|
                    Dev->This->DriverBindingHandle,
 | 
						|
                    Private->Handle,
 | 
						|
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      DEBUG ((
 | 
						|
        DEBUG_ERROR,
 | 
						|
        "open by child controller fail (%r)\n",
 | 
						|
        Status
 | 
						|
        ));
 | 
						|
      goto ErrorOpenProtocolByChild;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    DEBUG ((DEBUG_ERROR, "XenBus: does not exist: %a\n", DevicePath));
 | 
						|
    Status = EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
 | 
						|
ErrorOpenProtocolByChild:
 | 
						|
  gBS->UninstallMultipleProtocolInterfaces (
 | 
						|
         Private->Handle,
 | 
						|
         &gEfiDevicePathProtocolGuid,
 | 
						|
         Private->DevicePath,
 | 
						|
         &gXenBusProtocolGuid,
 | 
						|
         &Private->XenBusIo,
 | 
						|
         NULL
 | 
						|
         );
 | 
						|
ErrorInstallProtocol:
 | 
						|
  RemoveEntryList (&Private->Link);
 | 
						|
  FreePool (Private->DevicePath);
 | 
						|
  FreePool ((VOID *)Private->XenBusIo.Backend);
 | 
						|
  FreePool ((VOID *)Private->XenBusIo.Node);
 | 
						|
  FreePool ((VOID *)Private->XenBusIo.Type);
 | 
						|
  FreePool (Private);
 | 
						|
out:
 | 
						|
  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.
 | 
						|
 */
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
XenBusEnumerateDeviceType (
 | 
						|
  XENBUS_DEVICE  *Dev,
 | 
						|
  CONST CHAR8    *Type
 | 
						|
  )
 | 
						|
{
 | 
						|
  CONST CHAR8      **Directory;
 | 
						|
  UINTN            Index;
 | 
						|
  UINT32           Count;
 | 
						|
  XENSTORE_STATUS  Status;
 | 
						|
 | 
						|
  Status = XenStoreListDirectory (
 | 
						|
             XST_NIL,
 | 
						|
             "device",
 | 
						|
             Type,
 | 
						|
             &Count,
 | 
						|
             &Directory
 | 
						|
             );
 | 
						|
  if (Status != XENSTORE_STATUS_SUCCESS) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < Count; Index++) {
 | 
						|
    XenBusAddDevice (Dev, Type, Directory[Index]);
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool ((VOID *)Directory);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Enumerate the devices on a XenBus bus and install a XenBus Protocol instance.
 | 
						|
 | 
						|
  Caller should ensure that it is the only one to call this function. This
 | 
						|
  function cannot be called concurrently.
 | 
						|
 | 
						|
  @param Dev   A XENBUS_DEVICE instance.
 | 
						|
 | 
						|
  @return  On success, XENSTORE_STATUS_SUCCESS. 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,
 | 
						|
             "device",
 | 
						|
             "",
 | 
						|
             &Count,
 | 
						|
             &Types
 | 
						|
             );
 | 
						|
  if (Status != XENSTORE_STATUS_SUCCESS) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < Count; Index++) {
 | 
						|
    XenBusEnumerateDeviceType (Dev, Types[Index]);
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool ((VOID *)Types);
 | 
						|
 | 
						|
  return XENSTORE_STATUS_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
XENSTORE_STATUS
 | 
						|
EFIAPI
 | 
						|
XenBusSetState (
 | 
						|
  IN XENBUS_PROTOCOL             *This,
 | 
						|
  IN CONST XENSTORE_TRANSACTION  *Transaction,
 | 
						|
  IN enum xenbus_state           NewState
 | 
						|
  )
 | 
						|
{
 | 
						|
  enum xenbus_state  CurrentState;
 | 
						|
  XENSTORE_STATUS    Status;
 | 
						|
  CHAR8              *Temp;
 | 
						|
 | 
						|
  DEBUG ((DEBUG_INFO, "XenBus: Set state to %d\n", NewState));
 | 
						|
 | 
						|
  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 ((DEBUG_ERROR, "XenBus: failed to write new state\n"));
 | 
						|
    goto Out;
 | 
						|
  }
 | 
						|
 | 
						|
  DEBUG ((DEBUG_INFO, "XenBus: Set state to %d, done\n", NewState));
 | 
						|
 | 
						|
Out:
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
STATIC XENBUS_PRIVATE_DATA  gXenBusPrivateData = {
 | 
						|
  XENBUS_PRIVATE_DATA_SIGNATURE,    // Signature
 | 
						|
  { NULL, NULL },                   // Link
 | 
						|
  NULL,                             // Handle
 | 
						|
  {                                 // XenBusIo
 | 
						|
    XenBusXenStoreRead,             // XenBusIo.XsRead
 | 
						|
    XenBusXenStoreBackendRead,      // XenBusIo.XsBackendRead
 | 
						|
    XenBusXenStoreSPrint,           // XenBusIo.XsPrintf
 | 
						|
    XenBusXenStoreRemove,           // XenBusIo.XsRemove
 | 
						|
    XenBusXenStoreTransactionStart, // XenBusIo.XsTransactionStart
 | 
						|
    XenBusXenStoreTransactionEnd,   // XenBusIo.XsTransactionEnd
 | 
						|
    XenBusSetState,                 // XenBusIo.SetState
 | 
						|
    XenBusGrantAccess,              // XenBusIo.GrantAccess
 | 
						|
    XenBusGrantEndAccess,           // XenBusIo.GrantEndAccess
 | 
						|
    XenBusEventChannelAllocate,     // XenBusIo.EventChannelAllocate
 | 
						|
    XenBusEventChannelNotify,       // XenBusIo.EventChannelNotify
 | 
						|
    XenBusEventChannelClose,        // XenBusIo.EventChannelClose
 | 
						|
    XenBusRegisterWatch,            // XenBusIo.RegisterWatch
 | 
						|
    XenBusRegisterWatchBackend,     // XenBusIo.RegisterWatchBackend
 | 
						|
    XenBusUnregisterWatch,          // XenBusIo.UnregisterWatch
 | 
						|
    XenBusWaitForWatch,             // XenBusIo.WaitForWatch
 | 
						|
 | 
						|
    NULL,                           // XenBusIo.Type
 | 
						|
    0,                              // XenBusIo.DeviceId
 | 
						|
    NULL,                           // XenBusIo.Node
 | 
						|
    NULL,                           // XenBusIo.Backend
 | 
						|
  },
 | 
						|
 | 
						|
  NULL,                             // Dev
 | 
						|
  NULL                              // DevicePath
 | 
						|
};
 |