/** @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
};
