1*c24c993fSbouyer /* $NetBSD: xenbus.h,v 1.25 2020/04/25 15:26:17 bouyer Exp $ */ 2636656c4Sbouyer /****************************************************************************** 3636656c4Sbouyer * xenbus.h 4636656c4Sbouyer * 5636656c4Sbouyer * Talks to Xen Store to figure out what devices we have. 6636656c4Sbouyer * 7636656c4Sbouyer * Copyright (C) 2005 Rusty Russell, IBM Corporation 8636656c4Sbouyer * Copyright (C) 2005 XenSource Ltd. 9636656c4Sbouyer * 10636656c4Sbouyer * This file may be distributed separately from the Linux kernel, or 11636656c4Sbouyer * incorporated into other software packages, subject to the following license: 12636656c4Sbouyer * 13636656c4Sbouyer * Permission is hereby granted, free of charge, to any person obtaining a copy 14636656c4Sbouyer * of this source file (the "Software"), to deal in the Software without 15636656c4Sbouyer * restriction, including without limitation the rights to use, copy, modify, 16636656c4Sbouyer * merge, publish, distribute, sublicense, and/or sell copies of the Software, 17636656c4Sbouyer * and to permit persons to whom the Software is furnished to do so, subject to 18636656c4Sbouyer * the following conditions: 19636656c4Sbouyer * 20636656c4Sbouyer * The above copyright notice and this permission notice shall be included in 21636656c4Sbouyer * all copies or substantial portions of the Software. 22636656c4Sbouyer * 23636656c4Sbouyer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24636656c4Sbouyer * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25636656c4Sbouyer * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26636656c4Sbouyer * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27636656c4Sbouyer * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28636656c4Sbouyer * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 29636656c4Sbouyer * IN THE SOFTWARE. 30636656c4Sbouyer */ 31636656c4Sbouyer 32636656c4Sbouyer #ifndef _ASM_XEN_XENBUS_H 33636656c4Sbouyer #define _ASM_XEN_XENBUS_H 34636656c4Sbouyer 35636656c4Sbouyer #include <sys/device.h> 36010da6cfSjdolecek #include <sys/bus.h> 37636656c4Sbouyer #include <sys/queue.h> 38ac8432e2Scherry #include <xen/include/public/xen.h> 39ac8432e2Scherry #include <xen/include/public/io/xenbus.h> 40ac8432e2Scherry #include <xen/include/public/io/xs_wire.h> 41ac8432e2Scherry #include <xen/include/public/grant_table.h> /* for grant_ref_t */ 42636656c4Sbouyer 43636656c4Sbouyer /* xenbus to hypervisor attach */ 44636656c4Sbouyer struct xenbus_attach_args { 45636656c4Sbouyer const char *xa_device; 46636656c4Sbouyer int xa_handle; 47010da6cfSjdolecek bus_dma_tag_t xa_dmat; 48636656c4Sbouyer }; 49636656c4Sbouyer 50636656c4Sbouyer /* devices to xenbus attach */ 51636656c4Sbouyer struct xenbusdev_attach_args { 52636656c4Sbouyer const char *xa_type; 53636656c4Sbouyer int xa_id; 54636656c4Sbouyer struct xenbus_device *xa_xbusd; 55636656c4Sbouyer }; 56636656c4Sbouyer 57636656c4Sbouyer /* Register callback to watch this node. */ 5814e4157fSbouyer struct xenbus_watch { 59636656c4Sbouyer SLIST_ENTRY(xenbus_watch) watch_next; 60636656c4Sbouyer 61636656c4Sbouyer /* Path being watched. */ 6208090ccfSjdolecek char *node; 63418f6d13Sjdolecek size_t node_sz; 64636656c4Sbouyer 65636656c4Sbouyer /* Callback (executed in a process context with no locks held). */ 66aceceafcSbouyer void (*xbw_callback)(struct xenbus_watch *, 67636656c4Sbouyer const char **vec, unsigned int len); 68aceceafcSbouyer struct xenbus_device *xbw_dev; 69636656c4Sbouyer }; 70636656c4Sbouyer 71636656c4Sbouyer 720c9571beSbouyer /* 730c9571beSbouyer * A xenbus device. Note that the malloced memory will be larger than 740c9571beSbouyer * sizeof(xenbus_device) to have the storage for xbusd_path, so xbusd_path 750c9571beSbouyer * has to be the last entry. 760c9571beSbouyer */ 77237137c8Sbouyer typedef enum { 78237137c8Sbouyer XENBUS_FRONTEND_DEVICE, 79237137c8Sbouyer XENBUS_BACKEND_DEVICE 80237137c8Sbouyer } xenbusdev_type_t; 81237137c8Sbouyer 82636656c4Sbouyer struct xenbus_device { 830c9571beSbouyer SLIST_ENTRY(xenbus_device) xbusd_entries; 84782d8289Sjdolecek char xbusd_otherend[64]; /* the otherend path (size arbitrary) */ 85aceceafcSbouyer int xbusd_otherend_id; /* the otherend's id */ 86aceceafcSbouyer /* callback for otherend change */ 87237137c8Sbouyer void (*xbusd_otherend_changed)(void *, XenbusState); 88237137c8Sbouyer xenbusdev_type_t xbusd_type; 89237137c8Sbouyer union { 90237137c8Sbouyer struct { 91af33bdeeScegger device_t f_dev; 92237137c8Sbouyer } f; 93237137c8Sbouyer struct { 94237137c8Sbouyer void *b_cookie; /* private to backend driver */ 95237137c8Sbouyer int (*b_detach)(void *); 96237137c8Sbouyer } b; 97237137c8Sbouyer } xbusd_u; 98aceceafcSbouyer int xbusd_has_error; 99aceceafcSbouyer /* for xenbus internal use */ 100aceceafcSbouyer struct xenbus_watch xbusd_otherend_watch; 10143fc8b6fSjdolecek size_t xbusd_sz; /* size of allocated structure */ 102718f3cb4Sjdolecek bus_dma_tag_t xbusd_dmat; 1030c9571beSbouyer const char xbusd_path[1]; /* our path */ 104636656c4Sbouyer }; 105636656c4Sbouyer 106237137c8Sbouyer /* 107237137c8Sbouyer * frontend devices use the normal autoconf(9) framework to attach. 108237137c8Sbouyer * backend drivers need something more clever because we want the 109237137c8Sbouyer * domain's name or uid in the device's name. Each backend driver registers 110237137c8Sbouyer * to xenbus. 111237137c8Sbouyer */ 112237137c8Sbouyer 113237137c8Sbouyer struct xenbus_backend_driver { 114237137c8Sbouyer SLIST_ENTRY(xenbus_backend_driver) xbakd_entries; 115237137c8Sbouyer int (*xbakd_create) (struct xenbus_device *); /* called for new devs */ 116237137c8Sbouyer const char *xbakd_type; /* device type we register for */ 117636656c4Sbouyer }; 118636656c4Sbouyer 119237137c8Sbouyer void xenbus_backend_register(struct xenbus_backend_driver *); 120237137c8Sbouyer 121636656c4Sbouyer struct xenbus_transaction; 122636656c4Sbouyer 123636656c4Sbouyer int xenbus_directory(struct xenbus_transaction *t, 124636656c4Sbouyer const char *dir, const char *node, unsigned int *num, 125636656c4Sbouyer char ***); 126125dad3dSjdolecek void xenbus_directory_free(unsigned int, char **); 127782d8289Sjdolecek int xenbus_read(struct xenbus_transaction *, 128782d8289Sjdolecek const char *, const char *, char *, size_t); 12914e4157fSbouyer int xenbus_read_ul(struct xenbus_transaction *, 1302613e19eSbouyer const char *, const char *, unsigned long *, int); 131f742db21Sichiro int xenbus_read_ull(struct xenbus_transaction *, 132f742db21Sichiro const char *, const char *, unsigned long long *, int); 133636656c4Sbouyer int xenbus_write(struct xenbus_transaction *t, 134636656c4Sbouyer const char *dir, const char *node, const char *string); 135636656c4Sbouyer int xenbus_mkdir(struct xenbus_transaction *t, 136636656c4Sbouyer const char *dir, const char *node); 137636656c4Sbouyer int xenbus_exists(struct xenbus_transaction *t, 138636656c4Sbouyer const char *dir, const char *node); 139636656c4Sbouyer int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node); 140636656c4Sbouyer struct xenbus_transaction *xenbus_transaction_start(void); 141636656c4Sbouyer int xenbus_transaction_end(struct xenbus_transaction *t, int abort); 142636656c4Sbouyer 143636656c4Sbouyer /* Single printf and write: returns -errno or 0. */ 144636656c4Sbouyer int xenbus_printf(struct xenbus_transaction *t, 145636656c4Sbouyer const char *dir, const char *node, const char *fmt, ...) 146636656c4Sbouyer __attribute__((format(printf, 4, 5))); 147636656c4Sbouyer 148636656c4Sbouyer /* notifer routines for when the xenstore comes up */ 149636656c4Sbouyer // XXX int register_xenstore_notifier(struct notifier_block *nb); 150636656c4Sbouyer // XXX void unregister_xenstore_notifier(struct notifier_block *nb); 151636656c4Sbouyer 152636656c4Sbouyer int register_xenbus_watch(struct xenbus_watch *watch); 153636656c4Sbouyer void unregister_xenbus_watch(struct xenbus_watch *watch); 154636656c4Sbouyer void xs_suspend(void); 155636656c4Sbouyer void xs_resume(void); 156636656c4Sbouyer 157636656c4Sbouyer /* Used by xenbus_dev to borrow kernel's store connection. */ 158636656c4Sbouyer int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void **); 15979743bc4Sjdolecek void xenbus_dev_reply_free(struct xsd_sockmsg *msg, void *); 160636656c4Sbouyer 161636656c4Sbouyer void xenbus_probe(void *); 162636656c4Sbouyer 1630c9571beSbouyer int xenbus_free_device(struct xenbus_device *); 1640c9571beSbouyer 165636656c4Sbouyer #define XENBUS_IS_ERR_READ(str) ({ \ 166636656c4Sbouyer if (!IS_ERR(str) && strlen(str) == 0) { \ 167636656c4Sbouyer kfree(str); \ 168636656c4Sbouyer str = ERR_PTR(-ERANGE); \ 169636656c4Sbouyer } \ 170636656c4Sbouyer IS_ERR(str); \ 171636656c4Sbouyer }) 172636656c4Sbouyer 173636656c4Sbouyer #define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE) 174636656c4Sbouyer 175636656c4Sbouyer 176636656c4Sbouyer /** 177636656c4Sbouyer * Register a watch on the given path/path2, using the given xenbus_watch 178636656c4Sbouyer * structure for storage, and the given callback function as the callback. 179636656c4Sbouyer * Return 0 on success, or -errno on error. On success, the watched path 180636656c4Sbouyer * (path/path2) will be saved as watch->node, and becomes the caller's to 181636656c4Sbouyer * kfree(). On error, watch->node will be NULL, so the caller has nothing to 182636656c4Sbouyer * free, the device will switch to XenbusStateClosing, and the error will be 183636656c4Sbouyer * saved in the store. 184636656c4Sbouyer */ 185636656c4Sbouyer int xenbus_watch_path2(struct xenbus_device *dev, const char *path, 186636656c4Sbouyer const char *path2, struct xenbus_watch *watch, 187636656c4Sbouyer void (*callback)(struct xenbus_watch *, 188636656c4Sbouyer const char **, unsigned int)); 189636656c4Sbouyer 190418f6d13Sjdolecek /* Unregister the watch, and free associated internal structures. */ 191418f6d13Sjdolecek void xenbus_unwatch_path(struct xenbus_watch *); 192636656c4Sbouyer 193636656c4Sbouyer /** 194636656c4Sbouyer * Advertise in the store a change of the given driver to the given new_state. 195636656c4Sbouyer * Perform the change inside the given transaction xbt. xbt may be NULL, in 196636656c4Sbouyer * which case this is performed inside its own transaction. Return 0 on 197636656c4Sbouyer * success, or -errno on error. On error, the device will switch to 198636656c4Sbouyer * XenbusStateClosing, and the error will be saved in the store. 199636656c4Sbouyer */ 200636656c4Sbouyer int xenbus_switch_state(struct xenbus_device *dev, 201636656c4Sbouyer struct xenbus_transaction *xbt, 202636656c4Sbouyer XenbusState new_state); 203636656c4Sbouyer 204636656c4Sbouyer 205636656c4Sbouyer /** 206636656c4Sbouyer * Grant access to the given ring_mfn to the peer of the given device. Return 207636656c4Sbouyer * 0 on success, or -errno on error. On error, the device will switch to 208636656c4Sbouyer * XenbusStateClosing, and the error will be saved in the store. 209636656c4Sbouyer */ 210636656c4Sbouyer int xenbus_grant_ring(struct xenbus_device *, paddr_t, grant_ref_t *); 211636656c4Sbouyer 212636656c4Sbouyer 213636656c4Sbouyer /** 214636656c4Sbouyer * Allocate an event channel for the given xenbus_device, assigning the newly 215636656c4Sbouyer * created local port to *port. Return 0 on success, or -errno on error. On 216636656c4Sbouyer * error, the device will switch to XenbusStateClosing, and the error will be 217636656c4Sbouyer * saved in the store. 218636656c4Sbouyer */ 219636656c4Sbouyer int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port); 220636656c4Sbouyer 221636656c4Sbouyer 222636656c4Sbouyer /** 223636656c4Sbouyer * Return the state of the driver rooted at the given store path, or 224636656c4Sbouyer * XenbusStateClosed if no state can be read. 225636656c4Sbouyer */ 226636656c4Sbouyer XenbusState xenbus_read_driver_state(const char *path); 227636656c4Sbouyer 228636656c4Sbouyer 229636656c4Sbouyer /*** 230636656c4Sbouyer * Report the given negative errno into the store, along with the given 231636656c4Sbouyer * formatted message. 232636656c4Sbouyer */ 233636656c4Sbouyer void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, 234636656c4Sbouyer ...); 235636656c4Sbouyer 236636656c4Sbouyer 237636656c4Sbouyer /*** 238636656c4Sbouyer * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by 239636656c4Sbouyer * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly 240636656c4Sbouyer * closedown of this driver and its peer. 241636656c4Sbouyer */ 242636656c4Sbouyer void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, 243636656c4Sbouyer ...); 244636656c4Sbouyer 245eba16022Sjym bool xenbus_device_suspend(struct xenbus_device *); 246eba16022Sjym bool xenbus_device_resume(struct xenbus_device *); 247636656c4Sbouyer 248636656c4Sbouyer #endif /* _ASM_XEN_XENBUS_H */ 249636656c4Sbouyer 250636656c4Sbouyer /* 251636656c4Sbouyer * Local variables: 252636656c4Sbouyer * c-file-style: "linux" 253636656c4Sbouyer * indent-tabs-mode: t 254636656c4Sbouyer * c-indent-level: 8 255636656c4Sbouyer * c-basic-offset: 8 256636656c4Sbouyer * tab-width: 8 257636656c4Sbouyer * End: 258636656c4Sbouyer */ 259