Rev 856 | Rev 1007 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
495 | giacomo | 1 | #include <linuxcomp.h> |
2 | |||
3 | #include <asm/ptrace.h> |
||
4 | #include <asm-generic/errno-base.h> |
||
5 | #include <linux/kernel.h> |
||
6 | |||
526 | giacomo | 7 | extern void *int_arg_table[MAX_INT_TABLE]; |
8 | extern void *int_func_table[MAX_INT_TABLE]; |
||
495 | giacomo | 9 | |
847 | giacomo | 10 | #define MAX_IRQS 16 |
11 | |||
12 | #ifndef NIL |
||
13 | #define NIL -1 /*+ integer unvalid value +*/ |
||
14 | #endif |
||
15 | |||
16 | struct int_handler { |
||
17 | void (*func)(int, void *dev_id, struct pt_regs *); |
||
18 | void *data; |
||
19 | int flags; |
||
20 | struct int_handler *next; |
||
21 | }; |
||
22 | |||
23 | static struct irq_handler_list { |
||
24 | struct int_handler *handlers; |
||
25 | } irq_list[MAX_IRQS]; |
||
26 | |||
27 | void init_linux_irq(); |
||
28 | extern void fast_call_intr(int no); |
||
29 | extern void* malloc(int size); |
||
30 | extern void free(void *ptr); |
||
31 | extern int handler_set(int no, void (*fast)(int), int pi, BYTE lock); |
||
32 | extern int handler_remove(int no); |
||
33 | |||
34 | unsigned long intr_count = 0; |
||
35 | static int init = 0; |
||
36 | |||
495 | giacomo | 37 | /* |
847 | giacomo | 38 | * Generic Linux interrupt handler. |
39 | */ |
||
513 | giacomo | 40 | void linux_intr(int irq) |
495 | giacomo | 41 | { |
847 | giacomo | 42 | struct pt_regs regs; |
43 | struct int_handler *ihp; |
||
44 | |||
45 | intr_count++; |
||
46 | |||
956 | mauro | 47 | //cprintf("(Int %d)", irq); |
48 | |||
847 | giacomo | 49 | ihp=irq_list[irq].handlers; |
50 | while (ihp) { |
||
51 | (*ihp->func)(irq, ihp->data, ®s); |
||
52 | ihp=ihp->next; |
||
53 | } |
||
54 | |||
55 | intr_count--; |
||
56 | |||
495 | giacomo | 57 | } |
58 | |||
847 | giacomo | 59 | void add_list(struct int_handler** headp, struct int_handler *ihp) |
60 | { |
||
61 | if (*headp == NULL) { |
||
62 | *headp=ihp; |
||
63 | return; |
||
64 | } |
||
65 | ihp->next=*headp; |
||
66 | *headp=ihp; |
||
67 | } |
||
68 | |||
69 | #define USE_IRQ_SERVER |
||
70 | |||
495 | giacomo | 71 | /* |
847 | giacomo | 72 | * Attach a handler to an IRQ. |
73 | */ |
||
495 | giacomo | 74 | int request_irq(unsigned int irq, void (*handler)(int, void *dev_id, struct pt_regs *), unsigned long flags, const char *device, void *dev_id) |
75 | { |
||
847 | giacomo | 76 | struct int_handler *ihp; |
77 | |||
78 | if (init == 0) |
||
79 | init_linux_irq(); |
||
80 | |||
81 | ihp=malloc(sizeof(struct int_handler)); |
||
82 | if (ihp == NULL) |
||
83 | return -ENOMEM; |
||
84 | |||
85 | if (irq_list[irq].handlers == NULL) |
||
86 | { |
||
87 | //* Warning: check if irq is used from somebody that doesn't share! |
||
88 | #ifdef USE_IRQ_SERVER |
||
89 | shark_handler_set(irq, NULL, NULL); |
||
90 | #else |
||
91 | handler_set(irq, linux_intr, NIL, TRUE); |
||
92 | #endif |
||
93 | } |
||
94 | ihp->func = handler; |
||
95 | ihp->flags = flags; |
||
96 | ihp->data = dev_id; |
||
97 | ihp->next = NULL; |
||
98 | add_list(&irq_list[irq].handlers, ihp); |
||
99 | |||
495 | giacomo | 100 | return 0; |
101 | } |
||
102 | |||
103 | /* |
||
847 | giacomo | 104 | * Deallocate an irq |
105 | */ |
||
106 | void free_irq(unsigned int irq, void *dev_id) |
||
495 | giacomo | 107 | { |
847 | giacomo | 108 | struct int_handler **headp, *ihp; |
513 | giacomo | 109 | |
847 | giacomo | 110 | headp=&irq_list[irq].handlers; |
111 | while (*headp) |
||
112 | { |
||
113 | ihp=*headp; |
||
114 | if (ihp->data == dev_id) |
||
115 | { |
||
116 | *headp=ihp->next; |
||
117 | free(ihp); |
||
118 | break; |
||
119 | } |
||
120 | headp=&ihp->next; |
||
121 | } |
||
513 | giacomo | 122 | |
847 | giacomo | 123 | if (irq_list[irq].handlers == NULL) |
124 | { |
||
125 | handler_remove(irq); |
||
126 | } |
||
495 | giacomo | 127 | } |
847 | giacomo | 128 | |
129 | void init_linux_irq() |
||
130 | { |
||
131 | int i; |
||
132 | |||
133 | for (i=0; i<MAX_IRQS; i++) |
||
134 | { |
||
135 | irq_list[i].handlers = NULL; |
||
136 | } |
||
137 | init=1; |
||
138 | } |