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__
37typedef uint32_t evtchn_port_t;
38DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
39#define __XEN_EVTCHN_PORT_DEFINED__ 1
40#endif
41
42/** Registered Xen interrupt callback handle. */
43typedef void * xen_intr_handle_t;
44
45/** If non-zero, the hypervisor has been configured to use a direct vector */
46extern 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 */
66int 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 */
90int 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 */
114int 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 */
139int 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 */
157int 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 * Unbind an interrupt handler from its interrupt source.
163 *
164 * \param handlep  A pointer to the opaque handle that was initialized
165 *		   at the time the interrupt source was bound.
166 *
167 * \returns  0 on success, otherwise an errno.
168 *
169 * \note  The event channel, if any, that was allocated at bind time is
170 *        closed upon successful return of this method.
171 *
172 * \note  It is always safe to call xen_intr_unbind() on a handle that
173 *        has been initilized to NULL.
174 */
175void xen_intr_unbind(xen_intr_handle_t *handle);
176
177/**
178 * Add a description to an interrupt handler.
179 *
180 * \param handle  The opaque handle that was initialized at the time
181 *		  the interrupt source was bound.
182 *
183 * \param fmt     The sprintf compatible format string for the description,
184 *                followed by optional sprintf arguments.
185 *
186 * \returns  0 on success, otherwise an errno.
187 */
188int
189xen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...)
190	__attribute__((format(printf, 2, 3)));
191
192/**
193 * Signal the remote peer of an interrupt source associated with an
194 * event channel port.
195 *
196 * \param handle  The opaque handle that was initialized at the time
197 *                the interrupt source was bound.
198 *
199 * \note  For xen interrupt sources other than event channel ports,
200 *        this method takes no action.
201 */
202void xen_intr_signal(xen_intr_handle_t handle);
203
204/**
205 * Get the local event channel port number associated with this interrupt
206 * source.
207 *
208 * \param handle  The opaque handle that was initialized at the time
209 *                the interrupt source was bound.
210 *
211 * \returns  0 if the handle is invalid, otherwise positive port number.
212 */
213evtchn_port_t xen_intr_port(xen_intr_handle_t handle);
214
215#endif /* _XEN_INTR_H_ */
216