1
0
Fork 0

greybus: manifest: Use interface descriptor instead of module descriptor to get information

A module can have more than one interfaces and we get hotplug events or
manifests for interfaces, not modules. Details like version, vendor,
product id, etc. can be different for different interfaces within the
same module and so shall be fetched from interface descriptor instead of
module descriptor.

So what we have been doing for module descriptors until now must be done
for interface descriptors. There can only be one interface descriptor in
the manifest. Module descriptor isn't used anymore and probably most of
its fields can be removed now.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
hifive-unleashed-5.1
Viresh Kumar 2015-04-01 20:32:02 +05:30 committed by Greg Kroah-Hartman
parent bb97ea813b
commit a93db2d1f6
5 changed files with 35 additions and 37 deletions

View File

@ -1,5 +1,5 @@
/*
* Greybus module manifest definition
* Greybus manifest definition
*
* See "Greybus Application Protocol" document (version 0.1) for
* details on these values and structures.
@ -94,19 +94,16 @@ struct greybus_descriptor_string {
};
/*
* An interface descriptor simply defines a module-unique id for
* each interface present on a module. Its sole purpose is to allow
* CPort descriptors to specify which interface they are associated
* with. Normally there's only one interface, with id 0. The
* second one must have id 1, and so on consecutively.
*
* The largest CPort id associated with an interface (defined by a
* CPort descriptor in the manifest) is used to determine how to
* encode the device id and module number in UniPro packets
* that use the interface.
* An interface descriptor describes information about an interface as a whole,
* *not* the functions within it.
*/
struct greybus_descriptor_interface {
__u8 id; /* module-relative id (0..) */
__le16 vendor;
__le16 product;
__le16 version; // TODO - remove after Dec demo.
__u8 vendor_stringid;
__u8 product_stringid;
__le64 unique_id;
};
/*

View File

@ -197,7 +197,7 @@ static void gb_interface_destroy(struct gb_interface *intf)
/**
* gb_add_interface
*
* Pass in a buffer that _should_ contain a Greybus module manifest
* Pass in a buffer that _should_ contain a Greybus manifest
* and register a greybus device structure with the kernel core.
*/
void gb_add_interface(struct greybus_host_device *hd, u8 interface_id, u8 *data,

View File

@ -19,7 +19,7 @@ struct gb_interface {
struct list_head manifest_descs;
u8 interface_id; /* Physical location within the Endo */
/* Information taken from the manifest module descriptor */
/* Information taken from the manifest descriptor */
u16 vendor;
u16 product;
char *vendor_string;

View File

@ -1,5 +1,5 @@
/*
* Greybus module manifest parsing
* Greybus manifest parsing
*
* Copyright 2014-2015 Google Inc.
* Copyright 2014-2015 Linaro Ltd.
@ -40,7 +40,7 @@ static const char *get_descriptor_type_string(u8 type)
* We scan the manifest once to identify where all the descriptors
* are. The result is a list of these manifest_desc structures. We
* then pick through them for what we're looking for (starting with
* the module descriptor). As each is processed we remove it from
* the interface descriptor). As each is processed we remove it from
* the list. When we're done the list should (probably) be empty.
*/
struct manifest_desc {
@ -107,6 +107,7 @@ static int identify_descriptor(struct gb_interface *intf,
expected_size += desc->string.length;
break;
case GREYBUS_TYPE_INTERFACE:
expected_size += sizeof(struct greybus_descriptor_interface);
break;
case GREYBUS_TYPE_BUNDLE:
expected_size += sizeof(struct greybus_descriptor_bundle);
@ -282,28 +283,28 @@ static u32 gb_manifest_parse_bundles(struct gb_interface *intf)
return count;
}
static bool gb_manifest_parse_module(struct gb_interface *intf,
struct manifest_desc *module_desc)
static bool gb_manifest_parse_interface(struct gb_interface *intf,
struct manifest_desc *interface_desc)
{
struct greybus_descriptor_module *desc_module = module_desc->data;
struct greybus_descriptor_interface *desc_intf = interface_desc->data;
/* Handle the strings first--they can fail */
intf->vendor_string = gb_string_get(intf, desc_module->vendor_stringid);
intf->vendor_string = gb_string_get(intf, desc_intf->vendor_stringid);
if (IS_ERR(intf->vendor_string))
return false;
intf->product_string = gb_string_get(intf,
desc_module->product_stringid);
desc_intf->product_stringid);
if (IS_ERR(intf->product_string)) {
goto out_free_vendor_string;
}
intf->vendor = le16_to_cpu(desc_module->vendor);
intf->product = le16_to_cpu(desc_module->product);
intf->unique_id = le64_to_cpu(desc_module->unique_id);
intf->vendor = le16_to_cpu(desc_intf->vendor);
intf->product = le16_to_cpu(desc_intf->product);
intf->unique_id = le64_to_cpu(desc_intf->unique_id);
/* Release the module descriptor, now that we're done with it */
release_manifest_descriptor(module_desc);
/* Release the interface descriptor, now that we're done with it */
release_manifest_descriptor(interface_desc);
/* An interface must have at least one bundle descriptor */
if (!gb_manifest_parse_bundles(intf)) {
@ -323,7 +324,7 @@ out_free_vendor_string:
}
/*
* Parse a buffer containing a module manifest.
* Parse a buffer containing a Interface manifest.
*
* If we find anything wrong with the content/format of the buffer
* we reject it.
@ -335,7 +336,7 @@ out_free_vendor_string:
* the descriptors it contains, keeping track for each its type
* and the location size of its data in the buffer.
*
* Next we scan the descriptors, looking for a module descriptor;
* Next we scan the descriptors, looking for a interface descriptor;
* there must be exactly one of those. When found, we record the
* information it contains, and then remove that descriptor (and any
* string descriptors it refers to) from further consideration.
@ -351,7 +352,7 @@ bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size)
struct greybus_manifest_header *header;
struct greybus_descriptor *desc;
struct manifest_desc *descriptor;
struct manifest_desc *module_desc = NULL;
struct manifest_desc *interface_desc = NULL;
u16 manifest_size;
u32 found = 0;
bool result;
@ -399,28 +400,28 @@ bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size)
size -= desc_size;
}
/* There must be a single module descriptor */
/* There must be a single interface descriptor */
list_for_each_entry(descriptor, &intf->manifest_descs, links) {
if (descriptor->type == GREYBUS_TYPE_MODULE)
if (descriptor->type == GREYBUS_TYPE_INTERFACE)
if (!found++)
module_desc = descriptor;
interface_desc = descriptor;
}
if (found != 1) {
pr_err("manifest must have 1 module descriptor (%u found)\n",
pr_err("manifest must have 1 interface descriptor (%u found)\n",
found);
result = false;
goto out;
}
/* Parse the module manifest, starting with the module descriptor */
result = gb_manifest_parse_module(intf, module_desc);
/* Parse the manifest, starting with the interface descriptor */
result = gb_manifest_parse_interface(intf, interface_desc);
/*
* We really should have no remaining descriptors, but we
* don't know what newer format manifests might leave.
*/
if (result && !list_empty(&intf->manifest_descs))
pr_info("excess descriptors in module manifest\n");
pr_info("excess descriptors in interface manifest\n");
out:
release_manifest_descriptors(intf);

View File

@ -1,5 +1,5 @@
/*
* Greybus module manifest parsing
* Greybus manifest parsing
*
* Copyright 2014 Google Inc.
* Copyright 2014 Linaro Ltd.