ia64/xen-unstable

view linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c @ 13835:1e56ac73b9b9

linux: Allow xenbus_strstate() to be used from modules.

The function is referenced by a number of DPRINTK()-s. Also, properly
const-ify it.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author kfraser@localhost.localdomain
date Fri Feb 02 16:04:11 2007 +0000 (2007-02-02)
parents d275951acf10
children
line source
1 /******************************************************************************
2 * Client-facing interface for the Xenbus driver. In other words, the
3 * interface between the Xenbus and the device-specific code, be it the
4 * frontend or the backend of that driver.
5 *
6 * Copyright (C) 2005 XenSource Ltd
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation; or, when distributed
11 * separately from the Linux kernel or incorporated into other
12 * software packages, subject to the following license:
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this source file (the "Software"), to deal in the Software without
16 * restriction, including without limitation the rights to use, copy, modify,
17 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
18 * and to permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 * IN THE SOFTWARE.
31 */
33 #include <xen/evtchn.h>
34 #include <xen/gnttab.h>
35 #include <xen/xenbus.h>
36 #include <xen/driver_util.h>
38 #ifdef HAVE_XEN_PLATFORM_COMPAT_H
39 #include <xen/platform-compat.h>
40 #endif
42 #define DPRINTK(fmt, args...) \
43 pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
45 const char *xenbus_strstate(enum xenbus_state state)
46 {
47 static const char *const name[] = {
48 [ XenbusStateUnknown ] = "Unknown",
49 [ XenbusStateInitialising ] = "Initialising",
50 [ XenbusStateInitWait ] = "InitWait",
51 [ XenbusStateInitialised ] = "Initialised",
52 [ XenbusStateConnected ] = "Connected",
53 [ XenbusStateClosing ] = "Closing",
54 [ XenbusStateClosed ] = "Closed",
55 };
56 return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
57 }
58 EXPORT_SYMBOL_GPL(xenbus_strstate);
60 int xenbus_watch_path(struct xenbus_device *dev, const char *path,
61 struct xenbus_watch *watch,
62 void (*callback)(struct xenbus_watch *,
63 const char **, unsigned int))
64 {
65 int err;
67 watch->node = path;
68 watch->callback = callback;
70 err = register_xenbus_watch(watch);
72 if (err) {
73 watch->node = NULL;
74 watch->callback = NULL;
75 xenbus_dev_fatal(dev, err, "adding watch on %s", path);
76 }
78 return err;
79 }
80 EXPORT_SYMBOL_GPL(xenbus_watch_path);
83 int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
84 const char *path2, struct xenbus_watch *watch,
85 void (*callback)(struct xenbus_watch *,
86 const char **, unsigned int))
87 {
88 int err;
89 char *state = kasprintf(GFP_KERNEL, "%s/%s", path, path2);
90 if (!state) {
91 xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch");
92 return -ENOMEM;
93 }
94 err = xenbus_watch_path(dev, state, watch, callback);
96 if (err)
97 kfree(state);
98 return err;
99 }
100 EXPORT_SYMBOL_GPL(xenbus_watch_path2);
103 int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
104 {
105 /* We check whether the state is currently set to the given value, and
106 if not, then the state is set. We don't want to unconditionally
107 write the given state, because we don't want to fire watches
108 unnecessarily. Furthermore, if the node has gone, we don't write
109 to it, as the device will be tearing down, and we don't want to
110 resurrect that directory.
112 Note that, because of this cached value of our state, this function
113 will not work inside a Xenstore transaction (something it was
114 trying to in the past) because dev->state would not get reset if
115 the transaction was aborted.
117 */
119 int current_state;
120 int err;
122 if (state == dev->state)
123 return 0;
125 err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d",
126 &current_state);
127 if (err != 1)
128 return 0;
130 err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state);
131 if (err) {
132 if (state != XenbusStateClosing) /* Avoid looping */
133 xenbus_dev_fatal(dev, err, "writing new state");
134 return err;
135 }
137 dev->state = state;
139 return 0;
140 }
141 EXPORT_SYMBOL_GPL(xenbus_switch_state);
143 int xenbus_frontend_closed(struct xenbus_device *dev)
144 {
145 xenbus_switch_state(dev, XenbusStateClosed);
146 complete(&dev->down);
147 return 0;
148 }
149 EXPORT_SYMBOL_GPL(xenbus_frontend_closed);
151 /**
152 * Return the path to the error node for the given device, or NULL on failure.
153 * If the value returned is non-NULL, then it is the caller's to kfree.
154 */
155 static char *error_path(struct xenbus_device *dev)
156 {
157 return kasprintf(GFP_KERNEL, "error/%s", dev->nodename);
158 }
161 void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
162 va_list ap)
163 {
164 int ret;
165 unsigned int len;
166 char *printf_buffer = NULL, *path_buffer = NULL;
168 #define PRINTF_BUFFER_SIZE 4096
169 printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
170 if (printf_buffer == NULL)
171 goto fail;
173 len = sprintf(printf_buffer, "%i ", -err);
174 ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);
176 BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
178 dev_err(&dev->dev, "%s\n", printf_buffer);
180 path_buffer = error_path(dev);
182 if (path_buffer == NULL) {
183 printk("xenbus: failed to write error node for %s (%s)\n",
184 dev->nodename, printf_buffer);
185 goto fail;
186 }
188 if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
189 printk("xenbus: failed to write error node for %s (%s)\n",
190 dev->nodename, printf_buffer);
191 goto fail;
192 }
194 fail:
195 if (printf_buffer)
196 kfree(printf_buffer);
197 if (path_buffer)
198 kfree(path_buffer);
199 }
202 void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
203 ...)
204 {
205 va_list ap;
207 va_start(ap, fmt);
208 _dev_error(dev, err, fmt, ap);
209 va_end(ap);
210 }
211 EXPORT_SYMBOL_GPL(xenbus_dev_error);
214 void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
215 ...)
216 {
217 va_list ap;
219 va_start(ap, fmt);
220 _dev_error(dev, err, fmt, ap);
221 va_end(ap);
223 xenbus_switch_state(dev, XenbusStateClosing);
224 }
225 EXPORT_SYMBOL_GPL(xenbus_dev_fatal);
228 int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn)
229 {
230 int err = gnttab_grant_foreign_access(dev->otherend_id, ring_mfn, 0);
231 if (err < 0)
232 xenbus_dev_fatal(dev, err, "granting access to ring page");
233 return err;
234 }
235 EXPORT_SYMBOL_GPL(xenbus_grant_ring);
238 int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
239 {
240 struct evtchn_alloc_unbound alloc_unbound;
241 int err;
243 alloc_unbound.dom = DOMID_SELF;
244 alloc_unbound.remote_dom = dev->otherend_id;
246 err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
247 &alloc_unbound);
248 if (err)
249 xenbus_dev_fatal(dev, err, "allocating event channel");
250 else
251 *port = alloc_unbound.port;
253 return err;
254 }
255 EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
258 int xenbus_free_evtchn(struct xenbus_device *dev, int port)
259 {
260 struct evtchn_close close;
261 int err;
263 close.port = port;
265 err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
266 if (err)
267 xenbus_dev_error(dev, err, "freeing event channel %d", port);
269 return err;
270 }
271 EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
274 enum xenbus_state xenbus_read_driver_state(const char *path)
275 {
276 enum xenbus_state result;
277 int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
278 if (err)
279 result = XenbusStateUnknown;
281 return result;
282 }
283 EXPORT_SYMBOL_GPL(xenbus_read_driver_state);