Date: Mon, 31 Dec 2007 07:17:47 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 132155 for review Message-ID: <200712310717.lBV7Hlak033853@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=132155 Change 132155 by kmacy@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712310717.lBV7Hlak033853>