Skip to content

Commit

Permalink
thunderbolt: Parse generic drom entries
Browse files Browse the repository at this point in the history
Initially three types of generic entries are supported: vendor_name,
device_name and apple_serial. Log them for the benefit of the user.

Cc: Andreas Noever <andreas.noever@gmail.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
  • Loading branch information
l1k committed May 19, 2017
1 parent b6c9db7 commit d1b4636
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
36 changes: 36 additions & 0 deletions drivers/thunderbolt/eeprom.c
Expand Up @@ -5,6 +5,7 @@
*/

#include <linux/crc32.h>
#include <linux/ctype.h>
#include <linux/property.h>
#include <linux/slab.h>
#include "tb.h"
Expand Down Expand Up @@ -292,6 +293,40 @@ int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid)
return 0;
}

/**
* tb_drom_parse_entry_generic - parse generic drom entry
*
* Do not trust the text string to be null terminated in drom.
* Replace nonprintable characters with blanks.
*/
static int tb_drom_parse_entry_generic(struct tb_switch *sw,
struct tb_drom_entry_header *header)
{
char *sanitized_text, *text = (char *)header + sizeof(*header);
size_t text_len = header->len - sizeof(*header) + 1;
int i;

sanitized_text = kmalloc(text_len, GFP_KERNEL);
if (!sanitized_text)
return -ENOMEM;

for (i = 0; i < text_len - 1; i++)
sanitized_text[i] = (isascii(text[i]) && isprint(text[i])) ?
text[i] : ' ';
sanitized_text[text_len - 1] = '\0';

switch (header->index) {
case 0x01: sw->vendor_name = sanitized_text; return 0;
case 0x02: sw->device_name = sanitized_text; return 0;
case 0x30: sw->apple_serial = sanitized_text; return 0;
}

tb_sw_info(sw, "unknown generic entry %#x: %s\n", header->index,
sanitized_text);
kfree(sanitized_text);
return 0;
}

static int tb_drom_parse_entry_port(struct tb_switch *sw,
struct tb_drom_entry_header *header)
{
Expand Down Expand Up @@ -347,6 +382,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);
Expand Down
9 changes: 9 additions & 0 deletions drivers/thunderbolt/switch.c
Expand Up @@ -326,6 +326,9 @@ void tb_switch_free(struct tb_switch *sw)
if (!sw->is_unplugged)
tb_plug_events_active(sw, false);

kfree(sw->vendor_name);
kfree(sw->device_name);
kfree(sw->apple_serial);
kfree(sw->ports);
kfree(sw->drom);
kfree(sw);
Expand Down Expand Up @@ -405,6 +408,12 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route)
if (tb_drom_read(sw))
tb_sw_warn(sw, "tb_eeprom_read_rom failed, continuing\n");
tb_sw_info(sw, "uid: %#llx\n", sw->uid);
if (sw->vendor_name)
tb_sw_info(sw, "Vendor: %s\n", sw->vendor_name);
if (sw->device_name)
tb_sw_info(sw, "Device: %s\n", sw->device_name);
if (sw->apple_serial)
tb_sw_info(sw, "Apple Serial Number: %s\n", sw->apple_serial);

for (i = 0; i <= sw->config.max_port_number; i++) {
if (sw->ports[i].disabled) {
Expand Down
3 changes: 3 additions & 0 deletions drivers/thunderbolt/tb.h
Expand Up @@ -23,6 +23,9 @@ struct tb_switch {
int cap_plug_events; /* offset, zero if not found */
bool is_unplugged; /* unplugged, will go away */
u8 *drom;
char *vendor_name;
char *device_name;
char *apple_serial;
};

/**
Expand Down

0 comments on commit d1b4636

Please sign in to comment.