lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <7b5df03ebd6151cdbfda372da74d996d225198cf.camel@siemens.com>
Date: Wed, 21 Jan 2026 08:58:24 +0000
From: "Sverdlin, Alexander" <alexander.sverdlin@...mens.com>
To: "patrick@...set.ch" <patrick@...set.ch>, "linux-kernel@...r.kernel.org"
	<linux-kernel@...r.kernel.org>
CC: "Wicki, Patrick" <patrick.wicki@...mens.com>
Subject: Re: [PATCH 2/2] eeprom: at25: expose JEDEC ID via sysfs

On Tue, 2026-01-20 at 14:06 +0100, patrick@...set.ch wrote:
> From: Patrick Wicki <patrick.wicki@...mens.com>
> 
> Return the raw JEDEC ID bytes as returned by the RDID command, even for
> variations that have the bytes in reverse order. This way we can avoid
> ambiguity if the manufacturer ever releases a new chip that returns them
> according to standard.
> 
> Signed-off-by: Patrick Wicki <patrick.wicki@...mens.com>

Tested with CY15B204QSN:

Reviewed-by: Alexander Sverdlin <alexander.sverdlin@...mens.com>
Tested-by: Alexander Sverdlin <alexander.sverdlin@...mens.com>

> ---
>  .../ABI/testing/sysfs-class-spi-eeprom        | 11 ++++++
>  drivers/misc/eeprom/at25.c                    | 38 +++++++++++++++----
>  2 files changed, 41 insertions(+), 8 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-class-spi-eeprom b/Documentation/ABI/testing/sysfs-class-spi-eeprom
> index 1ff7579820798..f4bc7d9454cfb 100644
> --- a/Documentation/ABI/testing/sysfs-class-spi-eeprom
> +++ b/Documentation/ABI/testing/sysfs-class-spi-eeprom
> @@ -17,3 +17,14 @@ Description:
>  	from the device.
>  
>  	This is a read-only attribute.
> +
> +What:		/sys/class/spi_master/spi<bus>/spi<bus>.<dev>/jedec_id
> +Date:		January 2026
> +KernelVersion:	6.19
> +Contact:	Patrick Wicki <patrick.wicki@...mens.com>
> +Description:
> +	Contains the raw JEDEC ID bytes returned by the RDID (0x9f) command. The
> +	bytes are exposed as a hex string in big-endian order as read from the
> +	device.
> +
> +	This is a read-only attribute.
> diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
> index 5b00921d07d2e..bc2cfb75d9bb4 100644
> --- a/drivers/misc/eeprom/at25.c
> +++ b/drivers/misc/eeprom/at25.c
> @@ -34,6 +34,7 @@
>   */
>  
>  #define	FM25_SN_LEN	8		/* serial number length */
> +#define	FM25_MAX_ID_LEN	9		/* ID length */
>  #define EE_MAXADDRLEN	3		/* 24 bit addresses, up to 2 MBytes */
>  
>  struct at25_data {
> @@ -44,6 +45,8 @@ struct at25_data {
>  	struct nvmem_config	nvmem_config;
>  	struct nvmem_device	*nvmem;
>  	u8 sernum[FM25_SN_LEN];
> +	u8 id[FM25_MAX_ID_LEN];
> +	u8 id_len;
>  };
>  
>  #define	AT25_WREN	0x06		/* latch the write enable */
> @@ -64,8 +67,6 @@ struct at25_data {
>  
>  #define	AT25_INSTR_BIT3	0x08		/* additional address bit in instr */
>  
> -#define	FM25_ID_LEN	9		/* ID length */
> -
>  /*
>   * Specs often allow 5ms for a page write, sometimes 20ms;
>   * it's important to recover from write timeouts.
> @@ -180,11 +181,25 @@ static ssize_t sernum_show(struct device *dev, struct device_attribute *attr, ch
>  }
>  static DEVICE_ATTR_RO(sernum);
>  
> -static struct attribute *sernum_attrs[] = {
> +static ssize_t jedec_id_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +	struct at25_data *at25;
> +
> +	at25 = dev_get_drvdata(dev);
> +
> +	if (!at25->id_len)
> +		return -EOPNOTSUPP;
> +
> +	return sysfs_emit(buf, "%*phN\n", at25->id_len, at25->id);
> +}
> +static DEVICE_ATTR_RO(jedec_id);
> +
> +static struct attribute *at25_attrs[] = {
>  	&dev_attr_sernum.attr,
> +	&dev_attr_jedec_id.attr,
>  	NULL,
>  };
> -ATTRIBUTE_GROUPS(sernum);
> +ATTRIBUTE_GROUPS(at25);
>  
>  /*
>   * Poll Read Status Register with timeout
> @@ -378,7 +393,7 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip)
>  {
>  	struct at25_data *at25 = container_of(chip, struct at25_data, chip);
>  	u8 sernum[FM25_SN_LEN];
> -	u8 id[FM25_ID_LEN];
> +	u8 id[FM25_MAX_ID_LEN];
>  	u32 val;
>  	int i;
>  
> @@ -388,7 +403,12 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip)
>  		chip->byte_len = val;
>  	} else {
>  		/* Get ID of chip */
> -		fm25_aux_read(at25, id, FM25_RDID, FM25_ID_LEN);
> +		fm25_aux_read(at25, id, FM25_RDID, FM25_MAX_ID_LEN);
> +
> +		/* Store the unprocessed ID for exposing via sysfs */
> +		memcpy(at25->id, id, FM25_MAX_ID_LEN);
> +		at25->id_len = FM25_MAX_ID_LEN;
> +
>  		/* There are inside-out FRAM variations, detect them and reverse the ID bytes */
>  		if (id[6] == 0x7f && id[2] == 0xc2)
>  			for (i = 0; i < ARRAY_SIZE(id) / 2; i++) {
> @@ -400,6 +420,7 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip)
>  			}
>  
>  		if (id[6] == 0xc2) {
> +			at25->id_len = 9;
>  			switch (id[7]) {
>  			case 0x21 ... 0x26:
>  				chip->byte_len = BIT(id[7] - 0x21 + 4) * 1024;
> @@ -413,6 +434,7 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip)
>  				return -ENODEV;
>  			}
>  		} else if (id[2] == 0x82 && id[3] == 0x06) {
> +			at25->id_len = 8;
>  			switch (id[1]) {
>  			case 0x51 ... 0x54:
>  				/* CY15B102QSN ... CY15B204QSN */
> @@ -424,7 +446,7 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip)
>  			}
>  		} else {
>  			dev_err(dev, "Error: unrecognized JEDEC ID format: %*ph\n",
> -				FM25_ID_LEN, id);
> +				FM25_MAX_ID_LEN, id);
>  			return -ENODEV;
>  		}
>  
> @@ -549,7 +571,7 @@ static struct spi_mem_driver at25_driver = {
>  		.driver = {
>  			.name		= "at25",
>  			.of_match_table = at25_of_match,
> -			.dev_groups	= sernum_groups,
> +			.dev_groups	= at25_groups,
>  		},
>  		.id_table	= at25_spi_ids,
>  	},

-- 
Alexander Sverdlin
Siemens AG
www.siemens.com

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ