2 ** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
5 #include <kernel/kernel.h>
6 #include <kernel/int.h>
7 #include <kernel/debug.h>
8 #include <kernel/heap.h>
9 #include <kernel/smp.h>
10 #include <kernel/arch/int.h>
11 #include <newos/errors.h>
12 #include <boot/stage2.h>
16 #define NUM_IO_HANDLERS 256
19 struct io_handler
*next
;
24 static struct io_handler
**io_handlers
= NULL
;
25 static spinlock_t int_handler_list_spinlock
= 0;
27 int int_init(kernel_args
*ka
)
29 dprintf("init_int_handlers: entry\n");
31 int_handler_list_spinlock
= 0;
33 return arch_int_init(ka
);
36 int int_init2(kernel_args
*ka
)
38 io_handlers
= (struct io_handler
**)kmalloc(sizeof(struct io_handler
*) * NUM_IO_HANDLERS
);
39 if(io_handlers
== NULL
)
40 panic("int_init2: could not create io handler table!\n");
42 memset(io_handlers
, 0, sizeof(struct io_handler
*) * NUM_IO_HANDLERS
);
44 return arch_int_init2(ka
);
47 int int_set_io_interrupt_handler(int vector
, int (*func
)(void*), void* data
)
49 struct io_handler
*io
;
52 // insert this io handler in the chain of interrupt
53 // handlers registered for this io interrupt
55 io
= (struct io_handler
*)kmalloc(sizeof(struct io_handler
));
61 state
= int_disable_interrupts();
62 acquire_spinlock(&int_handler_list_spinlock
);
63 io
->next
= io_handlers
[vector
];
64 io_handlers
[vector
] = io
;
65 release_spinlock(&int_handler_list_spinlock
);
66 int_restore_interrupts(state
);
68 arch_int_enable_io_interrupt(vector
);
73 int int_remove_io_interrupt_handler(int vector
, int (*func
)(void*), void* data
)
75 struct io_handler
*io
, *prev
= NULL
;
78 // lock the structures down so it is not modified while we search
79 state
= int_disable_interrupts();
80 acquire_spinlock(&int_handler_list_spinlock
);
82 // start at the beginning
83 io
= io_handlers
[vector
];
87 // see if we match both the function & data
88 if (io
->func
== func
&& io
->data
== data
)
91 // Store our backlink and move to next
98 // unlink it, taking care of the change it was the first in line
100 prev
->next
= io
->next
;
102 io_handlers
[vector
] = io
->next
;
105 // release our lock as we're done with the table
106 release_spinlock(&int_handler_list_spinlock
);
107 int_restore_interrupts(state
);
109 // and disable the IRQ if nothing left
111 if (prev
== NULL
&& io
->next
== NULL
)
112 arch_int_disable_io_interrupt(vector
);
117 return (io
!= NULL
) ? NO_ERROR
: ERR_INVALID_ARGS
;
120 int int_io_interrupt_handler(int vector
)
122 int ret
= INT_NO_RESCHEDULE
;
124 // XXX rare race condition here. The io_handlers list is not locked
125 // need to find a good way to solve that problem
127 if(io_handlers
[vector
] == NULL
) {
128 dprintf("unhandled io interrupt %d\n", vector
);
130 struct io_handler
*io
;
133 io
= io_handlers
[vector
];
135 temp_ret
= io
->func(io
->data
);
136 if(temp_ret
== INT_RESCHEDULE
)
137 ret
= INT_RESCHEDULE
;