Index: cdl/interrupts.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/kernel/current/cdl/interrupts.cdl,v
retrieving revision 1.4
diff -u -r1.4 interrupts.cdl
--- cdl/interrupts.cdl	23 May 2002 23:06:45 -0000	1.4
+++ cdl/interrupts.cdl	15 Feb 2006 13:07:22 -0000
@@ -87,6 +87,21 @@
             possibility of a table overflow occurring."
     }
 
+    cdl_option CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO {
+        display       "Use FIFO for DSRs "
+        default_value 0
+        implements    CYGINT_KERNEL_INTERRUPTS_DSRS
+        description   "
+            When DSR support is enabled the kernel must keep track of all
+            the DSRs that are pending. This information can be kept in a
+            fixed-size table or in a linked list. The list implementation
+            requires that the kernel disable interrupts for a very short
+            period of time outside interrupt handlers, but there is no
+            possibility of a table overflow occurring. Instead of LIST this
+            implementation processed the DSR and first come, first serve
+            order, which reduces the ISR to DSR delay."
+    }
+
     cdl_component CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE {
         display       "Use fixed-size table for DSRs"
         default_value 0
Index: include/intr.hxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/kernel/current/include/intr.hxx,v
retrieving revision 1.11
diff -u -r1.11 intr.hxx
--- include/intr.hxx	23 May 2002 23:06:47 -0000	1.11
+++ include/intr.hxx	3 Apr 2006 14:30:19 -0000
@@ -187,6 +187,7 @@
                                                CYGBLD_ANNOTATE_VARIABLE_INTR;
 
 #endif
+
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
 
     // Number of DSR posts made
@@ -198,6 +199,22 @@
     // static list of pending DSRs
     static Cyg_Interrupt* volatile dsr_list[CYGNUM_KERNEL_CPU_MAX]
                                            CYGBLD_ANNOTATE_VARIABLE_INTR;
+
+#endif
+
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+    // Number of DSR posts made
+    volatile cyg_ucount32 dsr_count CYGBLD_ANNOTATE_VARIABLE_INTR; 
+
+    // next DSR in list
+    Cyg_Interrupt* volatile next_dsr CYGBLD_ANNOTATE_VARIABLE_INTR; 
+
+    // static list of pending DSRs
+    static Cyg_Interrupt* volatile dsr_list_head[CYGNUM_KERNEL_CPU_MAX]
+                                           CYGBLD_ANNOTATE_VARIABLE_INTR;
+    static Cyg_Interrupt* volatile dsr_list_tail[CYGNUM_KERNEL_CPU_MAX]
+                                           CYGBLD_ANNOTATE_VARIABLE_INTR;
     
 #endif
 
@@ -363,6 +380,12 @@
     return dsr_list[cpu] != NULL;
 
 #endif
+
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+    
+    return dsr_list_head[cpu] != NULL;
+
+#endif
 };
 #endif // CYGIMP_KERNEL_INTERRUPTS_DSRS
 
Index: include/kapidata.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/kernel/current/include/kapidata.h,v
retrieving revision 1.13
diff -u -r1.13 kapidata.h
--- include/kapidata.h	27 Feb 2003 06:14:32 -0000	1.13
+++ include/kapidata.h	4 Apr 2006 11:28:59 -0000
@@ -148,6 +148,10 @@
     cyg_ucount32        dsr_count;
     cyg_interrupt       *next_dsr;
 #endif
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+    cyg_ucount32        dsr_count;
+    cyg_interrupt       *next_dsr;
+#endif
 #ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
     cyg_interrupt       *next;
 #endif
Index: src/intr/intr.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/kernel/current/src/intr/intr.cxx,v
retrieving revision 1.17
diff -u -r1.17 intr.cxx
--- src/intr/intr.cxx	23 May 2002 23:06:54 -0000	1.17
+++ src/intr/intr.cxx	4 Apr 2006 16:57:20 -0000
@@ -100,6 +100,13 @@
 
 #endif
 
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+    dsr_count   = 0;
+    next_dsr    = NULL;
+
+#endif
+
 #ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
 
     next        = NULL;
@@ -139,6 +146,13 @@
 
 #endif
 
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list_head[CYGNUM_KERNEL_CPU_MAX];
+Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list_tail[CYGNUM_KERNEL_CPU_MAX];
+
+#endif
+
 // -------------------------------------------------------------------------
 // Call any pending DSRs
 
@@ -192,6 +206,38 @@
     }
     
 #endif
+
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+    cyg_uint32 old_intr;
+    HAL_DISABLE_INTERRUPTS(old_intr);
+    while( dsr_list_head[cpu] != NULL )
+    {
+        Cyg_Interrupt* intr;
+        cyg_count32 count;
+        
+        
+        intr = dsr_list_head[cpu];
+        dsr_list_head[cpu] = intr->next_dsr;
+        count = intr->dsr_count;
+        intr->dsr_count = 0;
+        intr->next_dsr = 0;
+        if (dsr_list_head[cpu] == NULL)
+        {
+            dsr_list_tail[cpu] = NULL;
+        }
+        
+        HAL_RESTORE_INTERRUPTS(old_intr);
+        
+        CYG_ASSERT( intr->dsr != NULL , "No DSR defined");
+
+        intr->dsr( intr->vector, count, (CYG_ADDRWORD)intr->data );
+        
+    	  HAL_DISABLE_INTERRUPTS(old_intr);
+    }
+    HAL_RESTORE_INTERRUPTS(old_intr);
+
+#endif
     
 };
 
@@ -256,6 +302,27 @@
     }
     
 #endif
+
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+    // Check if this is the first DSR to call. If yes, initialize the
+    // dsr_list_head, else attach the current irq to the dsr_list_tail.
+    
+    if( dsr_count++ == 0 )
+    {
+        Cyg_Interrupt* cur_last_dsr = dsr_list_tail[cpu];
+        if (cur_last_dsr != 0)
+        {
+            cur_last_dsr->next_dsr = this;
+        }
+        else
+        {
+            dsr_list_head[cpu] = this;
+        }
+        dsr_list_tail[cpu] = this;
+    }
+    
+#endif
     
     HAL_RESTORE_INTERRUPTS(old_intr);    
 };
@@ -282,6 +349,10 @@
     )
 {
 //    CYG_REPORT_FUNCTION();
+	if (intr == 0)
+	{
+		diag_printf("ERROR: zero interrupt: %d,0x%08x,0x%08x\n",isr_ret,(unsigned int) intr,(unsigned int) regs);
+	}
 
 #ifdef CYGPKG_KERNEL_SMP_SUPPORT
     Cyg_Scheduler::lock();
