xref: /freebsd/sys/xen/xenbus/xenbusb_front.c (revision 3e5e0e2f16785210d796ea6ece4b69d35a03fe47)
1ff662b5cSJustin T. Gibbs /******************************************************************************
2ff662b5cSJustin T. Gibbs  * Talks to Xen Store to figure out what devices we have.
3ff662b5cSJustin T. Gibbs  *
4ff662b5cSJustin T. Gibbs  * Copyright (C) 2009, 2010 Spectra Logic Corporation
5ff662b5cSJustin T. Gibbs  * Copyright (C) 2008 Doug Rabson
6ff662b5cSJustin T. Gibbs  * Copyright (C) 2005 Rusty Russell, IBM Corporation
7ff662b5cSJustin T. Gibbs  * Copyright (C) 2005 Mike Wray, Hewlett-Packard
8ff662b5cSJustin T. Gibbs  * Copyright (C) 2005 XenSource Ltd
9ff662b5cSJustin T. Gibbs  *
10ff662b5cSJustin T. Gibbs  * This file may be distributed separately from the Linux kernel, or
11ff662b5cSJustin T. Gibbs  * incorporated into other software packages, subject to the following license:
12ff662b5cSJustin T. Gibbs  *
13ff662b5cSJustin T. Gibbs  * Permission is hereby granted, free of charge, to any person obtaining a copy
14ff662b5cSJustin T. Gibbs  * of this source file (the "Software"), to deal in the Software without
15ff662b5cSJustin T. Gibbs  * restriction, including without limitation the rights to use, copy, modify,
16ff662b5cSJustin T. Gibbs  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
17ff662b5cSJustin T. Gibbs  * and to permit persons to whom the Software is furnished to do so, subject to
18ff662b5cSJustin T. Gibbs  * the following conditions:
19ff662b5cSJustin T. Gibbs  *
20ff662b5cSJustin T. Gibbs  * The above copyright notice and this permission notice shall be included in
21ff662b5cSJustin T. Gibbs  * all copies or substantial portions of the Software.
22ff662b5cSJustin T. Gibbs  *
23ff662b5cSJustin T. Gibbs  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24ff662b5cSJustin T. Gibbs  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25ff662b5cSJustin T. Gibbs  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26ff662b5cSJustin T. Gibbs  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27ff662b5cSJustin T. Gibbs  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28ff662b5cSJustin T. Gibbs  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29ff662b5cSJustin T. Gibbs  * IN THE SOFTWARE.
30ff662b5cSJustin T. Gibbs  */
31ff662b5cSJustin T. Gibbs 
32ff662b5cSJustin T. Gibbs /**
33ff662b5cSJustin T. Gibbs  * \file xenbusb_front.c
34ff662b5cSJustin T. Gibbs  *
35ff662b5cSJustin T. Gibbs  * XenBus management of the NewBus bus containing the frontend instances of
36ff662b5cSJustin T. Gibbs  * Xen split devices.
37ff662b5cSJustin T. Gibbs  */
38fdafd315SWarner Losh 
39ff662b5cSJustin T. Gibbs #include <sys/param.h>
40ff662b5cSJustin T. Gibbs #include <sys/bus.h>
41ff662b5cSJustin T. Gibbs #include <sys/kernel.h>
42ff662b5cSJustin T. Gibbs #include <sys/lock.h>
43ff662b5cSJustin T. Gibbs #include <sys/malloc.h>
44ff662b5cSJustin T. Gibbs #include <sys/module.h>
45ff662b5cSJustin T. Gibbs #include <sys/sbuf.h>
46ff662b5cSJustin T. Gibbs #include <sys/sysctl.h>
47ff662b5cSJustin T. Gibbs #include <sys/syslog.h>
48ff662b5cSJustin T. Gibbs #include <sys/systm.h>
49ff662b5cSJustin T. Gibbs #include <sys/sx.h>
50ff662b5cSJustin T. Gibbs #include <sys/taskqueue.h>
51ff662b5cSJustin T. Gibbs 
52ff662b5cSJustin T. Gibbs #include <machine/stdarg.h>
53ff662b5cSJustin T. Gibbs 
5476acc41fSJustin T. Gibbs #include <xen/xen-os.h>
55ff662b5cSJustin T. Gibbs #include <xen/gnttab.h>
56ff662b5cSJustin T. Gibbs #include <xen/xenbus/xenbusvar.h>
57ff662b5cSJustin T. Gibbs #include <xen/xenbus/xenbusb.h>
58ff662b5cSJustin T. Gibbs 
59ff662b5cSJustin T. Gibbs /*------------------ Private Device Attachment Functions  --------------------*/
60ff662b5cSJustin T. Gibbs /**
61bc9432d0SGordon Bergling  * \brief Probe for the existence of the XenBus front bus.
62ff662b5cSJustin T. Gibbs  *
63ff662b5cSJustin T. Gibbs  * \param dev  NewBus device_t for this XenBus front bus instance.
64ff662b5cSJustin T. Gibbs  *
65ff662b5cSJustin T. Gibbs  * \return  Always returns 0 indicating success.
66ff662b5cSJustin T. Gibbs  */
67ff662b5cSJustin T. Gibbs static int
xenbusb_front_probe(device_t dev)68ff662b5cSJustin T. Gibbs xenbusb_front_probe(device_t dev)
69ff662b5cSJustin T. Gibbs {
70ff662b5cSJustin T. Gibbs 	device_set_desc(dev, "Xen Frontend Devices");
71ff662b5cSJustin T. Gibbs 
72ff662b5cSJustin T. Gibbs 	return (0);
73ff662b5cSJustin T. Gibbs }
74ff662b5cSJustin T. Gibbs 
75ff662b5cSJustin T. Gibbs /**
76ff662b5cSJustin T. Gibbs  * \brief Attach the XenBus front bus.
77ff662b5cSJustin T. Gibbs  *
78ff662b5cSJustin T. Gibbs  * \param dev  NewBus device_t for this XenBus front bus instance.
79ff662b5cSJustin T. Gibbs  *
80ff662b5cSJustin T. Gibbs  * \return  On success, 0. Otherwise an errno value indicating the
81ff662b5cSJustin T. Gibbs  *          type of failure.
82ff662b5cSJustin T. Gibbs  */
83ff662b5cSJustin T. Gibbs static int
xenbusb_front_attach(device_t dev)84ff662b5cSJustin T. Gibbs xenbusb_front_attach(device_t dev)
85ff662b5cSJustin T. Gibbs {
86ff662b5cSJustin T. Gibbs 	return (xenbusb_attach(dev, "device", /*id_components*/1));
87ff662b5cSJustin T. Gibbs }
88ff662b5cSJustin T. Gibbs 
89ff662b5cSJustin T. Gibbs /**
90ff662b5cSJustin T. Gibbs  * \brief Enumerate all devices of the given type on this bus.
91ff662b5cSJustin T. Gibbs  *
92ff662b5cSJustin T. Gibbs  * \param dev   NewBus device_t for this XenBus front bus instance.
93ff662b5cSJustin T. Gibbs  * \param type  String indicating the device sub-tree (e.g. "vfb", "vif")
94ff662b5cSJustin T. Gibbs  *              to enumerate.
95ff662b5cSJustin T. Gibbs  *
96ff662b5cSJustin T. Gibbs  * \return  On success, 0. Otherwise an errno value indicating the
97ff662b5cSJustin T. Gibbs  *          type of failure.
98ff662b5cSJustin T. Gibbs  *
99ff662b5cSJustin T. Gibbs  * Devices that are found are entered into the NewBus hierarchy via
100ff662b5cSJustin T. Gibbs  * xenbusb_add_device().  xenbusb_add_device() ignores duplicate detects
101ff662b5cSJustin T. Gibbs  * and ignores duplicate devices, so it can be called unconditionally
102ff662b5cSJustin T. Gibbs  * for any device found in the XenStore.
103ff662b5cSJustin T. Gibbs  */
104ff662b5cSJustin T. Gibbs static int
xenbusb_front_enumerate_type(device_t dev,const char * type)105ff662b5cSJustin T. Gibbs xenbusb_front_enumerate_type(device_t dev, const char *type)
106ff662b5cSJustin T. Gibbs {
107ff662b5cSJustin T. Gibbs 	struct xenbusb_softc *xbs;
108ff662b5cSJustin T. Gibbs 	const char **dir;
109ff662b5cSJustin T. Gibbs 	unsigned int i, count;
110ff662b5cSJustin T. Gibbs 	int error;
111ff662b5cSJustin T. Gibbs 
112ff662b5cSJustin T. Gibbs 	xbs = device_get_softc(dev);
113ff662b5cSJustin T. Gibbs 	error = xs_directory(XST_NIL, xbs->xbs_node, type, &count, &dir);
114ff662b5cSJustin T. Gibbs 	if (error)
115ff662b5cSJustin T. Gibbs 		return (error);
116ff662b5cSJustin T. Gibbs 	for (i = 0; i < count; i++)
117ff662b5cSJustin T. Gibbs 		xenbusb_add_device(dev, type, dir[i]);
118ff662b5cSJustin T. Gibbs 
119ff662b5cSJustin T. Gibbs 	free(dir, M_XENSTORE);
120ff662b5cSJustin T. Gibbs 
121ff662b5cSJustin T. Gibbs 	return (0);
122ff662b5cSJustin T. Gibbs }
123ff662b5cSJustin T. Gibbs 
124ff662b5cSJustin T. Gibbs /**
125ff662b5cSJustin T. Gibbs  * \brief Determine and store the XenStore path for the other end of
126ff662b5cSJustin T. Gibbs  *        a split device whose local end is represented by ivars.
127ff662b5cSJustin T. Gibbs  *
128ff662b5cSJustin T. Gibbs  * If successful, the xd_otherend_path field of the child's instance
129ff662b5cSJustin T. Gibbs  * variables will be updated.
130ff662b5cSJustin T. Gibbs  *
131ff662b5cSJustin T. Gibbs  * \param dev    NewBus device_t for this XenBus front bus instance.
132ff662b5cSJustin T. Gibbs  * \param ivars  Instance variables from the XenBus child device for
133ff662b5cSJustin T. Gibbs  *               which to perform this function.
134ff662b5cSJustin T. Gibbs  *
135ff662b5cSJustin T. Gibbs  * \return  On success, 0. Otherwise an errno value indicating the
136ff662b5cSJustin T. Gibbs  *          type of failure.
137ff662b5cSJustin T. Gibbs  */
138ff662b5cSJustin T. Gibbs static int
xenbusb_front_get_otherend_node(device_t dev,struct xenbus_device_ivars * ivars)139ff662b5cSJustin T. Gibbs xenbusb_front_get_otherend_node(device_t dev, struct xenbus_device_ivars *ivars)
140ff662b5cSJustin T. Gibbs {
141ff662b5cSJustin T. Gibbs 	char *otherend_path;
142ff662b5cSJustin T. Gibbs 	int error;
143ff662b5cSJustin T. Gibbs 
144ff662b5cSJustin T. Gibbs 	if (ivars->xd_otherend_path != NULL) {
145ff662b5cSJustin T. Gibbs 		free(ivars->xd_otherend_path, M_XENBUS);
146ff662b5cSJustin T. Gibbs 		ivars->xd_otherend_path = NULL;
147ff662b5cSJustin T. Gibbs 	}
148ff662b5cSJustin T. Gibbs 
149ff662b5cSJustin T. Gibbs 	error = xs_gather(XST_NIL, ivars->xd_node,
150ff662b5cSJustin T. Gibbs 	    "backend-id", "%i", &ivars->xd_otherend_id,
151ff662b5cSJustin T. Gibbs 	    "backend", NULL, &otherend_path,
152ff662b5cSJustin T. Gibbs 	    NULL);
153ff662b5cSJustin T. Gibbs 
154ff662b5cSJustin T. Gibbs 	if (error == 0) {
155ff662b5cSJustin T. Gibbs 		ivars->xd_otherend_path = strdup(otherend_path, M_XENBUS);
156283d6f72SJustin T. Gibbs 		ivars->xd_otherend_path_len = strlen(otherend_path);
157ff662b5cSJustin T. Gibbs 		free(otherend_path, M_XENSTORE);
158ff662b5cSJustin T. Gibbs 	}
159ff662b5cSJustin T. Gibbs 	return (error);
160ff662b5cSJustin T. Gibbs }
161ff662b5cSJustin T. Gibbs 
162ff662b5cSJustin T. Gibbs /*-------------------- Private Device Attachment Data  -----------------------*/
163ff662b5cSJustin T. Gibbs static device_method_t xenbusb_front_methods[] = {
164ff662b5cSJustin T. Gibbs 	/* Device interface */
165ff662b5cSJustin T. Gibbs 	DEVMETHOD(device_identify,	xenbusb_identify),
166ff662b5cSJustin T. Gibbs 	DEVMETHOD(device_probe,         xenbusb_front_probe),
167ff662b5cSJustin T. Gibbs 	DEVMETHOD(device_attach,        xenbusb_front_attach),
168ff662b5cSJustin T. Gibbs 	DEVMETHOD(device_detach,        bus_generic_detach),
169ff662b5cSJustin T. Gibbs 	DEVMETHOD(device_shutdown,      bus_generic_shutdown),
170ff662b5cSJustin T. Gibbs 	DEVMETHOD(device_suspend,       bus_generic_suspend),
1712ca7463bSJustin T. Gibbs 	DEVMETHOD(device_resume,        xenbusb_resume),
172ff662b5cSJustin T. Gibbs 
173ff662b5cSJustin T. Gibbs 	/* Bus Interface */
174ff662b5cSJustin T. Gibbs 	DEVMETHOD(bus_print_child,      xenbusb_print_child),
175ff662b5cSJustin T. Gibbs 	DEVMETHOD(bus_read_ivar,        xenbusb_read_ivar),
176ff662b5cSJustin T. Gibbs 	DEVMETHOD(bus_write_ivar,       xenbusb_write_ivar),
177ff662b5cSJustin T. Gibbs 	DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
178ff662b5cSJustin T. Gibbs 	DEVMETHOD(bus_release_resource, bus_generic_release_resource),
179ff662b5cSJustin T. Gibbs 	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
180ff662b5cSJustin T. Gibbs 	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
181ff662b5cSJustin T. Gibbs 
182ff662b5cSJustin T. Gibbs 	/* XenBus Bus Interface */
183ff662b5cSJustin T. Gibbs 	DEVMETHOD(xenbusb_enumerate_type, xenbusb_front_enumerate_type),
184ff662b5cSJustin T. Gibbs 	DEVMETHOD(xenbusb_get_otherend_node, xenbusb_front_get_otherend_node),
185*3e5e0e2fSElliott Mitchell 
186*3e5e0e2fSElliott Mitchell 	DEVMETHOD_END
187ff662b5cSJustin T. Gibbs };
188ff662b5cSJustin T. Gibbs 
189ff662b5cSJustin T. Gibbs DEFINE_CLASS_0(xenbusb_front, xenbusb_front_driver, xenbusb_front_methods,
190ff662b5cSJustin T. Gibbs 	       sizeof(struct xenbusb_softc));
191ff662b5cSJustin T. Gibbs 
192f929eb1eSJohn Baldwin DRIVER_MODULE(xenbusb_front, xenstore, xenbusb_front_driver, 0, 0);
193