checkin if some disabled code that checks for interrupts being disabled when we take...
[newos.git] / kernel / int.c
blob814707220682743c056babd2da4a67af44c11946
1 /*
2 ** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
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>
13 #include <string.h>
14 #include <stdio.h>
16 #define NUM_IO_HANDLERS 256
18 struct io_handler {
19 struct io_handler *next;
20 int (*func)(void*);
21 void* data;
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;
50 int state;
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));
56 if(io == NULL)
57 return ERR_NO_MEMORY;
58 io->func = func;
59 io->data = data;
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);
70 return NO_ERROR;
73 int int_remove_io_interrupt_handler(int vector, int (*func)(void*), void* data)
75 struct io_handler *io, *prev = NULL;
76 int state;
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];
85 // while not at end
86 while(io != NULL) {
87 // see if we match both the function & data
88 if (io->func == func && io->data == data)
89 break;
91 // Store our backlink and move to next
92 prev = io;
93 io = io->next;
96 // If we found it
97 if (io != NULL) {
98 // unlink it, taking care of the change it was the first in line
99 if (prev != NULL)
100 prev->next = io->next;
101 else
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
110 if (io != NULL) {
111 if (prev == NULL && io->next == NULL)
112 arch_int_disable_io_interrupt(vector);
114 kfree(io);
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);
129 } else {
130 struct io_handler *io;
131 int temp_ret;
133 io = io_handlers[vector];
134 while(io != NULL) {
135 temp_ret = io->func(io->data);
136 if(temp_ret == INT_RESCHEDULE)
137 ret = INT_RESCHEDULE;
138 io = io->next;
142 return ret;