linux/drivers/xen/xenbus/xenbus_client.c

/******************************************************************************
 * Client-facing interface for the Xenbus driver.  In other words, the
 * interface between the Xenbus and the device-specific code, be it the
 * frontend or the backend of that driver.
 *
 * Copyright (C) 2005 XenSource Ltd
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation; or, when 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 <linux/mm.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
#include <linux/export.h>
#include <asm/xen/hypervisor.h>
#include <xen/page.h>
#include <xen/interface/xen.h>
#include <xen/interface/event_channel.h>
#include <xen/balloon.h>
#include <xen/events.h>
#include <xen/grant_table.h>
#include <xen/xenbus.h>
#include <xen/xen.h>
#include <xen/features.h>

#include "xenbus.h"

#define XENBUS_PAGES(_grants)

#define XENBUS_MAX_RING_PAGES

struct xenbus_map_node {};

struct map_ring_valloc {};

static DEFINE_SPINLOCK(xenbus_valloc_lock);
static LIST_HEAD(xenbus_valloc_pages);

struct xenbus_ring_ops {};

static const struct xenbus_ring_ops *ring_ops __read_mostly;

const char *xenbus_strstate(enum xenbus_state state)
{}
EXPORT_SYMBOL_GPL();

/**
 * xenbus_watch_path - register a watch
 * @dev: xenbus device
 * @path: path to watch
 * @watch: watch to register
 * @will_handle: events queuing determine callback
 * @callback: callback to register
 *
 * Register a @watch on the given path, using the given xenbus_watch structure
 * for storage, @will_handle function as the callback to determine if each
 * event need to be queued, and the given @callback function as the callback.
 * On success, the given @path will be saved as @watch->node, and remains the
 * caller's to free.  On error, @watch->node will be NULL, the device will
 * switch to %XenbusStateClosing, and the error will be saved in the store.
 *
 * Returns: %0 on success or -errno on error
 */
int xenbus_watch_path(struct xenbus_device *dev, const char *path,
		      struct xenbus_watch *watch,
		      bool (*will_handle)(struct xenbus_watch *,
					  const char *, const char *),
		      void (*callback)(struct xenbus_watch *,
				       const char *, const char *))
{}
EXPORT_SYMBOL_GPL();


/**
 * xenbus_watch_pathfmt - register a watch on a sprintf-formatted path
 * @dev: xenbus device
 * @watch: watch to register
 * @will_handle: events queuing determine callback
 * @callback: callback to register
 * @pathfmt: format of path to watch
 *
 * Register a watch on the given @path, using the given xenbus_watch
 * structure for storage, @will_handle function as the callback to determine if
 * each event need to be queued, and the given @callback function as the
 * callback.  On success, the watched path (@path/@path2) will be saved
 * as @watch->node, and becomes the caller's to kfree().
 * On error, watch->node will be NULL, so the caller has nothing to
 * free, the device will switch to %XenbusStateClosing, and the error will be
 * saved in the store.
 *
 * Returns: %0 on success or -errno on error
 */
int xenbus_watch_pathfmt(struct xenbus_device *dev,
			 struct xenbus_watch *watch,
			 bool (*will_handle)(struct xenbus_watch *,
					const char *, const char *),
			 void (*callback)(struct xenbus_watch *,
					  const char *, const char *),
			 const char *pathfmt, ...)
{}
EXPORT_SYMBOL_GPL();

static void xenbus_switch_fatal(struct xenbus_device *, int, int,
				const char *, ...);

static int
__xenbus_switch_state(struct xenbus_device *dev,
		      enum xenbus_state state, int depth)
{}

/**
 * xenbus_switch_state - save the new state of a driver
 * @dev: xenbus device
 * @state: new state
 *
 * Advertise in the store a change of the given driver to the given new_state.
 * On error, the device will switch to XenbusStateClosing, and the error
 * will be saved in the store.
 *
 * Returns: %0 on success or -errno on error
 */
int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
{}

EXPORT_SYMBOL_GPL();

int xenbus_frontend_closed(struct xenbus_device *dev)
{}
EXPORT_SYMBOL_GPL();

static void xenbus_va_dev_error(struct xenbus_device *dev, int err,
				const char *fmt, va_list ap)
{}

/**
 * xenbus_dev_error - place an error message into the store
 * @dev: xenbus device
 * @err: error to report
 * @fmt: error message format
 *
 * Report the given negative errno into the store, along with the given
 * formatted message.
 */
void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...)
{}
EXPORT_SYMBOL_GPL();

/**
 * xenbus_dev_fatal - put an error messages into the store and then shutdown
 * @dev: xenbus device
 * @err: error to report
 * @fmt: error message format
 *
 * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
 * xenbus_switch_state(dev, XenbusStateClosing) to schedule an orderly
 * closedown of this driver and its peer.
 */

void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...)
{}
EXPORT_SYMBOL_GPL();

/*
 * Equivalent to xenbus_dev_fatal(dev, err, fmt, args), but helps
 * avoiding recursion within xenbus_switch_state.
 */
static void xenbus_switch_fatal(struct xenbus_device *dev, int depth, int err,
				const char *fmt, ...)
{}

/*
 * xenbus_setup_ring
 * @dev: xenbus device
 * @vaddr: pointer to starting virtual address of the ring
 * @nr_pages: number of pages to be granted
 * @grefs: grant reference array to be filled in
 *
 * Allocate physically contiguous pages for a shared ring buffer and grant it
 * to the peer of the given device. The ring buffer is initially filled with
 * zeroes. The virtual address of the ring is stored at @vaddr and the
 * grant references are stored in the @grefs array. In case of error @vaddr
 * will be set to NULL and @grefs will be filled with INVALID_GRANT_REF.
 */
int xenbus_setup_ring(struct xenbus_device *dev, gfp_t gfp, void **vaddr,
		      unsigned int nr_pages, grant_ref_t *grefs)
{}
EXPORT_SYMBOL_GPL();

/*
 * xenbus_teardown_ring
 * @vaddr: starting virtual address of the ring
 * @nr_pages: number of pages
 * @grefs: grant reference array
 *
 * Remove grants for the shared ring buffer and free the associated memory.
 * On return the grant reference array is filled with INVALID_GRANT_REF.
 */
void xenbus_teardown_ring(void **vaddr, unsigned int nr_pages,
			  grant_ref_t *grefs)
{}
EXPORT_SYMBOL_GPL();

/*
 * Allocate an event channel for the given xenbus_device, assigning the newly
 * created local port to *port.  Return 0 on success, or -errno on error.  On
 * error, the device will switch to XenbusStateClosing, and the error will be
 * saved in the store.
 */
int xenbus_alloc_evtchn(struct xenbus_device *dev, evtchn_port_t *port)
{}
EXPORT_SYMBOL_GPL();


/*
 * Free an existing event channel. Returns 0 on success or -errno on error.
 */
int xenbus_free_evtchn(struct xenbus_device *dev, evtchn_port_t port)
{}
EXPORT_SYMBOL_GPL();


/**
 * xenbus_map_ring_valloc - allocate & map pages of VA space
 * @dev: xenbus device
 * @gnt_refs: grant reference array
 * @nr_grefs: number of grant references
 * @vaddr: pointer to address to be filled out by mapping
 *
 * Map @nr_grefs pages of memory into this domain from another
 * domain's grant table.  xenbus_map_ring_valloc allocates @nr_grefs
 * pages of virtual address space, maps the pages to that address, and sets
 * *vaddr to that address.  If an error is returned, device will switch to
 * XenbusStateClosing and the error message will be saved in XenStore.
 *
 * Returns: %0 on success or -errno on error
 */
int xenbus_map_ring_valloc(struct xenbus_device *dev, grant_ref_t *gnt_refs,
			   unsigned int nr_grefs, void **vaddr)
{}
EXPORT_SYMBOL_GPL();

/* N.B. sizeof(phys_addr_t) doesn't always equal to sizeof(unsigned
 * long), e.g. 32-on-64.  Caller is responsible for preparing the
 * right array to feed into this function */
static int __xenbus_map_ring(struct xenbus_device *dev,
			     grant_ref_t *gnt_refs,
			     unsigned int nr_grefs,
			     grant_handle_t *handles,
			     struct map_ring_valloc *info,
			     unsigned int flags,
			     bool *leaked)
{}

/**
 * xenbus_unmap_ring - unmap memory from another domain
 * @dev: xenbus device
 * @handles: grant handle array
 * @nr_handles: number of handles in the array
 * @vaddrs: addresses to unmap
 *
 * Unmap memory in this domain that was imported from another domain.
 *
 * Returns: %0 on success or GNTST_* on error
 * (see xen/include/interface/grant_table.h).
 */
static int xenbus_unmap_ring(struct xenbus_device *dev, grant_handle_t *handles,
			     unsigned int nr_handles, unsigned long *vaddrs)
{}

static void xenbus_map_ring_setup_grant_hvm(unsigned long gfn,
					    unsigned int goffset,
					    unsigned int len,
					    void *data)
{}

static int xenbus_map_ring_hvm(struct xenbus_device *dev,
			       struct map_ring_valloc *info,
			       grant_ref_t *gnt_ref,
			       unsigned int nr_grefs,
			       void **vaddr)
{}

/**
 * xenbus_unmap_ring_vfree - unmap a page of memory from another domain
 * @dev: xenbus device
 * @vaddr: addr to unmap
 *
 * Based on Rusty Russell's skeleton driver's unmap_page.
 * Unmap a page of memory in this domain that was imported from another domain.
 * Use xenbus_unmap_ring_vfree if you mapped in your memory with
 * xenbus_map_ring_valloc (it will free the virtual address space).
 *
 * Returns: %0 on success or GNTST_* on error
 * (see xen/include/interface/grant_table.h).
 */
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_XEN_PV
static int map_ring_apply(pte_t *pte, unsigned long addr, void *data)
{}

static int xenbus_map_ring_pv(struct xenbus_device *dev,
			      struct map_ring_valloc *info,
			      grant_ref_t *gnt_refs,
			      unsigned int nr_grefs,
			      void **vaddr)
{}

static int xenbus_unmap_ring_pv(struct xenbus_device *dev, void *vaddr)
{}

static const struct xenbus_ring_ops ring_ops_pv =;
#endif

struct unmap_ring_hvm
{};

static void xenbus_unmap_ring_setup_grant_hvm(unsigned long gfn,
					      unsigned int goffset,
					      unsigned int len,
					      void *data)
{}

static int xenbus_unmap_ring_hvm(struct xenbus_device *dev, void *vaddr)
{}

/**
 * xenbus_read_driver_state - read state from a store path
 * @path: path for driver
 *
 * Returns: the state of the driver rooted at the given store path, or
 * XenbusStateUnknown if no state can be read.
 */
enum xenbus_state xenbus_read_driver_state(const char *path)
{}
EXPORT_SYMBOL_GPL();

static const struct xenbus_ring_ops ring_ops_hvm =;

void __init xenbus_ring_ops_init(void)
{}