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

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

greybus: svc: refactor interface-route creation



Add interface-route-create helper to allocate an interface device id and
setup the route.

Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Reviewed-by: default avatarJeffrey Carlyle <jcarlyle@google.com>
Reviewed-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 60269b95
Loading
Loading
Loading
Loading
+1 −3
Original line number Original line Diff line number Diff line
@@ -186,14 +186,12 @@ void gb_interfaces_remove(struct gb_host_device *hd)
 * Finally initialize all the bundles to set routes via SVC and initialize all
 * Finally initialize all the bundles to set routes via SVC and initialize all
 * connections.
 * connections.
 */
 */
int gb_interface_init(struct gb_interface *intf, u8 device_id)
int gb_interface_init(struct gb_interface *intf)
{
{
	struct gb_bundle *bundle, *tmp;
	struct gb_bundle *bundle, *tmp;
	int ret, size;
	int ret, size;
	void *manifest;
	void *manifest;


	intf->device_id = device_id;

	/* Establish control connection */
	/* Establish control connection */
	ret = gb_control_enable(intf->control);
	ret = gb_control_enable(intf->control);
	if (ret)
	if (ret)
+1 −1
Original line number Original line Diff line number Diff line
@@ -47,7 +47,7 @@ struct gb_interface *gb_interface_find(struct gb_host_device *hd,


struct gb_interface *gb_interface_create(struct gb_host_device *hd,
struct gb_interface *gb_interface_create(struct gb_host_device *hd,
					 u8 interface_id);
					 u8 interface_id);
int gb_interface_init(struct gb_interface *intf, u8 device_id);
int gb_interface_init(struct gb_interface *intf);
void gb_interface_remove(struct gb_interface *intf);
void gb_interface_remove(struct gb_interface *intf);
void gb_interfaces_remove(struct gb_host_device *hd);
void gb_interfaces_remove(struct gb_host_device *hd);


+62 −44
Original line number Original line Diff line number Diff line
@@ -463,6 +463,61 @@ static int gb_svc_hello(struct gb_operation *op)
	return 0;
	return 0;
}
}


static int gb_svc_interface_route_create(struct gb_svc *svc,
						struct gb_interface *intf)
{
	u8 intf_id = intf->interface_id;
	u8 device_id;
	int ret;

	/*
	 * Create a device id for the interface:
	 * - device id 0 (GB_DEVICE_ID_SVC) belongs to the SVC
	 * - device id 1 (GB_DEVICE_ID_AP) belongs to the AP
	 *
	 * XXX Do we need to allocate device ID for SVC or the AP here? And what
	 * XXX about an AP with multiple interface blocks?
	 */
	ret = ida_simple_get(&svc->device_id_map,
			     GB_DEVICE_ID_MODULES_START, 0, GFP_KERNEL);
	if (ret < 0) {
		dev_err(&svc->dev, "failed to allocate device id for interface %u: %d\n",
				intf_id, ret);
		return ret;
	}
	device_id = ret;

	ret = gb_svc_intf_device_id(svc, intf_id, device_id);
	if (ret) {
		dev_err(&svc->dev, "failed to set device id %u for interface %u: %d\n",
				device_id, intf_id, ret);
		goto err_ida_remove;
	}

	/* Create a two-way route between the AP and the new interface. */
	ret = gb_svc_route_create(svc, svc->ap_intf_id, GB_DEVICE_ID_AP,
				  intf_id, device_id);
	if (ret) {
		dev_err(&svc->dev, "failed to create route to interface %u (device id %u): %d\n",
				intf_id, device_id, ret);
		goto err_svc_id_free;
	}

	intf->device_id = device_id;

	return 0;

err_svc_id_free:
	/*
	 * XXX Should we tell SVC that this id doesn't belong to interface
	 * XXX anymore.
	 */
err_ida_remove:
	ida_simple_remove(&svc->device_id_map, device_id);

	return ret;
}

static void gb_svc_intf_remove(struct gb_svc *svc, struct gb_interface *intf)
static void gb_svc_intf_remove(struct gb_svc *svc, struct gb_interface *intf)
{
{
	u8 intf_id = intf->interface_id;
	u8 intf_id = intf->interface_id;
@@ -487,7 +542,7 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
	struct gb_svc *svc = connection->private;
	struct gb_svc *svc = connection->private;
	struct gb_host_device *hd = connection->hd;
	struct gb_host_device *hd = connection->hd;
	struct gb_interface *intf;
	struct gb_interface *intf;
	u8 intf_id, device_id;
	u8 intf_id;
	u32 vendor_id = 0;
	u32 vendor_id = 0;
	u32 product_id = 0;
	u32 product_id = 0;
	int ret;
	int ret;
@@ -561,45 +616,14 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)
		goto destroy_interface;
		goto destroy_interface;
	}
	}


	/*
	ret = gb_svc_interface_route_create(svc, intf);
	 * Create a device id for the interface:
	if (ret)
	 * - device id 0 (GB_DEVICE_ID_SVC) belongs to the SVC
	 * - device id 1 (GB_DEVICE_ID_AP) belongs to the AP
	 *
	 * XXX Do we need to allocate device ID for SVC or the AP here? And what
	 * XXX about an AP with multiple interface blocks?
	 */
	device_id = ida_simple_get(&svc->device_id_map,
				   GB_DEVICE_ID_MODULES_START, 0, GFP_KERNEL);
	if (device_id < 0) {
		ret = device_id;
		dev_err(&svc->dev, "failed to allocate device id for interface %u: %d\n",
				intf_id, ret);
		goto destroy_interface;
		goto destroy_interface;
	}


	ret = gb_svc_intf_device_id(svc, intf_id, device_id);
	ret = gb_interface_init(intf);
	if (ret) {
	if (ret) {
		dev_err(&svc->dev, "failed to set device id %u for interface %u: %d\n",
		dev_err(&svc->dev, "failed to initialize interface %u: %d\n",
				device_id, intf_id, ret);
				intf_id, ret);
		goto ida_put;
	}

	/*
	 * Create a two-way route between the AP and the new interface
	 */
	ret = gb_svc_route_create(svc, svc->ap_intf_id, GB_DEVICE_ID_AP,
				  intf_id, device_id);
	if (ret) {
		dev_err(&svc->dev, "failed to create route to interface %u (device id %u): %d\n",
				intf_id, device_id, ret);
		goto svc_id_free;
	}

	ret = gb_interface_init(intf, device_id);
	if (ret) {
		dev_err(&svc->dev, "failed to initialize interface %u (device id %u): %d\n",
				intf_id, device_id, ret);
		goto destroy_route;
		goto destroy_route;
	}
	}


@@ -607,13 +631,7 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation)


destroy_route:
destroy_route:
	gb_svc_route_destroy(svc, svc->ap_intf_id, intf_id);
	gb_svc_route_destroy(svc, svc->ap_intf_id, intf_id);
svc_id_free:
	ida_simple_remove(&svc->device_id_map, intf->device_id);
	/*
	 * XXX Should we tell SVC that this id doesn't belong to interface
	 * XXX anymore.
	 */
ida_put:
	ida_simple_remove(&svc->device_id_map, device_id);
destroy_interface:
destroy_interface:
	gb_interface_remove(intf);
	gb_interface_remove(intf);
}
}