PERFORCE change 132155 for review
Kip Macy
kmacy at FreeBSD.org
Sun Dec 30 23:17:48 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=132155
Change 132155 by kmacy at pandemonium:kmacy:xen31 on 2007/12/31 07:17:11
bring xenbus more in line with the linux implementation
Affected files ...
.. //depot/projects/xen31/sys/i386/include/xen/xen-public/io/xenbus.h#2 edit
.. //depot/projects/xen31/sys/i386/include/xen/xenbus.h#2 edit
.. //depot/projects/xen31/sys/xen/xenbus/xenbus_client.c#3 edit
.. //depot/projects/xen31/sys/xen/xenbus/xenbus_comms.c#4 edit
.. //depot/projects/xen31/sys/xen/xenbus/xenbus_comms.h#3 edit
.. //depot/projects/xen31/sys/xen/xenbus/xenbus_dev.c#3 edit
.. //depot/projects/xen31/sys/xen/xenbus/xenbus_probe.c#4 edit
.. //depot/projects/xen31/sys/xen/xenbus/xenbus_xs.c#7 edit
Differences ...
==== //depot/projects/xen31/sys/i386/include/xen/xen-public/io/xenbus.h#2 (text+ko) ====
@@ -3,40 +3,71 @@
*
* Xenbus protocol details.
*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (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.
+ *
* Copyright (C) 2005 XenSource Ltd.
*/
#ifndef _XEN_PUBLIC_IO_XENBUS_H
#define _XEN_PUBLIC_IO_XENBUS_H
-/* The state of either end of the Xenbus, i.e. the current communication
- status of initialisation across the bus. States here imply nothing about
- the state of the connection between the driver and the kernel's device
- layers. */
-typedef enum
-{
- XenbusStateUnknown = 0,
- XenbusStateInitialising = 1,
- XenbusStateInitWait = 2, /* Finished early initialisation, but waiting
- for information from the peer or hotplug
- scripts. */
- XenbusStateInitialised = 3, /* Initialised and waiting for a connection
- from the peer. */
- XenbusStateConnected = 4,
- XenbusStateClosing = 5, /* The device is being closed due to an error
- or an unplug event. */
- XenbusStateClosed = 6
+/*
+ * The state of either end of the Xenbus, i.e. the current communication
+ * status of initialisation across the bus. States here imply nothing about
+ * the state of the connection between the driver and the kernel's device
+ * layers.
+ */
+enum xenbus_state {
+ XenbusStateUnknown = 0,
+
+ XenbusStateInitialising = 1,
+
+ /*
+ * InitWait: Finished early initialisation but waiting for information
+ * from the peer or hotplug scripts.
+ */
+ XenbusStateInitWait = 2,
+
+ /*
+ * Initialised: Waiting for a connection from the peer.
+ */
+ XenbusStateInitialised = 3,
+
+ XenbusStateConnected = 4,
+
+ /*
+ * Closing: The device is being closed due to an error or an unplug event.
+ */
+ XenbusStateClosing = 5,
-} XenbusState;
+ XenbusStateClosed = 6
+};
+typedef enum xenbus_state XenbusState;
#endif /* _XEN_PUBLIC_IO_XENBUS_H */
/*
* Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
* End:
*/
==== //depot/projects/xen31/sys/i386/include/xen/xenbus.h#2 (text+ko) ====
@@ -58,12 +58,13 @@
struct xenbus_watch otherend_watch; /* must be first */
const char *devicetype;
const char *nodename;
- char *otherend;
+ const char *otherend;
int otherend_id;
struct xendev_list_head *bus;
struct xenbus_driver *driver;
int has_error;
- void *data;
+ enum xenbus_state state;
+ void *dev_driver_data;
LIST_ENTRY(xenbus_device) list;
};
@@ -98,6 +99,7 @@
int (*read_otherend_details)(struct xenbus_device *dev);
int (*watch_otherend)(struct xenbus_device *dev);
int (*cleanup_device)(struct xenbus_device *dev);
+ int (*is_ready)(struct xenbus_device *dev);
LIST_ENTRY(xenbus_driver) list;
};
@@ -116,35 +118,40 @@
int xenbus_remove_device(struct xenbus_device *dev);
-struct xenbus_transaction;
+struct xenbus_transaction
+{
+ uint32_t id;
+};
+
+#define XBT_NIL ((struct xenbus_transaction) { 0 })
-char **xenbus_directory(struct xenbus_transaction *t,
+char **xenbus_directory(struct xenbus_transaction t,
const char *dir, const char *node, unsigned int *num);
-void *xenbus_read(struct xenbus_transaction *t,
+void *xenbus_read(struct xenbus_transaction t,
const char *dir, const char *node, unsigned int *len);
-int xenbus_write(struct xenbus_transaction *t,
+int xenbus_write(struct xenbus_transaction t,
const char *dir, const char *node, const char *string);
-int xenbus_mkdir(struct xenbus_transaction *t,
+int xenbus_mkdir(struct xenbus_transaction t,
const char *dir, const char *node);
-int xenbus_exists(struct xenbus_transaction *t,
+int xenbus_exists(struct xenbus_transaction t,
const char *dir, const char *node);
-int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
-struct xenbus_transaction *xenbus_transaction_start(void);
-int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
+int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node);
+int xenbus_transaction_start(struct xenbus_transaction *t);
+int xenbus_transaction_end(struct xenbus_transaction t, int abort);
/* Single read and scanf: returns -errno or num scanned if > 0. */
-int xenbus_scanf(struct xenbus_transaction *t,
+int xenbus_scanf(struct xenbus_transaction t,
const char *dir, const char *node, const char *fmt, ...)
__attribute__((format(scanf, 4, 5)));
/* Single printf and write: returns -errno or 0. */
-int xenbus_printf(struct xenbus_transaction *t,
+int xenbus_printf(struct xenbus_transaction t,
const char *dir, const char *node, const char *fmt, ...)
__attribute__((format(printf, 4, 5)));
/* Generic read function: NULL-terminated triples of name,
* sprintf-style type string, and pointer. Returns 0 or errno.*/
-int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
+int xenbus_gather(struct xenbus_transaction t, const char *dir, ...);
/* notifer routines for when the xenstore comes up */
int register_xenstore_notifier(xenstore_event_handler_t func, void *arg, int priority);
@@ -205,13 +212,11 @@
/**
* Advertise in the store a change of the given driver to the given new_state.
- * Perform the change inside the given transaction xbt. xbt may be NULL, in
* which case this is performed inside its own transaction. 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_switch_state(struct xenbus_device *dev,
- struct xenbus_transaction *xbt,
XenbusState new_state);
@@ -261,6 +266,11 @@
void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
...);
+int xenbus_dev_init(void);
+
+const char *xenbus_strstate(enum xenbus_state state);
+int xenbus_dev_is_online(struct xenbus_device *dev);
+int xenbus_frontend_closed(struct xenbus_device *dev);
#endif /* _ASM_XEN_XENBUS_H */
==== //depot/projects/xen31/sys/xen/xenbus/xenbus_client.c#3 (text+ko) ====
@@ -101,7 +101,6 @@
int xenbus_switch_state(struct xenbus_device *dev,
- struct xenbus_transaction *xbt,
XenbusState state)
{
/* We check whether the state is currently set to the given value, and
@@ -113,22 +112,36 @@
*/
int current_state;
+ int err;
+
+ if (state == dev->state)
+ return (0);
- int err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
+ err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d",
¤t_state);
- if ((err == 1 && (XenbusState)current_state == state) ||
- err == -ENOENT)
+ if (err != 1)
return 0;
- err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
+ err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state);
if (err) {
- xenbus_dev_fatal(dev, err, "writing new state");
+ if (state != XenbusStateClosing) /* Avoid looping */
+ xenbus_dev_fatal(dev, err, "writing new state");
return err;
}
+
+ dev->state = state;
return 0;
+
}
-EXPORT_SYMBOL(xenbus_switch_state);
+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.
@@ -165,8 +178,9 @@
ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
- dev->has_error = 1;
-
+#if 0
+ dev_err(&dev->dev, "%s\n", printf_buffer);
+#endif
path_buffer = error_path(dev);
if (path_buffer == NULL) {
@@ -175,7 +189,7 @@
goto fail;
}
- if (xenbus_write(NULL, path_buffer, "error", printf_buffer) != 0) {
+ 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;
@@ -210,7 +224,7 @@
_dev_error(dev, err, fmt, ap);
va_end(ap);
- xenbus_switch_state(dev, NULL, XenbusStateClosing);
+ xenbus_switch_state(dev, XenbusStateClosing);
}
EXPORT_SYMBOL(xenbus_dev_fatal);
@@ -264,7 +278,7 @@
{
XenbusState result;
- int err = xenbus_gather(NULL, path, "state", "%d", &result, NULL);
+ int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
if (err)
result = XenbusStateClosed;
==== //depot/projects/xen31/sys/xen/xenbus/xenbus_comms.c#4 (text+ko) ====
@@ -33,6 +33,7 @@
#include <sys/errno.h>
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/syslog.h>
#include <sys/proc.h>
#include <sys/kernel.h>
@@ -116,15 +117,18 @@
cons = intf->req_cons;
prod = intf->req_prod;
mb();
- if (!check_indexes(cons, prod))
- return -EIO;
+ 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;
@@ -140,6 +144,20 @@
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();
@@ -156,10 +174,11 @@
/* Read indexes, then verify. */
cons = intf->rsp_cons;
prod = intf->rsp_prod;
- mb();
- if (!check_indexes(cons, 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;
@@ -189,15 +208,24 @@
/* 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);
+ xen_start_info->store_evtchn,
+ "xenbus", wake_waiting, NULL, INTR_TYPE_NET, NULL);
if (err <= 0) {
- printk("XENBUS request irq failed %i\n", err);
+ log(LOG_WARNING, "XENBUS request irq failed %i\n", err);
return err;
}
==== //depot/projects/xen31/sys/xen/xenbus/xenbus_comms.h#3 (text+ko) ====
@@ -82,6 +82,65 @@
(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
+typedef struct mtx spinlock_t;
+#define spin_lock mtx_lock
+#define spin_unlock mtx_unlock
+#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 */
/*
==== //depot/projects/xen31/sys/xen/xenbus/xenbus_dev.c#3 (text+ko) ====
@@ -42,20 +42,18 @@
#include <sys/conf.h>
-#include <xen/xenbus/xenbus_comms.h>
-
#include <machine/xen/hypervisor.h>
#include <machine/xen/xenbus.h>
#include <machine/xen/hypervisor.h>
+#include <xen/xenbus/xenbus_comms.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
#define semaphore sema
#define rw_semaphore sema
-typedef struct mtx spinlock_t;
#define spin_lock mtx_lock
#define spin_unlock mtx_unlock
#define DEFINE_SPINLOCK(lock) struct mtx lock
@@ -65,7 +63,7 @@
struct xenbus_dev_transaction {
LIST_ENTRY(xenbus_dev_transaction) list;
- struct xenbus_transaction *handle;
+ struct xenbus_transaction handle;
};
struct xenbus_dev_data {
@@ -131,10 +129,10 @@
int len = uio->uio_iov[0].iov_len;
if ((len + u->len) > sizeof(u->u.buffer))
- return -EINVAL;
+ return EINVAL;
if (copyin(u->u.buffer + u->len, uio->uio_iov[0].iov_base, len) != 0)
- return -EFAULT;
+ return EFAULT;
u->len += len;
if (u->len < (sizeof(u->u.msg) + u->u.msg.len))
@@ -158,14 +156,13 @@
} else {
if (u->u.msg.type == XS_TRANSACTION_START) {
trans = kmalloc(sizeof(*trans), GFP_KERNEL);
- trans->handle = (struct xenbus_transaction *)
- simple_strtoul(reply, NULL, 0);
+ 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 ((unsigned long)trans->handle ==
- (unsigned long)u->u.msg.tx_id)
+ 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);
==== //depot/projects/xen31/sys/xen/xenbus/xenbus_probe.c#4 (text+ko) ====
@@ -46,6 +46,7 @@
#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>
@@ -57,27 +58,6 @@
#include <xen/xenbus/xenbus_comms.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
-#define semaphore sema
-#define rw_semaphore sema
-typedef struct mtx spinlock_t;
-#define spin_lock mtx_lock
-#define spin_unlock mtx_unlock
-#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 KERN_WARNING
-#define BUS_ID_SIZE 128
-
-
struct xendev_list_head xenbus_device_frontend_list;
struct xendev_list_head xenbus_device_backend_list;
static LIST_HEAD(, xenbus_driver) xendrv_list;
@@ -92,7 +72,6 @@
#define streq(a, b) (strcmp((a), (b)) == 0)
-static char *kasprintf(const char *fmt, ...);
static int watch_otherend(struct xenbus_device *dev);
@@ -123,44 +102,47 @@
}
#endif
-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, int unit);
- struct xendev_list_head *bus;
-#if 0
- struct bus_type bus;
- struct device dev;
-#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) {
- printk(KERN_WARNING "XENBUS: bad frontend %s\n", nodename);
- return EINVAL;
+ log(LOG_WARNING, "XENBUS: bad frontend %s\n", nodename);
+ return -EINVAL;
}
strlcpy(bus_id, nodename + 1, BUS_ID_SIZE);
if (!strchr(bus_id, '/')) {
- printk(KERN_WARNING "XENBUS: bus_id %s no slash\n", bus_id);
- return EINVAL;
+ log(LOG_WARNING, "XENBUS: bus_id %s no slash\n", bus_id);
+ return -EINVAL;
}
*strchr(bus_id, '/') = '-';
return 0;
}
-static int
+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(NULL, xendev->nodename,
+ int err = xenbus_gather(XBT_NIL, xendev->nodename,
id_node, "%i", &xendev->otherend_id,
path_node, NULL, &xendev->otherend,
NULL);
@@ -171,12 +153,12 @@
return err;
}
if (strlen(xendev->otherend) == 0 ||
- !xenbus_exists(NULL, xendev->otherend, "")) {
- xenbus_dev_fatal(xendev, ENOENT, "missing other end from %s",
+ !xenbus_exists(XBT_NIL, xendev->otherend, "")) {
+ xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
xendev->nodename);
- kfree(xendev->otherend);
+ kfree((void *)(uintptr_t)xendev->otherend);
xendev->otherend = NULL;
- return ENOENT;
+ return -ENOENT;
}
return 0;
@@ -185,95 +167,21 @@
static int read_backend_details(struct xenbus_device *xendev)
{
- if (!strncmp(xendev->nodename, "backend", 7))
- return -ENOENT;
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");
}
-
-static int watch_otherend_backend(struct xenbus_device *dev)
-{
- struct xenbus_transaction *xbt;
-
- /* We need to add the hotplug-status because we don't */
- /* have a hotplug script to do this. If we ever do, */
- /* this can be removed -- WORK */
- xbt = xenbus_transaction_start();
- xenbus_printf(xbt, dev->nodename, "hotplug-status","%s","connected");
- xenbus_transaction_end(xbt, 0);
+#endif
- return watch_otherend(dev);
-}
-
-static int watch_otherend_frontend(struct xenbus_device *dev)
-{
- return watch_otherend(dev);
-}
-
-/* We need to remove the backend device node from the xenbus */
-/* because we don't have a hotplug script to do this. If we */
-/* ever do, this can be removed -- WORK */
-static int
-xenbus_cleanup_backend_device(struct xenbus_device *dev)
-{
- char *node, **dir;
- unsigned int dir_n;
- int i;
-
- i = strlen(dev->nodename);
- if (!i)
- return 0;
-
- node = malloc(i+1, M_DEVBUF, M_WAITOK);
- if (!node)
- return ENOMEM;
- strcpy(node, dev->nodename);
-again:
- DPRINTK("removing %s\n", node);
- if (!xenbus_rm(NULL, node, "")) {
- while (i > 7) {
- if (node[i] == '/') {
- node[i] = '\0';
- dir = xenbus_directory(NULL, node, "", &dir_n);
- if (!IS_ERR(dir)) {
- kfree(dir);
- if (dir_n == 0)
- goto again;
- }
- break;
- }
- i--;
- }
- }
- free(node, M_DEVBUF);
- return 0;
-}
-
-static void free_otherend_details(struct xenbus_device *dev)
-{
- kfree(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;
- }
-}
-
/* Bus type for frontend drivers. */
-static int xenbus_probe_frontend(const char *type, const char *name, int unit);
+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> */
@@ -292,44 +200,6 @@
#endif
};
-/* 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;
- char *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(NULL, nodename, "frontend-id", "%i", &domid,
- "frontend", NULL, &frontend, NULL);
- if (err)
- return err;
- if (strlen(frontend) == 0)
- err = ERANGE;
-
- if (!err && !xenbus_exists(NULL, frontend, ""))
- err = ENOENT;
-
- if (err) {
- kfree(frontend);
- return err;
- }
-
- if (snprintf(bus_id, BUS_ID_SIZE,
- "%.*s-%i-%s", typelen, type, domid, devid) >= BUS_ID_SIZE)
- return ENOSPC;
- return 0;
-}
#if 0
static int xenbus_hotplug_backend(device_t dev, char **envp,
int num_envp, char *buffer, int buffer_size)
@@ -346,11 +216,11 @@
DPRINTK("");
if (dev == NULL)
- return ENODEV;
+ return -ENODEV;
xdev = to_xenbus_device(dev);
if (xdev == NULL)
- return ENODEV;
+ return -ENODEV;
if (dev->driver)
drv = to_xenbus_driver(dev->driver);
@@ -398,6 +268,7 @@
}
#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",
@@ -417,8 +288,8 @@
},
#endif
};
+#endif
-
static void otherend_changed(struct xenbus_watch *watch,
const char **vec, unsigned int len)
{
@@ -439,6 +310,22 @@
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);
@@ -485,7 +372,7 @@
err = talk_to_otherend(dev);
if (err) {
- printk(KERN_WARNING
+ log(LOG_WARNING,
"xenbus_probe: talk_to_otherend on %s failed.\n",
dev->nodename);
return err;
@@ -495,9 +382,9 @@
if (err)
goto fail;
- err = drv->watch_otherend(dev);
+ err = watch_otherend(dev);
if (err) {
- printk(KERN_WARNING
+ log(LOG_WARNING,
"xenbus_probe: watch_otherend on %s failed.\n",
dev->nodename);
return err;
@@ -506,8 +393,8 @@
return 0;
fail:
xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
- xenbus_switch_state(dev, NULL, XenbusStateClosed);
- return ENODEV;
+ xenbus_switch_state(dev, XenbusStateClosed);
+ return -ENODEV;
}
static void xenbus_dev_free(struct xenbus_device *xendev)
@@ -529,7 +416,7 @@
if (drv->remove)
drv->remove(dev);
- xenbus_switch_state(dev, NULL, XenbusStateClosed);
+ xenbus_switch_state(dev, XenbusStateClosed);
if (drv->cleanup_device)
return drv->cleanup_device(dev);
@@ -547,7 +434,7 @@
}
#endif
-static int xenbus_register_driver_common(struct xenbus_driver *drv,
+int xenbus_register_driver_common(struct xenbus_driver *drv,
struct xen_bus_type *bus)
{
struct xenbus_device *xdev;
@@ -581,22 +468,11 @@
int xenbus_register_frontend(struct xenbus_driver *drv)
{
drv->read_otherend_details = read_backend_details;
- drv->watch_otherend = watch_otherend_frontend;
- drv->cleanup_device = NULL;
return xenbus_register_driver_common(drv, &xenbus_frontend);
}
EXPORT_SYMBOL(xenbus_register_frontend);
-int xenbus_register_backend(struct xenbus_driver *drv)
-{
- drv->read_otherend_details = read_frontend_details;
- drv->watch_otherend = watch_otherend_backend;
- drv->cleanup_device = xenbus_cleanup_backend_device;
-
- return xenbus_register_driver_common(drv, &xenbus_backend);
-}
-EXPORT_SYMBOL(xenbus_register_backend);
void xenbus_unregister_driver(struct xenbus_driver *drv)
{
@@ -672,7 +548,7 @@
}
#endif
/* Simplified asprintf. */
-static char *kasprintf(const char *fmt, ...)
+char *kasprintf(const char *fmt, ...)
{
va_list ap;
unsigned int len;
@@ -706,8 +582,8 @@
DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL);
#endif
-static int xenbus_probe_node(struct xen_bus_type *bus, const char *type,
- const char *nodename, int unit)
+int xenbus_probe_node(struct xen_bus_type *bus, const char *type,
+ const char *nodename)
{
#define CHECK_FAIL \
do { \
@@ -734,7 +610,7 @@
stringlen = strlen(nodename) + 1 + strlen(type) + 1;
xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
if (!xendev)
- return ENOMEM;
+ return -ENOMEM;
memset(xendev, 0, sizeof(*xendev));
/* Copy the strings into the extra space. */
@@ -785,70 +661,22 @@
}
/* device/<typename>/<name> */
-static int xenbus_probe_frontend(const char *type, const char *name, int unit)
+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;
+ return -ENOMEM;
DPRINTK("%s", nodename);
- err = xenbus_probe_node(&xenbus_frontend, type, nodename, unit);
+ err = xenbus_probe_node(&xenbus_frontend, type, nodename);
kfree(nodename);
return err;
}
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list