[PATCH 1/2] mtd: spi-nor: sfdp: save a copy of the SFDP data

Pratyush Yadav p.yadav at ti.com
Mon Mar 22 18:42:16 GMT 2021


On 22/03/21 04:32PM, Michael Walle wrote:
> Am 2021-03-22 15:21, schrieb Pratyush Yadav:
> > On 18/03/21 10:24AM, Michael Walle wrote:
[...]
> > > @@ -1311,6 +1317,49 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
> > >  		}
> > >  	}
> > > 
> > > +	/*
> > > +	 * Cache the complete SFDP data. It is not (easily) possible to
> > > fetch
> > > +	 * SFDP after probe time and we need it for the sysfs access.
> > > +	 */
> > > +	for (i = 0; i < header.nph; i++) {
> > > +		param_header = &param_headers[i];
> > > +		sfdp_size = max_t(size_t, sfdp_size,
> > > +				  SFDP_PARAM_HEADER_PTP(param_header) +
> > > +				  SFDP_PARAM_HEADER_PARAM_LEN(param_header));
> > 
> > *sigh* If BFPT header was not made a part of the main SFDP header, two
> > "sfdp_size = ..." would not be needed, and we could do it all in one
> > place.
> > 
> > You can do that refactor if you're feeling like it, but I won't insist
> > on it.
> 
> I think that could be refactored when we also use the SFDP cache for
> the remaining parsing.

Ok.

[...]
> > 
> > > +
> > > +	sfdp->num_dwords = DIV_ROUND_UP(sfdp_size, sizeof(*sfdp->dwords));
> > 
> > The SFDP spec says that Parameter Table Pointer should be DWORD aligned
> > and Parameter Table length is specified in number of DWORDs. So,
> > sfdp_size should always be a multiple of 4. Any SFDP table where this is
> > not true is an invalid one.
> > 
> > Also, the spec says "Device behavior when the Read SFDP command crosses
> > the SFDP structure boundary is not defined".
> > 
> > So I think this should be a check for alignment instead of a round-up.
> 
> Well, that woundn't help for debugging. I.e. you also want the SFDP data
> in cases like this. IMHO we should try hard enough to actually get a
> reasonable dump.
> 
> OTOH we also rely on the header and the pointers in the header. Any
> other ideas, but just to chicken out?

Honestly, I don't think reading past the SFDP boundary would be too bad. 
It probably will just be some garbage data. But if you want to avoid 
that, you can always round down instead of up. This way you will only 
miss the last DWORD at most. In either case, a warning should be printed 
so this problem can be brought to the user's attention.

> 
> > > +	sfdp->dwords = devm_kcalloc(dev, sfdp->num_dwords,
> > > +				    sizeof(*sfdp->dwords), GFP_KERNEL);
> > > +	if (!sfdp->dwords) {
> > > +		err = -ENOMEM;
> > 
> > Free sfdp here since it won't be used any longer.
> 
> I see, spi_nor_parse_sfdp() is optional and won't fail the probe.
> Nice catch.
> 
> > 
> > > +		goto exit;
> > > +	}
> > > +
> > > +	err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sfdp_size, sfdp->dwords);
> > > +	if (err < 0) {
> > > +		dev_dbg(dev, "failed to read SFDP data\n");
> > > +		goto exit;
> > 
> > Free sfdp and sfdp->dwords here since they won't be used any longer.
> > 
> > > +	}
> > > +
> > > +	nor->sfdp = sfdp;
> > > +
> > >  	/*
> > >  	 * Check other parameter headers to get the latest revision of
> > >  	 * the basic flash parameter table.
> > > diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> > > index a0d572855444..55c550208949 100644
> > > --- a/include/linux/mtd/spi-nor.h
> > > +++ b/include/linux/mtd/spi-nor.h
> > > @@ -351,6 +351,7 @@ enum spi_nor_cmd_ext {
> > >  struct flash_info;
> > >  struct spi_nor_manufacturer;
> > >  struct spi_nor_flash_parameter;
> > > +struct sfdp;
> > 
> > nor->sfdp is a pointer. This should not be needed.
> > 
> > > 
> > >  /**
> > >   * struct spi_nor - Structure for defining the SPI NOR layer
> > > @@ -375,6 +376,7 @@ struct spi_nor_flash_parameter;
> > >   * @read_proto:		the SPI protocol for read operations
> > >   * @write_proto:	the SPI protocol for write operations
> > >   * @reg_proto:		the SPI protocol for read_reg/write_reg/erase
> > > operations
> > > + * @sfdp:		the SFDP data of the flash
> > >   * @controller_ops:	SPI NOR controller driver specific operations.
> > >   * @params:		[FLASH-SPECIFIC] SPI NOR flash parameters and settings.
> > >   *                      The structure includes legacy flash
> > > parameters and
> > > @@ -404,6 +406,7 @@ struct spi_nor {
> > >  	bool			sst_write_second;
> > >  	u32			flags;
> > >  	enum spi_nor_cmd_ext	cmd_ext_type;
> > > +	struct sfdp		*sfdp;
> > > 
> > >  	const struct spi_nor_controller_ops *controller_ops;
> > > 
> > > --
> > > 2.20.1
> > > 
> 
> -- 
> -michael

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.



More information about the linux-mtd mailing list