summaryrefslogtreecommitdiffstats
path: root/src/target/firmware/include
diff options
context:
space:
mode:
authorAndreas.Eversberg2010-09-12 15:49:41 +0200
committerAndreas.Eversberg2010-09-12 15:49:41 +0200
commit59894035c598f82239e3d7fb56636a6524534466 (patch)
tree2c3c4be5ab313b302f8de7b3fc0810644547eb7e /src/target/firmware/include
parent[layer1] Added frequency change control to layer 1 (L1CTL_FREQ_REQ) (diff)
downloadosmocom-59894035c598f82239e3d7fb56636a6524534466.tar.gz
osmocom-59894035c598f82239e3d7fb56636a6524534466.tar.xz
osmocom-59894035c598f82239e3d7fb56636a6524534466.zip
[layer1] Fixed double IRQ bug
During IRQ handling, disabling and enabling IRQ may cause the same IRQ to fire again. This is because the condition for this IRQ may be fullfilled again, while still handling it. Using local_firq_save() and local_irq_resore() intead, the IRQ handling will be completed before it is cleared, and may then fire again. The problem was detected during process of messages from layer23 to layer1. In the IRQ context, the TX-functions of l23_api.c are called. There, messages are queued and events are scheduled. During access to a queue or a scheduler from any IRQ context or from normal context, interrupts must be locked to prevent nested calls. If it is not desired to call l23_api.c inside IRQ context, a message queue must be used. If a message is written to that queue, it must be locked. Afterwards a signal must be sent to the main process. The main process locks the queue and de-queues the message. This is how it is done by all layer 1 drivers of mISDN.
Diffstat (limited to 'src/target/firmware/include')
-rw-r--r--src/target/firmware/include/layer1/async.h5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/target/firmware/include/layer1/async.h b/src/target/firmware/include/layer1/async.h
index 42c3223..16b016e 100644
--- a/src/target/firmware/include/layer1/async.h
+++ b/src/target/firmware/include/layer1/async.h
@@ -5,6 +5,10 @@
#include <layer1/mframe_sched.h>
+#if 0
+NOTE: Re-enabling interrupts causes an IRQ while processing the same IRQ.
+ Use local_firq_save and local_irq_restore instead!
+
/* When altering data structures used by L1 Sync part, we need to
* make sure to temporarily disable IRQ/FIQ to keep data consistent */
static inline void l1a_lock_sync(void)
@@ -16,6 +20,7 @@ static inline void l1a_unlock_sync(void)
{
arm_enable_interrupts();
}
+#endif
/* safely enable a message into the L1S TX queue */
void l1a_txq_msgb_enq(struct llist_head *queue, struct msgb *msg);