All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-core]  [Combo-PATCH] Shared interrupts (base, /proc support, edge-triggered stuff)
@ 2006-02-01 21:23 Dmitry Adamushko
  2006-02-02 10:51 ` Jan Kiszka
  0 siblings, 1 reply; 3+ messages in thread
From: Dmitry Adamushko @ 2006-02-01 21:23 UTC (permalink / raw)
  To: xenomai


[-- Attachment #1.1: Type: text/plain, Size: 860 bytes --]

Hi there,

as I promised, here go the following patches (ordered as they have to be
applied one by one) :


1) shirq-base.patch

Adds the "name" field to the interrupt object of the nucleus layer.
Reworks the related bits of the native skin (+ a few minor changes for
posix and rtdm) to support the named interrupt objects.


2) shirq-v7.patch

Generic support for shared interrupts.


3) shirq-proc.patch

/proc support.

Now /proc/xenomai/irq shows the names of handlers.

The related code have been removed from the hal layer to nucleus.


-----

4) shirq-isa.patch

Trying to handle the edge-triggered stuff.

This is a very preliminary version so the only thing I promise so far
is that it compiles successfully.


The functionality added by first 3 patches seem to be working.

--
Best regards,
Dmitry Adamushko

[-- Attachment #1.2: Type: text/html, Size: 1058 bytes --]

[-- Attachment #2: shirq-base.patch --]
[-- Type: application/octet-stream, Size: 10137 bytes --]

diff -urp xenomai-cvs/include/native/intr.h xenomai-intr-iface/include/native/intr.h
--- xenomai-cvs/include/native/intr.h	2005-11-01 23:37:45.000000000 +0100
+++ xenomai-intr-iface/include/native/intr.h	2006-02-01 16:10:28.000000000 +0100
@@ -71,8 +71,6 @@ typedef struct rt_intr {
 
     rt_handle_t handle;	/* !< Handle in registry -- zero if unregistered. */
 
-    char name[XNOBJECT_NAME_LEN]; /* !< Symbolic name. */
-
 #if defined(__KERNEL__) && defined(CONFIG_XENO_OPT_PERVASIVE)
 
     int mode;		/* !< Interrupt control mode. */
@@ -101,6 +99,7 @@ int __native_intr_pkg_init(void);
 void __native_intr_pkg_cleanup(void);
 
 int rt_intr_create(RT_INTR *intr,
+		   const char *name,
 		   unsigned irq,
 		   rt_isr_t isr,
 		   rt_iack_t iack);
@@ -122,7 +121,7 @@ extern "C" {
 #endif
 
 int rt_intr_bind(RT_INTR *intr,
-		 unsigned irq,
+		 const char *name,
 		 RTIME timeout);
 
 static inline int rt_intr_unbind (RT_INTR *intr)
@@ -133,6 +132,7 @@ static inline int rt_intr_unbind (RT_INT
 }
 
 int rt_intr_create(RT_INTR *intr,
+		   const char *name,
 		   unsigned irq,
 		   int mode);
 
diff -urp xenomai-cvs/include/nucleus/intr.h xenomai-intr-iface/include/nucleus/intr.h
--- xenomai-cvs/include/nucleus/intr.h	2005-11-01 23:37:45.000000000 +0100
+++ xenomai-intr-iface/include/nucleus/intr.h	2006-02-01 16:10:28.000000000 +0100
@@ -42,6 +42,8 @@ typedef struct xnintr {
 
     void *cookie;	/* !< User-defined cookie value. */
 
+    char name[XNOBJECT_NAME_LEN]; /* !< Symbolic name. */
+
 } xnintr_t;
 
 extern xnintr_t nkclock;
@@ -55,6 +57,7 @@ void xnintr_clock_handler(void);
     /* Public interface. */
 
 int xnintr_init(xnintr_t *intr,
+		const char *name,
 		unsigned irq,
 		xnisr_t isr,
 		xniack_t iack,
diff -urp xenomai-cvs/include/rtdm/rtdm_driver.h xenomai-intr-iface/include/rtdm/rtdm_driver.h
--- xenomai-cvs/include/rtdm/rtdm_driver.h	2006-01-03 19:53:37.000000000 +0100
+++ xenomai-intr-iface/include/rtdm/rtdm_driver.h	2006-02-01 16:10:28.000000000 +0100
@@ -743,7 +743,7 @@ static inline int rtdm_irq_request(rtdm_
                                    const char *device_name,
                                    void *arg)
 {
-    xnintr_init(irq_handle, irq_no, handler, NULL, flags);
+    xnintr_init(irq_handle, device_name, irq_no, handler, NULL, flags);
     return xnintr_attach(irq_handle, arg);
 }
 
diff -urp xenomai-cvs/ksrc/nucleus/intr.c xenomai-intr-iface/ksrc/nucleus/intr.c
--- xenomai-cvs/ksrc/nucleus/intr.c	2005-12-02 19:56:20.000000000 +0100
+++ xenomai-intr-iface/ksrc/nucleus/intr.c	2006-02-01 16:12:37.000000000 +0100
@@ -42,7 +42,7 @@ static void xnintr_irq_handler(unsigned 
 			       void *cookie);
 
 /*! 
- * \fn int xnintr_init (xnintr_t *intr,unsigned irq,xnisr_t isr,xniack_t iack,xnflags_t flags)
+ * \fn int xnintr_init (xnintr_t *intr,const char *name,unsigned irq,xnisr_t isr,xniack_t iack,xnflags_t flags)
  * \brief Initialize an interrupt object.
  *
  * Associates an interrupt object with an IRQ line.
@@ -82,6 +82,9 @@ static void xnintr_irq_handler(unsigned 
  * descriptor must always be valid while the object is active
  * therefore it must be allocated in permanent memory.
  *
+ * @param name An ASCII string standing for the symbolic name of the
+ * interrupt object.
+ *
  * @param irq The hardware interrupt channel associated with the
  * interrupt object. This value is architecture-dependent. An
  * interrupt object must then be attached to the hardware interrupt
@@ -120,6 +123,7 @@ static void xnintr_irq_handler(unsigned 
  */
 
 int xnintr_init (xnintr_t *intr,
+		 const char *name,
 		 unsigned irq,
 		 xnisr_t isr,
 		 xniack_t iack,
@@ -130,6 +134,7 @@ int xnintr_init (xnintr_t *intr,
     intr->iack = iack;
     intr->cookie = NULL;
     intr->hits = 0;
+    xnobject_copy_name(intr->name,name);
 
     return 0;
 }
diff -urp xenomai-cvs/ksrc/nucleus/pod.c xenomai-intr-iface/ksrc/nucleus/pod.c
--- xenomai-cvs/ksrc/nucleus/pod.c	2006-01-10 21:47:24.000000000 +0100
+++ xenomai-intr-iface/ksrc/nucleus/pod.c	2006-02-01 16:13:10.000000000 +0100
@@ -3042,7 +3042,7 @@ unlock_and_exit:
        attached directly by the arch-dependent layer
        (xnarch_start_timer). */
 
-    xnintr_init(&nkclock,0,tickhandler,NULL,0);
+    xnintr_init(&nkclock,NULL,0,tickhandler,NULL,0);
 
     __setbits(nkpod->status,XNTIMED);
 
diff -urp xenomai-cvs/ksrc/skins/native/intr.c xenomai-intr-iface/ksrc/skins/native/intr.c
--- xenomai-cvs/ksrc/skins/native/intr.c	2005-11-29 15:15:54.000000000 +0100
+++ xenomai-intr-iface/ksrc/skins/native/intr.c	2006-02-01 16:10:29.000000000 +0100
@@ -119,7 +119,7 @@ static RT_OBJECT_PROCNODE __intr_pnode =
 #endif /* CONFIG_XENO_NATIVE_EXPORT_REGISTRY */
 
 /*! 
- * \fn int rt_intr_create (RT_INTR *intr,unsigned irq,rt_isr_t isr,rt_iack_t iack)
+ * \fn int rt_intr_create (RT_INTR *intr,const char *name,unsigned irq,rt_isr_t isr,rt_iack_t iack)
  * \brief Create an interrupt object from kernel space.
  *
  * Initializes and associates an interrupt object with an IRQ line. In
@@ -155,6 +155,11 @@ static RT_OBJECT_PROCNODE __intr_pnode =
  * be valid while the object is active therefore it must be allocated
  * in permanent memory.
  *
+ * @param name An ASCII string standing for the symbolic name of the
+ * interrupt object. When non-NULL and non-empty, this string is copied
+ * to a safe place into the descriptor, and passed to the registry package
+ * if enabled for indexing the created interrupt objects.
+ *
  * @param irq The hardware interrupt channel associated with the
  * interrupt object. This value is architecture-dependent.
  *
@@ -205,6 +210,7 @@ static RT_OBJECT_PROCNODE __intr_pnode =
  */
 
 int rt_intr_create (RT_INTR *intr,
+		    const char *name,
 		    unsigned irq,
 		    rt_isr_t isr,
 		    rt_iack_t iack)
@@ -215,7 +221,7 @@ int rt_intr_create (RT_INTR *intr,
     if (xnpod_asynch_p())
 	return -EPERM;
 
-    xnintr_init(&intr->intr_base,irq,isr,iack,0);
+    xnintr_init(&intr->intr_base,name,irq,isr,iack,0);
 #if defined(__KERNEL__) && defined(CONFIG_XENO_OPT_PERVASIVE)
     xnsynch_init(&intr->synch_base,XNSYNCH_PRIO);
     intr->pending = 0;
@@ -228,7 +234,6 @@ int rt_intr_create (RT_INTR *intr,
     xnlock_get_irqsave(&nklock,s);
     appendq(&__xeno_intr_q,&intr->link);
     xnlock_put_irqrestore(&nklock,s);
-    snprintf(intr->name,sizeof(intr->name),"irq%u",irq);
 
     err = xnintr_attach(&intr->intr_base,intr);
 
@@ -238,7 +243,7 @@ int rt_intr_create (RT_INTR *intr,
        half-baked objects... */
 
     if (!err)
-	err = rt_registry_enter(intr->name,intr,&intr->handle,&__intr_pnode);
+	err = rt_registry_enter(intr->intr_base.name,intr,&intr->handle,&__intr_pnode);
 #endif /* CONFIG_XENO_OPT_NATIVE_REGISTRY */
 
     if (err)
@@ -492,7 +497,7 @@ int rt_intr_inquire (RT_INTR *intr,
         goto unlock_and_exit;
         }
     
-    strcpy(info->name,intr->name);
+    strcpy(info->name,intr->intr_base.name);
     info->hits = intr->intr_base.hits;
     info->irq = intr->intr_base.irq;
 
diff -urp xenomai-cvs/ksrc/skins/native/syscall.c xenomai-intr-iface/ksrc/skins/native/syscall.c
--- xenomai-cvs/ksrc/skins/native/syscall.c	2005-12-30 11:44:10.000000000 +0100
+++ xenomai-intr-iface/ksrc/skins/native/syscall.c	2006-02-01 16:10:29.000000000 +0100
@@ -2894,6 +2894,7 @@ EXPORT_SYMBOL(rt_intr_handler);
 
 /*
  * int __rt_intr_create(RT_INTR_PLACEHOLDER *ph,
+ *			const char *name,
  *                      unsigned irq,
  *                      int mode)
  */
@@ -2901,6 +2902,7 @@ EXPORT_SYMBOL(rt_intr_handler);
 static int __rt_intr_create (struct task_struct *curr, struct pt_regs *regs)
 
 {
+    char name[XNOBJECT_NAME_LEN];
     RT_INTR_PLACEHOLDER ph;
     int err, mode;
     RT_INTR *intr;
@@ -2909,11 +2911,22 @@ static int __rt_intr_create (struct task
     if (!__xn_access_ok(curr,VERIFY_WRITE,__xn_reg_arg1(regs),sizeof(ph)))
 	return -EFAULT;
 
+    if (__xn_reg_arg2(regs))
+	{
+	if (!__xn_access_ok(curr,VERIFY_READ,__xn_reg_arg2(regs),sizeof(name)))
+	    return -EFAULT;
+
+	__xn_strncpy_from_user(curr,name,(const char __user *)__xn_reg_arg2(regs),sizeof(name) - 1);
+	name[sizeof(name) - 1] = '\0';
+	}
+    else
+	*name = '\0';
+
     /* Interrupt line number. */
-    irq = (unsigned)__xn_reg_arg2(regs);
+    irq = (unsigned)__xn_reg_arg3(regs);
 
     /* Interrupt control mode. */
-    mode = (int)__xn_reg_arg3(regs);
+    mode = (int)__xn_reg_arg4(regs);
 
     if (mode & ~(I_AUTOENA|I_PROPAGATE))
 	return -EINVAL;
@@ -2923,7 +2936,7 @@ static int __rt_intr_create (struct task
     if (!intr)
 	return -ENOMEM;
 
-    err = rt_intr_create(intr,irq,&rt_intr_handler,NULL);
+    err = rt_intr_create(intr,name,irq,&rt_intr_handler,NULL);
 
     if (err == 0)
 	{
diff -urp xenomai-cvs/ksrc/skins/posix/intr.c xenomai-intr-iface/ksrc/skins/posix/intr.c
--- xenomai-cvs/ksrc/skins/posix/intr.c	2006-01-03 21:41:36.000000000 +0100
+++ xenomai-intr-iface/ksrc/skins/posix/intr.c	2006-02-01 16:10:29.000000000 +0100
@@ -27,7 +27,7 @@ int pse51_intr_attach (struct pse51_inte
     int err;
     spl_t s;
 
-    xnintr_init(&intr->intr_base,irq,isr,iack,0);
+    xnintr_init(&intr->intr_base,NULL,irq,isr,iack,0);
 
 #if defined(__KERNEL__) && defined(CONFIG_XENO_OPT_PERVASIVE)
     xnsynch_init(&intr->synch_base,XNSYNCH_PRIO);
diff -urp xenomai-cvs/src/skins/native/intr.c xenomai-intr-iface/src/skins/native/intr.c
--- xenomai-cvs/src/skins/native/intr.c	2005-11-01 23:37:45.000000000 +0100
+++ xenomai-intr-iface/src/skins/native/intr.c	2006-02-01 16:10:29.000000000 +0100
@@ -24,24 +24,22 @@
 extern int __native_muxid;
 
 int rt_intr_create (RT_INTR *intr,
+		    const char *name,
 		    unsigned irq,
 		    int mode)
 {
-    return XENOMAI_SKINCALL3(__native_muxid,
+    return XENOMAI_SKINCALL4(__native_muxid,
 			     __native_intr_create,
 			     intr,
+			     name,
 			     irq,
 			     mode);
 }
 
 int rt_intr_bind (RT_INTR *intr,
-		  unsigned irq,
+		  const char *name,
 		  RTIME timeout)
 {
-    char name[XNOBJECT_NAME_LEN];
-
-    snprintf(name,sizeof(name),"irq%u",irq);
-
     return XENOMAI_SKINCALL3(__native_muxid,
 			     __native_intr_bind,
 			     intr,

[-- Attachment #3: shirq-v7.patch --]
[-- Type: application/octet-stream, Size: 13122 bytes --]

diff -urp xenomai-intr-iface/include/asm-generic/hal.h xenomai-shirq-7/include/asm-generic/hal.h
--- xenomai-intr-iface/include/asm-generic/hal.h	2006-01-13 15:10:23.000000000 +0100
+++ xenomai-shirq-7/include/asm-generic/hal.h	2006-02-01 16:16:47.000000000 +0100
@@ -62,6 +62,7 @@
 #define RTHAL_NR_CPUS		IPIPE_NR_CPUS
 #define RTHAL_ROOT_PRIO		IPIPE_ROOT_PRIO
 #define RTHAL_NR_FAULTS		IPIPE_NR_FAULTS
+#define RTHAL_NR_IRQS		IPIPE_NR_IRQS
 
 #define RTHAL_SERVICE_IPI0	IPIPE_SERVICE_IPI0
 #define RTHAL_SERVICE_VECTOR0	IPIPE_SERVICE_VECTOR0
diff -urp xenomai-intr-iface/include/asm-generic/system.h xenomai-shirq-7/include/asm-generic/system.h
--- xenomai-intr-iface/include/asm-generic/system.h	2006-01-03 19:53:37.000000000 +0100
+++ xenomai-shirq-7/include/asm-generic/system.h	2006-02-01 16:16:47.000000000 +0100
@@ -101,6 +101,8 @@ typedef struct { volatile unsigned long 
 
 #define XNARCH_NR_CPUS               RTHAL_NR_CPUS
 
+#define XNARCH_TIMER_IRQ	     RTHAL_TIMER_IRQ
+
 #define XNARCH_ROOT_STACKSZ   0	/* Only a placeholder -- no stack */
 
 #define XNARCH_PROMPT "Xenomai: "
@@ -470,6 +472,16 @@ static inline unsigned long long xnarch_
 
 #ifdef XENO_INTR_MODULE
 
+#define XNARCH_NR_IRQS		     RTHAL_NR_IRQS
+
+static inline unsigned long xnarch_critical_enter(void (*synch)(void)) {
+    return rthal_critical_enter(synch);
+}
+
+static inline void xnarch_critical_exit(unsigned long flags) {
+    return rthal_critical_exit(flags);
+}
+
 static inline int xnarch_hook_irq (unsigned irq,
 				   rthal_irq_handler_t handler,
 				   rthal_irq_ackfn_t ackfn,
diff -urp xenomai-intr-iface/include/asm-i386/hal.h xenomai-shirq-7/include/asm-i386/hal.h
--- xenomai-intr-iface/include/asm-i386/hal.h	2006-01-04 11:32:29.000000000 +0100
+++ xenomai-shirq-7/include/asm-i386/hal.h	2006-02-01 16:16:47.000000000 +0100
@@ -191,6 +191,9 @@ static inline __attribute_const__ unsign
 #define RTHAL_APIC_TIMER_VECTOR    RTHAL_SERVICE_VECTOR3
 #define RTHAL_APIC_TIMER_IPI       RTHAL_SERVICE_IPI3
 #define RTHAL_APIC_ICOUNT          ((RTHAL_TIMER_FREQ + HZ/2)/HZ)
+#define RTHAL_TIMER_IRQ 	   RTHAL_APIC_TIMER_IPI
+#else  /* !CONFIG_X86_LOCAL_APIC */
+#define RTHAL_TIMER_IRQ		   RTHAL_8254_IRQ
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #define RTHAL_NMICLK_FREQ	RTHAL_CPU_FREQ
diff -urp xenomai-intr-iface/include/asm-sim/system.h xenomai-shirq-7/include/asm-sim/system.h
--- xenomai-intr-iface/include/asm-sim/system.h	2006-01-03 19:53:37.000000000 +0100
+++ xenomai-shirq-7/include/asm-sim/system.h	2006-02-01 16:16:47.000000000 +0100
@@ -75,6 +75,9 @@ typedef unsigned long xnlock_t;
 
 #define XNARCH_NR_CPUS              1
 
+/* Should be equal to the value used for creating the mvmtimer object (mvm_start_timer). */
+#define XNARCH_TIMER_IRQ	    1
+
 #define XNARCH_DEFAULT_TICK         10000000 /* ns, i.e. 10ms */
 #define XNARCH_HOST_TICK            0 /* No host ticking service. */
 
@@ -365,6 +368,16 @@ void mvm_tcl_build_pendq(mvm_tcl_listobj
 typedef void (*rthal_irq_handler_t)(unsigned, void *);
 typedef int (*rthal_irq_ackfn_t)(unsigned);
 
+#define XNARCH_NR_IRQS		     MVM_IRQ_LEVELS
+
+static inline unsigned long xnarch_critical_enter(void (*synch)(void)) {
+    return 0;
+}
+
+static inline void xnarch_critical_exit(unsigned long flags) {
+    return;
+}
+
 static inline int xnarch_hook_irq (unsigned irq,
 				   rthal_irq_handler_t handler,
 				   rthal_irq_ackfn_t ackfn, /* Ignored. */
diff -urp xenomai-intr-iface/include/asm-uvm/system.h xenomai-shirq-7/include/asm-uvm/system.h
--- xenomai-intr-iface/include/asm-uvm/system.h	2006-01-08 15:35:54.000000000 +0100
+++ xenomai-shirq-7/include/asm-uvm/system.h	2006-02-01 16:16:47.000000000 +0100
@@ -74,6 +74,8 @@ typedef unsigned long xnlock_t;
 
 #define XNARCH_NR_CPUS             1
 
+#define XNARCH_TIMER_IRQ	   0
+
 #define XNARCH_DEFAULT_TICK        1000000 /* ns, i.e. 1ms */
 #define XNARCH_SIG_RESTART         SIGUSR1
 #define XNARCH_HOST_TICK           0	/* No host ticking service */
@@ -270,6 +272,16 @@ void xnarch_sync_irq (void) /* Synchroni
 typedef void (*rthal_irq_handler_t)(unsigned, void *);
 typedef int (*rthal_irq_ackfn_t)(unsigned);
 
+#define XNARCH_NR_IRQS		     0
+
+static inline unsigned long xnarch_critical_enter(void (*synch)(void)) {
+    return 0;
+}
+
+static inline void xnarch_critical_exit(unsigned long flags) {
+    return;
+}
+
 static inline int xnarch_hook_irq (unsigned irq,
 				   rthal_irq_handler_t handler,
 				   rthal_irq_ackfn_t ackfn,
diff -urp xenomai-intr-iface/include/nucleus/intr.h xenomai-shirq-7/include/nucleus/intr.h
--- xenomai-intr-iface/include/nucleus/intr.h	2006-02-01 16:10:28.000000000 +0100
+++ xenomai-shirq-7/include/nucleus/intr.h	2006-02-01 16:16:47.000000000 +0100
@@ -26,21 +26,31 @@
 #define XN_ISR_CHAINED   0x1
 #define XN_ISR_ENABLE    0x2
 
+/* Creation flags. */
+#define XN_ISR_SHARED	 0x1
+
+/* Operational flags. */
+#define XN_ISR_ATTACHED	 0x100
+
 #if defined(__KERNEL__) || defined(__XENO_UVM__) || defined(__XENO_SIM__)
 
 struct xnintr;
 
 typedef struct xnintr {
 
-    unsigned irq;	/* !< IRQ number. */
+    struct xnintr *next;
 
     xnisr_t isr;	/* !< Interrupt service routine. */
 
-    xniack_t iack;	/* !< Interrupt acknowledge routine. */
+    void *cookie;	/* !< User-defined cookie value. */
 
     unsigned long hits;	/* !< Number of receipts (since attachment). */
 
-    void *cookie;	/* !< User-defined cookie value. */
+    xnflags_t flags; 	/* !< Creation flags. */
+
+    unsigned irq;	/* !< IRQ number. */
+
+    xniack_t iack;	/* !< Interrupt acknowledge routine. */
 
     char name[XNOBJECT_NAME_LEN]; /* !< Symbolic name. */
 
@@ -52,6 +62,8 @@ extern xnintr_t nkclock;
 extern "C" {
 #endif
 
+int xnintr_mount(void);
+
 void xnintr_clock_handler(void);
 
     /* Public interface. */
diff -urp xenomai-intr-iface/ksrc/nucleus/intr.c xenomai-shirq-7/ksrc/nucleus/intr.c
--- xenomai-intr-iface/ksrc/nucleus/intr.c	2006-02-01 16:12:37.000000000 +0100
+++ xenomai-shirq-7/ksrc/nucleus/intr.c	2006-02-01 18:30:14.000000000 +0100
@@ -41,6 +41,57 @@ xnintr_t nkclock;
 static void xnintr_irq_handler(unsigned irq,
 			       void *cookie);
 
+typedef struct xnintr_shirq {
+
+    xnintr_t *handlers;
+    
+#ifdef CONFIG_SMP
+    atomic_counter_t active;
+#endif /* CONFIG_SMP */
+
+} xnintr_shirq_t;
+
+static xnintr_shirq_t xnshirqs[XNARCH_NR_IRQS];
+
+#ifdef CONFIG_SMP
+
+static inline void xnintr_shirq_lock(xnintr_shirq_t *shirq)
+{
+    xnarch_atomic_inc(&shirq->active);
+}
+
+static inline void xnintr_shirq_unlock(xnintr_shirq_t *shirq)
+{
+    xnarch_atomic_dec(&shirq->active);
+}
+
+static inline void xnintr_shirq_spin(xnintr_shirq_t *shirq)
+{
+    while (xnarch_atomic_get(&shirq->active))
+	cpu_relax();
+}
+
+#else /* !CONFIG_SMP */
+
+static inline void xnintr_shirq_lock(xnintr_shirq_t *shirq) {}
+static inline void xnintr_shirq_unlock(xnintr_shirq_t *shirq) {}
+static inline void xnintr_shirq_spin(xnintr_shirq_t *shirq) {}
+
+#endif /* CONFIG_SMP */
+
+int xnintr_mount(void)
+{
+    int i;
+    for (i = 0; i < XNARCH_NR_IRQS; ++i)
+	{
+	xnshirqs[i].handlers = NULL;
+#ifdef CONFIG_SMP
+	atomic_set(&xnshirqs[i].active,0);
+#endif /* CONFIG_SMP */
+	}
+    return 0;
+}
+
 /*! 
  * \fn int xnintr_init (xnintr_t *intr,const char *name,unsigned irq,xnisr_t isr,xniack_t iack,xnflags_t flags)
  * \brief Initialize an interrupt object.
@@ -134,6 +185,8 @@ int xnintr_init (xnintr_t *intr,
     intr->iack = iack;
     intr->cookie = NULL;
     intr->hits = 0;
+    intr->flags = flags;
+    intr->next = NULL;
     xnobject_copy_name(intr->name,name);
 
     return 0;
@@ -169,7 +222,8 @@ int xnintr_init (xnintr_t *intr,
 int xnintr_destroy (xnintr_t *intr)
 
 {
-    return xnintr_detach(intr);
+    xnintr_detach(intr);
+    return 0;
 }
 
 /*! 
@@ -186,8 +240,7 @@ int xnintr_destroy (xnintr_t *intr)
  *
  * @param cookie A user-defined opaque value which is stored into the
  * interrupt object descriptor for further retrieval by the ISR/ISR
- * handlers.
- *
+ * handlers. *
  * @return 0 is returned on success. Otherwise, -EINVAL is returned if
  * a low-level error occurred while attaching the interrupt. -EBUSY is
  * specifically returned if the interrupt object was already attached.
@@ -209,9 +262,62 @@ int xnintr_destroy (xnintr_t *intr)
 int xnintr_attach (xnintr_t *intr,
 		   void *cookie)
 {
+    xnintr_shirq_t *shirq;
+    xnintr_t *prev, **p;
+    unsigned long flags;
+    int err = 0;
+
+    if (intr->irq >= XNARCH_NR_IRQS)
+	return -EINVAL;
+
     intr->hits = 0;
+    intr->next = NULL;
     intr->cookie = cookie;
-    return xnarch_hook_irq(intr->irq,&xnintr_irq_handler,intr->iack,intr);
+    shirq = &xnshirqs[intr->irq];
+
+    flags = xnarch_critical_enter(NULL);
+
+    if (__testbits(intr->flags,XN_ISR_ATTACHED))
+	{
+	err = -EPERM;
+	goto unlock_and_exit;
+	}
+
+    p = &shirq->handlers;
+
+    if ((prev = *p) != NULL)
+	{
+	/* Check on whether the shared mode is allowed. */
+	if (!(prev->flags & intr->flags & XN_ISR_SHARED) || (prev->iack != intr->iack))
+	    {
+	    err = -EBUSY;
+	    goto unlock_and_exit;
+	    }
+
+	/* Get a position at the end of the list to insert the new element. */
+	while (prev)
+	    {
+	    p = &prev->next;
+	    prev = *p;
+	    }
+	}
+    else
+	{
+	/* Initialize the corresponding interrupt channel */
+	err = xnarch_hook_irq(intr->irq,&xnintr_irq_handler,intr->iack,NULL);
+	if (err)
+	    goto unlock_and_exit;
+	}
+
+    __setbits(intr->flags,XN_ISR_ATTACHED);
+
+    /* Add a given interrupt object. */
+    *p = intr;
+
+unlock_and_exit:
+
+    xnarch_critical_exit(flags);
+    return err;
 }
 
 /*! 
@@ -246,7 +352,52 @@ int xnintr_attach (xnintr_t *intr,
 int xnintr_detach (xnintr_t *intr)
 
 {
-    return xnarch_release_irq(intr->irq);
+    xnintr_shirq_t *shirq;
+    unsigned long flags;
+    xnintr_t *e, **p;
+    int err = 0;
+
+    if (intr->irq >= XNARCH_NR_IRQS)
+	return -EINVAL;
+
+    shirq = &xnshirqs[intr->irq];
+
+    flags = xnarch_critical_enter(NULL);
+
+    if (!__testbits(intr->flags,XN_ISR_ATTACHED))
+	{
+	xnarch_critical_exit(flags);
+	return -EPERM;
+	}
+
+    __clrbits(intr->flags,XN_ISR_ATTACHED);
+
+    p = &shirq->handlers;
+
+    while ((e = *p) != NULL)
+	{
+	if (e == intr)
+	    {
+	    /* Remove a given interrupt object from the list. */
+	    if ((*p = e->next) == NULL)
+		err = xnarch_release_irq(intr->irq);
+    
+	    xnarch_critical_exit(flags);
+
+	    /* The idea here is to keep a detached interrupt object valid as long
+	       as the corresponding irq handler is running. This is one of the requirements
+	       to iterate over the xnintr_shirq_t::handlers list in xnintr_irq_handler()
+	       in a lockless way. */
+	    xnintr_shirq_spin(shirq);
+	    return err;
+	    }
+	p = &e->next;
+	}
+
+    xnarch_critical_exit(flags);
+
+    xnlogerr("Attempted to detach a non previously attached interrupt object");
+    return err;
 }
 
 /*! 
@@ -355,17 +506,41 @@ static void xnintr_irq_handler (unsigned
 
 {
     xnsched_t *sched = xnpod_current_sched();
-    xnintr_t *intr = (xnintr_t *)cookie;
-    int s;
+    xnintr_shirq_t *shirq;
+    xnintr_t *intr;
+    int s = 0;
 
     xnarch_memory_barrier();
 
     xnltt_log_event(xeno_ev_ienter,irq);
 
     ++sched->inesting;
-    s = intr->isr(intr);
+
+    if (irq == XNARCH_TIMER_IRQ)
+	{
+	intr = (xnintr_t*)cookie;
+	s = intr->isr(intr);
+	++intr->hits;
+	}
+    else
+	{
+	shirq = &xnshirqs[irq];
+
+	xnintr_shirq_lock(shirq);
+	intr = shirq->handlers;
+
+	while (intr)
+	    {
+	    s |= intr->isr(intr);
+	    ++intr->hits;
+
+	    intr = intr->next;
+	    }
+
+	xnintr_shirq_unlock(shirq);
+	}
+
     --sched->inesting;
-    ++intr->hits;
 
     if (s & XN_ISR_ENABLE)
 	xnarch_enable_irq(irq);
@@ -389,6 +564,7 @@ static void xnintr_irq_handler (unsigned
     xnltt_log_event(xeno_ev_iexit,irq);
 }
 
+
 /*@}*/
 
 EXPORT_SYMBOL(xnintr_attach);
diff -urp xenomai-intr-iface/ksrc/nucleus/module.c xenomai-shirq-7/ksrc/nucleus/module.c
--- xenomai-intr-iface/ksrc/nucleus/module.c	2005-11-30 10:36:33.000000000 +0100
+++ xenomai-shirq-7/ksrc/nucleus/module.c	2006-02-01 16:16:47.000000000 +0100
@@ -713,6 +713,8 @@ int __init __xeno_sys_init (void)
     xnpod_init_proc();
 #endif /* CONFIG_PROC_FS */
 
+    xnintr_mount();
+
 #ifdef CONFIG_LTT
     xnltt_mount();
 #endif /* CONFIG_LTT */
diff -urp xenomai-intr-iface/ksrc/nucleus/pod.c xenomai-shirq-7/ksrc/nucleus/pod.c
--- xenomai-intr-iface/ksrc/nucleus/pod.c	2006-02-01 16:13:10.000000000 +0100
+++ xenomai-shirq-7/ksrc/nucleus/pod.c	2006-02-01 16:19:45.000000000 +0100
@@ -3038,11 +3038,10 @@ unlock_and_exit:
 
     /* The clock interrupt does not need to be attached since the
        timer service will handle the arch-dependent setup. The IRQ
-       number (arg #2) is not used since the IRQ source will be
-       attached directly by the arch-dependent layer
+       source will be attached directly by the arch-dependent layer
        (xnarch_start_timer). */
 
-    xnintr_init(&nkclock,NULL,0,tickhandler,NULL,0);
+    xnintr_init(&nkclock,NULL,XNARCH_TIMER_IRQ,tickhandler,NULL,0);
 
     __setbits(nkpod->status,XNTIMED);
 

[-- Attachment #4: shirq-proc.patch --]
[-- Type: application/octet-stream, Size: 5116 bytes --]

diff -urp xenomai-shirq-7/include/nucleus/intr.h xenomai-shirq-7-proc/include/nucleus/intr.h
--- xenomai-shirq-7/include/nucleus/intr.h	2006-02-01 16:16:47.000000000 +0100
+++ xenomai-shirq-7-proc/include/nucleus/intr.h	2006-02-01 16:21:18.000000000 +0100
@@ -66,6 +66,8 @@ int xnintr_mount(void);
 
 void xnintr_clock_handler(void);
 
+int xnintr_irq_proc(unsigned int irq, char *str);
+
     /* Public interface. */
 
 int xnintr_init(xnintr_t *intr,
diff -urp xenomai-shirq-7/ksrc/arch/generic/hal.c xenomai-shirq-7-proc/ksrc/arch/generic/hal.c
--- xenomai-shirq-7/ksrc/arch/generic/hal.c	2006-01-10 18:44:02.000000000 +0100
+++ xenomai-shirq-7-proc/ksrc/arch/generic/hal.c	2006-02-01 16:21:18.000000000 +0100
@@ -697,45 +697,6 @@ static int hal_read_proc (char *page,
     return len;
 }
 
-static int irq_read_proc (char *page,
-			  char **start,
-			  off_t off,
-			  int count,
-			  int *eof,
-			  void *data)
-{
-    int len = 0, cpu, irq;
-    char *p = page;
-
-    p += sprintf(p,"IRQ ");
-
-    for_each_online_cpu(cpu) {
-	p += sprintf(p,"        CPU%d",cpu);
-    }
-
-    for (irq = 0; irq < IPIPE_NR_IRQS; irq++) {
-
-	if (rthal_irq_handler(&rthal_domain, irq) == NULL)
-	    continue;
-
-	p += sprintf(p,"\n%3d:",irq);
-
-	for_each_online_cpu(cpu) {
-	    p += sprintf(p,"%12lu",rthal_cpudata_irq_hits(&rthal_domain,cpu,irq));
-	}
-    }
-
-    p += sprintf(p,"\n");
-
-    len = p - page - off;
-    if (len <= off + count) *eof = 1;
-    *start = page + off;
-    if (len > count) len = count;
-    if (len < 0) len = 0;
-
-    return len;
-}
-
 static int faults_read_proc (char *page,
 			     char **start,
 			     off_t off,
@@ -862,12 +823,6 @@ static int rthal_proc_register (void)
 		  NULL,
 		  rthal_proc_root);
 
-    __rthal_add_proc_leaf("irq",
-		  &irq_read_proc,
-		  NULL,
-		  NULL,
-		  rthal_proc_root);
-
     __rthal_add_proc_leaf("faults",
 		  &faults_read_proc,
 		  NULL,
@@ -890,7 +845,6 @@ static void rthal_proc_unregister (void)
 {
     rthal_nmi_proc_unregister();
     remove_proc_entry("hal",rthal_proc_root);
-    remove_proc_entry("irq",rthal_proc_root);
     remove_proc_entry("faults",rthal_proc_root);
     remove_proc_entry("apc",rthal_proc_root);
     remove_proc_entry("xenomai",NULL);
diff -urp xenomai-shirq-7/ksrc/nucleus/intr.c xenomai-shirq-7-proc/ksrc/nucleus/intr.c
--- xenomai-shirq-7/ksrc/nucleus/intr.c	2006-02-01 18:30:14.000000000 +0100
+++ xenomai-shirq-7-proc/ksrc/nucleus/intr.c	2006-02-01 18:32:23.000000000 +0100
@@ -536,7 +536,6 @@ static void xnintr_irq_handler (unsigned
 
 	    intr = intr->next;
 	    }
-
 	xnintr_shirq_unlock(shirq);
 	}
 
@@ -564,6 +563,35 @@ static void xnintr_irq_handler (unsigned
     xnltt_log_event(xeno_ev_iexit,irq);
 }
 
+int xnintr_irq_proc(unsigned int irq, char *str)
+{
+    xnintr_shirq_t *shirq;
+    xnintr_t *intr;
+    char *p = str;
+
+    shirq = &xnshirqs[irq];
+
+    xnintr_shirq_lock(shirq);
+    intr = shirq->handlers;
+
+    if (intr)
+	p += sprintf(p, "        ");
+
+    while (intr)
+	{
+	if (*(intr->name))
+	    p += sprintf(p, " %s,", intr->name);
+
+	intr = intr->next;
+	}
+
+    xnintr_shirq_unlock(shirq);
+
+    if (p != str)
+	--p;
+
+    return p - str;
+}
 
 /*@}*/
 
diff -urp xenomai-shirq-7/ksrc/nucleus/module.c xenomai-shirq-7-proc/ksrc/nucleus/module.c
--- xenomai-shirq-7/ksrc/nucleus/module.c	2006-02-01 16:16:47.000000000 +0100
+++ xenomai-shirq-7-proc/ksrc/nucleus/module.c	2006-02-01 17:06:36.000000000 +0100
@@ -526,6 +526,48 @@ static int timer_read_proc (char *page,
     return len;
 }
 
+static int irq_read_proc (char *page,
+			  char **start,
+			  off_t off,
+			  int count,
+			  int *eof,
+			  void *data)
+{
+    int len = 0, cpu, irq;
+    char *p = page;
+
+    p += sprintf(p,"IRQ ");
+
+    for_each_online_cpu(cpu) {
+	p += sprintf(p,"        CPU%d",cpu);
+    }
+
+    for (irq = 0; irq < RTHAL_NR_IRQS; irq++) {
+
+	if (rthal_irq_handler(&rthal_domain, irq) == NULL)
+	    continue;
+
+	p += sprintf(p,"\n%3d:",irq);
+
+	for_each_online_cpu(cpu) {
+	    p += sprintf(p,"%12lu",rthal_cpudata_irq_hits(&rthal_domain,cpu,irq));
+	}
+
+	p += xnintr_irq_proc(irq, p); 
+    }
+
+    p += sprintf(p,"\n");
+
+    len = p - page - off;
+    if (len <= off + count) *eof = 1;
+    *start = page + off;
+    if (len > count) len = count;
+    if (len < 0) len = 0;
+
+    return len;
+}
+
+
 static struct proc_dir_entry *add_proc_leaf (const char *name,
 					     read_proc_t rdproc,
 					     write_proc_t wrproc,
@@ -614,6 +656,12 @@ void xnpod_init_proc (void)
 		  NULL,
 		  rthal_proc_root);
 
+    add_proc_leaf("irq",
+		  &irq_read_proc,
+		  NULL,
+		  NULL,
+		  rthal_proc_root);
+
 #ifdef CONFIG_XENO_OPT_PERVASIVE
     iface_proc_root = create_proc_entry("interfaces",
 					S_IFDIR,
@@ -633,6 +681,7 @@ void xnpod_delete_proc (void)
 
     remove_proc_entry("interfaces",rthal_proc_root);
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
+    remove_proc_entry("irq",rthal_proc_root);
     remove_proc_entry("timer",rthal_proc_root);
     remove_proc_entry("version",rthal_proc_root);
     remove_proc_entry("latency",rthal_proc_root);

[-- Attachment #5: shirq-isa.patch --]
[-- Type: application/octet-stream, Size: 3320 bytes --]

diff -urp xenomai/include/nucleus/intr.h xenomai-isa/include/nucleus/intr.h
--- xenomai/include/nucleus/intr.h	2006-02-01 16:23:35.000000000 +0100
+++ xenomai-isa/include/nucleus/intr.h	2006-02-01 22:29:47.000000000 +0100
@@ -25,9 +25,11 @@
 #define XN_ISR_HANDLED   0x0
 #define XN_ISR_CHAINED   0x1
 #define XN_ISR_ENABLE    0x2
+#define XN_ISR_NOINT	 0x4
 
 /* Creation flags. */
 #define XN_ISR_SHARED	 0x1
+#define XN_ISR_ISA	 0x2
 
 /* Operational flags. */
 #define XN_ISR_ATTACHED	 0x100
diff -urp xenomai/ksrc/nucleus/intr.c xenomai-isa/ksrc/nucleus/intr.c
--- xenomai/ksrc/nucleus/intr.c	2006-02-01 18:04:30.000000000 +0100
+++ xenomai-isa/ksrc/nucleus/intr.c	2006-02-01 22:32:24.000000000 +0100
@@ -41,6 +41,9 @@ xnintr_t nkclock;
 static void xnintr_irq_handler(unsigned irq,
 			       void *cookie);
 
+static void xnintr_isairq_handler(unsigned irq,
+			       void *cookie);
+
 typedef struct xnintr_shirq {
 
     xnintr_t *handlers;
@@ -288,7 +291,8 @@ int xnintr_attach (xnintr_t *intr,
     if ((prev = *p) != NULL)
 	{
 	/* Check on whether the shared mode is allowed. */
-	if (!(prev->flags & intr->flags & XN_ISR_SHARED) || (prev->iack != intr->iack))
+	if (!(prev->flags & intr->flags & XN_ISR_SHARED) || (prev->iack != intr->iack)
+	    || ((prev->flags & XN_ISR_ISA) != (intr->flags & XN_ISR_ISA)))
 	    {
 	    err = -EBUSY;
 	    goto unlock_and_exit;
@@ -304,7 +308,12 @@ int xnintr_attach (xnintr_t *intr,
     else
 	{
 	/* Initialize the corresponding interrupt channel */
-	err = xnarch_hook_irq(intr->irq,&xnintr_irq_handler,intr->iack,NULL);
+	void (*handler)(unsigned, void *) = &xnintr_irq_handler;
+
+	if (intr->flags & XN_ISR_ISA)
+	    handler = &xnintr_isairq_handler;
+
+	err = xnarch_hook_irq(intr->irq,handler,intr->iack,NULL);
 	if (err)
 	    goto unlock_and_exit;
 	}
@@ -564,6 +573,70 @@ static void xnintr_irq_handler (unsigned
     xnltt_log_event(xeno_ev_iexit,irq);
 }
 
+#define MAX_ISA_COUNTER		128
+
+static void xnintr_isairq_handler (unsigned irq, void *cookie)
+
+{
+    xnsched_t *sched = xnpod_current_sched();
+    xnintr_shirq_t *shirq;
+    xnintr_t *intr, *end = NULL;
+    int s = 0, handled = 0, counter = 0;
+
+    xnarch_memory_barrier();
+
+    xnltt_log_event(xeno_ev_ienter,irq);
+
+    ++sched->inesting;
+
+    shirq = &xnshirqs[irq];
+
+    xnintr_shirq_lock(shirq);
+    intr = shirq->handlers;
+
+    while (intr != end)
+        {
+	int ret = intr->isr(intr);
+
+	if (!(ret & XN_ISR_NOINT))
+	    {
+	    handled = 1;
+	    end = NULL;
+	    s |= ret;
+	    }
+	else if (end == NULL)
+	    end = intr;
+
+	if (!counter++)
+    	    ++intr->hits;
+
+        if (!(intr = intr->next))
+	    intr = shirq->handlers;
+
+	if (counter > MAX_ISA_COUNTER)
+	    break;
+        }
+
+    xnintr_shirq_unlock(shirq);
+
+    --sched->inesting;
+
+    /* If we encounter this case, the line is non-usable any more. */
+    if (counter > MAX_ISA_COUNTER)
+	xnlogerr("xnintr_isairq_handler() : failed to get the IRQ%d line free.\n", irq);
+
+    if (s & XN_ISR_ENABLE)
+	xnarch_enable_irq(irq);
+
+    if (s & XN_ISR_CHAINED)
+	xnarch_chain_irq(irq);
+
+    if (sched->inesting == 0 && xnsched_resched_p())
+	xnpod_schedule();
+
+    xnltt_log_event(xeno_ev_iexit,irq);
+}
+
 int xnintr_irq_proc(unsigned int irq, char *str)
 {
     xnintr_shirq_t *shirq;

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Xenomai-core]  [Combo-PATCH] Shared interrupts (base, /proc support, edge-triggered stuff)
  2006-02-01 21:23 [Xenomai-core] [Combo-PATCH] Shared interrupts (base, /proc support, edge-triggered stuff) Dmitry Adamushko
@ 2006-02-02 10:51 ` Jan Kiszka
  2006-02-02 12:01   ` Dmitry Adamushko
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Kiszka @ 2006-02-02 10:51 UTC (permalink / raw)
  To: Dmitry Adamushko; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 1367 bytes --]

Dmitry Adamushko wrote:
> Hi there,
> 
> as I promised, here go the following patches (ordered as they have to be
> applied one by one) :
> 
> 
> 1) shirq-base.patch
> 
> Adds the "name" field to the interrupt object of the nucleus layer.
> Reworks the related bits of the native skin (+ a few minor changes for
> posix and rtdm) to support the named interrupt objects.
> 
> 
> 2) shirq-v7.patch
> 
> Generic support for shared interrupts.
> 
> 
> 3) shirq-proc.patch
> 
> /proc support.
> 
> Now /proc/xenomai/irq shows the names of handlers.
> 
> The related code have been removed from the hal layer to nucleus.
> 
> 
> -----
> 
> 4) shirq-isa.patch
> 
> Trying to handle the edge-triggered stuff.
> 
> This is a very preliminary version so the only thing I promise so far
> is that it compiles successfully.

Why not name it XN_ISR_EDGE or so (also the related functions etc.)?
Although it mostly targets ISA hardware, it's about the edge-triggered
characteristic of that devices after all.

> 
> 
> The functionality added by first 3 patches seem to be working.
> 
> --
> Best regards,
> Dmitry Adamushko
> 

I'm now trying to organise a full test scenario with shared UART
ISA-IRQs at our institute. May take till beginning of next week, some
regressions in our own software need to be fixed first.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Xenomai-core] [Combo-PATCH] Shared interrupts (base, /proc support, edge-triggered stuff)
  2006-02-02 10:51 ` Jan Kiszka
@ 2006-02-02 12:01   ` Dmitry Adamushko
  0 siblings, 0 replies; 3+ messages in thread
From: Dmitry Adamushko @ 2006-02-02 12:01 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

[-- Attachment #1: Type: text/plain, Size: 1688 bytes --]

On 02/02/06, Jan Kiszka <jan.kiszka@domain.hid> wrote:
>
> Dmitry Adamushko wrote:
> > Hi there,
> >
> > as I promised, here go the following patches (ordered as they have to be
> > applied one by one) :
> >
> >
> > 1) shirq-base.patch
> >
> > Adds the "name" field to the interrupt object of the nucleus layer.
> > Reworks the related bits of the native skin (+ a few minor changes for
> > posix and rtdm) to support the named interrupt objects.
> >
> >
> > 2) shirq-v7.patch
> >
> > Generic support for shared interrupts.
> >
> >
> > 3) shirq-proc.patch
> >
> > /proc support.
> >
> > Now /proc/xenomai/irq shows the names of handlers.
> >
> > The related code have been removed from the hal layer to nucleus.
> >
> >
> > -----
> >
> > 4) shirq-isa.patch
> >
> > Trying to handle the edge-triggered stuff.
> >
> > This is a very preliminary version so the only thing I promise so far
> > is that it compiles successfully.
>
> Why not name it XN_ISR_EDGE or so (also the related functions etc.)?
> Although it mostly targets ISA hardware, it's about the edge-triggered
> characteristic of that devices after all.


Ack.

I forgot to apply your earlier fixes so it will be done too.


>
> >
> > The functionality added by first 3 patches seem to be working.
> >
> > --
> > Best regards,
> > Dmitry Adamushko
> >
>
> I'm now trying to organise a full test scenario with shared UART
> ISA-IRQs at our institute. May take till beginning of next week, some
> regressions in our own software need to be fixed first.


That's good. Thanks. Keep me informed on progress.


Jan
>
>
>
>

--
Best regards,
Dmitry Adamushko

[-- Attachment #2: Type: text/html, Size: 2457 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-02-02 12:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-02-01 21:23 [Xenomai-core] [Combo-PATCH] Shared interrupts (base, /proc support, edge-triggered stuff) Dmitry Adamushko
2006-02-02 10:51 ` Jan Kiszka
2006-02-02 12:01   ` Dmitry Adamushko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.