FreeBSD xen subsystem code
xenbusb.c File Reference

Shared support functions for managing the NewBus buses that contain Xen front and back end device instances. More...

#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/sbuf.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/systm.h>
#include <sys/sx.h>
#include <sys/taskqueue.h>
#include <machine/stdarg.h>
#include <xen/xen-os.h>
#include <xen/gnttab.h>
#include <xen/xenstore/xenstorevar.h>
#include <xen/xenbus/xenbusb.h>
#include <xen/xenbus/xenbusvar.h>
Include dependency graph for xenbusb.c:

Go to the source code of this file.

Functions

 __FBSDID ("$FreeBSD$")
 
static void xenbusb_free_child_ivars (struct xenbus_device_ivars *ivars)
 Deallocate XenBus device instance variables. More...
 
static void xenbusb_otherend_watch_cb (struct xs_watch *watch, const char **vec, unsigned int vec_size __unused)
 
static void xenbusb_local_watch_cb (struct xs_watch *watch, const char **vec, unsigned int vec_size __unused)
 
static device_t xenbusb_device_exists (device_t dev, const char *node)
 
static void xenbusb_delete_child (device_t dev, device_t child)
 
static void xenbusb_verify_device (device_t dev, device_t child)
 
static int xenbusb_enumerate_bus (struct xenbusb_softc *xbs)
 Enumerate the devices on a XenBus bus and register them with the NewBus device tree. More...
 
static int xenbusb_device_sysctl_handler (SYSCTL_HANDLER_ARGS)
 
static void xenbusb_device_sysctl_init (device_t dev)
 
static void xenbusb_release_confighook (struct xenbusb_softc *xbs)
 Decrement the number of XenBus child devices in the connecting state by one and release the xbs_attch_ch interrupt configuration hook if the connecting count drops to zero. More...
 
static int xenbusb_probe_children (device_t dev)
 Verify the existence of attached device instances and perform probe/attach processing for newly arrived devices. More...
 
static void xenbusb_probe_children_cb (void *arg, int pending __unused)
 Task callback function to perform XenBus probe operations from a known safe context. More...
 
static void xenbusb_devices_changed (struct xs_watch *watch, const char **vec, unsigned int len)
 XenStore watch callback for the root node of the XenStore subtree representing a XenBus. More...
 
static void xenbusb_nop_confighook_cb (void *arg __unused)
 Interrupt configuration hook callback associated with xbs_attch_ch. More...
 
void xenbusb_identify (driver_t *driver __unused, device_t parent)
 Identify instances of this device type in the system. More...
 
int xenbusb_add_device (device_t dev, const char *type, const char *id)
 Attempt to add a XenBus device instance to this XenBus bus. More...
 
int xenbusb_attach (device_t dev, char *bus_node, u_int id_components)
 Perform common XenBus bus attach processing. More...
 
int xenbusb_resume (device_t dev)
 Perform common XenBus bus resume handling. More...
 
int xenbusb_print_child (device_t dev, device_t child)
 Pretty-prints information about a child of a XenBus bus. More...
 
int xenbusb_read_ivar (device_t dev, device_t child, int index, uintptr_t *result)
 Common XenBus child instance variable read access method. More...
 
int xenbusb_write_ivar (device_t dev, device_t child, int index, uintptr_t value)
 Common XenBus child instance variable write access method. More...
 
void xenbusb_otherend_changed (device_t bus, device_t child, enum xenbus_state state)
 Common XenBus method implementing responses to peer state changes. More...
 
void xenbusb_localend_changed (device_t bus, device_t child, const char *path)
 Common XenBus method implementing responses to local XenStore changes. More...
 

Detailed Description

Shared support functions for managing the NewBus buses that contain Xen front and back end device instances.

The NewBus implementation of XenBus attaches a xenbusb_front and xenbusb_back child bus to the xenstore device. This strategy allows the small differences in the handling of XenBus operations for front and back devices to be handled as overrides in xenbusb_front/back.c. Front and back specific device classes are also provided so device drivers can register for the devices they can handle without the need to filter within their probe routines. The net result is a device hierarchy that might look like this:

xenstore0/ xenbusb_front0/ xn0 xbd0 xbd1 xenbusb_back0/ xbbd0 xnb0 xnb1

Definition in file xenbusb.c.

Function Documentation

◆ xenbusb_add_device()

int xenbusb_add_device ( device_t  dev,
const char *  type,
const char *  id 
)

Attempt to add a XenBus device instance to this XenBus bus.

Parameters
devThe NewBus device representing this XenBus bus.
typeThe device type being added (e.g. "vbd", "vif").
idThe device ID for this device.
Returns
On success, 0. Otherwise an errno value indicating the type of failure. Failure indicates that either the path to this device no longer exists or insufficient information exists in the XenStore to create a new device.

If successful, this routine will add a device_t with instance variable storage to the NewBus device topology. Probe/Attach processing is not performed by this routine, but must be scheduled via the xbs_probe_children task. This separation of responsibilities is required to avoid hanging up the XenStore event delivery thread with our probe/attach work in the event a device is added via a callback from the XenStore.

Definition at line 637 of file xenbusb.c.

References xenbusb_softc::xbs_connecting_children, xenbusb_softc::xbs_lock, xenbusb_softc::xbs_node, xenbus_device_ivars::xd_dev, xenbus_device_ivars::xd_flags, xenbus_device_ivars::xd_local_watch, xenbus_device_ivars::xd_lock, xenbus_device_ivars::xd_node, xenbus_device_ivars::xd_node_len, xenbus_device_ivars::xd_otherend_path, xenbus_device_ivars::xd_otherend_path_len, xenbus_device_ivars::xd_otherend_watch, xenbus_device_ivars::xd_state, xenbus_device_ivars::xd_type, XDF_CONNECTING, xenbus_read_driver_state(), xenbusb_device_exists(), xenbusb_free_child_ivars(), xenbusb_local_watch_cb(), and xenbusb_otherend_watch_cb().

Referenced by xenbusb_back_enumerate_type(), xenbusb_devices_changed(), and xenbusb_front_enumerate_type().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ xenbusb_attach()

int xenbusb_attach ( device_t  dev,
char *  bus_node,
u_int  id_components 
)

Perform common XenBus bus attach processing.

Parameters
devThe NewBus device representing this XenBus bus.
bus_nodeThe XenStore path to the XenStore subtree for this XenBus bus.
id_componentsThe number of '/' separated path components that make up a unique device ID on this XenBus bus.
Returns
On success, 0. Otherwise an errno value indicating the type of failure.

Intiailizes the softc for this bus, installs an interrupt driven configuration hook to block boot processing until XenBus devices fully configure, performs an initial probe/attach of the bus, and registers a XenStore watch so we are notified when the bus topology changes.

Definition at line 735 of file xenbusb.c.

References xenbusb_softc::xbs_attach_ch, xenbusb_softc::xbs_dev, xenbusb_softc::xbs_flags, xenbusb_softc::xbs_id_components, xenbusb_softc::xbs_lock, xenbusb_softc::xbs_node, and xenbusb_nop_confighook_cb().

Referenced by xenbusb_back_attach(), and xenbusb_front_attach().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ xenbusb_delete_child()

static void xenbusb_delete_child ( device_t  dev,
device_t  child 
)
static

Definition at line 229 of file xenbusb.c.

◆ xenbusb_device_exists()

static device_t xenbusb_device_exists ( device_t  dev,
const char *  node 
)
static

Search our internal record of configured devices (not the XenStore) to determine if the XenBus device indicated by node is known to the system.

Parameters
devThe XenBus bus instance to search for device children.
nodeThe XenStore node path for the device to find.
Returns
The device_t of the found device if any, or NULL.
Note
device_t is a pointer type, so it can be compared against NULL for validity.

Definition at line 205 of file xenbusb.c.

References xenbus_device_ivars::xd_node.

Referenced by xenbusb_add_device().

Here is the caller graph for this function:

◆ xenbusb_device_sysctl_handler()

static int xenbusb_device_sysctl_handler ( SYSCTL_HANDLER_ARGS  )
static

Handler for all generic XenBus device systcl nodes.

Definition at line 305 of file xenbusb.c.

References XENBUS_IVAR_NODE, XENBUS_IVAR_OTHEREND_ID, XENBUS_IVAR_OTHEREND_PATH, XENBUS_IVAR_STATE, XENBUS_IVAR_TYPE, and xenbus_strstate().

Referenced by xenbusb_device_sysctl_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ xenbusb_device_sysctl_init()

static void xenbusb_device_sysctl_init ( device_t  dev)
static

Create read-only systcl nodes for xenbusb device ivar data.

Parameters
devThe XenBus device instance to register with sysctl.

Definition at line 341 of file xenbusb.c.

References XENBUS_IVAR_NODE, XENBUS_IVAR_OTHEREND_ID, XENBUS_IVAR_OTHEREND_PATH, XENBUS_IVAR_STATE, XENBUS_IVAR_TYPE, and xenbusb_device_sysctl_handler().

Here is the call graph for this function:

◆ xenbusb_devices_changed()

static void xenbusb_devices_changed ( struct xs_watch watch,
const char **  vec,
unsigned int  len 
)
static

XenStore watch callback for the root node of the XenStore subtree representing a XenBus.

This callback performs, or delegates to the xbs_probe_children task, all processing necessary to handle dynmaic device arrival and departure events from a XenBus.

Parameters
watchThe XenStore watch object associated with this callback.
vecThe XenStore watch event data.
lenThe number of fields in the event data stream.

Definition at line 554 of file xenbusb.c.

References xenbusb_softc::xbs_dev, xenbusb_softc::xbs_id_components, xenbusb_softc::xbs_probe_children, and xenbusb_add_device().

Here is the call graph for this function:

◆ xenbusb_enumerate_bus()

static int xenbusb_enumerate_bus ( struct xenbusb_softc xbs)
static

Enumerate the devices on a XenBus bus and register them with the NewBus device tree.

xenbusb_enumerate_bus() will create entries (in state DS_NOTPRESENT) for nodes that appear in the XenStore, but will not invoke probe/attach operations on drivers. Probe/Attach processing must be separately performed via an invocation of xenbusb_probe_children(). This is usually done via the xbs_probe_children task.

Parameters
xbsXenBus Bus device softc of the owner of the bus to enumerate.
Returns
On success, 0. Otherwise an errno value indicating the type of failure.

Definition at line 282 of file xenbusb.c.

References xenbusb_softc::xbs_dev, and xenbusb_softc::xbs_node.

◆ xenbusb_free_child_ivars()

static void xenbusb_free_child_ivars ( struct xenbus_device_ivars ivars)
static

Deallocate XenBus device instance variables.

Parameters
ivarsThe instance variable block to free.

Definition at line 85 of file xenbusb.c.

References xenbus_device_ivars::xd_local_watch, xenbus_device_ivars::xd_node, xenbus_device_ivars::xd_node_len, xenbus_device_ivars::xd_otherend_path, xenbus_device_ivars::xd_otherend_path_len, xenbus_device_ivars::xd_otherend_watch, and xenbus_device_ivars::xd_type.

Referenced by xenbusb_add_device().

Here is the caller graph for this function:

◆ xenbusb_identify()

void xenbusb_identify ( driver_t *driver  __unused,
device_t  parent 
)

Identify instances of this device type in the system.

Parameters
driverThe driver performing this identify action.
parentThe NewBus parent device for any devices this method adds.

Definition at line 627 of file xenbusb.c.

◆ xenbusb_local_watch_cb()

static void xenbusb_local_watch_cb ( struct xs_watch watch,
const char **  vec,
unsigned int vec_size  __unused 
)
static

XenBus watch callback registered against the XenStore sub-tree represnting the local half of a split device connection.

This callback is invoked whenever any XenStore data in the subtree is modified, either by us or another privledged domain.

Parameters
watchThe xs_watch object used to register this callback function.
vecAn array of pointers to NUL terminated strings containing watch event data. The vector should be indexed via the xs_watch_type enum in xs_wire.h.
vec_sizeThe number of elements in vec.

Definition at line 171 of file xenbusb.c.

References xenbus_device_ivars::xd_dev, xenbus_device_ivars::xd_node, and xenbus_device_ivars::xd_node_len.

Referenced by xenbusb_add_device().

Here is the caller graph for this function:

◆ xenbusb_localend_changed()

void xenbusb_localend_changed ( device_t  bus,
device_t  child,
const char *  path 
)

Common XenBus method implementing responses to local XenStore changes.

Parameters
busThe XenBus bus parent of child.
childThe XenBus child whose peer stat has changed.
pathThe tree relative sub-path to the modified node. The empty string indicates the root of the tree was destroyed.

Definition at line 976 of file xenbusb.c.

References xenbus_device_ivars::xd_lock, xenbus_device_ivars::xd_node, xenbus_device_ivars::xd_state, and xenbus_read_driver_state().

Referenced by xenbusb_back_localend_changed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ xenbusb_nop_confighook_cb()

static void xenbusb_nop_confighook_cb ( void *arg  __unused)
static

Interrupt configuration hook callback associated with xbs_attch_ch.

Since interrupts are always functional at the time of XenBus configuration, there is nothing to be done when the callback occurs. This hook is only registered to hold up boot processing while XenBus devices come online.

Parameters
argUnused configuration hook callback argument.

Definition at line 620 of file xenbusb.c.

Referenced by xenbusb_attach().

Here is the caller graph for this function:

◆ xenbusb_otherend_changed()

void xenbusb_otherend_changed ( device_t  bus,
device_t  child,
enum xenbus_state  state 
)

Common XenBus method implementing responses to peer state changes.

Parameters
busThe XenBus bus parent of child.
childThe XenBus child whose peer stat has changed.
stateThe current state of the peer.

Definition at line 970 of file xenbusb.c.

Referenced by xenbusb_back_otherend_changed().

Here is the caller graph for this function:

◆ xenbusb_otherend_watch_cb()

static void xenbusb_otherend_watch_cb ( struct xs_watch watch,
const char **  vec,
unsigned int vec_size  __unused 
)
static

XenBus watch callback registered against the "state" XenStore node of the other-end of a split device connection.

This callback is invoked whenever the state of a device instance's peer changes.

Parameters
watchThe xs_watch object used to register this callback function.
vecAn array of pointers to NUL terminated strings containing watch event data. The vector should be indexed via the xs_watch_type enum in xs_wire.h.
vec_sizeThe number of elements in vec.

Definition at line 133 of file xenbusb.c.

References xenbus_device_ivars::xd_dev, xenbus_device_ivars::xd_otherend_path, xenbus_device_ivars::xd_otherend_path_len, and xenbus_read_driver_state().

Referenced by xenbusb_add_device().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ xenbusb_print_child()

int xenbusb_print_child ( device_t  dev,
device_t  child 
)

Pretty-prints information about a child of a XenBus bus.

Parameters
devThe NewBus device representing this XenBus bus.
childThe NewBus device representing a child of dev's XenBus bus.
Returns
On success, 0. Otherwise an errno value indicating the type of failure.

Definition at line 857 of file xenbusb.c.

References xenbus_device_ivars::xd_node.

◆ xenbusb_probe_children()

static int xenbusb_probe_children ( device_t  dev)
static

Verify the existence of attached device instances and perform probe/attach processing for newly arrived devices.

Parameters
devThe NewBus device representing this XenBus bus.
Returns
On success, 0. Otherwise an errno value indicating the type of failure.

Definition at line 440 of file xenbusb.c.

References xenbusb_verify_device().

Referenced by xenbusb_probe_children_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ xenbusb_probe_children_cb()

static void xenbusb_probe_children_cb ( void *  arg,
int pending  __unused 
)
static

Task callback function to perform XenBus probe operations from a known safe context.

Parameters
argThe NewBus device_t representing the bus instance to on which to perform probe processing.
pendingThe number of times this task was queued before it could be run.

Definition at line 532 of file xenbusb.c.

References xenbusb_probe_children().

Here is the call graph for this function:

◆ xenbusb_read_ivar()

int xenbusb_read_ivar ( device_t  dev,
device_t  child,
int  index,
uintptr_t *  result 
)

Common XenBus child instance variable read access method.

Parameters
devThe NewBus device representing this XenBus bus.
childThe NewBus device representing a child of dev's XenBus bus.
indexThe index of the instance variable to access.
resultThe value of the instance variable accessed.
Returns
On success, 0. Otherwise an errno value indicating the type of failure.

Definition at line 870 of file xenbusb.c.

References xenbus_device_ivars::xd_node, xenbus_device_ivars::xd_otherend_id, xenbus_device_ivars::xd_otherend_path, xenbus_device_ivars::xd_state, xenbus_device_ivars::xd_type, XENBUS_IVAR_NODE, XENBUS_IVAR_OTHEREND_ID, XENBUS_IVAR_OTHEREND_PATH, XENBUS_IVAR_STATE, and XENBUS_IVAR_TYPE.

◆ xenbusb_release_confighook()

static void xenbusb_release_confighook ( struct xenbusb_softc xbs)
static

Decrement the number of XenBus child devices in the connecting state by one and release the xbs_attch_ch interrupt configuration hook if the connecting count drops to zero.

Parameters
xbsXenBus Bus device softc of the owner of the bus to enumerate.

Definition at line 414 of file xenbusb.c.

References xenbusb_softc::xbs_connecting_children, xenbusb_softc::xbs_flags, and xenbusb_softc::xbs_lock.

Referenced by xenbusb_write_ivar().

Here is the caller graph for this function:

◆ xenbusb_resume()

int xenbusb_resume ( device_t  dev)

Perform common XenBus bus resume handling.

Parameters
devThe NewBus device representing this XenBus bus.
Returns
On success, 0. Otherwise an errno value indicating the type of failure.

Definition at line 791 of file xenbusb.c.

References xenbus_device_ivars::xd_lock, xenbus_device_ivars::xd_otherend_path, xenbus_device_ivars::xd_otherend_path_len, xenbus_device_ivars::xd_otherend_watch, and xenbus_device_ivars::xd_state.

◆ xenbusb_verify_device()

static void xenbusb_verify_device ( device_t  dev,
device_t  child 
)
static
Parameters
devThe NewBus device representing this XenBus bus.
childThe NewBus device representing a child of dev's XenBus bus.

Definition at line 255 of file xenbusb.c.

Referenced by xenbusb_probe_children().

Here is the caller graph for this function:

◆ xenbusb_write_ivar()

int xenbusb_write_ivar ( device_t  dev,
device_t  child,
int  index,
uintptr_t  value 
)

Common XenBus child instance variable write access method.

Parameters
devThe NewBus device representing this XenBus bus.
childThe NewBus device representing a child of dev's XenBus bus.
indexThe index of the instance variable to access.
valueThe new value to set in the instance variable accessed.
Returns
On success, 0. Otherwise an errno value indicating the type of failure.

Definition at line 900 of file xenbusb.c.

References xenbus_device_ivars::xd_flags, xenbus_device_ivars::xd_lock, xenbus_device_ivars::xd_node, xenbus_device_ivars::xd_state, XDF_CONNECTING, xenbus_dev_fatal(), XENBUS_IVAR_NODE, XENBUS_IVAR_OTHEREND_ID, XENBUS_IVAR_OTHEREND_PATH, XENBUS_IVAR_STATE, XENBUS_IVAR_TYPE, and xenbusb_release_confighook().

Here is the call graph for this function: