API: Add binding accessors to generic struct mctp_binding

Rather than have every binding include their own wrappers around
binding<->core functions, introduce an accessor to retrieve the struct
mctp_binding from each.

This means we no longer need the binding-specific registration
callbacks. However, we do now need a ->start callback, to allow bindings
to perform post-registration init.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Change-Id: I6cee9e93f37520f85c155a0ca34017cc0675552c
diff --git a/README.md b/README.md
index 50519e3..0079a2f 100644
--- a/README.md
+++ b/README.md
@@ -46,6 +46,40 @@
 Note that no EIDs are defined here; the bridge does not deliver any messages
 to a local rx callback, and messages are bridged as-is.
 
+Binding API
+-----------
+
+Hardware bindings provide a method for libmctp to send and receive packets
+to/from hardware. A binding defines a hardware specific structure (`struct
+mctp_binding_<name>`), which wraps the generic binding (`struct mctp_binding`):
+
+    struct mctp_binding_foo {
+	    struct mctp_binding binding;
+	    /* hardware-specific members here... */
+    };
+
+The binding code then provides a method (`_init`) to allocate and initialise
+the binding; this may be of any prototype (calling code will know what
+arguments to pass):
+
+    struct mctp_binding_foo *mctp_binding_foo_init(void);
+
+or maybe the `foo` binding needs a path argument:
+
+    struct mctp_binding_foo *mctp_binding_foo_init(const char *path);
+
+The binding then needs to provide a function (`_core`) to convert the
+hardware-specific struct to the libmctp generic core struct
+
+    struct mctp_binding *mctp_binding_foo_core(struct mctp_binding_foo *b);
+
+(Implementations of this will usually be fairly consistent, just returning
+`b->binding`). Callers can then use that generic pointer to register the
+binding with the core:
+
+    struct mctp_binding *binding = mctp_binding_foo_core(foo);
+    mctp_register_bus(mctp, binding, 8);
+
 
 Integration
 -----------
diff --git a/astlpc.c b/astlpc.c
index 4e6485c..cf75534 100644
--- a/astlpc.c
+++ b/astlpc.c
@@ -298,12 +298,6 @@
 	return 0;
 }
 
-void mctp_astlpc_register_bus(struct mctp_binding_astlpc *astlpc,
-		struct mctp *mctp, mctp_eid_t eid)
-{
-	mctp_register_bus(mctp, &astlpc->binding, eid);
-}
-
 static int mctp_astlpc_init_bmc(struct mctp_binding_astlpc *astlpc)
 {
 	struct mctp_lpcmap_hdr *hdr;
@@ -355,6 +349,11 @@
 	return astlpc;
 }
 
+struct mctp_binding *mctp_binding_astlpc_core(struct mctp_binding_astlpc *b)
+{
+	return &b->binding;
+}
+
 struct mctp_binding_astlpc *mctp_astlpc_init_ops(
 		struct mctp_binding_astlpc_ops *ops,
 		void *ops_data, void *lpc_map)
diff --git a/core.c b/core.c
index e0cb95d..61356e9 100644
--- a/core.c
+++ b/core.c
@@ -257,6 +257,10 @@
 	binding->bus = &mctp->busses[0];
 	binding->mctp = mctp;
 	mctp->route_policy = ROUTE_ENDPOINT;
+
+	if (binding->start)
+		binding->start(binding);
+
 	return 0;
 }
 
@@ -274,6 +278,13 @@
 	b2->mctp = mctp;
 
 	mctp->route_policy = ROUTE_BRIDGE;
+
+	if (b1->start)
+		b1->start(b1);
+
+	if (b2->start)
+		b2->start(b2);
+
 	return 0;
 }
 
diff --git a/libmctp-astlpc.h b/libmctp-astlpc.h
index 81f3b1b..92510c6 100644
--- a/libmctp-astlpc.h
+++ b/libmctp-astlpc.h
@@ -29,8 +29,9 @@
 struct mctp_binding_astlpc *mctp_astlpc_init_ops(
 		struct mctp_binding_astlpc_ops *ops,
 		void *ops_data, void *lpc_map);
-void mctp_astlpc_register_bus(struct mctp_binding_astlpc *astlpc,
-		struct mctp *mctp, mctp_eid_t eid);
+
+struct mctp_binding *mctp_binding_astlpc_core(struct mctp_binding_astlpc *b);
+
 int mctp_astlpc_poll(struct mctp_binding_astlpc *astlpc);
 
 /* fileio-based interface */
diff --git a/libmctp-serial.h b/libmctp-serial.h
index 5504864..5eaf948 100644
--- a/libmctp-serial.h
+++ b/libmctp-serial.h
@@ -13,8 +13,7 @@
 
 struct mctp_binding_serial *mctp_serial_init(void);
 
-void mctp_serial_register_bus(struct mctp_binding_serial *serial,
-		struct mctp *mctp, mctp_eid_t eid);
+struct mctp_binding *mctp_binding_serial_core(struct mctp_binding_serial *b);
 
 /* file-based IO */
 int mctp_serial_get_fd(struct mctp_binding_serial *serial);
diff --git a/libmctp.h b/libmctp.h
index 523891f..b36a943 100644
--- a/libmctp.h
+++ b/libmctp.h
@@ -97,6 +97,7 @@
 	struct mctp	*mctp;
 	int		pkt_size;
 	int		pkt_pad;
+	int		(*start)(struct mctp_binding *binding);
 	int		(*tx)(struct mctp_binding *binding,
 				struct mctp_pktbuf *pkt);
 };
diff --git a/serial.c b/serial.c
index f673a52..781a9c1 100644
--- a/serial.c
+++ b/serial.c
@@ -312,12 +312,15 @@
 	mctp_rx_consume(serial, buf, len);
 }
 
-void mctp_serial_register_bus(struct mctp_binding_serial *serial,
-		struct mctp *mctp, mctp_eid_t eid)
+static int mctp_serial_core_start(struct mctp_binding *binding)
 {
-	assert(serial->fd >= 0);
-	mctp_register_bus(mctp, &serial->binding, eid);
-	mctp_binding_set_tx_enabled(&serial->binding, true);
+	mctp_binding_set_tx_enabled(binding, true);
+	return 0;
+}
+
+struct mctp_binding *mctp_binding_serial_core(struct mctp_binding_serial *b)
+{
+	return &b->binding;
 }
 
 struct mctp_binding_serial *mctp_serial_init(void)
@@ -334,6 +337,7 @@
 	serial->binding.pkt_size = MCTP_BMTU;
 	serial->binding.pkt_pad = 0;
 
+	serial->binding.start = mctp_serial_core_start;
 	serial->binding.tx = mctp_binding_serial_tx;
 
 	return serial;
diff --git a/utils/mctp-demux-daemon.c b/utils/mctp-demux-daemon.c
index f64f029..96d9753 100644
--- a/utils/mctp-demux-daemon.c
+++ b/utils/mctp-demux-daemon.c
@@ -145,7 +145,7 @@
 	if (rc)
 		return -1;
 
-	mctp_serial_register_bus(serial, mctp, eid);
+	mctp_register_bus(mctp, mctp_binding_serial_core(serial), eid);
 
 	binding->data = serial;
 
@@ -179,7 +179,8 @@
 		return -1;
 	}
 
-	mctp_astlpc_register_bus(astlpc, mctp, eid);
+	mctp_register_bus(mctp, mctp_binding_astlpc_core(astlpc), eid);
+
 	binding->data = astlpc;
 	return 0;
 }