Here comes an attempt to clean up some of the mess that piled up in
nucleus/intr.c over the time and specifically after our last hot-fixes.

First of all, I think we don't loose much when merging the two separate
switches for level- and edge-triggered shared IRQs into a single one.
That already beatifies some lines, kills conditional code, and removes
one configuration decision the user has to make.

Then I reordered some code to avoid warnings for the non-shared non-SMP
case AND to fix a probable compilation issue of the simulator (due to
unknown ____cacheline_aligned_in_smp).

At this chance, a few redundant conditional lines in rtcan_*_pci.c
drivers were removed as well.

Jan
---
 include/nucleus/intr.h                     |    4 
 ksrc/drivers/can/sja1000/rtcan_ixxat_pci.c |    4 
 ksrc/drivers/can/sja1000/rtcan_peak_pci.c  |    4 
 ksrc/nucleus/Config.in                     |    8 -
 ksrc/nucleus/Kconfig                       |   32 +---
 ksrc/nucleus/intr.c                        |  213 ++++++++++++++---------------
 6 files changed, 116 insertions(+), 149 deletions(-)

Index: xenomai/include/nucleus/intr.h
===================================================================
--- xenomai.orig/include/nucleus/intr.h
+++ xenomai/include/nucleus/intr.h
@@ -45,9 +45,9 @@
 
 typedef struct xnintr {
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
+#ifdef CONFIG_XENO_OPT_SHIRQ
     struct xnintr *next; /* !< Next object in the IRQ-sharing chain. */
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif /* CONFIG_XENO_OPT_SHIRQ */
 
     unsigned unhandled;	/* !< Number of consequent unhandled interrupts */
 
Index: xenomai/ksrc/drivers/can/sja1000/rtcan_ixxat_pci.c
===================================================================
--- xenomai.orig/ksrc/drivers/can/sja1000/rtcan_ixxat_pci.c
+++ xenomai/ksrc/drivers/can/sja1000/rtcan_ixxat_pci.c
@@ -176,11 +176,7 @@ static int rtcan_ixxat_pci_add_chan(stru
     outb(intcsr, board->conf_addr + IXXAT_INTCSR_OFFSET);
 
     /* Register and setup interrupt handling */
-#ifdef CONFIG_XENO_OPT_SHIRQ_LEVEL
     chip->irq_flags = RTDM_IRQTYPE_SHARED;
-#else
-    chip->irq_flags = 0;
-#endif
     chip->irq_num = pdev->irq;
 
     RTCAN_DBG("%s: base_addr=0x%p conf_addr=%#x irq=%d ocr=%#x cdr=%#x\n",
Index: xenomai/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
===================================================================
--- xenomai.orig/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
+++ xenomai/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
@@ -230,11 +230,7 @@ static int rtcan_peak_pci_add_chan(struc
     strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ);
 
     /* Register and setup interrupt handling */
-#ifdef CONFIG_XENO_OPT_SHIRQ_LEVEL
     chip->irq_flags = RTDM_IRQTYPE_SHARED;
-#else
-    chip->irq_flags = 0;
-#endif
     chip->irq_num = pdev->irq;
     pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
     if (channel == CHANNEL_SLAVE) {
Index: xenomai/ksrc/nucleus/Config.in
===================================================================
--- xenomai.orig/ksrc/nucleus/Config.in
+++ xenomai/ksrc/nucleus/Config.in
@@ -36,6 +36,8 @@ if [ "$CONFIG_XENO_OPT_NUCLEUS" != "n" ]
 		bool 'Watchdog support' CONFIG_XENO_OPT_WATCHDOG
 	fi
 
+	bool 'Shared interrupts' CONFIG_XENO_OPT_SHIRQ
+
 	bool 'Enable periodic timing' CONFIG_XENO_OPT_TIMING_PERIODIC
 	int 'Timer tuning latency (ns)' CONFIG_XENO_OPT_TIMING_TIMERLAT 0
 	int 'Scheduling latency (ns)' CONFIG_XENO_OPT_TIMING_SCHEDLAT 0
@@ -55,12 +57,6 @@ if [ "$CONFIG_XENO_OPT_NUCLEUS" != "n" ]
 	fi
 	endmenu
 
-	mainmenu_option next_comment
-	comment 'Shared interrupts'
-		bool 'Level-triggered interrupts' CONFIG_XENO_OPT_SHIRQ_LEVEL
-		bool 'Edge-triggered interrupts' CONFIG_XENO_OPT_SHIRQ_EDGE
-	endmenu
-
 	if [ "$CONFIG_LTT" != "n" ]; then
 		mainmenu_option next_comment
 		comment 'LTT tracepoints filtering'
Index: xenomai/ksrc/nucleus/Kconfig
===================================================================
--- xenomai.orig/ksrc/nucleus/Kconfig
+++ xenomai/ksrc/nucleus/Kconfig
@@ -208,6 +208,15 @@ config XENO_OPT_WATCHDOG
 	behalf of the timer tick handler, thus is only active after
 	the timer has been started.
 
+config XENO_OPT_SHIRQ
+	bool "Shared interrupts"
+	help
+
+	Enables support for both level- and edge-triggered shared
+	interrupts, so that multiple real-time interrupt handlers
+	are allowed to control dedicated hardware devices which are
+	configured to share the same interrupt line.
+
 menu "Timing"
 
 config XENO_OPT_TIMING_PERIODIC
@@ -319,29 +328,6 @@ config XENO_OPT_TIMER_WHEEL_STEP
 
 endmenu
 
-
-menu "Shared interrupts"
-
-config XENO_OPT_SHIRQ_LEVEL
-	bool "Level-triggered interrupts"
-	help
-
-	Enables support for shared level-triggered interrupts, so that
-	multiple real-time interrupt handlers are allowed to control
-	dedicated hardware devices which are configured to share
-	the same interrupt channel.
-
-config XENO_OPT_SHIRQ_EDGE
-	bool "Edge-triggered interrupts"
-	help
-
-	Enables support for shared edge-triggered interrupts, so that
-	multiple real-time interrupt handlers are allowed to control
-	dedicated hardware devices which are configured to share
-	the same interrupt channel.
-
-endmenu
-
 menu "LTT tracepoints filtering"
 
 	depends on LTT
Index: xenomai/ksrc/nucleus/intr.c
===================================================================
--- xenomai.orig/ksrc/nucleus/intr.c
+++ xenomai/ksrc/nucleus/intr.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2001,2002,2003 Philippe Gerum <[EMAIL PROTECTED]>.
  * Copyright (C) 2005,2006 Dmitry Adamushko <[EMAIL PROTECTED]>.
+ * Copyright (C) 2007 Jan Kiszka <[EMAIL PROTECTED]>.
  *
  * Xenomai is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
@@ -41,18 +42,6 @@
 
 DEFINE_PRIVATE_XNLOCK(intrlock);
 
-typedef struct xnintr_irq {
-
-	DECLARE_XNLOCK(lock);
-
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
-	xnintr_t *handlers;
-	int unhandled;
-#endif
-} ____cacheline_aligned_in_smp xnintr_irq_t;
-
-static xnintr_irq_t xnirqs[RTHAL_NR_IRQS];
-
 #ifdef CONFIG_XENO_OPT_STATS
 xnintr_t nkclock;	/* Only for statistics */
 int xnintr_count = 1;	/* Number of attached xnintr objects + nkclock */
@@ -94,71 +83,7 @@ static inline void xnintr_stat_counter_d
 static inline void xnintr_sync_stat_references(xnintr_t *intr) {}
 #endif /* CONFIG_XENO_OPT_STATS */
 
-/*
- * Low-level interrupt handler dispatching the ISRs -- Called with
- * interrupts off.
- */
-
-static void xnintr_irq_handler(unsigned irq, void *cookie)
-{
-	xnsched_t *sched = xnpod_current_sched();
-	xnintr_t *intr;
-	xnstat_runtime_t *prev;
-	xnticks_t start;
-	int s;
-
-	prev  = xnstat_runtime_get_current(sched);
-	start = xnstat_runtime_now();
-	xnltt_log_event(xeno_ev_ienter, irq);
-
-	++sched->inesting;
-
-	xnlock_get(&xnirqs[irq].lock);
-
-#ifdef CONFIG_SMP
-	/* In SMP case, we have to reload the cookie under the per-IRQ lock
-	   to avoid racing with xnintr_detach. */
-	intr = rthal_irq_cookie(&rthal_domain, irq);
-	if (unlikely(!intr)) {
-		s = 0;
-		goto unlock_and_exit;
-	}
-#else
-	/* cookie always valid, attach/detach happens with IRQs disabled */
-	intr = cookie;
-#endif
-	s = intr->isr(intr);
-
-	if (unlikely(s == XN_ISR_NONE)) {
-		if (++intr->unhandled == XNINTR_MAX_UNHANDLED) {
-			xnlogerr("%s: IRQ%d not handled. Disabling IRQ "
-				 "line.\n", __FUNCTION__, irq);
-			s |= XN_ISR_NOENABLE;
-		}
-	} else {
-		xnstat_counter_inc(&intr->stat[xnsched_cpu(sched)].hits);
-		xnstat_runtime_lazy_switch(sched,
-			&intr->stat[xnsched_cpu(sched)].account,
-			start);
-		intr->unhandled = 0;
-	}
-
-#ifdef CONFIG_SMP
- unlock_and_exit:
-#endif
-	xnlock_put(&xnirqs[irq].lock);
-
-	if (s & XN_ISR_PROPAGATE)
-		xnarch_chain_irq(irq);
-	else if (!(s & XN_ISR_NOENABLE))
-		xnarch_end_irq(irq);
-
-	if (--sched->inesting == 0 && xnsched_resched_p())
-		xnpod_schedule();
-
-	xnltt_log_event(xeno_ev_iexit, irq);
-	xnstat_runtime_switch(sched, prev);
-}
+static void xnintr_irq_handler(unsigned irq, void *cookie);
 
 /* Low-level clock irq handler. */
 
@@ -205,14 +130,23 @@ void xnintr_clock_handler(void)
 
 /* Optional support for shared interrupts. */
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
+#ifdef CONFIG_XENO_OPT_SHIRQ
+
+typedef struct xnintr_irq {
+
+	DECLARE_XNLOCK(lock);
+
+	xnintr_t *handlers;
+	int unhandled;
+
+} ____cacheline_aligned_in_smp xnintr_irq_t;
+
+static xnintr_irq_t xnirqs[RTHAL_NR_IRQS];
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL)
 /*
  * Low-level interrupt handler dispatching the user-defined ISRs for
  * shared interrupts -- Called with interrupts off.
  */
-
 static void xnintr_shirq_handler(unsigned irq, void *cookie)
 {
 	xnsched_t *sched = xnpod_current_sched();
@@ -272,14 +206,10 @@ static void xnintr_shirq_handler(unsigne
 	xnstat_runtime_switch(sched, prev);
 }
 
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL */
-
-#if defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
 /*
  * Low-level interrupt handler dispatching the user-defined ISRs for
  * shared edge-triggered interrupts -- Called with interrupts off.
  */
-
 static void xnintr_edge_shirq_handler(unsigned irq, void *cookie)
 {
 	const int MAX_EDGEIRQ_COUNTER = 128;
@@ -356,8 +286,6 @@ static void xnintr_edge_shirq_handler(un
 	xnstat_runtime_switch(sched, prev);
 }
 
-#endif /* CONFIG_XENO_OPT_SHIRQ_EDGE */
-
 static inline int xnintr_irq_attach(xnintr_t *intr)
 {
 	xnintr_irq_t *shirq = &xnirqs[intr->irq];
@@ -389,17 +317,9 @@ static inline int xnintr_irq_attach(xnin
 
 		if (intr->flags & XN_ISR_SHARED) {
 			if (intr->flags & XN_ISR_EDGE)
-#if defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
 				handler = &xnintr_edge_shirq_handler;
-#else /* !CONFIG_XENO_OPT_SHIRQ_EDGE */
-				return -ENOSYS;
-#endif /* CONFIG_XENO_OPT_SHIRQ_EDGE */
 			else
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL)
 				handler = &xnintr_shirq_handler;
-#else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL */
-				return -ENOSYS;
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL */
 
 		}
 		shirq->unhandled = 0;
@@ -457,7 +377,17 @@ static inline int xnintr_irq_detach(xnin
 	return err;
 }
 
-#else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL && !CONFIG_XENO_OPT_SHIRQ_EDGE */
+#else /* !CONFIG_XENO_OPT_SHIRQ */
+
+#ifdef CONFIG_SMP
+typedef struct xnintr_irq {
+
+	DECLARE_XNLOCK(lock);
+
+} ____cacheline_aligned_in_smp xnintr_irq_t;
+
+static xnintr_irq_t xnirqs[RTHAL_NR_IRQS];
+#endif /* CONFIG_SMP */
 
 static inline int xnintr_irq_attach(xnintr_t *intr)
 {
@@ -477,7 +407,72 @@ static inline int xnintr_irq_detach(xnin
 	return err;
 }
 
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif /* !CONFIG_XENO_OPT_SHIRQ */
+
+/*
+ * Low-level interrupt handler dispatching non-shared ISRs -- Called with
+ * interrupts off.
+ */
+static void xnintr_irq_handler(unsigned irq, void *cookie)
+{
+	xnsched_t *sched = xnpod_current_sched();
+	xnintr_t *intr;
+	xnstat_runtime_t *prev;
+	xnticks_t start;
+	int s;
+
+	prev  = xnstat_runtime_get_current(sched);
+	start = xnstat_runtime_now();
+	xnltt_log_event(xeno_ev_ienter, irq);
+
+	++sched->inesting;
+
+	xnlock_get(&xnirqs[irq].lock);
+
+#ifdef CONFIG_SMP
+	/* In SMP case, we have to reload the cookie under the per-IRQ lock
+	   to avoid racing with xnintr_detach. */
+	intr = rthal_irq_cookie(&rthal_domain, irq);
+	if (unlikely(!intr)) {
+		s = 0;
+		goto unlock_and_exit;
+	}
+#else
+	/* cookie always valid, attach/detach happens with IRQs disabled */
+	intr = cookie;
+#endif
+	s = intr->isr(intr);
+
+	if (unlikely(s == XN_ISR_NONE)) {
+		if (++intr->unhandled == XNINTR_MAX_UNHANDLED) {
+			xnlogerr("%s: IRQ%d not handled. Disabling IRQ "
+				 "line.\n", __FUNCTION__, irq);
+			s |= XN_ISR_NOENABLE;
+		}
+	} else {
+		xnstat_counter_inc(&intr->stat[xnsched_cpu(sched)].hits);
+		xnstat_runtime_lazy_switch(sched,
+			&intr->stat[xnsched_cpu(sched)].account,
+			start);
+		intr->unhandled = 0;
+	}
+
+#ifdef CONFIG_SMP
+ unlock_and_exit:
+#endif
+	xnlock_put(&xnirqs[irq].lock);
+
+	if (s & XN_ISR_PROPAGATE)
+		xnarch_chain_irq(irq);
+	else if (!(s & XN_ISR_NOENABLE))
+		xnarch_end_irq(irq);
+
+	if (--sched->inesting == 0 && xnsched_resched_p())
+		xnpod_schedule();
+
+	xnltt_log_event(xeno_ev_iexit, irq);
+	xnstat_runtime_switch(sched, prev);
+}
 
 int xnintr_mount(void)
 {
@@ -598,9 +593,9 @@ int xnintr_init(xnintr_t *intr,
 	intr->flags = flags;
 	intr->unhandled = 0;
 	memset(&intr->stat, 0, sizeof(intr->stat));
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
+#ifdef CONFIG_XENO_OPT_SHIRQ
 	intr->next = NULL;
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif
 
 	return 0;
 }
@@ -849,7 +844,7 @@ int xnintr_irq_proc(unsigned int irq, ch
 
 	xnlock_get_irqsave(&intrlock, s);
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
+#ifdef CONFIG_XENO_OPT_SHIRQ
 	intr = xnirqs[irq].handlers;
 	if (intr) {
 		strcpy(p, "        "); p += 8;
@@ -861,13 +856,13 @@ int xnintr_irq_proc(unsigned int irq, ch
 			intr = intr->next;
 		} while (intr);
 	}
-#else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL && !CONFIG_XENO_OPT_SHIRQ_EDGE */
+#else /* !CONFIG_XENO_OPT_SHIRQ */
 	intr = rthal_irq_cookie(&rthal_domain, irq);
 	if (intr) {
 		strcpy(p, "         "); p += 9;
 		strcpy(p, intr->name); p += strlen(intr->name);
 	}
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif /* !CONFIG_XENO_OPT_SHIRQ */
 
 	xnlock_put_irqrestore(&intrlock, s);
 
@@ -897,21 +892,19 @@ int xnintr_query(int irq, int *cpu, xnin
 		goto unlock_and_exit;
 	}
 
-#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
-	if (*prev)
-		intr = (*prev)->next;
-	else if (irq == XNARCH_TIMER_IRQ)
+	if (irq == XNARCH_TIMER_IRQ)
 		intr = &nkclock;
+#ifdef CONFIG_XENO_OPT_SHIRQ
+	else if (*prev)
+		intr = (*prev)->next;
 	else
 		intr = xnirqs[irq].handlers;
-#else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL && !CONFIG_XENO_OPT_SHIRQ_EDGE */
-	if (*prev)
+#else /* !CONFIG_XENO_OPT_SHIRQ */
+	else if (*prev)
 		intr = NULL;
-	else if (irq == XNARCH_TIMER_IRQ)
-		intr = &nkclock;
 	else
 		intr = rthal_irq_cookie(&rthal_domain, irq);
-#endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
+#endif /* !CONFIG_XENO_OPT_SHIRQ */
 
 	if (!intr) {
 		err = -ENODEV;

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core

Reply via email to