Rev 526 | Rev 856 | 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 | // irq_mask(irq); |
||
46 | |||
47 | intr_count++; |
||
48 | |||
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 | // irq_unmask(irq); |
||
57 | |||
495 | giacomo | 58 | } |
59 | |||
847 | giacomo | 60 | void add_list(struct int_handler** headp, struct int_handler *ihp) |
61 | { |
||
62 | if (*headp == NULL) { |
||
63 | *headp=ihp; |
||
64 | return; |
||
65 | } |
||
66 | ihp->next=*headp; |
||
67 | *headp=ihp; |
||
68 | } |
||
69 | |||
70 | #define USE_IRQ_SERVER |
||
71 | |||
495 | giacomo | 72 | /* |
847 | giacomo | 73 | * Attach a handler to an IRQ. |
74 | */ |
||
495 | giacomo | 75 | int request_irq(unsigned int irq, void (*handler)(int, void *dev_id, struct pt_regs *), unsigned long flags, const char *device, void *dev_id) |
76 | { |
||
847 | giacomo | 77 | struct int_handler *ihp; |
78 | |||
79 | if (init == 0) |
||
80 | init_linux_irq(); |
||
81 | |||
82 | ihp=malloc(sizeof(struct int_handler)); |
||
83 | if (ihp == NULL) |
||
84 | return -ENOMEM; |
||
85 | |||
86 | if (irq_list[irq].handlers == NULL) |
||
87 | { |
||
88 | //* Warning: check if irq is used from somebody that doesn't share! |
||
89 | #ifdef USE_IRQ_SERVER |
||
90 | shark_handler_set(irq, NULL, NULL); |
||
91 | #else |
||
92 | handler_set(irq, linux_intr, NIL, TRUE); |
||
93 | #endif |
||
94 | } |
||
95 | ihp->func = handler; |
||
96 | ihp->flags = flags; |
||
97 | ihp->data = dev_id; |
||
98 | ihp->next = NULL; |
||
99 | add_list(&irq_list[irq].handlers, ihp); |
||
100 | |||
495 | giacomo | 101 | return 0; |
102 | } |
||
103 | |||
104 | /* |
||
847 | giacomo | 105 | * Deallocate an irq |
106 | */ |
||
107 | void free_irq(unsigned int irq, void *dev_id) |
||
495 | giacomo | 108 | { |
847 | giacomo | 109 | struct int_handler **headp, *ihp; |
513 | giacomo | 110 | |
847 | giacomo | 111 | headp=&irq_list[irq].handlers; |
112 | while (*headp) |
||
113 | { |
||
114 | ihp=*headp; |
||
115 | if (ihp->data == dev_id) |
||
116 | { |
||
117 | *headp=ihp->next; |
||
118 | free(ihp); |
||
119 | break; |
||
120 | } |
||
121 | headp=&ihp->next; |
||
122 | } |
||
513 | giacomo | 123 | |
847 | giacomo | 124 | if (irq_list[irq].handlers == NULL) |
125 | { |
||
126 | handler_remove(irq); |
||
127 | } |
||
495 | giacomo | 128 | } |
847 | giacomo | 129 | |
130 | void init_linux_irq() |
||
131 | { |
||
132 | int i; |
||
133 | |||
134 | for (i=0; i<MAX_IRQS; i++) |
||
135 | { |
||
136 | irq_list[i].handlers = NULL; |
||
137 | } |
||
138 | init=1; |
||
139 | } |