greybus: connection: return error-valued pointer on creation errors
authorJohan Hovold <johan@hovoldconsulting.com>
Thu, 21 Jan 2016 16:34:16 +0000 (17:34 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Fri, 22 Jan 2016 06:45:09 +0000 (22:45 -0800)
Return an ERR_PTR on errors when creating connections.

This allows driver probe to fail with a more informative error message
as not all connection creation errors are due to memory exhaustion.

Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/connection.c
drivers/staging/greybus/control.c
drivers/staging/greybus/legacy.c
drivers/staging/greybus/svc.c

index 5d0edbe..99efe31 100644 (file)
@@ -129,7 +129,8 @@ static void gb_connection_init_name(struct gb_connection *connection)
  * Serialised against concurrent create and destroy using the
  * gb_connection_mutex.
  *
- * Return: A pointer to the new connection if successful, or NULL otherwise.
+ * Return: A pointer to the new connection if successful, or an ERR_PTR
+ * otherwise.
  */
 static struct gb_connection *
 _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
@@ -139,6 +140,7 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
        struct gb_connection *connection;
        struct ida *id_map = &hd->cport_id_map;
        int ida_start, ida_end;
+       int ret;
 
        if (hd_cport_id < 0) {
                ida_start = 0;
@@ -148,23 +150,27 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
                ida_end = hd_cport_id + 1;
        } else {
                dev_err(&hd->dev, "cport %d not available\n", hd_cport_id);
-               return NULL;
+               return ERR_PTR(-EINVAL);
        }
 
        mutex_lock(&gb_connection_mutex);
 
        if (intf && gb_connection_intf_find(intf, cport_id)) {
                dev_err(&intf->dev, "cport %u already in use\n", cport_id);
+               ret = -EBUSY;
                goto err_unlock;
        }
 
-       hd_cport_id = ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
-       if (hd_cport_id < 0)
+       ret = ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
+       if (ret < 0)
                goto err_unlock;
+       hd_cport_id = ret;
 
        connection = kzalloc(sizeof(*connection), GFP_KERNEL);
-       if (!connection)
+       if (!connection) {
+               ret = -ENOMEM;
                goto err_remove_ida;
+       }
 
        connection->hd_cport_id = hd_cport_id;
        connection->intf_cport_id = cport_id;
@@ -181,8 +187,10 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
 
        connection->wq = alloc_workqueue("%s:%d", WQ_UNBOUND, 1,
                                         dev_name(&hd->dev), hd_cport_id);
-       if (!connection->wq)
+       if (!connection->wq) {
+               ret = -ENOMEM;
                goto err_free_connection;
+       }
 
        kref_init(&connection->kref);
 
@@ -209,7 +217,7 @@ err_remove_ida:
 err_unlock:
        mutex_unlock(&gb_connection_mutex);
 
-       return NULL;
+       return ERR_PTR(ret);
 }
 
 struct gb_connection *
index a766ec8..fb0bb1c 100644 (file)
@@ -187,8 +187,10 @@ struct gb_control *gb_control_create(struct gb_interface *intf)
                return NULL;
 
        control->connection = gb_connection_create_control(intf);
-       if (!control->connection) {
-               dev_err(&intf->dev, "failed to create control connection\n");
+       if (IS_ERR(control->connection)) {
+               dev_err(&intf->dev,
+                               "failed to create control connection: %ld\n",
+                               PTR_ERR(control->connection));
                kfree(control);
                return NULL;
        }
index fb0a82e..fc19b8b 100644 (file)
@@ -133,7 +133,7 @@ static int legacy_probe(struct gb_bundle *bundle,
        struct legacy_data *data;
        struct gb_connection *connection;
        int i;
-       int ret = -ENOMEM;
+       int ret;
 
        dev_dbg(&bundle->dev,
                        "%s - bundle class = 0x%02x, num_cports = %zu\n",
@@ -147,16 +147,20 @@ static int legacy_probe(struct gb_bundle *bundle,
        data->connections = kcalloc(data->num_cports,
                                                sizeof(*data->connections),
                                                GFP_KERNEL);
-       if (!data->connections)
+       if (!data->connections) {
+               ret = -ENOMEM;
                goto err_free_data;
+       }
 
        for (i = 0; i < data->num_cports; ++i) {
                cport_desc = &bundle->cport_desc[i];
 
                connection = gb_connection_create(bundle,
                                                le16_to_cpu(cport_desc->id));
-               if (!connection)
+               if (IS_ERR(connection)) {
+                       ret = PTR_ERR(connection);
                        goto err_connections_destroy;
+               }
 
                connection->protocol_id = cport_desc->protocol_id;
 
index 472997e..845f82d 100644 (file)
@@ -896,8 +896,9 @@ struct gb_svc *gb_svc_create(struct gb_host_device *hd)
        }
 
        svc->connection = gb_connection_create_static(hd, GB_SVC_CPORT_ID);
-       if (!svc->connection) {
-               dev_err(&svc->dev, "failed to create connection\n");
+       if (IS_ERR(svc->connection)) {
+               dev_err(&svc->dev, "failed to create connection: %ld\n",
+                               PTR_ERR(svc->connection));
                goto err_free_input;
        }