]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - sys/xen/xenbus/xenbusb.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / sys / xen / xenbus / xenbusb.c
1 /******************************************************************************
2  * Copyright (C) 2010 Spectra Logic Corporation
3  * Copyright (C) 2008 Doug Rabson
4  * Copyright (C) 2005 Rusty Russell, IBM Corporation
5  * Copyright (C) 2005 Mike Wray, Hewlett-Packard
6  * Copyright (C) 2005 XenSource Ltd
7  * 
8  * This file may be distributed separately from the Linux kernel, or
9  * incorporated into other software packages, subject to the following license:
10  * 
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this source file (the "Software"), to deal in the Software without
13  * restriction, including without limitation the rights to use, copy, modify,
14  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
15  * and to permit persons to whom the Software is furnished to do so, subject to
16  * the following conditions:
17  * 
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  * 
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27  * IN THE SOFTWARE.
28  */
29
30 /**
31  * \file xenbusb.c
32  *
33  * \brief Shared support functions for managing the NewBus busses that contain
34  *        Xen front and back end device instances.
35  *
36  * The NewBus implementation of XenBus attaches a xenbusb_front and xenbusb_back
37  * child bus to the xenstore device.  This strategy allows the small differences
38  * in the handling of XenBus operations for front and back devices to be handled
39  * as overrides in xenbusb_front/back.c.  Front and back specific device
40  * classes are also provided so device drivers can register for the devices they
41  * can handle without the need to filter within their probe routines.  The
42  * net result is a device hierarchy that might look like this:
43  *
44  * xenstore0/
45  *           xenbusb_front0/
46  *                         xn0
47  *                         xbd0
48  *                         xbd1
49  *           xenbusb_back0/
50  *                        xbbd0
51  *                        xnb0
52  *                        xnb1
53  */
54 #include <sys/cdefs.h>
55 __FBSDID("$FreeBSD$");
56
57 #include <sys/param.h>
58 #include <sys/bus.h>
59 #include <sys/kernel.h>
60 #include <sys/lock.h>
61 #include <sys/malloc.h>
62 #include <sys/module.h>
63 #include <sys/sbuf.h>
64 #include <sys/sysctl.h>
65 #include <sys/syslog.h>
66 #include <sys/systm.h>
67 #include <sys/sx.h>
68 #include <sys/taskqueue.h>
69
70 #include <machine/xen/xen-os.h>
71 #include <machine/stdarg.h>
72
73 #include <xen/gnttab.h>
74 #include <xen/xenstore/xenstorevar.h>
75 #include <xen/xenbus/xenbusb.h>
76 #include <xen/xenbus/xenbusvar.h>
77
78 /*------------------------- Private Functions --------------------------------*/
79 /**
80  * \brief Deallocate XenBus device instance variables.
81  *
82  * \param ivars  The instance variable block to free.
83  */
84 static void
85 xenbusb_free_child_ivars(struct xenbus_device_ivars *ivars)
86 {
87         if (ivars->xd_otherend_watch.node != NULL) {
88                 xs_unregister_watch(&ivars->xd_otherend_watch);
89                 free(ivars->xd_otherend_watch.node, M_XENBUS);
90                 ivars->xd_otherend_watch.node = NULL;
91         }
92
93         if (ivars->xd_local_watch.node != NULL) {
94                 xs_unregister_watch(&ivars->xd_local_watch);
95                 ivars->xd_local_watch.node = NULL;
96         }
97
98         if (ivars->xd_node != NULL) {
99                 free(ivars->xd_node, M_XENBUS);
100                 ivars->xd_node = NULL;
101         }
102         ivars->xd_node_len = 0;
103
104         if (ivars->xd_type != NULL) {
105                 free(ivars->xd_type, M_XENBUS);
106                 ivars->xd_type = NULL;
107         }
108
109         if (ivars->xd_otherend_path != NULL) {
110                 free(ivars->xd_otherend_path, M_XENBUS);
111                 ivars->xd_otherend_path = NULL;
112         }
113         ivars->xd_otherend_path_len = 0;
114
115         free(ivars, M_XENBUS);
116 }
117
118 /**
119  * XenBus watch callback registered against the "state" XenStore
120  * node of the other-end of a split device connection.
121  *
122  * This callback is invoked whenever the state of a device instance's
123  * peer changes.
124  *
125  * \param watch      The xs_watch object used to register this callback
126  *                   function.
127  * \param vec        An array of pointers to NUL terminated strings containing
128  *                   watch event data.  The vector should be indexed via the
129  *                   xs_watch_type enum in xs_wire.h.
130  * \param vec_size   The number of elements in vec.
131  */
132 static void
133 xenbusb_otherend_watch_cb(struct xs_watch *watch, const char **vec,
134     unsigned int vec_size __unused)
135 {
136         struct xenbus_device_ivars *ivars;
137         device_t child;
138         device_t bus;
139         const char *path;
140         enum xenbus_state newstate;
141
142         ivars = (struct xenbus_device_ivars *)watch->callback_data;
143         child = ivars->xd_dev;
144         bus = device_get_parent(child);
145
146         path = vec[XS_WATCH_PATH];
147         if (ivars->xd_otherend_path == NULL
148          || strncmp(ivars->xd_otherend_path, path, ivars->xd_otherend_path_len))
149                 return;
150
151         newstate = xenbus_read_driver_state(ivars->xd_otherend_path);
152         XENBUSB_OTHEREND_CHANGED(bus, child, newstate);
153 }
154
155 /**
156  * XenBus watch callback registered against the XenStore sub-tree
157  * represnting the local half of a split device connection.
158  *
159  * This callback is invoked whenever any XenStore data in the subtree
160  * is modified, either by us or another privledged domain.
161  *
162  * \param watch      The xs_watch object used to register this callback
163  *                   function.
164  * \param vec        An array of pointers to NUL terminated strings containing
165  *                   watch event data.  The vector should be indexed via the
166  *                   xs_watch_type enum in xs_wire.h.
167  * \param vec_size   The number of elements in vec.
168  *
169  */
170 static void
171 xenbusb_local_watch_cb(struct xs_watch *watch, const char **vec,
172     unsigned int vec_size __unused)
173 {
174         struct xenbus_device_ivars *ivars;
175         device_t child;
176         device_t bus;
177         const char *path;
178
179         ivars = (struct xenbus_device_ivars *)watch->callback_data;
180         child = ivars->xd_dev;
181         bus = device_get_parent(child);
182
183         path = vec[XS_WATCH_PATH];
184         if (ivars->xd_node == NULL
185          || strncmp(ivars->xd_node, path, ivars->xd_node_len))
186                 return;
187
188         XENBUSB_LOCALEND_CHANGED(bus, child, &path[ivars->xd_node_len]);
189 }
190
191 /**
192  * Search our internal record of configured devices (not the XenStore)
193  * to determine if the XenBus device indicated by \a node is known to
194  * the system.
195  *
196  * \param dev   The XenBus bus instance to search for device children.
197  * \param node  The XenStore node path for the device to find.
198  *
199  * \return  The device_t of the found device if any, or NULL.
200  *
201  * \note device_t is a pointer type, so it can be compared against
202  *       NULL for validity. 
203  */
204 static device_t
205 xenbusb_device_exists(device_t dev, const char *node)
206 {
207         device_t *kids;
208         device_t result;
209         struct xenbus_device_ivars *ivars;
210         int i, count;
211
212         if (device_get_children(dev, &kids, &count))
213                 return (FALSE);
214
215         result = NULL;
216         for (i = 0; i < count; i++) {
217                 ivars = device_get_ivars(kids[i]);
218                 if (!strcmp(ivars->xd_node, node)) {
219                         result = kids[i];
220                         break;
221                 }
222         }
223         free(kids, M_TEMP);
224
225         return (result);
226 }
227
228 static void
229 xenbusb_delete_child(device_t dev, device_t child)
230 {
231         struct xenbus_device_ivars *ivars;
232
233         ivars = device_get_ivars(child);
234
235         /*
236          * We no longer care about the otherend of the
237          * connection.  Cancel the watches now so that we
238          * don't try to handle an event for a partially
239          * detached child.
240          */
241         if (ivars->xd_otherend_watch.node != NULL)
242                 xs_unregister_watch(&ivars->xd_otherend_watch);
243         if (ivars->xd_local_watch.node != NULL)
244                 xs_unregister_watch(&ivars->xd_local_watch);
245         
246         device_delete_child(dev, child);
247         xenbusb_free_child_ivars(ivars);
248 }
249
250 /**
251  * \param dev    The NewBus device representing this XenBus bus.
252  * \param child  The NewBus device representing a child of dev%'s XenBus bus.
253  */
254 static void
255 xenbusb_verify_device(device_t dev, device_t child)
256 {
257         if (xs_exists(XST_NIL, xenbus_get_node(child), "") == 0) {
258
259                 /*
260                  * Device tree has been removed from Xenbus.
261                  * Tear down the device.
262                  */
263                 xenbusb_delete_child(dev, child);
264         }
265 }
266
267 /**
268  * \brief Enumerate the devices on a XenBus bus and register them with
269  *        the NewBus device tree.
270  *
271  * xenbusb_enumerate_bus() will create entries (in state DS_NOTPRESENT)
272  * for nodes that appear in the XenStore, but will not invoke probe/attach
273  * operations on drivers.  Probe/Attach processing must be separately
274  * performed via an invocation of xenbusb_probe_children().  This is usually
275  * done via the xbs_probe_children task.
276  *
277  * \param xbs  XenBus Bus device softc of the owner of the bus to enumerate.
278  *
279  * \return  On success, 0. Otherwise an errno value indicating the
280  *          type of failure.
281  */
282 static int
283 xenbusb_enumerate_bus(struct xenbusb_softc *xbs)
284 {
285         const char **types;
286         u_int type_idx;
287         u_int type_count;
288         int error;
289
290         error = xs_directory(XST_NIL, xbs->xbs_node, "", &type_count, &types);
291         if (error)
292                 return (error);
293
294         for (type_idx = 0; type_idx < type_count; type_idx++)
295                 XENBUSB_ENUMERATE_TYPE(xbs->xbs_dev, types[type_idx]);
296
297         free(types, M_XENSTORE);
298
299         return (0);
300 }
301
302 /**
303  * Handler for all generic XenBus device systcl nodes.
304  */
305 static int
306 xenbusb_device_sysctl_handler(SYSCTL_HANDLER_ARGS)  
307 {
308         device_t dev;
309         const char *value;
310
311         dev = (device_t)arg1;
312         switch (arg2) {
313         case XENBUS_IVAR_NODE:
314                 value = xenbus_get_node(dev);
315                 break;
316         case XENBUS_IVAR_TYPE:
317                 value = xenbus_get_type(dev);
318                 break;
319         case XENBUS_IVAR_STATE:
320                 value = xenbus_strstate(xenbus_get_state(dev));
321                 break;
322         case XENBUS_IVAR_OTHEREND_ID:
323                 return (sysctl_handle_int(oidp, NULL,
324                                           xenbus_get_otherend_id(dev),
325                                           req));
326                 /* NOTREACHED */
327         case XENBUS_IVAR_OTHEREND_PATH:
328                 value = xenbus_get_otherend_path(dev);
329                 break;
330         default:
331                 return (EINVAL);
332         }
333         return (SYSCTL_OUT(req, value, strlen(value)));
334 }
335
336 /**
337  * Create read-only systcl nodes for xenbusb device ivar data.
338  *
339  * \param dev  The XenBus device instance to register with sysctl.
340  */
341 static void
342 xenbusb_device_sysctl_init(device_t dev)
343 {
344         struct sysctl_ctx_list *ctx;
345         struct sysctl_oid      *tree;
346
347         ctx  = device_get_sysctl_ctx(dev);
348         tree = device_get_sysctl_tree(dev);
349
350         SYSCTL_ADD_PROC(ctx,
351                         SYSCTL_CHILDREN(tree),
352                         OID_AUTO,
353                         "xenstore_path",
354                         CTLTYPE_STRING | CTLFLAG_RD,
355                         dev,
356                         XENBUS_IVAR_NODE,
357                         xenbusb_device_sysctl_handler,
358                         "A",
359                         "XenStore path to device");
360
361         SYSCTL_ADD_PROC(ctx,
362                         SYSCTL_CHILDREN(tree),
363                         OID_AUTO,
364                         "xenbus_dev_type",
365                         CTLTYPE_STRING | CTLFLAG_RD,
366                         dev,
367                         XENBUS_IVAR_TYPE,
368                         xenbusb_device_sysctl_handler,
369                         "A",
370                         "XenBus device type");
371
372         SYSCTL_ADD_PROC(ctx,
373                         SYSCTL_CHILDREN(tree),
374                         OID_AUTO,
375                         "xenbus_connection_state",
376                         CTLTYPE_STRING | CTLFLAG_RD,
377                         dev,
378                         XENBUS_IVAR_STATE,
379                         xenbusb_device_sysctl_handler,
380                         "A",
381                         "XenBus state of peer connection");
382
383         SYSCTL_ADD_PROC(ctx,
384                         SYSCTL_CHILDREN(tree),
385                         OID_AUTO,
386                         "xenbus_peer_domid",
387                         CTLTYPE_INT | CTLFLAG_RD,
388                         dev,
389                         XENBUS_IVAR_OTHEREND_ID,
390                         xenbusb_device_sysctl_handler,
391                         "I",
392                         "Xen domain ID of peer");
393
394         SYSCTL_ADD_PROC(ctx,
395                         SYSCTL_CHILDREN(tree),
396                         OID_AUTO,
397                         "xenstore_peer_path",
398                         CTLTYPE_STRING | CTLFLAG_RD,
399                         dev,
400                         XENBUS_IVAR_OTHEREND_PATH,
401                         xenbusb_device_sysctl_handler,
402                         "A",
403                         "XenStore path to peer device");
404 }
405
406 /**
407  * \brief Verify the existance of attached device instances and perform
408  *        probe/attach processing for newly arrived devices.
409  *
410  * \param dev  The NewBus device representing this XenBus bus.
411  *
412  * \return  On success, 0. Otherwise an errno value indicating the
413  *          type of failure.
414  */
415 static int
416 xenbusb_probe_children(device_t dev)
417 {
418         device_t *kids;
419         struct xenbus_device_ivars *ivars;
420         int i, count;
421
422         if (device_get_children(dev, &kids, &count) == 0) {
423                 for (i = 0; i < count; i++) {
424                         if (device_get_state(kids[i]) != DS_NOTPRESENT) {
425                                 /*
426                                  * We already know about this one.
427                                  * Make sure it's still here.
428                                  */
429                                 xenbusb_verify_device(dev, kids[i]);
430                                 continue;
431                         }
432
433                         if (device_probe_and_attach(kids[i])) {
434                                 /*
435                                  * Transition device to the closed state
436                                  * so the world knows that attachment will
437                                  * not occur.
438                                  */
439                                 xenbus_set_state(kids[i], XenbusStateClosed);
440
441                                 /*
442                                  * Remove our record of this device.
443                                  * So long as it remains in the closed
444                                  * state in the XenStore, we will not find
445                                  * it again.  The state will only change
446                                  * if the control domain actively reconfigures
447                                  * this device.
448                                  */
449                                 xenbusb_delete_child(dev, kids[i]);
450
451                                 continue;
452                         }
453                         /*
454                          * Augment default newbus provided dynamic sysctl
455                          * variables with the standard ivar contents of
456                          * XenBus devices.
457                          */
458                         xenbusb_device_sysctl_init(kids[i]);
459
460                         /*
461                          * Now that we have a driver managing this device
462                          * that can receive otherend state change events,
463                          * hook up a watch for them.
464                          */
465                         ivars = device_get_ivars(kids[i]);
466                         xs_register_watch(&ivars->xd_otherend_watch);
467                         xs_register_watch(&ivars->xd_local_watch);
468                 }
469                 free(kids, M_TEMP);
470         }
471
472         return (0);
473 }
474
475 /**
476  * \brief Task callback function to perform XenBus probe operations
477  *        from a known safe context.
478  *
479  * \param arg      The NewBus device_t representing the bus instance to
480  *                 on which to perform probe processing.
481  * \param pending  The number of times this task was queued before it could
482  *                 be run.
483  */
484 static void
485 xenbusb_probe_children_cb(void *arg, int pending __unused)
486 {
487         device_t dev = (device_t)arg;
488
489         /*
490          * Hold Giant until the Giant free newbus changes are committed.
491          */
492         mtx_lock(&Giant);
493         xenbusb_probe_children(dev);
494         mtx_unlock(&Giant);
495 }
496
497 /**
498  * \brief XenStore watch callback for the root node of the XenStore
499  *        subtree representing a XenBus.
500  *
501  * This callback performs, or delegates to the xbs_probe_children task,
502  * all processing necessary to handle dynmaic device arrival and departure
503  * events from a XenBus.
504  *
505  * \param watch  The XenStore watch object associated with this callback.
506  * \param vec    The XenStore watch event data.
507  * \param len    The number of fields in the event data stream.
508  */
509 static void
510 xenbusb_devices_changed(struct xs_watch *watch, const char **vec,
511                         unsigned int len)
512 {
513         struct xenbusb_softc *xbs;
514         device_t dev;
515         char *node;
516         char *bus;
517         char *type;
518         char *id;
519         char *p;
520         u_int component;
521
522         xbs = (struct xenbusb_softc *)watch->callback_data;
523         dev = xbs->xbs_dev;
524
525         if (len <= XS_WATCH_PATH) {
526                 device_printf(dev, "xenbusb_devices_changed: "
527                               "Short Event Data.\n");
528                 return;
529         }
530
531         node = strdup(vec[XS_WATCH_PATH], M_XENBUS);
532         p = strchr(node, '/');
533         if (p == NULL)
534                 goto out;
535         bus = node;
536         *p = 0;
537         type = p + 1;
538
539         p = strchr(type, '/');
540         if (p == NULL)
541                 goto out;
542         *p++ = 0;
543
544         /*
545          * Extract the device ID.  A device ID has one or more path
546          * components separated by the '/' character.
547          *
548          * e.g. "<frontend vm id>/<frontend dev id>" for backend devices.
549          */
550         id = p;
551         for (component = 0; component < xbs->xbs_id_components; component++) {
552                 p = strchr(p, '/');
553                 if (p == NULL)
554                         break;
555                 p++;
556         }
557         if (p != NULL)
558                 *p = 0;
559
560         if (*id != 0 && component >= xbs->xbs_id_components - 1) {
561                 xenbusb_add_device(xbs->xbs_dev, type, id);
562                 taskqueue_enqueue(taskqueue_thread, &xbs->xbs_probe_children);
563         }
564 out:
565         free(node, M_XENBUS);
566 }
567
568 /**
569  * \brief Interrupt configuration hook callback associated with xbs_attch_ch.
570  *
571  * Since interrupts are always functional at the time of XenBus configuration,
572  * there is nothing to be done when the callback occurs.  This hook is only
573  * registered to hold up boot processing while XenBus devices come online.
574  * 
575  * \param arg  Unused configuration hook callback argument.
576  */
577 static void
578 xenbusb_nop_confighook_cb(void *arg __unused)
579 {
580 }
581
582 /**
583  * \brief Decrement the number of XenBus child devices in the
584  *        connecting state by one and release the xbs_attch_ch
585  *        interrupt configuration hook if the connecting count
586  *        drops to zero.
587  *
588  * \param xbs  XenBus Bus device softc of the owner of the bus to enumerate.
589  */
590 static void
591 xenbusb_release_confighook(struct xenbusb_softc *xbs)
592 {
593         mtx_lock(&xbs->xbs_lock);
594         KASSERT(xbs->xbs_connecting_children > 0,
595                 ("Connecting device count error\n"));
596         xbs->xbs_connecting_children--;
597         if (xbs->xbs_connecting_children == 0
598          && (xbs->xbs_flags & XBS_ATTACH_CH_ACTIVE) != 0) {
599                 xbs->xbs_flags &= ~XBS_ATTACH_CH_ACTIVE;
600                 mtx_unlock(&xbs->xbs_lock);
601                 config_intrhook_disestablish(&xbs->xbs_attach_ch);
602         } else {
603                 mtx_unlock(&xbs->xbs_lock);
604         }
605 }
606
607 /*--------------------------- Public Functions -------------------------------*/
608 /*--------- API comments for these methods can be found in xenbusb.h ---------*/
609 void
610 xenbusb_identify(driver_t *driver __unused, device_t parent)
611 {
612         /*
613          * A single instance of each bus type for which we have a driver
614          * is always present in a system operating under Xen.
615          */
616         BUS_ADD_CHILD(parent, 0, driver->name, 0);
617 }
618
619 int
620 xenbusb_add_device(device_t dev, const char *type, const char *id)
621 {
622         struct xenbusb_softc *xbs;
623         struct sbuf *devpath_sbuf;
624         char *devpath;
625         struct xenbus_device_ivars *ivars;
626         int error;
627
628         xbs = device_get_softc(dev);
629         devpath_sbuf = sbuf_new_auto();
630         sbuf_printf(devpath_sbuf, "%s/%s/%s", xbs->xbs_node, type, id);
631         sbuf_finish(devpath_sbuf);
632         devpath = sbuf_data(devpath_sbuf);
633
634         ivars = malloc(sizeof(*ivars), M_XENBUS, M_ZERO|M_WAITOK);
635         error = ENXIO;
636
637         if (xs_exists(XST_NIL, devpath, "") != 0) {
638                 device_t child;
639                 enum xenbus_state state;
640                 char *statepath;
641
642                 child = xenbusb_device_exists(dev, devpath);
643                 if (child != NULL) {
644                         /*
645                          * We are already tracking this node
646                          */
647                         error = 0;
648                         goto out;
649                 }
650                         
651                 state = xenbus_read_driver_state(devpath);
652                 if (state != XenbusStateInitialising) {
653                         /*
654                          * Device is not new, so ignore it. This can
655                          * happen if a device is going away after
656                          * switching to Closed.
657                          */
658                         printf("xenbusb_add_device: Device %s ignored. "
659                                "State %d\n", devpath, state);
660                         error = 0;
661                         goto out;
662                 }
663
664                 sx_init(&ivars->xd_lock, "xdlock");
665                 ivars->xd_flags = XDF_CONNECTING;
666                 ivars->xd_node = strdup(devpath, M_XENBUS);
667                 ivars->xd_node_len = strlen(devpath);
668                 ivars->xd_type  = strdup(type, M_XENBUS);
669                 ivars->xd_state = XenbusStateInitialising;
670
671                 error = XENBUSB_GET_OTHEREND_NODE(dev, ivars);
672                 if (error) {
673                         printf("xenbus_update_device: %s no otherend id\n",
674                             devpath); 
675                         goto out;
676                 }
677
678                 statepath = malloc(ivars->xd_otherend_path_len
679                     + strlen("/state") + 1, M_XENBUS, M_WAITOK);
680                 sprintf(statepath, "%s/state", ivars->xd_otherend_path);
681                 ivars->xd_otherend_watch.node = statepath;
682                 ivars->xd_otherend_watch.callback = xenbusb_otherend_watch_cb;
683                 ivars->xd_otherend_watch.callback_data = (uintptr_t)ivars;
684
685                 ivars->xd_local_watch.node = ivars->xd_node;
686                 ivars->xd_local_watch.callback = xenbusb_local_watch_cb;
687                 ivars->xd_local_watch.callback_data = (uintptr_t)ivars;
688
689                 mtx_lock(&xbs->xbs_lock);
690                 xbs->xbs_connecting_children++;
691                 mtx_unlock(&xbs->xbs_lock);
692
693                 child = device_add_child(dev, NULL, -1);
694                 ivars->xd_dev = child;
695                 device_set_ivars(child, ivars);
696         }
697
698 out:
699         sbuf_delete(devpath_sbuf);
700         if (error != 0)
701                 xenbusb_free_child_ivars(ivars);
702
703         return (error);
704 }
705
706 int
707 xenbusb_attach(device_t dev, char *bus_node, u_int id_components)
708 {
709         struct xenbusb_softc *xbs;
710
711         xbs = device_get_softc(dev);
712         mtx_init(&xbs->xbs_lock, "xenbusb softc lock", NULL, MTX_DEF);
713         xbs->xbs_node = bus_node;
714         xbs->xbs_id_components = id_components;
715         xbs->xbs_dev = dev;
716
717         /*
718          * Since XenBus busses are attached to the XenStore, and
719          * the XenStore does not probe children until after interrupt
720          * services are available, this config hook is used solely
721          * to ensure that the remainder of the boot process (e.g.
722          * mount root) is deferred until child devices are adequately
723          * probed.  We unblock the boot process as soon as the
724          * connecting child count in our softc goes to 0.
725          */
726         xbs->xbs_attach_ch.ich_func = xenbusb_nop_confighook_cb;
727         xbs->xbs_attach_ch.ich_arg = dev;
728         config_intrhook_establish(&xbs->xbs_attach_ch);
729         xbs->xbs_flags |= XBS_ATTACH_CH_ACTIVE;
730         xbs->xbs_connecting_children = 1;
731
732         /*
733          * The subtree for this bus type may not yet exist
734          * causing initial enumeration to fail.  We still
735          * want to return success from our attach though
736          * so that we are ready to handle devices for this
737          * bus when they are dynamically attached to us
738          * by a Xen management action.
739          */
740         (void)xenbusb_enumerate_bus(xbs);
741         xenbusb_probe_children(dev);
742
743         xbs->xbs_device_watch.node = bus_node;
744         xbs->xbs_device_watch.callback = xenbusb_devices_changed;
745         xbs->xbs_device_watch.callback_data = (uintptr_t)xbs;
746
747         TASK_INIT(&xbs->xbs_probe_children, 0, xenbusb_probe_children_cb, dev);
748
749         xs_register_watch(&xbs->xbs_device_watch);
750
751         xenbusb_release_confighook(xbs);
752
753         return (0);
754 }
755
756 int
757 xenbusb_resume(device_t dev)
758 {
759         device_t *kids;
760         struct xenbus_device_ivars *ivars;
761         int i, count, error;
762         char *statepath;
763
764         /*
765          * We must re-examine each device and find the new path for
766          * its backend.
767          */
768         if (device_get_children(dev, &kids, &count) == 0) {
769                 for (i = 0; i < count; i++) {
770                         if (device_get_state(kids[i]) == DS_NOTPRESENT)
771                                 continue;
772
773                         ivars = device_get_ivars(kids[i]);
774
775                         xs_unregister_watch(&ivars->xd_otherend_watch);
776                         xenbus_set_state(kids[i], XenbusStateInitialising);
777
778                         /*
779                          * Find the new backend details and
780                          * re-register our watch.
781                          */
782                         error = XENBUSB_GET_OTHEREND_NODE(dev, ivars);
783                         if (error)
784                                 return (error);
785
786                         statepath = malloc(ivars->xd_otherend_path_len
787                             + strlen("/state") + 1, M_XENBUS, M_WAITOK);
788                         sprintf(statepath, "%s/state", ivars->xd_otherend_path);
789
790                         free(ivars->xd_otherend_watch.node, M_XENBUS);
791                         ivars->xd_otherend_watch.node = statepath;
792
793                         DEVICE_RESUME(kids[i]);
794
795                         xs_register_watch(&ivars->xd_otherend_watch);
796 #if 0
797                         /*
798                          * Can't do this yet since we are running in
799                          * the xenwatch thread and if we sleep here,
800                          * we will stop delivering watch notifications
801                          * and the device will never come back online.
802                          */
803                         sx_xlock(&ivars->xd_lock);
804                         while (ivars->xd_state != XenbusStateClosed
805                             && ivars->xd_state != XenbusStateConnected)
806                                 sx_sleep(&ivars->xd_state, &ivars->xd_lock,
807                                     0, "xdresume", 0);
808                         sx_xunlock(&ivars->xd_lock);
809 #endif
810                 }
811                 free(kids, M_TEMP);
812         }
813
814         return (0);
815 }
816
817 int
818 xenbusb_print_child(device_t dev, device_t child)
819 {
820         struct xenbus_device_ivars *ivars = device_get_ivars(child);
821         int     retval = 0;
822
823         retval += bus_print_child_header(dev, child);
824         retval += printf(" at %s", ivars->xd_node);
825         retval += bus_print_child_footer(dev, child);
826
827         return (retval);
828 }
829
830 int
831 xenbusb_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
832 {
833         struct xenbus_device_ivars *ivars = device_get_ivars(child);
834
835         switch (index) {
836         case XENBUS_IVAR_NODE:
837                 *result = (uintptr_t) ivars->xd_node;
838                 return (0);
839
840         case XENBUS_IVAR_TYPE:
841                 *result = (uintptr_t) ivars->xd_type;
842                 return (0);
843
844         case XENBUS_IVAR_STATE:
845                 *result = (uintptr_t) ivars->xd_state;
846                 return (0);
847
848         case XENBUS_IVAR_OTHEREND_ID:
849                 *result = (uintptr_t) ivars->xd_otherend_id;
850                 return (0);
851
852         case XENBUS_IVAR_OTHEREND_PATH:
853                 *result = (uintptr_t) ivars->xd_otherend_path;
854                 return (0);
855         }
856
857         return (ENOENT);
858 }
859
860 int
861 xenbusb_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
862 {
863         struct xenbus_device_ivars *ivars = device_get_ivars(child);
864         enum xenbus_state newstate;
865         int currstate;
866
867         switch (index) {
868         case XENBUS_IVAR_STATE:
869         {
870                 int error;
871
872                 newstate = (enum xenbus_state)value;
873                 sx_xlock(&ivars->xd_lock);
874                 if (ivars->xd_state == newstate) {
875                         error = 0;
876                         goto out;
877                 }
878
879                 error = xs_scanf(XST_NIL, ivars->xd_node, "state",
880                     NULL, "%d", &currstate);
881                 if (error)
882                         goto out;
883
884                 do {
885                         error = xs_printf(XST_NIL, ivars->xd_node, "state",
886                             "%d", newstate);
887                 } while (error == EAGAIN);
888                 if (error) {
889                         /*
890                          * Avoid looping through xenbus_dev_fatal()
891                          * which calls xenbus_write_ivar to set the
892                          * state to closing.
893                          */
894                         if (newstate != XenbusStateClosing)
895                                 xenbus_dev_fatal(dev, error,
896                                                  "writing new state");
897                         goto out;
898                 }
899                 ivars->xd_state = newstate;
900
901                 if ((ivars->xd_flags & XDF_CONNECTING) != 0
902                  && (newstate == XenbusStateClosed
903                   || newstate == XenbusStateConnected)) {
904                         struct xenbusb_softc *xbs;
905
906                         ivars->xd_flags &= ~XDF_CONNECTING;
907                         xbs = device_get_softc(dev);
908                         xenbusb_release_confighook(xbs);
909                 }
910
911                 wakeup(&ivars->xd_state);
912         out:
913                 sx_xunlock(&ivars->xd_lock);
914                 return (error);
915         }
916
917         case XENBUS_IVAR_NODE:
918         case XENBUS_IVAR_TYPE:
919         case XENBUS_IVAR_OTHEREND_ID:
920         case XENBUS_IVAR_OTHEREND_PATH:
921                 /*
922                  * These variables are read-only.
923                  */
924                 return (EINVAL);
925         }
926
927         return (ENOENT);
928 }
929
930 void
931 xenbusb_otherend_changed(device_t bus, device_t child, enum xenbus_state state)
932 {
933         XENBUS_OTHEREND_CHANGED(child, state);
934 }
935
936 void
937 xenbusb_localend_changed(device_t bus, device_t child, const char *path)
938 {
939
940         if (strcmp(path, "/state") != 0) {
941                 struct xenbus_device_ivars *ivars;
942
943                 ivars = device_get_ivars(child);
944                 sx_xlock(&ivars->xd_lock);
945                 ivars->xd_state = xenbus_read_driver_state(ivars->xd_node);
946                 sx_xunlock(&ivars->xd_lock);
947         }
948         XENBUS_LOCALEND_CHANGED(child, path);
949 }