1/*-
2 * Core definitions and data structures shareable across OS platforms.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2010 Spectra Logic Corporation
7 * Copyright (C) 2008 Doug Rabson
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions, and the following disclaimer,
15 *    without modification.
16 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
17 *    substantially similar to the "NO WARRANTY" disclaimer below
18 *    ("Disclaimer") and any redistribution must be conditioned upon
19 *    including a substantially similar Disclaimer requirement for further
20 *    binary redistribution.
21 *
22 * NO WARRANTY
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGES.
34 */
35#ifndef _XEN_XENBUS_XENBUSB_H
36#define _XEN_XENBUS_XENBUSB_H
37
38/**
39 * \file xenbusb.h
40 *
41 * Datastructures and function declarations for use in implementing
42 * bus attachements (e.g. frontend and backend device buses) for XenBus.
43 */
44
45/**
46 * Enumeration of state flag values for the xbs_flags field of
47 * the xenbusb_softc structure.
48 */
49typedef enum {
50	/** */
51	XBS_ATTACH_CH_ACTIVE = 0x01
52} xenbusb_softc_flag;
53
54/**
55 * \brief Container for all state needed to manage a Xenbus Bus
56 *	  attachment.
57 */
58struct xenbusb_softc {
59	/**
60	 * XenStore watch used to monitor the subtree of the
61	 * XenStore where devices for this bus attachment arrive
62	 * and depart.
63	 */
64	struct xs_watch	        xbs_device_watch;
65
66	/** Mutex used to protect fields of the xenbusb_softc. */
67	struct mtx		xbs_lock;
68
69	/** State flags. */
70	xenbusb_softc_flag	xbs_flags;
71
72	/**
73	 * A dedicated task for processing child arrival and
74	 * departure events.
75	 */
76	struct task		xbs_probe_children;
77
78	/**
79	 * Config Hook used to block boot processing until
80	 * XenBus devices complete their connection processing
81	 * with other VMs.
82	 */
83	struct intr_config_hook xbs_attach_ch;
84
85	/**
86	 * The number of children for this bus that are still
87	 * in the connecting (to other VMs) state.  This variable
88	 * is used to determine when to release xbs_attach_ch.
89	 */
90	u_int			xbs_connecting_children;
91
92	/** The NewBus device_t for this bus attachment. */
93	device_t		xbs_dev;
94
95	/**
96	 * The VM relative path to the XenStore subtree this
97	 * bus attachment manages.
98	 */
99	const char	       *xbs_node;
100
101	/**
102	 * The number of path components (strings separated by the '/'
103	 * character) that make up the device ID on this bus.
104	 */
105	u_int			xbs_id_components;
106};
107
108/**
109 * Enumeration of state flag values for the xbs_flags field of
110 * the xenbusb_softc structure.
111 */
112typedef enum {
113	/**
114	 * This device is contributing to the xbs_connecting_children
115	 * count of its parent bus.
116	 */
117	XDF_CONNECTING = 0x01
118} xenbus_dev_flag;
119
120/** Instance variables for devices on a XenBus bus. */
121struct xenbus_device_ivars {
122	/**
123	 * XenStore watch used to monitor the subtree of the
124	 * XenStore where information about the otherend of
125	 * the split Xen device this device instance represents.
126	 */
127	struct xs_watch		xd_otherend_watch;
128
129	/**
130	 * XenStore watch used to monitor the XenStore sub-tree
131	 * associated with this device.  This watch will fire
132	 * for modifications that we make from our domain as
133	 * well as for those made by the control domain.
134	 */
135	struct xs_watch		xd_local_watch;
136
137	/** Sleepable lock used to protect instance data. */
138	struct sx		xd_lock;
139
140	/** State flags. */
141	xenbus_dev_flag		xd_flags;
142
143	/** The NewBus device_t for this XenBus device instance. */
144	device_t		xd_dev;
145
146	/**
147	 * The VM relative path to the XenStore subtree representing
148	 * this VMs half of this device.
149	 */
150	char		       *xd_node;
151
152	/** The length of xd_node.  */
153	int			xd_node_len;
154
155	/** XenBus device type ("vbd", "vif", etc.). */
156	char		       *xd_type;
157
158	/**
159	 * Cached version of <xd_node>/state node in the XenStore.
160	 */
161	enum xenbus_state	xd_state;
162
163	/** The VM identifier of the other end of this split device. */
164	int			xd_otherend_id;
165
166	/**
167	 * The path to the subtree of the XenStore where information
168	 * about the otherend of this split device instance.
169	 */
170	char		       *xd_otherend_path;
171
172	/** The length of xd_otherend_path.  */
173	int			xd_otherend_path_len;
174};
175
176/**
177 * \brief Identify instances of this device type in the system.
178 *
179 * \param driver  The driver performing this identify action.
180 * \param parent  The NewBus parent device for any devices this method adds.
181 */
182void xenbusb_identify(driver_t *driver __unused, device_t parent);
183
184/**
185 * \brief Perform common XenBus bus attach processing.
186 *
187 * \param dev            The NewBus device representing this XenBus bus.
188 * \param bus_node       The XenStore path to the XenStore subtree for
189 *                       this XenBus bus.
190 * \param id_components  The number of '/' separated path components that
191 *                       make up a unique device ID on this XenBus bus.
192 *
193 * \return  On success, 0. Otherwise an errno value indicating the
194 *          type of failure.
195 *
196 * Intiailizes the softc for this bus, installs an interrupt driven
197 * configuration hook to block boot processing until XenBus devices fully
198 * configure, performs an initial probe/attach of the bus, and registers
199 * a XenStore watch so we are notified when the bus topology changes.
200 */
201int xenbusb_attach(device_t dev, char *bus_node, u_int id_components);
202
203/**
204 * \brief Perform common XenBus bus resume handling.
205 *
206 * \param dev  The NewBus device representing this XenBus bus.
207 *
208 * \return  On success, 0. Otherwise an errno value indicating the
209 *          type of failure.
210 */
211int xenbusb_resume(device_t dev);
212
213/**
214 * \brief Pretty-prints information about a child of a XenBus bus.
215 *
216 * \param dev    The NewBus device representing this XenBus bus.
217 * \param child	 The NewBus device representing a child of dev%'s XenBus bus.
218 *
219 * \return  On success, 0. Otherwise an errno value indicating the
220 *          type of failure.
221 */
222int xenbusb_print_child(device_t dev, device_t child);
223
224/**
225 * \brief Common XenBus child instance variable read access method.
226 *
227 * \param dev     The NewBus device representing this XenBus bus.
228 * \param child	  The NewBus device representing a child of dev%'s XenBus bus.
229 * \param index	  The index of the instance variable to access.
230 * \param result  The value of the instance variable accessed.
231 *
232 * \return  On success, 0. Otherwise an errno value indicating the
233 *          type of failure.
234 */
235int xenbusb_read_ivar(device_t dev, device_t child, int index,
236		      uintptr_t *result);
237
238/**
239 * \brief Common XenBus child instance variable write access method.
240 *
241 * \param dev    The NewBus device representing this XenBus bus.
242 * \param child	 The NewBus device representing a child of dev%'s XenBus bus.
243 * \param index	 The index of the instance variable to access.
244 * \param value  The new value to set in the instance variable accessed.
245 *
246 * \return  On success, 0. Otherwise an errno value indicating the
247 *          type of failure.
248 */
249int xenbusb_write_ivar(device_t dev, device_t child, int index,
250		       uintptr_t value);
251
252/**
253 * \brief Common XenBus method implementing responses to peer state changes.
254 *
255 * \param bus       The XenBus bus parent of child.
256 * \param child     The XenBus child whose peer stat has changed.
257 * \param state     The current state of the peer.
258 */
259void xenbusb_otherend_changed(device_t bus, device_t child,
260			      enum xenbus_state state);
261
262/**
263 * \brief Common XenBus method implementing responses to local XenStore changes.
264 *
265 * \param bus    The XenBus bus parent of child.
266 * \param child  The XenBus child whose peer stat has changed.
267 * \param path   The tree relative sub-path to the modified node.  The empty
268 *               string indicates the root of the tree was destroyed.
269 */
270void xenbusb_localend_changed(device_t bus, device_t child, const char *path);
271
272/**
273 * \brief Attempt to add a XenBus device instance to this XenBus bus.
274 *
275 * \param dev   The NewBus device representing this XenBus bus.
276 * \param type  The device type being added (e.g. "vbd", "vif").
277 * \param id	The device ID for this device.
278 *
279 * \return  On success, 0. Otherwise an errno value indicating the
280 *          type of failure.  Failure indicates that either the
281 *          path to this device no longer exists or insufficient
282 *          information exists in the XenStore to create a new
283 *          device.
284 *
285 * If successful, this routine will add a device_t with instance
286 * variable storage to the NewBus device topology.  Probe/Attach
287 * processing is not performed by this routine, but must be scheduled
288 * via the xbs_probe_children task.  This separation of responsibilities
289 * is required to avoid hanging up the XenStore event delivery thread
290 * with our probe/attach work in the event a device is added via
291 * a callback from the XenStore.
292 */
293int xenbusb_add_device(device_t dev, const char *type, const char *id);
294
295#include "xenbusb_if.h"
296
297#endif /* _XEN_XENBUS_XENBUSB_H */
298