#include <stdio.h>
#include <errno.h>
-#include <osmocore/msgb.h>
+#include <osmocom/core/msgb.h>
#ifdef HOST_BUILD
-#define SERCOMM_RX_MSG_SIZE 2048
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#endif
-#include <sercomm.h>
-#define local_irq_save(x) (void) x
-#define local_fiq_disable()
-#define local_irq_restore(x) (void) x
+
+# define SERCOMM_RX_MSG_SIZE 2048
+# ifndef ARRAY_SIZE
+# define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+# endif
+# include <sercomm.h>
+
+static inline void sercomm_lock(unsigned long __attribute__((unused)) *flags) {}
+static inline void sercomm_unlock(unsigned long __attribute__((unused)) *flags) {}
#else
-#define SERCOMM_RX_MSG_SIZE 256
-#include <debug.h>
-#include <osmocore/linuxlist.h>
-#include <asm/system.h>
-#include <comm/sercomm.h>
-#include <calypso/uart.h>
+# define SERCOMM_RX_MSG_SIZE 256
+# include <debug.h>
+# include <osmocom/core/linuxlist.h>
+# include <asm/system.h>
+
+static inline void sercomm_lock(unsigned long *flags)
+{
+ local_firq_save(*flags);
+}
+
+static inline void sercomm_unlock(unsigned long *flags)
+{
+ local_irq_restore(*flags);
+}
+
+# include <comm/sercomm.h>
+# include <uart.h>
+
#endif
/* This functiion can be called from any context: FIQ, IRQ
* and supervisor context. Proper locking is important! */
- local_irq_save(flags);
- local_fiq_disable();
+ sercomm_lock(&flags);
msgb_enqueue(&sercomm.tx.dlci_queues[dlci], msg);
- local_irq_restore(flags);
+ sercomm_unlock(&flags);
#ifndef HOST_BUILD
/* tell UART that we have something to send */
/* fetch one octet of to-be-transmitted serial data */
int sercomm_drv_pull(uint8_t *ch)
{
- /* we are always called from interrupt context in this function,
- * which means that any data structures we use need to be for
- * our exclusive access */
+ unsigned long flags;
+
+ /* we may be called from interrupt context, but we stiff need to lock
+ * because sercomm could be accessed from a FIQ context ... */
+
+ sercomm_lock(&flags);
+
if (!sercomm.tx.msg) {
unsigned int i;
/* dequeue a new message from the queues */
/* start of a new message, send start flag octet */
*ch = HDLC_FLAG;
sercomm.tx.next_char = sercomm.tx.msg->data;
+ sercomm_unlock(&flags);
return 1;
} else {
/* no more data avilable */
+ sercomm_unlock(&flags);
return 0;
}
}
/* standard case, simply send next octet */
*ch = *sercomm.tx.next_char++;
}
+
+ sercomm_unlock(&flags);
return 1;
}