00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <agnix/agnix.h>
00015 #include <agnix/list.h>
00016 #include <agnix/irq.h>
00017 #include <agnix/queues.h>
00018 #include <agnix/tasks.h>
00019 #include <agnix/threads.h>
00020 #include <agnix/sched.h>
00021 #include <agnix/memory.h>
00022 #include <agnix/ioport.h>
00023 #include <agnix/fastrand.h>
00024 #include <agnix/console.h>
00025
00026 #define MOD_NAME "FASTIRQS: "
00027
00028 int fastirq_queue_desc;
00029 struct task_s *fastirq_task;
00030 int fastirq_started = 0;
00031 u32 fastirq_count[IRQ_MAX];
00032
00033 extern struct irq_s irq_info[IRQ_MAX];
00034 extern u32 random_val;
00035
00036 int fastirq_queue(u8 irq)
00037 {
00038 fastirq_count[irq]++;
00039 sched_activate_task(fastirq_task);
00040
00041 return 0;
00042 }
00043
00044 void fastirq_run_irq(u8 irq)
00045 {
00046 struct irq_s *irq_struct = &irq_info[irq];
00047 struct irq_routine_s *irq_proc;
00048 struct list_head *tmp;
00049 void (*proc)(u32);
00050 int (*check)(void);
00051 int irq_check_ok;
00052 u32 data;
00053 u32 flags;
00054
00055 spin_lock_irqsave(&irq_struct->lock, flags);
00056
00057 if (!list_empty(&irq_struct->head)) {
00058 list_for_each(tmp, &irq_struct->head) {
00059 irq_proc = list_entry(tmp, struct irq_routine_s, list);
00060 proc = irq_proc->proc;
00061 data = irq_proc->data;
00062 check = irq_proc->check;
00063 irq_check_ok = 1;
00064
00065 if (check)
00066 irq_check_ok = check();
00067
00068 if (!irq_check_ok)
00069 continue;
00070
00071 if (proc) {
00072 proc(data);
00073 }
00074
00075 if (irq_proc->flags & IRQ_FLAG_RANDOM)
00076 random_val = _fastrand(random_val);
00077 }
00078 }
00079
00080 spin_unlock_irqrestore(&irq_struct->lock, flags);
00081 }
00082
00083 void fastirq_thread(void *data)
00084 {
00085 int i;
00086
00087 fastirq_task = current_task;
00088 fastirq_started = 1;
00089
00090 __cli();
00091
00092 for (;;) {
00093 for (i = 0; i < IRQ_MAX; i++) {
00094 if (fastirq_count[i] > 0) {
00095 fastirq_run_irq((u8)i);
00096 fastirq_count[i] = 0;
00097 }
00098 }
00099
00100 sched_deactivate_task(current_task);
00101 schedule_task();
00102 }
00103 }
00104
00105 int fastirq_init(void)
00106 {
00107 printk(MOD_NAME "Initializing fastirqs\n");
00108
00109 create_kernel_thread("fastirq", fastirq_thread, NULL);
00110
00111 return 0;
00112 }