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