From 50bb9ccaa0e12823e7f225ce1571d4ae3d1f83e0 Mon Sep 17 00:00:00 2001
From: Fabien Parent <fparent@baylibre.com>
Date: Mon, 31 Aug 2015 17:21:14 +0530
Subject: [PATCH] greybus: connection: fail to bind if connection init fails

gb_connection_init() can fail and will return proper error code in that
case, but the caller is ignoring it currently.

Fix that by properly handling errors returned from gb_connection_init()
and propagating them to callers of gb_connection_bind_protocol().

Signed-off-by: Fabien Parent <fparent@baylibre.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
---
 drivers/staging/greybus/connection.c | 19 ++++++++++++++-----
 drivers/staging/greybus/connection.h |  2 +-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c
index 29870536aa2f..d0642bcd7600 100644
--- a/drivers/staging/greybus/connection.c
+++ b/drivers/staging/greybus/connection.c
@@ -451,19 +451,20 @@ void gb_hd_connections_exit(struct greybus_host_device *hd)
 		gb_connection_destroy(connection);
 }
 
-void gb_connection_bind_protocol(struct gb_connection *connection)
+int gb_connection_bind_protocol(struct gb_connection *connection)
 {
 	struct gb_protocol *protocol;
+	int ret;
 
 	/* If we already have a protocol bound here, just return */
 	if (connection->protocol)
-		return;
+		return 0;
 
 	protocol = gb_protocol_get(connection->protocol_id,
 				   connection->major,
 				   connection->minor);
 	if (!protocol)
-		return;
+		return 0;
 	connection->protocol = protocol;
 
 	/*
@@ -472,6 +473,14 @@ void gb_connection_bind_protocol(struct gb_connection *connection)
 	 */
 	if ((!connection->bundle &&
 	     connection->hd_cport_id == GB_SVC_CPORT_ID) ||
-	    connection->bundle->intf->device_id != GB_DEVICE_ID_BAD)
-		gb_connection_init(connection);
+	    connection->bundle->intf->device_id != GB_DEVICE_ID_BAD) {
+		ret = gb_connection_init(connection);
+		if (ret) {
+			gb_protocol_put(protocol);
+			connection->protocol = NULL;
+			return ret;
+		}
+	}
+
+	return 0;
 }
diff --git a/drivers/staging/greybus/connection.h b/drivers/staging/greybus/connection.h
index 0b442fe61b87..e3ae01dcfd82 100644
--- a/drivers/staging/greybus/connection.h
+++ b/drivers/staging/greybus/connection.h
@@ -68,6 +68,6 @@ void gb_connection_push_timestamp(struct gb_connection *connection);
 int gb_connection_pop_timestamp(struct gb_connection *connection,
 				struct timeval *tv);
 
-void gb_connection_bind_protocol(struct gb_connection *connection);
+int gb_connection_bind_protocol(struct gb_connection *connection);
 
 #endif /* __CONNECTION_H */