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",
 			       &current_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