xref: /freebsd/sys/xen/xen_intr.h (revision 8aac90f18aef7c9eea906c3ff9a001ca7b94f375)
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 #ifndef _XEN_INTR_H_
32 #define _XEN_INTR_H_
33 
34 #include <contrib/xen/event_channel.h>
35 
36 /** Registered Xen interrupt callback handle. */
37 typedef void * xen_intr_handle_t;
38 
39 /*
40  * Main handler for Xen event channel interrupts
41  */
42 extern driver_filter_t xen_intr_handle_upcall;
43 
44 /**
45  * Associate an already allocated local event channel port an interrupt
46  * handler.
47  *
48  * \param dev         The device making this bind request.
49  * \param local_port  The event channel to bind.
50  * \param filter      An interrupt filter handler.  Specify NULL
51  *                    to always dispatch to the ithread handler.
52  * \param handler     An interrupt ithread handler.  Optional (can
53  *                    specify NULL) if all necessary event actions
54  *                    are performed by filter.
55  * \param arg         Argument to present to both filter and handler.
56  * \param irqflags    Interrupt handler flags.  See sys/bus.h.
57  * \param handlep     Pointer to an opaque handle used to manage this
58  *                    registration.
59  *
60  * \returns  0 on success, otherwise an errno.
61  */
62 int xen_intr_bind_local_port(device_t dev, evtchn_port_t local_port,
63 	driver_filter_t filter, driver_intr_t handler, void *arg,
64 	enum intr_type irqflags, xen_intr_handle_t *handlep);
65 
66 /**
67  * Allocate a local event channel port, accessible by the specified
68  * remote/foreign domain and, if successful, associate the port with
69  * the specified interrupt handler.
70  *
71  * \param dev            The device making this bind request.
72  * \param remote_domain  Remote domain grant permission to signal the
73  *                       newly allocated local port.
74  * \param filter         An interrupt filter handler.  Specify NULL
75  *                       to always dispatch to the ithread handler.
76  * \param handler        An interrupt ithread handler.  Optional (can
77  *                       specify NULL) if all necessary event actions
78  *                       are performed by filter.
79  * \param arg            Argument to present to both filter and handler.
80  * \param irqflags       Interrupt handler flags.  See sys/bus.h.
81  * \param handlep        Pointer to an opaque handle used to manage this
82  *                       registration.
83  *
84  * \returns  0 on success, otherwise an errno.
85  */
86 int xen_intr_alloc_and_bind_local_port(device_t dev,
87 	u_int remote_domain, driver_filter_t filter, driver_intr_t handler,
88 	void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep);
89 
90 /**
91  * Associate the specified interrupt handler with the remote event
92  * channel port specified by remote_domain and remote_port.
93  *
94  * \param dev            The device making this bind request.
95  * \param remote_domain  The domain peer for this event channel connection.
96  * \param remote_port    Remote domain's local port number for this event
97  *                       channel port.
98  * \param filter         An interrupt filter handler.  Specify NULL
99  *                       to always dispatch to the ithread handler.
100  * \param handler        An interrupt ithread handler.  Optional (can
101  *                       specify NULL) if all necessary event actions
102  *                       are performed by filter.
103  * \param arg            Argument to present to both filter and handler.
104  * \param irqflags       Interrupt handler flags.  See sys/bus.h.
105  * \param handlep        Pointer to an opaque handle used to manage this
106  *                       registration.
107  *
108  * \returns  0 on success, otherwise an errno.
109  */
110 int xen_intr_bind_remote_port(device_t dev, u_int remote_domain,
111 	evtchn_port_t remote_port, driver_filter_t filter,
112 	driver_intr_t handler, void *arg, enum intr_type irqflags,
113 	xen_intr_handle_t *handlep);
114 
115 /**
116  * Associate the specified interrupt handler with the specified Xen
117  * virtual interrupt source.
118  *
119  * \param dev       The device making this bind request.
120  * \param virq      The Xen virtual IRQ number for the Xen interrupt
121  *                  source being hooked.
122  * \param cpu       The cpu on which interrupt events should be delivered.
123  * \param filter    An interrupt filter handler.  Specify NULL
124  *                  to always dispatch to the ithread handler.
125  * \param handler   An interrupt ithread handler.  Optional (can
126  *                  specify NULL) if all necessary event actions
127  *                  are performed by filter.
128  * \param arg       Argument to present to both filter and handler.
129  * \param irqflags  Interrupt handler flags.  See sys/bus.h.
130  * \param handlep   Pointer to an opaque handle used to manage this
131  *                  registration.
132  *
133  * \returns  0 on success, otherwise an errno.
134  */
135 int xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu,
136 	driver_filter_t filter, driver_intr_t handler,
137 	void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep);
138 
139 /**
140  * Allocate a local event channel port for servicing interprocessor
141  * interupts and, if successful, associate the port with the specified
142  * interrupt handler.
143  *
144  * \param cpu       The cpu receiving the IPI.
145  * \param filter    The interrupt filter servicing this IPI.
146  * \param irqflags  Interrupt handler flags.  See sys/bus.h.
147  * \param handlep   Pointer to an opaque handle used to manage this
148  *                  registration.
149  *
150  * \returns  0 on success, otherwise an errno.
151  */
152 int xen_intr_alloc_and_bind_ipi(u_int cpu,
153 	driver_filter_t filter, enum intr_type irqflags,
154 	xen_intr_handle_t *handlep);
155 
156 /**
157  * Unbind an interrupt handler from its interrupt source.
158  *
159  * \param handlep  A pointer to the opaque handle that was initialized
160  *		   at the time the interrupt source was bound.
161  *
162  * \returns  0 on success, otherwise an errno.
163  *
164  * \note  The event channel, if any, that was allocated at bind time is
165  *        closed upon successful return of this method.
166  *
167  * \note  It is always safe to call xen_intr_unbind() on a handle that
168  *        has been initilized to NULL.
169  */
170 void xen_intr_unbind(xen_intr_handle_t *handle);
171 
172 /**
173  * Add a description to an interrupt handler.
174  *
175  * \param handle  The opaque handle that was initialized at the time
176  *		  the interrupt source was bound.
177  *
178  * \param fmt     The sprintf compatible format string for the description,
179  *                followed by optional sprintf arguments.
180  *
181  * \returns  0 on success, otherwise an errno.
182  */
183 int
184 xen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...)
185 	__attribute__((format(printf, 2, 3)));
186 
187 /**
188  * Signal the remote peer of an interrupt source associated with an
189  * event channel port.
190  *
191  * \param handle  The opaque handle that was initialized at the time
192  *                the interrupt source was bound.
193  *
194  * \note  For xen interrupt sources other than event channel ports,
195  *        this method takes no action.
196  */
197 void xen_intr_signal(xen_intr_handle_t handle);
198 
199 /**
200  * Get the local event channel port number associated with this interrupt
201  * source.
202  *
203  * \param handle  The opaque handle that was initialized at the time
204  *                the interrupt source was bound.
205  *
206  * \returns  0 if the handle is invalid, otherwise positive port number.
207  */
208 evtchn_port_t xen_intr_port(xen_intr_handle_t handle);
209 
210 /**
211  * Bind an event channel port with a handler
212  *
213  * \param dev       The device making this bind request.
214  * \param filter    An interrupt filter handler.  Specify NULL
215  *                  to always dispatch to the ithread handler.
216  * \param handler   An interrupt ithread handler.  Optional (can
217  *                  specify NULL) if all necessary event actions
218  *                  are performed by filter.
219  * \param arg       Argument to present to both filter and handler.
220  * \param irqflags  Interrupt handler flags.  See sys/bus.h.
221  * \param handle    Opaque handle used to manage this registration.
222  *
223  * \returns  0 on success, otherwise an errno.
224  */
225 int xen_intr_add_handler(const char *name, driver_filter_t filter,
226 	driver_intr_t handler, void *arg, enum intr_type flags,
227 	xen_intr_handle_t handle);
228 
229 /**
230  * Get a reference to an event channel port
231  *
232  * \param port	    Event channel port to which we get a reference.
233  * \param handlep   Pointer to an opaque handle used to manage this
234  *                  registration.
235  *
236  * \returns  0 on success, otherwise an errno.
237  */
238 int xen_intr_get_evtchn_from_port(evtchn_port_t port,
239 	xen_intr_handle_t *handlep);
240 
241 #endif /* _XEN_INTR_H_ */
242