summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMario Limonciello <mario.limonciello@amd.com>2022-03-03 07:13:24 -0600
committerMika Westerberg <mika.westerberg@linux.intel.com>2022-03-04 17:10:36 +0300
commite87491a9fd4e33eaf18ef69d8295bb07b31452b2 (patch)
treef5778da0e5f50d77ab69ff967995ae59c5e0f0a5 /drivers
parent7f7b571becf3731dfa9aa50bed420e0c988e511d (diff)
thunderbolt: Retry DROM reads for more failure scenarios
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/thunderbolt/eeprom.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c
index 470885e6f1c8..10cdbcb55df9 100644
--- a/drivers/thunderbolt/eeprom.c
+++ b/drivers/thunderbolt/eeprom.c
@@ -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;
@@ -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;
@@ -662,7 +663,11 @@ parse:
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;
}
@@ -683,11 +688,9 @@ parse:
/* 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)