1255040Sgibbs/******************************************************************************
2255040Sgibbs * xen_intr.h
3255040Sgibbs *
4255040Sgibbs * APIs for managing Xen event channel, virtual IRQ, and physical IRQ
5255040Sgibbs * notifications.
6255040Sgibbs *
7255040Sgibbs * Copyright (c) 2004, K A Fraser
8255040Sgibbs * Copyright (c) 2012, Spectra Logic Corporation
9255040Sgibbs *
10255040Sgibbs * This file may be distributed separately from the Linux kernel, or
11255040Sgibbs * incorporated into other software packages, subject to the following license:
12255040Sgibbs *
13255040Sgibbs * Permission is hereby granted, free of charge, to any person obtaining a copy
14255040Sgibbs * of this source file (the "Software"), to deal in the Software without
15255040Sgibbs * restriction, including without limitation the rights to use, copy, modify,
16255040Sgibbs * merge, publish, distribute, sublicense, and/or sell copies of the Software,
17255040Sgibbs * and to permit persons to whom the Software is furnished to do so, subject to
18255040Sgibbs * the following conditions:
19255040Sgibbs *
20255040Sgibbs * The above copyright notice and this permission notice shall be included in
21255040Sgibbs * all copies or substantial portions of the Software.
22255040Sgibbs *
23255040Sgibbs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24255040Sgibbs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25255040Sgibbs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26255040Sgibbs * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27255040Sgibbs * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28255040Sgibbs * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29255040Sgibbs * IN THE SOFTWARE.
30255040Sgibbs *
31255040Sgibbs * $FreeBSD$
32255040Sgibbs */
33186557Skmacy#ifndef _XEN_INTR_H_
34186557Skmacy#define _XEN_INTR_H_
35186557Skmacy
36255040Sgibbs#ifndef __XEN_EVTCHN_PORT_DEFINED__
37255040Sgibbstypedef uint32_t evtchn_port_t;
38255040SgibbsDEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
39255040Sgibbs#define __XEN_EVTCHN_PORT_DEFINED__ 1
40255040Sgibbs#endif
41186557Skmacy
42255040Sgibbs/** Registered Xen interrupt callback handle. */
43255040Sgibbstypedef void * xen_intr_handle_t;
44186557Skmacy
45255040Sgibbs/** If non-zero, the hypervisor has been configured to use a direct vector */
46255040Sgibbsextern int xen_vector_callback_enabled;
47186557Skmacy
48255040Sgibbs/**
49255040Sgibbs * Associate an already allocated local event channel port an interrupt
50255040Sgibbs * handler.
51255040Sgibbs *
52255040Sgibbs * \param dev         The device making this bind request.
53255040Sgibbs * \param local_port  The event channel to bind.
54255040Sgibbs * \param filter      An interrupt filter handler.  Specify NULL
55255040Sgibbs *                    to always dispatch to the ithread handler.
56255040Sgibbs * \param handler     An interrupt ithread handler.  Optional (can
57255040Sgibbs *                    specify NULL) if all necessary event actions
58255040Sgibbs *                    are performed by filter.
59255040Sgibbs * \param arg         Argument to present to both filter and handler.
60255040Sgibbs * \param irqflags    Interrupt handler flags.  See sys/bus.h.
61255040Sgibbs * \param handlep     Pointer to an opaque handle used to manage this
62255040Sgibbs *                    registration.
63255040Sgibbs *
64255040Sgibbs * \returns  0 on success, otherwise an errno.
65255040Sgibbs */
66255040Sgibbsint xen_intr_bind_local_port(device_t dev, evtchn_port_t local_port,
67255040Sgibbs	driver_filter_t filter, driver_intr_t handler, void *arg,
68255040Sgibbs	enum intr_type irqflags, xen_intr_handle_t *handlep);
69186557Skmacy
70255040Sgibbs/**
71255040Sgibbs * Allocate a local event channel port, accessible by the specified
72255040Sgibbs * remote/foreign domain and, if successful, associate the port with
73255040Sgibbs * the specified interrupt handler.
74255040Sgibbs *
75255040Sgibbs * \param dev            The device making this bind request.
76255040Sgibbs * \param remote_domain  Remote domain grant permission to signal the
77255040Sgibbs *                       newly allocated local port.
78255040Sgibbs * \param filter         An interrupt filter handler.  Specify NULL
79255040Sgibbs *                       to always dispatch to the ithread handler.
80255040Sgibbs * \param handler        An interrupt ithread handler.  Optional (can
81255040Sgibbs *                       specify NULL) if all necessary event actions
82255040Sgibbs *                       are performed by filter.
83255040Sgibbs * \param arg            Argument to present to both filter and handler.
84255040Sgibbs * \param irqflags       Interrupt handler flags.  See sys/bus.h.
85255040Sgibbs * \param handlep        Pointer to an opaque handle used to manage this
86255040Sgibbs *                       registration.
87255040Sgibbs *
88255040Sgibbs * \returns  0 on success, otherwise an errno.
89255040Sgibbs */
90255040Sgibbsint xen_intr_alloc_and_bind_local_port(device_t dev,
91255040Sgibbs	u_int remote_domain, driver_filter_t filter, driver_intr_t handler,
92255040Sgibbs	void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep);
93186557Skmacy
94255040Sgibbs/**
95255040Sgibbs * Associate the specified interrupt handler with the remote event
96255040Sgibbs * channel port specified by remote_domain and remote_port.
97255040Sgibbs *
98255040Sgibbs * \param dev            The device making this bind request.
99255040Sgibbs * \param remote_domain  The domain peer for this event channel connection.
100255040Sgibbs * \param remote_port    Remote domain's local port number for this event
101255040Sgibbs *                       channel port.
102255040Sgibbs * \param filter         An interrupt filter handler.  Specify NULL
103255040Sgibbs *                       to always dispatch to the ithread handler.
104255040Sgibbs * \param handler        An interrupt ithread handler.  Optional (can
105255040Sgibbs *                       specify NULL) if all necessary event actions
106255040Sgibbs *                       are performed by filter.
107255040Sgibbs * \param arg            Argument to present to both filter and handler.
108255040Sgibbs * \param irqflags       Interrupt handler flags.  See sys/bus.h.
109255040Sgibbs * \param handlep        Pointer to an opaque handle used to manage this
110255040Sgibbs *                       registration.
111255040Sgibbs *
112255040Sgibbs * \returns  0 on success, otherwise an errno.
113189699Sdfr */
114255040Sgibbsint xen_intr_bind_remote_port(device_t dev, u_int remote_domain,
115255040Sgibbs	evtchn_port_t remote_port, driver_filter_t filter,
116255040Sgibbs	driver_intr_t handler, void *arg, enum intr_type irqflags,
117255040Sgibbs	xen_intr_handle_t *handlep);
118186557Skmacy
119255040Sgibbs/**
120255040Sgibbs * Associate the specified interrupt handler with the specified Xen
121255040Sgibbs * virtual interrupt source.
122255040Sgibbs *
123255040Sgibbs * \param dev       The device making this bind request.
124255040Sgibbs * \param virq      The Xen virtual IRQ number for the Xen interrupt
125255040Sgibbs *                  source being hooked.
126255040Sgibbs * \param cpu       The cpu on which interrupt events should be delivered.
127255040Sgibbs * \param filter    An interrupt filter handler.  Specify NULL
128255040Sgibbs *                  to always dispatch to the ithread handler.
129255040Sgibbs * \param handler   An interrupt ithread handler.  Optional (can
130255040Sgibbs *                  specify NULL) if all necessary event actions
131255040Sgibbs *                  are performed by filter.
132255040Sgibbs * \param arg       Argument to present to both filter and handler.
133255040Sgibbs * \param irqflags  Interrupt handler flags.  See sys/bus.h.
134255040Sgibbs * \param handlep   Pointer to an opaque handle used to manage this
135255040Sgibbs *                  registration.
136255040Sgibbs *
137255040Sgibbs * \returns  0 on success, otherwise an errno.
138189699Sdfr */
139255040Sgibbsint xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu,
140255040Sgibbs	driver_filter_t filter, driver_intr_t handler,
141255040Sgibbs	void *arg, enum intr_type irqflags, xen_intr_handle_t *handlep);
142189699Sdfr
143255040Sgibbs/**
144255331Sgibbs * Allocate a local event channel port for servicing interprocessor
145255331Sgibbs * interupts and, if successful, associate the port with the specified
146255331Sgibbs * interrupt handler.
147255040Sgibbs *
148255040Sgibbs * \param dev       The device making this bind request.
149255040Sgibbs * \param cpu       The cpu receiving the IPI.
150255331Sgibbs * \param filter    The interrupt filter servicing this IPI.
151255040Sgibbs * \param irqflags  Interrupt handler flags.  See sys/bus.h.
152255040Sgibbs * \param handlep   Pointer to an opaque handle used to manage this
153255040Sgibbs *                  registration.
154255040Sgibbs *
155255040Sgibbs * \returns  0 on success, otherwise an errno.
156189699Sdfr */
157255331Sgibbsint xen_intr_alloc_and_bind_ipi(device_t dev, u_int cpu,
158255040Sgibbs	driver_filter_t filter, enum intr_type irqflags,
159255040Sgibbs	xen_intr_handle_t *handlep);
160189699Sdfr
161255040Sgibbs/**
162255040Sgibbs * Unbind an interrupt handler from its interrupt source.
163255040Sgibbs *
164255040Sgibbs * \param handlep  A pointer to the opaque handle that was initialized
165255040Sgibbs *		   at the time the interrupt source was bound.
166255040Sgibbs *
167255040Sgibbs * \returns  0 on success, otherwise an errno.
168255040Sgibbs *
169255040Sgibbs * \note  The event channel, if any, that was allocated at bind time is
170255040Sgibbs *        closed upon successful return of this method.
171255040Sgibbs *
172255040Sgibbs * \note  It is always safe to call xen_intr_unbind() on a handle that
173255040Sgibbs *        has been initilized to NULL.
174189699Sdfr */
175255040Sgibbsvoid xen_intr_unbind(xen_intr_handle_t *handle);
176186557Skmacy
177255040Sgibbs/**
178255040Sgibbs * Add a description to an interrupt handler.
179255040Sgibbs *
180255040Sgibbs * \param handle  The opaque handle that was initialized at the time
181255040Sgibbs *		  the interrupt source was bound.
182255040Sgibbs *
183255040Sgibbs * \param fmt     The sprintf compatible format string for the description,
184255040Sgibbs *                followed by optional sprintf arguments.
185255040Sgibbs *
186255040Sgibbs * \returns  0 on success, otherwise an errno.
187189699Sdfr */
188255040Sgibbsint
189255040Sgibbsxen_intr_describe(xen_intr_handle_t port_handle, const char *fmt, ...)
190255040Sgibbs	__attribute__((format(printf, 2, 3)));
191189699Sdfr
192255040Sgibbs/**
193255040Sgibbs * Signal the remote peer of an interrupt source associated with an
194255040Sgibbs * event channel port.
195255040Sgibbs *
196255040Sgibbs * \param handle  The opaque handle that was initialized at the time
197255040Sgibbs *                the interrupt source was bound.
198255040Sgibbs *
199255040Sgibbs * \note  For xen interrupt sources other than event channel ports,
200255040Sgibbs *        this method takes no action.
201189699Sdfr */
202255040Sgibbsvoid xen_intr_signal(xen_intr_handle_t handle);
203186557Skmacy
204255040Sgibbs/**
205255040Sgibbs * Get the local event channel port number associated with this interrupt
206255040Sgibbs * source.
207255040Sgibbs *
208255040Sgibbs * \param handle  The opaque handle that was initialized at the time
209255040Sgibbs *                the interrupt source was bound.
210255040Sgibbs *
211255040Sgibbs * \returns  0 if the handle is invalid, otherwise positive port number.
212189699Sdfr */
213255040Sgibbsevtchn_port_t xen_intr_port(xen_intr_handle_t handle);
214186557Skmacy
215186557Skmacy#endif /* _XEN_INTR_H_ */
216