* Contributors: Added Alexis Berlemont and Simone Mannori.
authorFrank Mori Hess <fmhess@speakeasy.net>
Wed, 15 Jun 2005 23:24:19 +0000 (23:24 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Wed, 15 Jun 2005 23:24:19 +0000 (23:24 +0000)
* 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.

ChangeLog
Contributors
Makefile.am
comedi/rt.c
comedi/rt_pend_tq.c
include/linux/comedi_rt.h
m4/rtai.m4

index dc4ebfd8633dde532e616d480140619dd91427f0..ae4be3f8c6f498d98e24be4b9b75021a7fe79492 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-06-15  Frank Hess <fmhess@users.sourceforge.net>
+
+       * 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  <fmhess@users.sourceforge.net>
 
        Patch from abbotti@mev.co.uk (Ian Abbott) to
index dd1c7a2350b39748dbaa23453f9620cd11cc3390..b290cf0f481d958f3ee18d1d3790e299293ac4e4 100644 (file)
@@ -3,6 +3,7 @@ Ian Abbott <abbotti@mev.co.uk>
 Dave Andruczyk <dave@tech.buffalostate.edu>
 Chris R. Baugher <baugher@enteract.com>
 Brent Baccala <baccala@freesoft.org>
+Alexis Berlemont <berlemont.hauw@free.fr>
 Anders Blomdell <anders.blomdell@control.lth.se>
 Eric Bunn <ebu@cs.hut.fi>
 Herman Bruyninckx
@@ -24,6 +25,7 @@ Markus Kempf <kempf@matsci.uni-sb.de>
 Harald Kirsch <kir@iitb.fhg.de>
 Jochen Küpper <jochen@pc1.uni-duesseldorf.de>
 Brent Ledvina <bml22@cornell.edu>
+Simone Mannori <smannori@f2n.it>
 Ivan Martinez <ivanmr@altavista.com>
 Luis Martínez <luimarma@marcosa.e.telefonica.net>
 J.P. Mellor <jpmellor@rose-hulman.edu>
index d32de637f4a7bb918601ec1f90871c898caf0222..716f671f1fc8a59d712075aba3ee47e5e7095264 100644 (file)
@@ -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
index 50721b4bbd695d7b45269eb6c12962dd546e86ad..c0aea1737d3f54707dcfe628ac3fa1b40d3754ad 100644 (file)
 
 #ifdef CONFIG_COMEDI_RTAI
 #include <rtai.h>
+#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 <nucleus/asm/hal.h>
 #endif
 
 #ifdef CONFIG_COMEDI_RTL
 #include <rtl_core.h>
 #include <rtl_sync.h>
-
-#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;
 }
index 9b9271a1fb82341fde79556b30214dc3163270f0..2681ef9d3c44d23fa69020715e9d5679b5d2cafe 100644 (file)
@@ -8,6 +8,9 @@
 #ifdef CONFIG_COMEDI_RTAI
 #include <rtai.h>
 #endif
+#ifdef CONFIG_COMEDI_FUSION
+#include <nucleus/asm/hal.h>
+#endif
 #ifdef CONFIG_COMEDI_RTL
 #include <rtl_core.h>
 #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
index d0c0438fad5ce3788546d444933b5a6a2a6a42d0..f54699edd97687cb30479da9d3ce131ee9ee3773 100644 (file)
@@ -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);
 
index 17b4da8961873e557194472c728ae638fca7b949..0b23e21a420ded6280db3d71022d2a2da791fe8f 100644 (file)
@@ -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