Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24e094d6 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

greybus: connection: return error-valued pointer on creation errors



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: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 96c2af5c
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -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 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
err_unlock:
	mutex_unlock(&gb_connection_mutex);

	return NULL;
	return ERR_PTR(ret);
}

struct gb_connection *
+4 −2
Original line number Diff line number Diff line
@@ -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;
	}
+7 −3
Original line number Diff line number Diff line
@@ -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;

+3 −2
Original line number Diff line number Diff line
@@ -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;
	}