#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;
}
}
if (sercomm.tx.state == RX_ST_ESCAPE) {
/* we've already transmitted the ESCAPE octet,
- * we now need to trnsmit the escaped data */
+ * we now need to transmit the escaped data */
*ch = *sercomm.tx.next_char++;
sercomm.tx.state = RX_ST_DATA;
} else if (sercomm.tx.next_char >= sercomm.tx.msg->tail) {
/* standard case, simply send next octet */
*ch = *sercomm.tx.next_char++;
}
+
+ sercomm_unlock(&flags);
return 1;
}
return 0;
}
-/* dispatch an incomnig message once it is completely received */
+/* dispatch an incoming message once it is completely received */
static void dispatch_rx_msg(uint8_t dlci, struct msgb *msg)
{
if (dlci >= ARRAY_SIZE(sercomm.rx.dlci_handler) ||
ch ^= (1 << 5);
ptr = msgb_put(sercomm.rx.msg, 1);
*ptr = ch;
- /* transition back to nromal DATA state */
+ /* transition back to normal DATA state */
sercomm.rx.state = RX_ST_DATA;
break;
}