diff mbox

mtd: spi-nor: read 6 bytes for the ID

Message ID 20140528052237.GA7984@shlinux1.ap.freescale.net
State Changes Requested
Headers show

Commit Message

Huang Shijie May 28, 2014, 5:22 a.m. UTC
On Tue, May 27, 2014 at 05:57:31PM +0200, Christophe KERELLO wrote:
> Hello Huang,
> 
> I have one remark on this patch.
> 
> S25FL128S flash has 2 variants:
>  - Uniform 256-kB sectors (ext_id = 0x4D00)
>  - 4-kB parameter sectors with uniform 64-kB sectors (ext_id = 0x4D01)
> 
> If i would like to distinguish these 2 variants in spi_nor_ids
> array, i replace:
> { "s25fl128s", INFO(0x012018, 0x4d0180, 64 * 1024, 256,
> SPI_NOR_QUAD_READ) },
> with
> { "s25fl128s0", INFO(0x012018, 0x4d0080, 256 * 1024, 64,
> SPI_NOR_QUAD_READ) },
> { "s25fl128s1", INFO(0x012018, 0x4d0180, 64 * 1024, 256,
> SPI_NOR_QUAD_READ) },
> 
> In this case, i fail to find s25fl128s1 device.
> 
> The problem is coming from ext_jedec calculation.
> first try:
>     - jedec = 0x012018,
>     - ext_jedec = 0x4d0180,
>     - info->ext_id = 0x4d0080,
>     =>s25fl128s0 doesn't match
> 
> second try:
>     - jedec = 0x012018,
>     - ext_jedec = 0x4d018080,
>     - info->ext_id = 0x4d0180,
>     => s25fl128s1 doesn't match
> 
> I think there is similar issue with s25fl129p1 (if i use this patch
> without modifying it).
> first try:
>     - jedec = 0x012018,
>     - ext_jedec = 0x4d01xx, (xx = probably 0x00 or 0xff)
>     - info->ext_id = 0x4d0180,
>     =>s25fl128s doesn't match
> 
> second try:
>     - jedec = 0x012018,
>     - ext_jedec = 0x4d01xx,
>     - info->ext_id = 0x4d01,
>     => s25fl129p1 doesn't match
> 
> If I reset ext_jedec after each try, it works.
> 
> ext_jedec = ext_jedec << 8 | id[5];
> if (info->ext_id == ext_jedec)
>     return &spi_nor_ids[tmp];
> else
>     /* reset ext_jdec for next try */
>     ext_jedec = ext_jedec >> 8;
> 
hi Christophe:
  thanks for pointing this!

  Please try the new version.

thanks
Huang Shijie

---------------------------------------
From 7b920141899e4e7249bd23792dc8d5f1558cb7ca Mon Sep 17 00:00:00 2001
From: Huang Shijie <b32955@freescale.com>
Date: Mon, 14 Apr 2014 18:09:34 +0800
Subject: [PATCH v2] mtd: spi-nor: read 6 bytes for the ID

Currently, we read 5 bytes for ID, but s25fl128s has the same ext_id(0x4d01)
with s25fl129p1. The s25fl128s can support the DDR Quad read, while s25fl129p1
does not. So we have to distinguish the two NOR flashs.

This patch reads out 6 bytes for the ID, and use the 6 bytes ID to search the
right flash_info.

The detail of the patch is:
  [1] change the "ext_id" from u16 to u32.
      We can store two bytes or three bytes with the @ext_id now.

  [2] search the right flash_info with the 6byte ID and the new @ext_id.
      We use "matched" variable to track the legacy two bytes @ext_id.
      If the flash_info's @ext_id is three bytes, we will use the
      sixth byte of the ID to check it.

  [3] add the new item to spi_nor_ids for s25fl128s.

Signed-off-by: Huang Shijie <b32955@freescale.com>
---
 drivers/mtd/spi-nor/spi-nor.c |   30 +++++++++++++++++++++++++-----
 1 files changed, 25 insertions(+), 5 deletions(-)

Comments

Christophe Kerello May 28, 2014, 4:27 p.m. UTC | #1
On 05/28/2014 07:22 AM, Huang Shijie wrote:
> On Tue, May 27, 2014 at 05:57:31PM +0200, Christophe KERELLO wrote:
>> Hello Huang,
>>
>> I have one remark on this patch.
>>
>> S25FL128S flash has 2 variants:
>>   - Uniform 256-kB sectors (ext_id = 0x4D00)
>>   - 4-kB parameter sectors with uniform 64-kB sectors (ext_id = 0x4D01)
>>
>> If i would like to distinguish these 2 variants in spi_nor_ids
>> array, i replace:
>> { "s25fl128s", INFO(0x012018, 0x4d0180, 64 * 1024, 256,
>> SPI_NOR_QUAD_READ) },
>> with
>> { "s25fl128s0", INFO(0x012018, 0x4d0080, 256 * 1024, 64,
>> SPI_NOR_QUAD_READ) },
>> { "s25fl128s1", INFO(0x012018, 0x4d0180, 64 * 1024, 256,
>> SPI_NOR_QUAD_READ) },
>>
>> In this case, i fail to find s25fl128s1 device.
>>
>> The problem is coming from ext_jedec calculation.
>> first try:
>>      - jedec = 0x012018,
>>      - ext_jedec = 0x4d0180,
>>      - info->ext_id = 0x4d0080,
>>      =>s25fl128s0 doesn't match
>>
>> second try:
>>      - jedec = 0x012018,
>>      - ext_jedec = 0x4d018080,
>>      - info->ext_id = 0x4d0180,
>>      => s25fl128s1 doesn't match
>>
>> I think there is similar issue with s25fl129p1 (if i use this patch
>> without modifying it).
>> first try:
>>      - jedec = 0x012018,
>>      - ext_jedec = 0x4d01xx, (xx = probably 0x00 or 0xff)
>>      - info->ext_id = 0x4d0180,
>>      =>s25fl128s doesn't match
>>
>> second try:
>>      - jedec = 0x012018,
>>      - ext_jedec = 0x4d01xx,
>>      - info->ext_id = 0x4d01,
>>      => s25fl129p1 doesn't match
>>
>> If I reset ext_jedec after each try, it works.
>>
>> ext_jedec = ext_jedec << 8 | id[5];
>> if (info->ext_id == ext_jedec)
>>      return &spi_nor_ids[tmp];
>> else
>>      /* reset ext_jdec for next try */
>>      ext_jedec = ext_jedec >> 8;
>>
> hi Christophe:
>    thanks for pointing this!
>
>    Please try the new version.
>
> thanks
> Huang Shijie
Hello Huang,

Thanks.
Patch v2 works fine.

Regards,
Christophe Kerello.
>
> ---------------------------------------
>  From 7b920141899e4e7249bd23792dc8d5f1558cb7ca Mon Sep 17 00:00:00 2001
> From: Huang Shijie <b32955@freescale.com>
> Date: Mon, 14 Apr 2014 18:09:34 +0800
> Subject: [PATCH v2] mtd: spi-nor: read 6 bytes for the ID
>
> Currently, we read 5 bytes for ID, but s25fl128s has the same ext_id(0x4d01)
> with s25fl129p1. The s25fl128s can support the DDR Quad read, while s25fl129p1
> does not. So we have to distinguish the two NOR flashs.
>
> This patch reads out 6 bytes for the ID, and use the 6 bytes ID to search the
> right flash_info.
>
> The detail of the patch is:
>    [1] change the "ext_id" from u16 to u32.
>        We can store two bytes or three bytes with the @ext_id now.
>
>    [2] search the right flash_info with the 6byte ID and the new @ext_id.
>        We use "matched" variable to track the legacy two bytes @ext_id.
>        If the flash_info's @ext_id is three bytes, we will use the
>        sixth byte of the ID to check it.
>
>    [3] add the new item to spi_nor_ids for s25fl128s.
>
> Signed-off-by: Huang Shijie <b32955@freescale.com>
> ---
>   drivers/mtd/spi-nor/spi-nor.c |   30 +++++++++++++++++++++++++-----
>   1 files changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index c713c86..f21d3ef 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -383,7 +383,7 @@ struct flash_info {
>   	 * then a two byte device id.
>   	 */
>   	u32		jedec_id;
> -	u16             ext_id;
> +	u32		ext_id;
>   
>   	/* The size listed here is what works with SPINOR_OP_SE, which isn't
>   	 * necessarily called a "sector" by the vendor.
> @@ -505,6 +505,7 @@ const struct spi_device_id spi_nor_ids[] = {
>   	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
>   	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
>   	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
> +	{ "s25fl128s",	INFO(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
>   	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
>   	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
>   	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
> @@ -593,12 +594,13 @@ EXPORT_SYMBOL_GPL(spi_nor_ids);
>   static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
>   {
>   	int			tmp;
> -	u8			id[5];
> +	u8			id[6];
>   	u32			jedec;
> -	u16                     ext_jedec;
> +	u32                     ext_jedec;
>   	struct flash_info	*info;
> +	int			matched = -1;
>   
> -	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 5);
> +	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 6);
>   	if (tmp < 0) {
>   		dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp);
>   		return ERR_PTR(tmp);
> @@ -614,8 +616,26 @@ static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
>   	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
>   		info = (void *)spi_nor_ids[tmp].driver_data;
>   		if (info->jedec_id == jedec) {
> -			if (info->ext_id == 0 || info->ext_id == ext_jedec)
> +			if (info->ext_id == 0)
>   				return &spi_nor_ids[tmp];
> +
> +			/* the legacy two bytes ext_id */
> +			if ((info->ext_id >> 16) == 0) {
> +				if (info->ext_id == ext_jedec)
> +					matched = tmp;
> +			} else {
> +				/* check the sixth byte now */
> +				ext_jedec = ext_jedec << 8 | id[5];
> +				if (info->ext_id == ext_jedec)
> +					return &spi_nor_ids[tmp];
> +
> +				/* reset back the ext_jedec */
> +				ext_jedec >>= 8;
> +			}
> +		} else {
> +			/* shortcut */
> +			if (matched != -1)
> +				return &spi_nor_ids[matched];
>   		}
>   	}
>   	dev_err(nor->dev, "unrecognized JEDEC id %06x\n", jedec);
Marek Vasut May 29, 2014, 8:58 p.m. UTC | #2
On Wednesday, May 28, 2014 at 07:22:40 AM, Huang Shijie wrote:
[...]
> From 7b920141899e4e7249bd23792dc8d5f1558cb7ca Mon Sep 17 00:00:00 2001
> From: Huang Shijie <b32955@freescale.com>
> Date: Mon, 14 Apr 2014 18:09:34 +0800
> Subject: [PATCH v2] mtd: spi-nor: read 6 bytes for the ID
> 
> Currently, we read 5 bytes for ID, but s25fl128s has the same
> ext_id(0x4d01) with s25fl129p1. The s25fl128s can support the DDR Quad
> read, while s25fl129p1 does not. So we have to distinguish the two NOR
> flashs.
> 
> This patch reads out 6 bytes for the ID, and use the 6 bytes ID to search
> the right flash_info.
> 
> The detail of the patch is:
>   [1] change the "ext_id" from u16 to u32.
>       We can store two bytes or three bytes with the @ext_id now.
> 
>   [2] search the right flash_info with the 6byte ID and the new @ext_id.
>       We use "matched" variable to track the legacy two bytes @ext_id.
>       If the flash_info's @ext_id is three bytes, we will use the
>       sixth byte of the ID to check it.
> 
>   [3] add the new item to spi_nor_ids for s25fl128s.
> 
> Signed-off-by: Huang Shijie <b32955@freescale.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c |   30 +++++++++++++++++++++++++-----
>  1 files changed, 25 insertions(+), 5 deletions(-)

What exactly changed here please ?

Best regards,
Marek Vasut
Huang Shijie May 30, 2014, 12:49 a.m. UTC | #3
On Thu, May 29, 2014 at 10:58:52PM +0200, Marek Vasut wrote:
> On Wednesday, May 28, 2014 at 07:22:40 AM, Huang Shijie wrote:
> [...]
> > From 7b920141899e4e7249bd23792dc8d5f1558cb7ca Mon Sep 17 00:00:00 2001
> > From: Huang Shijie <b32955@freescale.com>
> > Date: Mon, 14 Apr 2014 18:09:34 +0800
> > Subject: [PATCH v2] mtd: spi-nor: read 6 bytes for the ID
> > 
> > Currently, we read 5 bytes for ID, but s25fl128s has the same
> > ext_id(0x4d01) with s25fl129p1. The s25fl128s can support the DDR Quad
> > read, while s25fl129p1 does not. So we have to distinguish the two NOR
> > flashs.
> > 
> > This patch reads out 6 bytes for the ID, and use the 6 bytes ID to search
> > the right flash_info.
> > 
> > The detail of the patch is:
> >   [1] change the "ext_id" from u16 to u32.
> >       We can store two bytes or three bytes with the @ext_id now.
> > 
> >   [2] search the right flash_info with the 6byte ID and the new @ext_id.
> >       We use "matched" variable to track the legacy two bytes @ext_id.
> >       If the flash_info's @ext_id is three bytes, we will use the
> >       sixth byte of the ID to check it.
> > 
> >   [3] add the new item to spi_nor_ids for s25fl128s.
> > 
> > Signed-off-by: Huang Shijie <b32955@freescale.com>
> > ---
> >  drivers/mtd/spi-nor/spi-nor.c |   30 +++++++++++++++++++++++++-----
> >  1 files changed, 25 insertions(+), 5 deletions(-)
> 
> What exactly changed here please ?

This patch will reset the ext_jedec to the old value if the sixth-byte-match fails.

------------------------------------------------------------
+				/* reset back the ext_jedec */
+				ext_jedec >>= 8;
------------------------------------------------------------

thanks
Huang Shijie
Marek Vasut June 3, 2014, 2:23 p.m. UTC | #4
On Friday, May 30, 2014 at 02:49:30 AM, Huang Shijie wrote:
> On Thu, May 29, 2014 at 10:58:52PM +0200, Marek Vasut wrote:
> > On Wednesday, May 28, 2014 at 07:22:40 AM, Huang Shijie wrote:
> > [...]
> > 
> > > From 7b920141899e4e7249bd23792dc8d5f1558cb7ca Mon Sep 17 00:00:00 2001
> > > From: Huang Shijie <b32955@freescale.com>
> > > Date: Mon, 14 Apr 2014 18:09:34 +0800
> > > Subject: [PATCH v2] mtd: spi-nor: read 6 bytes for the ID
> > > 
> > > Currently, we read 5 bytes for ID, but s25fl128s has the same
> > > ext_id(0x4d01) with s25fl129p1. The s25fl128s can support the DDR Quad
> > > read, while s25fl129p1 does not. So we have to distinguish the two NOR
> > > flashs.
> > > 
> > > This patch reads out 6 bytes for the ID, and use the 6 bytes ID to
> > > search the right flash_info.
> > > 
> > > The detail of the patch is:
> > >   [1] change the "ext_id" from u16 to u32.
> > >   
> > >       We can store two bytes or three bytes with the @ext_id now.
> > >   
> > >   [2] search the right flash_info with the 6byte ID and the new
> > >   @ext_id.
> > >   
> > >       We use "matched" variable to track the legacy two bytes @ext_id.
> > >       If the flash_info's @ext_id is three bytes, we will use the
> > >       sixth byte of the ID to check it.
> > >   
> > >   [3] add the new item to spi_nor_ids for s25fl128s.
> > > 
> > > Signed-off-by: Huang Shijie <b32955@freescale.com>
> > > ---
> > > 
> > >  drivers/mtd/spi-nor/spi-nor.c |   30 +++++++++++++++++++++++++-----
> > >  1 files changed, 25 insertions(+), 5 deletions(-)
> > 
> > What exactly changed here please ?
> 
> This patch will reset the ext_jedec to the old value if the
> sixth-byte-match fails.
> 
> ------------------------------------------------------------
> +				/* reset back the ext_jedec */
> +				ext_jedec >>= 8;
> ------------------------------------------------------------

Uh oh, I think we're getting deeper and deeper into ad-hoc adjustments :-(

Best regards,
Marek Vasut
Brian Norris Aug. 4, 2014, 11:24 p.m. UTC | #5
Hi Huang,

You asked for a review of this patch...

On Wed, May 28, 2014 at 01:22:40PM +0800, Huang Shijie wrote:
> From 7b920141899e4e7249bd23792dc8d5f1558cb7ca Mon Sep 17 00:00:00 2001
> From: Huang Shijie <b32955@freescale.com>
> Date: Mon, 14 Apr 2014 18:09:34 +0800
> Subject: [PATCH v2] mtd: spi-nor: read 6 bytes for the ID
> 
> Currently, we read 5 bytes for ID, but s25fl128s has the same ext_id(0x4d01)
> with s25fl129p1. The s25fl128s can support the DDR Quad read, while s25fl129p1
> does not. So we have to distinguish the two NOR flashs.
> 
> This patch reads out 6 bytes for the ID, and use the 6 bytes ID to search the
> right flash_info.
> 
> The detail of the patch is:
>   [1] change the "ext_id" from u16 to u32.
>       We can store two bytes or three bytes with the @ext_id now.
> 
>   [2] search the right flash_info with the 6byte ID and the new @ext_id.
>       We use "matched" variable to track the legacy two bytes @ext_id.
>       If the flash_info's @ext_id is three bytes, we will use the
>       sixth byte of the ID to check it.
> 
>   [3] add the new item to spi_nor_ids for s25fl128s.
> 
> Signed-off-by: Huang Shijie <b32955@freescale.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c |   30 +++++++++++++++++++++++++-----
>  1 files changed, 25 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index c713c86..f21d3ef 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -383,7 +383,7 @@ struct flash_info {
>  	 * then a two byte device id.
>  	 */
>  	u32		jedec_id;
> -	u16             ext_id;
> +	u32		ext_id;
>  
>  	/* The size listed here is what works with SPINOR_OP_SE, which isn't
>  	 * necessarily called a "sector" by the vendor.
> @@ -505,6 +505,7 @@ const struct spi_device_id spi_nor_ids[] = {
>  	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
>  	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
>  	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
> +	{ "s25fl128s",	INFO(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
>  	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
>  	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
>  	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
> @@ -593,12 +594,13 @@ EXPORT_SYMBOL_GPL(spi_nor_ids);
>  static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
>  {
>  	int			tmp;
> -	u8			id[5];
> +	u8			id[6];
>  	u32			jedec;
> -	u16                     ext_jedec;
> +	u32                     ext_jedec;
>  	struct flash_info	*info;
> +	int			matched = -1;
>  
> -	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 5);
> +	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 6);
>  	if (tmp < 0) {
>  		dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp);
>  		return ERR_PTR(tmp);
> @@ -614,8 +616,26 @@ static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
>  	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
>  		info = (void *)spi_nor_ids[tmp].driver_data;
>  		if (info->jedec_id == jedec) {
> -			if (info->ext_id == 0 || info->ext_id == ext_jedec)
> +			if (info->ext_id == 0)
>  				return &spi_nor_ids[tmp];
> +
> +			/* the legacy two bytes ext_id */
> +			if ((info->ext_id >> 16) == 0) {
> +				if (info->ext_id == ext_jedec)
> +					matched = tmp;
> +			} else {
> +				/* check the sixth byte now */
> +				ext_jedec = ext_jedec << 8 | id[5];
> +				if (info->ext_id == ext_jedec)
> +					return &spi_nor_ids[tmp];
> +
> +				/* reset back the ext_jedec */
> +				ext_jedec >>= 8;

As Marek already noted, this is very ad-hoc.

The logic here is just plain convoluted, because we haven't updated the
flash_info struct to contain the ID length. Please fix this. Just like
struct nand_flash_dev, we probably need an 'id_len' field. Bonus points
if you can extend the structure properly without having to modify the
entire existing table... Maybe a new INFO6() macro? (Better name
suggestions are welcome.)

Another reason for adding this field: what if we need to match to a
6-byte ID where the 6th byte is 0x00? I already see a 5-byte ID in our
table where the 5th byte is 0x00.

> +			}
> +		} else {
> +			/* shortcut */
> +			if (matched != -1)
> +				return &spi_nor_ids[matched];
>  		}
>  	}
>  	dev_err(nor->dev, "unrecognized JEDEC id %06x\n", jedec);

Brian
Huang Shijie Aug. 5, 2014, 12:52 a.m. UTC | #6
On Mon, Aug 04, 2014 at 04:24:07PM -0700, Brian Norris wrote:
> 
> The logic here is just plain convoluted, because we haven't updated the
> flash_info struct to contain the ID length. Please fix this. Just like
> struct nand_flash_dev, we probably need an 'id_len' field. Bonus points
> if you can extend the structure properly without having to modify the
> entire existing table... Maybe a new INFO6() macro? (Better name
> suggestions are welcome.)

ok. I will try to add a "id_len" field in the next patch.
> 
> Another reason for adding this field: what if we need to match to a
> 6-byte ID where the 6th byte is 0x00? I already see a 5-byte ID in our
> table where the 5th byte is 0x00.
I think it is okay if the 6the byte is 0x00. 
Anyway, we do not meet such NOR. If we meet such NOR in future, we
can check it carefully, and see if we need to change the code a little.

thanks
Huang Shijie
Marek Vasut Aug. 5, 2014, 7:14 a.m. UTC | #7
On Tuesday, August 05, 2014 at 02:52:00 AM, Huang Shijie wrote:
> On Mon, Aug 04, 2014 at 04:24:07PM -0700, Brian Norris wrote:
> > The logic here is just plain convoluted, because we haven't updated the
> > flash_info struct to contain the ID length. Please fix this. Just like
> > struct nand_flash_dev, we probably need an 'id_len' field. Bonus points
> > if you can extend the structure properly without having to modify the
> > entire existing table... Maybe a new INFO6() macro? (Better name
> > suggestions are welcome.)
> 
> ok. I will try to add a "id_len" field in the next patch.
> 
> > Another reason for adding this field: what if we need to match to a
> > 6-byte ID where the 6th byte is 0x00? I already see a 5-byte ID in our
> > table where the 5th byte is 0x00.
> 
> I think it is okay if the 6the byte is 0x00.
> Anyway, we do not meet such NOR. If we meet such NOR in future, we
> can check it carefully, and see if we need to change the code a little.

Well, I expressed my disagreement on that matter a few times already. Like Brian 
mentioned, adding an id_len field would be the way to go. It would prevent all 
kinds of crazy wrap-arounds when reading the IDs and other such strange 
behavior.

Best regards,
Marek Vasut
Huang Shijie Aug. 6, 2014, 12:23 a.m. UTC | #8
On Tue, Aug 05, 2014 at 09:14:11AM +0200, Marek Vasut wrote:
> On Tuesday, August 05, 2014 at 02:52:00 AM, Huang Shijie wrote:
> > On Mon, Aug 04, 2014 at 04:24:07PM -0700, Brian Norris wrote:
> > > The logic here is just plain convoluted, because we haven't updated the
> > > flash_info struct to contain the ID length. Please fix this. Just like
> > > struct nand_flash_dev, we probably need an 'id_len' field. Bonus points
> > > if you can extend the structure properly without having to modify the
> > > entire existing table... Maybe a new INFO6() macro? (Better name
> > > suggestions are welcome.)
> > 
> > ok. I will try to add a "id_len" field in the next patch.
> > 
> > > Another reason for adding this field: what if we need to match to a
> > > 6-byte ID where the 6th byte is 0x00? I already see a 5-byte ID in our
> > > table where the 5th byte is 0x00.
> > 
> > I think it is okay if the 6the byte is 0x00.
> > Anyway, we do not meet such NOR. If we meet such NOR in future, we
> > can check it carefully, and see if we need to change the code a little.
> 
> Well, I expressed my disagreement on that matter a few times already. Like Brian 
> mentioned, adding an id_len field would be the way to go. It would prevent all 
> kinds of crazy wrap-arounds when reading the IDs and other such strange 
> behavior.
thanks Marek, but i need to collect more comments to change patch.
Brian was busy in the past month.. 

thanks again.
Huang Shijie
diff mbox

Patch

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index c713c86..f21d3ef 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -383,7 +383,7 @@  struct flash_info {
 	 * then a two byte device id.
 	 */
 	u32		jedec_id;
-	u16             ext_id;
+	u32		ext_id;
 
 	/* The size listed here is what works with SPINOR_OP_SE, which isn't
 	 * necessarily called a "sector" by the vendor.
@@ -505,6 +505,7 @@  const struct spi_device_id spi_nor_ids[] = {
 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
 	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
+	{ "s25fl128s",	INFO(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
 	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
 	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
 	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
@@ -593,12 +594,13 @@  EXPORT_SYMBOL_GPL(spi_nor_ids);
 static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
 {
 	int			tmp;
-	u8			id[5];
+	u8			id[6];
 	u32			jedec;
-	u16                     ext_jedec;
+	u32                     ext_jedec;
 	struct flash_info	*info;
+	int			matched = -1;
 
-	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 5);
+	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, 6);
 	if (tmp < 0) {
 		dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp);
 		return ERR_PTR(tmp);
@@ -614,8 +616,26 @@  static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
 	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
 		info = (void *)spi_nor_ids[tmp].driver_data;
 		if (info->jedec_id == jedec) {
-			if (info->ext_id == 0 || info->ext_id == ext_jedec)
+			if (info->ext_id == 0)
 				return &spi_nor_ids[tmp];
+
+			/* the legacy two bytes ext_id */
+			if ((info->ext_id >> 16) == 0) {
+				if (info->ext_id == ext_jedec)
+					matched = tmp;
+			} else {
+				/* check the sixth byte now */
+				ext_jedec = ext_jedec << 8 | id[5];
+				if (info->ext_id == ext_jedec)
+					return &spi_nor_ids[tmp];
+
+				/* reset back the ext_jedec */
+				ext_jedec >>= 8;
+			}
+		} else {
+			/* shortcut */
+			if (matched != -1)
+				return &spi_nor_ids[matched];
 		}
 	}
 	dev_err(nor->dev, "unrecognized JEDEC id %06x\n", jedec);