/** @file
  Low-level kernel interface to the XenStore.

  The XenStore interface is a simple storage system that is a means of
  communicating state and configuration data between the Xen Domain 0
  and the various guest domains.  All configuration data other than
  a small amount of essential information required during the early
  boot process of launching a Xen aware guest, is managed using the
  XenStore.

  The XenStore is ASCII string based, and has a structure and semantics
  similar to a filesystem.  There are files and directories, the directories
  able to contain files or other directories.  The depth of the hierachy
  is only limited by the XenStore's maximum path length.

  The communication channel between the XenStore service and other
  domains is via two, guest specific, ring buffers in a shared memory
  area.  One ring buffer is used for communicating in each direction.
  The grant table references for this shared memory are given to the
  guest either via the xen_start_info structure for a fully para-
  virtualized guest, or via HVM hypercalls for a hardware virtualized
  guest.

  The XenStore communication relies on an event channel and thus
  interrupts.  But under OVMF this XenStore client will pull the
  state of the event channel.

  Several Xen services depend on the XenStore, most notably the
  XenBus used to discover and manage Xen devices.

  Copyright (C) 2005 Rusty Russell, IBM Corporation
  Copyright (C) 2009,2010 Spectra Logic Corporation
  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 "XenStore.h"

#include <Library/PrintLib.h>

#include <IndustryStandard/Xen/hvm/params.h>

#include "EventChannel.h"
#include <Library/XenHypercallLib.h>

//
// Private Data Structures
//

typedef struct {
  CONST VOID  *Data;
  UINT32      Len;
} WRITE_REQUEST;

/* Register callback to watch subtree (node) in the XenStore. */
#define XENSTORE_WATCH_SIGNATURE SIGNATURE_32 ('X','S','w','a')
struct _XENSTORE_WATCH
{
  UINT32      Signature;
  LIST_ENTRY  Link;

  /* Path being watched. */
  CHAR8       *Node;
};

#define XENSTORE_WATCH_FROM_LINK(l) \
  CR (l, XENSTORE_WATCH, Link, XENSTORE_WATCH_SIGNATURE)


/**
 * Structure capturing messages received from the XenStore service.
 */
#define XENSTORE_MESSAGE_SIGNATURE SIGNATURE_32 ('X', 'S', 's', 'm')
typedef struct {
  UINT32 Signature;
  LIST_ENTRY Link;

  struct xsd_sockmsg Header;

  union {
    /* Queued replies. */
    struct {
      CHAR8 *Body;
    } Reply;

    /* Queued watch events. */
    struct {
      XENSTORE_WATCH *Handle;
      CONST CHAR8 **Vector;
      UINT32 VectorSize;
    } Watch;
  } u;
} XENSTORE_MESSAGE;
#define XENSTORE_MESSAGE_FROM_LINK(r) \
  CR (r, XENSTORE_MESSAGE, Link, XENSTORE_MESSAGE_SIGNATURE)

/**
 * Container for all XenStore related state.
 */
typedef struct {
  /**
   * Pointer to shared memory communication structures allowing us
   * to communicate with the XenStore service.
   */
  struct xenstore_domain_interface *XenStore;

  XENBUS_DEVICE *Dev;

  /**
   * A list of replies to our requests.
   *
   * The reply list is filled by xs_rcv_thread().  It
   * is consumed by the context that issued the request
   * to which a reply is made.  The requester blocks in
   * XenStoreReadReply ().
   *
   * /note Only one requesting context can be active at a time.
   */
  LIST_ENTRY ReplyList;

  /** Lock protecting the reply list. */
  EFI_LOCK ReplyLock;

  /**
   * List of registered watches.
   */
  LIST_ENTRY RegisteredWatches;

  /** Lock protecting the registered watches list. */
  EFI_LOCK RegisteredWatchesLock;

  /**
   * List of pending watch callback events.
   */
  LIST_ENTRY WatchEvents;

  /** Lock protecting the watch calback list. */
  EFI_LOCK WatchEventsLock;

  /**
   * The event channel for communicating with the
   * XenStore service.
   */
  evtchn_port_t EventChannel;

  /** Handle for XenStore events. */
  EFI_EVENT EventChannelEvent;
} XENSTORE_PRIVATE;

//
// Global Data
//
static XENSTORE_PRIVATE xs;


//
// Private Utility Functions
//

/**
  Count and optionally record pointers to a number of NUL terminated
  strings in a buffer.

  @param Strings  A pointer to a contiguous buffer of NUL terminated strings.
  @param Len      The length of the buffer pointed to by strings.
  @param Dst      An array to store pointers to each string found in strings.

  @return  A count of the number of strings found.
**/
STATIC
UINT32
ExtractStrings (
  IN  CONST CHAR8 *Strings,
  IN  UINTN       Len,
  OUT CONST CHAR8 **Dst OPTIONAL
  )
{
  UINT32 Num = 0;
  CONST CHAR8 *Ptr;

  for (Ptr = Strings; Ptr < Strings + Len; Ptr += AsciiStrSize (Ptr)) {
    if (Dst != NULL) {
      *Dst++ = Ptr;
    }
    Num++;
  }

  return Num;
}

/**
  Convert a contiguous buffer containing a series of NUL terminated
  strings into an array of pointers to strings.

  The returned pointer references the array of string pointers which
  is followed by the storage for the string data.  It is the client's
  responsibility to free this storage.

  The storage addressed by Strings is free'd prior to Split returning.

  @param Strings  A pointer to a contiguous buffer of NUL terminated strings.
  @param Len      The length of the buffer pointed to by strings.
  @param NumPtr   The number of strings found and returned in the strings
                  array.

  @return  An array of pointers to the strings found in the input buffer.
**/
STATIC
CONST CHAR8 **
Split (
  IN  CHAR8   *Strings,
  IN  UINTN   Len,
  OUT UINT32  *NumPtr
  )
{
  CONST CHAR8 **Dst;

  ASSERT(NumPtr != NULL);
  ASSERT(Strings != NULL);

  /* Protect against unterminated buffers. */
  if (Len > 0) {
    Strings[Len - 1] = '\0';
  }

  /* Count the Strings. */
  *NumPtr = ExtractStrings (Strings, Len, NULL);

  /* Transfer to one big alloc for easy freeing by the caller. */
  Dst = AllocatePool (*NumPtr * sizeof (CHAR8 *) + Len);
  CopyMem ((VOID*)&Dst[*NumPtr], Strings, Len);
  FreePool (Strings);

  /* Extract pointers to newly allocated array. */
  Strings = (CHAR8 *) &Dst[*NumPtr];
  ExtractStrings (Strings, Len, Dst);

  return (Dst);
}

/**
  Convert from watch token (unique identifier) to the associated
  internal tracking structure for this watch.

  @param Tocken  The unique identifier for the watch to find.

  @return  A pointer to the found watch structure or NULL.
**/
STATIC
XENSTORE_WATCH *
XenStoreFindWatch (
  IN CONST CHAR8 *Token
  )
{
  XENSTORE_WATCH *Watch, *WantedWatch;
  LIST_ENTRY *Entry;

  WantedWatch = (VOID *) AsciiStrHexToUintn (Token);

  if (IsListEmpty (&xs.RegisteredWatches)) {
    return NULL;
  }
  for (Entry = GetFirstNode (&xs.RegisteredWatches);
       !IsNull (&xs.RegisteredWatches, Entry);
       Entry = GetNextNode (&xs.RegisteredWatches, Entry)) {
    Watch = XENSTORE_WATCH_FROM_LINK (Entry);
    if (Watch == WantedWatch)
      return Watch;
  }

  return NULL;
}

//
// Public Utility Functions
// API comments for these methods can be found in XenStore.h
//

CHAR8 *
XenStoreJoin (
  IN CONST CHAR8 *DirectoryPath,
  IN CONST CHAR8 *Node
  )
{
  CHAR8 *Buf;

  /* +1 for '/' and +1 for '\0' */
  Buf = AllocateZeroPool (
          AsciiStrLen (DirectoryPath) + AsciiStrLen (Node) + 2);
  AsciiStrCat (Buf, DirectoryPath);
  if (Node[0] != '\0') {
    AsciiStrCat (Buf, "/");
    AsciiStrCat (Buf, Node);
  }

  return Buf;
}

//
// Low Level Communication Management
//

/**
  Verify that the indexes for a ring are valid.

  The difference between the producer and consumer cannot
  exceed the size of the ring.

  @param Cons  The consumer index for the ring to test.
  @param Prod  The producer index for the ring to test.

  @retval TRUE   If indexes are in range.
  @retval FALSE  If the indexes are out of range.
**/
STATIC
BOOLEAN
XenStoreCheckIndexes (
  XENSTORE_RING_IDX Cons,
  XENSTORE_RING_IDX Prod
  )
{
  return ((Prod - Cons) <= XENSTORE_RING_SIZE);
}

/**
  Return a pointer to, and the length of, the contiguous
  free region available for output in a ring buffer.

  @param Cons    The consumer index for the ring.
  @param Prod    The producer index for the ring.
  @param Buffer  The base address of the ring's storage.
  @param LenPtr  The amount of contiguous storage available.

  @return  A pointer to the start location of the free region.
**/
STATIC
VOID *
XenStoreGetOutputChunk (
  IN  XENSTORE_RING_IDX Cons,
  IN  XENSTORE_RING_IDX Prod,
  IN  CHAR8             *Buffer,
  OUT UINT32            *LenPtr
  )
{
  UINT32 Len;
  Len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX (Prod);
  if ((XENSTORE_RING_SIZE - (Prod - Cons)) < Len) {
    Len = XENSTORE_RING_SIZE - (Prod - Cons);
  }
  *LenPtr = Len;
  return (Buffer + MASK_XENSTORE_IDX (Prod));
}

/**
  Return a pointer to, and the length of, the contiguous
  data available to read from a ring buffer.

  @param Cons    The consumer index for the ring.
  @param Prod    The producer index for the ring.
  @param Buffer  The base address of the ring's storage.
  @param LenPtr  The amount of contiguous data available to read.

  @return  A pointer to the start location of the available data.
**/
STATIC
CONST VOID *
XenStoreGetInputChunk (
  IN  XENSTORE_RING_IDX Cons,
  IN  XENSTORE_RING_IDX Prod,
  IN  CONST CHAR8       *Buffer,
  OUT UINT32            *LenPtr
  )
{
  UINT32 Len;

  Len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX (Cons);
  if ((Prod - Cons) < Len) {
    Len = Prod - Cons;
  }
  *LenPtr = Len;
  return (Buffer + MASK_XENSTORE_IDX (Cons));
}

/**
  Wait for an event or timeout.

  @param Event    Event to wait for.
  @param Timeout  A timeout value in 100ns units.

  @retval EFI_SUCCESS   Event have been triggered or the current TPL is not
                        TPL_APPLICATION.
  @retval EFI_TIMEOUT   Timeout have expired.
**/
STATIC
EFI_STATUS
XenStoreWaitForEvent (
  IN EFI_EVENT Event,
  IN UINT64    Timeout
  )
{
  UINTN Index;
  EFI_STATUS Status;
  EFI_EVENT TimerEvent;
  EFI_EVENT WaitList[2];

  gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
  gBS->SetTimer (TimerEvent, TimerRelative, Timeout);

  WaitList[0] = xs.EventChannelEvent;
  WaitList[1] = TimerEvent;
  Status = gBS->WaitForEvent (2, WaitList, &Index);
  ASSERT (Status != EFI_INVALID_PARAMETER);
  gBS->CloseEvent (TimerEvent);
  if (Status == EFI_UNSUPPORTED) {
    return EFI_SUCCESS;
  }
  if (Index == 1) {
    return EFI_TIMEOUT;
  } else {
    return EFI_SUCCESS;
  }
}

/**
  Transmit data to the XenStore service.

  The buffer pointed to by DataPtr is at least Len bytes in length.

  @param DataPtr  A pointer to the contiguous data to send.
  @param Len      The amount of data to send.

  @return  On success 0, otherwise an errno value indicating the
           cause of failure.
**/
STATIC
XENSTORE_STATUS
XenStoreWriteStore (
  IN CONST VOID *DataPtr,
  IN UINT32     Len
  )
{
  XENSTORE_RING_IDX Cons, Prod;
  CONST CHAR8 *Data = (CONST CHAR8 *)DataPtr;

  while (Len != 0) {
    void *Dest;
    UINT32 Available;

    Cons = xs.XenStore->req_cons;
    Prod = xs.XenStore->req_prod;
    if ((Prod - Cons) == XENSTORE_RING_SIZE) {
      /*
       * Output ring is full. Wait for a ring event.
       *
       * Note that the events from both queues are combined, so being woken
       * does not guarantee that data exist in the read ring.
       */
      EFI_STATUS Status;

      Status = XenStoreWaitForEvent (xs.EventChannelEvent,
                                     EFI_TIMER_PERIOD_SECONDS (1));
      if (Status == EFI_TIMEOUT) {
        DEBUG ((EFI_D_WARN, "XenStore Write, waiting for a ring event.\n"));
      }
      continue;
    }

    /* Verify queue sanity. */
    if (!XenStoreCheckIndexes (Cons, Prod)) {
      xs.XenStore->req_cons = xs.XenStore->req_prod = 0;
      return XENSTORE_STATUS_EIO;
    }

    Dest = XenStoreGetOutputChunk (Cons, Prod, xs.XenStore->req, &Available);
    if (Available > Len) {
      Available = Len;
    }

    CopyMem (Dest, Data, Available);
    Data += Available;
    Len -= Available;

    /*
     * The store to the producer index, which indicates
     * to the other side that new data has arrived, must
     * be visible only after our copy of the data into the
     * ring has completed.
     */
    MemoryFence ();
    xs.XenStore->req_prod += Available;

    /*
     * The other side will see the change to req_prod at the time of the
     * interrupt.
     */
    MemoryFence ();
    XenEventChannelNotify (xs.Dev, xs.EventChannel);
  }

  return XENSTORE_STATUS_SUCCESS;
}

/**
  Receive data from the XenStore service.

  The buffer pointed to by DataPtr is at least Len bytes in length.

  @param DataPtr  A pointer to the contiguous buffer to receive the data.
  @param Len      The amount of data to receive.

  @return  On success 0, otherwise an errno value indicating the
           cause of failure.
**/
STATIC
XENSTORE_STATUS
XenStoreReadStore (
  OUT VOID *DataPtr,
  IN  UINT32 Len
  )
{
  XENSTORE_RING_IDX Cons, Prod;
  CHAR8 *Data = (CHAR8 *) DataPtr;

  while (Len != 0) {
    UINT32 Available;
    CONST CHAR8 *Src;

    Cons = xs.XenStore->rsp_cons;
    Prod = xs.XenStore->rsp_prod;
    if (Cons == Prod) {
      /*
       * Nothing to read. Wait for a ring event.
       *
       * Note that the events from both queues are combined, so being woken
       * does not guarantee that data exist in the read ring.
       */
      EFI_STATUS Status;

      Status = XenStoreWaitForEvent (xs.EventChannelEvent,
                                     EFI_TIMER_PERIOD_SECONDS (1));
      if (Status == EFI_TIMEOUT) {
        DEBUG ((EFI_D_WARN, "XenStore Read, waiting for a ring event.\n"));
      }
      continue;
    }

    /* Verify queue sanity. */
    if (!XenStoreCheckIndexes (Cons, Prod)) {
      xs.XenStore->rsp_cons = xs.XenStore->rsp_prod = 0;
      return XENSTORE_STATUS_EIO;
    }

    Src = XenStoreGetInputChunk (Cons, Prod, xs.XenStore->rsp, &Available);
    if (Available > Len) {
      Available = Len;
    }

    /*
     * Insure the data we read is related to the indexes
     * we read above.
     */
    MemoryFence ();

    CopyMem (Data, Src, Available);
    Data += Available;
    Len -= Available;

    /*
     * Insure that the producer of this ring does not see
     * the ring space as free until after we have copied it
     * out.
     */
    MemoryFence ();
    xs.XenStore->rsp_cons += Available;

    /*
     * The producer will see the updated consumer index when the event is
     * delivered.
     */
    MemoryFence ();
    XenEventChannelNotify (xs.Dev, xs.EventChannel);
  }

  return XENSTORE_STATUS_SUCCESS;
}

//
// Received Message Processing
//

/**
  Block reading the next message from the XenStore service and
  process the result.

  @return  XENSTORE_STATUS_SUCCESS on success.  Otherwise an errno value
           indicating the type of failure encountered.
**/
STATIC
XENSTORE_STATUS
XenStoreProcessMessage (
  VOID
  )
{
  XENSTORE_MESSAGE *Message;
  CHAR8 *Body;
  XENSTORE_STATUS Status;

  Message = AllocateZeroPool (sizeof (XENSTORE_MESSAGE));
  Message->Signature = XENSTORE_MESSAGE_SIGNATURE;
  Status = XenStoreReadStore (&Message->Header, sizeof (Message->Header));
  if (Status != XENSTORE_STATUS_SUCCESS) {
    FreePool (Message);
    DEBUG ((EFI_D_ERROR, "XenStore: Error read store (%d)\n", Status));
    return Status;
  }

  Body = AllocatePool (Message->Header.len + 1);
  Status = XenStoreReadStore (Body, Message->Header.len);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    FreePool (Body);
    FreePool (Message);
    DEBUG ((EFI_D_ERROR, "XenStore: Error read store (%d)\n", Status));
    return Status;
  }
  Body[Message->Header.len] = '\0';

  if (Message->Header.type == XS_WATCH_EVENT) {
    Message->u.Watch.Vector = Split(Body, Message->Header.len,
                                    &Message->u.Watch.VectorSize);

    EfiAcquireLock (&xs.RegisteredWatchesLock);
    Message->u.Watch.Handle =
      XenStoreFindWatch (Message->u.Watch.Vector[XS_WATCH_TOKEN]);
    DEBUG ((EFI_D_INFO, "XenStore: Watch event %a\n",
            Message->u.Watch.Vector[XS_WATCH_TOKEN]));
    if (Message->u.Watch.Handle != NULL) {
      EfiAcquireLock (&xs.WatchEventsLock);
      InsertHeadList (&xs.WatchEvents, &Message->Link);
      EfiReleaseLock (&xs.WatchEventsLock);
    } else {
      DEBUG ((EFI_D_WARN, "XenStore: Watch handle %a not found\n",
              Message->u.Watch.Vector[XS_WATCH_TOKEN]));
      FreePool((VOID*)Message->u.Watch.Vector);
      FreePool(Message);
    }
    EfiReleaseLock (&xs.RegisteredWatchesLock);
  } else {
    Message->u.Reply.Body = Body;
    EfiAcquireLock (&xs.ReplyLock);
    InsertTailList (&xs.ReplyList, &Message->Link);
    EfiReleaseLock (&xs.ReplyLock);
  }

  return XENSTORE_STATUS_SUCCESS;
}

//
// XenStore Message Request/Reply Processing
//

/**
  Convert a XenStore error string into an errno number.

  Unknown error strings are converted to EINVAL.

  @param errorstring  The error string to convert.

  @return  The errno best matching the input string.

**/
typedef struct {
  XENSTORE_STATUS Status;
  CONST CHAR8 *ErrorStr;
} XenStoreErrors;

static XenStoreErrors gXenStoreErrors[] = {
  { XENSTORE_STATUS_EINVAL, "EINVAL" },
  { XENSTORE_STATUS_EACCES, "EACCES" },
  { XENSTORE_STATUS_EEXIST, "EEXIST" },
  { XENSTORE_STATUS_EISDIR, "EISDIR" },
  { XENSTORE_STATUS_ENOENT, "ENOENT" },
  { XENSTORE_STATUS_ENOMEM, "ENOMEM" },
  { XENSTORE_STATUS_ENOSPC, "ENOSPC" },
  { XENSTORE_STATUS_EIO, "EIO" },
  { XENSTORE_STATUS_ENOTEMPTY, "ENOTEMPTY" },
  { XENSTORE_STATUS_ENOSYS, "ENOSYS" },
  { XENSTORE_STATUS_EROFS, "EROFS" },
  { XENSTORE_STATUS_EBUSY, "EBUSY" },
  { XENSTORE_STATUS_EAGAIN, "EAGAIN" },
  { XENSTORE_STATUS_EISCONN, "EISCONN" },
  { XENSTORE_STATUS_E2BIG, "E2BIG" }
};
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

STATIC
XENSTORE_STATUS
XenStoreGetError (
  CONST CHAR8 *ErrorStr
  )
{
  UINT32 Index;

  for (Index = 0; Index < ARRAY_SIZE(gXenStoreErrors); Index++) {
    if (!AsciiStrCmp (ErrorStr, gXenStoreErrors[Index].ErrorStr)) {
      return gXenStoreErrors[Index].Status;
    }
  }
  DEBUG ((EFI_D_WARN, "XenStore gave unknown error %a\n", ErrorStr));
  return XENSTORE_STATUS_EINVAL;
}

/**
  Block waiting for a reply to a message request.

  @param TypePtr The returned type of the reply.
  @param LenPtr  The returned body length of the reply.
  @param Result  The returned body of the reply.
**/
STATIC
XENSTORE_STATUS
XenStoreReadReply (
  OUT enum xsd_sockmsg_type *TypePtr,
  OUT UINT32 *LenPtr OPTIONAL,
  OUT VOID **Result
  )
{
  XENSTORE_MESSAGE *Message;
  LIST_ENTRY *Entry;
  CHAR8 *Body;

  while (IsListEmpty (&xs.ReplyList)) {
    XENSTORE_STATUS Status;
    Status = XenStoreProcessMessage ();
    if (Status != XENSTORE_STATUS_SUCCESS && Status != XENSTORE_STATUS_EAGAIN) {
      DEBUG ((EFI_D_ERROR, "XenStore, error while reading the ring (%d).",
              Status));
      return Status;
    }
  }
  EfiAcquireLock (&xs.ReplyLock);
  Entry = GetFirstNode (&xs.ReplyList);
  Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
  RemoveEntryList (Entry);
  EfiReleaseLock (&xs.ReplyLock);

  *TypePtr = Message->Header.type;
  if (LenPtr != NULL) {
    *LenPtr = Message->Header.len;
  }
  Body = Message->u.Reply.Body;

  FreePool (Message);
  *Result = Body;
  return XENSTORE_STATUS_SUCCESS;
}

/**
  Send a message with an optionally muti-part body to the XenStore service.

  @param Transaction    The transaction to use for this request.
  @param RequestType    The type of message to send.
  @param WriteRequest   Pointers to the body sections of the request.
  @param NumRequests    The number of body sections in the request.
  @param LenPtr         The returned length of the reply.
  @param ResultPtr      The returned body of the reply.

  @return  XENSTORE_STATUS_SUCCESS on success.  Otherwise an errno indicating
           the cause of failure.
**/
STATIC
XENSTORE_STATUS
XenStoreTalkv (
  IN  CONST XENSTORE_TRANSACTION *Transaction,
  IN  enum xsd_sockmsg_type   RequestType,
  IN  CONST WRITE_REQUEST     *WriteRequest,
  IN  UINT32                  NumRequests,
  OUT UINT32                  *LenPtr OPTIONAL,
  OUT VOID                    **ResultPtr OPTIONAL
  )
{
  struct xsd_sockmsg Message;
  void *Return = NULL;
  UINT32 Index;
  XENSTORE_STATUS Status;

  if (Transaction == XST_NIL) {
    Message.tx_id = 0;
  } else {
    Message.tx_id = Transaction->Id;
  }
  Message.req_id = 0;
  Message.type = RequestType;
  Message.len = 0;
  for (Index = 0; Index < NumRequests; Index++) {
    Message.len += WriteRequest[Index].Len;
  }

  Status = XenStoreWriteStore (&Message, sizeof (Message));
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR, "XenStoreTalkv failed %d\n", Status));
    goto Error;
  }

  for (Index = 0; Index < NumRequests; Index++) {
    Status = XenStoreWriteStore (WriteRequest[Index].Data, WriteRequest[Index].Len);
    if (Status != XENSTORE_STATUS_SUCCESS) {
      DEBUG ((EFI_D_ERROR, "XenStoreTalkv failed %d\n", Status));
      goto Error;
    }
  }

  Status = XenStoreReadReply ((enum xsd_sockmsg_type *)&Message.type, LenPtr, &Return);

Error:
  if (Status != XENSTORE_STATUS_SUCCESS) {
    return Status;
  }

  if (Message.type == XS_ERROR) {
    Status = XenStoreGetError (Return);
    FreePool (Return);
    return Status;
  }

  /* Reply is either error or an echo of our request message type. */
  ASSERT ((enum xsd_sockmsg_type)Message.type == RequestType);

  if (ResultPtr) {
    *ResultPtr = Return;
  } else {
    FreePool (Return);
  }

  return XENSTORE_STATUS_SUCCESS;
}

/**
  Wrapper for XenStoreTalkv allowing easy transmission of a message with
  a single, contiguous, message body.

  The returned result is provided in malloced storage and thus must be free'd
  by the caller.

  @param Transaction    The transaction to use for this request.
  @param RequestType    The type of message to send.
  @param Body           The body of the request.
  @param LenPtr         The returned length of the reply.
  @param Result         The returned body of the reply.

  @return  0 on success.  Otherwise an errno indicating
           the cause of failure.
**/
STATIC
XENSTORE_STATUS
XenStoreSingle (
  IN  CONST XENSTORE_TRANSACTION *Transaction,
  IN  enum xsd_sockmsg_type   RequestType,
  IN  CONST CHAR8             *Body,
  OUT UINT32                  *LenPtr OPTIONAL,
  OUT VOID                    **Result OPTIONAL
  )
{
  WRITE_REQUEST WriteRequest;

  WriteRequest.Data = (VOID *) Body;
  WriteRequest.Len = (UINT32)AsciiStrSize (Body);

  return XenStoreTalkv (Transaction, RequestType, &WriteRequest, 1,
                        LenPtr, Result);
}

//
// XenStore Watch Support
//

/**
  Transmit a watch request to the XenStore service.

  @param Path    The path in the XenStore to watch.
  @param Tocken  A unique identifier for this watch.

  @return  XENSTORE_STATUS_SUCCESS on success.  Otherwise an errno indicating the
           cause of failure.
**/
STATIC
XENSTORE_STATUS
XenStoreWatch (
  CONST CHAR8 *Path,
  CONST CHAR8 *Token
  )
{
  WRITE_REQUEST WriteRequest[2];

  WriteRequest[0].Data = (VOID *) Path;
  WriteRequest[0].Len = (UINT32)AsciiStrSize (Path);
  WriteRequest[1].Data = (VOID *) Token;
  WriteRequest[1].Len = (UINT32)AsciiStrSize (Token);

  return XenStoreTalkv (XST_NIL, XS_WATCH, WriteRequest, 2, NULL, NULL);
}

/**
  Transmit an uwatch request to the XenStore service.

  @param Path    The path in the XenStore to watch.
  @param Tocken  A unique identifier for this watch.

  @return  XENSTORE_STATUS_SUCCESS on success.  Otherwise an errno indicating
           the cause of failure.
**/
STATIC
XENSTORE_STATUS
XenStoreUnwatch (
  CONST CHAR8 *Path,
  CONST CHAR8 *Token
  )
{
  WRITE_REQUEST WriteRequest[2];

  WriteRequest[0].Data = (VOID *) Path;
  WriteRequest[0].Len = (UINT32)AsciiStrSize (Path);
  WriteRequest[1].Data = (VOID *) Token;
  WriteRequest[1].Len = (UINT32)AsciiStrSize (Token);

  return XenStoreTalkv (XST_NIL, XS_UNWATCH, WriteRequest, 2, NULL, NULL);
}

STATIC
XENSTORE_STATUS
XenStoreWaitWatch (
  VOID *Token
  )
{
  XENSTORE_MESSAGE *Message;
  LIST_ENTRY *Entry = NULL;
  LIST_ENTRY *Last = NULL;
  XENSTORE_STATUS Status;

  while (TRUE) {
    EfiAcquireLock (&xs.WatchEventsLock);
    if (IsListEmpty (&xs.WatchEvents) ||
        Last == GetFirstNode (&xs.WatchEvents)) {
      EfiReleaseLock (&xs.WatchEventsLock);
      Status = XenStoreProcessMessage ();
      if (Status != XENSTORE_STATUS_SUCCESS && Status != XENSTORE_STATUS_EAGAIN) {
        return Status;
      }
      continue;
    }

    for (Entry = GetFirstNode (&xs.WatchEvents);
         Entry != Last && !IsNull (&xs.WatchEvents, Entry);
         Entry = GetNextNode (&xs.WatchEvents, Entry)) {
      Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
      if (Message->u.Watch.Handle == Token) {
        RemoveEntryList (Entry);
        EfiReleaseLock (&xs.WatchEventsLock);
        FreePool((VOID*)Message->u.Watch.Vector);
        FreePool(Message);
        return XENSTORE_STATUS_SUCCESS;
      }
    }
    Last = GetFirstNode (&xs.WatchEvents);
    EfiReleaseLock (&xs.WatchEventsLock);
  }
}

VOID
EFIAPI
NotifyEventChannelCheckForEvent (
  IN EFI_EVENT Event,
  IN VOID *Context
  )
{
  XENSTORE_PRIVATE *xsp;
  xsp = (XENSTORE_PRIVATE *)Context;
  if (TestAndClearBit (xsp->EventChannel, xsp->Dev->SharedInfo->evtchn_pending)) {
    gBS->SignalEvent (Event);
  }
}

/**
  Setup communication channels with the XenStore service.

  @retval EFI_SUCCESS if everything went well.
**/
STATIC
EFI_STATUS
XenStoreInitComms (
  XENSTORE_PRIVATE *xsp
  )
{
  EFI_STATUS Status;
  EFI_EVENT TimerEvent;
  struct xenstore_domain_interface *XenStore = xsp->XenStore;

  Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
  Status = gBS->SetTimer (TimerEvent, TimerRelative,
                          EFI_TIMER_PERIOD_SECONDS (5));
  while (XenStore->rsp_prod != XenStore->rsp_cons) {
    Status = gBS->CheckEvent (TimerEvent);
    if (!EFI_ERROR (Status)) {
      DEBUG ((EFI_D_WARN, "XENSTORE response ring is not quiescent "
              "(%08x:%08x): fixing up\n",
              XenStore->rsp_cons, XenStore->rsp_prod));
      XenStore->rsp_cons = XenStore->rsp_prod;
    }
  }
  gBS->CloseEvent (TimerEvent);

  Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_NOTIFY,
                             NotifyEventChannelCheckForEvent, xsp,
                             &xsp->EventChannelEvent);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
  Initialize XenStore.

  @param Dev  A XENBUS_DEVICE instance.

  @retval EFI_SUCCESS if everything went well.
**/
EFI_STATUS
XenStoreInit (
  XENBUS_DEVICE *Dev
  )
{
  EFI_STATUS Status;
  /**
   * The HVM guest pseudo-physical frame number.  This is Xen's mapping
   * of the true machine frame number into our "physical address space".
   */
  UINTN XenStoreGpfn;

  xs.Dev = Dev;

  xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam (HVM_PARAM_STORE_EVTCHN);
  XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (HVM_PARAM_STORE_PFN);
  xs.XenStore = (VOID *) (XenStoreGpfn << EFI_PAGE_SHIFT);
  DEBUG ((EFI_D_INFO, "XenBusInit: XenBus rings @%p, event channel %x\n",
          xs.XenStore, xs.EventChannel));

  InitializeListHead (&xs.ReplyList);
  InitializeListHead (&xs.WatchEvents);
  InitializeListHead (&xs.RegisteredWatches);

  EfiInitializeLock (&xs.ReplyLock, TPL_NOTIFY);
  EfiInitializeLock (&xs.RegisteredWatchesLock, TPL_NOTIFY);
  EfiInitializeLock (&xs.WatchEventsLock, TPL_NOTIFY);

  /* Initialize the shared memory rings to talk to xenstored */
  Status = XenStoreInitComms (&xs);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return Status;
}

VOID
XenStoreDeinit (
  IN XENBUS_DEVICE *Dev
  )
{
  //
  // Emptying the list RegisteredWatches, but this list should already be
  // empty. Every driver that is using Watches should unregister them when
  // it is stopped.
  //
  if (!IsListEmpty (&xs.RegisteredWatches)) {
    XENSTORE_WATCH *Watch;
    LIST_ENTRY *Entry;
    DEBUG ((EFI_D_WARN, "XenStore: RegisteredWatches is not empty, cleaning up..."));
    Entry = GetFirstNode (&xs.RegisteredWatches);
    while (!IsNull (&xs.RegisteredWatches, Entry)) {
      Watch = XENSTORE_WATCH_FROM_LINK (Entry);
      Entry = GetNextNode (&xs.RegisteredWatches, Entry);

      XenStoreUnregisterWatch (Watch);
    }
  }

  //
  // Emptying the list WatchEvents, but this list should already be empty after
  // having cleanup the list RegisteredWatches.
  //
  if (!IsListEmpty (&xs.WatchEvents)) {
    LIST_ENTRY *Entry;
    DEBUG ((EFI_D_WARN, "XenStore: WatchEvents is not empty, cleaning up..."));
    Entry = GetFirstNode (&xs.WatchEvents);
    while (!IsNull (&xs.WatchEvents, Entry)) {
      XENSTORE_MESSAGE *Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
      Entry = GetNextNode (&xs.WatchEvents, Entry);
      RemoveEntryList (&Message->Link);
      FreePool ((VOID*)Message->u.Watch.Vector);
      FreePool (Message);
    }
  }

  if (!IsListEmpty (&xs.ReplyList)) {
    XENSTORE_MESSAGE *Message;
    LIST_ENTRY *Entry;
    Entry = GetFirstNode (&xs.ReplyList);
    while (!IsNull (&xs.ReplyList, Entry)) {
      Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
      Entry = GetNextNode (&xs.ReplyList, Entry);
      RemoveEntryList (&Message->Link);
      FreePool (Message->u.Reply.Body);
      FreePool (Message);
    }
  }

  gBS->CloseEvent (xs.EventChannelEvent);

  if (xs.XenStore->server_features & XENSTORE_SERVER_FEATURE_RECONNECTION) {
    xs.XenStore->connection = XENSTORE_RECONNECT;
    XenEventChannelNotify (xs.Dev, xs.EventChannel);
    while (*(volatile UINT32*)&xs.XenStore->connection == XENSTORE_RECONNECT) {
      XenStoreWaitForEvent (xs.EventChannelEvent, EFI_TIMER_PERIOD_MILLISECONDS (100));
    }
  } else {
    /* If the backend reads the state while we're erasing it then the
     * ring state will become corrupted, preventing guest frontends from
     * connecting. This is rare. To help diagnose the failure, we fill
     * the ring with XS_INVALID packets. */
    SetMem (xs.XenStore->req, XENSTORE_RING_SIZE, 0xff);
    SetMem (xs.XenStore->rsp, XENSTORE_RING_SIZE, 0xff);
    xs.XenStore->req_cons = xs.XenStore->req_prod = 0;
    xs.XenStore->rsp_cons = xs.XenStore->rsp_prod = 0;
  }
  xs.XenStore = NULL;
}

//
// Public API
// API comments for these methods can be found in XenStore.h
//

XENSTORE_STATUS
XenStoreListDirectory (
  IN  CONST XENSTORE_TRANSACTION *Transaction,
  IN  CONST CHAR8           *DirectoryPath,
  IN  CONST CHAR8           *Node,
  OUT UINT32                *DirectoryCountPtr,
  OUT CONST CHAR8           ***DirectoryListPtr
  )
{
  CHAR8 *Path;
  CHAR8 *TempStr;
  UINT32 Len = 0;
  XENSTORE_STATUS Status;

  Path = XenStoreJoin (DirectoryPath, Node);
  Status = XenStoreSingle (Transaction, XS_DIRECTORY, Path, &Len,
                           (VOID **) &TempStr);
  FreePool (Path);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    return Status;
  }

  *DirectoryListPtr = Split (TempStr, Len, DirectoryCountPtr);

  return XENSTORE_STATUS_SUCCESS;
}

BOOLEAN
XenStorePathExists (
  IN CONST XENSTORE_TRANSACTION *Transaction,
  IN CONST CHAR8           *Directory,
  IN CONST CHAR8           *Node
  )
{
  CONST CHAR8 **TempStr;
  XENSTORE_STATUS Status;
  UINT32 TempNum;

  Status = XenStoreListDirectory (Transaction, Directory, Node,
                                  &TempNum, &TempStr);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    return FALSE;
  }
  FreePool ((VOID*)TempStr);
  return TRUE;
}

XENSTORE_STATUS
XenStoreRead (
  IN  CONST XENSTORE_TRANSACTION *Transaction,
  IN  CONST CHAR8             *DirectoryPath,
  IN  CONST CHAR8             *Node,
  OUT UINT32                  *LenPtr OPTIONAL,
  OUT VOID                    **Result
  )
{
  CHAR8 *Path;
  VOID *Value;
  XENSTORE_STATUS Status;

  Path = XenStoreJoin (DirectoryPath, Node);
  Status = XenStoreSingle (Transaction, XS_READ, Path, LenPtr, &Value);
  FreePool (Path);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    return Status;
  }

  *Result = Value;
  return XENSTORE_STATUS_SUCCESS;
}

XENSTORE_STATUS
XenStoreWrite (
  IN CONST XENSTORE_TRANSACTION *Transaction,
  IN CONST CHAR8           *DirectoryPath,
  IN CONST CHAR8           *Node,
  IN CONST CHAR8           *Str
  )
{
  CHAR8 *Path;
  WRITE_REQUEST WriteRequest[2];
  XENSTORE_STATUS Status;

  Path = XenStoreJoin (DirectoryPath, Node);

  WriteRequest[0].Data = (VOID *) Path;
  WriteRequest[0].Len = (UINT32)AsciiStrSize (Path);
  WriteRequest[1].Data = (VOID *) Str;
  WriteRequest[1].Len = (UINT32)AsciiStrLen (Str);

  Status = XenStoreTalkv (Transaction, XS_WRITE, WriteRequest, 2, NULL, NULL);
  FreePool (Path);

  return Status;
}

XENSTORE_STATUS
XenStoreRemove (
  IN CONST XENSTORE_TRANSACTION *Transaction,
  IN CONST CHAR8            *DirectoryPath,
  IN CONST CHAR8            *Node
  )
{
  CHAR8 *Path;
  XENSTORE_STATUS Status;

  Path = XenStoreJoin (DirectoryPath, Node);
  Status = XenStoreSingle (Transaction, XS_RM, Path, NULL, NULL);
  FreePool (Path);

  return Status;
}

XENSTORE_STATUS
XenStoreTransactionStart (
  OUT XENSTORE_TRANSACTION  *Transaction
  )
{
  CHAR8 *IdStr;
  XENSTORE_STATUS Status;

  Status = XenStoreSingle (XST_NIL, XS_TRANSACTION_START, "", NULL,
                           (VOID **) &IdStr);
  if (Status == XENSTORE_STATUS_SUCCESS) {
    Transaction->Id = (UINT32)AsciiStrDecimalToUintn (IdStr);
    FreePool (IdStr);
  }

  return Status;
}

XENSTORE_STATUS
XenStoreTransactionEnd (
  IN CONST XENSTORE_TRANSACTION *Transaction,
  IN BOOLEAN                Abort
  )
{
  CHAR8 AbortStr[2];

  if (Abort) {
    AsciiStrCpy (AbortStr, "F");
  } else {
    AsciiStrCpy (AbortStr, "T");
  }

  return XenStoreSingle (Transaction, XS_TRANSACTION_END, AbortStr, NULL, NULL);
}

XENSTORE_STATUS
XenStoreVSPrint (
  IN CONST XENSTORE_TRANSACTION *Transaction,
  IN CONST CHAR8           *DirectoryPath,
  IN CONST CHAR8           *Node,
  IN CONST CHAR8           *FormatString,
  IN VA_LIST               Marker
  )
{
  CHAR8 *Buf;
  XENSTORE_STATUS Status;
  UINTN BufSize;

  BufSize = SPrintLengthAsciiFormat (FormatString, Marker) + 1;
  Buf = AllocateZeroPool (BufSize);
  AsciiVSPrint (Buf, BufSize, FormatString, Marker);
  Status = XenStoreWrite (Transaction, DirectoryPath, Node, Buf);
  FreePool (Buf);

  return Status;
}

XENSTORE_STATUS
EFIAPI
XenStoreSPrint (
  IN CONST XENSTORE_TRANSACTION *Transaction,
  IN CONST CHAR8            *DirectoryPath,
  IN CONST CHAR8            *Node,
  IN CONST CHAR8            *FormatString,
  ...
  )
{
  VA_LIST Marker;
  XENSTORE_STATUS Status;

  VA_START (Marker, FormatString);
  Status = XenStoreVSPrint (Transaction, DirectoryPath, Node, FormatString, Marker);
  VA_END (Marker);

  return Status;
}

XENSTORE_STATUS
XenStoreRegisterWatch (
  IN CONST CHAR8      *DirectoryPath,
  IN CONST CHAR8      *Node,
  OUT XENSTORE_WATCH  **WatchPtr
  )
{
  /* Pointer in ascii is the token. */
  CHAR8 Token[sizeof (XENSTORE_WATCH) * 2 + 1];
  XENSTORE_STATUS Status;
  XENSTORE_WATCH *Watch;

  Watch = AllocateZeroPool (sizeof (XENSTORE_WATCH));
  Watch->Signature = XENSTORE_WATCH_SIGNATURE;
  Watch->Node = XenStoreJoin (DirectoryPath, Node);

  EfiAcquireLock (&xs.RegisteredWatchesLock);
  InsertTailList (&xs.RegisteredWatches, &Watch->Link);
  EfiReleaseLock (&xs.RegisteredWatchesLock);

  AsciiSPrint (Token, sizeof (Token), "%p", (VOID*) Watch);
  Status = XenStoreWatch (Watch->Node, Token);

  /* Ignore errors due to multiple registration. */
  if (Status == XENSTORE_STATUS_EEXIST) {
    Status = XENSTORE_STATUS_SUCCESS;
  }

  if (Status == XENSTORE_STATUS_SUCCESS) {
    *WatchPtr = Watch;
  } else {
    EfiAcquireLock (&xs.RegisteredWatchesLock);
    RemoveEntryList (&Watch->Link);
    EfiReleaseLock (&xs.RegisteredWatchesLock);
    FreePool (Watch->Node);
    FreePool (Watch);
  }

  return Status;
}

VOID
XenStoreUnregisterWatch (
  IN XENSTORE_WATCH *Watch
  )
{
  CHAR8 Token[sizeof (Watch) * 2 + 1];
  LIST_ENTRY *Entry;

  ASSERT (Watch->Signature == XENSTORE_WATCH_SIGNATURE);

  AsciiSPrint (Token, sizeof (Token), "%p", (VOID *) Watch);
  if (XenStoreFindWatch (Token) == NULL) {
    return;
  }

  EfiAcquireLock (&xs.RegisteredWatchesLock);
  RemoveEntryList (&Watch->Link);
  EfiReleaseLock (&xs.RegisteredWatchesLock);

  XenStoreUnwatch (Watch->Node, Token);

  /* Cancel pending watch events. */
  EfiAcquireLock (&xs.WatchEventsLock);
  Entry = GetFirstNode (&xs.WatchEvents);
  while (!IsNull (&xs.WatchEvents, Entry)) {
    XENSTORE_MESSAGE *Message = XENSTORE_MESSAGE_FROM_LINK (Entry);
    Entry = GetNextNode (&xs.WatchEvents, Entry);
    if (Message->u.Watch.Handle == Watch) {
      RemoveEntryList (&Message->Link);
      FreePool ((VOID*)Message->u.Watch.Vector);
      FreePool (Message);
    }
  }
  EfiReleaseLock (&xs.WatchEventsLock);

  FreePool (Watch->Node);
  FreePool (Watch);
}


//
// XENBUS protocol
//

XENSTORE_STATUS
EFIAPI
XenBusWaitForWatch (
  IN XENBUS_PROTOCOL *This,
  IN VOID *Token
  )
{
  return XenStoreWaitWatch (Token);
}

XENSTORE_STATUS
EFIAPI
XenBusXenStoreRead (
  IN  XENBUS_PROTOCOL       *This,
  IN  CONST XENSTORE_TRANSACTION *Transaction,
  IN  CONST CHAR8           *Node,
  OUT VOID                  **Value
  )
{
  return XenStoreRead (Transaction, This->Node, Node, NULL, Value);
}

XENSTORE_STATUS
EFIAPI
XenBusXenStoreBackendRead (
  IN  XENBUS_PROTOCOL       *This,
  IN  CONST XENSTORE_TRANSACTION *Transaction,
  IN  CONST CHAR8           *Node,
  OUT VOID                  **Value
  )
{
  return XenStoreRead (Transaction, This->Backend, Node, NULL, Value);
}

XENSTORE_STATUS
EFIAPI
XenBusXenStoreRemove (
  IN XENBUS_PROTOCOL        *This,
  IN CONST XENSTORE_TRANSACTION *Transaction,
  IN const char             *Node
  )
{
  return XenStoreRemove (Transaction, This->Node, Node);
}

XENSTORE_STATUS
EFIAPI
XenBusXenStoreTransactionStart (
  IN  XENBUS_PROTOCOL       *This,
  OUT XENSTORE_TRANSACTION  *Transaction
  )
{
  return XenStoreTransactionStart (Transaction);
}

XENSTORE_STATUS
EFIAPI
XenBusXenStoreTransactionEnd (
  IN XENBUS_PROTOCOL        *This,
  IN CONST XENSTORE_TRANSACTION *Transaction,
  IN BOOLEAN                Abort
  )
{
  return XenStoreTransactionEnd (Transaction, Abort);
}

XENSTORE_STATUS
EFIAPI
XenBusXenStoreSPrint (
  IN XENBUS_PROTOCOL        *This,
  IN CONST XENSTORE_TRANSACTION *Transaction,
  IN CONST CHAR8            *DirectoryPath,
  IN CONST CHAR8            *Node,
  IN CONST CHAR8            *FormatString,
  ...
  )
{
  VA_LIST Marker;
  XENSTORE_STATUS Status;

  VA_START (Marker, FormatString);
  Status = XenStoreVSPrint (Transaction, DirectoryPath, Node, FormatString, Marker);
  VA_END (Marker);

  return Status;
}

XENSTORE_STATUS
EFIAPI
XenBusRegisterWatch (
  IN  XENBUS_PROTOCOL *This,
  IN  CONST CHAR8     *Node,
  OUT VOID            **Token
  )
{
  return XenStoreRegisterWatch (This->Node, Node, (XENSTORE_WATCH **) Token);
}

XENSTORE_STATUS
EFIAPI
XenBusRegisterWatchBackend (
  IN  XENBUS_PROTOCOL *This,
  IN  CONST CHAR8     *Node,
  OUT VOID            **Token
  )
{
  return XenStoreRegisterWatch (This->Backend, Node, (XENSTORE_WATCH **) Token);
}

VOID
EFIAPI
XenBusUnregisterWatch (
  IN XENBUS_PROTOCOL  *This,
  IN VOID             *Token
  )
{
  XenStoreUnregisterWatch ((XENSTORE_WATCH *) Token);
}
