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