summaryrefslogtreecommitdiffstats
path: root/sys/xen/xenbus
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2008-11-22 16:14:52 +0000
committerdfr <dfr@FreeBSD.org>2008-11-22 16:14:52 +0000
commit19b6af98ec71398e77874582eb84ec5310c7156f (patch)
tree61eebb1b357f3edaa339d295e26a47a74534ac23 /sys/xen/xenbus
parent83299de5870b2dc099c17aec548d3502821bc29b (diff)
downloadFreeBSD-src-19b6af98ec71398e77874582eb84ec5310c7156f.zip
FreeBSD-src-19b6af98ec71398e77874582eb84ec5310c7156f.tar.gz
Clone Kip's Xen on stable/6 tree so that I can work on improving FreeBSD/amd64
performance in Xen's HVM mode.
Diffstat (limited to 'sys/xen/xenbus')
-rw-r--r--sys/xen/xenbus/init.txt14
-rw-r--r--sys/xen/xenbus/xenbus_client.c318
-rw-r--r--sys/xen/xenbus/xenbus_comms.c251
-rw-r--r--sys/xen/xenbus/xenbus_comms.h157
-rw-r--r--sys/xen/xenbus/xenbus_dev.c259
-rw-r--r--sys/xen/xenbus/xenbus_probe.c1134
-rw-r--r--sys/xen/xenbus/xenbus_probe_backend.c308
-rw-r--r--sys/xen/xenbus/xenbus_xs.c960
8 files changed, 0 insertions, 3401 deletions
diff --git a/sys/xen/xenbus/init.txt b/sys/xen/xenbus/init.txt
deleted file mode 100644
index 4249549..0000000
--- a/sys/xen/xenbus/init.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-- frontend driver initializes static xenbus_driver with _ids, _probe, _remove,
-_resume, _otherend_changed
-
- - initialization calls xenbus_register_frontend(xenbus_driver)
-
- - xenbus_register_frontend sets read_otherend details to read_backend_details
- then calls xenbus_register_driver_common(xenbus_driver, xenbus_frontend)
-
- - xenbus_register_driver_common sets underlying driver name to xenbus_driver name
- underlying driver bus to xenbus_frontend's bus, driver's probe to xenbus_dev_probe
- driver's remove to xenbus_dev_remove then calls driver_register
-
diff --git a/sys/xen/xenbus/xenbus_client.c b/sys/xen/xenbus/xenbus_client.c
deleted file mode 100644
index a6f9e6b..0000000
--- a/sys/xen/xenbus/xenbus_client.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/******************************************************************************
- * 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 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.
- */
-
-
-#if 0
-#define DPRINTK(fmt, args...) \
- printk("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <sys/malloc.h>
-#include <sys/libkern.h>
-
-#include <machine/xen/xen-os.h>
-#include <machine/xen/evtchn.h>
-#include <xen/gnttab.h>
-#include <machine/xen/xenbus.h>
-#include <machine/stdarg.h>
-
-
-#define EXPORT_SYMBOL(x)
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define kfree(ptr) free(ptr, M_DEVBUF)
-#define BUG_ON PANIC_IF
-
-
-const char *xenbus_strstate(XenbusState state)
-{
- static const char *const name[] = {
- [ XenbusStateUnknown ] = "Unknown",
- [ XenbusStateInitialising ] = "Initialising",
- [ XenbusStateInitWait ] = "InitWait",
- [ XenbusStateInitialised ] = "Initialised",
- [ XenbusStateConnected ] = "Connected",
- [ XenbusStateClosing ] = "Closing",
- [ XenbusStateClosed ] = "Closed",
- };
- return (state < (XenbusStateClosed + 1)) ? name[state] : "INVALID";
-}
-
-int
-xenbus_watch_path(struct xenbus_device *dev, char *path,
- struct xenbus_watch *watch,
- void (*callback)(struct xenbus_watch *,
- const char **, unsigned int))
-{
- int err;
-
- watch->node = path;
- watch->callback = callback;
-
- err = register_xenbus_watch(watch);
-
- if (err) {
- watch->node = NULL;
- watch->callback = NULL;
- xenbus_dev_fatal(dev, err, "adding watch on %s", path);
- }
-
- return err;
-}
-EXPORT_SYMBOL(xenbus_watch_path);
-
-
-int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
- const char *path2, struct xenbus_watch *watch,
- void (*callback)(struct xenbus_watch *,
- const char **, unsigned int))
-{
- int err;
- char *state =
- kmalloc(strlen(path) + 1 + strlen(path2) + 1, GFP_KERNEL);
- if (!state) {
- xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
- return -ENOMEM;
- }
- strcpy(state, path);
- strcat(state, "/");
- strcat(state, path2);
-
- err = xenbus_watch_path(dev, state, watch, callback);
-
- if (err) {
- kfree(state);
- }
- return err;
-}
-EXPORT_SYMBOL(xenbus_watch_path2);
-
-
-int xenbus_switch_state(struct xenbus_device *dev,
- XenbusState state)
-{
- /* We check whether the state is currently set to the given value, and
- if not, then the state is set. We don't want to unconditionally
- write the given state, because we don't want to fire watches
- unnecessarily. Furthermore, if the node has gone, we don't write
- to it, as the device will be tearing down, and we don't want to
- resurrect that directory.
- */
-
- int current_state;
- int err;
-
- if (state == dev->state)
- return (0);
-
- err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d",
- &current_state);
- if (err != 1)
- return 0;
-
- err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state);
- if (err) {
- if (state != XenbusStateClosing) /* Avoid looping */
- xenbus_dev_fatal(dev, err, "writing new state");
- return err;
- }
-
- dev->state = state;
- return 0;
-
-}
-
-int xenbus_frontend_closed(struct xenbus_device *dev)
-{
- xenbus_switch_state(dev, XenbusStateClosed);
-#if 0
- complete(&dev->down);
-#endif
- return 0;
-}
-
-/**
- * Return the path to the error node for the given device, or NULL on failure.
- * If the value returned is non-NULL, then it is the caller's to kfree.
- */
-static char *error_path(struct xenbus_device *dev)
-{
- char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) +
- 1, GFP_KERNEL);
- if (path_buffer == NULL) {
- return NULL;
- }
-
- strcpy(path_buffer, "error/");
- strcpy(path_buffer + strlen("error/"), dev->nodename);
-
- return path_buffer;
-}
-
-
-static void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
- va_list ap)
-{
- int ret;
- unsigned int len;
- char *printf_buffer = NULL, *path_buffer = NULL;
-
-#define PRINTF_BUFFER_SIZE 4096
- printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
- if (printf_buffer == NULL)
- goto fail;
-
- len = sprintf(printf_buffer, "%i ", -err);
- ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
-
- BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
-#if 0
- dev_err(&dev->dev, "%s\n", printf_buffer);
-#endif
- path_buffer = error_path(dev);
-
- if (path_buffer == NULL) {
- printk("xenbus: failed to write error node for %s (%s)\n",
- dev->nodename, printf_buffer);
- goto fail;
- }
-
- if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
- printk("xenbus: failed to write error node for %s (%s)\n",
- dev->nodename, printf_buffer);
- goto fail;
- }
-
- fail:
- if (printf_buffer)
- kfree(printf_buffer);
- if (path_buffer)
- kfree(path_buffer);
-}
-
-
-void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
- ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- _dev_error(dev, err, fmt, ap);
- va_end(ap);
-}
-EXPORT_SYMBOL(xenbus_dev_error);
-
-
-void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
- ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- _dev_error(dev, err, fmt, ap);
- va_end(ap);
-
- xenbus_switch_state(dev, XenbusStateClosing);
-}
-EXPORT_SYMBOL(xenbus_dev_fatal);
-
-
-int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn)
-{
- int err = gnttab_grant_foreign_access(dev->otherend_id, ring_mfn, 0);
- if (err < 0)
- xenbus_dev_fatal(dev, err, "granting access to ring page");
- return err;
-}
-EXPORT_SYMBOL(xenbus_grant_ring);
-
-
-int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
-{
- struct evtchn_alloc_unbound alloc_unbound;
- int err;
-
- alloc_unbound.dom = DOMID_SELF;
- alloc_unbound.remote_dom = dev->otherend_id;
-
- err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
- &alloc_unbound);
-
- if (err)
- xenbus_dev_fatal(dev, err, "allocating event channel");
- else
- *port = alloc_unbound.port;
- return err;
-}
-EXPORT_SYMBOL(xenbus_alloc_evtchn);
-
-
-int xenbus_free_evtchn(struct xenbus_device *dev, int port)
-{
- struct evtchn_close close;
- int err;
-
- close.port = port;
-
- err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
- if (err)
- xenbus_dev_error(dev, err, "freeing event channel %d", port);
- return err;
-}
-EXPORT_SYMBOL(xenbus_free_evtchn);
-
-
-XenbusState xenbus_read_driver_state(const char *path)
-{
- XenbusState result;
-
- int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
- if (err)
- result = XenbusStateClosed;
-
- return result;
-}
-EXPORT_SYMBOL(xenbus_read_driver_state);
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/sys/xen/xenbus/xenbus_comms.c b/sys/xen/xenbus/xenbus_comms.c
deleted file mode 100644
index 8f0f171..0000000
--- a/sys/xen/xenbus/xenbus_comms.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/******************************************************************************
- * xenbus_comms.c
- *
- * Low level code to talks to Xen Store: ringbuffer and event channel.
- *
- * Copyright (C) 2005 Rusty Russell, IBM Corporation
- *
- * 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 <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/time.h>
-#include <sys/errno.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/syslog.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-
-
-
-#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/evtchn.h>
-#include <machine/xen/xenbus.h>
-#include <machine/xen/xen_intr.h>
-#include <xen/xenbus/xenbus_comms.h>
-
-static int xenbus_irq;
-
-extern void xenbus_probe(void *);
-extern int xenstored_ready;
-#if 0
-static DECLARE_WORK(probe_work, xenbus_probe, NULL);
-#endif
-int xb_wait;
-extern char *xen_store;
-#define wake_up wakeup
-#define xb_waitq xb_wait
-#define pr_debug(a,b,c)
-
-static inline struct xenstore_domain_interface *xenstore_domain_interface(void)
-{
- return (struct xenstore_domain_interface *)xen_store;
-}
-
-static void
-wake_waiting(void * arg __attribute__((unused)))
-{
-#if 0
- if (unlikely(xenstored_ready == 0)) {
- xenstored_ready = 1;
- schedule_work(&probe_work);
- }
-#endif
- wakeup(&xb_wait);
-}
-
-static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
-{
- return ((prod - cons) <= XENSTORE_RING_SIZE);
-}
-
-static void *get_output_chunk(XENSTORE_RING_IDX cons,
- XENSTORE_RING_IDX prod,
- char *buf, uint32_t *len)
-{
- *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
- if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
- *len = XENSTORE_RING_SIZE - (prod - cons);
- return buf + MASK_XENSTORE_IDX(prod);
-}
-
-static const void *get_input_chunk(XENSTORE_RING_IDX cons,
- XENSTORE_RING_IDX prod,
- const char *buf, uint32_t *len)
-{
- *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
- if ((prod - cons) < *len)
- *len = prod - cons;
- return buf + MASK_XENSTORE_IDX(cons);
-}
-
-int xb_write(const void *tdata, unsigned len)
-{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- XENSTORE_RING_IDX cons, prod;
- const char *data = (const char *)tdata;
-
- while (len != 0) {
- void *dst;
- unsigned int avail;
-
- wait_event_interruptible(&xb_waitq,
- (intf->req_prod - intf->req_cons) !=
- XENSTORE_RING_SIZE);
-
- /* Read indexes, then verify. */
- cons = intf->req_cons;
- prod = intf->req_prod;
- mb();
- if (!check_indexes(cons, prod)) {
- intf->req_cons = intf->req_prod = 0;
- return -EIO;
- }
-
- dst = get_output_chunk(cons, prod, intf->req, &avail);
- if (avail == 0)
- continue;
- if (avail > len)
- avail = len;
- mb();
-
- memcpy(dst, data, avail);
- data += avail;
- len -= avail;
-
- /* Other side must not see new header until data is there. */
- wmb();
- intf->req_prod += avail;
-
- /* This implies mb() before other side sees interrupt. */
- notify_remote_via_evtchn(xen_start_info->store_evtchn);
- }
-
- return 0;
-}
-
-#ifdef notyet
-int xb_data_to_read(void)
-{
- struct xenstore_domain_interface *intf = xen_store_interface;
- return (intf->rsp_cons != intf->rsp_prod);
-}
-
-int xb_wait_for_data_to_read(void)
-{
- return wait_event_interruptible(xb_waitq, xb_data_to_read());
-}
-#endif
-
-
-int xb_read(void *tdata, unsigned len)
-{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- XENSTORE_RING_IDX cons, prod;
- char *data = (char *)tdata;
-
- while (len != 0) {
- unsigned int avail;
- const char *src;
-
- wait_event_interruptible(&xb_waitq,
- intf->rsp_cons != intf->rsp_prod);
-
- /* Read indexes, then verify. */
- cons = intf->rsp_cons;
- prod = intf->rsp_prod;
- if (!check_indexes(cons, prod)) {
- intf->rsp_cons = intf->rsp_prod = 0;
- return -EIO;
- }
-
- src = get_input_chunk(cons, prod, intf->rsp, &avail);
- if (avail == 0)
- continue;
- if (avail > len)
- avail = len;
-
- /* We must read header before we read data. */
- rmb();
-
- memcpy(data, src, avail);
- data += avail;
- len -= avail;
-
- /* Other side must not see free space until we've copied out */
- mb();
- intf->rsp_cons += avail;
-
- pr_debug("Finished read of %i bytes (%i to go)\n", avail, len);
-
- /* Implies mb(): they will see new header. */
- notify_remote_via_evtchn(xen_start_info->store_evtchn);
- }
-
- return 0;
-}
-
-/* Set up interrupt handler off store event channel. */
-int xb_init_comms(void)
-{
- struct xenstore_domain_interface *intf = xenstore_domain_interface();
- int err;
-
- if (intf->rsp_prod != intf->rsp_cons) {
- log(LOG_WARNING, "XENBUS response ring is not quiescent "
- "(%08x:%08x): fixing up\n",
- intf->rsp_cons, intf->rsp_prod);
- intf->rsp_cons = intf->rsp_prod;
- }
-
- if (xenbus_irq)
- unbind_from_irqhandler(xenbus_irq, &xb_waitq);
-
- err = bind_caller_port_to_irqhandler(
- xen_start_info->store_evtchn,
- "xenbus", wake_waiting, NULL, INTR_TYPE_NET, NULL);
- if (err <= 0) {
- log(LOG_WARNING, "XENBUS request irq failed %i\n", err);
- return err;
- }
-
- xenbus_irq = err;
-
- return 0;
-}
-
-/*
- * Local variables:
- * c-file-style: "bsd"
- * indent-tabs-mode: t
- * c-indent-level: 4
- * c-basic-offset: 8
- * tab-width: 4
- * End:
- */
diff --git a/sys/xen/xenbus/xenbus_comms.h b/sys/xen/xenbus/xenbus_comms.h
deleted file mode 100644
index 871afd5..0000000
--- a/sys/xen/xenbus/xenbus_comms.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Private include for xenbus communications.
- *
- * Copyright (C) 2005 Rusty Russell, IBM Corporation
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _XENBUS_COMMS_H
-#define _XENBUS_COMMS_H
-
-int xs_init(void);
-int xb_init_comms(void);
-
-/* Low level routines. */
-int xb_write(const void *data, unsigned len);
-int xb_read(void *data, unsigned len);
-int xs_input_avail(void);
-extern int xb_waitq;
-extern int xenbus_running;
-
-#define __wait_event_interruptible(wchan, condition, ret) \
-do { \
- for (;;) { \
- if (xenbus_running == 0) { \
- break; \
- } \
- if (condition) \
- break; \
- if ((ret = !tsleep(wchan, PWAIT | PCATCH, "waitev", hz/10))) \
- break; \
- } \
-} while (0)
-
-
-#define wait_event_interruptible(wchan, condition) \
-({ \
- int __ret = 0; \
- if (!(condition)) \
- __wait_event_interruptible(wchan, condition, __ret); \
- __ret; \
-})
-
-
-
-#define DECLARE_MUTEX(lock) struct sema lock
-#define semaphore sema
-#define rw_semaphore sema
-
-#define down sema_wait
-#define up sema_post
-#define down_read sema_wait
-#define up_read sema_post
-#define down_write sema_wait
-#define up_write sema_post
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-
-/*
- * XXX
- *
- */
-
-#define GFP_KERNEL 1
-#define EXPORT_SYMBOL(x)
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define kfree(ptr) free((void *)(uintptr_t)ptr, M_DEVBUF)
-#define BUG_ON PANIC_IF
-#define semaphore sema
-#define rw_semaphore sema
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define DECLARE_MUTEX(lock) struct sema lock
-#define u32 uint32_t
-#define list_del(head, ent) TAILQ_REMOVE(head, ent, list)
-#define simple_strtoul strtoul
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#define list_empty TAILQ_EMPTY
-#define wake_up wakeup
-#define BUS_ID_SIZE 128
-
-struct xen_bus_type
-{
- char *root;
- unsigned int levels;
- int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename);
- int (*probe)(const char *type, const char *dir);
- struct xendev_list_head *bus;
- int error;
-#if 0
- struct bus_type bus;
- struct device dev;
-#endif
-};
-
-
-extern void xenbus_backend_probe_and_watch(void);
-int xenbus_probe_node(struct xen_bus_type *bus, const char *type,
- const char *nodename);
-int xenbus_probe_devices(struct xen_bus_type *bus);
-
-int xenbus_register_driver_common(struct xenbus_driver *drv,
- struct xen_bus_type *bus);
-
-void dev_changed(const char *node, struct xen_bus_type *bus);
-
-int
-read_otherend_details(struct xenbus_device *xendev, char *id_node,
- char *path_node);
-
-char *kasprintf(const char *fmt, ...);
-
-
-
-
-#endif /* _XENBUS_COMMS_H */
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/sys/xen/xenbus/xenbus_dev.c b/sys/xen/xenbus/xenbus_dev.c
deleted file mode 100644
index 8a13322..0000000
--- a/sys/xen/xenbus/xenbus_dev.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * xenbus_dev.c
- *
- * Driver giving user-space access to the kernel's xenbus connection
- * to xenstore.
- *
- * Copyright (c) 2005, Christian Limpach
- * Copyright (c) 2005, Rusty Russell, IBM Corporation
- *
- * 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 <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/errno.h>
-#include <sys/uio.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/conf.h>
-
-
-#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xenbus.h>
-#include <machine/xen/hypervisor.h>
-#include <xen/xenbus/xenbus_comms.h>
-
-
-
-
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define BUG_ON PANIC_IF
-#define semaphore sema
-#define rw_semaphore sema
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define DECLARE_MUTEX(lock) struct sema lock
-#define u32 uint32_t
-#define simple_strtoul strtoul
-
-struct xenbus_dev_transaction {
- LIST_ENTRY(xenbus_dev_transaction) list;
- struct xenbus_transaction handle;
-};
-
-struct xenbus_dev_data {
- /* In-progress transaction. */
- LIST_HEAD(xdd_list_head, xenbus_dev_transaction) transactions;
-
- /* Partial request. */
- unsigned int len;
- union {
- struct xsd_sockmsg msg;
- char buffer[PAGE_SIZE];
- } u;
-
- /* Response queue. */
-#define MASK_READ_IDX(idx) ((idx)&(PAGE_SIZE-1))
- char read_buffer[PAGE_SIZE];
- unsigned int read_cons, read_prod;
- int read_waitq;
-};
-#if 0
-static struct proc_dir_entry *xenbus_dev_intf;
-#endif
-static int
-xenbus_dev_read(struct cdev *dev, struct uio *uio, int ioflag)
-{
- int i = 0;
- struct xenbus_dev_data *u = dev->si_drv1;
-
- if (wait_event_interruptible(&u->read_waitq,
- u->read_prod != u->read_cons))
- return EINTR;
-
- for (i = 0; i < uio->uio_iov[0].iov_len; i++) {
- if (u->read_cons == u->read_prod)
- break;
- copyout(&u->read_buffer[MASK_READ_IDX(u->read_cons)], (char *)uio->uio_iov[0].iov_base+i, 1);
- u->read_cons++;
- uio->uio_resid--;
- }
- return 0;
-}
-
-static void queue_reply(struct xenbus_dev_data *u,
- char *data, unsigned int len)
-{
- int i;
-
- for (i = 0; i < len; i++, u->read_prod++)
- u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i];
-
- BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer));
-
- wakeup(&u->read_waitq);
-}
-
-static int
-xenbus_dev_write(struct cdev *dev, struct uio *uio, int ioflag)
-{
- int err = 0;
- struct xenbus_dev_data *u = dev->si_drv1;
- struct xenbus_dev_transaction *trans;
- void *reply;
- int len = uio->uio_iov[0].iov_len;
-
- if ((len + u->len) > sizeof(u->u.buffer))
- return EINVAL;
-
- if (copyin(u->u.buffer + u->len, uio->uio_iov[0].iov_base, len) != 0)
- return EFAULT;
-
- u->len += len;
- if (u->len < (sizeof(u->u.msg) + u->u.msg.len))
- return len;
-
- switch (u->u.msg.type) {
- case XS_TRANSACTION_START:
- case XS_TRANSACTION_END:
- case XS_DIRECTORY:
- case XS_READ:
- case XS_GET_PERMS:
- case XS_RELEASE:
- case XS_GET_DOMAIN_PATH:
- case XS_WRITE:
- case XS_MKDIR:
- case XS_RM:
- case XS_SET_PERMS:
- reply = xenbus_dev_request_and_reply(&u->u.msg);
- if (IS_ERR(reply)) {
- err = PTR_ERR(reply);
- } else {
- if (u->u.msg.type == XS_TRANSACTION_START) {
- trans = kmalloc(sizeof(*trans), GFP_KERNEL);
- trans->handle.id = simple_strtoul(reply, NULL, 0);
- LIST_INSERT_HEAD(&u->transactions, trans, list);
- } else if (u->u.msg.type == XS_TRANSACTION_END) {
- LIST_FOREACH(trans, &u->transactions,
- list)
- if (trans->handle.id ==
- u->u.msg.tx_id)
- break;
-#if 0 /* XXX does this mean the list is empty? */
- BUG_ON(&trans->list == &u->transactions);
-#endif
- LIST_REMOVE(trans, list);
- kfree(trans);
- }
- queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
- queue_reply(u, (char *)reply, u->u.msg.len);
- kfree(reply);
- }
- break;
-
- default:
- err = EINVAL;
- break;
- }
-
- if (err == 0) {
- u->len = 0;
- err = len;
- }
-
- return err;
-}
-
-static int xenbus_dev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
-{
- struct xenbus_dev_data *u;
-
- if (xen_start_info->store_evtchn == 0)
- return ENOENT;
-#if 0 /* XXX figure out if equiv needed */
- nonseekable_open(inode, filp);
-#endif
- u = kmalloc(sizeof(*u), GFP_KERNEL);
- if (u == NULL)
- return ENOMEM;
-
- memset(u, 0, sizeof(*u));
- LIST_INIT(&u->transactions);
-
- dev->si_drv1 = u;
-
- return 0;
-}
-
-static int xenbus_dev_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
-{
- struct xenbus_dev_data *u = dev->si_drv1;
- struct xenbus_dev_transaction *trans, *tmp;
-
- LIST_FOREACH_SAFE(trans, &u->transactions, list, tmp) {
- xenbus_transaction_end(trans->handle, 1);
- LIST_REMOVE(trans, list);
- kfree(trans);
- }
-
- kfree(u);
- return 0;
-}
-
-static struct cdevsw xenbus_dev_cdevsw = {
- .d_version = D_VERSION,
- .d_read = xenbus_dev_read,
- .d_write = xenbus_dev_write,
- .d_open = xenbus_dev_open,
- .d_close = xenbus_dev_close,
- .d_name = "xenbus_dev",
-};
-
-static int
-xenbus_dev_sysinit(void)
-{
- make_dev(&xenbus_dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0400, "xenbus");
-
- return 0;
-}
-SYSINIT(xenbus_dev_sysinit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, xenbus_dev_sysinit, NULL);
-/* SYSINIT NEEDED XXX */
-
-
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff --git a/sys/xen/xenbus/xenbus_probe.c b/sys/xen/xenbus/xenbus_probe.c
deleted file mode 100644
index c45a375..0000000
--- a/sys/xen/xenbus/xenbus_probe.c
+++ /dev/null
@@ -1,1134 +0,0 @@
-/******************************************************************************
- * Talks to Xen Store to figure out what devices we have.
- *
- * Copyright (C) 2005 Rusty Russell, IBM Corporation
- * Copyright (C) 2005 Mike Wray, Hewlett-Packard
- * Copyright (C) 2005 XenSource 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.
- */
-
-#if 0
-#define DPRINTK(fmt, args...) \
- printf("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/time.h>
-#include <sys/sema.h>
-#include <sys/eventhandler.h>
-#include <sys/errno.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/systm.h>
-#include <sys/syslog.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/sx.h>
-
-#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xenbus.h>
-#include <machine/xen/evtchn.h>
-#include <machine/stdarg.h>
-
-#include <xen/xenbus/xenbus_comms.h>
-
-struct xendev_list_head xenbus_device_frontend_list;
-struct xendev_list_head xenbus_device_backend_list;
-static LIST_HEAD(, xenbus_driver) xendrv_list;
-
-extern struct sx xenwatch_mutex;
-
-EVENTHANDLER_DECLARE(xenstore_event, xenstore_event_handler_t);
-static struct eventhandler_list *xenstore_chain;
-device_t xenbus_dev;
-device_t xenbus_backend_dev;
-static MALLOC_DEFINE(M_XENDEV, "xenintrdrv", "xen system device");
-
-#define streq(a, b) (strcmp((a), (b)) == 0)
-
-static int watch_otherend(struct xenbus_device *dev);
-
-
-/* If something in array of ids matches this device, return it. */
-static const struct xenbus_device_id *
-match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev)
-{
- for (; !streq(arr->devicetype, ""); arr++) {
- if (streq(arr->devicetype, dev->devicetype))
- return arr;
- }
- return NULL;
-}
-
-#if 0
-static int xenbus_match(device_t _dev)
-{
- struct xenbus_driver *drv;
- struct xenbus_device *dev;
-
- dev = device_get_softc(_dev);
- drv = dev->driver;
-
- if (!drv->ids)
- return 0;
-
- return match_device(drv->ids, to_xenbus_device(_dev)) != NULL;
-}
-#endif
-
-
-/* device/<type>/<id> => <type>-<id> */
-static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
-{
- nodename = strchr(nodename, '/');
- if (!nodename || strlen(nodename + 1) >= BUS_ID_SIZE) {
- log(LOG_WARNING, "XENBUS: bad frontend %s\n", nodename);
- return -EINVAL;
- }
-
- strlcpy(bus_id, nodename + 1, BUS_ID_SIZE);
- if (!strchr(bus_id, '/')) {
- log(LOG_WARNING, "XENBUS: bus_id %s no slash\n", bus_id);
- return -EINVAL;
- }
- *strchr(bus_id, '/') = '-';
- return 0;
-}
-
-
-static void free_otherend_details(struct xenbus_device *dev)
-{
- kfree((void*)(uintptr_t)dev->otherend);
- dev->otherend = NULL;
-}
-
-
-static void free_otherend_watch(struct xenbus_device *dev)
-{
- if (dev->otherend_watch.node) {
- unregister_xenbus_watch(&dev->otherend_watch);
- kfree(dev->otherend_watch.node);
- dev->otherend_watch.node = NULL;
- }
-}
-
-int
-read_otherend_details(struct xenbus_device *xendev, char *id_node,
- char *path_node)
-{
- int err = xenbus_gather(XBT_NIL, xendev->nodename,
- id_node, "%i", &xendev->otherend_id,
- path_node, NULL, &xendev->otherend,
- NULL);
- if (err) {
- xenbus_dev_fatal(xendev, err,
- "reading other end details from %s",
- xendev->nodename);
- return err;
- }
- if (strlen(xendev->otherend) == 0 ||
- !xenbus_exists(XBT_NIL, xendev->otherend, "")) {
- xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
- xendev->nodename);
- kfree((void *)(uintptr_t)xendev->otherend);
- xendev->otherend = NULL;
- return -ENOENT;
- }
-
- return 0;
-}
-
-
-static int read_backend_details(struct xenbus_device *xendev)
-{
- return read_otherend_details(xendev, "backend-id", "backend");
-}
-
-#ifdef notyet
-/* XXX - move to probe backend */
-static int read_frontend_details(struct xenbus_device *xendev)
-{
- if (strncmp(xendev->nodename, "backend", 7))
- return -ENOENT;
- return read_otherend_details(xendev, "frontend-id", "frontend");
-}
-#endif
-
-/* Bus type for frontend drivers. */
-static int xenbus_probe_frontend(const char *type, const char *name);
-static struct xen_bus_type xenbus_frontend = {
- .root = "device",
- .levels = 2, /* device/type/<id> */
- .get_bus_id = frontend_bus_id,
- .probe = xenbus_probe_frontend,
- .bus = &xenbus_device_frontend_list,
-#if 0
- /* this initialization needs to happen dynamically */
- .bus = {
- .name = "xen",
- .match = xenbus_match,
- },
- .dev = {
- .bus_id = "xen",
- },
-#endif
-};
-
-#if 0
-static int xenbus_hotplug_backend(device_t dev, char **envp,
- int num_envp, char *buffer, int buffer_size)
-{
- panic("implement me");
-#if 0
- struct xenbus_device *xdev;
- struct xenbus_driver *drv = NULL;
- int i = 0;
- int length = 0;
- char *basepath_end;
- char *frontend_id;
-
- DPRINTK("");
-
- if (dev == NULL)
- return -ENODEV;
-
- xdev = to_xenbus_device(dev);
- if (xdev == NULL)
- return -ENODEV;
-
- if (dev->driver)
- drv = to_xenbus_driver(dev->driver);
-
- /* stuff we want to pass to /sbin/hotplug */
- add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "XENBUS_TYPE=%s", xdev->devicetype);
-
- add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "XENBUS_PATH=%s", xdev->nodename);
-
- add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "XENBUS_BASE_PATH=%s", xdev->nodename);
-
- basepath_end = strrchr(envp[i - 1], '/');
- length -= strlen(basepath_end);
- *basepath_end = '\0';
- basepath_end = strrchr(envp[i - 1], '/');
- length -= strlen(basepath_end);
- *basepath_end = '\0';
-
- basepath_end++;
- frontend_id = kmalloc(strlen(basepath_end) + 1, GFP_KERNEL);
- strcpy(frontend_id, basepath_end);
- add_hotplug_env_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "XENBUS_FRONTEND_ID=%s", frontend_id);
- kfree(frontend_id);
-
- /* terminate, set to next free slot, shrink available space */
- envp[i] = NULL;
- envp = &envp[i];
- num_envp -= i;
- buffer = &buffer[length];
- buffer_size -= length;
-
- if (drv && drv->hotplug)
- return drv->hotplug(xdev, envp, num_envp, buffer, buffer_size);
-
-#endif
- return 0;
-}
-#endif
-
-#if 0
-static int xenbus_probe_backend(const char *type, const char *domid, int unit);
-static struct xen_bus_type xenbus_backend = {
- .root = "backend",
- .levels = 3, /* backend/type/<frontend>/<id> */
- .get_bus_id = backend_bus_id,
- .probe = xenbus_probe_backend,
- /* at init time */
- .bus = &xenbus_device_backend_list,
-#if 0
- .bus = {
- .name = "xen-backend",
- .match = xenbus_match,
- .hotplug = xenbus_hotplug_backend,
- },
- .dev = {
- .bus_id = "xen-backend",
- },
-#endif
-};
-#endif
-
-static void otherend_changed(struct xenbus_watch *watch,
- const char **vec, unsigned int len)
-{
-
- struct xenbus_device *dev = (struct xenbus_device *)watch;
- struct xenbus_driver *drv = dev->driver;
- XenbusState state;
-
- /* Protect us against watches firing on old details when the otherend
- details change, say immediately after a resume. */
- if (!dev->otherend || strncmp(dev->otherend, vec[XS_WATCH_PATH],
- strlen(dev->otherend))) {
- DPRINTK("Ignoring watch at %s", vec[XS_WATCH_PATH]);
- return;
- }
-
- state = xenbus_read_driver_state(dev->otherend);
-
- DPRINTK("state is %d, %s, %s", state, dev->otherend_watch.node,
- vec[XS_WATCH_PATH]);
-
- /*
- * Ignore xenbus transitions during shutdown. This prevents us doing
- * work that can fail e.g., when the rootfs is gone.
- */
-#if 0
- if (system_state > SYSTEM_RUNNING) {
- struct xen_bus_type *bus = bus;
- bus = container_of(dev->dev.bus, struct xen_bus_type, bus);
- /* If we're frontend, drive the state machine to Closed. */
- /* This should cause the backend to release our resources. */
- if ((bus == &xenbus_frontend) && (state == XenbusStateClosing))
- xenbus_frontend_closed(dev);
- return;
- }
-#endif
- if (drv->otherend_changed)
- drv->otherend_changed(dev, state);
-
-}
-
-
-static int talk_to_otherend(struct xenbus_device *dev)
-{
- struct xenbus_driver *drv;
-
- drv = dev->driver;
-
- free_otherend_watch(dev);
- free_otherend_details(dev);
-
- return drv->read_otherend_details(dev);
-}
-
-static int watch_otherend(struct xenbus_device *dev)
-{
- return xenbus_watch_path2(dev, dev->otherend, "state",
- &dev->otherend_watch, otherend_changed);
-}
-
-static int
-xenbus_dev_probe(struct xenbus_device *dev)
-{
- struct xenbus_driver *drv = dev->driver;
- const struct xenbus_device_id *id;
- int err;
-
- DPRINTK("");
-
- if (!drv->probe) {
- err = -ENODEV;
- goto fail;
- }
-
- id = match_device(drv->ids, dev);
- if (!id) {
- err = -ENODEV;
- goto fail;
- }
-
- err = talk_to_otherend(dev);
- if (err) {
- log(LOG_WARNING,
- "xenbus_probe: talk_to_otherend on %s failed.\n",
- dev->nodename);
- return err;
- }
-
- err = drv->probe(dev, id);
- if (err)
- goto fail;
-
- err = watch_otherend(dev);
- if (err) {
- log(LOG_WARNING,
- "xenbus_probe: watch_otherend on %s failed.\n",
- dev->nodename);
- return err;
- }
-
- return 0;
- fail:
- xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
- xenbus_switch_state(dev, XenbusStateClosed);
- return -ENODEV;
-}
-
-static void xenbus_dev_free(struct xenbus_device *xendev)
-{
- LIST_REMOVE(xendev, list);
- kfree(xendev);
-}
-
-int
-xenbus_remove_device(struct xenbus_device *dev)
-{
- struct xenbus_driver *drv = dev->driver;
-
- DPRINTK("");
-
- free_otherend_watch(dev);
- free_otherend_details(dev);
-
- if (drv->remove)
- drv->remove(dev);
-
- xenbus_switch_state(dev, XenbusStateClosed);
-
- if (drv->cleanup_device)
- return drv->cleanup_device(dev);
-
- xenbus_dev_free(dev);
-
- return 0;
-}
-
-#if 0
-static int
-xenbus_dev_remove(device_t _dev)
-{
- return xenbus_remove_device(to_xenbus_device(_dev));
-}
-#endif
-
-int xenbus_register_driver_common(struct xenbus_driver *drv,
- struct xen_bus_type *bus)
-{
- struct xenbus_device *xdev;
-
-#if 0
- int ret;
- /* this all happens in the driver itself
- * doing this here simple serves to obfuscate
- */
-
- drv->driver.name = drv->name;
- drv->driver.bus = &bus->bus;
- drv->driver.owner = drv->owner;
- drv->driver.probe = xenbus_dev_probe;
- drv->driver.remove = xenbus_dev_remove;
-
- return ret;
-#endif
- sx_xlock(&xenwatch_mutex);
- LIST_INSERT_HEAD(&xendrv_list, drv, list);
- sx_xunlock(&xenwatch_mutex);
- LIST_FOREACH(xdev, bus->bus, list) {
- if (match_device(drv->ids, xdev)) {
- xdev->driver = drv;
- xenbus_dev_probe(xdev);
- }
- }
- return 0;
-}
-
-int xenbus_register_frontend(struct xenbus_driver *drv)
-{
- drv->read_otherend_details = read_backend_details;
-
- return xenbus_register_driver_common(drv, &xenbus_frontend);
-}
-EXPORT_SYMBOL(xenbus_register_frontend);
-
-
-void xenbus_unregister_driver(struct xenbus_driver *drv)
-{
-#if 0
- driver_unregister(&drv->driver);
-#endif
-}
-EXPORT_SYMBOL(xenbus_unregister_driver);
-
-struct xb_find_info
-{
- struct xenbus_device *dev;
- const char *nodename;
-};
-
-static struct xenbus_device *
-xenbus_device_find(const char *nodename, struct xendev_list_head *bus)
-{
- struct xenbus_device *xdev;
- LIST_FOREACH(xdev, bus, list) {
- if (streq(xdev->nodename, nodename)) {
- return xdev;
-#if 0
- get_device(dev);
-#endif
- }
- }
- return NULL;
-}
-#if 0
-static int cleanup_dev(device_t dev, void *data)
-{
- struct xenbus_device *xendev = device_get_softc(dev);
- struct xb_find_info *info = data;
- int len = strlen(info->nodename);
-
- DPRINTK("%s", info->nodename);
-
- if (!strncmp(xendev->nodename, info->nodename, len)) {
- info->dev = xendev;
-#if 0
- get_device(dev);
-#endif
- return 1;
- }
- return 0;
-}
-
-#endif
-static void xenbus_cleanup_devices(const char *path, struct xendev_list_head * bus)
-{
-#if 0
- struct xb_find_info info = { .nodename = path };
-
- do {
- info.dev = NULL;
- bus_for_each_dev(bus, NULL, &info, cleanup_dev);
- if (info.dev) {
- device_unregister(&info.dev->dev);
- put_device(&info.dev->dev);
- }
- } while (info.dev);
-#endif
-}
-
-#if 0
-void xenbus_dev_release(device_t dev)
-{
- /*
- * nothing to do softc gets freed with the device
- */
-
-}
-#endif
-/* Simplified asprintf. */
-char *kasprintf(const char *fmt, ...)
-{
- va_list ap;
- unsigned int len;
- char *p, dummy[1];
-
- va_start(ap, fmt);
- /* FIXME: vsnprintf has a bug, NULL should work */
- len = vsnprintf(dummy, 0, fmt, ap);
- va_end(ap);
-
- p = kmalloc(len + 1, GFP_KERNEL);
- if (!p)
- return NULL;
- va_start(ap, fmt);
- vsprintf(p, fmt, ap);
- va_end(ap);
- return p;
-}
-
-#if 0
-static ssize_t xendev_show_nodename(struct device *dev, char *buf)
-{
- return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename);
-}
-DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL);
-
-static ssize_t xendev_show_devtype(struct device *dev, char *buf)
-{
- return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype);
-}
-DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
-#endif
-
-int xenbus_probe_node(struct xen_bus_type *bus, const char *type,
- const char *nodename)
-{
-#define CHECK_FAIL \
- do { \
- if (err) \
- goto fail; \
- } while (0) \
-
-
-
- int err;
- struct xenbus_device *xendev;
- struct xenbus_driver *xdrv;
- size_t stringlen;
- char *tmpstring;
-
- XenbusState state = xenbus_read_driver_state(nodename);
-
- if (bus->error)
- return (bus->error);
-
-
- if (state != XenbusStateInitialising) {
- /* Device is not new, so ignore it. This can happen if a
- device is going away after switching to Closed. */
- return 0;
- }
-
- stringlen = strlen(nodename) + 1 + strlen(type) + 1;
- xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
- if (!xendev)
- return -ENOMEM;
- memset(xendev, 0, sizeof(*xendev));
- xendev->state = XenbusStateInitialising;
-
- /* Copy the strings into the extra space. */
-
- tmpstring = (char *)(xendev + 1);
- strcpy(tmpstring, nodename);
- xendev->nodename = tmpstring;
-
- tmpstring += strlen(tmpstring) + 1;
- strcpy(tmpstring, type);
- xendev->devicetype = tmpstring;
- /*
- * equivalent to device registration
- * events
- */
- LIST_INSERT_HEAD(bus->bus, xendev, list);
- LIST_FOREACH(xdrv, &xendrv_list, list) {
- if (match_device(xdrv->ids, xendev)) {
- xendev->driver = xdrv;
- if (!xenbus_dev_probe(xendev))
- break;
- }
- }
-
-#if 0
- xendev->dev.parent = &bus->dev;
- xendev->dev.bus = &bus->bus;
- xendev->dev.release = xenbus_dev_release;
-
- err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
- CHECK_FAIL;
-
- /* Register with generic device framework. */
- err = device_register(&xendev->dev);
- CHECK_FAIL;
-
- device_create_file(&xendev->dev, &dev_attr_nodename);
- device_create_file(&xendev->dev, &dev_attr_devtype);
-#endif
- return 0;
-
-#undef CHECK_FAIL
-#if 0
- fail:
- xenbus_dev_free(xendev);
-#endif
- return err;
-}
-
-/* device/<typename>/<name> */
-static int xenbus_probe_frontend(const char *type, const char *name)
-{
- char *nodename;
- int err;
-
- nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name);
- if (!nodename)
- return -ENOMEM;
-
- DPRINTK("%s", nodename);
-
- err = xenbus_probe_node(&xenbus_frontend, type, nodename);
- kfree(nodename);
- return err;
-}
-
-static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
-{
- int err = 0;
- char **dir;
- unsigned int dir_n = 0;
- int i;
-
- dir = xenbus_directory(XBT_NIL, bus->root, type, &dir_n);
- if (IS_ERR(dir))
- return PTR_ERR(dir);
-
- for (i = 0; i < dir_n; i++) {
- err = bus->probe(type, dir[i]);
- if (err)
- break;
- }
- kfree(dir);
- return err;
-}
-
-int xenbus_probe_devices(struct xen_bus_type *bus)
-{
- int err = 0;
- char **dir;
- unsigned int i, dir_n;
-
- dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
- if (IS_ERR(dir))
- return PTR_ERR(dir);
-
- for (i = 0; i < dir_n; i++) {
- err = xenbus_probe_device_type(bus, dir[i]);
- if (err)
- break;
- }
- kfree(dir);
-
- return err;
-}
-
-static unsigned int char_count(const char *str, char c)
-{
- unsigned int i, ret = 0;
-
- for (i = 0; str[i]; i++)
- if (str[i] == c)
- ret++;
- return ret;
-}
-
-static int strsep_len(const char *str, char c, unsigned int len)
-{
- unsigned int i;
-
- for (i = 0; str[i]; i++)
- if (str[i] == c) {
- if (len == 0)
- return i;
- len--;
- }
- return (len == 0) ? i : -ERANGE;
-}
-
-void dev_changed(const char *node, struct xen_bus_type *bus)
-{
- int exists, rootlen;
- struct xenbus_device *dev;
- char type[BUS_ID_SIZE];
- const char *p;
- char *root;
-
- DPRINTK("");
- if (char_count(node, '/') < 2)
- return;
-
- exists = xenbus_exists(XBT_NIL, node, "");
- if (!exists) {
- xenbus_cleanup_devices(node, bus->bus);
- return;
- }
-
- /* backend/<type>/... or device/<type>/... */
- p = strchr(node, '/') + 1;
- snprintf(type, BUS_ID_SIZE, "%.*s", (int)strcspn(p, "/"), p);
- type[BUS_ID_SIZE-1] = '\0';
-
- rootlen = strsep_len(node, '/', bus->levels);
- if (rootlen < 0)
- return;
- root = kasprintf("%.*s", rootlen, node);
- if (!root)
- return;
-
- dev = xenbus_device_find(root, bus->bus);
- if (!dev)
- xenbus_probe_node(bus, type, root);
-#if 0
- else
- put_device(&dev->dev);
-#endif
- kfree(root);
-}
-
-static void frontend_changed(struct xenbus_watch *watch,
- const char **vec, unsigned int len)
-{
- DPRINTK("");
-
- dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend);
-}
-
-/* We watch for devices appearing and vanishing. */
-static struct xenbus_watch fe_watch = {
- .node = "device",
- .callback = frontend_changed,
-};
-
-#ifdef notyet
-
-static int suspend_dev(device_t dev, void *data)
-{
- int err = 0;
- struct xenbus_driver *drv;
- struct xenbus_device *xdev;
-
- DPRINTK("");
-
- xdev = device_get_softc(dev);
-
- drv = xdev->driver;
-
- if (device_get_driver(dev) == NULL)
- return 0;
-
- if (drv->suspend)
- err = drv->suspend(xdev);
-#if 0
- /* bus_id ? */
- if (err)
- log(LOG_WARNING, "xenbus: suspend %s failed: %i\n",
- dev->bus_id, err);
-#endif
- return 0;
-}
-
-
-
-static int resume_dev(device_t dev, void *data)
-{
- int err;
- struct xenbus_driver *drv;
- struct xenbus_device *xdev;
-
- DPRINTK("");
-
- if (device_get_driver(dev) == NULL)
- return 0;
- xdev = device_get_softc(dev);
- drv = xdev->driver;
-
- err = talk_to_otherend(xdev);
-#if 0
- if (err) {
- log(LOG_WARNING,
- "xenbus: resume (talk_to_otherend) %s failed: %i\n",
- dev->bus_id, err);
- return err;
- }
-#endif
- if (drv->resume)
- err = drv->resume(xdev);
-
- err = watch_otherend(xdev);
-#if 0
- /* bus_id? */
- if (err)
- log(LOG_WARNING,
- "xenbus: resume %s failed: %i\n", dev->bus_id, err);
-#endif
- return err;
-}
-
-#endif
-void xenbus_suspend(void)
-{
- DPRINTK("");
- panic("implement me");
-#if 0
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
-#endif
- xs_suspend();
-}
-EXPORT_SYMBOL(xenbus_suspend);
-
-void xenbus_resume(void)
-{
- xb_init_comms();
- xs_resume();
- panic("implement me");
-#if 0
- bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev);
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev);
-#endif
-}
-EXPORT_SYMBOL(xenbus_resume);
-
-#if 0
-static device_t
-xenbus_add_child(device_t bus, int order, const char *name, int unit)
-{
- device_t child;
-
- child = device_add_child_ordered(bus, order, name, unit);
-
- return(child);
-}
-#endif
-
-/* A flag to determine if xenstored is 'ready' (i.e. has started) */
-int xenstored_ready = 0;
-
-
-int register_xenstore_notifier(xenstore_event_handler_t func, void *arg, int priority)
-{
- int ret = 0;
-
- if (xenstored_ready > 0)
- ret = func(NULL);
- else
- eventhandler_register(xenstore_chain, "xenstore", func, arg, priority);
-
- return ret;
-}
-EXPORT_SYMBOL(register_xenstore_notifier);
-#if 0
-void unregister_xenstore_notifier(struct notifier_block *nb)
-{
- notifier_chain_unregister(&xenstore_chain, nb);
-}
-EXPORT_SYMBOL(unregister_xenstore_notifier);
-#endif
-
-
-
-#ifdef DOM0
-static struct proc_dir_entry *xsd_mfn_intf;
-static struct proc_dir_entry *xsd_port_intf;
-
-
-static int xsd_mfn_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len;
- len = sprintf(page, "%ld", xen_start_info->store_mfn);
- *eof = 1;
- return len;
-}
-
-static int xsd_port_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len;
-
- len = sprintf(page, "%d", xen_start_info->store_evtchn);
- *eof = 1;
- return len;
-}
-
-#endif
-
-static int dom0 = 0;
-
-static int
-xenbus_probe_sysinit(void *unused)
-{
- int err = 0;
-
- DPRINTK("");
-
- LIST_INIT(&xenbus_device_frontend_list);
- LIST_INIT(&xenbus_device_backend_list);
- LIST_INIT(&xendrv_list);
-#if 0
- if (xen_init() < 0) {
- DPRINTK("failed");
- return -ENODEV;
- }
-
-
- /* Register ourselves with the kernel bus & device subsystems */
- bus_register(&xenbus_frontend.bus);
- bus_register(&xenbus_backend.bus);
- device_register(&xenbus_frontend.dev);
- device_register(&xenbus_backend.dev);
-#endif
-
- /*
- ** Domain0 doesn't have a store_evtchn or store_mfn yet.
- */
- dom0 = (xen_start_info->store_evtchn == 0);
-
-
-#ifdef DOM0
- if (dom0) {
-
- unsigned long page;
- evtchn_op_t op = { 0 };
- int ret;
-
-
- /* Allocate page. */
- page = get_zeroed_page(GFP_KERNEL);
- if (!page)
- return -ENOMEM;
-
- /* We don't refcnt properly, so set reserved on page.
- * (this allocation is permanent) */
- SetPageReserved(virt_to_page(page));
-
- xen_start_info->store_mfn =
- pfn_to_mfn(virt_to_phys((void *)page) >>
- PAGE_SHIFT);
-
- /* Next allocate a local port which xenstored can bind to */
- op.cmd = EVTCHNOP_alloc_unbound;
- op.u.alloc_unbound.dom = DOMID_SELF;
- op.u.alloc_unbound.remote_dom = 0;
-
- ret = HYPERVISOR_event_channel_op(&op);
- BUG_ON(ret);
- xen_start_info->store_evtchn = op.u.alloc_unbound.port;
-
- /* And finally publish the above info in /proc/xen */
- if((xsd_mfn_intf = create_xen_proc_entry("xsd_mfn", 0400)))
- xsd_mfn_intf->read_proc = xsd_mfn_read;
- if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400)))
- xsd_port_intf->read_proc = xsd_port_read;
- }
-#endif
- /* Initialize the interface to xenstore. */
- err = xs_init();
- if (err) {
- log(LOG_WARNING,
- "XENBUS: Error initializing xenstore comms: %i\n", err);
- return err;
- }
-
- return 0;
-}
-
-
-static int
-xenbus_probe_sysinit2(void *unused)
-{
- if (!dom0) {
- xenstored_ready = 1;
-#if 0
- xenbus_dev = BUS_ADD_CHILD(parent, 0, "xenbus", 0);
- if (xenbus_dev == NULL)
- panic("xenbus: could not attach");
- xenbus_backend_dev = BUS_ADD_CHILD(parent, 0, "xb_be", 0);
- if (xenbus_backend_dev == NULL)
- panic("xenbus: could not attach");
-#endif
- BUG_ON((xenstored_ready <= 0));
-
-
-
- /* Enumerate devices in xenstore. */
- xenbus_probe_devices(&xenbus_frontend);
- register_xenbus_watch(&fe_watch);
- xenbus_backend_probe_and_watch();
-
- /* Notify others that xenstore is up */
- EVENTHANDLER_INVOKE(xenstore_event);
- }
- return (0);
-}
-
-
-SYSINIT(xenbus_probe_sysinit, SI_SUB_PSEUDO, SI_ORDER_FIRST, xenbus_probe_sysinit, NULL);
-SYSINIT(xenbus_probe_sysinit2, SI_SUB_PSEUDO, SI_ORDER_ANY,
- xenbus_probe_sysinit2, NULL);
-
-#if 0
-static device_method_t xenbus_methods[] = {
- /* Device interface */
-#if 0
- DEVMETHOD(device_identify, xenbus_identify),
- DEVMETHOD(device_probe, xenbus_probe),
- DEVMETHOD(device_attach, xenbus_attach),
-
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-#endif
- DEVMETHOD(device_suspend, xenbus_suspend),
- DEVMETHOD(device_resume, xenbus_resume),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_add_child, xenbus_add_child),
- DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
- DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
-#if 0
- DEVMETHOD(bus_set_resource, bus_generic_set_resource),
- DEVMETHOD(bus_get_resource, bus_generic_get_resource),
-#endif
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_release_resource),
-#if 0
- DEVMETHOD(bus_delete_resource, bus_generic_delete_resource),
-#endif
- DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
- DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
- DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
-
- { 0, 0 }
-};
-
-static char driver_name[] = "xenbus";
-static driver_t xenbus_driver = {
- driver_name,
- xenbus_methods,
- sizeof(struct xenbus_device),
-};
-devclass_t xenbus_devclass;
-
-DRIVER_MODULE(xenbus, nexus, xenbus_driver, xenbus_devclass, 0, 0);
-
-#endif
-
-
-
-
-
-/*
- * Local variables:
- * c-file-style: "bsd"
- * indent-tabs-mode: t
- * c-indent-level: 4
- * c-basic-offset: 8
- * tab-width: 4
- * End:
- */
diff --git a/sys/xen/xenbus/xenbus_probe_backend.c b/sys/xen/xenbus/xenbus_probe_backend.c
deleted file mode 100644
index 3cb8e67..0000000
--- a/sys/xen/xenbus/xenbus_probe_backend.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/******************************************************************************
- * Talks to Xen Store to figure out what devices we have (backend half).
- *
- * Copyright (C) 2005 Rusty Russell, IBM Corporation
- * Copyright (C) 2005 Mike Wray, Hewlett-Packard
- * Copyright (C) 2005, 2006 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.
- */
-#if 0
-#define DPRINTK(fmt, args...) \
- printf("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
-#else
-#define DPRINTK(fmt, args...) ((void)0)
-#endif
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/time.h>
-#include <sys/sema.h>
-#include <sys/eventhandler.h>
-#include <sys/errno.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/systm.h>
-#include <sys/syslog.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/sx.h>
-
-#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xenbus.h>
-#include <machine/xen/evtchn.h>
-#include <machine/stdarg.h>
-
-#include <xen/xenbus/xenbus_comms.h>
-
-#define BUG_ON PANIC_IF
-#define semaphore sema
-#define rw_semaphore sema
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define DECLARE_MUTEX(lock) struct sema lock
-#define u32 uint32_t
-#define list_del(head, ent) TAILQ_REMOVE(head, ent, list)
-#define simple_strtoul strtoul
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#define list_empty TAILQ_EMPTY
-
-extern struct xendev_list_head xenbus_device_backend_list;
-#if 0
-static int xenbus_uevent_backend(struct device *dev, char **envp,
- int num_envp, char *buffer, int buffer_size);
-#endif
-static int xenbus_probe_backend(const char *type, const char *domid);
-
-static int read_frontend_details(struct xenbus_device *xendev)
-{
- return read_otherend_details(xendev, "frontend-id", "frontend");
-}
-
-/* backend/<type>/<fe-uuid>/<id> => <type>-<fe-domid>-<id> */
-static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
-{
- int domid, err;
- const char *devid, *type, *frontend;
- unsigned int typelen;
-
- type = strchr(nodename, '/');
- if (!type)
- return -EINVAL;
- type++;
- typelen = strcspn(type, "/");
- if (!typelen || type[typelen] != '/')
- return -EINVAL;
-
- devid = strrchr(nodename, '/') + 1;
-
- err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
- "frontend", NULL, &frontend,
- NULL);
- if (err)
- return err;
- if (strlen(frontend) == 0)
- err = -ERANGE;
- if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
- err = -ENOENT;
- kfree(frontend);
-
- if (err)
- return err;
-
- if (snprintf(bus_id, BUS_ID_SIZE,
- "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
- return -ENOSPC;
- return 0;
-}
-
-static struct xen_bus_type xenbus_backend = {
- .root = "backend",
- .levels = 3, /* backend/type/<frontend>/<id> */
- .get_bus_id = backend_bus_id,
- .probe = xenbus_probe_backend,
- .bus = &xenbus_device_backend_list,
-
-#if 0
- .error = -ENODEV,
- .bus = {
- .name = "xen-backend",
- .match = xenbus_match,
- .probe = xenbus_dev_probe,
- .remove = xenbus_dev_remove,
-// .shutdown = xenbus_dev_shutdown,
- .uevent = xenbus_uevent_backend,
- },
- .dev = {
- .bus_id = "xen-backend",
- },
-#endif
-};
-
-#if 0
-static int xenbus_uevent_backend(struct device *dev, char **envp,
- int num_envp, char *buffer, int buffer_size)
-{
- struct xenbus_device *xdev;
- struct xenbus_driver *drv;
- int i = 0;
- int length = 0;
-
- DPRINTK("");
-
- if (dev == NULL)
- return -ENODEV;
-
- xdev = to_xenbus_device(dev);
- if (xdev == NULL)
- return -ENODEV;
-2
- /* stuff we want to pass to /sbin/hotplug */
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "XENBUS_TYPE=%s", xdev->devicetype);
-
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "XENBUS_PATH=%s", xdev->nodename);
-
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "XENBUS_BASE_PATH=%s", xenbus_backend.root);
-
- /* terminate, set to next free slot, shrink available space */
- envp[i] = NULL;
- envp = &envp[i];
- num_envp -= i;
- buffer = &buffer[length];
- buffer_size -= length;
-
- if (dev->driver) {
- drv = to_xenbus_driver(dev->driver);
- if (drv && drv->uevent)
- return drv->uevent(xdev, envp, num_envp, buffer,
- buffer_size);
- }
-
- return 0;
-}
-#endif
-
-int xenbus_register_backend(struct xenbus_driver *drv)
-{
- drv->read_otherend_details = read_frontend_details;
-
- return xenbus_register_driver_common(drv, &xenbus_backend);
-}
-
-/* backend/<typename>/<frontend-uuid>/<name> */
-static int xenbus_probe_backend_unit(const char *dir,
- const char *type,
- const char *name)
-{
- char *nodename;
- int err;
-
- nodename = kasprintf("%s/%s", dir, name);
- if (!nodename)
- return -ENOMEM;
-
- DPRINTK("%s\n", nodename);
-
- err = xenbus_probe_node(&xenbus_backend, type, nodename);
- kfree(nodename);
- return err;
-}
-
-/* backend/<typename>/<frontend-domid> */
-static int xenbus_probe_backend(const char *type, const char *domid)
-{
- char *nodename;
- int err = 0;
- char **dir;
- unsigned int i, dir_n = 0;
-
- DPRINTK("");
-
- nodename = kasprintf("%s/%s/%s", xenbus_backend.root, type, domid);
- if (!nodename)
- return -ENOMEM;
-
- dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
- if (IS_ERR(dir)) {
- kfree(nodename);
- return PTR_ERR(dir);
- }
-
- for (i = 0; i < dir_n; i++) {
- err = xenbus_probe_backend_unit(nodename, type, dir[i]);
- if (err)
- break;
- }
- kfree(dir);
- kfree(nodename);
- return err;
-}
-
-static void backend_changed(struct xenbus_watch *watch,
- const char **vec, unsigned int len)
-{
- DPRINTK("");
-
- dev_changed(vec[XS_WATCH_PATH], &xenbus_backend);
-}
-
-static struct xenbus_watch be_watch = {
- .node = "backend",
- .callback = backend_changed,
-};
-#if 0
-void xenbus_backend_suspend(int (*fn)(struct device *, void *))
-{
- DPRINTK("");
- if (!xenbus_backend.error)
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
-}
-
-void xenbus_backend_resume(int (*fn)(struct device *, void *))
-{
- DPRINTK("");
- if (!xenbus_backend.error)
- bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, fn);
-}
-#endif
-void xenbus_backend_probe_and_watch(void)
-{
- xenbus_probe_devices(&xenbus_backend);
- register_xenbus_watch(&be_watch);
-}
-
-#if 0
-void xenbus_backend_bus_register(void)
-{
- xenbus_backend.error = bus_register(&xenbus_backend.bus);
- if (xenbus_backend.error)
- log(LOG_WARNING,
- "XENBUS: Error registering backend bus: %i\n",
- xenbus_backend.error);
-}
-
-void xenbus_backend_device_register(void)
-{
- if (xenbus_backend.error)
- return;
-
- xenbus_backend.error = device_register(&xenbus_backend.dev);
- if (xenbus_backend.error) {
- bus_unregister(&xenbus_backend.bus);
- log(LOG_WARNING,
- "XENBUS: Error registering backend device: %i\n",
- xenbus_backend.error);
- }
-}
-#endif
diff --git a/sys/xen/xenbus/xenbus_xs.c b/sys/xen/xenbus/xenbus_xs.c
deleted file mode 100644
index 90c32e1..0000000
--- a/sys/xen/xenbus/xenbus_xs.c
+++ /dev/null
@@ -1,960 +0,0 @@
-/******************************************************************************
- * xenbus_xs.c
- *
- * This is the kernel equivalent of the "xs" library. We don't need everything
- * and we use xenbus_comms for communication.
- *
- * Copyright (C) 2005 Rusty Russell, IBM Corporation
- *
- * 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 <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <sys/unistd.h>
-#include <sys/errno.h>
-#include <sys/uio.h>
-#include <sys/kernel.h>
-#include <sys/time.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/sx.h>
-#include <sys/sema.h>
-#include <sys/syslog.h>
-#include <sys/malloc.h>
-#include <sys/libkern.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/kthread.h>
-
-#include <machine/xen/xen-os.h>
-#include <machine/xen/hypervisor.h>
-#include <machine/xen/xenbus.h>
-#include <machine/stdarg.h>
-
-#include <xen/xenbus/xenbus_comms.h>
-static int xs_process_msg(enum xsd_sockmsg_type *type);
-
-#define kmalloc(size, unused) malloc(size, M_DEVBUF, M_WAITOK)
-#define BUG_ON PANIC_IF
-#define DEFINE_SPINLOCK(lock) struct mtx lock
-#define u32 uint32_t
-#define list_del(head, ent) TAILQ_REMOVE(head, ent, list)
-#define simple_strtoul strtoul
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#define list_empty TAILQ_EMPTY
-
-#define streq(a, b) (strcmp((a), (b)) == 0)
-int xenwatch_running = 0;
-int xenbus_running = 0;
-
-struct kvec {
- const void *iov_base;
- size_t iov_len;
-};
-
-struct xs_stored_msg {
- TAILQ_ENTRY(xs_stored_msg) list;
-
- struct xsd_sockmsg hdr;
-
- union {
- /* Queued replies. */
- struct {
- char *body;
- } reply;
-
- /* Queued watch events. */
- struct {
- struct xenbus_watch *handle;
- char **vec;
- unsigned int vec_size;
- } watch;
- } u;
-};
-
-struct xs_handle {
- /* A list of replies. Currently only one will ever be outstanding. */
- TAILQ_HEAD(xs_handle_list, xs_stored_msg) reply_list;
- struct mtx reply_lock;
- int reply_waitq;
-
- /* One request at a time. */
- struct sx request_mutex;
-
- /* Protect transactions against save/restore. */
- struct sx suspend_mutex;
-};
-
-static struct xs_handle xs_state;
-
-/* List of registered watches, and a lock to protect it. */
-static LIST_HEAD(watch_list_head, xenbus_watch) watches;
-static DEFINE_SPINLOCK(watches_lock);
-/* List of pending watch callback events, and a lock to protect it. */
-static TAILQ_HEAD(event_list_head, xs_stored_msg) watch_events;
-static DEFINE_SPINLOCK(watch_events_lock);
-/*
- * Details of the xenwatch callback kernel thread. The thread waits on the
- * watch_events_waitq for work to do (queued on watch_events list). When it
- * wakes up it acquires the xenwatch_mutex before reading the list and
- * carrying out work.
- */
-static pid_t xenwatch_pid;
-struct sx xenwatch_mutex;
-static int watch_events_waitq;
-
-static int get_error(const char *errorstring)
-{
- unsigned int i;
-
- for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) {
- if (i == ARRAY_SIZE(xsd_errors) - 1) {
- log(LOG_WARNING, "XENBUS xen store gave: unknown error %s",
- errorstring);
- return EINVAL;
- }
- }
- return xsd_errors[i].errnum;
-}
-
-extern void idle_block(void);
-extern void kdb_backtrace(void);
-
-static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
-{
- struct xs_stored_msg *msg;
- char *body;
- int i, err;
- enum xsd_sockmsg_type itype = *type;
-
- printf("read_reply ");
- if (xenbus_running == 0) {
- /*
- * Give other domain time to run :-/
- */
- for (i = 0; i < 1000000 && (xenbus_running == 0); i++) {
- err = xs_process_msg(type);
-
- if ((err == 0)
- && (*type != XS_WATCH_EVENT))
- break;
-
- HYPERVISOR_yield();
- }
-
- if (list_empty(&xs_state.reply_list)) {
- printf("giving up and returning an error type=%d\n",
- *type);
- kdb_backtrace();
- return (ERR_PTR(-1));
- }
-
- }
-
- mtx_lock(&xs_state.reply_lock);
- if (xenbus_running) {
- while (list_empty(&xs_state.reply_list)) {
- mtx_unlock(&xs_state.reply_lock);
- wait_event_interruptible(&xs_state.reply_waitq,
- !list_empty(&xs_state.reply_list));
-
- mtx_lock(&xs_state.reply_lock);
- }
- }
-
- msg = TAILQ_FIRST(&xs_state.reply_list);
- list_del(&xs_state.reply_list, msg);
-
- mtx_unlock(&xs_state.reply_lock);
-
- printf("itype=%d htype=%d ", itype, msg->hdr.type);
- *type = msg->hdr.type;
- if (len)
- *len = msg->hdr.len;
- body = msg->u.reply.body;
-
- kfree(msg);
- if (len)
- printf("len=%d\n", *len);
- else
- printf("len=NULL\n");
- return body;
-}
-
-#if 0
-/* Emergency write. UNUSED*/
-void xenbus_debug_write(const char *str, unsigned int count)
-{
- struct xsd_sockmsg msg = { 0 };
-
- msg.type = XS_DEBUG;
- msg.len = sizeof("print") + count + 1;
-
- sx_xlock(&xs_state.request_mutex);
- xb_write(&msg, sizeof(msg));
- xb_write("print", sizeof("print"));
- xb_write(str, count);
- xb_write("", 1);
- sx_xunlock(&xs_state.request_mutex);
-}
-
-#endif
-void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
-{
- void *ret;
- struct xsd_sockmsg req_msg = *msg;
- int err;
-
- if (req_msg.type == XS_TRANSACTION_START)
- sx_slock(&xs_state.suspend_mutex);
-
- sx_xlock(&xs_state.request_mutex);
-
- err = xb_write(msg, sizeof(*msg) + msg->len);
- if (err) {
- msg->type = XS_ERROR;
- ret = ERR_PTR(err);
- } else {
- ret = read_reply(&msg->type, &msg->len);
- }
-
- sx_xunlock(&xs_state.request_mutex);
-
- if ((msg->type == XS_TRANSACTION_END) ||
- ((req_msg.type == XS_TRANSACTION_START) &&
- (msg->type == XS_ERROR)))
- sx_sunlock(&xs_state.suspend_mutex);
-
- return ret;
-}
-
-static int xenwatch_inline;
-
-/* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
-static void *xs_talkv(struct xenbus_transaction t,
- enum xsd_sockmsg_type type,
- const struct kvec *iovec,
- unsigned int num_vecs,
- unsigned int *len)
-{
- struct xsd_sockmsg msg;
- void *ret = NULL;
- unsigned int i;
- int err;
-
- msg.tx_id = t.id;
- msg.req_id = 0;
- msg.type = type;
- msg.len = 0;
- for (i = 0; i < num_vecs; i++)
- msg.len += iovec[i].iov_len;
-
- printf("xs_talkv ");
-
- sx_xlock(&xs_state.request_mutex);
-
- err = xb_write(&msg, sizeof(msg));
- if (err) {
- sx_xunlock(&xs_state.request_mutex);
- printf("xs_talkv failed %d\n", err);
- return ERR_PTR(err);
- }
-
- for (i = 0; i < num_vecs; i++) {
- err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
- if (err) {
- sx_xunlock(&xs_state.request_mutex);
- printf("xs_talkv failed %d\n", err);
- return ERR_PTR(err);
- }
- }
-
- ret = read_reply(&msg.type, len);
-
- sx_xunlock(&xs_state.request_mutex);
-
- if (IS_ERR(ret))
- return ret;
-
- if (msg.type == XS_ERROR) {
- err = get_error(ret);
- kfree(ret);
- return ERR_PTR(-err);
- }
-
- if ((xenwatch_running == 0) && (xenwatch_inline == 0)) {
- xenwatch_inline = 1;
- while (!TAILQ_EMPTY(&watch_events)
- && xenwatch_running == 0) {
-
- struct xs_stored_msg *wmsg = TAILQ_FIRST(&watch_events);
- list_del(&watch_events, wmsg);
- printf("handling %p ...", wmsg->u.watch.handle->callback);
-
- wmsg->u.watch.handle->callback(
- wmsg->u.watch.handle,
- (const char **)wmsg->u.watch.vec,
- wmsg->u.watch.vec_size);
- printf("... %p done\n", wmsg->u.watch.handle->callback);
- kfree(wmsg->u.watch.vec);
- kfree(wmsg);
- }
- xenwatch_inline = 0;
- }
- BUG_ON(msg.type != type);
-
- return ret;
-}
-
-/* Simplified version of xs_talkv: single message. */
-static void *xs_single(struct xenbus_transaction t,
- enum xsd_sockmsg_type type,
- const char *string,
- unsigned int *len)
-{
- struct kvec iovec;
-
- printf("xs_single %s ", string);
- iovec.iov_base = (const void *)string;
- iovec.iov_len = strlen(string) + 1;
- return xs_talkv(t, type, &iovec, 1, len);
-}
-
-/* Many commands only need an ack, don't care what it says. */
-static int xs_error(char *reply)
-{
- if (IS_ERR(reply))
- return PTR_ERR(reply);
- kfree(reply);
- return 0;
-}
-
-static unsigned int count_strings(const char *strings, unsigned int len)
-{
- unsigned int num;
- const char *p;
-
- for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
- num++;
-
- return num;
-}
-
-/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */
-static char *join(const char *dir, const char *name)
-{
- char *buffer;
-
- buffer = kmalloc(strlen(dir) + strlen("/") + strlen(name) + 1,
- GFP_KERNEL);
- if (buffer == NULL)
- return ERR_PTR(-ENOMEM);
-
- strcpy(buffer, dir);
- if (!streq(name, "")) {
- strcat(buffer, "/");
- strcat(buffer, name);
- }
-
- return buffer;
-}
-
-static char **split(char *strings, unsigned int len, unsigned int *num)
-{
- char *p, **ret;
-
- /* Count the strings. */
- *num = count_strings(strings, len) + 1;
-
- /* Transfer to one big alloc for easy freeing. */
- ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL);
- if (!ret) {
- kfree(strings);
- return ERR_PTR(-ENOMEM);
- }
- memcpy(&ret[*num], strings, len);
- kfree(strings);
-
- strings = (char *)&ret[*num];
- for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
- ret[(*num)++] = p;
-
- ret[*num] = strings + len;
-
- return ret;
-}
-
-char **xenbus_directory(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *num)
-{
- char *strings, *path;
- unsigned int len = 0;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return (char **)path;
-
- strings = xs_single(t, XS_DIRECTORY, path, &len);
- kfree(path);
- if (IS_ERR(strings))
- return (char **)strings;
-
- return split(strings, len, num);
-}
-EXPORT_SYMBOL(xenbus_directory);
-
-/* Check if a path exists. Return 1 if it does. */
-int xenbus_exists(struct xenbus_transaction t,
- const char *dir, const char *node)
-{
- char **d;
- int dir_n;
-
- d = xenbus_directory(t, dir, node, &dir_n);
- if (IS_ERR(d))
- return 0;
- kfree(d);
- return 1;
-}
-EXPORT_SYMBOL(xenbus_exists);
-
-/* Get the value of a single file.
- * Returns a kmalloced value: call free() on it after use.
- * len indicates length in bytes.
- */
-void *xenbus_read(struct xenbus_transaction t,
- const char *dir, const char *node, unsigned int *len)
-{
- char *path;
- void *ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return (void *)path;
-
- printf("xs_read ");
- ret = xs_single(t, XS_READ, path, len);
- kfree(path);
- return ret;
-}
-EXPORT_SYMBOL(xenbus_read);
-
-/* Write the value of a single file.
- * Returns -err on failure.
- */
-int xenbus_write(struct xenbus_transaction t,
- const char *dir, const char *node, const char *string)
-{
- char *path;
- struct kvec iovec[2];
- int ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
-
- iovec[0].iov_base = path;
- iovec[0].iov_len = strlen(path) + 1;
- iovec[1].iov_base = string;
- iovec[1].iov_len = strlen(string);
-
- printf("xenbus_write dir=%s val=%s ", dir, string);
- ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
- kfree(path);
- return ret;
-}
-EXPORT_SYMBOL(xenbus_write);
-
-/* Create a new directory. */
-int xenbus_mkdir(struct xenbus_transaction t,
- const char *dir, const char *node)
-{
- char *path;
- int ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
-
- ret = xs_error(xs_single(t, XS_MKDIR, path, NULL));
- kfree(path);
- return ret;
-}
-EXPORT_SYMBOL(xenbus_mkdir);
-
-/* Destroy a file or directory (directories must be empty). */
-int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node)
-{
- char *path;
- int ret;
-
- path = join(dir, node);
- if (IS_ERR(path))
- return PTR_ERR(path);
-
- ret = xs_error(xs_single(t, XS_RM, path, NULL));
- kfree(path);
- return ret;
-}
-EXPORT_SYMBOL(xenbus_rm);
-
-/* Start a transaction: changes by others will not be seen during this
- * transaction, and changes will not be visible to others until end.
- */
-int xenbus_transaction_start(struct xenbus_transaction *t)
-{
- char *id_str;
-
- sx_slock(&xs_state.suspend_mutex);
- id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL);
- if (IS_ERR(id_str)) {
- sx_sunlock(&xs_state.suspend_mutex);
- return PTR_ERR(id_str);
- }
-
- t->id = simple_strtoul(id_str, NULL, 0);
- kfree(id_str);
-
- return 0;
-}
-EXPORT_SYMBOL(xenbus_transaction_start);
-
-/* End a transaction.
- * If abandon is true, transaction is discarded instead of committed.
- */
-int xenbus_transaction_end(struct xenbus_transaction t, int abort)
-{
- char abortstr[2];
- int err;
-
- if (abort)
- strcpy(abortstr, "F");
- else
- strcpy(abortstr, "T");
-
- printf("xenbus_transaction_end ");
- err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
-
- sx_sunlock(&xs_state.suspend_mutex);
-
- return err;
-}
-EXPORT_SYMBOL(xenbus_transaction_end);
-
-/* Single read and scanf: returns -errno or num scanned. */
-int xenbus_scanf(struct xenbus_transaction t,
- const char *dir, const char *node, const char *fmt, ...)
-{
- va_list ap;
- int ret;
- char *val;
-
- val = xenbus_read(t, dir, node, NULL);
- if (IS_ERR(val))
- return PTR_ERR(val);
-
- va_start(ap, fmt);
- ret = vsscanf(val, fmt, ap);
- va_end(ap);
- kfree(val);
- /* Distinctive errno. */
- if (ret == 0)
- return -ERANGE;
- return ret;
-}
-EXPORT_SYMBOL(xenbus_scanf);
-
-/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction t,
- const char *dir, const char *node, const char *fmt, ...)
-{
- va_list ap;
- int ret;
-#define PRINTF_BUFFER_SIZE 4096
- char *printf_buffer;
-
- printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
- if (printf_buffer == NULL)
- return -ENOMEM;
-
- va_start(ap, fmt);
- ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
- va_end(ap);
-
- BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
- ret = xenbus_write(t, dir, node, printf_buffer);
-
- kfree(printf_buffer);
-
- return ret;
-}
-EXPORT_SYMBOL(xenbus_printf);
-
-/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xenbus_gather(struct xenbus_transaction t, const char *dir, ...)
-{
- va_list ap;
- const char *name;
- int i, ret = 0;
-
- for (i = 0; i < 10000; i++)
- HYPERVISOR_yield();
-
- printf("gather ");
- va_start(ap, dir);
- while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
- const char *fmt = va_arg(ap, char *);
- void *result = va_arg(ap, void *);
- char *p;
-
- p = xenbus_read(t, dir, name, NULL);
- if (IS_ERR(p)) {
- ret = PTR_ERR(p);
- break;
- }
- printf(" %s ", p);
- if (fmt) {
- if (sscanf(p, fmt, result) == 0)
- ret = -EINVAL;
- kfree(p);
- } else
- *(char **)result = p;
- }
- va_end(ap);
- printf("\n");
- return ret;
-}
-EXPORT_SYMBOL(xenbus_gather);
-
-static int xs_watch(const char *path, const char *token)
-{
- struct kvec iov[2];
-
- iov[0].iov_base = path;
- iov[0].iov_len = strlen(path) + 1;
- iov[1].iov_base = token;
- iov[1].iov_len = strlen(token) + 1;
-
- return xs_error(xs_talkv(XBT_NIL, XS_WATCH, iov,
- ARRAY_SIZE(iov), NULL));
-}
-
-static int xs_unwatch(const char *path, const char *token)
-{
- struct kvec iov[2];
-
- iov[0].iov_base = path;
- iov[0].iov_len = strlen(path) + 1;
- iov[1].iov_base = token;
- iov[1].iov_len = strlen(token) + 1;
-
- return xs_error(xs_talkv(XBT_NIL, XS_UNWATCH, iov,
- ARRAY_SIZE(iov), NULL));
-}
-
-static struct xenbus_watch *find_watch(const char *token)
-{
- struct xenbus_watch *i, *cmp;
-
- cmp = (void *)simple_strtoul(token, NULL, 16);
-
- LIST_FOREACH(i, &watches, list)
- if (i == cmp)
- return i;
-
- return NULL;
-}
-
-/* Register callback to watch this node. */
-int register_xenbus_watch(struct xenbus_watch *watch)
-{
- /* Pointer in ascii is the token. */
- char token[sizeof(watch) * 2 + 1];
- int err;
-
- sprintf(token, "%lX", (long)watch);
-
- sx_slock(&xs_state.suspend_mutex);
-
- mtx_lock(&watches_lock);
- BUG_ON(find_watch(token) != NULL);
- LIST_INSERT_HEAD(&watches, watch, list);
- mtx_unlock(&watches_lock);
-
- err = xs_watch(watch->node, token);
-
- /* Ignore errors due to multiple registration. */
- if ((err != 0) && (err != -EEXIST)) {
- mtx_lock(&watches_lock);
- LIST_REMOVE(watch, list);
- mtx_unlock(&watches_lock);
- }
-
- sx_sunlock(&xs_state.suspend_mutex);
-
- return err;
-}
-EXPORT_SYMBOL(register_xenbus_watch);
-
-void unregister_xenbus_watch(struct xenbus_watch *watch)
-{
- struct xs_stored_msg *msg, *tmp;
- char token[sizeof(watch) * 2 + 1];
- int err;
-
- sprintf(token, "%lX", (long)watch);
-
- sx_slock(&xs_state.suspend_mutex);
-
- mtx_lock(&watches_lock);
- BUG_ON(!find_watch(token));
- LIST_REMOVE(watch, list);
- mtx_unlock(&watches_lock);
-
- err = xs_unwatch(watch->node, token);
- if (err)
- log(LOG_WARNING, "XENBUS Failed to release watch %s: %i\n",
- watch->node, err);
-
- sx_sunlock(&xs_state.suspend_mutex);
-
- /* Cancel pending watch events. */
- mtx_lock(&watch_events_lock);
- TAILQ_FOREACH_SAFE(msg, &watch_events, list, tmp) {
- if (msg->u.watch.handle != watch)
- continue;
- list_del(&watch_events, msg);
- kfree(msg->u.watch.vec);
- kfree(msg);
- }
- mtx_unlock(&watch_events_lock);
-
- /* Flush any currently-executing callback, unless we are it. :-) */
- if (curproc->p_pid != xenwatch_pid) {
- sx_xlock(&xenwatch_mutex);
- sx_xunlock(&xenwatch_mutex);
- }
-}
-EXPORT_SYMBOL(unregister_xenbus_watch);
-
-void xs_suspend(void)
-{
- sx_xlock(&xs_state.suspend_mutex);
- sx_xlock(&xs_state.request_mutex);
-}
-
-void xs_resume(void)
-{
- struct xenbus_watch *watch;
- char token[sizeof(watch) * 2 + 1];
-
- sx_xunlock(&xs_state.request_mutex);
-
- /* No need for watches_lock: the suspend_mutex is sufficient. */
- LIST_FOREACH(watch, &watches, list) {
- sprintf(token, "%lX", (long)watch);
- xs_watch(watch->node, token);
- }
-
- sx_xunlock(&xs_state.suspend_mutex);
-}
-
-static void xenwatch_thread(void *unused)
-{
- struct xs_stored_msg *msg;
-
- xenwatch_running = 1;
-
- DELAY(100000);
- while (xenwatch_inline) {
- printf("xenwatch inline still running\n");
- DELAY(100000);
- }
-
-
- for (;;) {
-
- while (list_empty(&watch_events))
- tsleep(&watch_events_waitq,
- PWAIT | PCATCH, "waitev", hz/10);
-
- sx_xlock(&xenwatch_mutex);
-
- mtx_lock(&watch_events_lock);
- msg = TAILQ_FIRST(&watch_events);
- if (msg)
- list_del(&watch_events, msg);
- mtx_unlock(&watch_events_lock);
-
- if (msg != NULL) {
- msg->u.watch.handle->callback(
- msg->u.watch.handle,
- (const char **)msg->u.watch.vec,
- msg->u.watch.vec_size);
- kfree(msg->u.watch.vec);
- kfree(msg);
- }
-
- sx_xunlock(&xenwatch_mutex);
- }
-}
-
-static int xs_process_msg(enum xsd_sockmsg_type *type)
-{
- struct xs_stored_msg *msg;
- char *body;
- int err;
-
- msg = kmalloc(sizeof(*msg), GFP_KERNEL);
- if (msg == NULL)
- return -ENOMEM;
-
- err = xb_read(&msg->hdr, sizeof(msg->hdr));
- if (err) {
- kfree(msg);
- return err;
- }
-
- body = kmalloc(msg->hdr.len + 1, GFP_KERNEL);
- if (body == NULL) {
- kfree(msg);
- return -ENOMEM;
- }
-
- err = xb_read(body, msg->hdr.len);
- if (err) {
- kfree(body);
- kfree(msg);
- return err;
- }
- body[msg->hdr.len] = '\0';
-
- *type = msg->hdr.type;
- if (msg->hdr.type == XS_WATCH_EVENT) {
- msg->u.watch.vec = split(body, msg->hdr.len,
- &msg->u.watch.vec_size);
- if (IS_ERR(msg->u.watch.vec)) {
- kfree(msg);
- return PTR_ERR(msg->u.watch.vec);
- }
-
- mtx_lock(&watches_lock);
- msg->u.watch.handle = find_watch(
- msg->u.watch.vec[XS_WATCH_TOKEN]);
- if (msg->u.watch.handle != NULL) {
- mtx_lock(&watch_events_lock);
- TAILQ_INSERT_TAIL(&watch_events, msg, list);
- wakeup(&watch_events_waitq);
- mtx_unlock(&watch_events_lock);
- } else {
- kfree(msg->u.watch.vec);
- kfree(msg);
- }
- mtx_unlock(&watches_lock);
- } else {
- printf("event=%d ", *type);
- msg->u.reply.body = body;
- mtx_lock(&xs_state.reply_lock);
- TAILQ_INSERT_TAIL(&xs_state.reply_list, msg, list);
- wakeup(&xs_state.reply_waitq);
- mtx_unlock(&xs_state.reply_lock);
- }
- if (*type == XS_WATCH_EVENT)
- printf("\n");
-
- return 0;
-}
-
-static void xenbus_thread(void *unused)
-{
- int err;
- enum xsd_sockmsg_type type;
-
- DELAY(10000);
- xenbus_running = 1;
- tsleep(&lbolt, 0, "xenbus", hz/10);
-
- for (;;) {
- err = xs_process_msg(&type);
- if (err)
- printf("XENBUS error %d while reading "
- "message\n", err);
-
- }
-}
-
-int xs_init(void)
-{
- int err;
- struct proc *p;
-
- TAILQ_INIT(&xs_state.reply_list);
- TAILQ_INIT(&watch_events);
- sx_init(&xenwatch_mutex, "xenwatch");
-
-
- mtx_init(&xs_state.reply_lock, "state reply", NULL, MTX_DEF);
- sx_init(&xs_state.request_mutex, "xenstore request");
- sx_init(&xs_state.suspend_mutex, "xenstore suspend");
-
-
-#if 0
- mtx_init(&xs_state.suspend_mutex, "xenstore suspend", NULL, MTX_DEF);
- sema_init(&xs_state.request_mutex, 1, "xenstore request");
- sema_init(&xenwatch_mutex, 1, "xenwatch");
-#endif
- mtx_init(&watches_lock, "watches", NULL, MTX_DEF);
- mtx_init(&watch_events_lock, "watch events", NULL, MTX_DEF);
-
- /* Initialize the shared memory rings to talk to xenstored */
- err = xb_init_comms();
- if (err)
- return err;
-
- err = kthread_create(xenwatch_thread, NULL, &p,
- RFHIGHPID, 0, "xenwatch");
- if (err)
- return err;
- xenwatch_pid = p->p_pid;
-
- err = kthread_create(xenbus_thread, NULL, NULL,
- RFHIGHPID, 0, "xenbus");
-
- return err;
-}
-
-
-/*
- * Local variables:
- * c-file-style: "bsd"
- * indent-tabs-mode: t
- * c-indent-level: 4
- * c-basic-offset: 8
- * tab-width: 4
- * End:
- */
OpenPOWER on IntegriCloud