greybus: October 1 updates

Update the definitions in "greybus_manifest.h" to reflect the
changes to the Greybus specification made on October 1.

They are:
    - renaming "device" to be "interface"
    - renumbering greybus descriptor type
    - eliminating the notion of a "function"
    - defining a CPort's protocol in the CPort descriptor
    - having a "class" take on the types previously used for "function"
    - renaming "serial number" to be "unique id" (for now)
    - relying on an interface's maximum cport id to determine how
      much device+cport address space the interface consumes
    - adding a simple class descriptor
    - renaming gb_interface->interface_id to be gb_interface->id

This also reorders some things to match ordering in the document,
and adds some commentary for the various structures.

Since greybus_function_type is gone, we eliminate the "type" field
from a function structure.  (Functions are going away, next.)

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
Alex Elder 2014-10-02 12:30:02 -05:00 committed by Greg Kroah-Hartman
parent b05890db5e
commit 63cc932b02
10 changed files with 84 additions and 61 deletions

View File

@ -22,7 +22,7 @@ static DEFINE_SPINLOCK(gb_functions_lock);
* pointer if a failure occurs due to memory exhaustion.
*/
struct gb_function *gb_function_create(struct gb_interface *interface,
u16 cport_id, enum greybus_function_type type)
u16 cport_id)
{
struct gb_function *function;
@ -32,7 +32,6 @@ struct gb_function *gb_function_create(struct gb_interface *interface,
function->interface = interface; /* XXX refcount? */
function->cport_id = cport_id;
function->type = type;
spin_lock_irq(&gb_functions_lock);
list_add_tail(&function->links, &interface->functions);

View File

@ -12,14 +12,12 @@
struct gb_function {
struct gb_interface *interface;
u16 cport_id;
enum greybus_function_type type;
struct list_head links; /* interface->functions */
};
struct gb_function *gb_function_create(struct gb_interface *interface,
u16 cport_id,
enum greybus_function_type function_type);
u16 cport_id);
void gb_function_destroy(struct gb_function *function);
#endif /* __FUNCTION_H */

View File

@ -13,7 +13,7 @@ struct greybus_module_id {
__u16 match_flags;
__u16 vendor;
__u16 product;
__u64 serial_number;
__u64 unique_id;
kernel_ulong_t driver_info
__attribute__((aligned(sizeof(kernel_ulong_t))));

View File

@ -17,13 +17,24 @@
enum greybus_descriptor_type {
GREYBUS_TYPE_INVALID = 0x00,
GREYBUS_TYPE_MODULE = 0x01,
GREYBUS_TYPE_DEVICE = 0x02,
GREYBUS_TYPE_CLASS = 0x03,
GREYBUS_TYPE_STRING = 0x04,
GREYBUS_TYPE_CPORT = 0x05,
GREYBUS_TYPE_STRING = 0x02,
GREYBUS_TYPE_INTERFACE = 0x03,
GREYBUS_TYPE_CPORT = 0x04,
GREYBUS_TYPE_CLASS = 0x05,
};
enum greybus_function_type {
enum greybus_protocol {
GREYBUS_PROTOCOL_CONTROL = 0x00,
GREYBUS_PROTOCOL_AP = 0x01,
GREYBUS_PROTOCOL_GPIO = 0x02,
GREYBUS_PROTOCOL_I2C = 0x03,
GREYBUS_PROTOCOL_UART = 0x04,
GREYBUS_PROTOCOL_HID = 0x05,
/* ... */
GREYBUS_PROTOCOL_VENDOR = 0xff,
};
enum greybus_class_type {
GREYBUS_FUNCTION_CONTROL = 0x00,
GREYBUS_FUNCTION_USB = 0x01,
GREYBUS_FUNCTION_GPIO = 0x02,
@ -48,57 +59,71 @@ struct greybus_descriptor_module {
__le16 vendor;
__le16 product;
__le16 version;
__le64 serial_number;
__u8 vendor_stringid;
__u8 product_stringid;
__le64 unique_id;
};
/*
* A UniPro device normally supports a range of 32 CPorts (0..31).
* It is possible to support more than this by having a UniPro
* switch treat one device as if it were more than one. E.g.,
* allocate 3 device ids (rather than the normal--1) to physical
* device 5, and configure the switch to route all packets destined
* for "encoded" device ids 5, 6, and 7 to physical device 5.
* Device 5 uses the encoded device id in incoming UniPro packets to
* determine which bank of 32 CPorts should receive the UniPro
* segment.
*
* The "scale" field in this structure is used to define the number
* of encoded device ids should be allocated for this physical
* device. Scale is normally 1, to represent 32 available CPorts.
* A scale value 2 represents up to 64 CPorts; scale value 3
* represents up to 96 CPorts, and so on.
* The string in a string descriptor is not NUL-terminated. The
* size of the descriptor will be rounded up to a multiple of 4
* bytes, by padding the string with 0x00 bytes if necessary.
*/
struct greybus_descriptor_interface {
__u8 id; /* module-relative id (0..) */
__u8 scale; /* indicates range of of CPorts supported */
/* UniPro gear, number of in/out lanes */
};
struct greybus_descriptor_cport {
__le16 id;
__u8 function_type; /* enum greybus_function_type */
};
struct greybus_descriptor_string {
__u8 length;
__u8 id;
__u8 string[0];
};
/*
* 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.
*/
struct greybus_descriptor_interface {
__u8 id; /* module-relative id (0..) */
};
/*
* A CPort descriptor indicates the id of the interface within the
* module it's associated with, along with the CPort id used to
* address the CPort. The protocol defines the format of messages
* exchanged using the CPort.
*/
struct greybus_descriptor_cport {
__u8 interface;
__le16 id;
__u8 protocol; /* enum greybus_protocol */
};
/*
* A class descriptor defines functionality supplied by a module.
* Beyond that, not much else is defined yet...
*/
struct greybus_descriptor_class {
__u8 class; /* enum greybus_class_type */
};
struct greybus_descriptor_header {
__le16 size;
__u8 type; /* enum greybus_descriptor_type */
__u8 type; /* enum greybus_descriptor_type */
};
struct greybus_descriptor {
struct greybus_descriptor_header header;
struct greybus_descriptor_header header;
union {
struct greybus_descriptor_module module;
struct greybus_descriptor_string string;
struct greybus_descriptor_interface interface;
struct greybus_descriptor_cport cport;
struct greybus_descriptor_class class;
};
};

View File

@ -32,7 +32,7 @@ gb_interface_create(struct gb_module *gmod, u8 interface_id)
return NULL;
interface->gmod = gmod; /* XXX refcount? */
interface->interface_id = interface_id;
interface->id = interface_id;
INIT_LIST_HEAD(&interface->functions);
spin_lock_irq(&gb_interfaces_lock);

View File

@ -13,7 +13,7 @@
struct gb_interface {
struct gb_module *gmod;
u8 interface_id;
u8 id;
struct list_head functions;
struct list_head links; /* module->interfaces */

View File

@ -80,11 +80,6 @@ static int identify_descriptor(struct greybus_descriptor *desc, size_t size)
return -EINVAL;
}
break;
case GREYBUS_TYPE_DEVICE:
break;
case GREYBUS_TYPE_CLASS:
pr_err("class descriptor found (ignoring)\n");
break;
case GREYBUS_TYPE_STRING:
expected_size = sizeof(struct greybus_descriptor_header);
expected_size += sizeof(struct greybus_descriptor_string);
@ -95,6 +90,8 @@ static int identify_descriptor(struct greybus_descriptor *desc, size_t size)
return -EINVAL;
}
break;
case GREYBUS_TYPE_INTERFACE:
break;
case GREYBUS_TYPE_CPORT:
if (desc_size < sizeof(struct greybus_descriptor_cport)) {
pr_err("cport descriptor too small (%u)\n",
@ -102,6 +99,9 @@ static int identify_descriptor(struct greybus_descriptor *desc, size_t size)
return -EINVAL;
}
break;
case GREYBUS_TYPE_CLASS:
pr_warn("class descriptor found (ignoring)\n");
break;
case GREYBUS_TYPE_INVALID:
default:
pr_err("invalid descriptor type (%hhu)\n", desc_header->type);
@ -183,7 +183,7 @@ u32 gb_manifest_parse_cports(struct gb_interface *interface)
while (true) {
struct manifest_desc *descriptor;
struct greybus_descriptor_cport *desc_cport;
enum greybus_function_type function_type;
enum greybus_protocol protocol;
u16 cport_id;
bool found;
@ -191,19 +191,20 @@ u32 gb_manifest_parse_cports(struct gb_interface *interface)
found = false;
list_for_each_entry(descriptor, &manifest_descs, links) {
if (descriptor->type == GREYBUS_TYPE_CPORT) {
found = true;
break;
desc_cport = descriptor->data;
if (desc_cport->interface == interface->id) {
found = true;
break;
}
}
}
if (!found)
break;
/* Found one. Set up its function structure */
desc_cport = descriptor->data;
function_type =
(enum greybus_function_type)desc_cport->function_type;
protocol = (enum greybus_protocol)desc_cport->protocol;
cport_id = le16_to_cpu(desc_cport->id);
if (!gb_function_create(interface, cport_id, function_type))
if (!gb_function_create(interface, cport_id))
return 0; /* Error */
count++;
@ -231,7 +232,7 @@ static u32 gb_manifest_parse_interfaces(struct gb_module *gmod)
/* Find an interface descriptor */
list_for_each_entry(descriptor, &manifest_descs, links) {
if (descriptor->type == GREYBUS_TYPE_DEVICE) {
if (descriptor->type == GREYBUS_TYPE_INTERFACE) {
found = true;
break;
}
@ -284,7 +285,7 @@ struct gb_module *gb_manifest_parse_module(struct manifest_desc *module_desc)
gmod->vendor = le16_to_cpu(desc_module->vendor);
gmod->product = le16_to_cpu(desc_module->product);
gmod->version = le16_to_cpu(desc_module->version);
gmod->serial_number = le64_to_cpu(desc_module->serial_number);
gmod->unique_id = le64_to_cpu(desc_module->unique_id);
/* Release the module descriptor, now that we're done with it */
release_manifest_descriptor(module_desc);

View File

@ -23,7 +23,7 @@ static int gb_module_match_one_id(struct gb_module *gmod,
return 0;
if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_SERIAL) &&
(id->serial_number != gmod->serial_number))
(id->unique_id != gmod->unique_id))
return 0;
return 1;
@ -35,7 +35,7 @@ const struct greybus_module_id *gb_module_match_id(struct gb_module *gmod,
if (id == NULL)
return NULL;
for (; id->vendor || id->product || id->serial_number ||
for (; id->vendor || id->product || id->unique_id ||
id->driver_info; id++) {
if (gb_module_match_one_id(gmod, id))
return id;

View File

@ -24,9 +24,9 @@ struct gb_module {
u16 vendor;
u16 product;
u16 version;
u64 serial_number;
char *vendor_string;
char *product_string;
u64 unique_id;
int num_cports;
int num_strings;

View File

@ -40,7 +40,7 @@ static ssize_t module_serial_number_show(struct device *dev,
{
struct gb_module *gmod = to_gb_module(dev);
return sprintf(buf, "%llX\n", (unsigned long long)gmod->serial_number);
return sprintf(buf, "%llX\n", (unsigned long long)gmod->unique_id);
}
static DEVICE_ATTR_RO(module_serial_number);
@ -86,7 +86,7 @@ static umode_t module_attrs_are_visible(struct kobject *kobj,
return mode;
if (gmod->vendor || gmod->product || gmod->version)
return mode;
if (gmod->serial_number)
if (gmod->unique_id)
return mode;
return 0;