From 4b739a479628ad8238e733d61489799f244aad50 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Tue, 13 Mar 2001 09:28:09 +0000 Subject: [PATCH] added rt_pend_tq support from Tomasz, plus my mods --- comedi/Makefile | 6 +-- comedi/rt.c | 14 ++++-- comedi/rt_pend_tq/Makefile | 42 ++++++++++++++++ comedi/rt_pend_tq/rt_pend_tq.c | 89 ++++++++++++++++++++++++++++++++++ comedi/rt_pend_tq/rt_pend_tq.h | 9 ++++ 5 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 comedi/rt_pend_tq/Makefile create mode 100644 comedi/rt_pend_tq/rt_pend_tq.c create mode 100644 comedi/rt_pend_tq/rt_pend_tq.h diff --git a/comedi/Makefile b/comedi/Makefile index 369d6d47..fbe9cfa9 100644 --- a/comedi/Makefile +++ b/comedi/Makefile @@ -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 diff --git a/comedi/rt.c b/comedi/rt.c index 16b6d5ec..619fbb5b 100644 --- a/comedi/rt.c +++ b/comedi/rt.c @@ -36,6 +36,8 @@ #include #include +#include "rt_pend_tq/rt_pend_tq.h" + #ifdef CONFIG_COMEDI_RTAI #include @@ -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 index 00000000..00815b0f --- /dev/null +++ b/comedi/rt_pend_tq/Makefile @@ -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 index 00000000..a4830da2 --- /dev/null +++ b/comedi/rt_pend_tq/rt_pend_tq.c @@ -0,0 +1,89 @@ +/* rt_pend_tq.c */ +#include +#include +#include +#include +#include "rt_pend_tq.h" +#ifdef CONFIG_COMEDI_RTAI +#include +#endif +#ifdef CONFIG_COMEDI_RTLINUX +#include +#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 index 00000000..5475a0cb --- /dev/null +++ b/comedi/rt_pend_tq/rt_pend_tq.h @@ -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); -- 2.26.2