This source file includes following definitions.
- do_bottom_half
- do_IRQ
- do_fast_IRQ
- irqaction
- request_irq
- free_irq
- math_error_irq
- no_action
- init_IRQ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include <linux/ptrace.h>
26 #include <linux/errno.h>
27 #include <linux/signal.h>
28 #include <linux/sched.h>
29 #include <linux/interrupt.h>
30
31 #include <asm/system.h>
32 #include <asm/io.h>
33 #include <asm/irq.h>
34
35
36 void irq13(void);
37
38 static unsigned long intr_count=0;
39
40
41 int bh_active=0;
42 struct bh_struct bh_base[32];
43
44
45
46
47 void do_bottom_half(void)
48 {
49 struct bh_struct *bh;
50 int mask;
51 int count;
52 static int in_bh = 0;
53
54 cli();
55 if (intr_count > 1) {
56 intr_count--;
57 return;
58 }
59
60
61 intr_count = 0;
62
63
64 if (in_bh != 0) {
65 return;
66 }
67
68 in_bh = 1;
69 do {
70 count = 0;
71 for (mask = 1, bh = bh_base; mask ; bh++, mask = mask << 1) {
72 if (mask > bh_active)
73 break;
74 if (!(mask & bh_active))
75 continue;
76
77 count++;
78 bh_active &= ~mask;
79
80
81 sti();
82
83 if (bh->routine != NULL)
84 bh->routine(bh->data);
85 else
86 printk ("irq.c:bad bottom half entry.\n");
87
88
89 cli();
90 }
91 } while (count > 0);
92 in_bh = 0;
93 }
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 BUILD_IRQ(FIRST,0,0x01)
111 BUILD_IRQ(FIRST,1,0x02)
112 BUILD_IRQ(FIRST,2,0x04)
113 BUILD_IRQ(FIRST,3,0x08)
114 BUILD_IRQ(FIRST,4,0x10)
115 BUILD_IRQ(FIRST,5,0x20)
116 BUILD_IRQ(FIRST,6,0x40)
117 BUILD_IRQ(FIRST,7,0x80)
118 BUILD_IRQ(SECOND,8,0x01)
119 BUILD_IRQ(SECOND,9,0x02)
120 BUILD_IRQ(SECOND,10,0x04)
121 BUILD_IRQ(SECOND,11,0x08)
122 BUILD_IRQ(SECOND,12,0x10)
123 BUILD_IRQ(SECOND,13,0x20)
124 BUILD_IRQ(SECOND,14,0x40)
125 BUILD_IRQ(SECOND,15,0x80)
126
127
128
129
130
131 static void (*interrupt[16])(void) = {
132 IRQ0_interrupt, IRQ1_interrupt, IRQ2_interrupt, IRQ3_interrupt,
133 IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
134 IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
135 IRQ12_interrupt, IRQ13_interrupt, IRQ14_interrupt, IRQ15_interrupt
136 };
137
138 static void (*fast_interrupt[16])(void) = {
139 fast_IRQ0_interrupt, fast_IRQ1_interrupt,
140 fast_IRQ2_interrupt, fast_IRQ3_interrupt,
141 fast_IRQ4_interrupt, fast_IRQ5_interrupt,
142 fast_IRQ6_interrupt, fast_IRQ7_interrupt,
143 fast_IRQ8_interrupt, fast_IRQ9_interrupt,
144 fast_IRQ10_interrupt, fast_IRQ11_interrupt,
145 fast_IRQ12_interrupt, fast_IRQ13_interrupt,
146 fast_IRQ14_interrupt, fast_IRQ15_interrupt
147 };
148
149 static void (*bad_interrupt[16])(void) = {
150 bad_IRQ0_interrupt, bad_IRQ1_interrupt,
151 bad_IRQ2_interrupt, bad_IRQ3_interrupt,
152 bad_IRQ4_interrupt, bad_IRQ5_interrupt,
153 bad_IRQ6_interrupt, bad_IRQ7_interrupt,
154 bad_IRQ8_interrupt, bad_IRQ9_interrupt,
155 bad_IRQ10_interrupt, bad_IRQ11_interrupt,
156 bad_IRQ12_interrupt, bad_IRQ13_interrupt,
157 bad_IRQ14_interrupt, bad_IRQ15_interrupt
158 };
159
160
161
162
163 static struct sigaction irq_sigaction[16] = {
164 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
165 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
166 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
167 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
168 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
169 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
170 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
171 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
172 };
173
174
175
176
177
178
179
180
181 void do_IRQ(int irq, struct pt_regs * regs)
182 {
183 struct sigaction * sa = irq + irq_sigaction;
184
185 sa->sa_handler((int) regs);
186 }
187
188
189
190
191
192
193 void do_fast_IRQ(int irq)
194 {
195 struct sigaction * sa = irq + irq_sigaction;
196
197 sa->sa_handler(irq);
198 }
199
200 int irqaction(unsigned int irq, struct sigaction * new)
201 {
202 struct sigaction * sa;
203 unsigned long flags;
204
205 if (irq > 15)
206 return -EINVAL;
207 sa = irq + irq_sigaction;
208 if (sa->sa_mask)
209 return -EBUSY;
210 if (!new->sa_handler)
211 return -EINVAL;
212 save_flags(flags);
213 cli();
214 *sa = *new;
215 sa->sa_mask = 1;
216 if (sa->sa_flags & SA_INTERRUPT)
217 set_intr_gate(0x20+irq,fast_interrupt[irq]);
218 else
219 set_intr_gate(0x20+irq,interrupt[irq]);
220 if (irq < 8)
221 outb(inb_p(0x21) & ~(1<<irq),0x21);
222 else {
223 outb(inb_p(0x21) & ~(1<<2),0x21);
224 outb(inb_p(0xA1) & ~(1<<(irq-8)),0xA1);
225 }
226 restore_flags(flags);
227 return 0;
228 }
229
230 int request_irq(unsigned int irq, void (*handler)(int))
231 {
232 struct sigaction sa;
233
234 sa.sa_handler = handler;
235 sa.sa_flags = 0;
236 sa.sa_mask = 0;
237 sa.sa_restorer = NULL;
238 return irqaction(irq,&sa);
239 }
240
241 void free_irq(unsigned int irq)
242 {
243 struct sigaction * sa = irq + irq_sigaction;
244 unsigned long flags;
245
246 if (irq > 15) {
247 printk("Trying to free IRQ%d\n",irq);
248 return;
249 }
250 if (!sa->sa_mask) {
251 printk("Trying to free free IRQ%d\n",irq);
252 return;
253 }
254 save_flags(flags);
255 cli();
256 if (irq < 8)
257 outb(inb_p(0x21) | (1<<irq),0x21);
258 else
259 outb(inb_p(0xA1) | (1<<(irq-8)),0xA1);
260 set_intr_gate(0x20+irq,bad_interrupt[irq]);
261 sa->sa_handler = NULL;
262 sa->sa_flags = 0;
263 sa->sa_mask = 0;
264 sa->sa_restorer = NULL;
265 restore_flags(flags);
266 }
267
268 extern void do_coprocessor_error(long,long);
269
270 static void math_error_irq(int cpl)
271 {
272 outb(0,0xF0);
273 do_coprocessor_error(0,0);
274 }
275
276 static void no_action(int cpl) { }
277
278 static struct sigaction ignore_IRQ = {
279 no_action,
280 0,
281 SA_INTERRUPT,
282 NULL
283 };
284
285 void init_IRQ(void)
286 {
287 int i;
288
289 for (i = 0; i < 16 ; i++)
290 set_intr_gate(0x20+i,bad_interrupt[i]);
291 if (irqaction(2,&ignore_IRQ))
292 printk("Unable to get IRQ2 for cascade\n");
293 if (request_irq(13,math_error_irq))
294 printk("Unable to get IRQ13 for math-error handler\n");
295
296
297 for (i = 0; i < 32; i++)
298 {
299 bh_base[i].routine = NULL;
300 bh_base[i].data = NULL;
301 }
302 bh_active = 0;
303
304 }