added rt_pend_tq support from Tomasz, plus my mods
authorDavid Schleef <ds@schleef.org>
Tue, 13 Mar 2001 09:28:09 +0000 (09:28 +0000)
committerDavid Schleef <ds@schleef.org>
Tue, 13 Mar 2001 09:28:09 +0000 (09:28 +0000)
comedi/Makefile
comedi/rt.c
comedi/rt_pend_tq/Makefile [new file with mode: 0644]
comedi/rt_pend_tq/rt_pend_tq.c [new file with mode: 0644]
comedi/rt_pend_tq/rt_pend_tq.h [new file with mode: 0644]

index 369d6d47f7d48b0a3aa877ea55b63243f6f935b0..fbe9cfa9ae1272d9be84dbab9eba3de72093d3ce 100644 (file)
@@ -1,7 +1,7 @@
 
 
 SUB_DIRS     := drivers
-ALL_SUB_DIRS := kcomedilib drivers realtime
+ALL_SUB_DIRS := kcomedilib drivers realtime rt_pend_tq
 MOD_SUB_DIRS := drivers
 MOD_IN_SUB_DIRS :=
 
@@ -13,8 +13,8 @@ ifneq ($(CONFIG_COMEDI_KLIB),)
 endif
 
 ifeq ($(CONFIG_COMEDI_RT),y)
-       MOD_SUB_DIRS += realtime
-       SUB_DIRS += realtime
+       MOD_SUB_DIRS += realtime rt_pend_tq
+       SUB_DIRS += realtime rt_pend_tq
 endif
 
 MOD_LIST_NAME := MISC_MODULES
index 16b6d5ecddaad5e7114d0187c7bd47586daa2c38..619fbb5bbb5e52082683a5aa9ab1c4f0c1359b69 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/irq.h>
 #include <asm/io.h>
 
+#include "rt_pend_tq/rt_pend_tq.h"
+
 #ifdef CONFIG_COMEDI_RTAI
 #include <rtai/rtai.h>
 
@@ -152,11 +154,6 @@ void comedi_switch_to_non_rt(comedi_device *dev)
        RT_spin_unlock_irq(&dev->spinlock);
 }
 
-void comedi_rt_pend_wakeup(wait_queue_head_t *q)
-{
-
-}
-
 #ifdef HAVE_RT_PEND_TQ
 void wake_up_int_handler(int arg1, void * arg2)
 {
@@ -164,6 +161,13 @@ void wake_up_int_handler(int arg1, void * arg2)
 }
 #endif
 
+void comedi_rt_pend_wakeup(wait_queue_head_t *q)
+{
+#ifdef HAVE_RT_PEND_TQ
+       rt_pend_call(wake_up_int_handler,0,q);
+#endif
+}
+
 
 /* RTAI section */
 #ifdef CONFIG_COMEDI_RTAI
diff --git a/comedi/rt_pend_tq/Makefile b/comedi/rt_pend_tq/Makefile
new file mode 100644 (file)
index 0000000..00815b0
--- /dev/null
@@ -0,0 +1,42 @@
+
+ALL_SUB_DIRS :=
+MOD_SUB_DIRS :=
+SUB_DIRS     :=
+MOD_LIST_NAME := MISC_MODULES
+
+EXTRA_CFLAGS := -I ../
+
+export-objs := 
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj-  :=
+
+obj-$(CONFIG_COMEDI_RT)                += rt_pend_tq.o
+
+obj-m += $(obj-y)
+
+#L_OBJS                := $(sort $(filter-out $(export-objs), $(obj-y)))
+#LX_OBJS       := $(sort $(filter     $(export-objs), $(obj-y)))
+#MI_OBJS       := $(sort $(filter-out $(export-objs), $(obj-y)))
+#MIX_OBJS      := $(sort $(filter     $(export-objs), $(obj-y)))
+M_OBJS         := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS                := $(sort $(filter     $(export-objs), $(obj-m)))
+
+
+
+include $(TOPDIR)/Rules.make
+
+ifdef CONFIG_COMEDI_RTL
+rt_pend_tq.o : rt_pend_tq_rtl.c
+
+endif
+
+ifdef CONFIG_COMEDI_RTAI
+rt_pend_tq.o : rt_pend_tq_rtai.c
+
+endif
+
+
+
diff --git a/comedi/rt_pend_tq/rt_pend_tq.c b/comedi/rt_pend_tq/rt_pend_tq.c
new file mode 100644 (file)
index 0000000..a4830da
--- /dev/null
@@ -0,0 +1,89 @@
+/* rt_pend_tq.c */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include "rt_pend_tq.h"
+#ifdef CONFIG_COMEDI_RTAI
+#include <rtai.h>
+#endif
+#ifdef CONFIG_COMEDI_RTLINUX
+#include <linux/rtl.h>
+#endif
+
+#ifdef standalone
+#define rt_pend_tq_init init_module
+#define rt_pend_tq_cleanup cleanup_module
+#endif
+
+volatile static struct rt_pend_tq rt_pend_tq[RT_PEND_TQ_SIZE]; 
+volatile static struct rt_pend_tq * volatile rt_pend_head= rt_pend_tq,
+       * volatile rt_pend_tail = rt_pend_tq;
+int rt_pend_tq_irq=0;
+
+// WARNING: following code not checked against race conditions yet.
+#define INC_CIRCULAR_PTR(ptr,begin,size) do {if(++(ptr)>=(begin)+(size)) (ptr)=(begin); } while(0)
+#define DEC_CIRCULAR_PTR(ptr,begin,size) do {if(--(ptr)<(begin)) (ptr)=(begin)+(size)-1; } while(0)
+
+int rt_pend_call(void (*func)(int arg1, void * arg2), int arg1, void * arg2)
+{
+       if(func==NULL)
+               return -EINVAL;
+       if(rt_pend_tq_irq<=0)
+               return -ENODEV;
+// FIXME: grab RT spinlock/cli
+       INC_CIRCULAR_PTR(rt_pend_head,rt_pend_tq,RT_PEND_TQ_SIZE);
+       if(rt_pend_head==rt_pend_tail) {
+               // overflow, we just refuse to take this request
+               DEC_CIRCULAR_PTR(rt_pend_head,rt_pend_tq,RT_PEND_TQ_SIZE);
+// FIXME: release RT spinlock/restore
+               return -EAGAIN;
+       }
+// FIXME: release RT spinlock/restore
+       rt_pend_head->func=func;
+       rt_pend_head->arg1=arg1;
+       rt_pend_head->arg2=arg2;
+#ifdef CONFIG_COMEDI_RTAI
+       rt_pend_linux_srq(rt_pend_tq_irq);
+#endif
+#ifdef CONFIG_COMEDI_RTLINUX
+       rtl_global_pend_irq(rt_pend_tq_irq);
+#endif
+       return 0;
+}
+
+#ifdef CONFIG_COMEDI_RTAI
+void rt_pend_irq_handler(void)
+#endif
+#ifdef CONFIG_COMEDI_RTLINUX
+void rt_pend_irq_handler(int irq, void *dev, struct pt_regs * regs)
+#endif
+{
+       while(rt_pend_head!=rt_pend_tail) {
+               INC_CIRCULAR_PTR(rt_pend_tail,rt_pend_tq,RT_PEND_TQ_SIZE);
+               rt_pend_tail->func(rt_pend_tail->arg1,rt_pend_tail->arg2);
+       }
+}
+
+int rt_pend_tq_init(void)
+{
+       rt_pend_head=rt_pend_tail=rt_pend_tq;
+#ifdef CONFIG_COMEDI_RTAI
+       rt_pend_tq_irq=rt_request_srq(0,rt_pend_irq_handler,NULL);
+#endif
+#ifdef CONFIG_COMEDI_RTLINUX
+       rt_pend_tq_irq=rtl_get_soft_irq(rt_pend_irq_handler,"rt_pend_irq");
+       if(rt_pend_tq_irq>0) 
+               printk("rt_pend_tq: RT bottom half scheduler initialized OK\n");
+       else
+               printk("rt_pend_tq: rtl_get_soft_irq failed\n");
+#endif
+       return 0;
+}
+
+void rt_pend_tq_cleanup(void)
+{
+       printk("rt_pend_tq: unloading\n");
+       free_irq(rt_pend_tq_irq,NULL);
+}
+
diff --git a/comedi/rt_pend_tq/rt_pend_tq.h b/comedi/rt_pend_tq/rt_pend_tq.h
new file mode 100644 (file)
index 0000000..5475a0c
--- /dev/null
@@ -0,0 +1,9 @@
+#define RT_PEND_TQ_SIZE 16
+struct rt_pend_tq {
+       void (*func)(int arg1, void * arg2);
+       int arg1;
+       void *arg2;
+} ;
+extern int rt_pend_call(void (*func)(int arg1, void * arg2), int arg1, void * arg2);
+extern int rt_pend_tq_init(void);
+extern void rt_pend_tq_cleanup(void);