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

greybus: control: add bundle-version operation



Add bundle-version operation to fetch the version of the bundle class.

Retrieve the bundle version of all bundles when initialising the
interface in case the control-protocol version is greater than 0.1.

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 96a9b9b0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -16,8 +16,12 @@
struct gb_bundle {
	struct device		dev;
	struct gb_interface	*intf;

	u8			id;
	u8			class;
	u8			class_major;
	u8			class_minor;

	struct list_head	connections;
	u8			*state;

+51 −0
Original line number Diff line number Diff line
@@ -54,6 +54,54 @@ int gb_control_get_version(struct gb_control *control)
	return 0;
}

static int gb_control_get_bundle_version(struct gb_control *control,
						struct gb_bundle *bundle)
{
	struct gb_interface *intf = control->connection->intf;
	struct gb_control_bundle_version_request request;
	struct gb_control_bundle_version_response response;
	int ret;

	request.bundle_id = bundle->id;

	ret = gb_operation_sync(control->connection,
				GB_CONTROL_TYPE_BUNDLE_VERSION,
				&request, sizeof(request),
				&response, sizeof(response));
	if (ret) {
		dev_err(&intf->dev,
				"failed to get bundle %u class version: %d\n",
				bundle->id, ret);
		return ret;
	}

	bundle->class_major = response.major;
	bundle->class_minor = response.minor;

	dev_dbg(&intf->dev, "%s - %u: %u.%u\n", __func__, bundle->id,
			response.major, response.minor);

	return 0;
}

int gb_control_get_bundle_versions(struct gb_control *control)
{
	struct gb_interface *intf = control->connection->intf;
	struct gb_bundle *bundle;
	int ret;

	if (!control->has_bundle_version)
		return 0;

	list_for_each_entry(bundle, &intf->bundles, links) {
		ret = gb_control_get_bundle_version(control, bundle);
		if (ret)
			return ret;
	}

	return 0;
}

/* Get Manifest's size from the interface */
int gb_control_get_manifest_size_operation(struct gb_interface *intf)
{
@@ -170,6 +218,9 @@ int gb_control_enable(struct gb_control *control)
	if (ret)
		goto err_disable_connection;

	if (control->protocol_major > 0 || control->protocol_minor > 1)
		control->has_bundle_version = true;

	return 0;

err_disable_connection:
+3 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ struct gb_control {

	u8 protocol_major;
	u8 protocol_minor;

	bool has_bundle_version;
};

struct gb_control *gb_control_create(struct gb_interface *intf);
@@ -22,6 +24,7 @@ int gb_control_enable(struct gb_control *control);
void gb_control_disable(struct gb_control *control);
void gb_control_destroy(struct gb_control *control);

int gb_control_get_bundle_versions(struct gb_control *control);
int gb_control_connected_operation(struct gb_control *control, u16 cport_id);
int gb_control_disconnected_operation(struct gb_control *control, u16 cport_id);
int gb_control_get_manifest_size_operation(struct gb_interface *intf);
+10 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ struct gb_protocol_version_response {
#define GB_CONTROL_TYPE_CONNECTED		0x05
#define GB_CONTROL_TYPE_DISCONNECTED		0x06
#define GB_CONTROL_TYPE_INTERFACE_VERSION	0x0a
#define GB_CONTROL_TYPE_BUNDLE_VERSION		0x0b

struct gb_control_version_request {
	__u8	major;
@@ -134,6 +135,15 @@ struct gb_control_version_response {
	__u8	minor;
} __packed;

struct gb_control_bundle_version_request {
	__u8	bundle_id;
} __packed;

struct gb_control_bundle_version_response {
	__u8	major;
	__u8	minor;
} __packed;

/* Control protocol manifest get size request has no payload*/
struct gb_control_get_manifest_size_response {
	__le16			size;
+4 −0
Original line number Diff line number Diff line
@@ -228,6 +228,10 @@ int gb_interface_init(struct gb_interface *intf, u8 device_id)
	if (ret)
		goto free_manifest;

	ret = gb_control_get_bundle_versions(intf->control);
	if (ret)
		goto free_manifest;

	/* Register the interface and its bundles. */
	ret = device_add(&intf->dev);
	if (ret) {