1
0
Fork 0

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: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
hifive-unleashed-5.1
Johan Hovold 2016-01-19 12:51:21 +01:00 committed by Greg Kroah-Hartman
parent 96a9b9b0eb
commit b807aa7aa5
5 changed files with 72 additions and 0 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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) {