ACK: [PATCH 1/1][SRU][OEM-B-OSP1][F][OEM-5.6][G] thunderbolt: Retry DROM read once if parsing fails
Kleber Souza
kleber.souza at canonical.com
Wed Sep 16 09:09:00 UTC 2020
On 15.09.20 05:32, AceLan Kao wrote:
> From: Mika Westerberg <mika.westerberg at linux.intel.com>
>
> BugLink: https://bugs.launchpad.net/bugs/1895606
>
> Kai-Heng reported that sometimes DROM parsing of ASUS PA27AC Thunderbolt 3
> monitor fails. This makes the driver to fail to add the device so only
> DisplayPort tunneling is functional.
>
> It is not clear what exactly happens but waiting for 100 ms and retrying
> the read seems to work this around so we do that here.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=206493
> Reported-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
> Tested-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
> Cc: stable at vger.kernel.org
> Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> (cherry picked from commit f022ff7bf377ca94367be05de61277934d42ea74
> linux-next)
> Signed-off-by: AceLan Kao <acelan.kao at canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
> ---
> drivers/thunderbolt/eeprom.c | 20 ++++++++++++++++----
> 1 file changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c
> index ee5196479854..fa491944de1a 100644
> --- a/drivers/thunderbolt/eeprom.c
> +++ b/drivers/thunderbolt/eeprom.c
> @@ -7,6 +7,7 @@
> */
>
> #include <linux/crc32.h>
> +#include <linux/delay.h>
> #include <linux/property.h>
> #include <linux/slab.h>
> #include "tb.h"
> @@ -386,8 +387,8 @@ static int tb_drom_parse_entries(struct tb_switch *sw)
> struct tb_drom_entry_header *entry = (void *) (sw->drom + pos);
> if (pos + 1 == drom_size || pos + entry->len > drom_size
> || !entry->len) {
> - tb_sw_warn(sw, "drom buffer overrun, aborting\n");
> - return -EIO;
> + tb_sw_warn(sw, "DROM buffer overrun\n");
> + return -EILSEQ;
> }
>
> switch (entry->type) {
> @@ -493,7 +494,8 @@ int tb_drom_read(struct tb_switch *sw)
> u16 size;
> u32 crc;
> struct tb_drom_header *header;
> - int res;
> + int res, retries = 1;
> +
> if (sw->drom)
> return 0;
>
> @@ -581,7 +583,17 @@ int tb_drom_read(struct tb_switch *sw)
> tb_sw_warn(sw, "drom device_rom_revision %#x unknown\n",
> header->device_rom_revision);
>
> - return tb_drom_parse_entries(sw);
> + res = tb_drom_parse_entries(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");
> + msleep(100);
> + res = tb_drom_read_n(sw, 0, sw->drom, size);
> + if (!res)
> + goto parse;
> + }
> +
> + return res;
> err:
> kfree(sw->drom);
> sw->drom = NULL;
>
More information about the kernel-team
mailing list