]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
thunderbolt: Retry DROM reads for more failure scenarios
authorMario Limonciello <mario.limonciello@amd.com>
Thu, 7 Apr 2022 17:17:35 +0000 (01:17 +0800)
committerStefan Bader <stefan.bader@canonical.com>
Fri, 20 May 2022 12:41:49 +0000 (14:41 +0200)
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 e87491a9fd4e33eaf18ef69d8295bb07b31452b2 linux-next)
Signed-off-by: You-Sheng Yang <vicamo.yang@canonical.com>
Acked-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Paolo Pisati <paolo.pisati@canonical.com>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
drivers/thunderbolt/eeprom.c

index 470885e6f1c86a748cb3c8f7c76176029505b228..10cdbcb55df98f22c99327834266dbed17b46488 100644 (file)
@@ -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)