1 /****************************************************************************** 2 * xen_intr.h 3 * 4 * APIs for managing Xen event channel, virtual IRQ, and physical IRQ 5 * notifications. 6 * 7 * Copyright (c) 2004, K A Fraser 8 * Copyright (c) 2012, Spectra Logic Corporation 9 * 10 * This file may be distributed separately from the Linux kernel, or 11 * incorporated into other software packages, subject to the following license: 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining a copy 14 * of this source file (the "Software"), to deal in the Software without 15 * restriction, including without limitation the rights to use, copy, modify, 16 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 17 * and to permit persons to whom the Software is furnished to do so, subject to 18 * the following conditions: 19 * 20 * The above copyright notice and this permission notice shall be included in 21 * all copies or substantial portions of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 29 * IN THE SOFTWARE. 30 * 31 * $FreeBSD$ 32 */ 33 #ifndef _XEN_INTR_H_ 34 #define _XEN_INTR_H_ 35 36 #ifndef __XEN_EVTCHN_PORT_DEFINED__ 37 typedef uint32_t evtchn_port_t; 38 DEFINE_XEN_GUEST_HANDLE(evtchn_port_t); 39 #define __XEN_EVTCHN_PORT_DEFINED__ 1 40 #endif 41 42 /** Registered Xen interrupt callback handle. */ 43 typedef void * xen_intr_handle_t; 44 45 /** If non-zero, the hypervisor has been configured to use a direct vector */ 46 extern int xen_vector_callback_enabled; 47 48 /** 49 * Associate an already allocated local event channel port an interrupt 50 * handler. 51 * 52 * \param dev The device making this bind request. 53 * \param local_port The event channel to bind. 54 * \param filter An interrupt filter handler. Specify NULL 55 * to always dispatch to the ithread handler. 56 * \param handler An interrupt ithread handler. Optional (can 57 * specify NULL) if all necessary event actions 58 * are performed by filter. 59 * \param arg Argument to present to both filter and handler. 60 * \param irqflags Interrupt handler flags. See sys/bus.h. 61 * \param handlep Pointer to an opaque handle used to manage this 62 * registration. 63 * 64 * \returns 0 on success, otherwise an errno. 65 */ 66 int xen_intr_bind_local_port(device_t dev, evtchn_port_t local_port, 67 driver_filter_t filter, driver_intr_t handler, void *arg, 68 enum intr_type irqflags, xen_intr_handle_t *handlep); 69 70 /** 71 * Allocate a local event channel port, accessible by the specified 72 * remote/foreign domain and, if successful, associate the port with 73 * the specified interrupt handler. 74 * 75 * \param dev The device making this bind request. 76 * \param remote_domain Remote domain grant permission to signal the 77 * newly allocated local port. 78 * \param filter An interrupt filter handler. Specify NULL 79 * to always dispatch to the ithread handler. 80 * \param handler An interrupt ithread handler. Optional (can 81 * specify NULL) if all necessary event actions 82 * are performed by filter. 83 * \param arg Argument to present to both filter and handler. 84 * \param irqflags Interrupt handler flags. See sys/bus.h. 85 * \param handlep Pointer to an opaque handle used to manage this 86 * registration. 87 * 88 * \returns 0 on success, otherwise an errno. 89 */ 90 int xen_intr_alloc_and_bind_local_port(device_t dev, 91 u_int remote_domain, driver_filter_t filter, driver_intr_t handler, 92 void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep); 93 94 /** 95 * Associate the specified interrupt handler with the remote event 96 * channel port specified by remote_domain and remote_port. 97 * 98 * \param dev The device making this bind request. 99 * \param remote_domain The domain peer for this event channel connection. 100 * \param remote_port Remote domain's local port number for this event 101 * channel port. 102 * \param filter An interrupt filter handler. Specify NULL 103 * to always dispatch to the ithread handler. 104 * \param handler An interrupt ithread handler. Optional (can 105 * specify NULL) if all necessary event actions 106 * are performed by filter. 107 * \param arg Argument to present to both filter and handler. 108 * \param irqflags Interrupt handler flags. See sys/bus.h. 109 * \param handlep Pointer to an opaque handle used to manage this 110 * registration. 111 * 112 * \returns 0 on success, otherwise an errno. 113 */ 114 int xen_intr_bind_remote_port(device_t dev, u_int remote_domain, 115 evtchn_port_t remote_port, driver_filter_t filter, 116 driver_intr_t handler, void *arg, enum intr_type irqflags, 117 xen_intr_handle_t *handlep); 118 119 /** 120 * Associate the specified interrupt handler with the specified Xen 121 * virtual interrupt source. 122 * 123 * \param dev The device making this bind request. 124 * \param virq The Xen virtual IRQ number for the Xen interrupt 125 * source being hooked. 126 * \param cpu The cpu on which interrupt events should be delivered. 127 * \param filter An interrupt filter handler. Specify NULL 128 * to always dispatch to the ithread handler. 129 * \param handler An interrupt ithread handler. Optional (can 130 * specify NULL) if all necessary event actions 131 * are performed by filter. 132 * \param arg Argument to present to both filter and handler. 133 * \param irqflags Interrupt handler flags. See sys/bus.h. 134 * \param handlep Pointer to an opaque handle used to manage this 135 * registration. 136 * 137 * \returns 0 on success, otherwise an errno. 138 */ 139 int xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu, 140 driver_filter_t filter, driver_intr_t handler, 141 void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep); 142 143 /** 144 * Allocate a local event channel port for servicing interprocessor 145 * interupts and, if successful, associate the port with the specified 146 * interrupt handler. 147 * 148 * \param dev The device making this bind request. 149 * \param cpu The cpu receiving the IPI. 150 * \param filter The interrupt filter servicing this IPI. 151 * \param irqflags Interrupt handler flags. See sys/bus.h. 152 * \param handlep Pointer to an opaque handle used to manage this 153 * registration. 154 * 155 * \returns 0 on success, otherwise an errno. 156 */ 157 int xen_intr_alloc_and_bind_ipi(device_t dev, u_int cpu, 158 driver_filter_t filter, enum intr_type irqflags, 159 xen_intr_handle_t *handlep); 160 161 /** 162 * Register a physical interrupt vector and setup the interrupt source. 163 * 164 * \param vector The global vector to use. 165 * \param trig Default trigger method. 166 * \param pol Default polarity of the interrupt. 167 * 168 * \returns 0 on success, otherwise an errno. 169 */ 170 int xen_register_pirq(int vector, enum intr_trigger trig, 171 enum intr_polarity pol); 172 173 /** 174 * Unbind an interrupt handler from its interrupt source. 175 * 176 * \param handlep A pointer to the opaque handle that was initialized 177 * at the time the interrupt source was bound. 178 * 179 * \returns 0 on success, otherwise an errno. 180 * 181 * \note The event channel, if any, that was allocated at bind time is 182 * closed upon successful return of this method. 183 * 184 * \note It is always safe to call xen_intr_unbind() on a handle that 185 * has been initilized to NULL. 186 */ 187 void xen_intr_unbind(xen_intr_handle_t *handle); 188 189 /** 190 * Add a description to an interrupt handler. 191 * 192 * \param handle The opaque handle that was initialized at the time 193 * the interrupt source was bound. 194 * 195 * \param fmt The sprintf compatible format string for the description, 196 * followed by optional sprintf arguments. 197 * 198 * \returns 0 on success, otherwise an errno. 199 */ 200 int 201 xen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...) 202 __attribute__((format(printf, 2, 3))); 203 204 /** 205 * Signal the remote peer of an interrupt source associated with an 206 * event channel port. 207 * 208 * \param handle The opaque handle that was initialized at the time 209 * the interrupt source was bound. 210 * 211 * \note For xen interrupt sources other than event channel ports, 212 * this method takes no action. 213 */ 214 void xen_intr_signal(xen_intr_handle_t handle); 215 216 /** 217 * Get the local event channel port number associated with this interrupt 218 * source. 219 * 220 * \param handle The opaque handle that was initialized at the time 221 * the interrupt source was bound. 222 * 223 * \returns 0 if the handle is invalid, otherwise positive port number. 224 */ 225 evtchn_port_t xen_intr_port(xen_intr_handle_t handle); 226 227 /** 228 * Setup MSI vector interrupt(s). 229 * 230 * \param dev The device that requests the binding. 231 * 232 * \param vector Requested initial vector to bind the MSI interrupt(s) to. 233 * 234 * \param count Number of vectors to allocate. 235 * 236 * \returns 0 on success, otherwise an errno. 237 */ 238 int xen_register_msi(device_t dev, int vector, int count); 239 240 /** 241 * Teardown a MSI vector interrupt. 242 * 243 * \param vector Requested vector to release. 244 * 245 * \returns 0 on success, otherwise an errno. 246 */ 247 int xen_release_msi(int vector); 248 249 /** 250 * Bind an event channel port with a handler 251 * 252 * \param dev The device making this bind request. 253 * \param filter An interrupt filter handler. Specify NULL 254 * to always dispatch to the ithread handler. 255 * \param handler An interrupt ithread handler. Optional (can 256 * specify NULL) if all necessary event actions 257 * are performed by filter. 258 * \param arg Argument to present to both filter and handler. 259 * \param irqflags Interrupt handler flags. See sys/bus.h. 260 * \param handle Opaque handle used to manage this registration. 261 * 262 * \returns 0 on success, otherwise an errno. 263 */ 264 int xen_intr_add_handler(device_t dev, driver_filter_t filter, 265 driver_intr_t handler, void *arg, enum intr_type flags, 266 xen_intr_handle_t handle); 267 268 #endif /* _XEN_INTR_H_ */ 269