ia64/xen-unstable

changeset 9445:8286738ab7f9

The patch removes old Xenbus files, fixes 0 length mmu_updates table bug
(bugfix by Melvin Anderson) and adds missing console.h header file
(again spotted by Melvin).

Signed-off-by: Grzegorz Milos <gm281@cam.ac.uk>
author kaf24@firebug.cl.cam.ac.uk
date Fri Mar 24 10:52:10 2006 +0100 (2006-03-24)
parents 8c21c8ea5fff
children 6d0929e34ce2 c0865290c071
files extras/mini-os/include/console.h extras/mini-os/mm.c
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/extras/mini-os/include/console.h	Fri Mar 24 10:52:10 2006 +0100
     1.3 @@ -0,0 +1,49 @@
     1.4 +/* 
     1.5 + ****************************************************************************
     1.6 + * (C) 2006 - Grzegorz Milos - Cambridge University
     1.7 + ****************************************************************************
     1.8 + *
     1.9 + *        File: console.h
    1.10 + *      Author: Grzegorz Milos
    1.11 + *     Changes: 
    1.12 + *              
    1.13 + *        Date: Mar 2006
    1.14 + * 
    1.15 + * Environment: Xen Minimal OS
    1.16 + * Description: Console interface.
    1.17 + *
    1.18 + * Handles console I/O. Defines printk.
    1.19 + *
    1.20 + ****************************************************************************
    1.21 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    1.22 + * of this software and associated documentation files (the "Software"), to
    1.23 + * deal in the Software without restriction, including without limitation the
    1.24 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    1.25 + * sell copies of the Software, and to permit persons to whom the Software is
    1.26 + * furnished to do so, subject to the following conditions:
    1.27 + * 
    1.28 + * The above copyright notice and this permission notice shall be included in
    1.29 + * all copies or substantial portions of the Software.
    1.30 + * 
    1.31 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    1.32 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    1.33 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
    1.34 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    1.35 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
    1.36 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
    1.37 + * DEALINGS IN THE SOFTWARE.
    1.38 + */
    1.39 +#ifndef _LIB_CONSOLE_H_
    1.40 +#define _LIB_CONSOLE_H_
    1.41 +
    1.42 +#include<traps.h>
    1.43 +
    1.44 +void printk(const char *fmt, ...);
    1.45 +void xprintk(const char *fmt, ...);
    1.46 +
    1.47 +void xencons_rx(char *buf, unsigned len, struct pt_regs *regs);
    1.48 +void xencons_tx(void);
    1.49 +
    1.50 +void init_console(void);
    1.51 +
    1.52 +#endif /* _LIB_CONSOLE_H_ */
     2.1 --- a/extras/mini-os/mm.c	Fri Mar 24 10:47:48 2006 +0100
     2.2 +++ b/extras/mini-os/mm.c	Fri Mar 24 10:52:10 2006 +0100
     2.3 @@ -372,7 +372,7 @@ void new_pt_frame(unsigned long *pt_pfn,
     2.4      unsigned long *tab = (unsigned long *)start_info.pt_base;
     2.5      unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn); 
     2.6      unsigned long prot_e, prot_t, pincmd;
     2.7 -    mmu_update_t mmu_updates[0];
     2.8 +    mmu_update_t mmu_updates[1];
     2.9      struct mmuext_op pin_request;
    2.10      
    2.11      DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
     3.1 --- a/extras/mini-os/xenbus/Makefile	Fri Mar 24 10:47:48 2006 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,9 +0,0 @@
     3.4 -all: xenstore.h xenbus_comms.o xenbus_xs.o xenbus_probe.o
     3.5 -
     3.6 -xenstore.h:
     3.7 -	[ -e xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h xenstored.h
     3.8 -
     3.9 -clean:
    3.10 -	#Taken care of by main Makefile
    3.11 -	#rm xenstored.h
    3.12 -	#rm *.o
     4.1 --- a/extras/mini-os/xenbus/xenbus_comms.c	Fri Mar 24 10:47:48 2006 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,184 +0,0 @@
     4.4 -/******************************************************************************
     4.5 - * xenbus_comms.c
     4.6 - *
     4.7 - * Low level code to talks to Xen Store: ringbuffer and event channel.
     4.8 - *
     4.9 - * Copyright (C) 2005 Rusty Russell, IBM Corporation
    4.10 - * 
    4.11 - * This file may be distributed separately from the Linux kernel, or
    4.12 - * incorporated into other software packages, subject to the following license:
    4.13 - * 
    4.14 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    4.15 - * of this source file (the "Software"), to deal in the Software without
    4.16 - * restriction, including without limitation the rights to use, copy, modify,
    4.17 - * merge, publish, distribute, sublicense, and/or sell copies of the Software,
    4.18 - * and to permit persons to whom the Software is furnished to do so, subject to
    4.19 - * the following conditions:
    4.20 - * 
    4.21 - * The above copyright notice and this permission notice shall be included in
    4.22 - * all copies or substantial portions of the Software.
    4.23 - * 
    4.24 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    4.25 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    4.26 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    4.27 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    4.28 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    4.29 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    4.30 - * IN THE SOFTWARE.
    4.31 - */
    4.32 -#include <types.h>
    4.33 -#include <wait.h>
    4.34 -#include <mm.h>
    4.35 -#include <hypervisor.h>
    4.36 -#include <events.h>
    4.37 -#include <os.h>
    4.38 -#include <lib.h>
    4.39 -#include <xenbus.h>
    4.40 -#include "xenbus_comms.h"
    4.41 -
    4.42 -static int xenbus_irq;
    4.43 -
    4.44 -extern void xenbus_probe(void *);
    4.45 -extern int xenstored_ready;
    4.46 -
    4.47 -DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
    4.48 -
    4.49 -static inline struct xenstore_domain_interface *xenstore_domain_interface(void)
    4.50 -{
    4.51 -	return mfn_to_virt(start_info.store_mfn);
    4.52 -}
    4.53 -
    4.54 -static void wake_waiting(int port, struct pt_regs *regs)
    4.55 -{
    4.56 -	wake_up(&xb_waitq);
    4.57 -}
    4.58 -
    4.59 -static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
    4.60 -{
    4.61 -	return ((prod - cons) <= XENSTORE_RING_SIZE);
    4.62 -}
    4.63 -
    4.64 -static void *get_output_chunk(XENSTORE_RING_IDX cons,
    4.65 -			      XENSTORE_RING_IDX prod,
    4.66 -			      char *buf, uint32_t *len)
    4.67 -{
    4.68 -	*len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
    4.69 -	if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
    4.70 -		*len = XENSTORE_RING_SIZE - (prod - cons);
    4.71 -	return buf + MASK_XENSTORE_IDX(prod);
    4.72 -}
    4.73 -
    4.74 -static const void *get_input_chunk(XENSTORE_RING_IDX cons,
    4.75 -				   XENSTORE_RING_IDX prod,
    4.76 -				   const char *buf, uint32_t *len)
    4.77 -{
    4.78 -	*len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
    4.79 -	if ((prod - cons) < *len)
    4.80 -		*len = prod - cons;
    4.81 -	return buf + MASK_XENSTORE_IDX(cons);
    4.82 -}
    4.83 -
    4.84 -int xb_write(const void *data, unsigned len)
    4.85 -{
    4.86 -	struct xenstore_domain_interface *intf = xenstore_domain_interface();
    4.87 -	XENSTORE_RING_IDX cons, prod;
    4.88 -
    4.89 -	while (len != 0) {
    4.90 -		void *dst;
    4.91 -		unsigned int avail;
    4.92 -
    4.93 -		wait_event(xb_waitq, (intf->req_prod - intf->req_cons) !=
    4.94 -			   XENSTORE_RING_SIZE);
    4.95 -
    4.96 -		/* Read indexes, then verify. */
    4.97 -		cons = intf->req_cons;
    4.98 -		prod = intf->req_prod;
    4.99 -		mb();
   4.100 -		if (!check_indexes(cons, prod))
   4.101 -			return -EIO;
   4.102 -
   4.103 -		dst = get_output_chunk(cons, prod, intf->req, &avail);
   4.104 -		if (avail == 0)
   4.105 -			continue;
   4.106 -		if (avail > len)
   4.107 -			avail = len;
   4.108 -
   4.109 -		memcpy(dst, data, avail);
   4.110 -		data = (void*) ( (unsigned long)data + avail );
   4.111 -		len -= avail;
   4.112 -
   4.113 -		/* Other side must not see new header until data is there. */
   4.114 -		wmb();
   4.115 -		intf->req_prod += avail;
   4.116 -
   4.117 -		/* This implies mb() before other side sees interrupt. */
   4.118 -		notify_remote_via_evtchn(start_info.store_evtchn);
   4.119 -	}
   4.120 -
   4.121 -	return 0;
   4.122 -}
   4.123 -
   4.124 -int xb_read(void *data, unsigned len)
   4.125 -{
   4.126 -	struct xenstore_domain_interface *intf = xenstore_domain_interface();
   4.127 -	XENSTORE_RING_IDX cons, prod;
   4.128 -
   4.129 -	while (len != 0) {
   4.130 -		unsigned int avail;
   4.131 -		const char *src;
   4.132 -
   4.133 -		wait_event(xb_waitq,
   4.134 -			   intf->rsp_cons != intf->rsp_prod);
   4.135 -
   4.136 -		/* Read indexes, then verify. */
   4.137 -		cons = intf->rsp_cons;
   4.138 -		prod = intf->rsp_prod;
   4.139 -		mb();
   4.140 -		if (!check_indexes(cons, prod))
   4.141 -			return -EIO;
   4.142 -
   4.143 -		src = get_input_chunk(cons, prod, intf->rsp, &avail);
   4.144 -		if (avail == 0)
   4.145 -			continue;
   4.146 -		if (avail > len)
   4.147 -			avail = len;
   4.148 -
   4.149 -		/* We must read header before we read data. */
   4.150 -		rmb();
   4.151 -
   4.152 -		memcpy(data, src, avail);
   4.153 -		data = (void*) ( (unsigned long)data + avail );
   4.154 -		len -= avail;
   4.155 -
   4.156 -		/* Other side must not see free space until we've copied out */
   4.157 -		mb();
   4.158 -		intf->rsp_cons += avail;
   4.159 -
   4.160 -		printk("Finished read of %i bytes (%i to go)\n", avail, len);
   4.161 -
   4.162 -		/* Implies mb(): they will see new header. */
   4.163 -		notify_remote_via_evtchn(start_info.store_evtchn);
   4.164 -	}
   4.165 -
   4.166 -	return 0;
   4.167 -}
   4.168 -
   4.169 -/* Set up interrupt handler off store event channel. */
   4.170 -int xb_init_comms(void)
   4.171 -{
   4.172 -	int err;
   4.173 -
   4.174 -	if (xenbus_irq)
   4.175 -		unbind_evtchn(xenbus_irq);
   4.176 -
   4.177 -	err = bind_evtchn(
   4.178 -		start_info.store_evtchn, wake_waiting);
   4.179 -	if (err <= 0) {
   4.180 -		printk("XENBUS request irq failed %i\n", err);
   4.181 -		return err;
   4.182 -	}
   4.183 -
   4.184 -	xenbus_irq = err;
   4.185 -
   4.186 -	return 0;
   4.187 -}
     5.1 --- a/extras/mini-os/xenbus/xenbus_comms.h	Fri Mar 24 10:47:48 2006 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,40 +0,0 @@
     5.4 -/*
     5.5 - * Private include for xenbus communications.
     5.6 - * 
     5.7 - * Copyright (C) 2005 Rusty Russell, IBM Corporation
     5.8 - *
     5.9 - * This file may be distributed separately from the Linux kernel, or
    5.10 - * incorporated into other software packages, subject to the following license:
    5.11 - * 
    5.12 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    5.13 - * of this source file (the "Software"), to deal in the Software without
    5.14 - * restriction, including without limitation the rights to use, copy, modify,
    5.15 - * merge, publish, distribute, sublicense, and/or sell copies of the Software,
    5.16 - * and to permit persons to whom the Software is furnished to do so, subject to
    5.17 - * the following conditions:
    5.18 - * 
    5.19 - * The above copyright notice and this permission notice shall be included in
    5.20 - * all copies or substantial portions of the Software.
    5.21 - * 
    5.22 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    5.23 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    5.24 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    5.25 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    5.26 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    5.27 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    5.28 - * IN THE SOFTWARE.
    5.29 - */
    5.30 -
    5.31 -#ifndef _XENBUS_COMMS_H
    5.32 -#define _XENBUS_COMMS_H
    5.33 -
    5.34 -int xs_init(void);
    5.35 -int xb_init_comms(void);
    5.36 -
    5.37 -/* Low level routines. */
    5.38 -int xb_write(const void *data, unsigned len);
    5.39 -int xb_read(void *data, unsigned len);
    5.40 -int xs_input_avail(void);
    5.41 -extern struct wait_queue_head xb_waitq;
    5.42 -
    5.43 -#endif /* _XENBUS_COMMS_H */
     6.1 --- a/extras/mini-os/xenbus/xenbus_xs.c	Fri Mar 24 10:47:48 2006 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,796 +0,0 @@
     6.4 -/******************************************************************************
     6.5 - * xenbus_xs.c
     6.6 - *
     6.7 - * This is the kernel equivalent of the "xs" library.  We don't need everything
     6.8 - * and we use xenbus_comms for communication.
     6.9 - *
    6.10 - * Copyright (C) 2005 Rusty Russell, IBM Corporation
    6.11 - * 
    6.12 - * This file may be distributed separately from the Linux kernel, or
    6.13 - * incorporated into other software packages, subject to the following license:
    6.14 - * 
    6.15 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    6.16 - * of this source file (the "Software"), to deal in the Software without
    6.17 - * restriction, including without limitation the rights to use, copy, modify,
    6.18 - * merge, publish, distribute, sublicense, and/or sell copies of the Software,
    6.19 - * and to permit persons to whom the Software is furnished to do so, subject to
    6.20 - * the following conditions:
    6.21 - * 
    6.22 - * The above copyright notice and this permission notice shall be included in
    6.23 - * all copies or substantial portions of the Software.
    6.24 - * 
    6.25 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    6.26 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    6.27 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    6.28 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    6.29 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    6.30 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    6.31 - * IN THE SOFTWARE.
    6.32 - */
    6.33 -#include <errno.h>
    6.34 -#include <types.h>
    6.35 -#include <list.h>
    6.36 -#include <lib.h>
    6.37 -#include <err.h>
    6.38 -#include <os.h>
    6.39 -#include <xmalloc.h>
    6.40 -#include <fcntl.h>
    6.41 -#include <xenbus.h>
    6.42 -#include <wait.h>
    6.43 -#include <sched.h>
    6.44 -#include <semaphore.h>
    6.45 -#include <spinlock.h>
    6.46 -#include <xen/io/xs_wire.h>
    6.47 -#include "xenbus_comms.h"
    6.48 -
    6.49 -#define streq(a, b) (strcmp((a), (b)) == 0)
    6.50 -
    6.51 -struct xs_stored_msg {
    6.52 -	struct list_head list;
    6.53 -
    6.54 -	struct xsd_sockmsg hdr;
    6.55 -
    6.56 -	union {
    6.57 -		/* Queued replies. */
    6.58 -		struct {
    6.59 -			char *body;
    6.60 -		} reply;
    6.61 -
    6.62 -		/* Queued watch events. */
    6.63 -		struct {
    6.64 -			struct xenbus_watch *handle;
    6.65 -			char **vec;
    6.66 -			unsigned int vec_size;
    6.67 -		} watch;
    6.68 -	} u;
    6.69 -};
    6.70 -
    6.71 -struct xs_handle {
    6.72 -	/* A list of replies. Currently only one will ever be outstanding. */
    6.73 -	struct list_head reply_list;
    6.74 -	spinlock_t reply_lock;
    6.75 -	struct wait_queue_head reply_waitq;
    6.76 -
    6.77 -	/* One request at a time. */
    6.78 -	struct semaphore request_mutex;
    6.79 -
    6.80 -	/* Protect transactions against save/restore. */
    6.81 -	struct rw_semaphore suspend_mutex;
    6.82 -};
    6.83 -
    6.84 -static struct xs_handle xs_state;
    6.85 -
    6.86 -/* List of registered watches, and a lock to protect it. */
    6.87 -static LIST_HEAD(watches);
    6.88 -static DEFINE_SPINLOCK(watches_lock);
    6.89 -
    6.90 -/* List of pending watch callback events, and a lock to protect it. */
    6.91 -static LIST_HEAD(watch_events);
    6.92 -static DEFINE_SPINLOCK(watch_events_lock);
    6.93 -
    6.94 -/*
    6.95 - * Details of the xenwatch callback kernel thread. The thread waits on the
    6.96 - * watch_events_waitq for work to do (queued on watch_events list). When it
    6.97 - * wakes up it acquires the xenwatch_mutex before reading the list and
    6.98 - * carrying out work.
    6.99 - */
   6.100 -/* static */ DECLARE_MUTEX(xenwatch_mutex);
   6.101 -static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq);
   6.102 -
   6.103 -static int get_error(const char *errorstring)
   6.104 -{
   6.105 -	unsigned int i;
   6.106 -
   6.107 -	for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) {
   6.108 -		if (i == ARRAY_SIZE(xsd_errors) - 1) {
   6.109 -			printk("XENBUS xen store gave: unknown error %s",
   6.110 -			       errorstring);
   6.111 -			return EINVAL;
   6.112 -		}
   6.113 -	}
   6.114 -	return xsd_errors[i].errnum;
   6.115 -}
   6.116 -
   6.117 -static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
   6.118 -{
   6.119 -	struct xs_stored_msg *msg;
   6.120 -	char *body;
   6.121 -
   6.122 -	spin_lock(&xs_state.reply_lock);
   6.123 -
   6.124 -	while (list_empty(&xs_state.reply_list)) {
   6.125 -		spin_unlock(&xs_state.reply_lock);
   6.126 -		wait_event(xs_state.reply_waitq,
   6.127 -			   !list_empty(&xs_state.reply_list));
   6.128 -		spin_lock(&xs_state.reply_lock);
   6.129 -	}
   6.130 -
   6.131 -	msg = list_entry(xs_state.reply_list.next,
   6.132 -			 struct xs_stored_msg, list);
   6.133 -	list_del(&msg->list);
   6.134 -
   6.135 -	spin_unlock(&xs_state.reply_lock);
   6.136 -
   6.137 -	*type = msg->hdr.type;
   6.138 -	if (len)
   6.139 -		*len = msg->hdr.len;
   6.140 -	body = msg->u.reply.body;
   6.141 -
   6.142 -	free(msg);
   6.143 -
   6.144 -	return body;
   6.145 -}
   6.146 -
   6.147 -/* Emergency write. */
   6.148 -void xenbus_debug_write(const char *str, unsigned int count)
   6.149 -{
   6.150 -	struct xsd_sockmsg msg = { 0 };
   6.151 -
   6.152 -	msg.type = XS_DEBUG;
   6.153 -	msg.len = sizeof("print") + count + 1;
   6.154 -
   6.155 -	down(&xs_state.request_mutex);
   6.156 -	xb_write(&msg, sizeof(msg));
   6.157 -	xb_write("print", sizeof("print"));
   6.158 -	xb_write(str, count);
   6.159 -	xb_write("", 1);
   6.160 -	up(&xs_state.request_mutex);
   6.161 -}
   6.162 -
   6.163 -void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
   6.164 -{
   6.165 -	void *ret;
   6.166 -	struct xsd_sockmsg req_msg = *msg;
   6.167 -	int err;
   6.168 -
   6.169 -	if (req_msg.type == XS_TRANSACTION_START)
   6.170 -		down_read(&xs_state.suspend_mutex);
   6.171 -
   6.172 -	down(&xs_state.request_mutex);
   6.173 -
   6.174 -	err = xb_write(msg, sizeof(*msg) + msg->len);
   6.175 -	if (err) {
   6.176 -		msg->type = XS_ERROR;
   6.177 -		ret = ERR_PTR(err);
   6.178 -	} else {
   6.179 -		ret = read_reply(&msg->type, &msg->len);
   6.180 -	}
   6.181 -
   6.182 -	up(&xs_state.request_mutex);
   6.183 -
   6.184 -	if ((msg->type == XS_TRANSACTION_END) ||
   6.185 -	    ((req_msg.type == XS_TRANSACTION_START) &&
   6.186 -	     (msg->type == XS_ERROR)))
   6.187 -		up_read(&xs_state.suspend_mutex);
   6.188 -
   6.189 -	return ret;
   6.190 -}
   6.191 -
   6.192 -/* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
   6.193 -static void *xs_talkv(struct xenbus_transaction *t,
   6.194 -		      enum xsd_sockmsg_type type,
   6.195 -		      const struct kvec *iovec,
   6.196 -		      unsigned int num_vecs,
   6.197 -		      unsigned int *len)
   6.198 -{
   6.199 -	struct xsd_sockmsg msg;
   6.200 -	void *ret = NULL;
   6.201 -	unsigned int i;
   6.202 -	int err;
   6.203 -
   6.204 -	msg.tx_id = (u32)(unsigned long)t;
   6.205 -	msg.req_id = 0;
   6.206 -	msg.type = type;
   6.207 -	msg.len = 0;
   6.208 -	for (i = 0; i < num_vecs; i++)
   6.209 -		msg.len += iovec[i].iov_len;
   6.210 -
   6.211 -	down(&xs_state.request_mutex);
   6.212 -
   6.213 -	err = xb_write(&msg, sizeof(msg));
   6.214 -	if (err) {
   6.215 -		up(&xs_state.request_mutex);
   6.216 -		return ERR_PTR(err);
   6.217 -	}
   6.218 -
   6.219 -	for (i = 0; i < num_vecs; i++) {
   6.220 -		err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
   6.221 -		if (err) {
   6.222 -			up(&xs_state.request_mutex);
   6.223 -			return ERR_PTR(err);
   6.224 -		}
   6.225 -	}
   6.226 -
   6.227 -	ret = read_reply(&msg.type, len);
   6.228 -
   6.229 -	up(&xs_state.request_mutex);
   6.230 -
   6.231 -	if (IS_ERR(ret))
   6.232 -		return ret;
   6.233 -
   6.234 -	if (msg.type == XS_ERROR) {
   6.235 -		err = get_error(ret);
   6.236 -		free(ret);
   6.237 -		return ERR_PTR(-err);
   6.238 -	}
   6.239 -
   6.240 -	//	BUG_ON(msg.type != type);
   6.241 -	return ret;
   6.242 -}
   6.243 -
   6.244 -/* Simplified version of xs_talkv: single message. */
   6.245 -static void *xs_single(struct xenbus_transaction *t,
   6.246 -		       enum xsd_sockmsg_type type,
   6.247 -		       const char *string,
   6.248 -		       unsigned int *len)
   6.249 -{
   6.250 -	struct kvec iovec;
   6.251 -
   6.252 -	iovec.iov_base = (void *)string;
   6.253 -	iovec.iov_len = strlen(string) + 1;
   6.254 -	return xs_talkv(t, type, &iovec, 1, len);
   6.255 -}
   6.256 -
   6.257 -/* Many commands only need an ack, don't care what it says. */
   6.258 -static int xs_error(char *reply)
   6.259 -{
   6.260 -	if (IS_ERR(reply))
   6.261 -		return PTR_ERR(reply);
   6.262 -	free(reply);
   6.263 -	return 0;
   6.264 -}
   6.265 -
   6.266 -static unsigned int count_strings(const char *strings, unsigned int len)
   6.267 -{
   6.268 -	unsigned int num;
   6.269 -	const char *p;
   6.270 -
   6.271 -	for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
   6.272 -		num++;
   6.273 -
   6.274 -	return num;
   6.275 -}
   6.276 -
   6.277 -/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */ 
   6.278 -static char *join(const char *dir, const char *name)
   6.279 -{
   6.280 -	char *buffer;
   6.281 -
   6.282 -	buffer = malloc(strlen(dir) + strlen("/") + strlen(name) + 1);
   6.283 -	if (buffer == NULL)
   6.284 -		return ERR_PTR(-ENOMEM);
   6.285 -
   6.286 -	strcpy(buffer, dir);
   6.287 -	if (!streq(name, "")) {
   6.288 -		strcat(buffer, "/");
   6.289 -		strcat(buffer, name);
   6.290 -	}
   6.291 -
   6.292 -	return buffer;
   6.293 -}
   6.294 -
   6.295 -static char **split(char *strings, unsigned int len, unsigned int *num)
   6.296 -{
   6.297 -	char *p, **ret;
   6.298 -
   6.299 -	/* Count the strings. */
   6.300 -	*num = count_strings(strings, len);
   6.301 -
   6.302 -	/* Transfer to one big alloc for easy freeing. */
   6.303 -	ret = malloc(*num * sizeof(char *) + len);
   6.304 -	if (!ret) {
   6.305 -		free(strings);
   6.306 -		return ERR_PTR(-ENOMEM);
   6.307 -	}
   6.308 -	memcpy(&ret[*num], strings, len);
   6.309 -	free(strings);
   6.310 -
   6.311 -	strings = (char *)&ret[*num];
   6.312 -	for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
   6.313 -		ret[(*num)++] = p;
   6.314 -
   6.315 -	return ret;
   6.316 -}
   6.317 -
   6.318 -char **xenbus_directory(struct xenbus_transaction *t,
   6.319 -			const char *dir, const char *node, unsigned int *num)
   6.320 -{
   6.321 -	char *strings, *path;
   6.322 -	unsigned int len;
   6.323 -
   6.324 -	path = join(dir, node);
   6.325 -	if (IS_ERR(path))
   6.326 -		return (char **)path;
   6.327 -
   6.328 -	strings = xs_single(t, XS_DIRECTORY, path, &len);
   6.329 -	free(path);
   6.330 -	if (IS_ERR(strings))
   6.331 -		return (char **)strings;
   6.332 -
   6.333 -	return split(strings, len, num);
   6.334 -}
   6.335 -
   6.336 -/* Check if a path exists. Return 1 if it does. */
   6.337 -int xenbus_exists(struct xenbus_transaction *t,
   6.338 -		  const char *dir, const char *node)
   6.339 -{
   6.340 -	char **d;
   6.341 -	int dir_n;
   6.342 -
   6.343 -	d = xenbus_directory(t, dir, node, &dir_n);
   6.344 -	if (IS_ERR(d))
   6.345 -		return 0;
   6.346 -	free(d);
   6.347 -	return 1;
   6.348 -}
   6.349 -
   6.350 -/* Get the value of a single file.
   6.351 - * Returns a kmalloced value: call free() on it after use.
   6.352 - * len indicates length in bytes.
   6.353 - */
   6.354 -void *xenbus_read(struct xenbus_transaction *t,
   6.355 -		  const char *dir, const char *node, unsigned int *len)
   6.356 -{
   6.357 -	char *path;
   6.358 -	void *ret;
   6.359 -
   6.360 -	path = join(dir, node);
   6.361 -	if (IS_ERR(path))
   6.362 -		return (void *)path;
   6.363 -
   6.364 -	ret = xs_single(t, XS_READ, path, len);
   6.365 -	free(path);
   6.366 -	return ret;
   6.367 -}
   6.368 -
   6.369 -/* Write the value of a single file.
   6.370 - * Returns -err on failure.
   6.371 - */
   6.372 -int xenbus_write(struct xenbus_transaction *t,
   6.373 -		 const char *dir, const char *node, const char *string)
   6.374 -{
   6.375 -	const char *path;
   6.376 -	struct kvec iovec[2];
   6.377 -	int ret;
   6.378 -
   6.379 -	path = join(dir, node);
   6.380 -	if (IS_ERR(path))
   6.381 -		return PTR_ERR(path);
   6.382 -
   6.383 -	iovec[0].iov_base = (void *)path;
   6.384 -	iovec[0].iov_len = strlen(path) + 1;
   6.385 -	iovec[1].iov_base = (void *)string;
   6.386 -	iovec[1].iov_len = strlen(string);
   6.387 -
   6.388 -	ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
   6.389 -	free(path);
   6.390 -	return ret;
   6.391 -}
   6.392 -
   6.393 -/* Create a new directory. */
   6.394 -int xenbus_mkdir(struct xenbus_transaction *t,
   6.395 -		 const char *dir, const char *node)
   6.396 -{
   6.397 -	char *path;
   6.398 -	int ret;
   6.399 -
   6.400 -	path = join(dir, node);
   6.401 -	if (IS_ERR(path))
   6.402 -		return PTR_ERR(path);
   6.403 -
   6.404 -	ret = xs_error(xs_single(t, XS_MKDIR, path, NULL));
   6.405 -	free(path);
   6.406 -	return ret;
   6.407 -}
   6.408 -
   6.409 -/* Destroy a file or directory (directories must be empty). */
   6.410 -int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
   6.411 -{
   6.412 -	char *path;
   6.413 -	int ret;
   6.414 -
   6.415 -	path = join(dir, node);
   6.416 -	if (IS_ERR(path))
   6.417 -		return PTR_ERR(path);
   6.418 -
   6.419 -	ret = xs_error(xs_single(t, XS_RM, path, NULL));
   6.420 -	free(path);
   6.421 -	return ret;
   6.422 -}
   6.423 -
   6.424 -/* Start a transaction: changes by others will not be seen during this
   6.425 - * transaction, and changes will not be visible to others until end.
   6.426 - */
   6.427 -struct xenbus_transaction *xenbus_transaction_start(void)
   6.428 -{
   6.429 -	char *id_str;
   6.430 -	unsigned long id;
   6.431 -
   6.432 -	down_read(&xs_state.suspend_mutex);
   6.433 -
   6.434 -	id_str = xs_single(NULL, XS_TRANSACTION_START, "", NULL);
   6.435 -	if (IS_ERR(id_str)) {
   6.436 -		up_read(&xs_state.suspend_mutex);
   6.437 -		return (struct xenbus_transaction *)id_str;
   6.438 -	}
   6.439 -
   6.440 -	id = simple_strtoul(id_str, NULL, 0);
   6.441 -	free(id_str);
   6.442 -
   6.443 -	return (struct xenbus_transaction *)id;
   6.444 -}
   6.445 -
   6.446 -/* End a transaction.
   6.447 - * If abandon is true, transaction is discarded instead of committed.
   6.448 - */
   6.449 -int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
   6.450 -{
   6.451 -	char abortstr[2];
   6.452 -	int err;
   6.453 -
   6.454 -	if (abort)
   6.455 -		strcpy(abortstr, "F");
   6.456 -	else
   6.457 -		strcpy(abortstr, "T");
   6.458 -
   6.459 -	err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL));
   6.460 -
   6.461 -	up_read(&xs_state.suspend_mutex);
   6.462 -
   6.463 -	return err;
   6.464 -}
   6.465 -
   6.466 -/* Single read and scanf: returns -errno or num scanned. */
   6.467 -int xenbus_scanf(struct xenbus_transaction *t,
   6.468 -		 const char *dir, const char *node, const char *fmt, ...)
   6.469 -{
   6.470 -	va_list ap;
   6.471 -	int ret;
   6.472 -	char *val;
   6.473 -
   6.474 -	val = xenbus_read(t, dir, node, NULL);
   6.475 -	if (IS_ERR(val))
   6.476 -		return PTR_ERR(val);
   6.477 -
   6.478 -	va_start(ap, fmt);
   6.479 -	ret = vsscanf(val, fmt, ap);
   6.480 -	va_end(ap);
   6.481 -	free(val);
   6.482 -	/* Distinctive errno. */
   6.483 -	if (ret == 0)
   6.484 -		return -ERANGE;
   6.485 -	return ret;
   6.486 -}
   6.487 -
   6.488 -/* Single printf and write: returns -errno or 0. */
   6.489 -int xenbus_printf(struct xenbus_transaction *t,
   6.490 -		  const char *dir, const char *node, const char *fmt, ...)
   6.491 -{
   6.492 -	va_list ap;
   6.493 -	int ret;
   6.494 -#define PRINTF_BUFFER_SIZE 4096
   6.495 -	char *printf_buffer;
   6.496 -
   6.497 -	printf_buffer = malloc(PRINTF_BUFFER_SIZE);
   6.498 -	if (printf_buffer == NULL)
   6.499 -		return -ENOMEM;
   6.500 -
   6.501 -	va_start(ap, fmt);
   6.502 -	ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap);
   6.503 -	va_end(ap);
   6.504 -
   6.505 -	//	BUG_ON(ret > PRINTF_BUFFER_SIZE-1);
   6.506 -	ret = xenbus_write(t, dir, node, printf_buffer);
   6.507 -
   6.508 -	free(printf_buffer);
   6.509 -
   6.510 -	return ret;
   6.511 -}
   6.512 -
   6.513 -/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
   6.514 -int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
   6.515 -{
   6.516 -	va_list ap;
   6.517 -	const char *name;
   6.518 -	int ret = 0;
   6.519 -
   6.520 -	va_start(ap, dir);
   6.521 -	while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
   6.522 -		const char *fmt = va_arg(ap, char *);
   6.523 -		void *result = va_arg(ap, void *);
   6.524 -		char *p;
   6.525 -
   6.526 -		p = xenbus_read(t, dir, name, NULL);
   6.527 -		if (IS_ERR(p)) {
   6.528 -			ret = PTR_ERR(p);
   6.529 -			break;
   6.530 -		}
   6.531 -		if (fmt) {
   6.532 -			if (sscanf(p, fmt, result) == 0)
   6.533 -				ret = -EINVAL;
   6.534 -			free(p);
   6.535 -		} else
   6.536 -			*(char **)result = p;
   6.537 -	}
   6.538 -	va_end(ap);
   6.539 -	return ret;
   6.540 -}
   6.541 -
   6.542 -static int xs_watch(const char *path, const char *token)
   6.543 -{
   6.544 -	struct kvec iov[2];
   6.545 -
   6.546 -	iov[0].iov_base = (void *)path;
   6.547 -	iov[0].iov_len = strlen(path) + 1;
   6.548 -	iov[1].iov_base = (void *)token;
   6.549 -	iov[1].iov_len = strlen(token) + 1;
   6.550 -
   6.551 -	return xs_error(xs_talkv(NULL, XS_WATCH, iov,
   6.552 -				 ARRAY_SIZE(iov), NULL));
   6.553 -}
   6.554 -
   6.555 -static int xs_unwatch(const char *path, const char *token)
   6.556 -{
   6.557 -	struct kvec iov[2];
   6.558 -
   6.559 -	iov[0].iov_base = (char *)path;
   6.560 -	iov[0].iov_len = strlen(path) + 1;
   6.561 -	iov[1].iov_base = (char *)token;
   6.562 -	iov[1].iov_len = strlen(token) + 1;
   6.563 -
   6.564 -	return xs_error(xs_talkv(NULL, XS_UNWATCH, iov,
   6.565 -				 ARRAY_SIZE(iov), NULL));
   6.566 -}
   6.567 -
   6.568 -static struct xenbus_watch *find_watch(const char *token)
   6.569 -{
   6.570 -	struct xenbus_watch *i, *cmp;
   6.571 -
   6.572 -	cmp = (void *)simple_strtoul(token, NULL, 16);
   6.573 -
   6.574 -	list_for_each_entry(i, &watches, list)
   6.575 -		if (i == cmp)
   6.576 -			return i;
   6.577 -
   6.578 -	return NULL;
   6.579 -}
   6.580 -
   6.581 -/* Register callback to watch this node. */
   6.582 -int register_xenbus_watch(struct xenbus_watch *watch)
   6.583 -{
   6.584 -	/* Pointer in ascii is the token. */
   6.585 -	char token[sizeof(watch) * 2 + 1];
   6.586 -	int err;
   6.587 -
   6.588 -	sprintf(token, "%lX", (long)watch);
   6.589 -
   6.590 -	down_read(&xs_state.suspend_mutex);
   6.591 -
   6.592 -	spin_lock(&watches_lock);
   6.593 -	//	BUG_ON(find_watch(token));
   6.594 -	list_add(&watch->list, &watches);
   6.595 -	spin_unlock(&watches_lock);
   6.596 -
   6.597 -	err = xs_watch(watch->node, token);
   6.598 -
   6.599 -	/* Ignore errors due to multiple registration. */
   6.600 -	if ((err != 0) && (err != -EEXIST)) {
   6.601 -		spin_lock(&watches_lock);
   6.602 -		list_del(&watch->list);
   6.603 -		spin_unlock(&watches_lock);
   6.604 -	}
   6.605 -
   6.606 -	up_read(&xs_state.suspend_mutex);
   6.607 -
   6.608 -	return err;
   6.609 -}
   6.610 -
   6.611 -void unregister_xenbus_watch(struct xenbus_watch *watch)
   6.612 -{
   6.613 -	struct xs_stored_msg *msg, *tmp;
   6.614 -	char token[sizeof(watch) * 2 + 1];
   6.615 -	int err;
   6.616 -
   6.617 -	sprintf(token, "%lX", (long)watch);
   6.618 -
   6.619 -	down_read(&xs_state.suspend_mutex);
   6.620 -
   6.621 -	spin_lock(&watches_lock);
   6.622 -	//	BUG_ON(!find_watch(token));
   6.623 -	list_del(&watch->list);
   6.624 -	spin_unlock(&watches_lock);
   6.625 -
   6.626 -	err = xs_unwatch(watch->node, token);
   6.627 -	if (err)
   6.628 -		printk("XENBUS Failed to release watch %s: %i\n",
   6.629 -		       watch->node, err);
   6.630 -
   6.631 -	up_read(&xs_state.suspend_mutex);
   6.632 -
   6.633 -	/* Cancel pending watch events. */
   6.634 -	spin_lock(&watch_events_lock);
   6.635 -	list_for_each_entry_safe(msg, tmp, &watch_events, list) {
   6.636 -		if (msg->u.watch.handle != watch)
   6.637 -			continue;
   6.638 -		list_del(&msg->list);
   6.639 -		free(msg->u.watch.vec);
   6.640 -		free(msg);
   6.641 -	}
   6.642 -	spin_unlock(&watch_events_lock);
   6.643 -}
   6.644 -
   6.645 -void xs_suspend(void)
   6.646 -{
   6.647 -	down_write(&xs_state.suspend_mutex);
   6.648 -	down(&xs_state.request_mutex);
   6.649 -}
   6.650 -
   6.651 -void xs_resume(void)
   6.652 -{
   6.653 -	struct xenbus_watch *watch;
   6.654 -	char token[sizeof(watch) * 2 + 1];
   6.655 -
   6.656 -	up(&xs_state.request_mutex);
   6.657 -
   6.658 -	/* No need for watches_lock: the suspend_mutex is sufficient. */
   6.659 -	list_for_each_entry(watch, &watches, list) {
   6.660 -		sprintf(token, "%lX", (long)watch);
   6.661 -		xs_watch(watch->node, token);
   6.662 -	}
   6.663 -
   6.664 -	up_write(&xs_state.suspend_mutex);
   6.665 -}
   6.666 -
   6.667 -static void xenwatch_thread(void *unused)
   6.668 -{
   6.669 -	struct list_head *ent;
   6.670 -	struct xs_stored_msg *msg;
   6.671 -
   6.672 -	for (;;) {
   6.673 -		wait_event(watch_events_waitq,
   6.674 -			   !list_empty(&watch_events));
   6.675 -
   6.676 -		down(&xenwatch_mutex);
   6.677 -
   6.678 -		spin_lock(&watch_events_lock);
   6.679 -		ent = watch_events.next;
   6.680 -		if (ent != &watch_events)
   6.681 -			list_del(ent);
   6.682 -		spin_unlock(&watch_events_lock);
   6.683 -
   6.684 -		if (ent != &watch_events) {
   6.685 -			msg = list_entry(ent, struct xs_stored_msg, list);
   6.686 -			msg->u.watch.handle->callback(
   6.687 -				msg->u.watch.handle,
   6.688 -				(const char **)msg->u.watch.vec,
   6.689 -				msg->u.watch.vec_size);
   6.690 -			free(msg->u.watch.vec);
   6.691 -			free(msg);
   6.692 -		}
   6.693 -
   6.694 -		up(&xenwatch_mutex);
   6.695 -	}
   6.696 -}
   6.697 -
   6.698 -static int process_msg(void)
   6.699 -{
   6.700 -	struct xs_stored_msg *msg;
   6.701 -	char *body;
   6.702 -	int err;
   6.703 -
   6.704 -	msg = malloc(sizeof(*msg));
   6.705 -	if (msg == NULL)
   6.706 -		return -ENOMEM;
   6.707 -
   6.708 -	err = xb_read(&msg->hdr, sizeof(msg->hdr));
   6.709 -	if (err) {
   6.710 -		free(msg);
   6.711 -		return err;
   6.712 -	}
   6.713 -
   6.714 -	body = malloc(msg->hdr.len + 1);
   6.715 -	if (body == NULL) {
   6.716 -		free(msg);
   6.717 -		return -ENOMEM;
   6.718 -	}
   6.719 -
   6.720 -	err = xb_read(body, msg->hdr.len);
   6.721 -	if (err) {
   6.722 -		free(body);
   6.723 -		free(msg);
   6.724 -		return err;
   6.725 -	}
   6.726 -	body[msg->hdr.len] = '\0';
   6.727 -
   6.728 -	if (msg->hdr.type == XS_WATCH_EVENT) {
   6.729 -		msg->u.watch.vec = split(body, msg->hdr.len,
   6.730 -					 &msg->u.watch.vec_size);
   6.731 -		if (IS_ERR(msg->u.watch.vec)) {
   6.732 -			free(msg);
   6.733 -			return PTR_ERR(msg->u.watch.vec);
   6.734 -		}
   6.735 -
   6.736 -		spin_lock(&watches_lock);
   6.737 -		msg->u.watch.handle = find_watch(
   6.738 -			msg->u.watch.vec[XS_WATCH_TOKEN]);
   6.739 -		if (msg->u.watch.handle != NULL) {
   6.740 -			spin_lock(&watch_events_lock);
   6.741 -			list_add_tail(&msg->list, &watch_events);
   6.742 -			wake_up(&watch_events_waitq);
   6.743 -			spin_unlock(&watch_events_lock);
   6.744 -		} else {
   6.745 -			free(msg->u.watch.vec);
   6.746 -			free(msg);
   6.747 -		}
   6.748 -		spin_unlock(&watches_lock);
   6.749 -	} else {
   6.750 -		msg->u.reply.body = body;
   6.751 -		spin_lock(&xs_state.reply_lock);
   6.752 -		list_add_tail(&msg->list, &xs_state.reply_list);
   6.753 -		spin_unlock(&xs_state.reply_lock);
   6.754 -		wake_up(&xs_state.reply_waitq);
   6.755 -	}
   6.756 -
   6.757 -	return 0;
   6.758 -}
   6.759 -
   6.760 -static void xenbus_thread(void *unused)
   6.761 -{
   6.762 -	int err;
   6.763 -
   6.764 -	for (;;) {
   6.765 -		err = process_msg();
   6.766 -		if (err)
   6.767 -			printk("XENBUS error %d while reading "
   6.768 -			       "message\n", err);
   6.769 -	}
   6.770 -}
   6.771 -
   6.772 -int xs_init(void)
   6.773 -{
   6.774 -	int err;
   6.775 -	struct thread *kxwatcher_thread;
   6.776 -	struct thread *kxenbus_thread;
   6.777 -
   6.778 -	INIT_LIST_HEAD(&xs_state.reply_list);
   6.779 -	spin_lock_init(&xs_state.reply_lock);
   6.780 -	init_waitqueue_head(&xs_state.reply_waitq);
   6.781 -
   6.782 -	init_MUTEX(&xs_state.request_mutex);
   6.783 -	init_rwsem(&xs_state.suspend_mutex);
   6.784 -
   6.785 -	/* Initialize the shared memory rings to talk to xenstored */
   6.786 -	err = xb_init_comms();
   6.787 -	if (err)
   6.788 -		return err;
   6.789 -
   6.790 -	kxwatcher_thread = create_thread("kxwatch", xenwatch_thread, NULL);
   6.791 -	if (IS_ERR(kxwatcher_thread))
   6.792 -		return PTR_ERR(kxwatcher_thread);
   6.793 -
   6.794 -	kxenbus_thread = create_thread("kxenbus", xenbus_thread, NULL);
   6.795 -	if (IS_ERR(kxenbus_thread))
   6.796 -		return PTR_ERR(kxenbus_thread);
   6.797 -
   6.798 -	return 0;
   6.799 -}