From 63cc932b02bc5e697b5ba8f04a5d846b61f38879 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Thu, 2 Oct 2014 12:30:02 -0500 Subject: [PATCH] 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 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/function.c | 3 +- drivers/staging/greybus/function.h | 4 +- drivers/staging/greybus/greybus_id.h | 2 +- drivers/staging/greybus/greybus_manifest.h | 83 ++++++++++++++-------- drivers/staging/greybus/interface.c | 2 +- drivers/staging/greybus/interface.h | 2 +- drivers/staging/greybus/manifest.c | 29 ++++---- drivers/staging/greybus/module.c | 4 +- drivers/staging/greybus/module.h | 2 +- drivers/staging/greybus/sysfs.c | 4 +- 10 files changed, 79 insertions(+), 56 deletions(-) diff --git a/drivers/staging/greybus/function.c b/drivers/staging/greybus/function.c index b06265c53025..bfc9ac7e4c81 100644 --- a/drivers/staging/greybus/function.c +++ b/drivers/staging/greybus/function.c @@ -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); diff --git a/drivers/staging/greybus/function.h b/drivers/staging/greybus/function.h index 379ffcdabec7..e1b30c515a2a 100644 --- a/drivers/staging/greybus/function.h +++ b/drivers/staging/greybus/function.h @@ -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 */ diff --git a/drivers/staging/greybus/greybus_id.h b/drivers/staging/greybus/greybus_id.h index 8b3bce6a9d0b..f8e7b38b5176 100644 --- a/drivers/staging/greybus/greybus_id.h +++ b/drivers/staging/greybus/greybus_id.h @@ -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)))); diff --git a/drivers/staging/greybus/greybus_manifest.h b/drivers/staging/greybus/greybus_manifest.h index 61189995f7d9..35e1c5df0424 100644 --- a/drivers/staging/greybus/greybus_manifest.h +++ b/drivers/staging/greybus/greybus_manifest.h @@ -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; +}; + +/* + * 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_string { + __u8 length; + __u8 id; + __u8 string[0]; }; /* - * 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. + * 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 "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 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..) */ - __u8 scale; /* indicates range of of CPorts supported */ - /* UniPro gear, number of in/out lanes */ }; +/* + * 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 function_type; /* enum greybus_function_type */ + __u8 protocol; /* enum greybus_protocol */ }; -struct greybus_descriptor_string { - __u8 length; - __u8 id; - __u8 string[0]; +/* + * 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; }; }; diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index dc7d00975eee..a2c2f05f1fd9 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -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); diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h index 7c3feb7e98a8..7a4b3704b6a0 100644 --- a/drivers/staging/greybus/interface.h +++ b/drivers/staging/greybus/interface.h @@ -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 */ diff --git a/drivers/staging/greybus/manifest.c b/drivers/staging/greybus/manifest.c index bae260f0bc81..4066547cd2e5 100644 --- a/drivers/staging/greybus/manifest.c +++ b/drivers/staging/greybus/manifest.c @@ -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); diff --git a/drivers/staging/greybus/module.c b/drivers/staging/greybus/module.c index 6618d212d6e1..1970e7b01081 100644 --- a/drivers/staging/greybus/module.c +++ b/drivers/staging/greybus/module.c @@ -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; diff --git a/drivers/staging/greybus/module.h b/drivers/staging/greybus/module.h index 326176a57adf..7b01950fa36e 100644 --- a/drivers/staging/greybus/module.h +++ b/drivers/staging/greybus/module.h @@ -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; diff --git a/drivers/staging/greybus/sysfs.c b/drivers/staging/greybus/sysfs.c index f969d90d2502..2777b8cf5b3a 100644 --- a/drivers/staging/greybus/sysfs.c +++ b/drivers/staging/greybus/sysfs.c @@ -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; -- 2.20.1