From 025acf659431d5316a54fe34d6f0e0ebf13c08af Mon Sep 17 00:00:00 2001
From: Alexandre Bailon <abailon@baylibre.com>
Date: Thu, 9 Mar 2017 22:06:35 +0100
Subject: [PATCH] controller: Use interface and cport id to get a connection

In order to make controller more generic, use interface id
and cport id to get a pointer to connection.

Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 controller.c | 74 +++++++++++++++++++++++++++-------------------------
 controller.h |  3 ++-
 netlink.c    |  6 ++---
 3 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/controller.c b/controller.c
index 3036f72..ff75668 100644
--- a/controller.c
+++ b/controller.c
@@ -92,51 +92,52 @@ int read_gb_msg(int fd, void *data, size_t max_len)
 	return gb_operation_msg_size(data);
 }
 
-static struct connection *cport_id_to_connection(struct interface *intf,
-						 uint16_t cport2_id)
+int hd_to_intf_cport_id(uint16_t hd_cport_id,
+			uint8_t *intf_id, uint16_t *cport_id)
 {
 	struct connection *conn;
 
+	if (hd_cport_id == SVC_CPORT) {
+		*intf_id = 0;
+		*cport_id = 0;
+		return 0;
+	}
+
 	TAILQ_FOREACH(conn, &connections, node) {
-		if (conn->intf2 == intf && conn->cport2_id == cport2_id)
-			return conn;
+		if (conn->cport1_id == hd_cport_id) {
+			*intf_id = conn->intf2->id;
+			*cport_id = conn->cport2_id;
+			return 0;
+		}
 	}
 
-	return NULL;
+	return -EINVAL;
 }
 
-static struct connection *hd_cport_id_to_connection(uint16_t cport_id)
+static struct connection *_get_connection(struct interface *intf,
+					  uint16_t cport_id)
 {
 	struct connection *conn;
 
 	TAILQ_FOREACH(conn, &connections, node) {
-		if (conn->cport1_id == cport_id)
+		if (conn->intf1 == intf && conn->cport1_id == cport_id)
+			return conn;
+		if (conn->intf2 == intf && conn->cport2_id == cport_id)
 			return conn;
 	}
 
 	return NULL;
 }
 
-int hd_to_intf_cport_id(uint16_t hd_cport_id,
-			uint8_t *intf_id, uint16_t *cport_id)
+static struct connection *get_connection(uint8_t intf_id, uint16_t cport_id)
 {
-	struct connection *conn;
-
-	if (hd_cport_id == SVC_CPORT) {
-		*intf_id = 0;
-		*cport_id = 0;
-		return 0;
-	}
+	struct interface *intf;
 
-	TAILQ_FOREACH(conn, &connections, node) {
-		if (conn->cport1_id == hd_cport_id) {
-			*intf_id = conn->intf2->id;
-			*cport_id = conn->cport2_id;
-			return 0;
-		}
-	}
+	intf = get_interface(intf_id);
+	if (!intf)
+		return NULL;
 
-	return -EINVAL;
+	return _get_connection(intf, cport_id);
 }
 
 static void *interface_recv(void *data)
@@ -157,7 +158,7 @@ static void *interface_recv(void *data)
 
 		pr_dump(buffer, ret);
 
-		conn = cport_id_to_connection(intf, cport_id);
+		conn = _get_connection(intf, cport_id);
 		if (!conn) {
 			pr_err("Received data on invalid cport number\n");
 			continue;
@@ -363,20 +364,17 @@ int
 connection_destroy(uint8_t intf1_id, uint16_t cport1_id,
 		   uint8_t intf2_id, uint16_t cport2_id)
 {
-	struct interface *intf;
+	struct interface *intf2;
 	struct connection *conn;
 	struct controller *ctrl;
 
-	intf = get_interface(intf2_id);
-	if (!intf)
-		return -EINVAL;
-
-	conn = hd_cport_id_to_connection(cport1_id);
+	conn = get_connection(intf1_id, cport1_id);
 	if (!conn) {
 		return -EINVAL;
 	}
 
-	ctrl = intf->ctrl;
+	intf2 = conn->intf2;
+	ctrl = intf2->ctrl;
 	if (ctrl->connection_destroy)
 		ctrl->connection_destroy(conn);
 
@@ -430,18 +428,24 @@ static void controller_loop_exit(struct controller *ctrl)
 	pthread_join(ctrl->thread, NULL);
 }
 
-int controller_write(uint16_t cport_id, void *data, size_t len)
+int controller_write(uint8_t intf_id, uint16_t cport_id,
+		     void *data, size_t len)
 {
 	struct connection *conn;
 	struct controller *ctrl;
+	struct interface *intf;
+
+	intf = get_interface(intf_id);
+	if (!intf)
+		return -EINVAL;
 
-	conn = hd_cport_id_to_connection(cport_id);
+	conn = _get_connection(intf, cport_id);
 	if (!conn)
 		return -EINVAL;
 
 	pr_dump(data, len);
 
-	ctrl = conn->intf2->ctrl;
+	ctrl = intf->ctrl;
 	return ctrl->write(conn, data, len);
 }
 
diff --git a/controller.h b/controller.h
index dfcdf24..14748c5 100644
--- a/controller.h
+++ b/controller.h
@@ -99,7 +99,8 @@ int connection_create(uint8_t intf1_id, uint16_t cport1_id,
 int connection_destroy(uint8_t intf1_id, uint16_t cport1_id,
 		       uint8_t intf2_id, uint16_t cport2_id);
 
-int controller_write(uint16_t cport_id, void *data, size_t len);
+int controller_write(uint8_t intf_id, uint16_t cport_id,
+		     void *data, size_t len);
 void controllers_init(void);
 void controllers_exit(void);
 void register_controller(struct controller *controller);
diff --git a/netlink.c b/netlink.c
index 43c8a32..f8ae29c 100644
--- a/netlink.c
+++ b/netlink.c
@@ -57,8 +57,8 @@ parse_gb_nl_msg(struct nl_cache_ops *unused, struct genl_cmd *cmd,
 		return -EPROTO;
 	}
 
+	hd_to_intf_cport_id(hd_cport_id, &intf_id, &cport_id);
 	if (hd_cport_id == SVC_CPORT) {
-		hd_to_intf_cport_id(hd_cport_id, &intf_id, &cport_id);
 		ret = greybus_handler(intf_id, cport_id, hdr);
 		if (ret) {
 			pr_err("Failed to handle svc operation %d: %d\n",
@@ -66,8 +66,8 @@ parse_gb_nl_msg(struct nl_cache_ops *unused, struct genl_cmd *cmd,
 		}
 	} else {
 		ret =
-		    controller_write(hd_cport_id, hdr,
-				     gb_operation_msg_size(hdr));
+		    controller_write(intf_id, cport_id,
+				     hdr, gb_operation_msg_size(hdr));
 	}
 
 	return 0;
-- 
GitLab