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 #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
129
130
131 static struct sigaction irq_sigaction[16] = {
132 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
133 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
134 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
135 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
136 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
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 };
141
142
143
144
145
146
147
148
149 void do_IRQ(int irq, struct pt_regs * regs)
150 {
151 struct sigaction * sa = irq + irq_sigaction;
152
153 sa->sa_handler((int) regs);
154 }
155
156
157
158
159
160
161 void do_fast_IRQ(int irq)
162 {
163 struct sigaction * sa = irq + irq_sigaction;
164
165 sa->sa_handler(irq);
166 }
167
168 int irqaction(unsigned int irq, struct sigaction * new)
169 {
170 struct sigaction * sa;
171 unsigned long flags;
172
173 if (irq > 15)
174 return -EINVAL;
175 sa = irq + irq_sigaction;
176 if (sa->sa_mask)
177 return -EBUSY;
178 if (!new->sa_handler)
179 return -EINVAL;
180 save_flags(flags);
181 cli();
182 *sa = *new;
183 sa->sa_mask = 1;
184 if (sa->sa_flags & SA_INTERRUPT)
185 set_intr_gate(0x20+irq,fast_interrupt[irq]);
186 else
187 set_intr_gate(0x20+irq,interrupt[irq]);
188 if (irq < 8) {
189 cache_21 &= ~(1<<irq);
190 outb(cache_21,0x21);
191 } else {
192 cache_21 &= ~(1<<2);
193 cache_A1 &= ~(1<<(irq-8));
194 outb(cache_21,0x21);
195 outb(cache_A1,0xA1);
196 }
197 restore_flags(flags);
198 return 0;
199 }
200
201 int request_irq(unsigned int irq, void (*handler)(int))
202 {
203 struct sigaction sa;
204
205 sa.sa_handler = handler;
206 sa.sa_flags = 0;
207 sa.sa_mask = 0;
208 sa.sa_restorer = NULL;
209 return irqaction(irq,&sa);
210 }
211
212 void free_irq(unsigned int irq)
213 {
214 struct sigaction * sa = irq + irq_sigaction;
215 unsigned long flags;
216
217 if (irq > 15) {
218 printk("Trying to free IRQ%d\n",irq);
219 return;
220 }
221 if (!sa->sa_mask) {
222 printk("Trying to free free IRQ%d\n",irq);
223 return;
224 }
225 save_flags(flags);
226 cli();
227 if (irq < 8) {
228 cache_21 |= 1 << irq;
229 outb(cache_21,0x21);
230 } else {
231 cache_A1 |= 1 << (irq-8);
232 outb(cache_A1,0xA1);
233 }
234 set_intr_gate(0x20+irq,bad_interrupt[irq]);
235 sa->sa_handler = NULL;
236 sa->sa_flags = 0;
237 sa->sa_mask = 0;
238 sa->sa_restorer = NULL;
239 restore_flags(flags);
240 }
241
242
243
244
245
246
247
248
249 static void math_error_irq(int cpl)
250 {
251 outb(0,0xF0);
252 if (ignore_irq13)
253 return;
254 send_sig(SIGFPE, last_task_used_math, 1);
255 __asm__("fninit");
256 }
257
258 static void no_action(int cpl) { }
259
260 static struct sigaction ignore_IRQ = {
261 no_action,
262 0,
263 SA_INTERRUPT,
264 NULL
265 };
266
267 void init_IRQ(void)
268 {
269 int i;
270
271 for (i = 0; i < 16 ; i++)
272 set_intr_gate(0x20+i,bad_interrupt[i]);
273 if (irqaction(2,&ignore_IRQ))
274 printk("Unable to get IRQ2 for cascade\n");
275 if (request_irq(13,math_error_irq))
276 printk("Unable to get IRQ13 for math-error handler\n");
277
278
279 for (i = 0; i < 32; i++) {
280 bh_base[i].routine = NULL;
281 bh_base[i].data = NULL;
282 }
283 bh_active = 0;
284 intr_count = 0;
285 }