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 */ 38ff662b5cSJustin T. Gibbs #include <sys/cdefs.h> 39ff662b5cSJustin T. Gibbs __FBSDID("$FreeBSD$"); 40ff662b5cSJustin T. Gibbs 41ff662b5cSJustin T. Gibbs #include <sys/param.h> 42ff662b5cSJustin T. Gibbs #include <sys/bus.h> 43ff662b5cSJustin T. Gibbs #include <sys/kernel.h> 44ff662b5cSJustin T. Gibbs #include <sys/lock.h> 45ff662b5cSJustin T. Gibbs #include <sys/malloc.h> 46ff662b5cSJustin T. Gibbs #include <sys/module.h> 47ff662b5cSJustin T. Gibbs #include <sys/sbuf.h> 48ff662b5cSJustin T. Gibbs #include <sys/sysctl.h> 49ff662b5cSJustin T. Gibbs #include <sys/syslog.h> 50ff662b5cSJustin T. Gibbs #include <sys/systm.h> 51ff662b5cSJustin T. Gibbs #include <sys/sx.h> 52ff662b5cSJustin T. Gibbs #include <sys/taskqueue.h> 53ff662b5cSJustin T. Gibbs 54ff662b5cSJustin T. Gibbs #include <machine/xen/xen-os.h> 55ff662b5cSJustin T. Gibbs #include <machine/stdarg.h> 56ff662b5cSJustin T. Gibbs 57ff662b5cSJustin T. Gibbs #include <xen/gnttab.h> 58ff662b5cSJustin T. Gibbs #include <xen/xenbus/xenbusvar.h> 59ff662b5cSJustin T. Gibbs #include <xen/xenbus/xenbusb.h> 60ff662b5cSJustin T. Gibbs 61ff662b5cSJustin T. Gibbs 62ff662b5cSJustin T. Gibbs /*------------------ Private Device Attachment Functions --------------------*/ 63ff662b5cSJustin T. Gibbs /** 64ff662b5cSJustin T. Gibbs * \brief Probe for the existance of the XenBus front bus. 65ff662b5cSJustin T. Gibbs * 66ff662b5cSJustin T. Gibbs * \param dev NewBus device_t for this XenBus front bus instance. 67ff662b5cSJustin T. Gibbs * 68ff662b5cSJustin T. Gibbs * \return Always returns 0 indicating success. 69ff662b5cSJustin T. Gibbs */ 70ff662b5cSJustin T. Gibbs static int 71ff662b5cSJustin T. Gibbs xenbusb_front_probe(device_t dev) 72ff662b5cSJustin T. Gibbs { 73ff662b5cSJustin T. Gibbs device_set_desc(dev, "Xen Frontend Devices"); 74ff662b5cSJustin T. Gibbs 75ff662b5cSJustin T. Gibbs return (0); 76ff662b5cSJustin T. Gibbs } 77ff662b5cSJustin T. Gibbs 78ff662b5cSJustin T. Gibbs /** 79ff662b5cSJustin T. Gibbs * \brief Attach the XenBus front bus. 80ff662b5cSJustin T. Gibbs * 81ff662b5cSJustin T. Gibbs * \param dev NewBus device_t for this XenBus front bus instance. 82ff662b5cSJustin T. Gibbs * 83ff662b5cSJustin T. Gibbs * \return On success, 0. Otherwise an errno value indicating the 84ff662b5cSJustin T. Gibbs * type of failure. 85ff662b5cSJustin T. Gibbs */ 86ff662b5cSJustin T. Gibbs static int 87ff662b5cSJustin T. Gibbs xenbusb_front_attach(device_t dev) 88ff662b5cSJustin T. Gibbs { 89ff662b5cSJustin T. Gibbs return (xenbusb_attach(dev, "device", /*id_components*/1)); 90ff662b5cSJustin T. Gibbs } 91ff662b5cSJustin T. Gibbs 92ff662b5cSJustin T. Gibbs /** 93ff662b5cSJustin T. Gibbs * \brief Enumerate all devices of the given type on this bus. 94ff662b5cSJustin T. Gibbs * 95ff662b5cSJustin T. Gibbs * \param dev NewBus device_t for this XenBus front bus instance. 96ff662b5cSJustin T. Gibbs * \param type String indicating the device sub-tree (e.g. "vfb", "vif") 97ff662b5cSJustin T. Gibbs * to enumerate. 98ff662b5cSJustin T. Gibbs * 99ff662b5cSJustin T. Gibbs * \return On success, 0. Otherwise an errno value indicating the 100ff662b5cSJustin T. Gibbs * type of failure. 101ff662b5cSJustin T. Gibbs * 102ff662b5cSJustin T. Gibbs * Devices that are found are entered into the NewBus hierarchy via 103ff662b5cSJustin T. Gibbs * xenbusb_add_device(). xenbusb_add_device() ignores duplicate detects 104ff662b5cSJustin T. Gibbs * and ignores duplicate devices, so it can be called unconditionally 105ff662b5cSJustin T. Gibbs * for any device found in the XenStore. 106ff662b5cSJustin T. Gibbs */ 107ff662b5cSJustin T. Gibbs static int 108ff662b5cSJustin T. Gibbs xenbusb_front_enumerate_type(device_t dev, const char *type) 109ff662b5cSJustin T. Gibbs { 110ff662b5cSJustin T. Gibbs struct xenbusb_softc *xbs; 111ff662b5cSJustin T. Gibbs const char **dir; 112ff662b5cSJustin T. Gibbs unsigned int i, count; 113ff662b5cSJustin T. Gibbs int error; 114ff662b5cSJustin T. Gibbs 115ff662b5cSJustin T. Gibbs xbs = device_get_softc(dev); 116ff662b5cSJustin T. Gibbs error = xs_directory(XST_NIL, xbs->xbs_node, type, &count, &dir); 117ff662b5cSJustin T. Gibbs if (error) 118ff662b5cSJustin T. Gibbs return (error); 119ff662b5cSJustin T. Gibbs for (i = 0; i < count; i++) 120ff662b5cSJustin T. Gibbs xenbusb_add_device(dev, type, dir[i]); 121ff662b5cSJustin T. Gibbs 122ff662b5cSJustin T. Gibbs free(dir, M_XENSTORE); 123ff662b5cSJustin T. Gibbs 124ff662b5cSJustin T. Gibbs return (0); 125ff662b5cSJustin T. Gibbs } 126ff662b5cSJustin T. Gibbs 127ff662b5cSJustin T. Gibbs /** 128ff662b5cSJustin T. Gibbs * \brief Determine and store the XenStore path for the other end of 129ff662b5cSJustin T. Gibbs * a split device whose local end is represented by ivars. 130ff662b5cSJustin T. Gibbs * 131ff662b5cSJustin T. Gibbs * If successful, the xd_otherend_path field of the child's instance 132ff662b5cSJustin T. Gibbs * variables will be updated. 133ff662b5cSJustin T. Gibbs * 134ff662b5cSJustin T. Gibbs * \param dev NewBus device_t for this XenBus front bus instance. 135ff662b5cSJustin T. Gibbs * \param ivars Instance variables from the XenBus child device for 136ff662b5cSJustin T. Gibbs * which to perform this function. 137ff662b5cSJustin T. Gibbs * 138ff662b5cSJustin T. Gibbs * \return On success, 0. Otherwise an errno value indicating the 139ff662b5cSJustin T. Gibbs * type of failure. 140ff662b5cSJustin T. Gibbs */ 141ff662b5cSJustin T. Gibbs static int 142ff662b5cSJustin T. Gibbs xenbusb_front_get_otherend_node(device_t dev, struct xenbus_device_ivars *ivars) 143ff662b5cSJustin T. Gibbs { 144ff662b5cSJustin T. Gibbs char *otherend_path; 145ff662b5cSJustin T. Gibbs int error; 146ff662b5cSJustin T. Gibbs 147ff662b5cSJustin T. Gibbs if (ivars->xd_otherend_path != NULL) { 148ff662b5cSJustin T. Gibbs free(ivars->xd_otherend_path, M_XENBUS); 149ff662b5cSJustin T. Gibbs ivars->xd_otherend_path = NULL; 150ff662b5cSJustin T. Gibbs } 151ff662b5cSJustin T. Gibbs 152ff662b5cSJustin T. Gibbs error = xs_gather(XST_NIL, ivars->xd_node, 153ff662b5cSJustin T. Gibbs "backend-id", "%i", &ivars->xd_otherend_id, 154ff662b5cSJustin T. Gibbs "backend", NULL, &otherend_path, 155ff662b5cSJustin T. Gibbs NULL); 156ff662b5cSJustin T. Gibbs 157ff662b5cSJustin T. Gibbs if (error == 0) { 158ff662b5cSJustin T. Gibbs ivars->xd_otherend_path = strdup(otherend_path, M_XENBUS); 159ff662b5cSJustin T. Gibbs free(otherend_path, M_XENSTORE); 160ff662b5cSJustin T. Gibbs } 161ff662b5cSJustin T. Gibbs return (error); 162ff662b5cSJustin T. Gibbs } 163ff662b5cSJustin T. Gibbs 164ff662b5cSJustin T. Gibbs /*-------------------- Private Device Attachment Data -----------------------*/ 165ff662b5cSJustin T. Gibbs static device_method_t xenbusb_front_methods[] = { 166ff662b5cSJustin T. Gibbs /* Device interface */ 167ff662b5cSJustin T. Gibbs DEVMETHOD(device_identify, xenbusb_identify), 168ff662b5cSJustin T. Gibbs DEVMETHOD(device_probe, xenbusb_front_probe), 169ff662b5cSJustin T. Gibbs DEVMETHOD(device_attach, xenbusb_front_attach), 170ff662b5cSJustin T. Gibbs DEVMETHOD(device_detach, bus_generic_detach), 171ff662b5cSJustin T. Gibbs DEVMETHOD(device_shutdown, bus_generic_shutdown), 172ff662b5cSJustin T. Gibbs DEVMETHOD(device_suspend, bus_generic_suspend), 173ff662b5cSJustin T. Gibbs DEVMETHOD(device_resume, bus_generic_resume), 174ff662b5cSJustin T. Gibbs 175ff662b5cSJustin T. Gibbs /* Bus Interface */ 176ff662b5cSJustin T. Gibbs DEVMETHOD(bus_print_child, xenbusb_print_child), 177ff662b5cSJustin T. Gibbs DEVMETHOD(bus_read_ivar, xenbusb_read_ivar), 178ff662b5cSJustin T. Gibbs DEVMETHOD(bus_write_ivar, xenbusb_write_ivar), 179ff662b5cSJustin T. Gibbs DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), 180ff662b5cSJustin T. Gibbs DEVMETHOD(bus_release_resource, bus_generic_release_resource), 181ff662b5cSJustin T. Gibbs DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 182ff662b5cSJustin T. Gibbs DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 183ff662b5cSJustin T. Gibbs 184ff662b5cSJustin T. Gibbs /* XenBus Bus Interface */ 185ff662b5cSJustin T. Gibbs DEVMETHOD(xenbusb_enumerate_type, xenbusb_front_enumerate_type), 186ff662b5cSJustin T. Gibbs DEVMETHOD(xenbusb_get_otherend_node, xenbusb_front_get_otherend_node), 187ff662b5cSJustin T. Gibbs { 0, 0 } 188ff662b5cSJustin T. Gibbs }; 189ff662b5cSJustin T. Gibbs 190ff662b5cSJustin T. Gibbs DEFINE_CLASS_0(xenbusb_front, xenbusb_front_driver, xenbusb_front_methods, 191ff662b5cSJustin T. Gibbs sizeof(struct xenbusb_softc)); 192ff662b5cSJustin T. Gibbs devclass_t xenbusb_front_devclass; 193ff662b5cSJustin T. Gibbs 194ff662b5cSJustin T. Gibbs DRIVER_MODULE(xenbusb_front, xenstore, xenbusb_front_driver, 195ff662b5cSJustin T. Gibbs xenbusb_front_devclass, 0, 0); 196