This source file includes following definitions.
- disable_irq
- enable_irq
- get_irq_list
- request_irq
- free_irq
- handle_irq
- device_interrupt
- machine_check
- do_entInt
- init_IRQ
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/ptrace.h>
14 #include <linux/errno.h>
15 #include <linux/kernel_stat.h>
16 #include <linux/signal.h>
17 #include <linux/sched.h>
18 #include <linux/interrupt.h>
19
20 #include <asm/system.h>
21 #include <asm/io.h>
22 #include <asm/irq.h>
23 #include <asm/bitops.h>
24
25 static unsigned char cache_21 = 0xff;
26 static unsigned char cache_A1 = 0xff;
27
28 void disable_irq(unsigned int irq_nr)
29 {
30 unsigned long flags;
31 unsigned char mask;
32
33 mask = 1 << (irq_nr & 7);
34 save_flags(flags);
35 if (irq_nr < 8) {
36 cli();
37 cache_21 |= mask;
38 outb(cache_21,0x21);
39 restore_flags(flags);
40 return;
41 }
42 cli();
43 cache_A1 |= mask;
44 outb(cache_A1,0xA1);
45 restore_flags(flags);
46 }
47
48 void enable_irq(unsigned int irq_nr)
49 {
50 unsigned long flags;
51 unsigned char mask;
52
53 mask = ~(1 << (irq_nr & 7));
54 save_flags(flags);
55 if (irq_nr < 8) {
56 cli();
57 cache_21 &= mask;
58 outb(cache_21,0x21);
59 restore_flags(flags);
60 return;
61 }
62 cli();
63 cache_A1 &= mask;
64 outb(cache_A1,0xA1);
65 restore_flags(flags);
66 }
67
68
69
70
71 struct irqaction {
72 void (*handler)(int, struct pt_regs *);
73 unsigned long flags;
74 unsigned long mask;
75 const char *name;
76 };
77
78 static struct irqaction irq_action[16] = {
79 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
80 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
81 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
82 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
83 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
84 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
85 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
86 { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
87 };
88
89 int get_irq_list(char *buf)
90 {
91 int i, len = 0;
92 struct irqaction * action = irq_action;
93
94 for (i = 0 ; i < 16 ; i++, action++) {
95 if (!action->handler)
96 continue;
97 len += sprintf(buf+len, "%2d: %8d %c %s\n",
98 i, kstat.interrupts[i],
99 (action->flags & SA_INTERRUPT) ? '+' : ' ',
100 action->name);
101 }
102 return len;
103 }
104
105 int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
106 unsigned long irqflags, const char * devname)
107 {
108 struct irqaction * action;
109 unsigned long flags;
110
111 if (irq > 15)
112 return -EINVAL;
113 action = irq + irq_action;
114 if (action->handler)
115 return -EBUSY;
116 if (!handler)
117 return -EINVAL;
118 save_flags(flags);
119 cli();
120 action->handler = handler;
121 action->flags = irqflags;
122 action->mask = 0;
123 action->name = devname;
124 if (irq < 8) {
125 cache_21 &= ~(1<<irq);
126 outb(cache_21,0x21);
127 } else {
128 cache_21 &= ~(1<<2);
129 cache_A1 &= ~(1<<(irq-8));
130 outb(cache_21,0x21);
131 outb(cache_A1,0xA1);
132 }
133 restore_flags(flags);
134 return 0;
135 }
136
137 void free_irq(unsigned int irq)
138 {
139 halt();
140 }
141
142 static void handle_irq(int irq, struct pt_regs * regs)
143 {
144 struct irqaction * action = irq + irq_action;
145
146 kstat.interrupts[irq]++;
147 if (action->handler)
148 action->handler(irq, regs);
149 }
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 static void device_interrupt(unsigned long vector, struct pt_regs * regs)
176 {
177 int i;
178 static int nr = 0;
179
180 if (vector == 0x980 && irq_action[1].handler) {
181 handle_irq(1, regs);
182 return;
183 }
184
185 if (nr > 3)
186 return;
187 nr++;
188 printk("IO device interrupt, vector = %lx\n", vector);
189 printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
190 printk("Expecting: ");
191 for (i = 0; i < 16; i++)
192 if (irq_action[i].handler)
193 printk("[%s:%d] ", irq_action[i].name, i);
194 printk("\n");
195 printk("64=%02x, 60=%02x, 3fa=%02x 2fa=%02x\n",
196 inb(0x64), inb(0x60), inb(0x3fa), inb(0x2fa));
197 printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
198 }
199
200 static void machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs)
201 {
202 printk("Machine check\n");
203 }
204
205 asmlinkage void do_entInt(unsigned long type, unsigned long vector,
206 unsigned long la_ptr, struct pt_regs *regs)
207 {
208 switch (type) {
209 case 0:
210 printk("Interprocessor interrupt? You must be kidding\n");
211 break;
212 case 1:
213
214 handle_irq(0, regs);
215 return;
216 case 2:
217 machine_check(vector, la_ptr, regs);
218 break;
219 case 3:
220 device_interrupt(vector, regs);
221 return;
222 case 4:
223 printk("Performance counter interrupt\n");
224 break;;
225 default:
226 printk("Hardware intr %ld %lx? Huh?\n", type, vector);
227 }
228 printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
229 }
230
231 extern asmlinkage void entInt(void);
232
233 void init_IRQ(void)
234 {
235 wrent(entInt, 0);
236 }