From: Frank Mori Hess Date: Wed, 15 Jun 2005 23:24:19 +0000 (+0000) Subject: * Contributors: Added Alexis Berlemont and Simone Mannori. X-Git-Tag: r0_7_71~143 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=ea830a12c0cd2ae843c0bb031a2df00088ec12c7;p=comedi.git * Contributors: Added Alexis Berlemont and Simone Mannori. * Makefile.am: Fix depmod call on "make install". * comedi/rt.c: (comedi_request_irq), (comedi_free_irq), (comedi_switch_to_rt), (comedi_switch_to_non_rt), (handle_void_irq), (comedi_rt_get_irq), (fusion_handle_irq), (comedi_rt_release_irq), (comedi_rt_init), (comedi_rt_cleanup), (handle_rtl_irq): rtai fusion support from Alexis Berlemont, plus some cleanups by me. * comedi/rt_pend_tq.c: (rt_pend_call), (rt_pend_tq_init), (rt_pend_tq_cleanup): rtai fusion support from Alexis Berlemont. * include/linux/comedi_rt.h: Implemented comedi_spinlock_irqsave() and comedi_spinlock_irqrestore for rtai fusion. * m4/rtai.m4: rtai fusion support from Alexis Berlemont. --- diff --git a/ChangeLog b/ChangeLog index dc4ebfd8..ae4be3f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2005-06-15 Frank Hess + + * Contributors: Added Alexis Berlemont and Simone Mannori. + * Makefile.am: Fix depmod call on "make install". + * comedi/rt.c: (comedi_request_irq), (comedi_free_irq), + (comedi_switch_to_rt), (comedi_switch_to_non_rt), + (handle_void_irq), (comedi_rt_get_irq), (fusion_handle_irq), + (comedi_rt_release_irq), (comedi_rt_init), (comedi_rt_cleanup), + (handle_rtl_irq): rtai fusion support from Alexis Berlemont, + plus some cleanups by me. + * comedi/rt_pend_tq.c: (rt_pend_call), (rt_pend_tq_init), + (rt_pend_tq_cleanup): rtai fusion support from Alexis Berlemont. + * include/linux/comedi_rt.h: Implemented comedi_spinlock_irqsave() + and comedi_spinlock_irqrestore for rtai fusion. + * m4/rtai.m4: rtai fusion support from Alexis Berlemont. + + 2005-06-04 Frank Hess Patch from abbotti@mev.co.uk (Ian Abbott) to diff --git a/Contributors b/Contributors index dd1c7a23..b290cf0f 100644 --- a/Contributors +++ b/Contributors @@ -3,6 +3,7 @@ Ian Abbott Dave Andruczyk Chris R. Baugher Brent Baccala +Alexis Berlemont Anders Blomdell Eric Bunn Herman Bruyninckx @@ -24,6 +25,7 @@ Markus Kempf Harald Kirsch Jochen Küpper Brent Ledvina +Simone Mannori Ivan Martinez Luis Martínez J.P. Mellor diff --git a/Makefile.am b/Makefile.am index d32de637..716f671f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,8 +88,8 @@ moo: DISTCLEANFILES = modtool install-data-hook: - if test x"$(DESTDIR)" = x ; then \ - if test x"$(prefix)" = x/ ; then \ + if test x$(DESTDIR) = x ; then \ + if test x$(prefix) = x/ ; then \ $(DEPMOD) -ae $(LINUX_KERNELRELEASE) ; \ fi \ fi diff --git a/comedi/rt.c b/comedi/rt.c index 50721b4b..c0aea173 100644 --- a/comedi/rt.c +++ b/comedi/rt.c @@ -40,36 +40,21 @@ #ifdef CONFIG_COMEDI_RTAI #include +#endif -#define RT_protect() hard_cli() -#define RT_unprotect() hard_sti() -#define RT_spin_lock_irq(x) rt_spin_lock_irq(x) -#define RT_spin_unlock_irq(x) rt_spin_unlock_irq(x) +#ifdef CONFIG_COMEDI_FUSION +#include #endif #ifdef CONFIG_COMEDI_RTL #include #include - -#define RT_protect() rtl_make_rt_system_active() -#define RT_unprotect() rtl_make_rt_system_idle() -/* RTL doesn't have the necessary primitives, so we have to hack - * it, dealing with the race */ -#define RT_spin_lock_irq(x) do{RT_protect();rtl_spin_lock(x);}while(0) -#define RT_spin_unlock_irq(x) do{rtl_spin_unlock(x);RT_unprotect();}while(0) -#endif - -#ifdef CONFIG_PRIORITY_IRQ -#define RT_protect() __local_irq_disable() -#define RT_unprotect() __local_irq_enable() -#define RT_spin_lock_irq(x) spin_lock_hard_irq(x) -#define RT_spin_unlock_irq(x) spin_unlock_hard_irq(x) #endif struct comedi_irq_struct { int rt; int irq; - void (*handler)(int irq,void *dev_id,struct pt_regs *regs); + irqreturn_t (*handler)(int irq,void *dev_id,struct pt_regs *regs); unsigned long flags; const char *device; comedi_device *dev_id; @@ -78,97 +63,43 @@ struct comedi_irq_struct { static int comedi_rt_get_irq(struct comedi_irq_struct *it); static int comedi_rt_release_irq(struct comedi_irq_struct *it); -#define MAX_IRQ_SHARING 6 -static struct comedi_irq_struct *comedi_irqs[NR_IRQS][MAX_IRQ_SHARING]; - -static struct comedi_irq_struct * find_comedi_irq_struct( int irq, comedi_device *dev_id ) -{ - int i; - - for( i = 0; i < MAX_IRQ_SHARING; i++) - { - if( comedi_irqs[ irq ][ i ] && - comedi_irqs[ irq ][ i ]->dev_id == dev_id ) - { - return comedi_irqs[ irq ][ i ]; - } - } - return NULL; -} - -static void free_comedi_irq_struct( int irq, comedi_device *dev_id ) -{ - int i; - - for( i = 0; i < MAX_IRQ_SHARING; i++) - { - if( comedi_irqs[ irq ][ i ] && - comedi_irqs[ irq ][ i ]->dev_id == dev_id ) - { - kfree( comedi_irqs[ irq ][ i ] ); - comedi_irqs[ irq ][ i ] = NULL; - return; - } - } -} - -static int insert_comedi_irq_struct( int irq, - struct comedi_irq_struct *it ) -{ - int i; - - for( i = 0; i < MAX_IRQ_SHARING; i++ ) - { - if( comedi_irqs[ irq ][ i ] == NULL ) - { - comedi_irqs[ irq ][ i ] = it; - return 0; - } - } - return -1; -} +static struct comedi_irq_struct *comedi_irqs[NR_IRQS]; int comedi_request_irq(unsigned irq, irqreturn_t (*handler)(int, void *,struct pt_regs *), unsigned long flags,const char *device,comedi_device *dev_id) { struct comedi_irq_struct *it; int ret; - - it=kmalloc(sizeof(struct comedi_irq_struct),GFP_KERNEL); - if(!it) - return -ENOMEM; - memset(it,0,sizeof(struct comedi_irq_struct)); - - it->handler=handler; - it->irq=irq; - it->dev_id=dev_id; - it->device=device; - /* null shared interrupt flag, since rt interrupt handlers do not - * support it, and this version of comedi_request_irq() is only - * called for kernels with rt support */ - it->flags = flags & ~SA_SHIRQ; - - ret=request_irq(irq,handler,it->flags,device,dev_id); + * support it, and this version of comedi_request_irq() is only + * called for kernels with rt support */ + unsigned long unshared_flags = flags & ~SA_SHIRQ; + + ret = request_irq(irq, handler, unshared_flags, device, dev_id); if(ret<0){ - // we failed, so fall back on allowing shared interrupt + // we failed, so fall back on allowing shared interrupt (which we won't ever make RT) if(flags & SA_SHIRQ) { - it->flags = flags; - ret=request_irq(irq,handler,it->flags,device,dev_id); + rt_printk("comedi: cannot get unshared interrupt, will not use RT interrupts.\n"); + ret=request_irq(irq, handler, flags, device, dev_id); } if(ret<0){ - kfree(it); return ret; } - } - - if( insert_comedi_irq_struct( irq, it ) ) + }else { - kfree(it); - return -1; + it = kmalloc(sizeof(struct comedi_irq_struct), GFP_KERNEL); + if(!it) + return -ENOMEM; + memset(it, 0, sizeof(struct comedi_irq_struct)); + + it->handler=handler; + it->irq=irq; + it->dev_id=dev_id; + it->device=device; + it->flags = unshared_flags; + comedi_irqs[irq] = it; } - return 0; } @@ -176,7 +107,9 @@ void comedi_free_irq(unsigned int irq,comedi_device *dev_id) { struct comedi_irq_struct *it; - it = find_comedi_irq_struct( irq, dev_id ); + free_irq(irq, dev_id); + + it = comedi_irqs[irq]; if( it == NULL ) return; if(it->rt){ @@ -184,9 +117,8 @@ void comedi_free_irq(unsigned int irq,comedi_device *dev_id) comedi_rt_release_irq(it); } - free_irq(it->irq,it->dev_id); - - free_comedi_irq_struct( irq, dev_id ); + kfree(it); + comedi_irqs[irq] = NULL; } @@ -196,16 +128,11 @@ int comedi_switch_to_rt(comedi_device *dev) struct comedi_irq_struct *it; unsigned long flags; - it = find_comedi_irq_struct( dev->irq, dev ); - /* drivers might not be using an interrupt for commands */ + it = comedi_irqs[dev->irq]; + /* drivers might not be using an interrupt for commands, + or we might not have been able to get an unshared irq */ if( it == NULL ) return -1; - /* rt interrupts and shared interrupts don't mix */ - if(it->flags & SA_SHIRQ){ - rt_printk("comedi: cannot switch shared interrupt to RT priority\n"); - return -1; - } - comedi_spin_lock_irqsave( &dev->spinlock, flags ); if(!dev->rt) @@ -224,14 +151,10 @@ void comedi_switch_to_non_rt(comedi_device *dev) struct comedi_irq_struct *it; unsigned long flags; - it = find_comedi_irq_struct( dev->irq, dev ); + it = comedi_irqs[dev->irq]; if(it == NULL) return; - /* rt interrupts and shared interrupts don't mix */ - if(it->flags & SA_SHIRQ) - return; - comedi_spin_lock_irqsave( &dev->spinlock, flags ); dev->rt--; @@ -263,15 +186,15 @@ static void handle_void_irq_ ## irq (void){ handle_void_irq(irq);} static void handle_void_irq(int irq) { - int i; struct comedi_irq_struct *it; - for( i = 0; i < MAX_IRQ_SHARING; i++ ) + it = comedi_irqs[irq]; + if(it == NULL) { - it = comedi_irqs[ irq ][ i ]; - if( it == NULL ) continue; - it->handler( irq, it->dev_id, NULL ); + rt_printk("comedi: null irq struct?\n"); + return; } + it->handler(irq, it->dev_id, NULL); rt_enable_irq(irq); //needed by rtai-adeos, seems like it shouldn't hurt earlier versions } @@ -327,11 +250,10 @@ static V_FP_V handle_void_irq_ptrs[]={ handle_void_irq_22, handle_void_irq_23, }; -/* if you need more, fix it yourself... */ static int comedi_rt_get_irq(struct comedi_irq_struct *it) { - rt_request_global_irq(it->irq,handle_void_irq_ptrs[it->irq]); + rt_request_global_irq(it->irq, handle_void_irq_ptrs[it->irq]); rt_startup_irq(it->irq); return 0; @@ -383,21 +305,53 @@ void comedi_rt_cleanup(void) #endif +/* Fusion section */ +#ifdef CONFIG_COMEDI_FUSION + +static void fusion_handle_irq(unsigned int irq, void *cookie) +{ + struct comedi_irq_struct *it = cookie; + + it->handler(irq, it->dev_id, NULL); + rthal_irq_enable(irq); +} + +static int comedi_rt_get_irq(struct comedi_irq_struct *it) +{ + rthal_irq_request(it->irq, fusion_handle_irq, it); + rthal_irq_enable(it->irq); + return 0; +} + +static int comedi_rt_release_irq(struct comedi_irq_struct *it) +{ + rthal_irq_disable(it->irq); + rthal_irq_release(it->irq); + return 0; +} + +void comedi_rt_init(void) +{ + rt_pend_tq_init(); +} + +void comedi_rt_cleanup(void) +{ + rt_pend_tq_cleanup(); +} + +#endif /*CONFIG_COMEDI_FUSION*/ /* RTLinux section */ #ifdef CONFIG_COMEDI_RTL static unsigned int handle_rtl_irq(unsigned int irq,struct pt_regs *regs) { - int i; struct comedi_irq_struct *it; - for( i = 0; i < MAX_IRQ_SHARING; i++ ) - { - it = comedi_irqs[ irq ][ i ]; - if( it == NULL ) continue; - it->handler( irq, it->dev_id, regs ); - } + it = comedi_irqs[irq]; + if( it == NULL ) return 0; + it->handler( irq, it->dev_id, regs ); rtl_hard_enable_irq(irq); return 0; } diff --git a/comedi/rt_pend_tq.c b/comedi/rt_pend_tq.c index 9b9271a1..2681ef9d 100644 --- a/comedi/rt_pend_tq.c +++ b/comedi/rt_pend_tq.c @@ -8,6 +8,9 @@ #ifdef CONFIG_COMEDI_RTAI #include #endif +#ifdef CONFIG_COMEDI_FUSION +#include +#endif #ifdef CONFIG_COMEDI_RTL #include #endif @@ -51,6 +54,9 @@ int rt_pend_call(void (*func)(int arg1, void * arg2), int arg1, void * arg2) #ifdef CONFIG_COMEDI_RTAI rt_pend_linux_srq(rt_pend_tq_irq); #endif +#ifdef CONFIG_COMEDI_FUSION + rthal_apc_schedule(rt_pend_tq_irq); +#endif #ifdef CONFIG_COMEDI_RTL rtl_global_pend_irq(rt_pend_tq_irq); @@ -60,8 +66,9 @@ int rt_pend_call(void (*func)(int arg1, void * arg2), int arg1, void * arg2) #ifdef CONFIG_COMEDI_RTAI void rt_pend_irq_handler(void) -#endif -#ifdef CONFIG_COMEDI_RTL +#elif defined(CONFIG_COMEDI_FUSION) +void rt_pend_irq_handler(void * cookie) +#elif defined(CONFIG_COMEDI_RTL) void rt_pend_irq_handler(int irq, void *dev, struct pt_regs * regs) #endif { @@ -77,6 +84,9 @@ int rt_pend_tq_init(void) #ifdef CONFIG_COMEDI_RTAI rt_pend_tq_irq=rt_request_srq(0,rt_pend_irq_handler,NULL); #endif +#ifdef CONFIG_COMEDI_FUSION + rt_pend_tq_irq=rthal_apc_alloc("comedi APC" ,rt_pend_irq_handler, NULL); +#endif #ifdef CONFIG_COMEDI_RTL rt_pend_tq_irq=rtl_get_soft_irq(rt_pend_irq_handler,"rt_pend_irq"); #endif @@ -93,6 +103,9 @@ void rt_pend_tq_cleanup(void) #ifdef CONFIG_COMEDI_RTAI rt_free_srq(rt_pend_tq_irq); #endif +#ifdef CONFIG_COMEDI_FUSION + rthal_apc_free(rt_pend_tq_irq); +#endif #ifdef CONFIG_COMEDI_RTL free_irq(rt_pend_tq_irq,NULL); #endif diff --git a/include/linux/comedi_rt.h b/include/linux/comedi_rt.h index d0c0438f..f54699ed 100644 --- a/include/linux/comedi_rt.h +++ b/include/linux/comedi_rt.h @@ -51,6 +51,9 @@ //#endif #define rt_printk rtl_printf #endif +#ifdef CONFIG_COMEDI_FUSION +#define rt_printk(format, args...) printk(format , ## args ) +#endif /* CONFIG_COMEDI_FUSION */ #ifdef CONFIG_PRIORITY_IRQ #define rt_printk printk #endif @@ -100,6 +103,8 @@ static inline unsigned long __comedi_spin_lock_irqsave(spinlock_t *lock_ptr) #elif defined(CONFIG_COMEDI_RTL_V1) rtl_spin_lock_irqsave(lock_ptr, flags); +#elif defined(CONFIG_COMEDI_FUSION) + rthal_spin_lock_irqsave(lock_ptr, flags); #else spin_lock_irqsave(lock_ptr, flags); @@ -119,7 +124,8 @@ static inline void comedi_spin_unlock_irqrestore(spinlock_t *lock_ptr, unsigned #elif defined(CONFIG_COMEDI_RTL_V1) rtl_spin_unlock_irqrestore(lock_ptr, flags); - +#elif defined(CONFIG_COMEDI_FUSION) + rthal_spin_unlock_irqrestore(lock_ptr, flags); #else spin_unlock_irqrestore(lock_ptr, flags); diff --git a/m4/rtai.m4 b/m4/rtai.m4 index 17b4da89..0b23e21a 100644 --- a/m4/rtai.m4 +++ b/m4/rtai.m4 @@ -23,7 +23,14 @@ AC_DEFUN([DS_RTAI], fi $1 AC_MSG_RESULT([found]) - AC_DEFINE([CONFIG_COMEDI_RTAI],[true],[Define if kernel is RTAI patched]) + FUSION_TEST=`${RTAI_DIR}/bin/rtai-config --version | cut -d"-" -f2 ` + if test "${FUSION_TEST}" = "fusion" + then + AC_DEFINE([CONFIG_COMEDI_FUSION],[true],[Define if kernel is RTAI patched]) + else + AC_DEFINE([CONFIG_COMEDI_RTAI],[true],[Define if kernel is RTAI patched]) + fi + else $2 fi