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. */
37typedef void * xen_intr_handle_t;
38
39/*
40 * Main handler for Xen event channel interrupts
41 */
42extern 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 */
62int 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 */
86int 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 */
110int 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 */
135int 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 */
152int 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 */
170void 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 */
183int
184xen_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 */
197void 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 */
208evtchn_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 */
225int 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 */
238int xen_intr_get_evtchn_from_port(evtchn_port_t port,
239	xen_intr_handle_t *handlep);
240
241#endif /* _XEN_INTR_H_ */
242