Skip to content

Commit

Permalink
thunderbolt: Retry DROM reads for more failure scenarios
Browse files Browse the repository at this point in the history
BugLink: https://bugs.launchpad.net/bugs/1962349

Currently DROM reads are only retried in the case that parsing failed.
However if the size or CRC fails, then there should also be a retry.

This helps with reading the DROM on TBT3 devices connected to AMD
Yellow Carp which will sometimes fail on the first attempt.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
(cherry picked from commit e87491a linux-next)
Signed-off-by: You-Sheng Yang <vicamo.yang@canonical.com>
Signed-off-by: Timo Aaltonen <timo.aaltonen@canonical.com>
  • Loading branch information
Mario Limonciello authored and Timo Aaltonen committed Apr 4, 2022
1 parent 2dd5d9d commit ce3950f
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions drivers/thunderbolt/eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,9 @@ static int tb_drom_parse(struct tb_switch *sw)
crc = tb_crc8((u8 *) &header->uid, 8);
if (crc != header->uid_crc8) {
tb_sw_warn(sw,
"DROM UID CRC8 mismatch (expected: %#x, got: %#x), aborting\n",
"DROM UID CRC8 mismatch (expected: %#x, got: %#x)\n",
header->uid_crc8, crc);
return -EINVAL;
return -EILSEQ;
}
if (!sw->uid)
sw->uid = header->uid;
Expand Down Expand Up @@ -654,6 +654,7 @@ int tb_drom_read(struct tb_switch *sw)
sw->drom = kzalloc(size, GFP_KERNEL);
if (!sw->drom)
return -ENOMEM;
read:
res = tb_drom_read_n(sw, 0, sw->drom, size);
if (res)
goto err;
Expand All @@ -662,7 +663,11 @@ int tb_drom_read(struct tb_switch *sw)
header = (void *) sw->drom;

if (header->data_len + TB_DROM_DATA_START != size) {
tb_sw_warn(sw, "drom size mismatch, aborting\n");
tb_sw_warn(sw, "drom size mismatch\n");
if (retries--) {
msleep(100);
goto read;
}
goto err;
}

Expand All @@ -683,11 +688,9 @@ int tb_drom_read(struct tb_switch *sw)

/* If the DROM parsing fails, wait a moment and retry once */
if (res == -EILSEQ && retries--) {
tb_sw_warn(sw, "parsing DROM failed, retrying\n");
tb_sw_warn(sw, "parsing DROM failed\n");
msleep(100);
res = tb_drom_read_n(sw, 0, sw->drom, size);
if (!res)
goto parse;
goto read;
}

if (!res)
Expand Down

0 comments on commit ce3950f

Please sign in to comment.