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 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 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 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 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 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 }
Cache object: 79eed93dccc6a973514c9e14929908f1
|