Merge branch 'externc' of https://github.com/dkodihal/libmctp

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
diff --git a/Makefile.inc b/Makefile.inc
index 99edaac..98df834 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -1,5 +1,8 @@
 LIBMCTP_DIR ?= libmctp/
-LIBMCTP_OBJS = core.o alloc.o serial.o
+LIBMCTP_OBJS = core.o alloc.o
+LIBMCTP_BINDINGS ?= serial
+
+LIBMCTP_OBJS += $(LIBMCTP_BINDINGS:%=%.o)
 
 LIBMCTP = $(LIBMCTP_DIR)libmctp.a
 
diff --git a/README.md b/README.md
index 62f9195..80b0150 100644
--- a/README.md
+++ b/README.md
@@ -79,6 +79,9 @@
     - `MCTP_LOG_CUSTOM`: provide your own macro for logging, of
       the format: ```#define mctp_prlog(level, fmt, ...) (....)```
 
+ - `MCTP_NO_DEFAULT_ALLOC`: do not set default allocator functions (malloc,
+   free, realloc), and require the use of `mctp_set_alloc_ops`.
+
 TODO
 ----
 
diff --git a/alloc.c b/alloc.c
index 2389dd3..db16d84 100644
--- a/alloc.c
+++ b/alloc.c
@@ -2,50 +2,53 @@
 
 #include <assert.h>
 
+#include "libmctp.h"
 #include "libmctp-alloc.h"
 
 struct {
-	void	*(*alloc)(size_t);
-	void	(*free)(void *);
-	void	*(*realloc)(void *, size_t);
+	void	*(*m_alloc)(size_t);
+	void	(*m_free)(void *);
+	void	*(*m_realloc)(void *, size_t);
 } alloc_ops = {
+#ifndef MCTP_NO_DEFAULT_ALLOC
 	malloc,
 	free,
 	realloc,
+#endif
 };
 
 /* internal-only allocation functions */
 void *__mctp_alloc(size_t size)
 {
-	if (alloc_ops.alloc)
-		return alloc_ops.alloc(size);
-	if (alloc_ops.realloc)
-		return alloc_ops.realloc(NULL, size);
+	if (alloc_ops.m_alloc)
+		return alloc_ops.m_alloc(size);
+	if (alloc_ops.m_realloc)
+		return alloc_ops.m_realloc(NULL, size);
 	assert(0);
 }
 
 void __mctp_free(void *ptr)
 {
-	if (alloc_ops.free)
-		alloc_ops.free(ptr);
-	else if (alloc_ops.realloc)
-		alloc_ops.realloc(ptr, 0);
+	if (alloc_ops.m_free)
+		alloc_ops.m_free(ptr);
+	else if (alloc_ops.m_realloc)
+		alloc_ops.m_realloc(ptr, 0);
 	else
 		assert(0);
 }
 
 void *__mctp_realloc(void *ptr, size_t size)
 {
-	if (alloc_ops.realloc)
-		return alloc_ops.realloc(ptr, size);
+	if (alloc_ops.m_realloc)
+		return alloc_ops.m_realloc(ptr, size);
 	assert(0);
 }
 
-void mctp_set_alloc_ops(void *(*alloc)(size_t),
-		void (*free)(void *),
-		void *(realloc)(void *, size_t))
+void mctp_set_alloc_ops(void *(*m_alloc)(size_t),
+		void (*m_free)(void *),
+		void *(m_realloc)(void *, size_t))
 {
-	alloc_ops.alloc = alloc;
-	alloc_ops.free = free;
-	alloc_ops.realloc = realloc;
+	alloc_ops.m_alloc = m_alloc;
+	alloc_ops.m_free = m_free;
+	alloc_ops.m_realloc = m_realloc;
 }
diff --git a/core.c b/core.c
index 0a5a135..ebad5f8 100644
--- a/core.c
+++ b/core.c
@@ -20,6 +20,10 @@
 struct mctp_bus {
 	mctp_eid_t		eid;
 	struct mctp_binding	*binding;
+	bool			tx_enabled;
+
+	struct mctp_pktbuf	*tx_queue_head;
+	struct mctp_pktbuf	*tx_queue_tail;
 
 	/* todo: routing */
 };
@@ -37,9 +41,6 @@
 	/* todo: multiple busses */
 	struct mctp_bus	busses[1];
 
-	struct mctp_pktbuf	*tx_queue_head;
-	struct mctp_pktbuf	*tx_queue_tail;
-
 	/* Message RX callback */
 	mctp_rx_fn		message_rx;
 	void			*message_rx_data;
@@ -149,7 +150,7 @@
 static struct mctp_msg_ctx *mctp_msg_ctx_create(struct mctp *mctp,
 		uint8_t src, uint8_t tag)
 {
-	struct mctp_msg_ctx *ctx;
+	struct mctp_msg_ctx *ctx = NULL;
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) {
@@ -229,20 +230,23 @@
 	return &mctp->busses[0];
 }
 
-unsigned long mctp_register_bus(struct mctp *mctp,
+int mctp_register_bus(struct mctp *mctp,
 		struct mctp_binding *binding,
 		mctp_eid_t eid)
 {
+	/* todo: multiple busses */
 	assert(!mctp->busses[0].binding);
 	mctp->busses[0].binding = binding;
 	mctp->busses[0].eid = eid;
+	binding->bus = &mctp->busses[0];
+	binding->mctp = mctp;
 	return 0;
 }
 
-void mctp_bus_rx(struct mctp *mctp, unsigned long bus_id,
-		struct mctp_pktbuf *pkt)
+void mctp_bus_rx(struct mctp_binding *binding, struct mctp_pktbuf *pkt)
 {
-	struct mctp_bus *bus = &mctp->busses[bus_id];
+	struct mctp_bus *bus = binding->bus;
+	struct mctp *mctp = binding->mctp;
 	struct mctp_msg_ctx *ctx;
 	struct mctp_hdr *hdr;
 	uint8_t flags, seq, tag;
@@ -250,6 +254,8 @@
 	void *p;
 	int rc;
 
+	assert(bus);
+
 	hdr = mctp_pktbuf_hdr(pkt);
 
 	if (hdr->dest != bus->eid)
@@ -266,7 +272,7 @@
 		 * no need to create a message context */
 		len = pkt->end - pkt->mctp_hdr_off - sizeof(struct mctp_hdr);
 		p = pkt->data + pkt->mctp_hdr_off + sizeof(struct mctp_hdr),
-		mctp->message_rx(bus->eid, mctp->message_rx_data, p, len);
+		mctp->message_rx(hdr->src, mctp->message_rx_data, p, len);
 		break;
 
 	case MCTP_HDR_FLAG_SOM:
@@ -314,17 +320,50 @@
 	}
 }
 
-static int mctp_packet_tx(struct mctp *mctp __attribute__((unused)),
-		struct mctp_bus *bus,
+static int mctp_packet_tx(struct mctp_bus *bus,
 		struct mctp_pktbuf *pkt)
 {
+	if (!bus->tx_enabled)
+		return -1;
+
+	mctp_prdebug("sending pkt, len %d",
+			mctp_pktbuf_size(pkt));
+
 	return bus->binding->tx(bus->binding, pkt);
 }
 
+static void mctp_send_tx_queue(struct mctp_bus *bus)
+{
+	struct mctp_pktbuf *pkt;
+
+	while ((pkt = bus->tx_queue_head)) {
+		int rc;
+
+		rc = mctp_packet_tx(bus, pkt);
+		if (rc)
+			break;
+
+		bus->tx_queue_head = pkt->next;
+		mctp_pktbuf_free(pkt);
+	}
+
+	if (!bus->tx_queue_head)
+		bus->tx_queue_tail = NULL;
+
+}
+
+void mctp_binding_set_tx_enabled(struct mctp_binding *binding, bool enable)
+{
+	struct mctp_bus *bus = binding->bus;
+	bus->tx_enabled = enable;
+	if (enable)
+		mctp_send_tx_queue(bus);
+}
+
 int mctp_message_tx(struct mctp *mctp, mctp_eid_t eid,
 		void *msg, size_t msg_len)
 {
-	struct mctp_pktbuf *pkt, *tmp;
+	struct mctp_pktbuf *pkt;
 	struct mctp_hdr *hdr;
 	struct mctp_bus *bus;
 	size_t pkt_len, p;
@@ -353,27 +392,16 @@
 		memcpy(mctp_pktbuf_data(pkt), msg + p, pkt_len);
 
 		/* add to tx queue */
-		if (mctp->tx_queue_tail)
-			mctp->tx_queue_tail->next = pkt;
+		if (bus->tx_queue_tail)
+			bus->tx_queue_tail->next = pkt;
 		else
-			mctp->tx_queue_head = pkt;
-		mctp->tx_queue_tail = pkt;
+			bus->tx_queue_head = pkt;
+		bus->tx_queue_tail = pkt;
 
 		p += pkt_len;
 	}
 
-	/* send queued packets */
-	for (pkt = mctp->tx_queue_head; pkt;) {
-		mctp_prdebug("sending pkt, len %d",
-				mctp_pktbuf_size(pkt));
-		mctp_packet_tx(mctp, bus, pkt);
-		tmp = pkt->next;
-		mctp_pktbuf_free(pkt);
-		pkt = tmp;
-	}
-
-	mctp->tx_queue_tail = NULL;
-	mctp->tx_queue_head = NULL;
+	mctp_send_tx_queue(bus);
 
 	return 0;
 }
diff --git a/libmctp-log.h b/libmctp-log.h
index e24738a..1024913 100644
--- a/libmctp-log.h
+++ b/libmctp-log.h
@@ -34,11 +34,8 @@
 
 #elif defined(MCTP_LOG_CUSTOM)
 
-#include <config.h>
-
-#if !defined(mctp_prlog)
-#error Custom logging implementation enabled, but no definition for mctp_prlog
-#endif
+extern void mctp_prlog(int level, const char *fmt, ...)
+	__attribute__((format(printf, 2, 3)));
 
 
 #else
diff --git a/libmctp.h b/libmctp.h
index d1696a4..a47eb35 100644
--- a/libmctp.h
+++ b/libmctp.h
@@ -7,7 +7,9 @@
 extern "C" {
 #endif
 
+#include <stdbool.h>
 #include <stdint.h>
+#include <stddef.h>
 
 typedef uint8_t mctp_eid_t;
 
@@ -61,11 +63,15 @@
 
 /* MCTP core */
 struct mctp;
+struct mctp_bus;
 struct mctp_binding;
 
 struct mctp *mctp_init(void);
 
-unsigned long mctp_register_bus(struct mctp *mctp,
+/* Register a binding to the MCTP core, and creates a bus (populating
+ * binding->bus).
+ */
+int mctp_register_bus(struct mctp *mctp,
 		struct mctp_binding *binding,
 		mctp_eid_t eid);
 
@@ -81,12 +87,15 @@
 struct mctp_binding {
 	const char	*name;
 	uint8_t		version;
+	struct mctp_bus	*bus;
+	struct mctp	*mctp;
 	int		(*tx)(struct mctp_binding *binding,
 				struct mctp_pktbuf *pkt);
 };
 
-void mctp_bus_rx(struct mctp *mctp, unsigned long bus_id,
-		struct mctp_pktbuf *pkt);
+void mctp_binding_set_tx_enabled(struct mctp_binding *binding, bool enable);
+
+void mctp_bus_rx(struct mctp_binding *binding, struct mctp_pktbuf *pkt);
 
 /* environment-specific allocation */
 void mctp_set_alloc_ops(void *(*alloc)(size_t),
diff --git a/serial.c b/serial.c
index 87524f6..22c1b4b 100644
--- a/serial.c
+++ b/serial.c
@@ -19,7 +19,6 @@
 
 struct mctp_binding_serial {
 	struct mctp_binding	binding;
-	struct mctp		*mctp;
 	int			fd;
 	unsigned long		bus_id;
 
@@ -138,7 +137,7 @@
 	assert(pkt);
 
 	if (valid)
-		mctp_bus_rx(serial->mctp, serial->bus_id, pkt);
+		mctp_bus_rx(&serial->binding, pkt);
 
 	mctp_pktbuf_free(pkt);
 	serial->rx_pkt = NULL;
@@ -186,14 +185,8 @@
 			mctp_prdebug("invalid size %d", c);
 			serial->rx_state = STATE_WAIT_SYNC_START;
 		} else {
-			uint8_t *p;
-
 			mctp_serial_start_packet(serial, 0);
 			pkt = serial->rx_pkt;
-			p = mctp_pktbuf_alloc_start(pkt, 3);
-			p[0] = MCTP_SERIAL_FRAMING_FLAG;
-			p[1] = MCTP_SERIAL_REVISION;
-			p[2] = c;
 			serial->rx_exp_len = c;
 			serial->rx_state = STATE_DATA;
 		}
@@ -294,8 +287,8 @@
 		struct mctp *mctp, mctp_eid_t eid)
 {
 	assert(serial->fd >= 0);
-	serial->mctp = mctp;
-	serial->bus_id = mctp_register_bus(mctp, &serial->binding, eid);
+	mctp_register_bus(mctp, &serial->binding, eid);
+	mctp_binding_set_tx_enabled(&serial->binding, true);
 }
 
 struct mctp_binding_serial *mctp_serial_init(void)