Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / include / xen / evtchn.h
1 #if defined(CONFIG_PARAVIRT_XEN) || !defined(__KERNEL__)
2 #include "public/evtchn.h"
3 #else
4 /******************************************************************************
5  * evtchn.h
6  *
7  * Communication via Xen event channels.
8  * Also definitions for the device that demuxes notifications to userspace.
9  *
10  * Copyright (c) 2003-2005, K A Fraser
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License version 2
14  * as published by the Free Software Foundation; or, when distributed
15  * separately from the Linux kernel or incorporated into other
16  * software packages, subject to the following license:
17  *
18  * Permission is hereby granted, free of charge, to any person obtaining a copy
19  * of this source file (the "Software"), to deal in the Software without
20  * restriction, including without limitation the rights to use, copy, modify,
21  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
22  * and to permit persons to whom the Software is furnished to do so, subject to
23  * the following conditions:
24  *
25  * The above copyright notice and this permission notice shall be included in
26  * all copies or substantial portions of the Software.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
34  * IN THE SOFTWARE.
35  */
36
37 #ifndef __ASM_EVTCHN_H__
38 #define __ASM_EVTCHN_H__
39
40 #include <linux/interrupt.h>
41 #include <asm/hypervisor.h>
42 #include <asm/ptrace.h>
43 #include <asm/sync_bitops.h>
44 #include <xen/interface/event_channel.h>
45 #include <linux/smp.h>
46
47 /*
48  * LOW-LEVEL DEFINITIONS
49  */
50
51 #ifdef CONFIG_XEN
52 struct irq_cfg {
53         u32 info;
54         union {
55                 int bindcount; /* for dynamic IRQs */
56 #ifdef CONFIG_X86_IO_APIC
57                 u8 vector; /* for physical IRQs */
58 #endif
59         };
60 };
61 struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node);
62 static inline int evtchn_make_refcounted(unsigned int evtchn) { return 0; }
63 #endif
64
65 /*
66  * Dynamically bind an event source to an IRQ-like callback handler.
67  * On some platforms this may not be implemented via the Linux IRQ subsystem.
68  * The IRQ argument passed to the callback handler is the same as returned
69  * from the bind call. It may not correspond to a Linux IRQ number.
70  * Returns IRQ or negative errno.
71  */
72 int bind_caller_port_to_irqhandler(
73         unsigned int caller_port,
74         irq_handler_t handler,
75         unsigned long irqflags,
76         const char *devname,
77         void *dev_id);
78 int bind_listening_port_to_irqhandler(
79         unsigned int remote_domain,
80         irq_handler_t handler,
81         unsigned long irqflags,
82         const char *devname,
83         void *dev_id);
84 int bind_interdomain_evtchn_to_irqhandler(
85         unsigned int remote_domain,
86         unsigned int remote_port,
87         irq_handler_t handler,
88         unsigned long irqflags,
89         const char *devname,
90         void *dev_id);
91 int bind_virq_to_irqhandler(
92         unsigned int virq,
93         unsigned int cpu,
94         irq_handler_t handler,
95         unsigned long irqflags,
96         const char *devname,
97         void *dev_id);
98 #if defined(CONFIG_SMP) && defined(CONFIG_XEN) && defined(CONFIG_X86)
99 int bind_virq_to_irqaction(
100         unsigned int virq,
101         unsigned int cpu,
102         struct irqaction *action);
103 #else
104 #define bind_virq_to_irqaction(virq, cpu, action) \
105         bind_virq_to_irqhandler(virq, cpu, (action)->handler, \
106                                 (action)->flags | IRQF_NOBALANCING, \
107                                 (action)->name, action)
108 #endif
109 #if defined(CONFIG_SMP) && !defined(MODULE)
110 #ifndef CONFIG_X86
111 int bind_ipi_to_irqhandler(
112         unsigned int ipi,
113         unsigned int cpu,
114         irq_handler_t handler,
115         unsigned long irqflags,
116         const char *devname,
117         void *dev_id);
118 #else
119 int bind_ipi_to_irqaction(
120         unsigned int cpu,
121         struct irqaction *action);
122 DECLARE_PER_CPU(DECLARE_BITMAP(, NR_IPIS), ipi_pending);
123 #endif
124 #endif
125
126 /*
127  * Common unbind function for all event sources. Takes IRQ to unbind from.
128  * Automatically closes the underlying event channel (except for bindings
129  * made with bind_caller_port_to_irqhandler()).
130  */
131 void unbind_from_irqhandler(unsigned int irq, void *dev_id);
132
133 #if defined(CONFIG_SMP) && defined(CONFIG_XEN) && defined(CONFIG_X86)
134 /* Specialized unbind function for per-CPU IRQs. */
135 void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu,
136                              struct irqaction *);
137 #else
138 #define unbind_from_per_cpu_irq(irq, cpu, action) \
139         unbind_from_irqhandler(irq, action)
140 #endif
141
142 #ifndef CONFIG_XEN
143 void irq_resume(void);
144 #endif
145
146 /* Entry point for notifications into Linux subsystems. */
147 asmlinkage void evtchn_do_upcall(struct pt_regs *regs);
148
149 /* Mark a PIRQ as unavailable for dynamic allocation. */
150 void evtchn_register_pirq(int irq);
151 /* Map a Xen-supplied PIRQ to a dynamically allocated one. */
152 int evtchn_map_pirq(int irq, int xen_pirq);
153 /* Look up a Xen-supplied PIRQ for a dynamically allocated one. */
154 int evtchn_get_xen_pirq(int irq);
155
156 void mask_evtchn(int port);
157 void disable_all_local_evtchn(void);
158 void unmask_evtchn(int port);
159 unsigned int irq_from_evtchn(unsigned int port);
160
161 static inline int test_and_set_evtchn_mask(int port)
162 {
163         shared_info_t *s = HYPERVISOR_shared_info;
164         return sync_test_and_set_bit(port, s->evtchn_mask);
165 }
166
167 static inline void clear_evtchn(int port)
168 {
169         shared_info_t *s = HYPERVISOR_shared_info;
170         sync_clear_bit(port, s->evtchn_pending);
171 }
172
173 static inline void set_evtchn(int port)
174 {
175         shared_info_t *s = HYPERVISOR_shared_info;
176         sync_set_bit(port, s->evtchn_pending);
177 }
178
179 static inline int test_evtchn(int port)
180 {
181         shared_info_t *s = HYPERVISOR_shared_info;
182         return sync_test_bit(port, s->evtchn_pending);
183 }
184
185 static inline void notify_remote_via_evtchn(int port)
186 {
187         struct evtchn_send send = { .port = port };
188         VOID(HYPERVISOR_event_channel_op(EVTCHNOP_send, &send));
189 }
190
191 static inline void
192 multi_notify_remote_via_evtchn(multicall_entry_t *mcl, int port)
193 {
194         struct evtchn_send *send = (void *)(mcl->args + 2);
195
196         BUILD_BUG_ON(sizeof(*send) > sizeof(mcl->args) - 2 * sizeof(*mcl->args));
197         send->port = port;
198         mcl->op = __HYPERVISOR_event_channel_op;
199         mcl->args[0] = EVTCHNOP_send;
200         mcl->args[1] = (unsigned long)send;
201 }
202
203 static inline int close_evtchn(int port)
204 {
205         struct evtchn_close close = { .port = port };
206         return HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
207 }
208
209 /* Test an irq's pending state. */
210 int xen_test_irq_pending(int irq);
211
212 /*
213  * Use these to access the event channel underlying the IRQ handle returned
214  * by bind_*_to_irqhandler().
215  */
216 void notify_remote_via_irq(int irq);
217 int multi_notify_remote_via_irq(multicall_entry_t *, int irq);
218 int irq_to_evtchn_port(int irq);
219
220 #if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)
221 void notify_remote_via_ipi(unsigned int ipi, unsigned int cpu);
222 void clear_ipi_evtchn(void);
223 #endif
224
225 #if defined(CONFIG_XEN_SPINLOCK_ACQUIRE_NESTING) \
226     && CONFIG_XEN_SPINLOCK_ACQUIRE_NESTING
227 void xen_spin_irq_enter(void);
228 void xen_spin_irq_exit(void);
229 #else
230 static inline void xen_spin_irq_enter(void) {}
231 static inline void xen_spin_irq_exit(void) {}
232 #endif
233
234 #endif /* __ASM_EVTCHN_H__ */
235 #endif /* CONFIG_PARAVIRT_XEN */