summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/eeprom.c
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2017-06-06 15:25:05 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-06-09 11:42:42 +0200
commit72ee33907b629355d8fd1980140a467041a9f519 (patch)
tree3f5242955d986d7f22137d02582566a047c821b2 /drivers/thunderbolt/eeprom.c
parent02b17a41ad102934a3772ffc82f345345c232ee4 (diff)
thunderbolt: Read vendor and device name from DROM
The device DROM contains name of the vendor and device among other things. Extract this information and expose it to the userspace via two new attributes. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com> Reviewed-by: Michael Jamet <michael.jamet@intel.com> Signed-off-by: Andreas Noever <andreas.noever@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/thunderbolt/eeprom.c')
-rw-r--r--drivers/thunderbolt/eeprom.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c
index 5c7d80a109b1..d40a5f07fc4c 100644
--- a/drivers/thunderbolt/eeprom.c
+++ b/drivers/thunderbolt/eeprom.c
@@ -204,6 +204,11 @@ struct tb_drom_entry_header {
enum tb_drom_entry_type type:1;
} __packed;
+struct tb_drom_entry_generic {
+ struct tb_drom_entry_header header;
+ u8 data[0];
+} __packed;
+
struct tb_drom_entry_port {
/* BYTES 0-1 */
struct tb_drom_entry_header header;
@@ -295,6 +300,32 @@ int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid)
return 0;
}
+static int tb_drom_parse_entry_generic(struct tb_switch *sw,
+ struct tb_drom_entry_header *header)
+{
+ const struct tb_drom_entry_generic *entry =
+ (const struct tb_drom_entry_generic *)header;
+
+ switch (header->index) {
+ case 1:
+ /* Length includes 2 bytes header so remove it before copy */
+ sw->vendor_name = kstrndup(entry->data,
+ header->len - sizeof(*header), GFP_KERNEL);
+ if (!sw->vendor_name)
+ return -ENOMEM;
+ break;
+
+ case 2:
+ sw->device_name = kstrndup(entry->data,
+ header->len - sizeof(*header), GFP_KERNEL);
+ if (!sw->device_name)
+ return -ENOMEM;
+ break;
+ }
+
+ return 0;
+}
+
static int tb_drom_parse_entry_port(struct tb_switch *sw,
struct tb_drom_entry_header *header)
{
@@ -350,6 +381,7 @@ static int tb_drom_parse_entries(struct tb_switch *sw)
switch (entry->type) {
case TB_DROM_ENTRY_GENERIC:
+ res = tb_drom_parse_entry_generic(sw, entry);
break;
case TB_DROM_ENTRY_PORT:
res = tb_drom_parse_entry_port(sw, entry);