Re: [PATCH v2 0/7] mtd: nand: Abstract away the NAND interface type

2016-11-17 Thread Peter Pan
Hi Boris,

On Thu, Nov 17, 2016 at 3:56 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> Hi Peter,
>
> On Thu, 17 Nov 2016 14:26:37 +0800
> Peter Pan <peterpans...@gmail.com> wrote:
>
>> Hi Boris,
>>
>> On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
>> <boris.brezil...@free-electrons.com> wrote:
>> > Hi,
>> >
>> > This series is aiming at providing a generic NAND layer to share code
>> > between different NAND based devices.
>> >
>> > We currently have 3 different interfaces to interact with NANDs:
>> > - Raw NANDs
>> > - OneNANDs
>> > - SPI NANDs
>> >
>> > Apart from the way these NAND devices are accessed they have a lot
>> > in common, like the way the memory is organized, or their constraints.
>> > This is usually a good sign that some work should be done to factorize
>> > the code.
>> >
>> > This work has been started by Peter who wanted to re-use the BBT
>> > code for its SPI-NAND driver. But I think we can push it further
>> > other stuff (the software ECC implementation, or the way offsets are
>> > converted to block/page number).
>> >
>> > Peter, can you please review/test this version, and if possible, post
>> > the code you've done to support SPI NANDs.
>> >
>>
>> I already finished review and test work. The BBT works well after I applied
>> my modification which I already sent to your by email. I tried to build a new
>> BBT on a new NAND and then mark one block to bad. Both works well.
>> My test platform is Xilinx Zed board.
>
> Thanks a lot for testing and reviewing this series. I'll address your
> comments and send a new version soon.
>
> My plan is to have it in -next just after 4.10-rc1 is released, in order
> to detect bugs early.
>
>>
>> I will try to rebase my SPI NAND patch on your patch and send it out.
>> It will take me some time because I'm quite busy with other company affairs.
>
> I'd be happy to review this part.

Looking forward for your reviewing! Your comments are really needed!

Thanks,
Peter Pan


Re: [PATCH v2 0/7] mtd: nand: Abstract away the NAND interface type

2016-11-17 Thread Peter Pan
Hi Boris,

On Thu, Nov 17, 2016 at 3:56 PM, Boris Brezillon
 wrote:
> Hi Peter,
>
> On Thu, 17 Nov 2016 14:26:37 +0800
> Peter Pan  wrote:
>
>> Hi Boris,
>>
>> On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
>>  wrote:
>> > Hi,
>> >
>> > This series is aiming at providing a generic NAND layer to share code
>> > between different NAND based devices.
>> >
>> > We currently have 3 different interfaces to interact with NANDs:
>> > - Raw NANDs
>> > - OneNANDs
>> > - SPI NANDs
>> >
>> > Apart from the way these NAND devices are accessed they have a lot
>> > in common, like the way the memory is organized, or their constraints.
>> > This is usually a good sign that some work should be done to factorize
>> > the code.
>> >
>> > This work has been started by Peter who wanted to re-use the BBT
>> > code for its SPI-NAND driver. But I think we can push it further
>> > other stuff (the software ECC implementation, or the way offsets are
>> > converted to block/page number).
>> >
>> > Peter, can you please review/test this version, and if possible, post
>> > the code you've done to support SPI NANDs.
>> >
>>
>> I already finished review and test work. The BBT works well after I applied
>> my modification which I already sent to your by email. I tried to build a new
>> BBT on a new NAND and then mark one block to bad. Both works well.
>> My test platform is Xilinx Zed board.
>
> Thanks a lot for testing and reviewing this series. I'll address your
> comments and send a new version soon.
>
> My plan is to have it in -next just after 4.10-rc1 is released, in order
> to detect bugs early.
>
>>
>> I will try to rebase my SPI NAND patch on your patch and send it out.
>> It will take me some time because I'm quite busy with other company affairs.
>
> I'd be happy to review this part.

Looking forward for your reviewing! Your comments are really needed!

Thanks,
Peter Pan


Re: [PATCH v2 0/7] mtd: nand: Abstract away the NAND interface type

2016-11-16 Thread Peter Pan
Hi Boris,

On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> Hi,
>
> This series is aiming at providing a generic NAND layer to share code
> between different NAND based devices.
>
> We currently have 3 different interfaces to interact with NANDs:
> - Raw NANDs
> - OneNANDs
> - SPI NANDs
>
> Apart from the way these NAND devices are accessed they have a lot
> in common, like the way the memory is organized, or their constraints.
> This is usually a good sign that some work should be done to factorize
> the code.
>
> This work has been started by Peter who wanted to re-use the BBT
> code for its SPI-NAND driver. But I think we can push it further
> other stuff (the software ECC implementation, or the way offsets are
> converted to block/page number).
>
> Peter, can you please review/test this version, and if possible, post
> the code you've done to support SPI NANDs.
>

I already finished review and test work. The BBT works well after I applied
my modification which I already sent to your by email. I tried to build a new
BBT on a new NAND and then mark one block to bad. Both works well.
My test platform is Xilinx Zed board.

I will try to rebase my SPI NAND patch on your patch and send it out.
It will take me some time because I'm quite busy with other company affairs.


Thanks,
Peter Pan


Re: [PATCH v2 0/7] mtd: nand: Abstract away the NAND interface type

2016-11-16 Thread Peter Pan
Hi Boris,

On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
 wrote:
> Hi,
>
> This series is aiming at providing a generic NAND layer to share code
> between different NAND based devices.
>
> We currently have 3 different interfaces to interact with NANDs:
> - Raw NANDs
> - OneNANDs
> - SPI NANDs
>
> Apart from the way these NAND devices are accessed they have a lot
> in common, like the way the memory is organized, or their constraints.
> This is usually a good sign that some work should be done to factorize
> the code.
>
> This work has been started by Peter who wanted to re-use the BBT
> code for its SPI-NAND driver. But I think we can push it further
> other stuff (the software ECC implementation, or the way offsets are
> converted to block/page number).
>
> Peter, can you please review/test this version, and if possible, post
> the code you've done to support SPI NANDs.
>

I already finished review and test work. The BBT works well after I applied
my modification which I already sent to your by email. I tried to build a new
BBT on a new NAND and then mark one block to bad. Both works well.
My test platform is Xilinx Zed board.

I will try to rebase my SPI NAND patch on your patch and send it out.
It will take me some time because I'm quite busy with other company affairs.


Thanks,
Peter Pan


Re: [PATCH v2 6/7] mtd: nand: raw: make BBT code more generic

2016-11-16 Thread Peter Pan
Hi Boris,

On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
 wrote:
> BBT support is currently tightly tied to raw NAND, though this is the kind
> of code we could share across all NAND based devices, no matter what
> physical interface is to communicate with the NAND chip.
>
> Make BBT code interface agnostic by replacing all occurrence of
> struct nand_chip by struct nand_device, and move functions that are
> specific to raw NANDs to drivers/mtd/nand/rawnand/nand_base.c.
>
> Signed-off-by: Boris Brezillon 
> ---
>  drivers/mtd/nand/raw/nand_base.c |  78 -
>  drivers/mtd/nand/raw/nand_bbt.c  | 609 
> ++-
>  include/linux/mtd/nand.h |   8 +
>  include/linux/mtd/rawnand.h  |   4 -
>  4 files changed, 361 insertions(+), 338 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/nand_base.c 
> b/drivers/mtd/nand/raw/nand_base.c
> index b86f4a1bfbe1..4930b3569de9 100644
> --- a/drivers/mtd/nand/raw/nand_base.c
> +++ b/drivers/mtd/nand/raw/nand_base.c
> @@ -471,7 +471,7 @@ static int nand_block_markbad_lowlevel(struct mtd_info 
> *mtd, loff_t ofs)
>
> /* Mark block bad in BBT */
> if (chip->bbt) {

Should be "if (!nand->bbt.bbt)".

> -   res = nand_markbad_bbt(mtd, ofs);
> +   res = nand_markbad_bbt(mtd_to_nand(mtd), ofs);
> if (!ret)
> ret = res;
> }


Re: [PATCH v2 6/7] mtd: nand: raw: make BBT code more generic

2016-11-16 Thread Peter Pan
Hi Boris,

On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
 wrote:
> BBT support is currently tightly tied to raw NAND, though this is the kind
> of code we could share across all NAND based devices, no matter what
> physical interface is to communicate with the NAND chip.
>
> Make BBT code interface agnostic by replacing all occurrence of
> struct nand_chip by struct nand_device, and move functions that are
> specific to raw NANDs to drivers/mtd/nand/rawnand/nand_base.c.
>
> Signed-off-by: Boris Brezillon 
> ---
>  drivers/mtd/nand/raw/nand_base.c |  78 -
>  drivers/mtd/nand/raw/nand_bbt.c  | 609 
> ++-
>  include/linux/mtd/nand.h |   8 +
>  include/linux/mtd/rawnand.h  |   4 -
>  4 files changed, 361 insertions(+), 338 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/nand_base.c 
> b/drivers/mtd/nand/raw/nand_base.c
> index b86f4a1bfbe1..4930b3569de9 100644
> --- a/drivers/mtd/nand/raw/nand_base.c
> +++ b/drivers/mtd/nand/raw/nand_base.c
> @@ -471,7 +471,7 @@ static int nand_block_markbad_lowlevel(struct mtd_info 
> *mtd, loff_t ofs)
>
> /* Mark block bad in BBT */
> if (chip->bbt) {

Should be "if (!nand->bbt.bbt)".

> -   res = nand_markbad_bbt(mtd, ofs);
> +   res = nand_markbad_bbt(mtd_to_nand(mtd), ofs);
> if (!ret)
> ret = res;
> }


Re: [PATCH v2 3/7] mtd: nand: add a nand.h file to expose basic NAND stuff

2016-11-16 Thread Peter Pan
Hi Boris,

On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> Now that raw NAND header has been moved to rawnand.h, we can add a new
> nand.h file and define the common nand stuff in there.
>
> Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> ---
>  include/linux/mtd/nand.h | 480 
> +++
>  1 file changed, 480 insertions(+)
>  create mode 100644 include/linux/mtd/nand.h
>
> diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> new file mode 100644
> index ..b9b5d3c1bdf9
> --- /dev/null
> +++ b/include/linux/mtd/nand.h
[...]
> +
> +/**
> + * nand_offs_to_die - Convert an absolute offset to a die number
> + * @nand: NAND device
> + * @offs: absolute offset
> + *
> + * Returns the die number containing @offs.
> + */
> +static inline int nand_offs_to_die(struct nand_device *nand, loff_t offs)
> +{
> +   u64 die = offs;
> +
> +   do_div(die, nand->memorg.diesize);
> +
> +   return die;

Is it proper to use do_div here?. If I'm right, the divisor of do_div is 32bit.
It may cause division 0 exception when die size is larger than 4GB.
div64_u64 may be better.

Thanks,
Peter Pan


Re: [PATCH v2 3/7] mtd: nand: add a nand.h file to expose basic NAND stuff

2016-11-16 Thread Peter Pan
Hi Boris,

On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
 wrote:
> Now that raw NAND header has been moved to rawnand.h, we can add a new
> nand.h file and define the common nand stuff in there.
>
> Signed-off-by: Boris Brezillon 
> ---
>  include/linux/mtd/nand.h | 480 
> +++
>  1 file changed, 480 insertions(+)
>  create mode 100644 include/linux/mtd/nand.h
>
> diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> new file mode 100644
> index ..b9b5d3c1bdf9
> --- /dev/null
> +++ b/include/linux/mtd/nand.h
[...]
> +
> +/**
> + * nand_offs_to_die - Convert an absolute offset to a die number
> + * @nand: NAND device
> + * @offs: absolute offset
> + *
> + * Returns the die number containing @offs.
> + */
> +static inline int nand_offs_to_die(struct nand_device *nand, loff_t offs)
> +{
> +   u64 die = offs;
> +
> +   do_div(die, nand->memorg.diesize);
> +
> +   return die;

Is it proper to use do_div here?. If I'm right, the divisor of do_div is 32bit.
It may cause division 0 exception when die size is larger than 4GB.
div64_u64 may be better.

Thanks,
Peter Pan


Re: [PATCH v2 6/7] mtd: nand: raw: make BBT code more generic

2016-11-16 Thread Peter Pan
Hi Boris,

I found a bug during my review. Please see below.

On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> BBT support is currently tightly tied to raw NAND, though this is the kind
> of code we could share across all NAND based devices, no matter what
> physical interface is to communicate with the NAND chip.
>
> Make BBT code interface agnostic by replacing all occurrence of
> struct nand_chip by struct nand_device, and move functions that are
> specific to raw NANDs to drivers/mtd/nand/rawnand/nand_base.c.
>
> Signed-off-by: Boris Brezillon <boris.brezil...@free-electrons.com>
> ---
>  drivers/mtd/nand/raw/nand_base.c |  78 -
>  drivers/mtd/nand/raw/nand_bbt.c  | 609 
> ++-
>  include/linux/mtd/nand.h |   8 +
>  include/linux/mtd/rawnand.h  |   4 -
>  4 files changed, 361 insertions(+), 338 deletions(-)
>
[...]
>  /**
>   * write_bbt - [GENERIC] (Re)write the bad block table
> - * @mtd: MTD device structure
> + * @this: NAND device
>   * @buf: temporary buffer
>   * @td: descriptor for the bad block table
>   * @md: descriptor for the bad block table mirror
> @@ -708,11 +707,11 @@ static void mark_bbt_block_bad(struct nand_chip *this,
>   *
>   * (Re)write the bad block table.
>   */
> -static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
> +static int write_bbt(struct nand_device *this, uint8_t *buf,
>  struct nand_bbt_descr *td, struct nand_bbt_descr *md,
>  int chipsel)
>  {
> -   struct nand_chip *this = mtd_to_nandc(mtd);
> +   struct mtd_info *mtd = nand_to_mtd(this);
> struct erase_info einfo;
> int i, res, chip = 0;
> int bits, page, offs, numblocks, sft, sftmsk;
> @@ -723,7 +722,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
> loff_t to;
> struct mtd_oob_ops ops;
>
> -   ops.ooblen = mtd->oobsize;
> +   ops.ooblen = nand_per_page_oobsize(this);
> ops.ooboffs = 0;
> ops.datbuf = NULL;
> ops.mode = MTD_OPS_PLACE_OOB;
> @@ -732,16 +731,16 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
> rcode = 0xff;
> /* Write bad block table per chip rather than per device? */
> if (td->options & NAND_BBT_PERCHIP) {
> -   numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
> +   numblocks = nand_eraseblocks_per_die(this);
> /* Full device write or specific chip? */
> if (chipsel == -1) {
> -   nrchips = this->numchips;
> +   nrchips = nand_ndies(this);
> } else {
> nrchips = chipsel + 1;
> chip = chipsel;
> }
> } else {
> -   numblocks = (int)(mtd->size >> this->bbt_erase_shift);
> +   numblocks = nand_neraseblocks(this);
> nrchips = 1;
> }
>
> @@ -760,7 +759,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
>  * get_bbt_block() returns a block number, shift the value to
>  * get a page number.
>  */
> -   page = block << (this->bbt_erase_shift - this->page_shift);
> +   nand_eraseblock_to_page(this, block);

Should be page = nand_eraseblock_to_page(this, block);

I will continue to review and test your patch. Hope give you feedback this week.

Thanks,
Peter Pan


Re: [PATCH v2 6/7] mtd: nand: raw: make BBT code more generic

2016-11-16 Thread Peter Pan
Hi Boris,

I found a bug during my review. Please see below.

On Sun, Oct 16, 2016 at 10:35 PM, Boris Brezillon
 wrote:
> BBT support is currently tightly tied to raw NAND, though this is the kind
> of code we could share across all NAND based devices, no matter what
> physical interface is to communicate with the NAND chip.
>
> Make BBT code interface agnostic by replacing all occurrence of
> struct nand_chip by struct nand_device, and move functions that are
> specific to raw NANDs to drivers/mtd/nand/rawnand/nand_base.c.
>
> Signed-off-by: Boris Brezillon 
> ---
>  drivers/mtd/nand/raw/nand_base.c |  78 -
>  drivers/mtd/nand/raw/nand_bbt.c  | 609 
> ++-
>  include/linux/mtd/nand.h |   8 +
>  include/linux/mtd/rawnand.h  |   4 -
>  4 files changed, 361 insertions(+), 338 deletions(-)
>
[...]
>  /**
>   * write_bbt - [GENERIC] (Re)write the bad block table
> - * @mtd: MTD device structure
> + * @this: NAND device
>   * @buf: temporary buffer
>   * @td: descriptor for the bad block table
>   * @md: descriptor for the bad block table mirror
> @@ -708,11 +707,11 @@ static void mark_bbt_block_bad(struct nand_chip *this,
>   *
>   * (Re)write the bad block table.
>   */
> -static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
> +static int write_bbt(struct nand_device *this, uint8_t *buf,
>  struct nand_bbt_descr *td, struct nand_bbt_descr *md,
>  int chipsel)
>  {
> -   struct nand_chip *this = mtd_to_nandc(mtd);
> +   struct mtd_info *mtd = nand_to_mtd(this);
> struct erase_info einfo;
> int i, res, chip = 0;
> int bits, page, offs, numblocks, sft, sftmsk;
> @@ -723,7 +722,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
> loff_t to;
> struct mtd_oob_ops ops;
>
> -   ops.ooblen = mtd->oobsize;
> +   ops.ooblen = nand_per_page_oobsize(this);
> ops.ooboffs = 0;
> ops.datbuf = NULL;
> ops.mode = MTD_OPS_PLACE_OOB;
> @@ -732,16 +731,16 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
> rcode = 0xff;
> /* Write bad block table per chip rather than per device? */
> if (td->options & NAND_BBT_PERCHIP) {
> -   numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
> +   numblocks = nand_eraseblocks_per_die(this);
> /* Full device write or specific chip? */
> if (chipsel == -1) {
> -   nrchips = this->numchips;
> +   nrchips = nand_ndies(this);
> } else {
> nrchips = chipsel + 1;
> chip = chipsel;
> }
> } else {
> -   numblocks = (int)(mtd->size >> this->bbt_erase_shift);
> +   numblocks = nand_neraseblocks(this);
> nrchips = 1;
> }
>
> @@ -760,7 +759,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
>  * get_bbt_block() returns a block number, shift the value to
>  * get a page number.
>  */
> -   page = block << (this->bbt_erase_shift - this->page_shift);
> +   nand_eraseblock_to_page(this, block);

Should be page = nand_eraseblock_to_page(this, block);

I will continue to review and test your patch. Hope give you feedback this week.

Thanks,
Peter Pan


Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-06-16 Thread Peter Pan
Hi Boris,

On Tue, May 17, 2016 at 9:03 AM, Peter Pan <peterpans...@gmail.com> wrote:
> Hi Boris,
>
> Firstly, sorry for late reply.
>
> On Thu, May 5, 2016 at 4:33 AM, Boris Brezillon
> <boris.brezil...@free-electrons.com> wrote:
>> Hi Peter,
>>
>> On Wed, 4 May 2016 09:36:05 +0800
>> Peter Pan <peterpans...@gmail.com> wrote:
>>
>>> Hi Boris,
>>>
>>> On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
>>> <boris.brezil...@free-electrons.com> wrote:
>>> > Hi Peter,
>>> >
>>> > On Tue, 19 Apr 2016 08:40:40 +0800
>>> > Peter Pan <peterpans...@gmail.com> wrote:
>>> >>
>>> >> >
>>> >> >> So it's true, it
>>> >> >> should still be numchips in nand_bbt.c?  I just came out this 
>>> >> >> question when
>>> >> >> making v4. :)
>>> >> >
>>> >> > BTW, I have something for you [1]. I started to move things around to
>>> >> > allow spinand and onenand layers to lie under drivers/mtd/nand/, and I
>>> >> > wonder if we shouldn't do this move before reworking the nand_bbt code
>>> >> > to make it generic.
>>> >> > Note that this rework is not finished yet, but it gives a rough idea of
>>> >> > what I'd like to see.
>>> >>
>>> >> I saw you also rework BBT in your git tree, which is a bit duplicate
>>> >> with my BBT patch,
>>> >> so should I continue my BBT patch by join part of your BBT rework code
>>> >> or continue
>>> >> your git tree ?
>>> >
>>> > Well, if you ask me what I'd prefer, it's clearly the 2nd solution.
>>> > Note that my branch should just serve as a reference of what I expect,
>>> > it just a pile of rework that should probably be reordered and cleaned
>>> > up.
>>> >
>>> > Here's the sequencing I'd like to see:
>>> >
>>> > 1/ Move include/linux/mtd/nand.h into include/linux/mtd/rawnand.h and
>>> >move all files under drivers/mtd/nand/ into
>>> >drivers/mtd/nand/rawnand (including nand_bbt.c). This can be done in
>>> >several patches
>>> >
>>> > 2/ Add the generic nand layer (include/linux/mtd/nand.h and
>>> >drivers/mtd/nand/core.c). In my version I put everything in
>>> >include/linux/mtd/nand.h, but maybe we'll need a few functions to be
>>> >defined in drivers/mtd/nand/core.c.
>>> >
>>> > 3/ Create a rawnand_device structure inheriting from nand_device, and
>>> >then make nand_chip inherit from rawnand_device. Patch the
>>> >nand_base.c code to initialize all the nand_device fields properly,
>>> >so that we'll be ready to switch to the generic BBT code.
>>> >
>>> > 4/ Modify the nand_bbt.c code to make use of the generic NAND interface
>>> >instead of the MTD and rawnand one (this implies identifying all the
>>> >generic helpers you might need, and implementing them in
>>> >include/linux/mtd/nand.h or drivers/mtd/nand/core.c).
>>> >
>>> > 5/ Move drivers/mtd/nand/rawnand/nand_bbt.c into
>>> >drivers/mtd/nand/bbt.c
>>> >
>>> > 6/[optional] Implement your spinand layer in drivers/mtd/nand/spinand
>>> >
>>> > I know I'm asking a lot, especially given that you already spent a lot
>>> > of time iterating on this BBT rework series. But your goal is to move
>>> > mt29f driver out of staging, and you'll need to do the generic NAND
>>> > layer to achieve that, so I'd really prefer having the BBT code use
>>> > this generic layer instead of directly using the MTD API + an extra set
>>> > of NAND specific structs (like the nand_chip_layout_info one).
>>>
>>> Yes, I want to upstreaming my SPI NAND frameworks and it's indeed better
>>> to have a nand core. In fact, I already finished a SPI NAND framework with
>>> the BBT patch I sent which is directly under MTD (don't have a NAND core 
>>> layer).
>>>
>>> Actually, I'm interested in this NAND framework refining work. And I
>>> know you already
>>> gave a speech on ELC about this. But due to the resource limitation, I may 
>>> not
>>> to do all of the things. So how about I continue my BBT patch with
>>> your NAND refining
>>> ideas. I'll try 

Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-06-16 Thread Peter Pan
Hi Boris,

On Tue, May 17, 2016 at 9:03 AM, Peter Pan  wrote:
> Hi Boris,
>
> Firstly, sorry for late reply.
>
> On Thu, May 5, 2016 at 4:33 AM, Boris Brezillon
>  wrote:
>> Hi Peter,
>>
>> On Wed, 4 May 2016 09:36:05 +0800
>> Peter Pan  wrote:
>>
>>> Hi Boris,
>>>
>>> On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
>>>  wrote:
>>> > Hi Peter,
>>> >
>>> > On Tue, 19 Apr 2016 08:40:40 +0800
>>> > Peter Pan  wrote:
>>> >>
>>> >> >
>>> >> >> So it's true, it
>>> >> >> should still be numchips in nand_bbt.c?  I just came out this 
>>> >> >> question when
>>> >> >> making v4. :)
>>> >> >
>>> >> > BTW, I have something for you [1]. I started to move things around to
>>> >> > allow spinand and onenand layers to lie under drivers/mtd/nand/, and I
>>> >> > wonder if we shouldn't do this move before reworking the nand_bbt code
>>> >> > to make it generic.
>>> >> > Note that this rework is not finished yet, but it gives a rough idea of
>>> >> > what I'd like to see.
>>> >>
>>> >> I saw you also rework BBT in your git tree, which is a bit duplicate
>>> >> with my BBT patch,
>>> >> so should I continue my BBT patch by join part of your BBT rework code
>>> >> or continue
>>> >> your git tree ?
>>> >
>>> > Well, if you ask me what I'd prefer, it's clearly the 2nd solution.
>>> > Note that my branch should just serve as a reference of what I expect,
>>> > it just a pile of rework that should probably be reordered and cleaned
>>> > up.
>>> >
>>> > Here's the sequencing I'd like to see:
>>> >
>>> > 1/ Move include/linux/mtd/nand.h into include/linux/mtd/rawnand.h and
>>> >move all files under drivers/mtd/nand/ into
>>> >drivers/mtd/nand/rawnand (including nand_bbt.c). This can be done in
>>> >several patches
>>> >
>>> > 2/ Add the generic nand layer (include/linux/mtd/nand.h and
>>> >drivers/mtd/nand/core.c). In my version I put everything in
>>> >include/linux/mtd/nand.h, but maybe we'll need a few functions to be
>>> >defined in drivers/mtd/nand/core.c.
>>> >
>>> > 3/ Create a rawnand_device structure inheriting from nand_device, and
>>> >then make nand_chip inherit from rawnand_device. Patch the
>>> >nand_base.c code to initialize all the nand_device fields properly,
>>> >so that we'll be ready to switch to the generic BBT code.
>>> >
>>> > 4/ Modify the nand_bbt.c code to make use of the generic NAND interface
>>> >instead of the MTD and rawnand one (this implies identifying all the
>>> >generic helpers you might need, and implementing them in
>>> >include/linux/mtd/nand.h or drivers/mtd/nand/core.c).
>>> >
>>> > 5/ Move drivers/mtd/nand/rawnand/nand_bbt.c into
>>> >drivers/mtd/nand/bbt.c
>>> >
>>> > 6/[optional] Implement your spinand layer in drivers/mtd/nand/spinand
>>> >
>>> > I know I'm asking a lot, especially given that you already spent a lot
>>> > of time iterating on this BBT rework series. But your goal is to move
>>> > mt29f driver out of staging, and you'll need to do the generic NAND
>>> > layer to achieve that, so I'd really prefer having the BBT code use
>>> > this generic layer instead of directly using the MTD API + an extra set
>>> > of NAND specific structs (like the nand_chip_layout_info one).
>>>
>>> Yes, I want to upstreaming my SPI NAND frameworks and it's indeed better
>>> to have a nand core. In fact, I already finished a SPI NAND framework with
>>> the BBT patch I sent which is directly under MTD (don't have a NAND core 
>>> layer).
>>>
>>> Actually, I'm interested in this NAND framework refining work. And I
>>> know you already
>>> gave a speech on ELC about this. But due to the resource limitation, I may 
>>> not
>>> to do all of the things. So how about I continue my BBT patch with
>>> your NAND refining
>>> ideas. I'll try to make the BBT patch compatible with the refining
>>> work. What do you
>>> think?
>>
>> The thing is, I'm not happy with these intermediate reworks, which 

Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-05-16 Thread Peter Pan
Hi Boris,

Firstly, sorry for late reply.

On Thu, May 5, 2016 at 4:33 AM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> Hi Peter,
>
> On Wed, 4 May 2016 09:36:05 +0800
> Peter Pan <peterpans...@gmail.com> wrote:
>
>> Hi Boris,
>>
>> On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
>> <boris.brezil...@free-electrons.com> wrote:
>> > Hi Peter,
>> >
>> > On Tue, 19 Apr 2016 08:40:40 +0800
>> > Peter Pan <peterpans...@gmail.com> wrote:
>> >>
>> >> >
>> >> >> So it's true, it
>> >> >> should still be numchips in nand_bbt.c?  I just came out this question 
>> >> >> when
>> >> >> making v4. :)
>> >> >
>> >> > BTW, I have something for you [1]. I started to move things around to
>> >> > allow spinand and onenand layers to lie under drivers/mtd/nand/, and I
>> >> > wonder if we shouldn't do this move before reworking the nand_bbt code
>> >> > to make it generic.
>> >> > Note that this rework is not finished yet, but it gives a rough idea of
>> >> > what I'd like to see.
>> >>
>> >> I saw you also rework BBT in your git tree, which is a bit duplicate
>> >> with my BBT patch,
>> >> so should I continue my BBT patch by join part of your BBT rework code
>> >> or continue
>> >> your git tree ?
>> >
>> > Well, if you ask me what I'd prefer, it's clearly the 2nd solution.
>> > Note that my branch should just serve as a reference of what I expect,
>> > it just a pile of rework that should probably be reordered and cleaned
>> > up.
>> >
>> > Here's the sequencing I'd like to see:
>> >
>> > 1/ Move include/linux/mtd/nand.h into include/linux/mtd/rawnand.h and
>> >move all files under drivers/mtd/nand/ into
>> >drivers/mtd/nand/rawnand (including nand_bbt.c). This can be done in
>> >several patches
>> >
>> > 2/ Add the generic nand layer (include/linux/mtd/nand.h and
>> >drivers/mtd/nand/core.c). In my version I put everything in
>> >include/linux/mtd/nand.h, but maybe we'll need a few functions to be
>> >defined in drivers/mtd/nand/core.c.
>> >
>> > 3/ Create a rawnand_device structure inheriting from nand_device, and
>> >then make nand_chip inherit from rawnand_device. Patch the
>> >nand_base.c code to initialize all the nand_device fields properly,
>> >so that we'll be ready to switch to the generic BBT code.
>> >
>> > 4/ Modify the nand_bbt.c code to make use of the generic NAND interface
>> >instead of the MTD and rawnand one (this implies identifying all the
>> >generic helpers you might need, and implementing them in
>> >include/linux/mtd/nand.h or drivers/mtd/nand/core.c).
>> >
>> > 5/ Move drivers/mtd/nand/rawnand/nand_bbt.c into
>> >drivers/mtd/nand/bbt.c
>> >
>> > 6/[optional] Implement your spinand layer in drivers/mtd/nand/spinand
>> >
>> > I know I'm asking a lot, especially given that you already spent a lot
>> > of time iterating on this BBT rework series. But your goal is to move
>> > mt29f driver out of staging, and you'll need to do the generic NAND
>> > layer to achieve that, so I'd really prefer having the BBT code use
>> > this generic layer instead of directly using the MTD API + an extra set
>> > of NAND specific structs (like the nand_chip_layout_info one).
>>
>> Yes, I want to upstreaming my SPI NAND frameworks and it's indeed better
>> to have a nand core. In fact, I already finished a SPI NAND framework with
>> the BBT patch I sent which is directly under MTD (don't have a NAND core 
>> layer).
>>
>> Actually, I'm interested in this NAND framework refining work. And I
>> know you already
>> gave a speech on ELC about this. But due to the resource limitation, I may 
>> not
>> to do all of the things. So how about I continue my BBT patch with
>> your NAND refining
>> ideas. I'll try to make the BBT patch compatible with the refining
>> work. What do you
>> think?
>
> The thing is, I'm not happy with these intermediate reworks, which in my
> opinion are adding more confusion and will make things even harder to
> rework afterward.
> You said you already developed your SPI NAND framework and it's not
> based on the generic NAND layer, which means you (or someone else) will
> have to migrate it to this approach at 

Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-05-16 Thread Peter Pan
Hi Boris,

Firstly, sorry for late reply.

On Thu, May 5, 2016 at 4:33 AM, Boris Brezillon
 wrote:
> Hi Peter,
>
> On Wed, 4 May 2016 09:36:05 +0800
> Peter Pan  wrote:
>
>> Hi Boris,
>>
>> On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
>>  wrote:
>> > Hi Peter,
>> >
>> > On Tue, 19 Apr 2016 08:40:40 +0800
>> > Peter Pan  wrote:
>> >>
>> >> >
>> >> >> So it's true, it
>> >> >> should still be numchips in nand_bbt.c?  I just came out this question 
>> >> >> when
>> >> >> making v4. :)
>> >> >
>> >> > BTW, I have something for you [1]. I started to move things around to
>> >> > allow spinand and onenand layers to lie under drivers/mtd/nand/, and I
>> >> > wonder if we shouldn't do this move before reworking the nand_bbt code
>> >> > to make it generic.
>> >> > Note that this rework is not finished yet, but it gives a rough idea of
>> >> > what I'd like to see.
>> >>
>> >> I saw you also rework BBT in your git tree, which is a bit duplicate
>> >> with my BBT patch,
>> >> so should I continue my BBT patch by join part of your BBT rework code
>> >> or continue
>> >> your git tree ?
>> >
>> > Well, if you ask me what I'd prefer, it's clearly the 2nd solution.
>> > Note that my branch should just serve as a reference of what I expect,
>> > it just a pile of rework that should probably be reordered and cleaned
>> > up.
>> >
>> > Here's the sequencing I'd like to see:
>> >
>> > 1/ Move include/linux/mtd/nand.h into include/linux/mtd/rawnand.h and
>> >move all files under drivers/mtd/nand/ into
>> >drivers/mtd/nand/rawnand (including nand_bbt.c). This can be done in
>> >several patches
>> >
>> > 2/ Add the generic nand layer (include/linux/mtd/nand.h and
>> >drivers/mtd/nand/core.c). In my version I put everything in
>> >include/linux/mtd/nand.h, but maybe we'll need a few functions to be
>> >defined in drivers/mtd/nand/core.c.
>> >
>> > 3/ Create a rawnand_device structure inheriting from nand_device, and
>> >then make nand_chip inherit from rawnand_device. Patch the
>> >nand_base.c code to initialize all the nand_device fields properly,
>> >so that we'll be ready to switch to the generic BBT code.
>> >
>> > 4/ Modify the nand_bbt.c code to make use of the generic NAND interface
>> >instead of the MTD and rawnand one (this implies identifying all the
>> >generic helpers you might need, and implementing them in
>> >include/linux/mtd/nand.h or drivers/mtd/nand/core.c).
>> >
>> > 5/ Move drivers/mtd/nand/rawnand/nand_bbt.c into
>> >drivers/mtd/nand/bbt.c
>> >
>> > 6/[optional] Implement your spinand layer in drivers/mtd/nand/spinand
>> >
>> > I know I'm asking a lot, especially given that you already spent a lot
>> > of time iterating on this BBT rework series. But your goal is to move
>> > mt29f driver out of staging, and you'll need to do the generic NAND
>> > layer to achieve that, so I'd really prefer having the BBT code use
>> > this generic layer instead of directly using the MTD API + an extra set
>> > of NAND specific structs (like the nand_chip_layout_info one).
>>
>> Yes, I want to upstreaming my SPI NAND frameworks and it's indeed better
>> to have a nand core. In fact, I already finished a SPI NAND framework with
>> the BBT patch I sent which is directly under MTD (don't have a NAND core 
>> layer).
>>
>> Actually, I'm interested in this NAND framework refining work. And I
>> know you already
>> gave a speech on ELC about this. But due to the resource limitation, I may 
>> not
>> to do all of the things. So how about I continue my BBT patch with
>> your NAND refining
>> ideas. I'll try to make the BBT patch compatible with the refining
>> work. What do you
>> think?
>
> The thing is, I'm not happy with these intermediate reworks, which in my
> opinion are adding more confusion and will make things even harder to
> rework afterward.
> You said you already developed your SPI NAND framework and it's not
> based on the generic NAND layer, which means you (or someone else) will
> have to migrate it to this approach at some point, and this extra work
> is kind of useless, especially since we seem to agree that the generic
> NAND layer is the way to go for

Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-05-03 Thread Peter Pan
Hi Boris,

On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> Hi Peter,
>
> On Tue, 19 Apr 2016 08:40:40 +0800
> Peter Pan <peterpans...@gmail.com> wrote:
>>
>> >
>> >> So it's true, it
>> >> should still be numchips in nand_bbt.c?  I just came out this question 
>> >> when
>> >> making v4. :)
>> >
>> > BTW, I have something for you [1]. I started to move things around to
>> > allow spinand and onenand layers to lie under drivers/mtd/nand/, and I
>> > wonder if we shouldn't do this move before reworking the nand_bbt code
>> > to make it generic.
>> > Note that this rework is not finished yet, but it gives a rough idea of
>> > what I'd like to see.
>>
>> I saw you also rework BBT in your git tree, which is a bit duplicate
>> with my BBT patch,
>> so should I continue my BBT patch by join part of your BBT rework code
>> or continue
>> your git tree ?
>
> Well, if you ask me what I'd prefer, it's clearly the 2nd solution.
> Note that my branch should just serve as a reference of what I expect,
> it just a pile of rework that should probably be reordered and cleaned
> up.
>
> Here's the sequencing I'd like to see:
>
> 1/ Move include/linux/mtd/nand.h into include/linux/mtd/rawnand.h and
>move all files under drivers/mtd/nand/ into
>drivers/mtd/nand/rawnand (including nand_bbt.c). This can be done in
>several patches
>
> 2/ Add the generic nand layer (include/linux/mtd/nand.h and
>drivers/mtd/nand/core.c). In my version I put everything in
>include/linux/mtd/nand.h, but maybe we'll need a few functions to be
>defined in drivers/mtd/nand/core.c.
>
> 3/ Create a rawnand_device structure inheriting from nand_device, and
>then make nand_chip inherit from rawnand_device. Patch the
>nand_base.c code to initialize all the nand_device fields properly,
>so that we'll be ready to switch to the generic BBT code.
>
> 4/ Modify the nand_bbt.c code to make use of the generic NAND interface
>instead of the MTD and rawnand one (this implies identifying all the
>generic helpers you might need, and implementing them in
>include/linux/mtd/nand.h or drivers/mtd/nand/core.c).
>
> 5/ Move drivers/mtd/nand/rawnand/nand_bbt.c into
>drivers/mtd/nand/bbt.c
>
> 6/[optional] Implement your spinand layer in drivers/mtd/nand/spinand
>
> I know I'm asking a lot, especially given that you already spent a lot
> of time iterating on this BBT rework series. But your goal is to move
> mt29f driver out of staging, and you'll need to do the generic NAND
> layer to achieve that, so I'd really prefer having the BBT code use
> this generic layer instead of directly using the MTD API + an extra set
> of NAND specific structs (like the nand_chip_layout_info one).

Yes, I want to upstreaming my SPI NAND frameworks and it's indeed better
to have a nand core. In fact, I already finished a SPI NAND framework with
the BBT patch I sent which is directly under MTD (don't have a NAND core layer).

Actually, I'm interested in this NAND framework refining work. And I
know you already
gave a speech on ELC about this. But due to the resource limitation, I may not
to do all of the things. So how about I continue my BBT patch with
your NAND refining
ideas. I'll try to make the BBT patch compatible with the refining
work. What do you
think?

Thanks,
Peter Pan


Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-05-03 Thread Peter Pan
Hi Boris,

On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
 wrote:
> Hi Peter,
>
> On Tue, 19 Apr 2016 08:40:40 +0800
> Peter Pan  wrote:
>>
>> >
>> >> So it's true, it
>> >> should still be numchips in nand_bbt.c?  I just came out this question 
>> >> when
>> >> making v4. :)
>> >
>> > BTW, I have something for you [1]. I started to move things around to
>> > allow spinand and onenand layers to lie under drivers/mtd/nand/, and I
>> > wonder if we shouldn't do this move before reworking the nand_bbt code
>> > to make it generic.
>> > Note that this rework is not finished yet, but it gives a rough idea of
>> > what I'd like to see.
>>
>> I saw you also rework BBT in your git tree, which is a bit duplicate
>> with my BBT patch,
>> so should I continue my BBT patch by join part of your BBT rework code
>> or continue
>> your git tree ?
>
> Well, if you ask me what I'd prefer, it's clearly the 2nd solution.
> Note that my branch should just serve as a reference of what I expect,
> it just a pile of rework that should probably be reordered and cleaned
> up.
>
> Here's the sequencing I'd like to see:
>
> 1/ Move include/linux/mtd/nand.h into include/linux/mtd/rawnand.h and
>move all files under drivers/mtd/nand/ into
>drivers/mtd/nand/rawnand (including nand_bbt.c). This can be done in
>several patches
>
> 2/ Add the generic nand layer (include/linux/mtd/nand.h and
>drivers/mtd/nand/core.c). In my version I put everything in
>include/linux/mtd/nand.h, but maybe we'll need a few functions to be
>defined in drivers/mtd/nand/core.c.
>
> 3/ Create a rawnand_device structure inheriting from nand_device, and
>then make nand_chip inherit from rawnand_device. Patch the
>nand_base.c code to initialize all the nand_device fields properly,
>so that we'll be ready to switch to the generic BBT code.
>
> 4/ Modify the nand_bbt.c code to make use of the generic NAND interface
>instead of the MTD and rawnand one (this implies identifying all the
>generic helpers you might need, and implementing them in
>include/linux/mtd/nand.h or drivers/mtd/nand/core.c).
>
> 5/ Move drivers/mtd/nand/rawnand/nand_bbt.c into
>drivers/mtd/nand/bbt.c
>
> 6/[optional] Implement your spinand layer in drivers/mtd/nand/spinand
>
> I know I'm asking a lot, especially given that you already spent a lot
> of time iterating on this BBT rework series. But your goal is to move
> mt29f driver out of staging, and you'll need to do the generic NAND
> layer to achieve that, so I'd really prefer having the BBT code use
> this generic layer instead of directly using the MTD API + an extra set
> of NAND specific structs (like the nand_chip_layout_info one).

Yes, I want to upstreaming my SPI NAND frameworks and it's indeed better
to have a nand core. In fact, I already finished a SPI NAND framework with
the BBT patch I sent which is directly under MTD (don't have a NAND core layer).

Actually, I'm interested in this NAND framework refining work. And I
know you already
gave a speech on ELC about this. But due to the resource limitation, I may not
to do all of the things. So how about I continue my BBT patch with
your NAND refining
ideas. I'll try to make the BBT patch compatible with the refining
work. What do you
think?

Thanks,
Peter Pan


Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-04-18 Thread Peter Pan
Hi Boris,

On Mon, Apr 18, 2016 at 3:44 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> Hi Peter,
>
> On Mon, 18 Apr 2016 14:22:09 +0800
> Peter Pan <peterpans...@gmail.com> wrote:
>
>> Hi  Boris,
>>
>> On Fri, Mar 25, 2016 at 4:35 PM, Boris Brezillon
>> <boris.brezil...@free-electrons.com> wrote:
>> > Hi Peter,
>> >
>> > On Mon, 14 Mar 2016 02:47:55 +
>> > Peter Pan <peterpans...@gmail.com> wrote:
>> >
>> >> From: Brian Norris <computersforpe...@gmail.com>
>> >>
>> >> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> >> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> >> onenand has own bbt(onenand_bbt.c).
>> >>
>> >> Separate struct nand_chip from BBT code can make current BBT shareable.
>> >> We create struct nand_bbt to take place of nand_chip in nand_bbt.c
>> >>
>> >> Below is mtd folder structure we want:
>> >>   drivers/mtd/nand/
>> >>   drivers/mtd/nand/raw/
>> >>   drivers/mtd/nand/spi/
>> >>   drivers/mtd/nand/onenand/
>> >>   drivers/mtd/nand/chips/
>> >>
>> >> Of course, nand_bbt.c should be part of .
>> >>
>> >> We put every chip layout related information BBT needed into struct
>> >> nand_chip_layout_info.
>> >>   @numchips:  number of physical chips, required for 
>> >> NAND_BBT_PERCHIP
>> >>   @chipsize:  the size of one chip for multichip arrays
>> >>   @chip_shift:number of address bits in one chip
>> >>   @bbt_erase_shift:   number of address bits in a bbt entry
>> >>   @page_shift:number of address bits in a page
>> >>
>> >> We defined a struct nand_bbt_ops for BBT ops. Struct
>> >>   @is_bad_bbm:check if a block is factory bad block
>> >>   @erase: erase block bypassing resvered checks
>> >>
>> >> Struct nand_bbt includes all BBT information:
>> >>   @mtd:   pointer to MTD device structure
>> >>   @bbt_options:   bad block specific options. All options used
>> >>   here must come from nand_bbt.h.
>> >>   @bbt_ops:   struct nand_bbt_ops pointer.
>> >>   @info:  struct nand_chip_layout_info pointer.
>> >>   @bbt_td:bad block table descriptor for flash lookup.
>> >>   @bbt_md:bad block table mirror descriptor
>> >>   @bbt:   bad block table pointer
>> >>
>> >> Signed-off-by: Brian Norris <computersforpe...@gmail.com>
>> >> [Peter: 1. correct comment style
>> >>   2. introduce struct nand_bbt_ops and nand_chip_layout_info]
>> >> Signed-off-by: Peter Pan <peterpand...@micron.com>
>> >> ---
>> >>  include/linux/mtd/nand_bbt.h | 67 
>> >> 
>> >>  1 file changed, 67 insertions(+)
>> >>
>> >> diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
>> >> index 5a65230..cfb22c8 100644
>> >> --- a/include/linux/mtd/nand_bbt.h
>> >> +++ b/include/linux/mtd/nand_bbt.h
>> >> @@ -18,6 +18,8 @@
>> >>  #ifndef __LINUX_MTD_NAND_BBT_H
>> >>  #define __LINUX_MTD_NAND_BBT_H
>> >>
>> >> +struct mtd_info;
>> >> +
>> >>  /* The maximum number of NAND chips in an array */
>> >>  #define NAND_MAX_CHIPS   8
>> >>
>> >> @@ -115,4 +117,69 @@ struct nand_bbt_descr {
>> >>  /* The maximum number of blocks to scan for a bbt */
>> >>  #define NAND_BBT_SCAN_MAXBLOCKS  4
>> >>
>> >> +struct nand_bbt;
>> >> +
>> >> +/**
>> >> + * struct nand_bbt_ops - bad block table operations
>> >> + * @is_bad_bbm:  check if a block is factory bad block
>> >> + * @erase:   erase block bypassing resvered checks
>> >> + */
>> >> +struct nand_bbt_ops {
>> >> + /*
>> >> +  * This is important to abstract out of nand_bbt.c and provide
>> >> +  * separately in nand_base.c and spi-nand-base.c -- it's sort of
>> >> +  * duplicated in nand_block_bad() (nand_base) and
>> >> +  * scan_block_fast() (nand_bbt) right now
>> >> +  *
>> >

Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-04-18 Thread Peter Pan
Hi Boris,

On Mon, Apr 18, 2016 at 3:44 PM, Boris Brezillon
 wrote:
> Hi Peter,
>
> On Mon, 18 Apr 2016 14:22:09 +0800
> Peter Pan  wrote:
>
>> Hi  Boris,
>>
>> On Fri, Mar 25, 2016 at 4:35 PM, Boris Brezillon
>>  wrote:
>> > Hi Peter,
>> >
>> > On Mon, 14 Mar 2016 02:47:55 +
>> > Peter Pan  wrote:
>> >
>> >> From: Brian Norris 
>> >>
>> >> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> >> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> >> onenand has own bbt(onenand_bbt.c).
>> >>
>> >> Separate struct nand_chip from BBT code can make current BBT shareable.
>> >> We create struct nand_bbt to take place of nand_chip in nand_bbt.c
>> >>
>> >> Below is mtd folder structure we want:
>> >>   drivers/mtd/nand/
>> >>   drivers/mtd/nand/raw/
>> >>   drivers/mtd/nand/spi/
>> >>   drivers/mtd/nand/onenand/
>> >>   drivers/mtd/nand/chips/
>> >>
>> >> Of course, nand_bbt.c should be part of .
>> >>
>> >> We put every chip layout related information BBT needed into struct
>> >> nand_chip_layout_info.
>> >>   @numchips:  number of physical chips, required for 
>> >> NAND_BBT_PERCHIP
>> >>   @chipsize:  the size of one chip for multichip arrays
>> >>   @chip_shift:number of address bits in one chip
>> >>   @bbt_erase_shift:   number of address bits in a bbt entry
>> >>   @page_shift:number of address bits in a page
>> >>
>> >> We defined a struct nand_bbt_ops for BBT ops. Struct
>> >>   @is_bad_bbm:check if a block is factory bad block
>> >>   @erase: erase block bypassing resvered checks
>> >>
>> >> Struct nand_bbt includes all BBT information:
>> >>   @mtd:   pointer to MTD device structure
>> >>   @bbt_options:   bad block specific options. All options used
>> >>   here must come from nand_bbt.h.
>> >>   @bbt_ops:   struct nand_bbt_ops pointer.
>> >>   @info:  struct nand_chip_layout_info pointer.
>> >>   @bbt_td:bad block table descriptor for flash lookup.
>> >>   @bbt_md:bad block table mirror descriptor
>> >>   @bbt:   bad block table pointer
>> >>
>> >> Signed-off-by: Brian Norris 
>> >> [Peter: 1. correct comment style
>> >>   2. introduce struct nand_bbt_ops and nand_chip_layout_info]
>> >> Signed-off-by: Peter Pan 
>> >> ---
>> >>  include/linux/mtd/nand_bbt.h | 67 
>> >> 
>> >>  1 file changed, 67 insertions(+)
>> >>
>> >> diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
>> >> index 5a65230..cfb22c8 100644
>> >> --- a/include/linux/mtd/nand_bbt.h
>> >> +++ b/include/linux/mtd/nand_bbt.h
>> >> @@ -18,6 +18,8 @@
>> >>  #ifndef __LINUX_MTD_NAND_BBT_H
>> >>  #define __LINUX_MTD_NAND_BBT_H
>> >>
>> >> +struct mtd_info;
>> >> +
>> >>  /* The maximum number of NAND chips in an array */
>> >>  #define NAND_MAX_CHIPS   8
>> >>
>> >> @@ -115,4 +117,69 @@ struct nand_bbt_descr {
>> >>  /* The maximum number of blocks to scan for a bbt */
>> >>  #define NAND_BBT_SCAN_MAXBLOCKS  4
>> >>
>> >> +struct nand_bbt;
>> >> +
>> >> +/**
>> >> + * struct nand_bbt_ops - bad block table operations
>> >> + * @is_bad_bbm:  check if a block is factory bad block
>> >> + * @erase:   erase block bypassing resvered checks
>> >> + */
>> >> +struct nand_bbt_ops {
>> >> + /*
>> >> +  * This is important to abstract out of nand_bbt.c and provide
>> >> +  * separately in nand_base.c and spi-nand-base.c -- it's sort of
>> >> +  * duplicated in nand_block_bad() (nand_base) and
>> >> +  * scan_block_fast() (nand_bbt) right now
>> >> +  *
>> >> +  * Note that this also means nand_chip.badblock_pattern should
>> >> +  * be removed from nand_bbt.c
>> >> +  */
>> >> + int (*is_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
>

Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-04-18 Thread Peter Pan
Hi  Boris,

On Fri, Mar 25, 2016 at 4:35 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> Hi Peter,
>
> On Mon, 14 Mar 2016 02:47:55 +0000
> Peter Pan <peterpans...@gmail.com> wrote:
>
>> From: Brian Norris <computersforpe...@gmail.com>
>>
>> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> onenand has own bbt(onenand_bbt.c).
>>
>> Separate struct nand_chip from BBT code can make current BBT shareable.
>> We create struct nand_bbt to take place of nand_chip in nand_bbt.c
>>
>> Below is mtd folder structure we want:
>>   drivers/mtd/nand/
>>   drivers/mtd/nand/raw/
>>   drivers/mtd/nand/spi/
>>   drivers/mtd/nand/onenand/
>>   drivers/mtd/nand/chips/
>>
>> Of course, nand_bbt.c should be part of .
>>
>> We put every chip layout related information BBT needed into struct
>> nand_chip_layout_info.
>>   @numchips:  number of physical chips, required for NAND_BBT_PERCHIP
>>   @chipsize:  the size of one chip for multichip arrays
>>   @chip_shift:number of address bits in one chip
>>   @bbt_erase_shift:   number of address bits in a bbt entry
>>   @page_shift:number of address bits in a page
>>
>> We defined a struct nand_bbt_ops for BBT ops. Struct
>>   @is_bad_bbm:check if a block is factory bad block
>>   @erase: erase block bypassing resvered checks
>>
>> Struct nand_bbt includes all BBT information:
>>   @mtd:   pointer to MTD device structure
>>   @bbt_options:   bad block specific options. All options used
>>   here must come from nand_bbt.h.
>>   @bbt_ops:   struct nand_bbt_ops pointer.
>>   @info:  struct nand_chip_layout_info pointer.
>>   @bbt_td:bad block table descriptor for flash lookup.
>>   @bbt_md:bad block table mirror descriptor
>>   @bbt:   bad block table pointer
>>
>> Signed-off-by: Brian Norris <computersforpe...@gmail.com>
>> [Peter: 1. correct comment style
>>   2. introduce struct nand_bbt_ops and nand_chip_layout_info]
>> Signed-off-by: Peter Pan <peterpand...@micron.com>
>> ---
>>  include/linux/mtd/nand_bbt.h | 67 
>> 
>>  1 file changed, 67 insertions(+)
>>
>> diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
>> index 5a65230..cfb22c8 100644
>> --- a/include/linux/mtd/nand_bbt.h
>> +++ b/include/linux/mtd/nand_bbt.h
>> @@ -18,6 +18,8 @@
>>  #ifndef __LINUX_MTD_NAND_BBT_H
>>  #define __LINUX_MTD_NAND_BBT_H
>>
>> +struct mtd_info;
>> +
>>  /* The maximum number of NAND chips in an array */
>>  #define NAND_MAX_CHIPS   8
>>
>> @@ -115,4 +117,69 @@ struct nand_bbt_descr {
>>  /* The maximum number of blocks to scan for a bbt */
>>  #define NAND_BBT_SCAN_MAXBLOCKS  4
>>
>> +struct nand_bbt;
>> +
>> +/**
>> + * struct nand_bbt_ops - bad block table operations
>> + * @is_bad_bbm:  check if a block is factory bad block
>> + * @erase:   erase block bypassing resvered checks
>> + */
>> +struct nand_bbt_ops {
>> + /*
>> +  * This is important to abstract out of nand_bbt.c and provide
>> +  * separately in nand_base.c and spi-nand-base.c -- it's sort of
>> +  * duplicated in nand_block_bad() (nand_base) and
>> +  * scan_block_fast() (nand_bbt) right now
>> +  *
>> +  * Note that this also means nand_chip.badblock_pattern should
>> +  * be removed from nand_bbt.c
>> +  */
>> + int (*is_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
>> +
>> + /* Erase a block, bypassing reserved checks */
>> + int (*erase)(struct mtd_info *mtd, loff_t ofs);
>> +};
>> +
>> +/**
>> + * struct nand_chip_layout_info - strucure contains all chip layout
>> + * information that BBT needed.
>> + * @numchips:number of physical chips, required for NAND_BBT_PERCHIP
>> + * @chipsize:the size of one chip for multichip arrays
>> + * @chip_shift:  number of address bits in one chip
>> + * @bbt_erase_shift: number of address bits in a bbt entry
>> + * @page_shift:  number of address bits in a page
>> + */
>> +struct nand_chip_layout_info {
>
> I know I'm the one who suggested this name, but NAND datasheet seems to
> call it "memory organization", so maybe we should rename this struct
> nand_memory_organization.
>
>> + int numchips;
>
> I would rename it numdies, or ndies. numchips implies you're having
> several chips, which is not the case.

In struct nand_chip and nand_base.c, numchips stands for the number of
physical nand chips not number of dies(LUNs), am I right? So it's true, it
should still be numchips in nand_bbt.c?  I just came out this question when
making v4. :)

Thanks,
Peter Pan


Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-04-18 Thread Peter Pan
Hi  Boris,

On Fri, Mar 25, 2016 at 4:35 PM, Boris Brezillon
 wrote:
> Hi Peter,
>
> On Mon, 14 Mar 2016 02:47:55 +0000
> Peter Pan  wrote:
>
>> From: Brian Norris 
>>
>> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> onenand has own bbt(onenand_bbt.c).
>>
>> Separate struct nand_chip from BBT code can make current BBT shareable.
>> We create struct nand_bbt to take place of nand_chip in nand_bbt.c
>>
>> Below is mtd folder structure we want:
>>   drivers/mtd/nand/
>>   drivers/mtd/nand/raw/
>>   drivers/mtd/nand/spi/
>>   drivers/mtd/nand/onenand/
>>   drivers/mtd/nand/chips/
>>
>> Of course, nand_bbt.c should be part of .
>>
>> We put every chip layout related information BBT needed into struct
>> nand_chip_layout_info.
>>   @numchips:  number of physical chips, required for NAND_BBT_PERCHIP
>>   @chipsize:  the size of one chip for multichip arrays
>>   @chip_shift:number of address bits in one chip
>>   @bbt_erase_shift:   number of address bits in a bbt entry
>>   @page_shift:number of address bits in a page
>>
>> We defined a struct nand_bbt_ops for BBT ops. Struct
>>   @is_bad_bbm:check if a block is factory bad block
>>   @erase: erase block bypassing resvered checks
>>
>> Struct nand_bbt includes all BBT information:
>>   @mtd:   pointer to MTD device structure
>>   @bbt_options:   bad block specific options. All options used
>>   here must come from nand_bbt.h.
>>   @bbt_ops:   struct nand_bbt_ops pointer.
>>   @info:  struct nand_chip_layout_info pointer.
>>   @bbt_td:bad block table descriptor for flash lookup.
>>   @bbt_md:    bad block table mirror descriptor
>>   @bbt:   bad block table pointer
>>
>> Signed-off-by: Brian Norris 
>> [Peter: 1. correct comment style
>>   2. introduce struct nand_bbt_ops and nand_chip_layout_info]
>> Signed-off-by: Peter Pan 
>> ---
>>  include/linux/mtd/nand_bbt.h | 67 
>> 
>>  1 file changed, 67 insertions(+)
>>
>> diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
>> index 5a65230..cfb22c8 100644
>> --- a/include/linux/mtd/nand_bbt.h
>> +++ b/include/linux/mtd/nand_bbt.h
>> @@ -18,6 +18,8 @@
>>  #ifndef __LINUX_MTD_NAND_BBT_H
>>  #define __LINUX_MTD_NAND_BBT_H
>>
>> +struct mtd_info;
>> +
>>  /* The maximum number of NAND chips in an array */
>>  #define NAND_MAX_CHIPS   8
>>
>> @@ -115,4 +117,69 @@ struct nand_bbt_descr {
>>  /* The maximum number of blocks to scan for a bbt */
>>  #define NAND_BBT_SCAN_MAXBLOCKS  4
>>
>> +struct nand_bbt;
>> +
>> +/**
>> + * struct nand_bbt_ops - bad block table operations
>> + * @is_bad_bbm:  check if a block is factory bad block
>> + * @erase:   erase block bypassing resvered checks
>> + */
>> +struct nand_bbt_ops {
>> + /*
>> +  * This is important to abstract out of nand_bbt.c and provide
>> +  * separately in nand_base.c and spi-nand-base.c -- it's sort of
>> +  * duplicated in nand_block_bad() (nand_base) and
>> +  * scan_block_fast() (nand_bbt) right now
>> +  *
>> +  * Note that this also means nand_chip.badblock_pattern should
>> +  * be removed from nand_bbt.c
>> +  */
>> + int (*is_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
>> +
>> + /* Erase a block, bypassing reserved checks */
>> + int (*erase)(struct mtd_info *mtd, loff_t ofs);
>> +};
>> +
>> +/**
>> + * struct nand_chip_layout_info - strucure contains all chip layout
>> + * information that BBT needed.
>> + * @numchips:number of physical chips, required for NAND_BBT_PERCHIP
>> + * @chipsize:the size of one chip for multichip arrays
>> + * @chip_shift:  number of address bits in one chip
>> + * @bbt_erase_shift: number of address bits in a bbt entry
>> + * @page_shift:  number of address bits in a page
>> + */
>> +struct nand_chip_layout_info {
>
> I know I'm the one who suggested this name, but NAND datasheet seems to
> call it "memory organization", so maybe we should rename this struct
> nand_memory_organization.
>
>> + int numchips;
>
> I would rename it numdies, or ndies. numchips implies you're having
> several chips, which is not the case.

In struct nand_chip and nand_base.c, numchips stands for the number of
physical nand chips not number of dies(LUNs), am I right? So it's true, it
should still be numchips in nand_bbt.c?  I just came out this question when
making v4. :)

Thanks,
Peter Pan


Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT

2016-03-28 Thread Peter Pan
Hi Ezequiel,

Sorry for reply your mail late. And thaks a lot for reviewing it.

On Thu, Mar 24, 2016 at 4:57 AM, Ezequiel Garcia
<ezequ...@vanguardiasur.com.ar> wrote:
> Hello,
>
> On 13 March 2016 at 23:47, Peter Pan <peterpans...@gmail.com> wrote:
>> Sorry for send the v3 out late. I went through a busy time in the past
>> two month.
>>
>> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> onenand has own bbt(onenand_bbt.c).
>>
>> Separate struct nand_chip from BBT code can make current BBT shareable.
>> We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
>> Struct nand_bbt contains all the information BBT needed from outside and
>> it should be embedded into NAND family chip struct (such as struct 
>> nand_chip).
>>
>> Below is mtd folder structure we want:
>> drivers/mtd/nand/
>> drivers/mtd/nand/raw/
>> drivers/mtd/nand/spi/
>> drivers/mtd/nand/onenand/
>> drivers/mtd/nand/chips/
>>
>
> You mention this structure, but nothing in the current patchset is actually
> enforcing it. This is more the future direction we are going.

Yes, this is what we want.
>
>> Most of the patch is borrowed from Brian Norris 
>> <computersforpe...@gmail.com>.
>> http://git.infradead.org/users/norris/linux-mtd.git/shortlog/refs/heads/nand-bbt
>> I decided the authorship of each patch by contribution. Please let me know if
>> there is something unproper.
>> Based on Brian's suggestion and Boris's comments, I make 11 independent
>> patches. Previous patch is http://patchwork.ozlabs.org/patch/492066/
>> After discussion with Boris and Ezequiel, I realized above structure is 
>> better,
>> so I drop the patch to move nand_bbt.c to mtd folder.
>>
>
> I have reviewed this patchset, and it looks mostly good to me. I can
> spot trivial style comments, or comments related to the commit logs, or the
> way commits are splitted.
>
> Boris will probably have more insightful comments to make.
>
> However, before starting my silly bikeshedding I'd like to know if we all
> agree with the patchset's overall scheme.
>
> It would be good to finally move forward with this, to take mt29f out
> of staging and also support other SPI NAND vendors.

Yes. We plan to move mt29f_spi_nand out from staging. But because mt29f_spi_nand
is under raw/parallel NAND framework, it mismatch the stucture we
want. Rewite it
under SPI NAND framework may be a better choice, right? Actually I'm
working on this
now.

Thanks,
Peter Pan


Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT

2016-03-28 Thread Peter Pan
Hi Ezequiel,

Sorry for reply your mail late. And thaks a lot for reviewing it.

On Thu, Mar 24, 2016 at 4:57 AM, Ezequiel Garcia
 wrote:
> Hello,
>
> On 13 March 2016 at 23:47, Peter Pan  wrote:
>> Sorry for send the v3 out late. I went through a busy time in the past
>> two month.
>>
>> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> onenand has own bbt(onenand_bbt.c).
>>
>> Separate struct nand_chip from BBT code can make current BBT shareable.
>> We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
>> Struct nand_bbt contains all the information BBT needed from outside and
>> it should be embedded into NAND family chip struct (such as struct 
>> nand_chip).
>>
>> Below is mtd folder structure we want:
>> drivers/mtd/nand/
>> drivers/mtd/nand/raw/
>> drivers/mtd/nand/spi/
>> drivers/mtd/nand/onenand/
>> drivers/mtd/nand/chips/
>>
>
> You mention this structure, but nothing in the current patchset is actually
> enforcing it. This is more the future direction we are going.

Yes, this is what we want.
>
>> Most of the patch is borrowed from Brian Norris 
>> .
>> http://git.infradead.org/users/norris/linux-mtd.git/shortlog/refs/heads/nand-bbt
>> I decided the authorship of each patch by contribution. Please let me know if
>> there is something unproper.
>> Based on Brian's suggestion and Boris's comments, I make 11 independent
>> patches. Previous patch is http://patchwork.ozlabs.org/patch/492066/
>> After discussion with Boris and Ezequiel, I realized above structure is 
>> better,
>> so I drop the patch to move nand_bbt.c to mtd folder.
>>
>
> I have reviewed this patchset, and it looks mostly good to me. I can
> spot trivial style comments, or comments related to the commit logs, or the
> way commits are splitted.
>
> Boris will probably have more insightful comments to make.
>
> However, before starting my silly bikeshedding I'd like to know if we all
> agree with the patchset's overall scheme.
>
> It would be good to finally move forward with this, to take mt29f out
> of staging and also support other SPI NAND vendors.

Yes. We plan to move mt29f_spi_nand out from staging. But because mt29f_spi_nand
is under raw/parallel NAND framework, it mismatch the stucture we
want. Rewite it
under SPI NAND framework may be a better choice, right? Actually I'm
working on this
now.

Thanks,
Peter Pan


Re: [PATCH 05/11] mtd: nand: use new BBT API instead of old ones

2016-03-28 Thread Peter Pan
On Fri, Mar 25, 2016 at 4:51 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> On Mon, 14 Mar 2016 02:47:58 +0000
> Peter Pan <peterpans...@gmail.com> wrote:
>
>> Use new BBT APIs (nand_bbt_*()) in NAND. Keep old APIs (nand_*_bbt())
>> exist temporarily.
>>
>> Signed-off-by: Brian Norris <computersforpe...@gmail.com>
>> Signed-off-by: Peter Pan <peterpand...@micron.com>
>> ---
>>  drivers/mtd/nand/docg4.c |   7 +-
>>  drivers/mtd/nand/nand_base.c | 151 
>> ---
>>  include/linux/mtd/nand.h |  15 -
>>  3 files changed, 160 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
>> index b6facac..6f0e3b9 100644
>> --- a/drivers/mtd/nand/nand_base.c
>> +++ b/drivers/mtd/nand/nand_base.c
>
> [...]
>
>> +static int nand_default_bbt(struct mtd_info *mtd)
>> +{
>> + struct nand_chip *chip = mtd_to_nand(mtd);
>> + struct nand_bbt *nand_bbt = NULL;
>> + struct nand_chip_layout_info *info =
>> + kzalloc(sizeof(struct nand_chip_layout_info), GFP_KERNEL);
>
> No, this should be directly embedded in nand_chip, and should replace
> the numchips/chipsize/... fields declared in there.

As I said in patch 2, I keep it like this temporarily. Will embedded it in
struct nand_chip later.

Thanks,
Peter Pan


Re: [PATCH 05/11] mtd: nand: use new BBT API instead of old ones

2016-03-28 Thread Peter Pan
On Fri, Mar 25, 2016 at 4:51 PM, Boris Brezillon
 wrote:
> On Mon, 14 Mar 2016 02:47:58 +
> Peter Pan  wrote:
>
>> Use new BBT APIs (nand_bbt_*()) in NAND. Keep old APIs (nand_*_bbt())
>> exist temporarily.
>>
>> Signed-off-by: Brian Norris 
>> Signed-off-by: Peter Pan 
>> ---
>>  drivers/mtd/nand/docg4.c |   7 +-
>>  drivers/mtd/nand/nand_base.c | 151 
>> ---
>>  include/linux/mtd/nand.h |  15 -
>>  3 files changed, 160 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
>> index b6facac..6f0e3b9 100644
>> --- a/drivers/mtd/nand/nand_base.c
>> +++ b/drivers/mtd/nand/nand_base.c
>
> [...]
>
>> +static int nand_default_bbt(struct mtd_info *mtd)
>> +{
>> + struct nand_chip *chip = mtd_to_nand(mtd);
>> + struct nand_bbt *nand_bbt = NULL;
>> + struct nand_chip_layout_info *info =
>> + kzalloc(sizeof(struct nand_chip_layout_info), GFP_KERNEL);
>
> No, this should be directly embedded in nand_chip, and should replace
> the numchips/chipsize/... fields declared in there.

As I said in patch 2, I keep it like this temporarily. Will embedded it in
struct nand_chip later.

Thanks,
Peter Pan


Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-03-28 Thread Peter Pan
Hi Boris,

Firstly, thanks a lot for taking time to review my patches.

On Fri, Mar 25, 2016 at 4:35 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> Hi Peter,
>
> On Mon, 14 Mar 2016 02:47:55 +0000
> Peter Pan <peterpans...@gmail.com> wrote:
>
>> From: Brian Norris <computersforpe...@gmail.com>
>>
>> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> onenand has own bbt(onenand_bbt.c).
>>
>> Separate struct nand_chip from BBT code can make current BBT shareable.
>> We create struct nand_bbt to take place of nand_chip in nand_bbt.c
>>
>> Below is mtd folder structure we want:
>>   drivers/mtd/nand/
>>   drivers/mtd/nand/raw/
>>   drivers/mtd/nand/spi/
>>   drivers/mtd/nand/onenand/
>>   drivers/mtd/nand/chips/
>>
>> Of course, nand_bbt.c should be part of .
>>
>> We put every chip layout related information BBT needed into struct
>> nand_chip_layout_info.
>>   @numchips:  number of physical chips, required for NAND_BBT_PERCHIP
>>   @chipsize:  the size of one chip for multichip arrays
>>   @chip_shift:number of address bits in one chip
>>   @bbt_erase_shift:   number of address bits in a bbt entry
>>   @page_shift:number of address bits in a page
>>
>> We defined a struct nand_bbt_ops for BBT ops. Struct
>>   @is_bad_bbm:check if a block is factory bad block
>>   @erase: erase block bypassing resvered checks
>>
>> Struct nand_bbt includes all BBT information:
>>   @mtd:   pointer to MTD device structure
>>   @bbt_options:   bad block specific options. All options used
>>   here must come from nand_bbt.h.
>>   @bbt_ops:   struct nand_bbt_ops pointer.
>>   @info:  struct nand_chip_layout_info pointer.
>>   @bbt_td:bad block table descriptor for flash lookup.
>>   @bbt_md:bad block table mirror descriptor
>>   @bbt:   bad block table pointer
>>
>> Signed-off-by: Brian Norris <computersforpe...@gmail.com>
>> [Peter: 1. correct comment style
>>   2. introduce struct nand_bbt_ops and nand_chip_layout_info]
>> Signed-off-by: Peter Pan <peterpand...@micron.com>
>> ---
>>  include/linux/mtd/nand_bbt.h | 67 
>> 
>>  1 file changed, 67 insertions(+)
>>
>> diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
>> index 5a65230..cfb22c8 100644
>> --- a/include/linux/mtd/nand_bbt.h
>> +++ b/include/linux/mtd/nand_bbt.h
>> @@ -18,6 +18,8 @@
>>  #ifndef __LINUX_MTD_NAND_BBT_H
>>  #define __LINUX_MTD_NAND_BBT_H
>>
>> +struct mtd_info;
>> +
>>  /* The maximum number of NAND chips in an array */
>>  #define NAND_MAX_CHIPS   8
>>
>> @@ -115,4 +117,69 @@ struct nand_bbt_descr {
>>  /* The maximum number of blocks to scan for a bbt */
>>  #define NAND_BBT_SCAN_MAXBLOCKS  4
>>
>> +struct nand_bbt;
>> +
>> +/**
>> + * struct nand_bbt_ops - bad block table operations
>> + * @is_bad_bbm:  check if a block is factory bad block
>> + * @erase:   erase block bypassing resvered checks
>> + */
>> +struct nand_bbt_ops {
>> + /*
>> +  * This is important to abstract out of nand_bbt.c and provide
>> +  * separately in nand_base.c and spi-nand-base.c -- it's sort of
>> +  * duplicated in nand_block_bad() (nand_base) and
>> +  * scan_block_fast() (nand_bbt) right now
>> +  *
>> +  * Note that this also means nand_chip.badblock_pattern should
>> +  * be removed from nand_bbt.c
>> +  */
>> + int (*is_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
>> +
>> + /* Erase a block, bypassing reserved checks */
>> + int (*erase)(struct mtd_info *mtd, loff_t ofs);
>> +};
>> +
>> +/**
>> + * struct nand_chip_layout_info - strucure contains all chip layout
>> + * information that BBT needed.
>> + * @numchips:number of physical chips, required for NAND_BBT_PERCHIP
>> + * @chipsize:the size of one chip for multichip arrays
>> + * @chip_shift:  number of address bits in one chip
>> + * @bbt_erase_shift: number of address bits in a bbt entry
>> + * @page_shift:  number of address bits in a page
>> + */
>> +struct nand_chip_layout_info {
>
> I know I'm the one who suggested this name, but NAND datasheet

Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-03-28 Thread Peter Pan
Hi Boris,

Firstly, thanks a lot for taking time to review my patches.

On Fri, Mar 25, 2016 at 4:35 PM, Boris Brezillon
 wrote:
> Hi Peter,
>
> On Mon, 14 Mar 2016 02:47:55 +0000
> Peter Pan  wrote:
>
>> From: Brian Norris 
>>
>> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> onenand has own bbt(onenand_bbt.c).
>>
>> Separate struct nand_chip from BBT code can make current BBT shareable.
>> We create struct nand_bbt to take place of nand_chip in nand_bbt.c
>>
>> Below is mtd folder structure we want:
>>   drivers/mtd/nand/
>>   drivers/mtd/nand/raw/
>>   drivers/mtd/nand/spi/
>>   drivers/mtd/nand/onenand/
>>   drivers/mtd/nand/chips/
>>
>> Of course, nand_bbt.c should be part of .
>>
>> We put every chip layout related information BBT needed into struct
>> nand_chip_layout_info.
>>   @numchips:  number of physical chips, required for NAND_BBT_PERCHIP
>>   @chipsize:  the size of one chip for multichip arrays
>>   @chip_shift:number of address bits in one chip
>>   @bbt_erase_shift:   number of address bits in a bbt entry
>>   @page_shift:number of address bits in a page
>>
>> We defined a struct nand_bbt_ops for BBT ops. Struct
>>   @is_bad_bbm:check if a block is factory bad block
>>   @erase: erase block bypassing resvered checks
>>
>> Struct nand_bbt includes all BBT information:
>>   @mtd:   pointer to MTD device structure
>>   @bbt_options:   bad block specific options. All options used
>>   here must come from nand_bbt.h.
>>   @bbt_ops:   struct nand_bbt_ops pointer.
>>   @info:  struct nand_chip_layout_info pointer.
>>   @bbt_td:bad block table descriptor for flash lookup.
>>   @bbt_md:    bad block table mirror descriptor
>>   @bbt:   bad block table pointer
>>
>> Signed-off-by: Brian Norris 
>> [Peter: 1. correct comment style
>>   2. introduce struct nand_bbt_ops and nand_chip_layout_info]
>> Signed-off-by: Peter Pan 
>> ---
>>  include/linux/mtd/nand_bbt.h | 67 
>> 
>>  1 file changed, 67 insertions(+)
>>
>> diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
>> index 5a65230..cfb22c8 100644
>> --- a/include/linux/mtd/nand_bbt.h
>> +++ b/include/linux/mtd/nand_bbt.h
>> @@ -18,6 +18,8 @@
>>  #ifndef __LINUX_MTD_NAND_BBT_H
>>  #define __LINUX_MTD_NAND_BBT_H
>>
>> +struct mtd_info;
>> +
>>  /* The maximum number of NAND chips in an array */
>>  #define NAND_MAX_CHIPS   8
>>
>> @@ -115,4 +117,69 @@ struct nand_bbt_descr {
>>  /* The maximum number of blocks to scan for a bbt */
>>  #define NAND_BBT_SCAN_MAXBLOCKS  4
>>
>> +struct nand_bbt;
>> +
>> +/**
>> + * struct nand_bbt_ops - bad block table operations
>> + * @is_bad_bbm:  check if a block is factory bad block
>> + * @erase:   erase block bypassing resvered checks
>> + */
>> +struct nand_bbt_ops {
>> + /*
>> +  * This is important to abstract out of nand_bbt.c and provide
>> +  * separately in nand_base.c and spi-nand-base.c -- it's sort of
>> +  * duplicated in nand_block_bad() (nand_base) and
>> +  * scan_block_fast() (nand_bbt) right now
>> +  *
>> +  * Note that this also means nand_chip.badblock_pattern should
>> +  * be removed from nand_bbt.c
>> +  */
>> + int (*is_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
>> +
>> + /* Erase a block, bypassing reserved checks */
>> + int (*erase)(struct mtd_info *mtd, loff_t ofs);
>> +};
>> +
>> +/**
>> + * struct nand_chip_layout_info - strucure contains all chip layout
>> + * information that BBT needed.
>> + * @numchips:number of physical chips, required for NAND_BBT_PERCHIP
>> + * @chipsize:the size of one chip for multichip arrays
>> + * @chip_shift:  number of address bits in one chip
>> + * @bbt_erase_shift: number of address bits in a bbt entry
>> + * @page_shift:  number of address bits in a page
>> + */
>> +struct nand_chip_layout_info {
>
> I know I'm the one who suggested this name, but NAND datasheet seems to
> call it "memory organization", so maybe we should rename this struct
> nand_memory_organization.

Fix this in v4
>
>> + int numchips;
>

Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT

2016-03-28 Thread Peter Pan
On Fri, Mar 25, 2016 at 4:50 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> On Mon, 14 Mar 2016 02:47:53 +0000
> Peter Pan <peterpans...@gmail.com> wrote:
>
>> Sorry for send the v3 out late. I went through a busy time in the past
>> two month.
>>
>> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> onenand has own bbt(onenand_bbt.c).
>>
>> Separate struct nand_chip from BBT code can make current BBT shareable.
>> We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
>> Struct nand_bbt contains all the information BBT needed from outside and
>> it should be embedded into NAND family chip struct (such as struct 
>> nand_chip).
>>
>> Below is mtd folder structure we want:
>>   drivers/mtd/nand/
>>   drivers/mtd/nand/raw/
>>   drivers/mtd/nand/spi/
>>   drivers/mtd/nand/onenand/
>>   drivers/mtd/nand/chips/
>
> Hm, we should have a chips directory under each interface type, because
> vendor specific handling is dependent on the NAND interface.
> Otherwise, yes, that's the idea.

Update this in v4

Thanks,
Peter Pan


Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT

2016-03-28 Thread Peter Pan
On Fri, Mar 25, 2016 at 4:50 PM, Boris Brezillon
 wrote:
> On Mon, 14 Mar 2016 02:47:53 +
> Peter Pan  wrote:
>
>> Sorry for send the v3 out late. I went through a busy time in the past
>> two month.
>>
>> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
>> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> onenand has own bbt(onenand_bbt.c).
>>
>> Separate struct nand_chip from BBT code can make current BBT shareable.
>> We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
>> Struct nand_bbt contains all the information BBT needed from outside and
>> it should be embedded into NAND family chip struct (such as struct 
>> nand_chip).
>>
>> Below is mtd folder structure we want:
>>   drivers/mtd/nand/
>>   drivers/mtd/nand/raw/
>>   drivers/mtd/nand/spi/
>>   drivers/mtd/nand/onenand/
>>   drivers/mtd/nand/chips/
>
> Hm, we should have a chips directory under each interface type, because
> vendor specific handling is dependent on the NAND interface.
> Otherwise, yes, that's the idea.

Update this in v4

Thanks,
Peter Pan


Re: [PATCH 03/11] mtd: nand_bbt: add new API definitions

2016-03-28 Thread Peter Pan
On Fri, Mar 25, 2016 at 4:49 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> On Mon, 14 Mar 2016 02:47:56 +0000
> Peter Pan <peterpans...@gmail.com> wrote:
>
>> Add new API definitions for nand_bbt to replace old ones without
>> any users. These API includes:
>>   struct nand_bbt_create(struct mtd_info *mtd);
>>   struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
>>   const struct nand_bbt_ops *ops,
>>   struct nand_chip_layout_info *info,
>>   unsigned int options,
>>   struct nand_bbt_descr *bbt_td,
>>   struct nand_bbt_descr *bbt_md);
>>   void nand_bbt_destroy(struct nand_bbt *bbt);
>>   int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
>>   int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
>>   int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);
>>
>> Signed-off-by: Brian Norris <computersforpe...@gmail.com>
>> Signed-off-by: Peter Pan <peterpand...@micron.com>
>> ---
>>  drivers/mtd/nand/nand_bbt.c  | 113 
>> +++
>>  include/linux/mtd/nand_bbt.h |  11 +
>>  2 files changed, 124 insertions(+)
>>
>
>>
>> +struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
>> + const struct nand_bbt_ops *ops,
>> + struct nand_chip_layout_info *info,
>
> Should be const struct nand_chip_layout_info *.

Fix this in v4

Thanks,
Peter Pan


Re: [PATCH 03/11] mtd: nand_bbt: add new API definitions

2016-03-28 Thread Peter Pan
On Fri, Mar 25, 2016 at 4:49 PM, Boris Brezillon
 wrote:
> On Mon, 14 Mar 2016 02:47:56 +
> Peter Pan  wrote:
>
>> Add new API definitions for nand_bbt to replace old ones without
>> any users. These API includes:
>>   struct nand_bbt_create(struct mtd_info *mtd);
>>   struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
>>   const struct nand_bbt_ops *ops,
>>   struct nand_chip_layout_info *info,
>>   unsigned int options,
>>   struct nand_bbt_descr *bbt_td,
>>   struct nand_bbt_descr *bbt_md);
>>   void nand_bbt_destroy(struct nand_bbt *bbt);
>>   int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
>>   int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
>>   int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);
>>
>> Signed-off-by: Brian Norris 
>> Signed-off-by: Peter Pan 
>> ---
>>  drivers/mtd/nand/nand_bbt.c  | 113 
>> +++
>>  include/linux/mtd/nand_bbt.h |  11 +
>>  2 files changed, 124 insertions(+)
>>
>
>>
>> +struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
>> + const struct nand_bbt_ops *ops,
>> + struct nand_chip_layout_info *info,
>
> Should be const struct nand_chip_layout_info *.

Fix this in v4

Thanks,
Peter Pan


Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT

2016-03-13 Thread Peter Pan
Sorry I forgot to add subject prefix. Should I re-send it ?

On Mon, Mar 14, 2016 at 10:47 AM, Peter Pan <peterpans...@gmail.com> wrote:
> Sorry for send the v3 out late. I went through a busy time in the past
> two month.
>
> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
> onenand has own bbt(onenand_bbt.c).
>
> Separate struct nand_chip from BBT code can make current BBT shareable.
> We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
> Struct nand_bbt contains all the information BBT needed from outside and
> it should be embedded into NAND family chip struct (such as struct nand_chip).
>
> Below is mtd folder structure we want:
> drivers/mtd/nand/
> drivers/mtd/nand/raw/
> drivers/mtd/nand/spi/
> drivers/mtd/nand/onenand/
> drivers/mtd/nand/chips/
>
> Most of the patch is borrowed from Brian Norris <computersforpe...@gmail.com>.
> http://git.infradead.org/users/norris/linux-mtd.git/shortlog/refs/heads/nand-bbt
> I decided the authorship of each patch by contribution. Please let me know if
> there is something unproper.
> Based on Brian's suggestion and Boris's comments, I make 11 independent
> patches. Previous patch is http://patchwork.ozlabs.org/patch/492066/
> After discussion with Boris and Ezequiel, I realized above structure is 
> better,
> so I drop the patch to move nand_bbt.c to mtd folder.
>
> The patch is tested on Zed board.
>
> v3 changes:
> introduce struct nand_bbt_ops
> introduce struct nand_chip_layout_info
> add nand_bbt_create/destroy() API
> use mtd_to_nand instead mtd->priv directly
> remove mark_bad_bbm() due to no user yet
> keep nand_bbt.c in mtd/nand folder
> add nand_get_bbt() helper function
> rebase patch series on 4.5.0-rc1
> v2 changes:
> rebase patch series on master branch of l2-mtd.git
>
>
> Brian Norris (7):
>   mtd: nand_bbt: new header for nand family BBT
>   mtd: nand_bbt: introduce BBT related data structure
>   mtd: nand_bbt: use struct nand_bbt_ops in BBT
>   mtd: nand: make nand_erase_nand() static
>   mtd: nand_bbt: remove struct nand_chip from nand_bbt.c
>   mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro
>   mtd: nand: remove nand_chip.bbt
>
> Peter Pan (4):
>   mtd: nand_bbt: add new API definitions
>   mtd: nand_bbt: add nand_bbt_markbad_factory() interface
>   mtd: nand: use new BBT API instead of old ones
>   mtd: nand_bbt: remove old API definitions
>
>  drivers/mtd/nand/docg4.c |   7 +-
>  drivers/mtd/nand/nand_base.c | 156 ++-
>  drivers/mtd/nand/nand_bbt.c  | 604 
> +--
>  include/linux/mtd/bbm.h  |  96 +--
>  include/linux/mtd/nand.h |  22 +-
>  include/linux/mtd/nand_bbt.h | 190 ++
>  6 files changed, 644 insertions(+), 431 deletions(-)
>  create mode 100644 include/linux/mtd/nand_bbt.h
>
> --
> 1.9.1
>


Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT

2016-03-13 Thread Peter Pan
Sorry I forgot to add subject prefix. Should I re-send it ?

On Mon, Mar 14, 2016 at 10:47 AM, Peter Pan  wrote:
> Sorry for send the v3 out late. I went through a busy time in the past
> two month.
>
> Currently nand_bbt.c is tied with struct nand_chip, and it makes other
> NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
> onenand has own bbt(onenand_bbt.c).
>
> Separate struct nand_chip from BBT code can make current BBT shareable.
> We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
> Struct nand_bbt contains all the information BBT needed from outside and
> it should be embedded into NAND family chip struct (such as struct nand_chip).
>
> Below is mtd folder structure we want:
> drivers/mtd/nand/
> drivers/mtd/nand/raw/
> drivers/mtd/nand/spi/
> drivers/mtd/nand/onenand/
> drivers/mtd/nand/chips/
>
> Most of the patch is borrowed from Brian Norris .
> http://git.infradead.org/users/norris/linux-mtd.git/shortlog/refs/heads/nand-bbt
> I decided the authorship of each patch by contribution. Please let me know if
> there is something unproper.
> Based on Brian's suggestion and Boris's comments, I make 11 independent
> patches. Previous patch is http://patchwork.ozlabs.org/patch/492066/
> After discussion with Boris and Ezequiel, I realized above structure is 
> better,
> so I drop the patch to move nand_bbt.c to mtd folder.
>
> The patch is tested on Zed board.
>
> v3 changes:
> introduce struct nand_bbt_ops
> introduce struct nand_chip_layout_info
> add nand_bbt_create/destroy() API
> use mtd_to_nand instead mtd->priv directly
> remove mark_bad_bbm() due to no user yet
> keep nand_bbt.c in mtd/nand folder
> add nand_get_bbt() helper function
> rebase patch series on 4.5.0-rc1
> v2 changes:
> rebase patch series on master branch of l2-mtd.git
>
>
> Brian Norris (7):
>   mtd: nand_bbt: new header for nand family BBT
>   mtd: nand_bbt: introduce BBT related data structure
>   mtd: nand_bbt: use struct nand_bbt_ops in BBT
>   mtd: nand: make nand_erase_nand() static
>   mtd: nand_bbt: remove struct nand_chip from nand_bbt.c
>   mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro
>   mtd: nand: remove nand_chip.bbt
>
> Peter Pan (4):
>   mtd: nand_bbt: add new API definitions
>   mtd: nand_bbt: add nand_bbt_markbad_factory() interface
>   mtd: nand: use new BBT API instead of old ones
>   mtd: nand_bbt: remove old API definitions
>
>  drivers/mtd/nand/docg4.c |   7 +-
>  drivers/mtd/nand/nand_base.c | 156 ++-
>  drivers/mtd/nand/nand_bbt.c  | 604 
> +--
>  include/linux/mtd/bbm.h  |  96 +--
>  include/linux/mtd/nand.h |  22 +-
>  include/linux/mtd/nand_bbt.h | 190 ++
>  6 files changed, 644 insertions(+), 431 deletions(-)
>  create mode 100644 include/linux/mtd/nand_bbt.h
>
> --
> 1.9.1
>


[PATCH 11/11] mtd: nand: remove nand_chip.bbt

2016-03-13 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

With new nand_bbt.c, nand_chip doesn't need bbt element any more

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 include/linux/mtd/nand.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d180e86..00c2dbb 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -651,7 +651,6 @@ struct nand_buffers {
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
- * @bbt:   [INTERN] bad block table pointer
  * @nand_bbt:  [INTERN] pointer to bad block table structure, which
  * includes all information needed by Bad Block Management
  * @bbt_td:[REPLACEABLE] bad block table descriptor for flash
@@ -739,7 +738,6 @@ struct nand_chip {
struct nand_buffers *buffers;
struct nand_hw_control hwcontrol;
 
-   uint8_t *bbt;
struct nand_bbt *nand_bbt;
struct nand_bbt_descr *bbt_td;
struct nand_bbt_descr *bbt_md;
-- 
1.9.1



[PATCH 06/11] mtd: nand_bbt: use struct nand_bbt_ops in BBT

2016-03-13 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

Since NAND already create its nand_bbt struct, we can use erase()
hook instead of call nand_erase_nand() directly. Also, we can use
is_bad_bbm() to avoid passing badblock_pattern to BBT.

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
[Peter: remove @buf in create_bbt()
introduce struct nand_bbt_ops]
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c | 140 +---
 1 file changed, 14 insertions(+), 126 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 2ac90a1..d319822 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -122,23 +122,6 @@ static int check_pattern(uint8_t *buf, int len, int 
paglen, struct nand_bbt_desc
 }
 
 /**
- * check_short_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf: the buffer to search
- * @td:search pattern descriptor
- *
- * Check for a pattern at the given place. Used to search bad block tables and
- * good / bad block identifiers. Same as check_pattern, but no optional empty
- * check.
- */
-static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
-{
-   /* Compare the pattern */
-   if (memcmp(buf + td->offs, td->pattern, td->len))
-   return -1;
-   return 0;
-}
-
-/**
  * add_marker_len - compute the length of the marker in data area
  * @td: BBT descriptor used for computation
  *
@@ -409,63 +392,24 @@ static void read_abs_bbts(struct mtd_info *mtd, uint8_t 
*buf,
}
 }
 
-/* Scan a given block partially */
-static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
-  loff_t offs, uint8_t *buf, int numpages)
-{
-   struct mtd_oob_ops ops;
-   int j, ret;
-
-   ops.ooblen = mtd->oobsize;
-   ops.oobbuf = buf;
-   ops.ooboffs = 0;
-   ops.datbuf = NULL;
-   ops.mode = MTD_OPS_PLACE_OOB;
-
-   for (j = 0; j < numpages; j++) {
-   /*
-* Read the full oob until read_oob is fixed to handle single
-* byte reads for 16 bit buswidth.
-*/
-   ret = mtd_read_oob(mtd, offs, );
-   /* Ignore ECC errors when checking for BBM */
-   if (ret && !mtd_is_bitflip_or_eccerr(ret))
-   return ret;
-
-   if (check_short_pattern(buf, bd))
-   return 1;
-
-   offs += mtd->writesize;
-   }
-   return 0;
-}
-
 /**
  * create_bbt - [GENERIC] Create a bad block table by scanning the device
  * @mtd: MTD device structure
- * @buf: temporary buffer
- * @bd: descriptor for the good/bad block search pattern
  * @chip: create the table for a specific chip, -1 read all chips; applies only
  *if NAND_BBT_PERCHIP option is set
  *
  * Create a bad block table by scanning the device for the given good/bad block
  * identify pattern.
  */
-static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
-   struct nand_bbt_descr *bd, int chip)
+static int create_bbt(struct mtd_info *mtd, int chip)
 {
struct nand_chip *this = mtd_to_nand(mtd);
-   int i, numblocks, numpages;
-   int startblock;
+   int i, numblocks, startblock;
loff_t from;
+   struct nand_bbt *nand_bbt = nand_get_bbt(this);
 
pr_info("Scanning device for bad blocks\n");
 
-   if (bd->options & NAND_BBT_SCAN2NDPAGE)
-   numpages = 2;
-   else
-   numpages = 1;
-
if (chip == -1) {
numblocks = mtd->size >> this->bbt_erase_shift;
startblock = 0;
@@ -482,15 +426,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
from = (loff_t)startblock << this->bbt_erase_shift;
}
 
-   if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
-   from += mtd->erasesize - (mtd->writesize * numpages);
-
for (i = startblock; i < numblocks; i++) {
int ret;
 
-   BUG_ON(bd->options & NAND_BBT_NO_OOB);
-
-   ret = scan_block_fast(mtd, bd, from, buf, numpages);
+   ret = nand_bbt->bbt_ops->is_bad_bbm(mtd, from);
if (ret < 0)
return ret;
 
@@ -619,7 +558,6 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 int chipsel)
 {
struct nand_chip *this = mtd_to_nand(mtd);
-   struct erase_info einfo;
int i, res, chip = 0;
int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
int nrchips, pageoffs, ooboffs;
@@ -628,6 +566,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
size_t retlen, len = 0;
loff_t to;
struct mtd_oob_ops ops;
+   struct nand_bbt *nand_bbt = nand_get_bbt(this);
 

[PATCH 07/11] mtd: nand: make nand_erase_nand() static

2016-03-13 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

nand_bbt.c doesn't need to call nand_erase_nand() any more.

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_base.c | 5 -
 include/linux/mtd/nand.h | 2 --
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 6f0e3b9..371e65f 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -97,6 +97,9 @@ static int nand_get_device(struct mtd_info *mtd, int 
new_state);
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 struct mtd_oob_ops *ops);
 
+static int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+  int allowbbt);
+
 /*
  * For devices which display every fart in the system on a separate LED. Is
  * compiled away when LED support is disabled.
@@ -2897,7 +2900,7 @@ static int nand_erase(struct mtd_info *mtd, struct 
erase_info *instr)
  *
  * Erase one ore more blocks.
  */
-int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+static int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
int allowbbt)
 {
int page, status, pages_per_block, ret, chipnr;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 5072041..8730afd 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -896,8 +896,6 @@ extern struct nand_manufacturers nand_manuf_ids[];
 extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
 extern int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs);
 extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
-extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
-  int allowbbt);
 extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, uint8_t *buf);
 
-- 
1.9.1



[PATCH 09/11] mtd: nand_bbt: remove old API definitions

2016-03-13 Thread Peter Pan
remove old BBT APIs

Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c | 94 -
 include/linux/mtd/nand.h|  3 --
 2 files changed, 15 insertions(+), 82 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 0dda0c5..ef887c0 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1180,13 +1180,14 @@ static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
 };
 
 /**
- * nand_default_bbt - [NAND Interface] Select a default bad block table for 
the device
+ * nand_bbt_init - [NAND BBT Interface] Initialize and locate/create a bad 
block
+ * table
  * @bbt: NAND BBT structure
  *
  * This function selects the default bad block table support for the device and
- * calls the nand_scan_bbt function.
+ * scans for an existing table, or else creates one.
  */
-int nand_default_bbt(struct nand_bbt *bbt)
+static int nand_bbt_init(struct nand_bbt *bbt)
 {
/* Is a flash based bad block table requested? */
if (bbt->bbt_options & NAND_BBT_USE_FLASH) {
@@ -1209,11 +1210,11 @@ int nand_default_bbt(struct nand_bbt *bbt)
 }
 
 /**
- * nand_isreserved_bbt - [NAND Interface] Check if a block is reserved
+ * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
  * @bbt: NAND BBT structure
  * @offs: offset in the device
  */
-int nand_isreserved_bbt(struct nand_bbt *bbt, loff_t offs)
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
 {
struct nand_chip_layout_info *info = bbt->info;
int block;
@@ -1221,14 +1222,14 @@ int nand_isreserved_bbt(struct nand_bbt *bbt, loff_t 
offs)
block = (int)(offs >> info->bbt_erase_shift);
return bbt_get_entry(bbt, block) == BBT_BLOCK_RESERVED;
 }
+EXPORT_SYMBOL(nand_bbt_isreserved);
 
 /**
- * nand_isbad_bbt - [NAND Interface] Check if a block is bad
+ * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
  * @bbt: NAND BBT structure
  * @offs: offset in the device
- * @allowbbt: allow access to bad block table region
  */
-int nand_isbad_bbt(struct nand_bbt *bbt, loff_t offs, int allowbbt)
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
 {
struct nand_chip_layout_info *info = bbt->info;
int block, res;
@@ -1236,19 +1237,20 @@ int nand_isbad_bbt(struct nand_bbt *bbt, loff_t offs, 
int allowbbt)
block = (int)(offs >> info->bbt_erase_shift);
res = bbt_get_entry(bbt, block);
 
-   pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 
0x%02x\n",
+   pr_debug("nand_bbt_isbad(): bbt info for offs 0x%08x: (block %d) 
0x%02x\n",
 (unsigned int)offs, block, res);
 
switch (res) {
case BBT_BLOCK_GOOD:
+   case BBT_BLOCK_RESERVED:
return 0;
case BBT_BLOCK_WORN:
+   case BBT_BLOCK_FACTORY_BAD:
+   default:
return 1;
-   case BBT_BLOCK_RESERVED:
-   return allowbbt ? 0 : 1;
}
-   return 1;
 }
+EXPORT_SYMBOL(nand_bbt_isbad);
 
 /**
  * nand_bbt_update_mark - update mark in the BBT
@@ -1273,32 +1275,6 @@ static int nand_bbt_update_mark(struct nand_bbt *bbt, 
loff_t offs, uint8_t mark)
return ret;
 }
 
-/**
- * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
- * @bbt: NAND BBT structure
- * @offs: offset of the bad block
- */
-int nand_markbad_bbt(struct nand_bbt *bbt, loff_t offs)
-{
-   return nand_bbt_update_mark(bbt, offs, BBT_BLOCK_WORN);
-}
-
-/**
- * nand_bbt_init - Initialize and locate/create a bad block table
- * @bbt: NAND BBT structure
- *
- * This function selects the default bad block table support for the device and
- * scans for an existing table, or else creates one.
- */
-static int nand_bbt_init(struct nand_bbt *bbt)
-{
-   /*
-* FIXME: For now, we call nand_default_bbt() directly. It will change
-* when we use struct nand_bbt instead of struct nand_chip.
-*/
-   return nand_default_bbt(bbt);
-}
-
 static void nand_bbt_release(struct nand_bbt *bbt)
 {
kfree(bbt->bbt);
@@ -1350,49 +1326,13 @@ void nand_bbt_destroy(struct nand_bbt *bbt)
 EXPORT_SYMBOL(nand_bbt_destroy);
 
 /**
- * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
- * @bbt: NAND BBT structure
- * @offs: offset in the device
- */
-int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
-{
-   /*
-* FIXME: For now, we call nand_isreserved_bbt() directly. It will
-* change when we use struct nand_bbt instead of struct nand_chip.
-*/
-   return nand_isreserved_bbt(bbt, offs);
-}
-EXPORT_SYMBOL(nand_bbt_isreserved);
-
-/**
- * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
- * @bbt: NAND BBT structure
- * @offs: offset in the device
- */
-int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
-{
-   /*
-* FIXME: For now, we call nand

[PATCH 06/11] mtd: nand_bbt: use struct nand_bbt_ops in BBT

2016-03-13 Thread Peter Pan
From: Brian Norris 

Since NAND already create its nand_bbt struct, we can use erase()
hook instead of call nand_erase_nand() directly. Also, we can use
is_bad_bbm() to avoid passing badblock_pattern to BBT.

Signed-off-by: Brian Norris 
[Peter: remove @buf in create_bbt()
introduce struct nand_bbt_ops]
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c | 140 +---
 1 file changed, 14 insertions(+), 126 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 2ac90a1..d319822 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -122,23 +122,6 @@ static int check_pattern(uint8_t *buf, int len, int 
paglen, struct nand_bbt_desc
 }
 
 /**
- * check_short_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf: the buffer to search
- * @td:search pattern descriptor
- *
- * Check for a pattern at the given place. Used to search bad block tables and
- * good / bad block identifiers. Same as check_pattern, but no optional empty
- * check.
- */
-static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
-{
-   /* Compare the pattern */
-   if (memcmp(buf + td->offs, td->pattern, td->len))
-   return -1;
-   return 0;
-}
-
-/**
  * add_marker_len - compute the length of the marker in data area
  * @td: BBT descriptor used for computation
  *
@@ -409,63 +392,24 @@ static void read_abs_bbts(struct mtd_info *mtd, uint8_t 
*buf,
}
 }
 
-/* Scan a given block partially */
-static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
-  loff_t offs, uint8_t *buf, int numpages)
-{
-   struct mtd_oob_ops ops;
-   int j, ret;
-
-   ops.ooblen = mtd->oobsize;
-   ops.oobbuf = buf;
-   ops.ooboffs = 0;
-   ops.datbuf = NULL;
-   ops.mode = MTD_OPS_PLACE_OOB;
-
-   for (j = 0; j < numpages; j++) {
-   /*
-* Read the full oob until read_oob is fixed to handle single
-* byte reads for 16 bit buswidth.
-*/
-   ret = mtd_read_oob(mtd, offs, );
-   /* Ignore ECC errors when checking for BBM */
-   if (ret && !mtd_is_bitflip_or_eccerr(ret))
-   return ret;
-
-   if (check_short_pattern(buf, bd))
-   return 1;
-
-   offs += mtd->writesize;
-   }
-   return 0;
-}
-
 /**
  * create_bbt - [GENERIC] Create a bad block table by scanning the device
  * @mtd: MTD device structure
- * @buf: temporary buffer
- * @bd: descriptor for the good/bad block search pattern
  * @chip: create the table for a specific chip, -1 read all chips; applies only
  *if NAND_BBT_PERCHIP option is set
  *
  * Create a bad block table by scanning the device for the given good/bad block
  * identify pattern.
  */
-static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
-   struct nand_bbt_descr *bd, int chip)
+static int create_bbt(struct mtd_info *mtd, int chip)
 {
struct nand_chip *this = mtd_to_nand(mtd);
-   int i, numblocks, numpages;
-   int startblock;
+   int i, numblocks, startblock;
loff_t from;
+   struct nand_bbt *nand_bbt = nand_get_bbt(this);
 
pr_info("Scanning device for bad blocks\n");
 
-   if (bd->options & NAND_BBT_SCAN2NDPAGE)
-   numpages = 2;
-   else
-   numpages = 1;
-
if (chip == -1) {
numblocks = mtd->size >> this->bbt_erase_shift;
startblock = 0;
@@ -482,15 +426,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
from = (loff_t)startblock << this->bbt_erase_shift;
}
 
-   if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
-   from += mtd->erasesize - (mtd->writesize * numpages);
-
for (i = startblock; i < numblocks; i++) {
int ret;
 
-   BUG_ON(bd->options & NAND_BBT_NO_OOB);
-
-   ret = scan_block_fast(mtd, bd, from, buf, numpages);
+   ret = nand_bbt->bbt_ops->is_bad_bbm(mtd, from);
if (ret < 0)
return ret;
 
@@ -619,7 +558,6 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 int chipsel)
 {
struct nand_chip *this = mtd_to_nand(mtd);
-   struct erase_info einfo;
int i, res, chip = 0;
int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
int nrchips, pageoffs, ooboffs;
@@ -628,6 +566,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
size_t retlen, len = 0;
loff_t to;
struct mtd_oob_ops ops;
+   struct nand_bbt *nand_bbt = nand_get_bbt(this);
 
ops.ooblen = mtd->oobsize;
ops.ooboffs = 0;
@@ -782,11 +721,7 @@ static int write_

[PATCH 07/11] mtd: nand: make nand_erase_nand() static

2016-03-13 Thread Peter Pan
From: Brian Norris 

nand_bbt.c doesn't need to call nand_erase_nand() any more.

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_base.c | 5 -
 include/linux/mtd/nand.h | 2 --
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 6f0e3b9..371e65f 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -97,6 +97,9 @@ static int nand_get_device(struct mtd_info *mtd, int 
new_state);
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 struct mtd_oob_ops *ops);
 
+static int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+  int allowbbt);
+
 /*
  * For devices which display every fart in the system on a separate LED. Is
  * compiled away when LED support is disabled.
@@ -2897,7 +2900,7 @@ static int nand_erase(struct mtd_info *mtd, struct 
erase_info *instr)
  *
  * Erase one ore more blocks.
  */
-int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+static int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
int allowbbt)
 {
int page, status, pages_per_block, ret, chipnr;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 5072041..8730afd 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -896,8 +896,6 @@ extern struct nand_manufacturers nand_manuf_ids[];
 extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
 extern int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs);
 extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
-extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
-  int allowbbt);
 extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, uint8_t *buf);
 
-- 
1.9.1



[PATCH 09/11] mtd: nand_bbt: remove old API definitions

2016-03-13 Thread Peter Pan
remove old BBT APIs

Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c | 94 -
 include/linux/mtd/nand.h|  3 --
 2 files changed, 15 insertions(+), 82 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 0dda0c5..ef887c0 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1180,13 +1180,14 @@ static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
 };
 
 /**
- * nand_default_bbt - [NAND Interface] Select a default bad block table for 
the device
+ * nand_bbt_init - [NAND BBT Interface] Initialize and locate/create a bad 
block
+ * table
  * @bbt: NAND BBT structure
  *
  * This function selects the default bad block table support for the device and
- * calls the nand_scan_bbt function.
+ * scans for an existing table, or else creates one.
  */
-int nand_default_bbt(struct nand_bbt *bbt)
+static int nand_bbt_init(struct nand_bbt *bbt)
 {
/* Is a flash based bad block table requested? */
if (bbt->bbt_options & NAND_BBT_USE_FLASH) {
@@ -1209,11 +1210,11 @@ int nand_default_bbt(struct nand_bbt *bbt)
 }
 
 /**
- * nand_isreserved_bbt - [NAND Interface] Check if a block is reserved
+ * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
  * @bbt: NAND BBT structure
  * @offs: offset in the device
  */
-int nand_isreserved_bbt(struct nand_bbt *bbt, loff_t offs)
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
 {
struct nand_chip_layout_info *info = bbt->info;
int block;
@@ -1221,14 +1222,14 @@ int nand_isreserved_bbt(struct nand_bbt *bbt, loff_t 
offs)
block = (int)(offs >> info->bbt_erase_shift);
return bbt_get_entry(bbt, block) == BBT_BLOCK_RESERVED;
 }
+EXPORT_SYMBOL(nand_bbt_isreserved);
 
 /**
- * nand_isbad_bbt - [NAND Interface] Check if a block is bad
+ * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
  * @bbt: NAND BBT structure
  * @offs: offset in the device
- * @allowbbt: allow access to bad block table region
  */
-int nand_isbad_bbt(struct nand_bbt *bbt, loff_t offs, int allowbbt)
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
 {
struct nand_chip_layout_info *info = bbt->info;
int block, res;
@@ -1236,19 +1237,20 @@ int nand_isbad_bbt(struct nand_bbt *bbt, loff_t offs, 
int allowbbt)
block = (int)(offs >> info->bbt_erase_shift);
res = bbt_get_entry(bbt, block);
 
-   pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 
0x%02x\n",
+   pr_debug("nand_bbt_isbad(): bbt info for offs 0x%08x: (block %d) 
0x%02x\n",
 (unsigned int)offs, block, res);
 
switch (res) {
case BBT_BLOCK_GOOD:
+   case BBT_BLOCK_RESERVED:
return 0;
case BBT_BLOCK_WORN:
+   case BBT_BLOCK_FACTORY_BAD:
+   default:
return 1;
-   case BBT_BLOCK_RESERVED:
-   return allowbbt ? 0 : 1;
}
-   return 1;
 }
+EXPORT_SYMBOL(nand_bbt_isbad);
 
 /**
  * nand_bbt_update_mark - update mark in the BBT
@@ -1273,32 +1275,6 @@ static int nand_bbt_update_mark(struct nand_bbt *bbt, 
loff_t offs, uint8_t mark)
return ret;
 }
 
-/**
- * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
- * @bbt: NAND BBT structure
- * @offs: offset of the bad block
- */
-int nand_markbad_bbt(struct nand_bbt *bbt, loff_t offs)
-{
-   return nand_bbt_update_mark(bbt, offs, BBT_BLOCK_WORN);
-}
-
-/**
- * nand_bbt_init - Initialize and locate/create a bad block table
- * @bbt: NAND BBT structure
- *
- * This function selects the default bad block table support for the device and
- * scans for an existing table, or else creates one.
- */
-static int nand_bbt_init(struct nand_bbt *bbt)
-{
-   /*
-* FIXME: For now, we call nand_default_bbt() directly. It will change
-* when we use struct nand_bbt instead of struct nand_chip.
-*/
-   return nand_default_bbt(bbt);
-}
-
 static void nand_bbt_release(struct nand_bbt *bbt)
 {
kfree(bbt->bbt);
@@ -1350,49 +1326,13 @@ void nand_bbt_destroy(struct nand_bbt *bbt)
 EXPORT_SYMBOL(nand_bbt_destroy);
 
 /**
- * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
- * @bbt: NAND BBT structure
- * @offs: offset in the device
- */
-int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
-{
-   /*
-* FIXME: For now, we call nand_isreserved_bbt() directly. It will
-* change when we use struct nand_bbt instead of struct nand_chip.
-*/
-   return nand_isreserved_bbt(bbt, offs);
-}
-EXPORT_SYMBOL(nand_bbt_isreserved);
-
-/**
- * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
- * @bbt: NAND BBT structure
- * @offs: offset in the device
- */
-int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
-{
-   /*
-* FIXME: For now, we call nand_isbad_bbt() directly. It will

[PATCH 11/11] mtd: nand: remove nand_chip.bbt

2016-03-13 Thread Peter Pan
From: Brian Norris 

With new nand_bbt.c, nand_chip doesn't need bbt element any more

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 include/linux/mtd/nand.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d180e86..00c2dbb 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -651,7 +651,6 @@ struct nand_buffers {
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
- * @bbt:   [INTERN] bad block table pointer
  * @nand_bbt:  [INTERN] pointer to bad block table structure, which
  * includes all information needed by Bad Block Management
  * @bbt_td:[REPLACEABLE] bad block table descriptor for flash
@@ -739,7 +738,6 @@ struct nand_chip {
struct nand_buffers *buffers;
struct nand_hw_control hwcontrol;
 
-   uint8_t *bbt;
struct nand_bbt *nand_bbt;
struct nand_bbt_descr *bbt_td;
struct nand_bbt_descr *bbt_md;
-- 
1.9.1



[PATCH 10/11] mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro

2016-03-13 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

nand_bbt doesn't need nand badblock_pattern any more. So remove
NAND_BBT_DYNAMICSTRUCT from nand_bbt.h

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 include/linux/mtd/nand_bbt.h | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index a0683b0..ec3d5ec 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -107,13 +107,6 @@ struct nand_bbt_descr {
  */
 #define NAND_BBT_NO_OOB_BBM0x0008
 
-/*
- * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
- * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
- * in nand_chip.bbt_options.
- */
-#define NAND_BBT_DYNAMICSTRUCT 0x8000
-
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS4
 
-- 
1.9.1



[PATCH 08/11] mtd: nand_bbt: remove struct nand_chip from nand_bbt.c

2016-03-13 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

This commit contains most of modification. But the job is quite
simple --- replace struct nand_chip with struct nand_bbt, nand_bbt_ops
and nand_chip_layout_info . There is no algorithm change, just
replacement.

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
[Peter Pan: replacement with struct nand_chip_layout_info]
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c | 410 +++-
 1 file changed, 210 insertions(+), 200 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index d319822..0dda0c5 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -60,8 +60,7 @@
 #include 
 #include 
 #include 
-#include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -76,20 +75,20 @@
 #define BBT_ENTRY_MASK 0x03
 #define BBT_ENTRY_SHIFT2
 
-static int nand_update_bbt(struct mtd_info *mtd, loff_t offs);
+static int nand_update_bbt(struct nand_bbt *bbt, loff_t offs);
 
-static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block)
+static inline uint8_t bbt_get_entry(struct nand_bbt *bbt, int block)
 {
-   uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT];
+   uint8_t entry = bbt->bbt[block >> BBT_ENTRY_SHIFT];
entry >>= (block & BBT_ENTRY_MASK) * 2;
return entry & BBT_ENTRY_MASK;
 }
 
-static inline void bbt_mark_entry(struct nand_chip *chip, int block,
+static inline void bbt_mark_entry(struct nand_bbt *bbt, int block,
uint8_t mark)
 {
uint8_t msk = (mark & BBT_ENTRY_MASK) << ((block & BBT_ENTRY_MASK) * 2);
-   chip->bbt[block >> BBT_ENTRY_SHIFT] |= msk;
+   bbt->bbt[block >> BBT_ENTRY_SHIFT] |= msk;
 }
 
 static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
@@ -142,7 +141,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
 
 /**
  * read_bbt - [GENERIC] Read the bad block table starting from page
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @page: the starting page
  * @num: the number of bbt descriptors to read
@@ -151,11 +150,12 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
  *
  * Read the bad block table starting from page.
  */
-static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
+static int read_bbt(struct nand_bbt *bbt, uint8_t *buf, int page, int num,
struct nand_bbt_descr *td, int offs)
 {
+   struct mtd_info *mtd = bbt->mtd;
+   struct nand_chip_layout_info *info = bbt->info;
int res, ret = 0, i, j, act = 0;
-   struct nand_chip *this = mtd_to_nand(mtd);
size_t retlen, len, totlen;
loff_t from;
int bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -165,10 +165,10 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, 
int page, int num,
 
totlen = (num * bits) >> 3;
marker_len = add_marker_len(td);
-   from = ((loff_t)page) << this->page_shift;
+   from = ((loff_t)page) << info->page_shift;
 
while (totlen) {
-   len = min(totlen, (size_t)(1 << this->bbt_erase_shift));
+   len = min(totlen, (size_t)(1 << info->bbt_erase_shift));
if (marker_len) {
/*
 * In case the BBT marker is not in the OOB area it
@@ -204,8 +204,8 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int 
page, int num,
if (reserved_block_code && (tmp == 
reserved_block_code)) {
pr_info("nand_read_bbt: reserved block 
at 0x%012llx\n",
 (loff_t)(offs + act) <<
-this->bbt_erase_shift);
-   bbt_mark_entry(this, offs + act,
+info->bbt_erase_shift);
+   bbt_mark_entry(bbt, offs + act,
BBT_BLOCK_RESERVED);
mtd->ecc_stats.bbtblocks++;
continue;
@@ -216,13 +216,13 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, 
int page, int num,
 */
pr_info("nand_read_bbt: bad block at 
0x%012llx\n",
 (loff_t)(offs + act) <<
-this->bbt_erase_shift);
+info->bbt_erase_shift);
/* Factory marked bad or worn out? 

[PATCH 10/11] mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro

2016-03-13 Thread Peter Pan
From: Brian Norris 

nand_bbt doesn't need nand badblock_pattern any more. So remove
NAND_BBT_DYNAMICSTRUCT from nand_bbt.h

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 include/linux/mtd/nand_bbt.h | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index a0683b0..ec3d5ec 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -107,13 +107,6 @@ struct nand_bbt_descr {
  */
 #define NAND_BBT_NO_OOB_BBM0x0008
 
-/*
- * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
- * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
- * in nand_chip.bbt_options.
- */
-#define NAND_BBT_DYNAMICSTRUCT 0x8000
-
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS4
 
-- 
1.9.1



[PATCH 08/11] mtd: nand_bbt: remove struct nand_chip from nand_bbt.c

2016-03-13 Thread Peter Pan
From: Brian Norris 

This commit contains most of modification. But the job is quite
simple --- replace struct nand_chip with struct nand_bbt, nand_bbt_ops
and nand_chip_layout_info . There is no algorithm change, just
replacement.

Signed-off-by: Brian Norris 
[Peter Pan: replacement with struct nand_chip_layout_info]
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c | 410 +++-
 1 file changed, 210 insertions(+), 200 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index d319822..0dda0c5 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -60,8 +60,7 @@
 #include 
 #include 
 #include 
-#include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -76,20 +75,20 @@
 #define BBT_ENTRY_MASK 0x03
 #define BBT_ENTRY_SHIFT2
 
-static int nand_update_bbt(struct mtd_info *mtd, loff_t offs);
+static int nand_update_bbt(struct nand_bbt *bbt, loff_t offs);
 
-static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block)
+static inline uint8_t bbt_get_entry(struct nand_bbt *bbt, int block)
 {
-   uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT];
+   uint8_t entry = bbt->bbt[block >> BBT_ENTRY_SHIFT];
entry >>= (block & BBT_ENTRY_MASK) * 2;
return entry & BBT_ENTRY_MASK;
 }
 
-static inline void bbt_mark_entry(struct nand_chip *chip, int block,
+static inline void bbt_mark_entry(struct nand_bbt *bbt, int block,
uint8_t mark)
 {
uint8_t msk = (mark & BBT_ENTRY_MASK) << ((block & BBT_ENTRY_MASK) * 2);
-   chip->bbt[block >> BBT_ENTRY_SHIFT] |= msk;
+   bbt->bbt[block >> BBT_ENTRY_SHIFT] |= msk;
 }
 
 static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
@@ -142,7 +141,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
 
 /**
  * read_bbt - [GENERIC] Read the bad block table starting from page
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @page: the starting page
  * @num: the number of bbt descriptors to read
@@ -151,11 +150,12 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
  *
  * Read the bad block table starting from page.
  */
-static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
+static int read_bbt(struct nand_bbt *bbt, uint8_t *buf, int page, int num,
struct nand_bbt_descr *td, int offs)
 {
+   struct mtd_info *mtd = bbt->mtd;
+   struct nand_chip_layout_info *info = bbt->info;
int res, ret = 0, i, j, act = 0;
-   struct nand_chip *this = mtd_to_nand(mtd);
size_t retlen, len, totlen;
loff_t from;
int bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -165,10 +165,10 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, 
int page, int num,
 
totlen = (num * bits) >> 3;
marker_len = add_marker_len(td);
-   from = ((loff_t)page) << this->page_shift;
+   from = ((loff_t)page) << info->page_shift;
 
while (totlen) {
-   len = min(totlen, (size_t)(1 << this->bbt_erase_shift));
+   len = min(totlen, (size_t)(1 << info->bbt_erase_shift));
if (marker_len) {
/*
 * In case the BBT marker is not in the OOB area it
@@ -204,8 +204,8 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int 
page, int num,
if (reserved_block_code && (tmp == 
reserved_block_code)) {
pr_info("nand_read_bbt: reserved block 
at 0x%012llx\n",
 (loff_t)(offs + act) <<
-this->bbt_erase_shift);
-   bbt_mark_entry(this, offs + act,
+info->bbt_erase_shift);
+   bbt_mark_entry(bbt, offs + act,
BBT_BLOCK_RESERVED);
mtd->ecc_stats.bbtblocks++;
continue;
@@ -216,13 +216,13 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, 
int page, int num,
 */
pr_info("nand_read_bbt: bad block at 
0x%012llx\n",
 (loff_t)(offs + act) <<
-this->bbt_erase_shift);
+info->bbt_erase_shift);
/* Factory marked bad or worn out? */
if (tmp == 0)
-   bbt_mark_entry(this, offs + act,
+ 

[PATCH 04/11] mtd: nand_bbt: add nand_bbt_markbad_factory() interface

2016-03-13 Thread Peter Pan
Some nand controller drivers(like docg4.c) mark factory bad block
mark by accessing bbt buffer directly, so create this API to avoid
breaking layer.

Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c  | 33 ++---
 include/linux/mtd/nand_bbt.h |  1 +
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index aab734e..2ac90a1 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1353,11 +1353,12 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, 
int allowbbt)
 }
 
 /**
- * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
+ * nand_bbt_update_mark - update mark in the BBT
  * @mtd: MTD device structure
  * @offs: offset of the bad block
+ * @mark: block type mark
  */
-int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
+static int nand_bbt_update_mark(struct mtd_info *mtd, loff_t offs, uint8_t 
mark)
 {
struct nand_chip *this = mtd_to_nand(mtd);
int block, ret = 0;
@@ -1365,7 +1366,7 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
block = (int)(offs >> this->bbt_erase_shift);
 
/* Mark bad block in memory */
-   bbt_mark_entry(this, block, BBT_BLOCK_WORN);
+   bbt_mark_entry(this, block, mark);
 
/* Update flash-based bad block table */
if (this->bbt_options & NAND_BBT_USE_FLASH)
@@ -1375,6 +1376,16 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
 }
 
 /**
+ * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
+ * @mtd: MTD device structure
+ * @offs: offset of the bad block
+ */
+int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
+{
+   return nand_bbt_update_mark(mtd, offs, BBT_BLOCK_WORN);
+}
+
+/**
  * nand_bbt_init - Initialize and locate/create a bad block table
  * @bbt: NAND BBT structure
  *
@@ -1486,3 +1497,19 @@ int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs)
return nand_markbad_bbt(bbt->mtd, offs);
 }
 EXPORT_SYMBOL(nand_bbt_markbad);
+
+/**
+ * nand_bbt_markbad_factory - [NAND BBT Interface] Mark a block as factory bad
+ * in the BBT
+ * @bbt: NAND BBT structure
+ * @offs: offset of the bad block
+ */
+int nand_bbt_markbad_factory(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_markbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_bbt_update_mark(bbt->mtd, offs, BBT_BLOCK_FACTORY_BAD);
+}
+EXPORT_SYMBOL(nand_bbt_markbad_factory);
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index c651d95..a0683b0 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -192,5 +192,6 @@ void nand_bbt_destroy(struct nand_bbt *bbt);
 int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
 int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
 int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);
+int nand_bbt_markbad_factory(struct nand_bbt *bbt, loff_t offs);
 
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1



[PATCH 05/11] mtd: nand: use new BBT API instead of old ones

2016-03-13 Thread Peter Pan
Use new BBT APIs (nand_bbt_*()) in NAND. Keep old APIs (nand_*_bbt())
exist temporarily.

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/docg4.c |   7 +-
 drivers/mtd/nand/nand_base.c | 151 ---
 include/linux/mtd/nand.h |  15 -
 3 files changed, 160 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index d86a60e..6fce881 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -1021,6 +1021,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
uint8_t *buf;
int i, block;
__u32 eccfailed_stats = mtd->ecc_stats.failed;
+   struct nand_bbt *nand_bbt = nand_get_bbt(nand);
 
buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
if (buf == NULL)
@@ -1036,7 +1037,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
 * operation after device power-up.  The above read ensures it never is.
 * Ugly, I know.
 */
-   if (nand->bbt == NULL)  /* no memory-based bbt */
+   if (nand_bbt == NULL)  /* no memory-based bbt */
goto exit;
 
if (mtd->ecc_stats.failed > eccfailed_stats) {
@@ -1063,8 +1064,8 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
unsigned long bits = ~buf[i];
for_each_set_bit(bitnum, , 8) {
int badblock = block + 7 - bitnum;
-   nand->bbt[badblock / 4] |=
-   0x03 << ((badblock % 4) * 2);
+   nand_bbt_markbad_factory(nand_bbt,
+   badblock << nand->bbt_erase_shift);
mtd->ecc_stats.badblocks++;
dev_notice(doc->dev, "factory-marked bad block: %d\n",
   badblock);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index b6facac..6f0e3b9 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -417,6 +417,7 @@ static int nand_block_markbad_lowlevel(struct mtd_info 
*mtd, loff_t ofs)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
int res, ret = 0;
+   struct nand_bbt *nand_bbt = nand_get_bbt(chip);
 
if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) {
struct erase_info einfo;
@@ -435,8 +436,8 @@ static int nand_block_markbad_lowlevel(struct mtd_info 
*mtd, loff_t ofs)
}
 
/* Mark block bad in BBT */
-   if (chip->bbt) {
-   res = nand_markbad_bbt(mtd, ofs);
+   if (nand_bbt) {
+   res = nand_bbt_markbad(nand_bbt, ofs);
if (!ret)
ret = res;
}
@@ -477,11 +478,12 @@ static int nand_check_wp(struct mtd_info *mtd)
 static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_bbt *nand_bbt = nand_get_bbt(chip);
 
-   if (!chip->bbt)
+   if (!nand_bbt)
return 0;
/* Return info from the table */
-   return nand_isreserved_bbt(mtd, ofs);
+   return nand_bbt_isreserved(nand_bbt, ofs);
 }
 
 /**
@@ -496,12 +498,18 @@ static int nand_block_isreserved(struct mtd_info *mtd, 
loff_t ofs)
 static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_bbt *nand_bbt = nand_get_bbt(chip);
 
-   if (!chip->bbt)
+   if (!nand_bbt)
return chip->block_bad(mtd, ofs);
 
/* Return info from the table */
-   return nand_isbad_bbt(mtd, ofs, allowbbt);
+   if (nand_bbt_isbad(nand_bbt, ofs))
+   return 1;
+   else if (allowbbt)
+   return 0;
+   else
+   return nand_bbt_isreserved(nand_bbt, ofs);
 }
 
 /**
@@ -2996,6 +3004,129 @@ erase_exit:
return ret;
 }
 
+/* NAND BBT helper - erase a block, including reserved blocks */
+static int nand_bbt_erase_block(struct mtd_info *mtd, loff_t addr)
+{
+   struct erase_info einfo;
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
+   memset(, 0, sizeof(einfo));
+   einfo.mtd = mtd;
+   einfo.addr = addr;
+   einfo.len = 1ULL << chip->phys_erase_shift;
+
+   return nand_erase_nand(mtd, , 1);
+}
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+#define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB)
+/**
+ * nand_create_factory_badblock_pattern - [INTERN] Creates a BBT descriptor
+ * structure for factory bad block marker
+ * @chip: NAND chip to create descriptor for
+ *
+ * This function allocates and initializes a badblock_pattern for factory bad
+ * block marker based on the properties of @chip when chip.badblock_pattern
+ * is NULL.
+ */
+static int nand_create

[PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-03-13 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

Currently nand_bbt.c is tied with struct nand_chip, and it makes other
NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
onenand has own bbt(onenand_bbt.c).

Separate struct nand_chip from BBT code can make current BBT shareable.
We create struct nand_bbt to take place of nand_chip in nand_bbt.c

Below is mtd folder structure we want:
drivers/mtd/nand/
drivers/mtd/nand/raw/
drivers/mtd/nand/spi/
drivers/mtd/nand/onenand/
drivers/mtd/nand/chips/

Of course, nand_bbt.c should be part of .

We put every chip layout related information BBT needed into struct
nand_chip_layout_info.
@numchips:  number of physical chips, required for NAND_BBT_PERCHIP
@chipsize:  the size of one chip for multichip arrays
@chip_shift:number of address bits in one chip
@bbt_erase_shift:   number of address bits in a bbt entry
@page_shift:number of address bits in a page

We defined a struct nand_bbt_ops for BBT ops. Struct
@is_bad_bbm:check if a block is factory bad block
@erase: erase block bypassing resvered checks

Struct nand_bbt includes all BBT information:
@mtd:   pointer to MTD device structure
@bbt_options:   bad block specific options. All options used
here must come from nand_bbt.h.
@bbt_ops:   struct nand_bbt_ops pointer.
@info:  struct nand_chip_layout_info pointer.
@bbt_td:bad block table descriptor for flash lookup.
@bbt_md:bad block table mirror descriptor
@bbt:   bad block table pointer

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
[Peter: 1. correct comment style
2. introduce struct nand_bbt_ops and nand_chip_layout_info]
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 include/linux/mtd/nand_bbt.h | 67 
 1 file changed, 67 insertions(+)

diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index 5a65230..cfb22c8 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -18,6 +18,8 @@
 #ifndef __LINUX_MTD_NAND_BBT_H
 #define __LINUX_MTD_NAND_BBT_H
 
+struct mtd_info;
+
 /* The maximum number of NAND chips in an array */
 #define NAND_MAX_CHIPS 8
 
@@ -115,4 +117,69 @@ struct nand_bbt_descr {
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS4
 
+struct nand_bbt;
+
+/**
+ * struct nand_bbt_ops - bad block table operations
+ * @is_bad_bbm:check if a block is factory bad block
+ * @erase: erase block bypassing resvered checks
+ */
+struct nand_bbt_ops {
+   /*
+* This is important to abstract out of nand_bbt.c and provide
+* separately in nand_base.c and spi-nand-base.c -- it's sort of
+* duplicated in nand_block_bad() (nand_base) and
+* scan_block_fast() (nand_bbt) right now
+*
+* Note that this also means nand_chip.badblock_pattern should
+* be removed from nand_bbt.c
+*/
+   int (*is_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
+
+   /* Erase a block, bypassing reserved checks */
+   int (*erase)(struct mtd_info *mtd, loff_t ofs);
+};
+
+/**
+ * struct nand_chip_layout_info - strucure contains all chip layout
+ * information that BBT needed.
+ * @numchips:  number of physical chips, required for NAND_BBT_PERCHIP
+ * @chipsize:  the size of one chip for multichip arrays
+ * @chip_shift:number of address bits in one chip
+ * @bbt_erase_shift:   number of address bits in a bbt entry
+ * @page_shift:number of address bits in a page
+ */
+struct nand_chip_layout_info {
+   int numchips;
+   u64 chipsize;
+   int chip_shift;
+   int bbt_erase_shift;
+   int page_shift;
+};
+
+/**
+ * struct nand_bbt - bad block table structure
+ * @mtd:   pointer to MTD device structure
+ * @bbt_options:   bad block specific options. All options used
+ * here must come from nand_bbt.h.
+ * @bbt_ops:   struct nand_bbt_ops pointer.
+ * @info:  struct nand_chip_layout_info pointer.
+ * @bbt_td:bad block table descriptor for flash lookup.
+ * @bbt_md:bad block table mirror descriptor
+ * @bbt:   bad block table pointer
+ */
+struct nand_bbt {
+   struct mtd_info *mtd;
+   unsigned int bbt_options;
+   const struct nand_bbt_ops *bbt_ops;
+   struct nand_chip_layout_info *info;
+   /*
+* Discourage new custom usages here; suggest usage of the
+* relevant NAND_BBT_* options instead
+*/
+   struct nand_bbt_descr *bbt_td;
+   struct nand_bbt_descr *bbt_md;
+   u8 *bbt;
+};
+
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1



[PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure

2016-03-13 Thread Peter Pan
From: Brian Norris 

Currently nand_bbt.c is tied with struct nand_chip, and it makes other
NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
onenand has own bbt(onenand_bbt.c).

Separate struct nand_chip from BBT code can make current BBT shareable.
We create struct nand_bbt to take place of nand_chip in nand_bbt.c

Below is mtd folder structure we want:
drivers/mtd/nand/
drivers/mtd/nand/raw/
drivers/mtd/nand/spi/
drivers/mtd/nand/onenand/
drivers/mtd/nand/chips/

Of course, nand_bbt.c should be part of .

We put every chip layout related information BBT needed into struct
nand_chip_layout_info.
@numchips:  number of physical chips, required for NAND_BBT_PERCHIP
@chipsize:  the size of one chip for multichip arrays
@chip_shift:number of address bits in one chip
@bbt_erase_shift:   number of address bits in a bbt entry
@page_shift:number of address bits in a page

We defined a struct nand_bbt_ops for BBT ops. Struct
@is_bad_bbm:check if a block is factory bad block
@erase: erase block bypassing resvered checks

Struct nand_bbt includes all BBT information:
@mtd:   pointer to MTD device structure
@bbt_options:   bad block specific options. All options used
here must come from nand_bbt.h.
@bbt_ops:   struct nand_bbt_ops pointer.
@info:  struct nand_chip_layout_info pointer.
@bbt_td:bad block table descriptor for flash lookup.
@bbt_md:bad block table mirror descriptor
@bbt:   bad block table pointer

Signed-off-by: Brian Norris 
[Peter: 1. correct comment style
2. introduce struct nand_bbt_ops and nand_chip_layout_info]
Signed-off-by: Peter Pan 
---
 include/linux/mtd/nand_bbt.h | 67 
 1 file changed, 67 insertions(+)

diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index 5a65230..cfb22c8 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -18,6 +18,8 @@
 #ifndef __LINUX_MTD_NAND_BBT_H
 #define __LINUX_MTD_NAND_BBT_H
 
+struct mtd_info;
+
 /* The maximum number of NAND chips in an array */
 #define NAND_MAX_CHIPS 8
 
@@ -115,4 +117,69 @@ struct nand_bbt_descr {
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS4
 
+struct nand_bbt;
+
+/**
+ * struct nand_bbt_ops - bad block table operations
+ * @is_bad_bbm:check if a block is factory bad block
+ * @erase: erase block bypassing resvered checks
+ */
+struct nand_bbt_ops {
+   /*
+* This is important to abstract out of nand_bbt.c and provide
+* separately in nand_base.c and spi-nand-base.c -- it's sort of
+* duplicated in nand_block_bad() (nand_base) and
+* scan_block_fast() (nand_bbt) right now
+*
+* Note that this also means nand_chip.badblock_pattern should
+* be removed from nand_bbt.c
+*/
+   int (*is_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
+
+   /* Erase a block, bypassing reserved checks */
+   int (*erase)(struct mtd_info *mtd, loff_t ofs);
+};
+
+/**
+ * struct nand_chip_layout_info - strucure contains all chip layout
+ * information that BBT needed.
+ * @numchips:  number of physical chips, required for NAND_BBT_PERCHIP
+ * @chipsize:  the size of one chip for multichip arrays
+ * @chip_shift:number of address bits in one chip
+ * @bbt_erase_shift:   number of address bits in a bbt entry
+ * @page_shift:number of address bits in a page
+ */
+struct nand_chip_layout_info {
+   int numchips;
+   u64 chipsize;
+   int chip_shift;
+   int bbt_erase_shift;
+   int page_shift;
+};
+
+/**
+ * struct nand_bbt - bad block table structure
+ * @mtd:   pointer to MTD device structure
+ * @bbt_options:   bad block specific options. All options used
+ * here must come from nand_bbt.h.
+ * @bbt_ops:   struct nand_bbt_ops pointer.
+ * @info:  struct nand_chip_layout_info pointer.
+ * @bbt_td:bad block table descriptor for flash lookup.
+ * @bbt_md:bad block table mirror descriptor
+ * @bbt:   bad block table pointer
+ */
+struct nand_bbt {
+   struct mtd_info *mtd;
+   unsigned int bbt_options;
+   const struct nand_bbt_ops *bbt_ops;
+   struct nand_chip_layout_info *info;
+   /*
+* Discourage new custom usages here; suggest usage of the
+* relevant NAND_BBT_* options instead
+*/
+   struct nand_bbt_descr *bbt_td;
+   struct nand_bbt_descr *bbt_md;
+   u8 *bbt;
+};
+
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1



[PATCH 04/11] mtd: nand_bbt: add nand_bbt_markbad_factory() interface

2016-03-13 Thread Peter Pan
Some nand controller drivers(like docg4.c) mark factory bad block
mark by accessing bbt buffer directly, so create this API to avoid
breaking layer.

Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c  | 33 ++---
 include/linux/mtd/nand_bbt.h |  1 +
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index aab734e..2ac90a1 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1353,11 +1353,12 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, 
int allowbbt)
 }
 
 /**
- * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
+ * nand_bbt_update_mark - update mark in the BBT
  * @mtd: MTD device structure
  * @offs: offset of the bad block
+ * @mark: block type mark
  */
-int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
+static int nand_bbt_update_mark(struct mtd_info *mtd, loff_t offs, uint8_t 
mark)
 {
struct nand_chip *this = mtd_to_nand(mtd);
int block, ret = 0;
@@ -1365,7 +1366,7 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
block = (int)(offs >> this->bbt_erase_shift);
 
/* Mark bad block in memory */
-   bbt_mark_entry(this, block, BBT_BLOCK_WORN);
+   bbt_mark_entry(this, block, mark);
 
/* Update flash-based bad block table */
if (this->bbt_options & NAND_BBT_USE_FLASH)
@@ -1375,6 +1376,16 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
 }
 
 /**
+ * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
+ * @mtd: MTD device structure
+ * @offs: offset of the bad block
+ */
+int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
+{
+   return nand_bbt_update_mark(mtd, offs, BBT_BLOCK_WORN);
+}
+
+/**
  * nand_bbt_init - Initialize and locate/create a bad block table
  * @bbt: NAND BBT structure
  *
@@ -1486,3 +1497,19 @@ int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs)
return nand_markbad_bbt(bbt->mtd, offs);
 }
 EXPORT_SYMBOL(nand_bbt_markbad);
+
+/**
+ * nand_bbt_markbad_factory - [NAND BBT Interface] Mark a block as factory bad
+ * in the BBT
+ * @bbt: NAND BBT structure
+ * @offs: offset of the bad block
+ */
+int nand_bbt_markbad_factory(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_markbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_bbt_update_mark(bbt->mtd, offs, BBT_BLOCK_FACTORY_BAD);
+}
+EXPORT_SYMBOL(nand_bbt_markbad_factory);
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index c651d95..a0683b0 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -192,5 +192,6 @@ void nand_bbt_destroy(struct nand_bbt *bbt);
 int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
 int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
 int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);
+int nand_bbt_markbad_factory(struct nand_bbt *bbt, loff_t offs);
 
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1



[PATCH 05/11] mtd: nand: use new BBT API instead of old ones

2016-03-13 Thread Peter Pan
Use new BBT APIs (nand_bbt_*()) in NAND. Keep old APIs (nand_*_bbt())
exist temporarily.

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/docg4.c |   7 +-
 drivers/mtd/nand/nand_base.c | 151 ---
 include/linux/mtd/nand.h |  15 -
 3 files changed, 160 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index d86a60e..6fce881 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -1021,6 +1021,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
uint8_t *buf;
int i, block;
__u32 eccfailed_stats = mtd->ecc_stats.failed;
+   struct nand_bbt *nand_bbt = nand_get_bbt(nand);
 
buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
if (buf == NULL)
@@ -1036,7 +1037,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
 * operation after device power-up.  The above read ensures it never is.
 * Ugly, I know.
 */
-   if (nand->bbt == NULL)  /* no memory-based bbt */
+   if (nand_bbt == NULL)  /* no memory-based bbt */
goto exit;
 
if (mtd->ecc_stats.failed > eccfailed_stats) {
@@ -1063,8 +1064,8 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
unsigned long bits = ~buf[i];
for_each_set_bit(bitnum, , 8) {
int badblock = block + 7 - bitnum;
-   nand->bbt[badblock / 4] |=
-   0x03 << ((badblock % 4) * 2);
+   nand_bbt_markbad_factory(nand_bbt,
+   badblock << nand->bbt_erase_shift);
mtd->ecc_stats.badblocks++;
dev_notice(doc->dev, "factory-marked bad block: %d\n",
   badblock);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index b6facac..6f0e3b9 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -417,6 +417,7 @@ static int nand_block_markbad_lowlevel(struct mtd_info 
*mtd, loff_t ofs)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
int res, ret = 0;
+   struct nand_bbt *nand_bbt = nand_get_bbt(chip);
 
if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) {
struct erase_info einfo;
@@ -435,8 +436,8 @@ static int nand_block_markbad_lowlevel(struct mtd_info 
*mtd, loff_t ofs)
}
 
/* Mark block bad in BBT */
-   if (chip->bbt) {
-   res = nand_markbad_bbt(mtd, ofs);
+   if (nand_bbt) {
+   res = nand_bbt_markbad(nand_bbt, ofs);
if (!ret)
ret = res;
}
@@ -477,11 +478,12 @@ static int nand_check_wp(struct mtd_info *mtd)
 static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_bbt *nand_bbt = nand_get_bbt(chip);
 
-   if (!chip->bbt)
+   if (!nand_bbt)
return 0;
/* Return info from the table */
-   return nand_isreserved_bbt(mtd, ofs);
+   return nand_bbt_isreserved(nand_bbt, ofs);
 }
 
 /**
@@ -496,12 +498,18 @@ static int nand_block_isreserved(struct mtd_info *mtd, 
loff_t ofs)
 static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_bbt *nand_bbt = nand_get_bbt(chip);
 
-   if (!chip->bbt)
+   if (!nand_bbt)
return chip->block_bad(mtd, ofs);
 
/* Return info from the table */
-   return nand_isbad_bbt(mtd, ofs, allowbbt);
+   if (nand_bbt_isbad(nand_bbt, ofs))
+   return 1;
+   else if (allowbbt)
+   return 0;
+   else
+   return nand_bbt_isreserved(nand_bbt, ofs);
 }
 
 /**
@@ -2996,6 +3004,129 @@ erase_exit:
return ret;
 }
 
+/* NAND BBT helper - erase a block, including reserved blocks */
+static int nand_bbt_erase_block(struct mtd_info *mtd, loff_t addr)
+{
+   struct erase_info einfo;
+   struct nand_chip *chip = mtd_to_nand(mtd);
+
+   memset(, 0, sizeof(einfo));
+   einfo.mtd = mtd;
+   einfo.addr = addr;
+   einfo.len = 1ULL << chip->phys_erase_shift;
+
+   return nand_erase_nand(mtd, , 1);
+}
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+#define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB)
+/**
+ * nand_create_factory_badblock_pattern - [INTERN] Creates a BBT descriptor
+ * structure for factory bad block marker
+ * @chip: NAND chip to create descriptor for
+ *
+ * This function allocates and initializes a badblock_pattern for factory bad
+ * block marker based on the properties of @chip when chip.badblock_pattern
+ * is NULL.
+ */
+static int nand_create_factory_badblock_pattern(struct nand_chip *chip)

[PATCH 03/11] mtd: nand_bbt: add new API definitions

2016-03-13 Thread Peter Pan
Add new API definitions for nand_bbt to replace old ones without
any users. These API includes:
struct nand_bbt_create(struct mtd_info *mtd);
struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
const struct nand_bbt_ops *ops,
struct nand_chip_layout_info *info,
unsigned int options,
struct nand_bbt_descr *bbt_td,
struct nand_bbt_descr *bbt_md);
void nand_bbt_destroy(struct nand_bbt *bbt);
int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c  | 113 +++
 include/linux/mtd/nand_bbt.h |  11 +
 2 files changed, 124 insertions(+)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 2fbb523..aab734e 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1373,3 +1373,116 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
 
return ret;
 }
+
+/**
+ * nand_bbt_init - Initialize and locate/create a bad block table
+ * @bbt: NAND BBT structure
+ *
+ * This function selects the default bad block table support for the device and
+ * scans for an existing table, or else creates one.
+ */
+static int nand_bbt_init(struct nand_bbt *bbt)
+{
+   /*
+* FIXME: For now, we call nand_default_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_default_bbt(bbt->mtd);
+}
+
+static void nand_bbt_release(struct nand_bbt *bbt)
+{
+   kfree(bbt->bbt);
+}
+
+/**
+ * nand_bbt_create - [NAND BBT Interface] create BBT structures for certain
+ * MTD device
+ * @mtd: MTD structure
+ */
+struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
+   const struct nand_bbt_ops *ops,
+   struct nand_chip_layout_info *info,
+   unsigned int options,
+   struct nand_bbt_descr *bbt_td,
+   struct nand_bbt_descr *bbt_md)
+{
+   struct nand_bbt *bbt = kzalloc(sizeof(struct nand_bbt),
+   GFP_KERNEL);
+   int ret;
+
+   if (!bbt)
+   return ERR_PTR(-ENOMEM);
+
+   bbt->mtd = mtd;
+   bbt->bbt_options = options;
+   bbt->bbt_ops = ops;
+   bbt->info = info;
+   bbt->bbt_td = bbt_td;
+   bbt->bbt_md = bbt_md;
+
+   ret = nand_bbt_init(bbt);
+   if (ret)
+   return ERR_PTR(ret);
+
+   return bbt;
+}
+EXPORT_SYMBOL(nand_bbt_create);
+
+/**
+ * nand_bbt_destroy - [NAND BBT Interface] Destroy BBT structures
+ * @bbt: NAND BBT structure
+ */
+void nand_bbt_destroy(struct nand_bbt *bbt)
+{
+   nand_bbt_release(bbt);
+   kfree(bbt);
+}
+EXPORT_SYMBOL(nand_bbt_destroy);
+
+/**
+ * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
+ * @bbt: NAND BBT structure
+ * @offs: offset in the device
+ */
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_isreserved_bbt() directly. It will
+* change when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_isreserved_bbt(bbt->mtd, offs);
+}
+EXPORT_SYMBOL(nand_bbt_isreserved);
+
+/**
+ * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
+ * @bbt: NAND BBT structure
+ * @offs: offset in the device
+ */
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_isbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+* Since we already have nand_bbt_isreserved(), we don't need to
+* check pass down allow_bbt.
+*/
+   return nand_isbad_bbt(bbt->mtd, offs, 1);
+}
+EXPORT_SYMBOL(nand_bbt_isbad);
+
+/**
+ * nand_bbt_markbad - [NAND BBT Interface] Mark a block bad in the BBT
+ * @bbt: NAND BBT structure
+ * @offs: offset of the bad block
+ */
+int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_markbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_markbad_bbt(bbt->mtd, offs);
+}
+EXPORT_SYMBOL(nand_bbt_markbad);
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index cfb22c8..c651d95 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -182,4 +182,15 @@ struct nand_bbt {
u8 *bbt;
 };
 
+struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
+

[PATCH 01/11] mtd: nand_bbt: new header for nand family BBT

2016-03-13 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

Migrating existing BBT definitions from bbm.h to nand_bbt.h

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
[Peter: correct misspelling. s/neccecary/necessary/]
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 include/linux/mtd/bbm.h  |  96 +--
 include/linux/mtd/nand_bbt.h | 118 +++
 2 files changed, 119 insertions(+), 95 deletions(-)
 create mode 100644 include/linux/mtd/nand_bbt.h

diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 3bf8f95..1f082c8 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -28,102 +28,8 @@
 #ifndef __LINUX_MTD_BBM_H
 #define __LINUX_MTD_BBM_H
 
-/* The maximum number of NAND chips in an array */
-#define NAND_MAX_CHIPS 8
+#include 
 
-/**
- * struct nand_bbt_descr - bad block table descriptor
- * @options:   options for this descriptor
- * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE
- * when bbt is searched, then we store the found bbts pages here.
- * Its an array and supports up to 8 chips now
- * @offs:  offset of the pattern in the oob area of the page
- * @veroffs:   offset of the bbt version counter in the oob are of the page
- * @version:   version read from the bbt page during scan
- * @len:   length of the pattern, if 0 no pattern check is performed
- * @maxblocks: maximum number of blocks to search for a bbt. This number of
- * blocks is reserved at the end of the device where the tables are
- * written.
- * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
- *  bad) block in the stored bbt
- * @pattern:   pattern to identify bad block table or factory marked good /
- * bad blocks, can be NULL, if len = 0
- *
- * Descriptor for the bad block table marker and the descriptor for the
- * pattern which identifies good and bad blocks. The assumption is made
- * that the pattern and the version count are always located in the oob area
- * of the first block.
- */
-struct nand_bbt_descr {
-   int options;
-   int pages[NAND_MAX_CHIPS];
-   int offs;
-   int veroffs;
-   uint8_t version[NAND_MAX_CHIPS];
-   int len;
-   int maxblocks;
-   int reserved_block_code;
-   uint8_t *pattern;
-};
-
-/* Options for the bad block table descriptors */
-
-/* The number of bits used per block in the bbt on the device */
-#define NAND_BBT_NRBITS_MSK0x000F
-#define NAND_BBT_1BIT  0x0001
-#define NAND_BBT_2BIT  0x0002
-#define NAND_BBT_4BIT  0x0004
-#define NAND_BBT_8BIT  0x0008
-/* The bad block table is in the last good block of the device */
-#define NAND_BBT_LASTBLOCK 0x0010
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_ABSPAGE   0x0020
-/* bbt is stored per chip on multichip devices */
-#define NAND_BBT_PERCHIP   0x0080
-/* bbt has a version counter at offset veroffs */
-#define NAND_BBT_VERSION   0x0100
-/* Create a bbt if none exists */
-#define NAND_BBT_CREATE0x0200
-/*
- * Create an empty BBT with no vendor information. Vendor's information may be
- * unavailable, for example, if the NAND controller has a different data and 
OOB
- * layout or if this information is already purged. Must be used in conjunction
- * with NAND_BBT_CREATE.
- */
-#define NAND_BBT_CREATE_EMPTY  0x0400
-/* Write bbt if neccecary */
-#define NAND_BBT_WRITE 0x2000
-/* Read and write back block contents when writing bbt */
-#define NAND_BBT_SAVECONTENT   0x4000
-/* Search good / bad pattern on the first and the second page */
-#define NAND_BBT_SCAN2NDPAGE   0x8000
-/* Search good / bad pattern on the last page of the eraseblock */
-#define NAND_BBT_SCANLASTPAGE  0x0001
-/*
- * Use a flash based bad block table. By default, OOB identifier is saved in
- * OOB area. This option is passed to the default bad block table function.
- */
-#define NAND_BBT_USE_FLASH 0x0002
-/*
- * Do not store flash based bad block table marker in the OOB area; store it
- * in-band.
- */
-#define NAND_BBT_NO_OOB0x0004
-/*
- * Do not write new bad block markers to OOB; useful, e.g., when ECC covers
- * entire spare area. Must be used with NAND_BBT_USE_FLASH.
- */
-#define NAND_BBT_NO_OOB_BBM0x0008
-
-/*
- * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
- * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
- * in nand_chip.bbt_options.
- */
-#define NAND_BBT_DYNAMICSTRUCT 0x8000
-
-/* The maximum number of blocks to scan for a bbt */
-#define NAND_BBT_SCAN_MAXBLOCKS4
 
 /*
  * Constants for oob configuration
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
ne

[PATCH 01/11] mtd: nand_bbt: new header for nand family BBT

2016-03-13 Thread Peter Pan
From: Brian Norris 

Migrating existing BBT definitions from bbm.h to nand_bbt.h

Signed-off-by: Brian Norris 
[Peter: correct misspelling. s/neccecary/necessary/]
Signed-off-by: Peter Pan 
---
 include/linux/mtd/bbm.h  |  96 +--
 include/linux/mtd/nand_bbt.h | 118 +++
 2 files changed, 119 insertions(+), 95 deletions(-)
 create mode 100644 include/linux/mtd/nand_bbt.h

diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 3bf8f95..1f082c8 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -28,102 +28,8 @@
 #ifndef __LINUX_MTD_BBM_H
 #define __LINUX_MTD_BBM_H
 
-/* The maximum number of NAND chips in an array */
-#define NAND_MAX_CHIPS 8
+#include 
 
-/**
- * struct nand_bbt_descr - bad block table descriptor
- * @options:   options for this descriptor
- * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE
- * when bbt is searched, then we store the found bbts pages here.
- * Its an array and supports up to 8 chips now
- * @offs:  offset of the pattern in the oob area of the page
- * @veroffs:   offset of the bbt version counter in the oob are of the page
- * @version:   version read from the bbt page during scan
- * @len:   length of the pattern, if 0 no pattern check is performed
- * @maxblocks: maximum number of blocks to search for a bbt. This number of
- * blocks is reserved at the end of the device where the tables are
- * written.
- * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
- *  bad) block in the stored bbt
- * @pattern:   pattern to identify bad block table or factory marked good /
- * bad blocks, can be NULL, if len = 0
- *
- * Descriptor for the bad block table marker and the descriptor for the
- * pattern which identifies good and bad blocks. The assumption is made
- * that the pattern and the version count are always located in the oob area
- * of the first block.
- */
-struct nand_bbt_descr {
-   int options;
-   int pages[NAND_MAX_CHIPS];
-   int offs;
-   int veroffs;
-   uint8_t version[NAND_MAX_CHIPS];
-   int len;
-   int maxblocks;
-   int reserved_block_code;
-   uint8_t *pattern;
-};
-
-/* Options for the bad block table descriptors */
-
-/* The number of bits used per block in the bbt on the device */
-#define NAND_BBT_NRBITS_MSK0x000F
-#define NAND_BBT_1BIT  0x0001
-#define NAND_BBT_2BIT  0x0002
-#define NAND_BBT_4BIT  0x0004
-#define NAND_BBT_8BIT  0x0008
-/* The bad block table is in the last good block of the device */
-#define NAND_BBT_LASTBLOCK 0x0010
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_ABSPAGE   0x0020
-/* bbt is stored per chip on multichip devices */
-#define NAND_BBT_PERCHIP   0x0080
-/* bbt has a version counter at offset veroffs */
-#define NAND_BBT_VERSION   0x0100
-/* Create a bbt if none exists */
-#define NAND_BBT_CREATE0x0200
-/*
- * Create an empty BBT with no vendor information. Vendor's information may be
- * unavailable, for example, if the NAND controller has a different data and 
OOB
- * layout or if this information is already purged. Must be used in conjunction
- * with NAND_BBT_CREATE.
- */
-#define NAND_BBT_CREATE_EMPTY  0x0400
-/* Write bbt if neccecary */
-#define NAND_BBT_WRITE 0x2000
-/* Read and write back block contents when writing bbt */
-#define NAND_BBT_SAVECONTENT   0x4000
-/* Search good / bad pattern on the first and the second page */
-#define NAND_BBT_SCAN2NDPAGE   0x8000
-/* Search good / bad pattern on the last page of the eraseblock */
-#define NAND_BBT_SCANLASTPAGE  0x0001
-/*
- * Use a flash based bad block table. By default, OOB identifier is saved in
- * OOB area. This option is passed to the default bad block table function.
- */
-#define NAND_BBT_USE_FLASH 0x0002
-/*
- * Do not store flash based bad block table marker in the OOB area; store it
- * in-band.
- */
-#define NAND_BBT_NO_OOB0x0004
-/*
- * Do not write new bad block markers to OOB; useful, e.g., when ECC covers
- * entire spare area. Must be used with NAND_BBT_USE_FLASH.
- */
-#define NAND_BBT_NO_OOB_BBM0x0008
-
-/*
- * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
- * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
- * in nand_chip.bbt_options.
- */
-#define NAND_BBT_DYNAMICSTRUCT 0x8000
-
-/* The maximum number of blocks to scan for a bbt */
-#define NAND_BBT_SCAN_MAXBLOCKS4
 
 /*
  * Constants for oob configuration
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
new file mode 100644
index 000..5a65230
--- /dev/null
+++ b/include/linux/mtd/nand_bbt.h
@@ -0,0 +1,118

[PATCH 03/11] mtd: nand_bbt: add new API definitions

2016-03-13 Thread Peter Pan
Add new API definitions for nand_bbt to replace old ones without
any users. These API includes:
struct nand_bbt_create(struct mtd_info *mtd);
struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
const struct nand_bbt_ops *ops,
struct nand_chip_layout_info *info,
unsigned int options,
struct nand_bbt_descr *bbt_td,
struct nand_bbt_descr *bbt_md);
void nand_bbt_destroy(struct nand_bbt *bbt);
int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c  | 113 +++
 include/linux/mtd/nand_bbt.h |  11 +
 2 files changed, 124 insertions(+)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 2fbb523..aab734e 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1373,3 +1373,116 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
 
return ret;
 }
+
+/**
+ * nand_bbt_init - Initialize and locate/create a bad block table
+ * @bbt: NAND BBT structure
+ *
+ * This function selects the default bad block table support for the device and
+ * scans for an existing table, or else creates one.
+ */
+static int nand_bbt_init(struct nand_bbt *bbt)
+{
+   /*
+* FIXME: For now, we call nand_default_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_default_bbt(bbt->mtd);
+}
+
+static void nand_bbt_release(struct nand_bbt *bbt)
+{
+   kfree(bbt->bbt);
+}
+
+/**
+ * nand_bbt_create - [NAND BBT Interface] create BBT structures for certain
+ * MTD device
+ * @mtd: MTD structure
+ */
+struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
+   const struct nand_bbt_ops *ops,
+   struct nand_chip_layout_info *info,
+   unsigned int options,
+   struct nand_bbt_descr *bbt_td,
+   struct nand_bbt_descr *bbt_md)
+{
+   struct nand_bbt *bbt = kzalloc(sizeof(struct nand_bbt),
+   GFP_KERNEL);
+   int ret;
+
+   if (!bbt)
+   return ERR_PTR(-ENOMEM);
+
+   bbt->mtd = mtd;
+   bbt->bbt_options = options;
+   bbt->bbt_ops = ops;
+   bbt->info = info;
+   bbt->bbt_td = bbt_td;
+   bbt->bbt_md = bbt_md;
+
+   ret = nand_bbt_init(bbt);
+   if (ret)
+   return ERR_PTR(ret);
+
+   return bbt;
+}
+EXPORT_SYMBOL(nand_bbt_create);
+
+/**
+ * nand_bbt_destroy - [NAND BBT Interface] Destroy BBT structures
+ * @bbt: NAND BBT structure
+ */
+void nand_bbt_destroy(struct nand_bbt *bbt)
+{
+   nand_bbt_release(bbt);
+   kfree(bbt);
+}
+EXPORT_SYMBOL(nand_bbt_destroy);
+
+/**
+ * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
+ * @bbt: NAND BBT structure
+ * @offs: offset in the device
+ */
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_isreserved_bbt() directly. It will
+* change when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_isreserved_bbt(bbt->mtd, offs);
+}
+EXPORT_SYMBOL(nand_bbt_isreserved);
+
+/**
+ * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
+ * @bbt: NAND BBT structure
+ * @offs: offset in the device
+ */
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_isbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+* Since we already have nand_bbt_isreserved(), we don't need to
+* check pass down allow_bbt.
+*/
+   return nand_isbad_bbt(bbt->mtd, offs, 1);
+}
+EXPORT_SYMBOL(nand_bbt_isbad);
+
+/**
+ * nand_bbt_markbad - [NAND BBT Interface] Mark a block bad in the BBT
+ * @bbt: NAND BBT structure
+ * @offs: offset of the bad block
+ */
+int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_markbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_markbad_bbt(bbt->mtd, offs);
+}
+EXPORT_SYMBOL(nand_bbt_markbad);
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index cfb22c8..c651d95 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -182,4 +182,15 @@ struct nand_bbt {
u8 *bbt;
 };
 
+struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
+   const struct nand_bbt_ops *ops,
+   s

[PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT

2016-03-13 Thread Peter Pan
Sorry for send the v3 out late. I went through a busy time in the past
two month.

Currently nand_bbt.c is tied with struct nand_chip, and it makes other
NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
onenand has own bbt(onenand_bbt.c).

Separate struct nand_chip from BBT code can make current BBT shareable.
We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
Struct nand_bbt contains all the information BBT needed from outside and
it should be embedded into NAND family chip struct (such as struct nand_chip).

Below is mtd folder structure we want:
drivers/mtd/nand/
drivers/mtd/nand/raw/
drivers/mtd/nand/spi/
drivers/mtd/nand/onenand/
drivers/mtd/nand/chips/

Most of the patch is borrowed from Brian Norris <computersforpe...@gmail.com>.
http://git.infradead.org/users/norris/linux-mtd.git/shortlog/refs/heads/nand-bbt
I decided the authorship of each patch by contribution. Please let me know if
there is something unproper.
Based on Brian's suggestion and Boris's comments, I make 11 independent
patches. Previous patch is http://patchwork.ozlabs.org/patch/492066/
After discussion with Boris and Ezequiel, I realized above structure is better,
so I drop the patch to move nand_bbt.c to mtd folder.

The patch is tested on Zed board.

v3 changes:
introduce struct nand_bbt_ops
introduce struct nand_chip_layout_info
add nand_bbt_create/destroy() API
use mtd_to_nand instead mtd->priv directly
remove mark_bad_bbm() due to no user yet
keep nand_bbt.c in mtd/nand folder
add nand_get_bbt() helper function
rebase patch series on 4.5.0-rc1
v2 changes:
rebase patch series on master branch of l2-mtd.git


Brian Norris (7):
  mtd: nand_bbt: new header for nand family BBT
  mtd: nand_bbt: introduce BBT related data structure
  mtd: nand_bbt: use struct nand_bbt_ops in BBT
  mtd: nand: make nand_erase_nand() static
  mtd: nand_bbt: remove struct nand_chip from nand_bbt.c
  mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro
  mtd: nand: remove nand_chip.bbt

Peter Pan (4):
  mtd: nand_bbt: add new API definitions
  mtd: nand_bbt: add nand_bbt_markbad_factory() interface
  mtd: nand: use new BBT API instead of old ones
  mtd: nand_bbt: remove old API definitions

 drivers/mtd/nand/docg4.c |   7 +-
 drivers/mtd/nand/nand_base.c | 156 ++-
 drivers/mtd/nand/nand_bbt.c  | 604 +--
 include/linux/mtd/bbm.h  |  96 +--
 include/linux/mtd/nand.h |  22 +-
 include/linux/mtd/nand_bbt.h | 190 ++
 6 files changed, 644 insertions(+), 431 deletions(-)
 create mode 100644 include/linux/mtd/nand_bbt.h

-- 
1.9.1



[PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT

2016-03-13 Thread Peter Pan
Sorry for send the v3 out late. I went through a busy time in the past
two month.

Currently nand_bbt.c is tied with struct nand_chip, and it makes other
NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
onenand has own bbt(onenand_bbt.c).

Separate struct nand_chip from BBT code can make current BBT shareable.
We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
Struct nand_bbt contains all the information BBT needed from outside and
it should be embedded into NAND family chip struct (such as struct nand_chip).

Below is mtd folder structure we want:
drivers/mtd/nand/
drivers/mtd/nand/raw/
drivers/mtd/nand/spi/
drivers/mtd/nand/onenand/
drivers/mtd/nand/chips/

Most of the patch is borrowed from Brian Norris .
http://git.infradead.org/users/norris/linux-mtd.git/shortlog/refs/heads/nand-bbt
I decided the authorship of each patch by contribution. Please let me know if
there is something unproper.
Based on Brian's suggestion and Boris's comments, I make 11 independent
patches. Previous patch is http://patchwork.ozlabs.org/patch/492066/
After discussion with Boris and Ezequiel, I realized above structure is better,
so I drop the patch to move nand_bbt.c to mtd folder.

The patch is tested on Zed board.

v3 changes:
introduce struct nand_bbt_ops
introduce struct nand_chip_layout_info
add nand_bbt_create/destroy() API
use mtd_to_nand instead mtd->priv directly
remove mark_bad_bbm() due to no user yet
keep nand_bbt.c in mtd/nand folder
add nand_get_bbt() helper function
rebase patch series on 4.5.0-rc1
v2 changes:
rebase patch series on master branch of l2-mtd.git


Brian Norris (7):
  mtd: nand_bbt: new header for nand family BBT
  mtd: nand_bbt: introduce BBT related data structure
  mtd: nand_bbt: use struct nand_bbt_ops in BBT
  mtd: nand: make nand_erase_nand() static
  mtd: nand_bbt: remove struct nand_chip from nand_bbt.c
  mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro
  mtd: nand: remove nand_chip.bbt

Peter Pan (4):
  mtd: nand_bbt: add new API definitions
  mtd: nand_bbt: add nand_bbt_markbad_factory() interface
  mtd: nand: use new BBT API instead of old ones
  mtd: nand_bbt: remove old API definitions

 drivers/mtd/nand/docg4.c |   7 +-
 drivers/mtd/nand/nand_base.c | 156 ++-
 drivers/mtd/nand/nand_bbt.c  | 604 +--
 include/linux/mtd/bbm.h  |  96 +--
 include/linux/mtd/nand.h |  22 +-
 include/linux/mtd/nand_bbt.h | 190 ++
 6 files changed, 644 insertions(+), 431 deletions(-)
 create mode 100644 include/linux/mtd/nand_bbt.h

-- 
1.9.1



Re: [PATCH v2 00/12] mtd: nand_bbt: introduce independent nand BBT

2016-01-06 Thread Peter Pan
Hi Boris,

On Wed, Jan 6, 2016 at 10:29 PM, Boris Brezillon
 wrote:
> On Wed, 30 Dec 2015 09:31:06 +0100
> Boris Brezillon  wrote:
>
>> Hi Peter,
>>
>> On Wed, 30 Dec 2015 15:18:39 +0800
>> 潘栋  wrote:
>>
>> > Hi Boris and Ezequiel,
>> >
>> > 2015-12-29 23:11 GMT+08:00 Boris Brezillon 
>> > :
>> > > On Tue, 29 Dec 2015 12:07:50 -0300
>> > > Ezequiel Garcia  wrote:
>> > >
>> > >> On 29 December 2015 at 06:35, Boris Brezillon
>> > >>  wrote:
>> > >> > Hi,
>> > >> >
>> > >> > On Mon, 28 Dec 2015 17:42:50 -0300
>> > >> > Ezequiel Garcia  wrote:
>> > >> >
>> > >> >> This is looking a lot better, thanks for the good work!
>> > >> >>
>> > >> >> On 15 December 2015 at 02:59, Peter Pan  
>> > >> >> wrote:
>> > >> >> > Currently nand_bbt.c is tied with struct nand_chip, and it makes 
>> > >> >> > other
>> > >> >> > NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> > >> >> > onenand has own bbt(onenand_bbt.c).
>> > >> >> >
>> > >> >> > Separate struct nand_chip from BBT code can make current BBT 
>> > >> >> > shareable.
>> > >> >> > We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
>> > >> >> > Struct nand_bbt contains all the information BBT needed from 
>> > >> >> > outside and
>> > >> >> > it should be embedded into NAND family chip struct (such as struct 
>> > >> >> > nand_chip).
>> > >> >> > NAND family driver should allocate, initialize and free struct 
>> > >> >> > nand_bbt.
>> > >> >> >
>> > >> >> > Below is mtd folder structure we want:
>> > >> >> > mtd
>> > >> >> > ├── Kconfig
>> > >> >> > ├── Makefile
>> > >> >> > ├── ...
>> > >> >> > ├── nand_bbt.c
>> > >> >>
>> > >> >> Hm.. I'm not sure about having nand_bbt.c in drivers/mtd.
>> > >> >> What's wrong with drivers/mtd/nand ?
>> > >> >
>> > >> > I haven't reviewed the series yet, but I agree. If the BBT code is 
>> > >> > only
>> > >> > meant to be used on NAND based devices, it should probably stay in
>> > >> > drivers/mtd/nand.
>> > >> >
>> > >> >>
>> > >> >> In fact, I  was thinking we could go further and clean up the 
>> > >> >> directories a bit
>> > >> >> by separating core code, from controllers code, from SPI NAND code:
>> > >> >>
>> > >> >> drivers/mtd/nand/
>> > >> >> drivers/mtd/nand/controllers
>> > >> >> drivers/mtd/nand/spi
>> > >> >>
>> > >> >> Makes any sense?
>> > >> >
>> > >> > Actually I had the secret plan of moving all (raw) NAND controller
>> > >> > drivers into the drivers/mtd/nand/controllers directory, though this
>> > >> > was for a different reason: I'd like to create another directory for
>> > >> > manufacturer specific code in order to support some advanced features
>> > >> > on NANDs that do not implement (or only partially implement) the ONFI
>> > >> > standard.
>> > >> >
>> > >> > The separation you're talking about here is more related to the
>> > >> > interface used to communicate with the NAND chip.
>> > >> >
>> > >> > How about using the following hierarchy?
>> > >> >
>> > >> > drivers/mtd/nand/
>> > >> > drivers/mtd/nand/interfaces/raw/
>> > >> > drivers/mtd/nand/interfaces/raw/controllers/
>> > >> > drivers/mtd/nand/interfaces/spi/
>> > >> > drivers/mtd/nand/interfaces/onenand/
>> > >> > drivers/mtd/nand/chips/
>> > >> >
>> > >> > What do you think?
>> > >> >
>> > >>
>> > >> I believe we are bikeshedding here, but what the heck.
>> &g

Re: [PATCH v2 00/12] mtd: nand_bbt: introduce independent nand BBT

2016-01-06 Thread Peter Pan
Hi Boris,

On Wed, Jan 6, 2016 at 10:29 PM, Boris Brezillon
<boris.brezil...@free-electrons.com> wrote:
> On Wed, 30 Dec 2015 09:31:06 +0100
> Boris Brezillon <boris.brezil...@free-electrons.com> wrote:
>
>> Hi Peter,
>>
>> On Wed, 30 Dec 2015 15:18:39 +0800
>> 潘栋 <peterpans...@gmail.com> wrote:
>>
>> > Hi Boris and Ezequiel,
>> >
>> > 2015-12-29 23:11 GMT+08:00 Boris Brezillon 
>> > <boris.brezil...@free-electrons.com>:
>> > > On Tue, 29 Dec 2015 12:07:50 -0300
>> > > Ezequiel Garcia <ezequ...@vanguardiasur.com.ar> wrote:
>> > >
>> > >> On 29 December 2015 at 06:35, Boris Brezillon
>> > >> <boris.brezil...@free-electrons.com> wrote:
>> > >> > Hi,
>> > >> >
>> > >> > On Mon, 28 Dec 2015 17:42:50 -0300
>> > >> > Ezequiel Garcia <ezequ...@vanguardiasur.com.ar> wrote:
>> > >> >
>> > >> >> This is looking a lot better, thanks for the good work!
>> > >> >>
>> > >> >> On 15 December 2015 at 02:59, Peter Pan <peterpans...@gmail.com> 
>> > >> >> wrote:
>> > >> >> > Currently nand_bbt.c is tied with struct nand_chip, and it makes 
>> > >> >> > other
>> > >> >> > NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
>> > >> >> > onenand has own bbt(onenand_bbt.c).
>> > >> >> >
>> > >> >> > Separate struct nand_chip from BBT code can make current BBT 
>> > >> >> > shareable.
>> > >> >> > We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
>> > >> >> > Struct nand_bbt contains all the information BBT needed from 
>> > >> >> > outside and
>> > >> >> > it should be embedded into NAND family chip struct (such as struct 
>> > >> >> > nand_chip).
>> > >> >> > NAND family driver should allocate, initialize and free struct 
>> > >> >> > nand_bbt.
>> > >> >> >
>> > >> >> > Below is mtd folder structure we want:
>> > >> >> > mtd
>> > >> >> > ├── Kconfig
>> > >> >> > ├── Makefile
>> > >> >> > ├── ...
>> > >> >> > ├── nand_bbt.c
>> > >> >>
>> > >> >> Hm.. I'm not sure about having nand_bbt.c in drivers/mtd.
>> > >> >> What's wrong with drivers/mtd/nand ?
>> > >> >
>> > >> > I haven't reviewed the series yet, but I agree. If the BBT code is 
>> > >> > only
>> > >> > meant to be used on NAND based devices, it should probably stay in
>> > >> > drivers/mtd/nand.
>> > >> >
>> > >> >>
>> > >> >> In fact, I  was thinking we could go further and clean up the 
>> > >> >> directories a bit
>> > >> >> by separating core code, from controllers code, from SPI NAND code:
>> > >> >>
>> > >> >> drivers/mtd/nand/
>> > >> >> drivers/mtd/nand/controllers
>> > >> >> drivers/mtd/nand/spi
>> > >> >>
>> > >> >> Makes any sense?
>> > >> >
>> > >> > Actually I had the secret plan of moving all (raw) NAND controller
>> > >> > drivers into the drivers/mtd/nand/controllers directory, though this
>> > >> > was for a different reason: I'd like to create another directory for
>> > >> > manufacturer specific code in order to support some advanced features
>> > >> > on NANDs that do not implement (or only partially implement) the ONFI
>> > >> > standard.
>> > >> >
>> > >> > The separation you're talking about here is more related to the
>> > >> > interface used to communicate with the NAND chip.
>> > >> >
>> > >> > How about using the following hierarchy?
>> > >> >
>> > >> > drivers/mtd/nand/
>> > >> > drivers/mtd/nand/interfaces/raw/
>> > >> > drivers/mtd/nand/interfaces/raw/controllers/
>> > >> > drivers/mtd/nand/interfaces/spi/
>> > >> >

[PATCH v2 05/12] mtd: nand: use new BBT API instead of old ones

2015-12-14 Thread Peter Pan
From: Brian Norris 

Use new BBT APIs (nand_bbt_*()) in NAND. Keep old APIs (nand_*_bbt())
exist temporarily.

Signed-off-by: Brian Norris 
[Peter: 1. use nand_bbt_markbad_factory() in docg4.c and implement
2. nand_create_factory_badblock_pattern(), nand_is_bad_bbm() and
nand_default_bbt() in nand_base.c
3. add NAND_BADBLOCK_PATTERN_ALLOC macro]
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/docg4.c |   6 +-
 drivers/mtd/nand/nand_base.c | 140 ---
 include/linux/mtd/nand.h |   9 ++-
 3 files changed, 143 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index da93d7f..1be7fa2 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -1037,7 +1037,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
 * operation after device power-up.  The above read ensures it never is.
 * Ugly, I know.
 */
-   if (nand->bbt == NULL)  /* no memory-based bbt */
+   if (nand->nand_bbt == NULL)  /* no memory-based bbt */
goto exit;
 
if (mtd->ecc_stats.failed > eccfailed_stats) {
@@ -1064,8 +1064,8 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
unsigned long bits = ~buf[i];
for_each_set_bit(bitnum, , 8) {
int badblock = block + 7 - bitnum;
-   nand->bbt[badblock / 4] |=
-   0x03 << ((badblock % 4) * 2);
+   nand_bbt_markbad_factory(nand->nand_bbt,
+   badblock << nand->bbt_erase_shift);
mtd->ecc_stats.badblocks++;
dev_notice(doc->dev, "factory-marked bad block: %d\n",
   badblock);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5aec154..28d7a58 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -450,8 +450,8 @@ static int nand_block_markbad_lowlevel(struct mtd_info 
*mtd, loff_t ofs)
}
 
/* Mark block bad in BBT */
-   if (chip->bbt) {
-   res = nand_markbad_bbt(mtd, ofs);
+   if (chip->nand_bbt) {
+   res = nand_bbt_markbad(chip->nand_bbt, ofs);
if (!ret)
ret = res;
}
@@ -493,10 +493,10 @@ static int nand_block_isreserved(struct mtd_info *mtd, 
loff_t ofs)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
 
-   if (!chip->bbt)
+   if (!chip->nand_bbt)
return 0;
/* Return info from the table */
-   return nand_isreserved_bbt(mtd, ofs);
+   return nand_bbt_isreserved(chip->nand_bbt, ofs);
 }
 
 /**
@@ -513,12 +513,18 @@ static int nand_block_checkbad(struct mtd_info *mtd, 
loff_t ofs, int getchip,
   int allowbbt)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_bbt *bbt = chip->nand_bbt;
 
-   if (!chip->bbt)
+   if (!bbt)
return chip->block_bad(mtd, ofs, getchip);
 
/* Return info from the table */
-   return nand_isbad_bbt(mtd, ofs, allowbbt);
+   if (nand_bbt_isbad(bbt, ofs))
+   return 1;
+   else if (allowbbt)
+   return 0;
+   else
+   return nand_bbt_isreserved(bbt, ofs);
 }
 
 /**
@@ -2982,6 +2988,122 @@ erase_exit:
return ret;
 }
 
+/* NAND BBT helper - erase a block, including reserved blocks */
+static int nand_bbt_erase_block(struct mtd_info *mtd, loff_t addr)
+{
+   struct erase_info einfo;
+   struct nand_chip *chip = mtd->priv;
+
+   memset(, 0, sizeof(einfo));
+   einfo.mtd = mtd;
+   einfo.addr = addr;
+   einfo.len = 1ULL << chip->phys_erase_shift;
+
+   return nand_erase_nand(mtd, , 1);
+}
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+#define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB)
+/**
+ * nand_create_factory_badblock_pattern - [INTERN] Creates a BBT descriptor
+ * structure for factory bad block marker
+ * @chip: NAND chip to create descriptor for
+ *
+ * This function allocates and initializes a badblock_pattern for factory bad
+ * block marker based on the properties of @chip when chip.badblock_pattern
+ * is NULL.
+ */
+static int nand_create_factory_badblock_pattern(struct nand_chip *chip)
+{
+   struct nand_bbt_descr *bd;
+
+   if (chip->badblock_pattern) {
+   pr_warn("Bad block pattern already allocated; not replacing\n");
+   return -EINVAL;
+   }
+   bd = kzalloc(sizeof(*bd), GFP_KERNEL);
+   if (!bd)
+   return -ENOMEM;
+   bd->options = chip->bbt_options & BADBLOCK_SCAN_MASK;
+   bd->offs = chip->badblockpos;
+   bd->len = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
+   bd->patt

[PATCH v2 09/12] mtd: nand_bbt: remove old API definitions

2015-12-14 Thread Peter Pan
From: Brian Norris 

remove old BBT APIs

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c | 110 +---
 include/linux/mtd/nand.h|   3 --
 2 files changed, 22 insertions(+), 91 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index b46b4ae..22861a1 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1166,13 +1166,14 @@ static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
 };
 
 /**
- * nand_default_bbt - [NAND Interface] Select a default bad block table for 
the device
+ * nand_bbt_init - [NAND BBT Interface] Initialize and locate/create a bad 
block
+ * table
  * @bbt: NAND BBT structure
  *
  * This function selects the default bad block table support for the device and
- * calls the nand_scan_bbt function.
+ * scans for an existing table, or else creates one.
  */
-int nand_default_bbt(struct nand_bbt *bbt)
+int nand_bbt_init(struct nand_bbt *bbt)
 {
/* Is a flash based bad block table requested? */
if (bbt->bbt_options & NAND_BBT_USE_FLASH) {
@@ -1193,46 +1194,54 @@ int nand_default_bbt(struct nand_bbt *bbt)
 
return nand_scan_bbt(bbt);
 }
+EXPORT_SYMBOL(nand_bbt_init);
+
+void nand_bbt_release(struct nand_bbt *bbt)
+{
+   kfree(bbt->bbt);
+}
+EXPORT_SYMBOL(nand_bbt_release);
 
 /**
- * nand_isreserved_bbt - [NAND Interface] Check if a block is reserved
+ * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
  * @bbt: NAND BBT structure
  * @offs: offset in the device
  */
-int nand_isreserved_bbt(struct nand_bbt *bbt, loff_t offs)
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
 {
int block;
 
block = (int)(offs >> bbt->bbt_erase_shift);
return bbt_get_entry(bbt, block) == BBT_BLOCK_RESERVED;
 }
+EXPORT_SYMBOL(nand_bbt_isreserved);
 
 /**
- * nand_isbad_bbt - [NAND Interface] Check if a block is bad
+ * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
  * @bbt: NAND BBT structure
  * @offs: offset in the device
- * @allowbbt: allow access to bad block table region
  */
-int nand_isbad_bbt(struct nand_bbt *bbt, loff_t offs, int allowbbt)
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
 {
int block, res;
 
block = (int)(offs >> bbt->bbt_erase_shift);
res = bbt_get_entry(bbt, block);
 
-   pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 
0x%02x\n",
+   pr_debug("nand_bbt_isbad(): bbt info for offs 0x%08x: (block %d) 
0x%02x\n",
 (unsigned int)offs, block, res);
 
switch (res) {
case BBT_BLOCK_GOOD:
+   case BBT_BLOCK_RESERVED:
return 0;
case BBT_BLOCK_WORN:
+   case BBT_BLOCK_FACTORY_BAD:
+   default:
return 1;
-   case BBT_BLOCK_RESERVED:
-   return allowbbt ? 0 : 1;
}
-   return 1;
 }
+EXPORT_SYMBOL(nand_bbt_isbad);
 
 /**
  * nand_bbt_update_mark - update mark in the BBT
@@ -1257,84 +1266,13 @@ static int nand_bbt_update_mark(struct nand_bbt *bbt, 
loff_t offs, uint8_t mark)
 }
 
 /**
- * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
- * @bbt: NAND BBT structure
- * @offs: offset of the bad block
- */
-int nand_markbad_bbt(struct nand_bbt *bbt, loff_t offs)
-{
-   return nand_bbt_update_mark(bbt, offs, BBT_BLOCK_WORN);
-}
-EXPORT_SYMBOL(nand_scan_bbt);
-
-/**
- * nand_bbt_init - [NAND BBT Interface] Initialize and locate/create a bad 
block
- * table
- * @bbt: NAND BBT structure
- *
- * This function selects the default bad block table support for the device and
- * scans for an existing table, or else creates one.
- */
-int nand_bbt_init(struct nand_bbt *bbt)
-{
-   /*
-* FIXME: For now, we call nand_default_bbt() directly. It will change
-* when we use struct nand_bbt instead of struct nand_chip.
-*/
-   return nand_default_bbt(bbt);
-}
-EXPORT_SYMBOL(nand_bbt_init);
-
-void nand_bbt_release(struct nand_bbt *bbt)
-{
-   kfree(bbt->bbt);
-}
-EXPORT_SYMBOL(nand_bbt_release);
-
-/**
- * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
- * @bbt: NAND BBT structure
- * @offs: offset in the device
- */
-int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
-{
-   /*
-* FIXME: For now, we call nand_isreserved_bbt() directly. It will
-* change when we use struct nand_bbt instead of struct nand_chip.
-*/
-   return nand_isreserved_bbt(bbt, offs);
-}
-EXPORT_SYMBOL(nand_bbt_isreserved);
-
-/**
- * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
- * @bbt: NAND BBT structure
- * @offs: offset in the device
- */
-int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
-{
-   /*
-* FIXME: For now, we call nand_isbad_bbt() directly. It will change
-* when we use struct nand_bbt instead of struct nand_chip.
-

[PATCH v2 02/12] mtd: nand_bbt: introduce struct nand_bbt

2015-12-14 Thread Peter Pan
From: Brian Norris 

Currently nand_bbt.c is tied with struct nand_chip, and it makes other
NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
onenand has own bbt(onenand_bbt.c).

Separate struct nand_chip from BBT code can make current BBT shareable.
We create struct nand_bbt to take place of nand_chip in nand_bbt.c

Below is mtd folder structure we want:
mtd
├── Kconfig
├── Makefile
├── ...
├── nand_bbt.c
├── nand
│   ├── Kconfig
│   ├── Makefile
│   ├── nand_base.c
│   ├── nand_ids.c
│   ├── ...
│   └── xway_nand.c
├── spi-nand
│   ├── Kconfig
│   ├── Makefile
│   ├── spi-nand-base.c
│   ├── ...
│   └── spi-nand-device.c
└── ...

We put every information nand_bbt.c needed from outside into struct
nand_bbt, include:
@mtd:   pointer to MTD device structure
@is_bad_bbm:check if a block is factory bad block
@mark_bad_bbm:  imitate a block as factory bad block
@erase: erase block bypassing resvered checks
@bbt_options:   bad block specific options. All options used
here must come from nand_bbt.h.
@numchips:  number of physical chips, required for NAND_BBT_PERCHIP
@bbt_td:bad block table descriptor for flash lookup.
@bbt_md:bad block table mirror descriptor
@chipsize:  the size of one chip for multichip arrays
@chip_shift:number of address bits in one chip
@bbt_erase_shift:   number of address bits in a bbt entry
@page_shift:number of address bits in a page
@bbt:   bad block table pointer

Signed-off-by: Brian Norris 
[Peter: correct comment style]
Signed-off-by: Peter Pan 
---
 include/linux/mtd/nand_bbt.h | 59 
 1 file changed, 59 insertions(+)

diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index 5a65230..e468571 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -18,6 +18,8 @@
 #ifndef __LINUX_MTD_NAND_BBT_H
 #define __LINUX_MTD_NAND_BBT_H
 
+struct mtd_info;
+
 /* The maximum number of NAND chips in an array */
 #define NAND_MAX_CHIPS 8
 
@@ -115,4 +117,61 @@ struct nand_bbt_descr {
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS4
 
+/**
+ * struct nand_bbt - bad block table structure
+ * @mtd:   pointer to MTD device structure
+ * @is_bad_bbm:check if a block is factory bad block
+ * @mark_bad_bbm:  imitate a block as factory bad block
+ * @erase: erase block bypassing resvered checks
+ * @bbt_options:   bad block specific options. All options used
+ * here must come from nand_bbt.h.
+ * @numchips:  number of physical chips, required for NAND_BBT_PERCHIP
+ * @bbt_td:bad block table descriptor for flash lookup.
+ * @bbt_md:bad block table mirror descriptor
+ * @chipsize:  the size of one chip for multichip arrays
+ * @chip_shift:number of address bits in one chip
+ * @bbt_erase_shift:   number of address bits in a bbt entry
+ * @page_shift:number of address bits in a page
+ * @bbt:   bad block table pointer
+ *
+ */
+struct nand_bbt {
+   struct mtd_info *mtd;
+
+   /*
+* This is important to abstract out of nand_bbt.c and provide
+* separately in nand_base.c and spi-nand-base.c -- it's sort of
+* duplicated in nand_block_bad() (nand_base) and
+* scan_block_fast() (nand_bbt) right now
+*
+* Note that this also means nand_chip.badblock_pattern should
+* be removed from nand_bbt.c
+*/
+   int (*is_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
+
+   /*
+* Only required if the driver wants to attempt to program new
+* bad block markers that imitate the factory-marked BBMs
+*/
+   int (*mark_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
+
+   /* Erase a block, bypassing reserved checks */
+   int (*erase)(struct mtd_info *mtd, loff_t ofs);
+
+   unsigned int bbt_options;
+   int numchips;
+
+   /*
+* Discourage new custom usages here; suggest usage of the
+* relevant NAND_BBT_* options instead
+*/
+   struct nand_bbt_descr *bbt_td;
+   struct nand_bbt_descr *bbt_md;
+   u64 chipsize;
+   int chip_shift;
+   int bbt_erase_shift;
+   int page_shift;
+   u8 *bbt;
+};
+
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 04/12] mtd: nand_bbt: add nand_bbt_markbad_factory() interface

2015-12-14 Thread Peter Pan
Some nand controller drivers(like docg4.c) mark factory bad block
mark by accessing bbt buffer directly, so create this API to avoid
breaking layer.

Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c  | 32 +---
 include/linux/mtd/nand_bbt.h |  1 +
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 72aed20..f256be1 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1353,11 +1353,12 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, 
int allowbbt)
 }
 
 /**
- * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
+ * nand_bbt_update_mark - update mark in the BBT
  * @mtd: MTD device structure
  * @offs: offset of the bad block
+ * @mark: block type mark
  */
-int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
+static int nand_bbt_update_mark(struct mtd_info *mtd, loff_t offs, uint8_t 
mark)
 {
struct nand_chip *this = mtd_to_nand(mtd);
int block, ret = 0;
@@ -1365,7 +1366,7 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
block = (int)(offs >> this->bbt_erase_shift);
 
/* Mark bad block in memory */
-   bbt_mark_entry(this, block, BBT_BLOCK_WORN);
+   bbt_mark_entry(this, block, mark);
 
/* Update flash-based bad block table */
if (this->bbt_options & NAND_BBT_USE_FLASH)
@@ -1374,6 +1375,15 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
return ret;
 }
 
+/**
+ * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
+ * @mtd: MTD device structure
+ * @offs: offset of the bad block
+ */
+int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
+{
+   return nand_bbt_update_mark(mtd, offs, BBT_BLOCK_WORN);
+}
 EXPORT_SYMBOL(nand_scan_bbt);
 
 /**
@@ -1446,3 +1456,19 @@ int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs)
return nand_markbad_bbt(bbt->mtd, offs);
 }
 EXPORT_SYMBOL(nand_bbt_markbad);
+
+/**
+ * nand_bbt_markbad_factory - [NAND BBT Interface] Mark a block as factory bad
+ * in the BBT
+ * @bbt: NAND BBT structure
+ * @offs: offset of the bad block
+ */
+int nand_bbt_markbad_factory(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_markbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_bbt_update_mark(bbt->mtd, offs, BBT_BLOCK_FACTORY_BAD);
+}
+EXPORT_SYMBOL(nand_bbt_markbad_factory);
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index 150c49a..48a0620 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -179,5 +179,6 @@ void nand_bbt_release(struct nand_bbt *bbt);
 int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
 int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
 int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);
+int nand_bbt_markbad_factory(struct nand_bbt *bbt, loff_t offs);
 
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 00/12] mtd: nand_bbt: introduce independent nand BBT

2015-12-14 Thread Peter Pan
Currently nand_bbt.c is tied with struct nand_chip, and it makes other
NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
onenand has own bbt(onenand_bbt.c).

Separate struct nand_chip from BBT code can make current BBT shareable.
We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
Struct nand_bbt contains all the information BBT needed from outside and
it should be embedded into NAND family chip struct (such as struct nand_chip).
NAND family driver should allocate, initialize and free struct nand_bbt.

Below is mtd folder structure we want:
mtd
├── Kconfig
├── Makefile
├── ...
├── nand_bbt.c
├── nand
│   ├── Kconfig
│   ├── Makefile
│   ├── nand_base.c
│   ├── nand_ids.c
│   ├── ...
│   └── xway_nand.c
├── spi-nand
│   ├── Kconfig
│   ├── Makefile
│   ├── spi-nand-base.c
│   ├── ...
│   └── spi-nand-device.c
└── ...

Most of the patch is borrowed from Brian Norris .
http://git.infradead.org/users/norris/linux-mtd.git/shortlog/refs/heads/nand-bbt
Based on Brian's suggestion, I make my previous BBT patch into 12 independent
patches. Previous patch is http://patchwork.ozlabs.org/patch/492066/
Beside the patch split, I also moved nand_bbt.c to mtd folder, which didn't in
previous patch.

Patch 3, 7, 8, 9, 10 and 11 are totally borrowed from Brian's git tree. I just
test and split the code into independent patch. Patch 1, 2, 5 and 6 are partial
borrowed. I make some changes from Brian's git tree and the changes are recorded
in commit log. Patch 4 and 12 are written by me.

The patch is tested on Zed board.

v2 changes:
rebase patch series on master branch of l2-mtd.git

Brian Norris (10):
  mtd: nand_bbt: new header for nand family BBT
  mtd: nand_bbt: introduce struct nand_bbt
  mtd: nand_bbt: add new API definitions
  mtd: nand: use new BBT API instead of old ones
  mtd: nand_bbt: use erase() and is_bad_bbm() hook in BBT
  mtd: nand: make nand_erase_nand() static
  mtd: nand_bbt: remove struct nand_chip from nand_bbt.c
  mtd: nand_bbt: remove old API definitions
  mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro
  mtd: nand: remove nand_chip.bbt

Peter Pan (2):
  mtd: nand_bbt: add nand_bbt_markbad_factory() interface
  mtd: nand-bbt: move nand_bbt.c to mtd folder

 drivers/mtd/Kconfig   |   7 +
 drivers/mtd/Makefile  |   1 +
 drivers/mtd/nand/Kconfig  |   2 +-
 drivers/mtd/nand/Makefile |   2 +-
 drivers/mtd/nand/docg4.c  |   6 +-
 drivers/mtd/nand/nand_base.c  | 145 +-
 drivers/mtd/{nand => }/nand_bbt.c | 542 --
 include/linux/mtd/bbm.h   |  96 +--
 include/linux/mtd/nand.h  |  16 +-
 include/linux/mtd/nand_bbt.h  | 177 +
 10 files changed, 562 insertions(+), 432 deletions(-)
 rename drivers/mtd/{nand => }/nand_bbt.c (68%)
 create mode 100644 include/linux/mtd/nand_bbt.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 07/12] mtd: nand: make nand_erase_nand() static

2015-12-14 Thread Peter Pan
From: Brian Norris 

nand_bbt.c doesn't need to call nand_erase_nand() any more.

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_base.c | 5 -
 include/linux/mtd/nand.h | 2 --
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 28d7a58..3058bb9 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -97,6 +97,9 @@ static int nand_get_device(struct mtd_info *mtd, int 
new_state);
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 struct mtd_oob_ops *ops);
 
+static int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+  int allowbbt);
+
 /*
  * For devices which display every fart in the system on a separate LED. Is
  * compiled away when LED support is disabled.
@@ -2881,7 +2884,7 @@ static int nand_erase(struct mtd_info *mtd, struct 
erase_info *instr)
  *
  * Erase one ore more blocks.
  */
-int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+static int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
int allowbbt)
 {
int page, status, pages_per_block, ret, chipnr;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 12c9c07..2051bd9 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -866,8 +866,6 @@ extern struct nand_manufacturers nand_manuf_ids[];
 extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
 extern int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs);
 extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
-extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
-  int allowbbt);
 extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, uint8_t *buf);
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 11/12] mtd: nand: remove nand_chip.bbt

2015-12-14 Thread Peter Pan
From: Brian Norris 

With new nand_bbt.c, nand_chip doesn't need bbt element any more

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 include/linux/mtd/nand.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index ee15f7d..99e4846 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -629,7 +629,6 @@ struct nand_buffers {
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
- * @bbt:   [INTERN] bad block table pointer
  * @nand_bbt:  [INTERN] pointer to bad block table structure, which
  * includes all information needed by Bad Block Management
  * @bbt_td:[REPLACEABLE] bad block table descriptor for flash
@@ -719,7 +718,6 @@ struct nand_chip {
struct nand_buffers *buffers;
struct nand_hw_control hwcontrol;
 
-   uint8_t *bbt;
struct nand_bbt *nand_bbt;
struct nand_bbt_descr *bbt_td;
struct nand_bbt_descr *bbt_md;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 10/12] mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro

2015-12-14 Thread Peter Pan
From: Brian Norris 

nand_bbt doesn't need nand badblock_pattern any more. So remove
NAND_BBT_DYNAMICSTRUCT from nand_bbt.h

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 include/linux/mtd/nand_bbt.h | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index 48a0620..e85596f 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -107,13 +107,6 @@ struct nand_bbt_descr {
  */
 #define NAND_BBT_NO_OOB_BBM0x0008
 
-/*
- * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
- * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
- * in nand_chip.bbt_options.
- */
-#define NAND_BBT_DYNAMICSTRUCT 0x8000
-
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS4
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 06/12] mtd: nand_bbt: use erase() and is_bad_bbm() hook in BBT

2015-12-14 Thread Peter Pan
From: Brian Norris 

Since NAND already create its nand_bbt struct, we can use erase()
hook instead of call nand_erase_nand() directly. Also, we can use
is_bad_bbm() to avoid passing badblock_pattern to BBT.

Signed-off-by: Brian Norris 
[Peter: remove @buf in create_bbt()]
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c | 138 
 1 file changed, 12 insertions(+), 126 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index f256be1..a5c8ab5 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -122,23 +122,6 @@ static int check_pattern(uint8_t *buf, int len, int 
paglen, struct nand_bbt_desc
 }
 
 /**
- * check_short_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf: the buffer to search
- * @td:search pattern descriptor
- *
- * Check for a pattern at the given place. Used to search bad block tables and
- * good / bad block identifiers. Same as check_pattern, but no optional empty
- * check.
- */
-static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
-{
-   /* Compare the pattern */
-   if (memcmp(buf + td->offs, td->pattern, td->len))
-   return -1;
-   return 0;
-}
-
-/**
  * add_marker_len - compute the length of the marker in data area
  * @td: BBT descriptor used for computation
  *
@@ -409,63 +392,23 @@ static void read_abs_bbts(struct mtd_info *mtd, uint8_t 
*buf,
}
 }
 
-/* Scan a given block partially */
-static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
-  loff_t offs, uint8_t *buf, int numpages)
-{
-   struct mtd_oob_ops ops;
-   int j, ret;
-
-   ops.ooblen = mtd->oobsize;
-   ops.oobbuf = buf;
-   ops.ooboffs = 0;
-   ops.datbuf = NULL;
-   ops.mode = MTD_OPS_PLACE_OOB;
-
-   for (j = 0; j < numpages; j++) {
-   /*
-* Read the full oob until read_oob is fixed to handle single
-* byte reads for 16 bit buswidth.
-*/
-   ret = mtd_read_oob(mtd, offs, );
-   /* Ignore ECC errors when checking for BBM */
-   if (ret && !mtd_is_bitflip_or_eccerr(ret))
-   return ret;
-
-   if (check_short_pattern(buf, bd))
-   return 1;
-
-   offs += mtd->writesize;
-   }
-   return 0;
-}
-
 /**
  * create_bbt - [GENERIC] Create a bad block table by scanning the device
  * @mtd: MTD device structure
- * @buf: temporary buffer
- * @bd: descriptor for the good/bad block search pattern
  * @chip: create the table for a specific chip, -1 read all chips; applies only
  *if NAND_BBT_PERCHIP option is set
  *
  * Create a bad block table by scanning the device for the given good/bad block
  * identify pattern.
  */
-static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
-   struct nand_bbt_descr *bd, int chip)
+static int create_bbt(struct mtd_info *mtd, int chip)
 {
struct nand_chip *this = mtd_to_nand(mtd);
-   int i, numblocks, numpages;
-   int startblock;
+   int i, startblock, numblocks;
loff_t from;
 
pr_info("Scanning device for bad blocks\n");
 
-   if (bd->options & NAND_BBT_SCAN2NDPAGE)
-   numpages = 2;
-   else
-   numpages = 1;
-
if (chip == -1) {
numblocks = mtd->size >> this->bbt_erase_shift;
startblock = 0;
@@ -482,15 +425,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
from = (loff_t)startblock << this->bbt_erase_shift;
}
 
-   if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
-   from += mtd->erasesize - (mtd->writesize * numpages);
-
for (i = startblock; i < numblocks; i++) {
int ret;
 
-   BUG_ON(bd->options & NAND_BBT_NO_OOB);
-
-   ret = scan_block_fast(mtd, bd, from, buf, numpages);
+   ret = this->nand_bbt->is_bad_bbm(mtd, from);
if (ret < 0)
return ret;
 
@@ -619,7 +557,6 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 int chipsel)
 {
struct nand_chip *this = mtd_to_nand(mtd);
-   struct erase_info einfo;
int i, res, chip = 0;
int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
int nrchips, pageoffs, ooboffs;
@@ -782,11 +719,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
buf[offs + (i >> sft)] &= ~(msk[dat] << sftcnt);
}
 
-   memset(, 0, sizeof(einfo));
-   einfo.mtd = mtd;
-   einfo.addr = to;
-   einfo.len = 1 << this->bbt_erase_shift;
-   res = nand_erase_nand(mtd, , 1);
+  

[PATCH v2 12/12] mtd: nand-bbt: move nand_bbt.c to mtd folder

2015-12-14 Thread Peter Pan
Since struct nand_chip is removed from nand_bbt.c, BBT is now
shareable. Both NAND and SPI NAND can use it. So move nand_bbt.c
from nand/ foler to mtd/ folder and create MTD_NAND_BBT config.
Both NAND and SPI NAND should depend on MTD_NAND_BBT.

Signed-off-by: Peter Pan 
---
 drivers/mtd/Kconfig   | 7 +++
 drivers/mtd/Makefile  | 1 +
 drivers/mtd/nand/Kconfig  | 2 +-
 drivers/mtd/nand/Makefile | 2 +-
 drivers/mtd/{nand => }/nand_bbt.c | 0
 5 files changed, 10 insertions(+), 2 deletions(-)
 rename drivers/mtd/{nand => }/nand_bbt.c (100%)

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 42cc953..8718556 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -322,6 +322,13 @@ config MTD_PARTITIONED_MASTER
  the parent of the partition device be the master device, rather than
  what lies behind the master.
 
+config MTD_NAND_BBT
+   tristate "Bad Block Table support for NAND based devices"
+   depends on MTD
+   help
+ Since struct nand_chip is removed from nand_bbt.c, BBT is now
+ shareable. Both NAND and SPI NAND can use it.
+
 source "drivers/mtd/chips/Kconfig"
 
 source "drivers/mtd/maps/Kconfig"
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 99bb9a1..55aed6f 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_SSFDC)   += ssfdc.o
 obj-$(CONFIG_SM_FTL)   += sm_ftl.o
 obj-$(CONFIG_MTD_OOPS) += mtdoops.o
 obj-$(CONFIG_MTD_SWAP) += mtdswap.o
+obj-$(CONFIG_MTD_NAND_BBT) += nand_bbt.o
 
 nftl-objs  := nftlcore.o nftlmount.o
 inftl-objs := inftlcore.o inftlmount.o
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 6c71f62..2e11994 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -12,7 +12,7 @@ config MTD_NAND_ECC_SMC
 
 menuconfig MTD_NAND
tristate "NAND Device Support"
-   depends on MTD
+   depends on MTD && MTD_NAND_BBT
select MTD_NAND_IDS
select MTD_NAND_ECC
help
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 2c7f014..4429f86 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -56,4 +56,4 @@ obj-$(CONFIG_MTD_NAND_SUNXI)  += sunxi_nand.o
 obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)+= brcmnand/
 
-nand-objs := nand_base.o nand_bbt.o nand_timings.o
+nand-objs := nand_base.o nand_timings.o
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand_bbt.c
similarity index 100%
rename from drivers/mtd/nand/nand_bbt.c
rename to drivers/mtd/nand_bbt.c
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 03/12] mtd: nand_bbt: add new API definitions

2015-12-14 Thread Peter Pan
From: Brian Norris 

Add new API definitions for nand_bbt to replace old ones without
any users. These API includes:
int nand_bbt_init(struct nand_bbt *bbt);
void nand_bbt_release(struct nand_bbt *bbt);
int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c  | 71 
 include/linux/mtd/nand_bbt.h |  6 
 2 files changed, 77 insertions(+)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 4b6a708..72aed20 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1375,3 +1375,74 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
 }
 
 EXPORT_SYMBOL(nand_scan_bbt);
+
+/**
+ * nand_bbt_init - [NAND BBT Interface] Initialize and locate/create a bad 
block
+ * table
+ * @bbt: NAND BBT structure
+ *
+ * This function selects the default bad block table support for the device and
+ * scans for an existing table, or else creates one.
+ */
+int nand_bbt_init(struct nand_bbt *bbt)
+{
+   /*
+* FIXME: For now, we call nand_default_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_default_bbt(bbt->mtd);
+}
+EXPORT_SYMBOL(nand_bbt_init);
+
+void nand_bbt_release(struct nand_bbt *bbt)
+{
+   kfree(bbt->bbt);
+}
+EXPORT_SYMBOL(nand_bbt_release);
+
+/**
+ * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
+ * @bbt: NAND BBT structure
+ * @offs: offset in the device
+ */
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_isreserved_bbt() directly. It will
+* change when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_isreserved_bbt(bbt->mtd, offs);
+}
+EXPORT_SYMBOL(nand_bbt_isreserved);
+
+/**
+ * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
+ * @bbt: NAND BBT structure
+ * @offs: offset in the device
+ */
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_isbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+* Since we already have nand_bbt_isreserved(), we don't need to
+* check pass down allow_bbt.
+*/
+   return nand_isbad_bbt(bbt->mtd, offs, 1);
+}
+EXPORT_SYMBOL(nand_bbt_isbad);
+
+/**
+ * nand_bbt_markbad - [NAND BBT Interface] Mark a block bad in the BBT
+ * @bbt: NAND BBT structure
+ * @offs: offset of the bad block
+ */
+int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_markbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_markbad_bbt(bbt->mtd, offs);
+}
+EXPORT_SYMBOL(nand_bbt_markbad);
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index e468571..150c49a 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -174,4 +174,10 @@ struct nand_bbt {
u8 *bbt;
 };
 
+int nand_bbt_init(struct nand_bbt *bbt);
+void nand_bbt_release(struct nand_bbt *bbt);
+int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);
+
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 08/12] mtd: nand_bbt: remove struct nand_chip from nand_bbt.c

2015-12-14 Thread Peter Pan
From: Brian Norris 

This commit contains most of modification. But the job is quite
simple --- replace struct nand_chip with struct nand_bbt. There
is no algorithm change, just replacement.

Signed-off-by: Brian Norris 
Signed-off-by: Peter Pan 
---
 drivers/mtd/nand/nand_bbt.c | 391 ++--
 1 file changed, 193 insertions(+), 198 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index a5c8ab5..b46b4ae 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -60,8 +60,7 @@
 #include 
 #include 
 #include 
-#include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -76,20 +75,20 @@
 #define BBT_ENTRY_MASK 0x03
 #define BBT_ENTRY_SHIFT2
 
-static int nand_update_bbt(struct mtd_info *mtd, loff_t offs);
+static int nand_update_bbt(struct nand_bbt *bbt, loff_t offs);
 
-static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block)
+static inline uint8_t bbt_get_entry(struct nand_bbt *bbt, int block)
 {
-   uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT];
+   uint8_t entry = bbt->bbt[block >> BBT_ENTRY_SHIFT];
entry >>= (block & BBT_ENTRY_MASK) * 2;
return entry & BBT_ENTRY_MASK;
 }
 
-static inline void bbt_mark_entry(struct nand_chip *chip, int block,
+static inline void bbt_mark_entry(struct nand_bbt *bbt, int block,
uint8_t mark)
 {
uint8_t msk = (mark & BBT_ENTRY_MASK) << ((block & BBT_ENTRY_MASK) * 2);
-   chip->bbt[block >> BBT_ENTRY_SHIFT] |= msk;
+   bbt->bbt[block >> BBT_ENTRY_SHIFT] |= msk;
 }
 
 static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
@@ -142,7 +141,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
 
 /**
  * read_bbt - [GENERIC] Read the bad block table starting from page
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @page: the starting page
  * @num: the number of bbt descriptors to read
@@ -151,11 +150,11 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
  *
  * Read the bad block table starting from page.
  */
-static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
+static int read_bbt(struct nand_bbt *bbt, uint8_t *buf, int page, int num,
struct nand_bbt_descr *td, int offs)
 {
+   struct mtd_info *mtd = bbt->mtd;
int res, ret = 0, i, j, act = 0;
-   struct nand_chip *this = mtd_to_nand(mtd);
size_t retlen, len, totlen;
loff_t from;
int bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -165,10 +164,10 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, 
int page, int num,
 
totlen = (num * bits) >> 3;
marker_len = add_marker_len(td);
-   from = ((loff_t)page) << this->page_shift;
+   from = ((loff_t)page) << bbt->page_shift;
 
while (totlen) {
-   len = min(totlen, (size_t)(1 << this->bbt_erase_shift));
+   len = min(totlen, (size_t)(1 << bbt->bbt_erase_shift));
if (marker_len) {
/*
 * In case the BBT marker is not in the OOB area it
@@ -204,8 +203,8 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int 
page, int num,
if (reserved_block_code && (tmp == 
reserved_block_code)) {
pr_info("nand_read_bbt: reserved block 
at 0x%012llx\n",
 (loff_t)(offs + act) <<
-this->bbt_erase_shift);
-   bbt_mark_entry(this, offs + act,
+bbt->bbt_erase_shift);
+   bbt_mark_entry(bbt, offs + act,
BBT_BLOCK_RESERVED);
mtd->ecc_stats.bbtblocks++;
continue;
@@ -216,13 +215,13 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, 
int page, int num,
 */
pr_info("nand_read_bbt: bad block at 
0x%012llx\n",
 (loff_t)(offs + act) <<
-this->bbt_erase_shift);
+bbt->bbt_erase_shift);
/* Factory marked bad or worn out? */
if (tmp == 0)
-   bbt_mark_entry(this, offs + act,
+   bbt_mark_entry(bbt, offs + act,
BBT_BLOCK_FACTORY_BAD);
 

[PATCH v2 01/12] mtd: nand_bbt: new header for nand family BBT

2015-12-14 Thread Peter Pan
From: Brian Norris 

Migrating existing BBT definitions from bbm.h to nand_bbt.h

Signed-off-by: Brian Norris 
[Peter: correct misspelling. s/neccecary/necessary/]
Signed-off-by: Peter Pan 
---
 include/linux/mtd/bbm.h  |  96 +--
 include/linux/mtd/nand_bbt.h | 118 +++
 2 files changed, 119 insertions(+), 95 deletions(-)
 create mode 100644 include/linux/mtd/nand_bbt.h

diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 36bb6a5..fb751d9 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -28,102 +28,8 @@
 #ifndef __LINUX_MTD_BBM_H
 #define __LINUX_MTD_BBM_H
 
-/* The maximum number of NAND chips in an array */
-#define NAND_MAX_CHIPS 8
+#include 
 
-/**
- * struct nand_bbt_descr - bad block table descriptor
- * @options:   options for this descriptor
- * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE
- * when bbt is searched, then we store the found bbts pages here.
- * Its an array and supports up to 8 chips now
- * @offs:  offset of the pattern in the oob area of the page
- * @veroffs:   offset of the bbt version counter in the oob are of the page
- * @version:   version read from the bbt page during scan
- * @len:   length of the pattern, if 0 no pattern check is performed
- * @maxblocks: maximum number of blocks to search for a bbt. This number of
- * blocks is reserved at the end of the device where the tables are
- * written.
- * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
- *  bad) block in the stored bbt
- * @pattern:   pattern to identify bad block table or factory marked good /
- * bad blocks, can be NULL, if len = 0
- *
- * Descriptor for the bad block table marker and the descriptor for the
- * pattern which identifies good and bad blocks. The assumption is made
- * that the pattern and the version count are always located in the oob area
- * of the first block.
- */
-struct nand_bbt_descr {
-   int options;
-   int pages[NAND_MAX_CHIPS];
-   int offs;
-   int veroffs;
-   uint8_t version[NAND_MAX_CHIPS];
-   int len;
-   int maxblocks;
-   int reserved_block_code;
-   uint8_t *pattern;
-};
-
-/* Options for the bad block table descriptors */
-
-/* The number of bits used per block in the bbt on the device */
-#define NAND_BBT_NRBITS_MSK0x000F
-#define NAND_BBT_1BIT  0x0001
-#define NAND_BBT_2BIT  0x0002
-#define NAND_BBT_4BIT  0x0004
-#define NAND_BBT_8BIT  0x0008
-/* The bad block table is in the last good block of the device */
-#define NAND_BBT_LASTBLOCK 0x0010
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_ABSPAGE   0x0020
-/* bbt is stored per chip on multichip devices */
-#define NAND_BBT_PERCHIP   0x0080
-/* bbt has a version counter at offset veroffs */
-#define NAND_BBT_VERSION   0x0100
-/* Create a bbt if none exists */
-#define NAND_BBT_CREATE0x0200
-/*
- * Create an empty BBT with no vendor information. Vendor's information may be
- * unavailable, for example, if the NAND controller has a different data and 
OOB
- * layout or if this information is already purged. Must be used in conjunction
- * with NAND_BBT_CREATE.
- */
-#define NAND_BBT_CREATE_EMPTY  0x0400
-/* Write bbt if neccecary */
-#define NAND_BBT_WRITE 0x2000
-/* Read and write back block contents when writing bbt */
-#define NAND_BBT_SAVECONTENT   0x4000
-/* Search good / bad pattern on the first and the second page */
-#define NAND_BBT_SCAN2NDPAGE   0x8000
-/* Search good / bad pattern on the last page of the eraseblock */
-#define NAND_BBT_SCANLASTPAGE  0x0001
-/*
- * Use a flash based bad block table. By default, OOB identifier is saved in
- * OOB area. This option is passed to the default bad block table function.
- */
-#define NAND_BBT_USE_FLASH 0x0002
-/*
- * Do not store flash based bad block table marker in the OOB area; store it
- * in-band.
- */
-#define NAND_BBT_NO_OOB0x0004
-/*
- * Do not write new bad block markers to OOB; useful, e.g., when ECC covers
- * entire spare area. Must be used with NAND_BBT_USE_FLASH.
- */
-#define NAND_BBT_NO_OOB_BBM0x0008
-
-/*
- * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
- * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
- * in nand_chip.bbt_options.
- */
-#define NAND_BBT_DYNAMICSTRUCT 0x8000
-
-/* The maximum number of blocks to scan for a bbt */
-#define NAND_BBT_SCAN_MAXBLOCKS4
 
 /*
  * Constants for oob configuration
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
new file mode 100644
index 000..5a65230
--- /dev/null
+++ b/include/linux/mtd/nand_bbt.h
@@ -0,0 +1,118

[PATCH v2 11/12] mtd: nand: remove nand_chip.bbt

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

With new nand_bbt.c, nand_chip doesn't need bbt element any more

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 include/linux/mtd/nand.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index ee15f7d..99e4846 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -629,7 +629,6 @@ struct nand_buffers {
  * @read_retries:  [INTERN] the number of read retry modes supported
  * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
- * @bbt:   [INTERN] bad block table pointer
  * @nand_bbt:  [INTERN] pointer to bad block table structure, which
  * includes all information needed by Bad Block Management
  * @bbt_td:[REPLACEABLE] bad block table descriptor for flash
@@ -719,7 +718,6 @@ struct nand_chip {
struct nand_buffers *buffers;
struct nand_hw_control hwcontrol;
 
-   uint8_t *bbt;
struct nand_bbt *nand_bbt;
struct nand_bbt_descr *bbt_td;
struct nand_bbt_descr *bbt_md;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 07/12] mtd: nand: make nand_erase_nand() static

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

nand_bbt.c doesn't need to call nand_erase_nand() any more.

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_base.c | 5 -
 include/linux/mtd/nand.h | 2 --
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 28d7a58..3058bb9 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -97,6 +97,9 @@ static int nand_get_device(struct mtd_info *mtd, int 
new_state);
 static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
 struct mtd_oob_ops *ops);
 
+static int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+  int allowbbt);
+
 /*
  * For devices which display every fart in the system on a separate LED. Is
  * compiled away when LED support is disabled.
@@ -2881,7 +2884,7 @@ static int nand_erase(struct mtd_info *mtd, struct 
erase_info *instr)
  *
  * Erase one ore more blocks.
  */
-int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+static int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
int allowbbt)
 {
int page, status, pages_per_block, ret, chipnr;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 12c9c07..2051bd9 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -866,8 +866,6 @@ extern struct nand_manufacturers nand_manuf_ids[];
 extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
 extern int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs);
 extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
-extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
-  int allowbbt);
 extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, uint8_t *buf);
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 10/12] mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

nand_bbt doesn't need nand badblock_pattern any more. So remove
NAND_BBT_DYNAMICSTRUCT from nand_bbt.h

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 include/linux/mtd/nand_bbt.h | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index 48a0620..e85596f 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -107,13 +107,6 @@ struct nand_bbt_descr {
  */
 #define NAND_BBT_NO_OOB_BBM0x0008
 
-/*
- * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
- * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
- * in nand_chip.bbt_options.
- */
-#define NAND_BBT_DYNAMICSTRUCT 0x8000
-
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS4
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 08/12] mtd: nand_bbt: remove struct nand_chip from nand_bbt.c

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

This commit contains most of modification. But the job is quite
simple --- replace struct nand_chip with struct nand_bbt. There
is no algorithm change, just replacement.

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c | 391 ++--
 1 file changed, 193 insertions(+), 198 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index a5c8ab5..b46b4ae 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -60,8 +60,7 @@
 #include 
 #include 
 #include 
-#include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -76,20 +75,20 @@
 #define BBT_ENTRY_MASK 0x03
 #define BBT_ENTRY_SHIFT2
 
-static int nand_update_bbt(struct mtd_info *mtd, loff_t offs);
+static int nand_update_bbt(struct nand_bbt *bbt, loff_t offs);
 
-static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block)
+static inline uint8_t bbt_get_entry(struct nand_bbt *bbt, int block)
 {
-   uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT];
+   uint8_t entry = bbt->bbt[block >> BBT_ENTRY_SHIFT];
entry >>= (block & BBT_ENTRY_MASK) * 2;
return entry & BBT_ENTRY_MASK;
 }
 
-static inline void bbt_mark_entry(struct nand_chip *chip, int block,
+static inline void bbt_mark_entry(struct nand_bbt *bbt, int block,
uint8_t mark)
 {
uint8_t msk = (mark & BBT_ENTRY_MASK) << ((block & BBT_ENTRY_MASK) * 2);
-   chip->bbt[block >> BBT_ENTRY_SHIFT] |= msk;
+   bbt->bbt[block >> BBT_ENTRY_SHIFT] |= msk;
 }
 
 static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
@@ -142,7 +141,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
 
 /**
  * read_bbt - [GENERIC] Read the bad block table starting from page
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @page: the starting page
  * @num: the number of bbt descriptors to read
@@ -151,11 +150,11 @@ static u32 add_marker_len(struct nand_bbt_descr *td)
  *
  * Read the bad block table starting from page.
  */
-static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
+static int read_bbt(struct nand_bbt *bbt, uint8_t *buf, int page, int num,
struct nand_bbt_descr *td, int offs)
 {
+   struct mtd_info *mtd = bbt->mtd;
int res, ret = 0, i, j, act = 0;
-   struct nand_chip *this = mtd_to_nand(mtd);
size_t retlen, len, totlen;
loff_t from;
int bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -165,10 +164,10 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, 
int page, int num,
 
totlen = (num * bits) >> 3;
marker_len = add_marker_len(td);
-   from = ((loff_t)page) << this->page_shift;
+   from = ((loff_t)page) << bbt->page_shift;
 
while (totlen) {
-   len = min(totlen, (size_t)(1 << this->bbt_erase_shift));
+   len = min(totlen, (size_t)(1 << bbt->bbt_erase_shift));
if (marker_len) {
/*
 * In case the BBT marker is not in the OOB area it
@@ -204,8 +203,8 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int 
page, int num,
if (reserved_block_code && (tmp == 
reserved_block_code)) {
pr_info("nand_read_bbt: reserved block 
at 0x%012llx\n",
 (loff_t)(offs + act) <<
-this->bbt_erase_shift);
-   bbt_mark_entry(this, offs + act,
+bbt->bbt_erase_shift);
+   bbt_mark_entry(bbt, offs + act,
BBT_BLOCK_RESERVED);
mtd->ecc_stats.bbtblocks++;
continue;
@@ -216,13 +215,13 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, 
int page, int num,
 */
pr_info("nand_read_bbt: bad block at 
0x%012llx\n",
 (loff_t)(offs + act) <<
-this->bbt_erase_shift);
+bbt->bbt_erase_shift);
/* Factory marked bad or worn out? */
if (tmp == 0)
-   bbt_mark_entry(this, offs + act,
+   bbt_mark_entry(bbt, offs + act,

[PATCH v2 06/12] mtd: nand_bbt: use erase() and is_bad_bbm() hook in BBT

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

Since NAND already create its nand_bbt struct, we can use erase()
hook instead of call nand_erase_nand() directly. Also, we can use
is_bad_bbm() to avoid passing badblock_pattern to BBT.

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
[Peter: remove @buf in create_bbt()]
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c | 138 
 1 file changed, 12 insertions(+), 126 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index f256be1..a5c8ab5 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -122,23 +122,6 @@ static int check_pattern(uint8_t *buf, int len, int 
paglen, struct nand_bbt_desc
 }
 
 /**
- * check_short_pattern - [GENERIC] check if a pattern is in the buffer
- * @buf: the buffer to search
- * @td:search pattern descriptor
- *
- * Check for a pattern at the given place. Used to search bad block tables and
- * good / bad block identifiers. Same as check_pattern, but no optional empty
- * check.
- */
-static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
-{
-   /* Compare the pattern */
-   if (memcmp(buf + td->offs, td->pattern, td->len))
-   return -1;
-   return 0;
-}
-
-/**
  * add_marker_len - compute the length of the marker in data area
  * @td: BBT descriptor used for computation
  *
@@ -409,63 +392,23 @@ static void read_abs_bbts(struct mtd_info *mtd, uint8_t 
*buf,
}
 }
 
-/* Scan a given block partially */
-static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
-  loff_t offs, uint8_t *buf, int numpages)
-{
-   struct mtd_oob_ops ops;
-   int j, ret;
-
-   ops.ooblen = mtd->oobsize;
-   ops.oobbuf = buf;
-   ops.ooboffs = 0;
-   ops.datbuf = NULL;
-   ops.mode = MTD_OPS_PLACE_OOB;
-
-   for (j = 0; j < numpages; j++) {
-   /*
-* Read the full oob until read_oob is fixed to handle single
-* byte reads for 16 bit buswidth.
-*/
-   ret = mtd_read_oob(mtd, offs, );
-   /* Ignore ECC errors when checking for BBM */
-   if (ret && !mtd_is_bitflip_or_eccerr(ret))
-   return ret;
-
-   if (check_short_pattern(buf, bd))
-   return 1;
-
-   offs += mtd->writesize;
-   }
-   return 0;
-}
-
 /**
  * create_bbt - [GENERIC] Create a bad block table by scanning the device
  * @mtd: MTD device structure
- * @buf: temporary buffer
- * @bd: descriptor for the good/bad block search pattern
  * @chip: create the table for a specific chip, -1 read all chips; applies only
  *if NAND_BBT_PERCHIP option is set
  *
  * Create a bad block table by scanning the device for the given good/bad block
  * identify pattern.
  */
-static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
-   struct nand_bbt_descr *bd, int chip)
+static int create_bbt(struct mtd_info *mtd, int chip)
 {
struct nand_chip *this = mtd_to_nand(mtd);
-   int i, numblocks, numpages;
-   int startblock;
+   int i, startblock, numblocks;
loff_t from;
 
pr_info("Scanning device for bad blocks\n");
 
-   if (bd->options & NAND_BBT_SCAN2NDPAGE)
-   numpages = 2;
-   else
-   numpages = 1;
-
if (chip == -1) {
numblocks = mtd->size >> this->bbt_erase_shift;
startblock = 0;
@@ -482,15 +425,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
from = (loff_t)startblock << this->bbt_erase_shift;
}
 
-   if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
-   from += mtd->erasesize - (mtd->writesize * numpages);
-
for (i = startblock; i < numblocks; i++) {
int ret;
 
-   BUG_ON(bd->options & NAND_BBT_NO_OOB);
-
-   ret = scan_block_fast(mtd, bd, from, buf, numpages);
+   ret = this->nand_bbt->is_bad_bbm(mtd, from);
if (ret < 0)
return ret;
 
@@ -619,7 +557,6 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 int chipsel)
 {
struct nand_chip *this = mtd_to_nand(mtd);
-   struct erase_info einfo;
int i, res, chip = 0;
int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
int nrchips, pageoffs, ooboffs;
@@ -782,11 +719,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
buf[offs + (i >> sft)] &= ~(msk[dat] << sftcnt);
}
 
-   memset(, 0, sizeof(einfo));
-   einfo.mtd = mtd;
-   einfo.addr = to;
-   einfo.

[PATCH v2 12/12] mtd: nand-bbt: move nand_bbt.c to mtd folder

2015-12-14 Thread Peter Pan
Since struct nand_chip is removed from nand_bbt.c, BBT is now
shareable. Both NAND and SPI NAND can use it. So move nand_bbt.c
from nand/ foler to mtd/ folder and create MTD_NAND_BBT config.
Both NAND and SPI NAND should depend on MTD_NAND_BBT.

Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/Kconfig   | 7 +++
 drivers/mtd/Makefile  | 1 +
 drivers/mtd/nand/Kconfig  | 2 +-
 drivers/mtd/nand/Makefile | 2 +-
 drivers/mtd/{nand => }/nand_bbt.c | 0
 5 files changed, 10 insertions(+), 2 deletions(-)
 rename drivers/mtd/{nand => }/nand_bbt.c (100%)

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 42cc953..8718556 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -322,6 +322,13 @@ config MTD_PARTITIONED_MASTER
  the parent of the partition device be the master device, rather than
  what lies behind the master.
 
+config MTD_NAND_BBT
+   tristate "Bad Block Table support for NAND based devices"
+   depends on MTD
+   help
+ Since struct nand_chip is removed from nand_bbt.c, BBT is now
+ shareable. Both NAND and SPI NAND can use it.
+
 source "drivers/mtd/chips/Kconfig"
 
 source "drivers/mtd/maps/Kconfig"
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 99bb9a1..55aed6f 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_SSFDC)   += ssfdc.o
 obj-$(CONFIG_SM_FTL)   += sm_ftl.o
 obj-$(CONFIG_MTD_OOPS) += mtdoops.o
 obj-$(CONFIG_MTD_SWAP) += mtdswap.o
+obj-$(CONFIG_MTD_NAND_BBT) += nand_bbt.o
 
 nftl-objs  := nftlcore.o nftlmount.o
 inftl-objs := inftlcore.o inftlmount.o
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 6c71f62..2e11994 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -12,7 +12,7 @@ config MTD_NAND_ECC_SMC
 
 menuconfig MTD_NAND
tristate "NAND Device Support"
-   depends on MTD
+   depends on MTD && MTD_NAND_BBT
select MTD_NAND_IDS
select MTD_NAND_ECC
help
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 2c7f014..4429f86 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -56,4 +56,4 @@ obj-$(CONFIG_MTD_NAND_SUNXI)  += sunxi_nand.o
 obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)+= brcmnand/
 
-nand-objs := nand_base.o nand_bbt.o nand_timings.o
+nand-objs := nand_base.o nand_timings.o
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand_bbt.c
similarity index 100%
rename from drivers/mtd/nand/nand_bbt.c
rename to drivers/mtd/nand_bbt.c
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 03/12] mtd: nand_bbt: add new API definitions

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

Add new API definitions for nand_bbt to replace old ones without
any users. These API includes:
int nand_bbt_init(struct nand_bbt *bbt);
void nand_bbt_release(struct nand_bbt *bbt);
int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c  | 71 
 include/linux/mtd/nand_bbt.h |  6 
 2 files changed, 77 insertions(+)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 4b6a708..72aed20 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1375,3 +1375,74 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
 }
 
 EXPORT_SYMBOL(nand_scan_bbt);
+
+/**
+ * nand_bbt_init - [NAND BBT Interface] Initialize and locate/create a bad 
block
+ * table
+ * @bbt: NAND BBT structure
+ *
+ * This function selects the default bad block table support for the device and
+ * scans for an existing table, or else creates one.
+ */
+int nand_bbt_init(struct nand_bbt *bbt)
+{
+   /*
+* FIXME: For now, we call nand_default_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_default_bbt(bbt->mtd);
+}
+EXPORT_SYMBOL(nand_bbt_init);
+
+void nand_bbt_release(struct nand_bbt *bbt)
+{
+   kfree(bbt->bbt);
+}
+EXPORT_SYMBOL(nand_bbt_release);
+
+/**
+ * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
+ * @bbt: NAND BBT structure
+ * @offs: offset in the device
+ */
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_isreserved_bbt() directly. It will
+* change when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_isreserved_bbt(bbt->mtd, offs);
+}
+EXPORT_SYMBOL(nand_bbt_isreserved);
+
+/**
+ * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
+ * @bbt: NAND BBT structure
+ * @offs: offset in the device
+ */
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_isbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+* Since we already have nand_bbt_isreserved(), we don't need to
+* check pass down allow_bbt.
+*/
+   return nand_isbad_bbt(bbt->mtd, offs, 1);
+}
+EXPORT_SYMBOL(nand_bbt_isbad);
+
+/**
+ * nand_bbt_markbad - [NAND BBT Interface] Mark a block bad in the BBT
+ * @bbt: NAND BBT structure
+ * @offs: offset of the bad block
+ */
+int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_markbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_markbad_bbt(bbt->mtd, offs);
+}
+EXPORT_SYMBOL(nand_bbt_markbad);
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index e468571..150c49a 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -174,4 +174,10 @@ struct nand_bbt {
u8 *bbt;
 };
 
+int nand_bbt_init(struct nand_bbt *bbt);
+void nand_bbt_release(struct nand_bbt *bbt);
+int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);
+
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 01/12] mtd: nand_bbt: new header for nand family BBT

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

Migrating existing BBT definitions from bbm.h to nand_bbt.h

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
[Peter: correct misspelling. s/neccecary/necessary/]
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 include/linux/mtd/bbm.h  |  96 +--
 include/linux/mtd/nand_bbt.h | 118 +++
 2 files changed, 119 insertions(+), 95 deletions(-)
 create mode 100644 include/linux/mtd/nand_bbt.h

diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 36bb6a5..fb751d9 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -28,102 +28,8 @@
 #ifndef __LINUX_MTD_BBM_H
 #define __LINUX_MTD_BBM_H
 
-/* The maximum number of NAND chips in an array */
-#define NAND_MAX_CHIPS 8
+#include 
 
-/**
- * struct nand_bbt_descr - bad block table descriptor
- * @options:   options for this descriptor
- * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE
- * when bbt is searched, then we store the found bbts pages here.
- * Its an array and supports up to 8 chips now
- * @offs:  offset of the pattern in the oob area of the page
- * @veroffs:   offset of the bbt version counter in the oob are of the page
- * @version:   version read from the bbt page during scan
- * @len:   length of the pattern, if 0 no pattern check is performed
- * @maxblocks: maximum number of blocks to search for a bbt. This number of
- * blocks is reserved at the end of the device where the tables are
- * written.
- * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
- *  bad) block in the stored bbt
- * @pattern:   pattern to identify bad block table or factory marked good /
- * bad blocks, can be NULL, if len = 0
- *
- * Descriptor for the bad block table marker and the descriptor for the
- * pattern which identifies good and bad blocks. The assumption is made
- * that the pattern and the version count are always located in the oob area
- * of the first block.
- */
-struct nand_bbt_descr {
-   int options;
-   int pages[NAND_MAX_CHIPS];
-   int offs;
-   int veroffs;
-   uint8_t version[NAND_MAX_CHIPS];
-   int len;
-   int maxblocks;
-   int reserved_block_code;
-   uint8_t *pattern;
-};
-
-/* Options for the bad block table descriptors */
-
-/* The number of bits used per block in the bbt on the device */
-#define NAND_BBT_NRBITS_MSK0x000F
-#define NAND_BBT_1BIT  0x0001
-#define NAND_BBT_2BIT  0x0002
-#define NAND_BBT_4BIT  0x0004
-#define NAND_BBT_8BIT  0x0008
-/* The bad block table is in the last good block of the device */
-#define NAND_BBT_LASTBLOCK 0x0010
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_ABSPAGE   0x0020
-/* bbt is stored per chip on multichip devices */
-#define NAND_BBT_PERCHIP   0x0080
-/* bbt has a version counter at offset veroffs */
-#define NAND_BBT_VERSION   0x0100
-/* Create a bbt if none exists */
-#define NAND_BBT_CREATE0x0200
-/*
- * Create an empty BBT with no vendor information. Vendor's information may be
- * unavailable, for example, if the NAND controller has a different data and 
OOB
- * layout or if this information is already purged. Must be used in conjunction
- * with NAND_BBT_CREATE.
- */
-#define NAND_BBT_CREATE_EMPTY  0x0400
-/* Write bbt if neccecary */
-#define NAND_BBT_WRITE 0x2000
-/* Read and write back block contents when writing bbt */
-#define NAND_BBT_SAVECONTENT   0x4000
-/* Search good / bad pattern on the first and the second page */
-#define NAND_BBT_SCAN2NDPAGE   0x8000
-/* Search good / bad pattern on the last page of the eraseblock */
-#define NAND_BBT_SCANLASTPAGE  0x0001
-/*
- * Use a flash based bad block table. By default, OOB identifier is saved in
- * OOB area. This option is passed to the default bad block table function.
- */
-#define NAND_BBT_USE_FLASH 0x0002
-/*
- * Do not store flash based bad block table marker in the OOB area; store it
- * in-band.
- */
-#define NAND_BBT_NO_OOB0x0004
-/*
- * Do not write new bad block markers to OOB; useful, e.g., when ECC covers
- * entire spare area. Must be used with NAND_BBT_USE_FLASH.
- */
-#define NAND_BBT_NO_OOB_BBM0x0008
-
-/*
- * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
- * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
- * in nand_chip.bbt_options.
- */
-#define NAND_BBT_DYNAMICSTRUCT 0x8000
-
-/* The maximum number of blocks to scan for a bbt */
-#define NAND_BBT_SCAN_MAXBLOCKS4
 
 /*
  * Constants for oob configuration
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
ne

[PATCH v2 09/12] mtd: nand_bbt: remove old API definitions

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

remove old BBT APIs

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c | 110 +---
 include/linux/mtd/nand.h|   3 --
 2 files changed, 22 insertions(+), 91 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index b46b4ae..22861a1 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1166,13 +1166,14 @@ static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
 };
 
 /**
- * nand_default_bbt - [NAND Interface] Select a default bad block table for 
the device
+ * nand_bbt_init - [NAND BBT Interface] Initialize and locate/create a bad 
block
+ * table
  * @bbt: NAND BBT structure
  *
  * This function selects the default bad block table support for the device and
- * calls the nand_scan_bbt function.
+ * scans for an existing table, or else creates one.
  */
-int nand_default_bbt(struct nand_bbt *bbt)
+int nand_bbt_init(struct nand_bbt *bbt)
 {
/* Is a flash based bad block table requested? */
if (bbt->bbt_options & NAND_BBT_USE_FLASH) {
@@ -1193,46 +1194,54 @@ int nand_default_bbt(struct nand_bbt *bbt)
 
return nand_scan_bbt(bbt);
 }
+EXPORT_SYMBOL(nand_bbt_init);
+
+void nand_bbt_release(struct nand_bbt *bbt)
+{
+   kfree(bbt->bbt);
+}
+EXPORT_SYMBOL(nand_bbt_release);
 
 /**
- * nand_isreserved_bbt - [NAND Interface] Check if a block is reserved
+ * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
  * @bbt: NAND BBT structure
  * @offs: offset in the device
  */
-int nand_isreserved_bbt(struct nand_bbt *bbt, loff_t offs)
+int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
 {
int block;
 
block = (int)(offs >> bbt->bbt_erase_shift);
return bbt_get_entry(bbt, block) == BBT_BLOCK_RESERVED;
 }
+EXPORT_SYMBOL(nand_bbt_isreserved);
 
 /**
- * nand_isbad_bbt - [NAND Interface] Check if a block is bad
+ * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
  * @bbt: NAND BBT structure
  * @offs: offset in the device
- * @allowbbt: allow access to bad block table region
  */
-int nand_isbad_bbt(struct nand_bbt *bbt, loff_t offs, int allowbbt)
+int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
 {
int block, res;
 
block = (int)(offs >> bbt->bbt_erase_shift);
res = bbt_get_entry(bbt, block);
 
-   pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 
0x%02x\n",
+   pr_debug("nand_bbt_isbad(): bbt info for offs 0x%08x: (block %d) 
0x%02x\n",
 (unsigned int)offs, block, res);
 
switch (res) {
case BBT_BLOCK_GOOD:
+   case BBT_BLOCK_RESERVED:
return 0;
case BBT_BLOCK_WORN:
+   case BBT_BLOCK_FACTORY_BAD:
+   default:
return 1;
-   case BBT_BLOCK_RESERVED:
-   return allowbbt ? 0 : 1;
}
-   return 1;
 }
+EXPORT_SYMBOL(nand_bbt_isbad);
 
 /**
  * nand_bbt_update_mark - update mark in the BBT
@@ -1257,84 +1266,13 @@ static int nand_bbt_update_mark(struct nand_bbt *bbt, 
loff_t offs, uint8_t mark)
 }
 
 /**
- * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
- * @bbt: NAND BBT structure
- * @offs: offset of the bad block
- */
-int nand_markbad_bbt(struct nand_bbt *bbt, loff_t offs)
-{
-   return nand_bbt_update_mark(bbt, offs, BBT_BLOCK_WORN);
-}
-EXPORT_SYMBOL(nand_scan_bbt);
-
-/**
- * nand_bbt_init - [NAND BBT Interface] Initialize and locate/create a bad 
block
- * table
- * @bbt: NAND BBT structure
- *
- * This function selects the default bad block table support for the device and
- * scans for an existing table, or else creates one.
- */
-int nand_bbt_init(struct nand_bbt *bbt)
-{
-   /*
-* FIXME: For now, we call nand_default_bbt() directly. It will change
-* when we use struct nand_bbt instead of struct nand_chip.
-*/
-   return nand_default_bbt(bbt);
-}
-EXPORT_SYMBOL(nand_bbt_init);
-
-void nand_bbt_release(struct nand_bbt *bbt)
-{
-   kfree(bbt->bbt);
-}
-EXPORT_SYMBOL(nand_bbt_release);
-
-/**
- * nand_bbt_isreserved - [NAND BBT Interface] Check if a block is reserved
- * @bbt: NAND BBT structure
- * @offs: offset in the device
- */
-int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs)
-{
-   /*
-* FIXME: For now, we call nand_isreserved_bbt() directly. It will
-* change when we use struct nand_bbt instead of struct nand_chip.
-*/
-   return nand_isreserved_bbt(bbt, offs);
-}
-EXPORT_SYMBOL(nand_bbt_isreserved);
-
-/**
- * nand_bbt_isbad - [NAND BBT Interface] Check if a block is bad
- * @bbt: NAND BBT structure
- * @offs: offset in the device
- */
-int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
-{
-   /*
-* FIXME: For now, we call nand_isbad_

[PATCH v2 05/12] mtd: nand: use new BBT API instead of old ones

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

Use new BBT APIs (nand_bbt_*()) in NAND. Keep old APIs (nand_*_bbt())
exist temporarily.

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
[Peter: 1. use nand_bbt_markbad_factory() in docg4.c and implement
2. nand_create_factory_badblock_pattern(), nand_is_bad_bbm() and
nand_default_bbt() in nand_base.c
3. add NAND_BADBLOCK_PATTERN_ALLOC macro]
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/docg4.c |   6 +-
 drivers/mtd/nand/nand_base.c | 140 ---
 include/linux/mtd/nand.h |   9 ++-
 3 files changed, 143 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index da93d7f..1be7fa2 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -1037,7 +1037,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
 * operation after device power-up.  The above read ensures it never is.
 * Ugly, I know.
 */
-   if (nand->bbt == NULL)  /* no memory-based bbt */
+   if (nand->nand_bbt == NULL)  /* no memory-based bbt */
goto exit;
 
if (mtd->ecc_stats.failed > eccfailed_stats) {
@@ -1064,8 +1064,8 @@ static int __init read_factory_bbt(struct mtd_info *mtd)
unsigned long bits = ~buf[i];
for_each_set_bit(bitnum, , 8) {
int badblock = block + 7 - bitnum;
-   nand->bbt[badblock / 4] |=
-   0x03 << ((badblock % 4) * 2);
+   nand_bbt_markbad_factory(nand->nand_bbt,
+   badblock << nand->bbt_erase_shift);
mtd->ecc_stats.badblocks++;
dev_notice(doc->dev, "factory-marked bad block: %d\n",
   badblock);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5aec154..28d7a58 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -450,8 +450,8 @@ static int nand_block_markbad_lowlevel(struct mtd_info 
*mtd, loff_t ofs)
}
 
/* Mark block bad in BBT */
-   if (chip->bbt) {
-   res = nand_markbad_bbt(mtd, ofs);
+   if (chip->nand_bbt) {
+   res = nand_bbt_markbad(chip->nand_bbt, ofs);
if (!ret)
ret = res;
}
@@ -493,10 +493,10 @@ static int nand_block_isreserved(struct mtd_info *mtd, 
loff_t ofs)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
 
-   if (!chip->bbt)
+   if (!chip->nand_bbt)
return 0;
/* Return info from the table */
-   return nand_isreserved_bbt(mtd, ofs);
+   return nand_bbt_isreserved(chip->nand_bbt, ofs);
 }
 
 /**
@@ -513,12 +513,18 @@ static int nand_block_checkbad(struct mtd_info *mtd, 
loff_t ofs, int getchip,
   int allowbbt)
 {
struct nand_chip *chip = mtd_to_nand(mtd);
+   struct nand_bbt *bbt = chip->nand_bbt;
 
-   if (!chip->bbt)
+   if (!bbt)
return chip->block_bad(mtd, ofs, getchip);
 
/* Return info from the table */
-   return nand_isbad_bbt(mtd, ofs, allowbbt);
+   if (nand_bbt_isbad(bbt, ofs))
+   return 1;
+   else if (allowbbt)
+   return 0;
+   else
+   return nand_bbt_isreserved(bbt, ofs);
 }
 
 /**
@@ -2982,6 +2988,122 @@ erase_exit:
return ret;
 }
 
+/* NAND BBT helper - erase a block, including reserved blocks */
+static int nand_bbt_erase_block(struct mtd_info *mtd, loff_t addr)
+{
+   struct erase_info einfo;
+   struct nand_chip *chip = mtd->priv;
+
+   memset(, 0, sizeof(einfo));
+   einfo.mtd = mtd;
+   einfo.addr = addr;
+   einfo.len = 1ULL << chip->phys_erase_shift;
+
+   return nand_erase_nand(mtd, , 1);
+}
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+#define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB)
+/**
+ * nand_create_factory_badblock_pattern - [INTERN] Creates a BBT descriptor
+ * structure for factory bad block marker
+ * @chip: NAND chip to create descriptor for
+ *
+ * This function allocates and initializes a badblock_pattern for factory bad
+ * block marker based on the properties of @chip when chip.badblock_pattern
+ * is NULL.
+ */
+static int nand_create_factory_badblock_pattern(struct nand_chip *chip)
+{
+   struct nand_bbt_descr *bd;
+
+   if (chip->badblock_pattern) {
+   pr_warn("Bad block pattern already allocated; not replacing\n");
+   return -EINVAL;
+   }
+   bd = kzalloc(sizeof(*bd), GFP_KERNEL);
+   if (!bd)
+   return -ENOMEM;
+   bd->options = chip->bbt_options & BADBLOCK_SCAN_MASK;
+   bd->offs = chip-&g

[PATCH v2 02/12] mtd: nand_bbt: introduce struct nand_bbt

2015-12-14 Thread Peter Pan
From: Brian Norris <computersforpe...@gmail.com>

Currently nand_bbt.c is tied with struct nand_chip, and it makes other
NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
onenand has own bbt(onenand_bbt.c).

Separate struct nand_chip from BBT code can make current BBT shareable.
We create struct nand_bbt to take place of nand_chip in nand_bbt.c

Below is mtd folder structure we want:
mtd
├── Kconfig
├── Makefile
├── ...
├── nand_bbt.c
├── nand
│   ├── Kconfig
│   ├── Makefile
│   ├── nand_base.c
│   ├── nand_ids.c
│   ├── ...
│   └── xway_nand.c
├── spi-nand
│   ├── Kconfig
│   ├── Makefile
│   ├── spi-nand-base.c
│   ├── ...
│   └── spi-nand-device.c
└── ...

We put every information nand_bbt.c needed from outside into struct
nand_bbt, include:
@mtd:   pointer to MTD device structure
@is_bad_bbm:check if a block is factory bad block
@mark_bad_bbm:  imitate a block as factory bad block
@erase: erase block bypassing resvered checks
@bbt_options:   bad block specific options. All options used
here must come from nand_bbt.h.
@numchips:  number of physical chips, required for NAND_BBT_PERCHIP
@bbt_td:bad block table descriptor for flash lookup.
@bbt_md:bad block table mirror descriptor
@chipsize:  the size of one chip for multichip arrays
@chip_shift:number of address bits in one chip
@bbt_erase_shift:   number of address bits in a bbt entry
@page_shift:number of address bits in a page
@bbt:   bad block table pointer

Signed-off-by: Brian Norris <computersforpe...@gmail.com>
[Peter: correct comment style]
Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 include/linux/mtd/nand_bbt.h | 59 
 1 file changed, 59 insertions(+)

diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index 5a65230..e468571 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -18,6 +18,8 @@
 #ifndef __LINUX_MTD_NAND_BBT_H
 #define __LINUX_MTD_NAND_BBT_H
 
+struct mtd_info;
+
 /* The maximum number of NAND chips in an array */
 #define NAND_MAX_CHIPS 8
 
@@ -115,4 +117,61 @@ struct nand_bbt_descr {
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS4
 
+/**
+ * struct nand_bbt - bad block table structure
+ * @mtd:   pointer to MTD device structure
+ * @is_bad_bbm:check if a block is factory bad block
+ * @mark_bad_bbm:  imitate a block as factory bad block
+ * @erase: erase block bypassing resvered checks
+ * @bbt_options:   bad block specific options. All options used
+ * here must come from nand_bbt.h.
+ * @numchips:  number of physical chips, required for NAND_BBT_PERCHIP
+ * @bbt_td:bad block table descriptor for flash lookup.
+ * @bbt_md:bad block table mirror descriptor
+ * @chipsize:  the size of one chip for multichip arrays
+ * @chip_shift:number of address bits in one chip
+ * @bbt_erase_shift:   number of address bits in a bbt entry
+ * @page_shift:number of address bits in a page
+ * @bbt:   bad block table pointer
+ *
+ */
+struct nand_bbt {
+   struct mtd_info *mtd;
+
+   /*
+* This is important to abstract out of nand_bbt.c and provide
+* separately in nand_base.c and spi-nand-base.c -- it's sort of
+* duplicated in nand_block_bad() (nand_base) and
+* scan_block_fast() (nand_bbt) right now
+*
+* Note that this also means nand_chip.badblock_pattern should
+* be removed from nand_bbt.c
+*/
+   int (*is_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
+
+   /*
+* Only required if the driver wants to attempt to program new
+* bad block markers that imitate the factory-marked BBMs
+*/
+   int (*mark_bad_bbm)(struct mtd_info *mtd, loff_t ofs);
+
+   /* Erase a block, bypassing reserved checks */
+   int (*erase)(struct mtd_info *mtd, loff_t ofs);
+
+   unsigned int bbt_options;
+   int numchips;
+
+   /*
+* Discourage new custom usages here; suggest usage of the
+* relevant NAND_BBT_* options instead
+*/
+   struct nand_bbt_descr *bbt_td;
+   struct nand_bbt_descr *bbt_md;
+   u64 chipsize;
+   int chip_shift;
+   int bbt_erase_shift;
+   int page_shift;
+   u8 *bbt;
+};
+
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 04/12] mtd: nand_bbt: add nand_bbt_markbad_factory() interface

2015-12-14 Thread Peter Pan
Some nand controller drivers(like docg4.c) mark factory bad block
mark by accessing bbt buffer directly, so create this API to avoid
breaking layer.

Signed-off-by: Peter Pan <peterpand...@micron.com>
---
 drivers/mtd/nand/nand_bbt.c  | 32 +---
 include/linux/mtd/nand_bbt.h |  1 +
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 72aed20..f256be1 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -1353,11 +1353,12 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, 
int allowbbt)
 }
 
 /**
- * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
+ * nand_bbt_update_mark - update mark in the BBT
  * @mtd: MTD device structure
  * @offs: offset of the bad block
+ * @mark: block type mark
  */
-int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
+static int nand_bbt_update_mark(struct mtd_info *mtd, loff_t offs, uint8_t 
mark)
 {
struct nand_chip *this = mtd_to_nand(mtd);
int block, ret = 0;
@@ -1365,7 +1366,7 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
block = (int)(offs >> this->bbt_erase_shift);
 
/* Mark bad block in memory */
-   bbt_mark_entry(this, block, BBT_BLOCK_WORN);
+   bbt_mark_entry(this, block, mark);
 
/* Update flash-based bad block table */
if (this->bbt_options & NAND_BBT_USE_FLASH)
@@ -1374,6 +1375,15 @@ int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
return ret;
 }
 
+/**
+ * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
+ * @mtd: MTD device structure
+ * @offs: offset of the bad block
+ */
+int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
+{
+   return nand_bbt_update_mark(mtd, offs, BBT_BLOCK_WORN);
+}
 EXPORT_SYMBOL(nand_scan_bbt);
 
 /**
@@ -1446,3 +1456,19 @@ int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs)
return nand_markbad_bbt(bbt->mtd, offs);
 }
 EXPORT_SYMBOL(nand_bbt_markbad);
+
+/**
+ * nand_bbt_markbad_factory - [NAND BBT Interface] Mark a block as factory bad
+ * in the BBT
+ * @bbt: NAND BBT structure
+ * @offs: offset of the bad block
+ */
+int nand_bbt_markbad_factory(struct nand_bbt *bbt, loff_t offs)
+{
+   /*
+* FIXME: For now, we call nand_markbad_bbt() directly. It will change
+* when we use struct nand_bbt instead of struct nand_chip.
+*/
+   return nand_bbt_update_mark(bbt->mtd, offs, BBT_BLOCK_FACTORY_BAD);
+}
+EXPORT_SYMBOL(nand_bbt_markbad_factory);
diff --git a/include/linux/mtd/nand_bbt.h b/include/linux/mtd/nand_bbt.h
index 150c49a..48a0620 100644
--- a/include/linux/mtd/nand_bbt.h
+++ b/include/linux/mtd/nand_bbt.h
@@ -179,5 +179,6 @@ void nand_bbt_release(struct nand_bbt *bbt);
 int nand_bbt_markbad(struct nand_bbt *bbt, loff_t offs);
 int nand_bbt_isreserved(struct nand_bbt *bbt, loff_t offs);
 int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs);
+int nand_bbt_markbad_factory(struct nand_bbt *bbt, loff_t offs);
 
 #endif /* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 00/12] mtd: nand_bbt: introduce independent nand BBT

2015-12-14 Thread Peter Pan
Currently nand_bbt.c is tied with struct nand_chip, and it makes other
NAND family chips hard to use nand_bbt.c. Maybe it's the reason why
onenand has own bbt(onenand_bbt.c).

Separate struct nand_chip from BBT code can make current BBT shareable.
We create struct nand_bbt to take place of nand_chip in nand_bbt.c.
Struct nand_bbt contains all the information BBT needed from outside and
it should be embedded into NAND family chip struct (such as struct nand_chip).
NAND family driver should allocate, initialize and free struct nand_bbt.

Below is mtd folder structure we want:
mtd
├── Kconfig
├── Makefile
├── ...
├── nand_bbt.c
├── nand
│   ├── Kconfig
│   ├── Makefile
│   ├── nand_base.c
│   ├── nand_ids.c
│   ├── ...
│   └── xway_nand.c
├── spi-nand
│   ├── Kconfig
│   ├── Makefile
│   ├── spi-nand-base.c
│   ├── ...
│   └── spi-nand-device.c
└── ...

Most of the patch is borrowed from Brian Norris <computersforpe...@gmail.com>.
http://git.infradead.org/users/norris/linux-mtd.git/shortlog/refs/heads/nand-bbt
Based on Brian's suggestion, I make my previous BBT patch into 12 independent
patches. Previous patch is http://patchwork.ozlabs.org/patch/492066/
Beside the patch split, I also moved nand_bbt.c to mtd folder, which didn't in
previous patch.

Patch 3, 7, 8, 9, 10 and 11 are totally borrowed from Brian's git tree. I just
test and split the code into independent patch. Patch 1, 2, 5 and 6 are partial
borrowed. I make some changes from Brian's git tree and the changes are recorded
in commit log. Patch 4 and 12 are written by me.

The patch is tested on Zed board.

v2 changes:
rebase patch series on master branch of l2-mtd.git

Brian Norris (10):
  mtd: nand_bbt: new header for nand family BBT
  mtd: nand_bbt: introduce struct nand_bbt
  mtd: nand_bbt: add new API definitions
  mtd: nand: use new BBT API instead of old ones
  mtd: nand_bbt: use erase() and is_bad_bbm() hook in BBT
  mtd: nand: make nand_erase_nand() static
  mtd: nand_bbt: remove struct nand_chip from nand_bbt.c
  mtd: nand_bbt: remove old API definitions
  mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro
  mtd: nand: remove nand_chip.bbt

Peter Pan (2):
  mtd: nand_bbt: add nand_bbt_markbad_factory() interface
  mtd: nand-bbt: move nand_bbt.c to mtd folder

 drivers/mtd/Kconfig   |   7 +
 drivers/mtd/Makefile  |   1 +
 drivers/mtd/nand/Kconfig  |   2 +-
 drivers/mtd/nand/Makefile |   2 +-
 drivers/mtd/nand/docg4.c  |   6 +-
 drivers/mtd/nand/nand_base.c  | 145 +-
 drivers/mtd/{nand => }/nand_bbt.c | 542 --
 include/linux/mtd/bbm.h   |  96 +--
 include/linux/mtd/nand.h  |  16 +-
 include/linux/mtd/nand_bbt.h  | 177 +
 10 files changed, 562 insertions(+), 432 deletions(-)
 rename drivers/mtd/{nand => }/nand_bbt.c (68%)
 create mode 100644 include/linux/mtd/nand_bbt.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/