linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT
@ 2016-03-14  2:47 Peter Pan
  2016-03-14  2:47 ` [PATCH 01/11] mtd: nand_bbt: new header for nand family BBT Peter Pan
                   ` (13 more replies)
  0 siblings, 14 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:47 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, 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/<all-nand-core-code>
	drivers/mtd/nand/raw/<raw-nand-controller-drivers>
	drivers/mtd/nand/spi/<spi-nand-code>
	drivers/mtd/nand/onenand/<onenand-code>
	drivers/mtd/nand/chips/<manufacturer-spcific-code>

Most of the patch is borrowed from Brian Norris <computersforpeace@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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 01/11] mtd: nand_bbt: new header for nand family BBT
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
@ 2016-03-14  2:47 ` Peter Pan
  2016-03-14  2:47 ` [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure Peter Pan
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:47 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, Peter Pan

From: Brian Norris <computersforpeace@gmail.com>

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

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
[Peter: correct misspelling. s/neccecary/necessary/]
Signed-off-by: Peter Pan <peterpandong@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 <linux/mtd/nand_bbt.h>
 
-/**
- * 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_MSK	0x0000000F
-#define NAND_BBT_1BIT		0x00000001
-#define NAND_BBT_2BIT		0x00000002
-#define NAND_BBT_4BIT		0x00000004
-#define NAND_BBT_8BIT		0x00000008
-/* The bad block table is in the last good block of the device */
-#define NAND_BBT_LASTBLOCK	0x00000010
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_ABSPAGE	0x00000020
-/* bbt is stored per chip on multichip devices */
-#define NAND_BBT_PERCHIP	0x00000080
-/* bbt has a version counter at offset veroffs */
-#define NAND_BBT_VERSION	0x00000100
-/* Create a bbt if none exists */
-#define NAND_BBT_CREATE		0x00000200
-/*
- * 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	0x00000400
-/* Write bbt if neccecary */
-#define NAND_BBT_WRITE		0x00002000
-/* Read and write back block contents when writing bbt */
-#define NAND_BBT_SAVECONTENT	0x00004000
-/* Search good / bad pattern on the first and the second page */
-#define NAND_BBT_SCAN2NDPAGE	0x00008000
-/* Search good / bad pattern on the last page of the eraseblock */
-#define NAND_BBT_SCANLASTPAGE	0x00010000
-/*
- * 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	0x00020000
-/*
- * Do not store flash based bad block table marker in the OOB area; store it
- * in-band.
- */
-#define NAND_BBT_NO_OOB		0x00040000
-/*
- * 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_BBM	0x00080000
-
-/*
- * 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	0x80000000
-
-/* The maximum number of blocks to scan for a bbt */
-#define NAND_BBT_SCAN_MAXBLOCKS	4
 
 /*
  * 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 0000000..5a65230
--- /dev/null
+++ b/include/linux/mtd/nand_bbt.h
@@ -0,0 +1,118 @@
+/*
+ *  NAND family Bad Block Table support
+ *
+ *  Copyright © 2015 Broadcom Corporation
+ *  Brian Norris <computersforpeace@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __LINUX_MTD_NAND_BBT_H
+#define __LINUX_MTD_NAND_BBT_H
+
+/* The maximum number of NAND chips in an array */
+#define NAND_MAX_CHIPS		8
+
+/**
+ * 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_MSK	0x0000000F
+#define NAND_BBT_1BIT		0x00000001
+#define NAND_BBT_2BIT		0x00000002
+#define NAND_BBT_4BIT		0x00000004
+#define NAND_BBT_8BIT		0x00000008
+/* The bad block table is in the last good block of the device */
+#define NAND_BBT_LASTBLOCK	0x00000010
+/* The bbt is at the given page, else we must scan for the bbt */
+#define NAND_BBT_ABSPAGE	0x00000020
+/* bbt is stored per chip on multichip devices */
+#define NAND_BBT_PERCHIP	0x00000080
+/* bbt has a version counter at offset veroffs */
+#define NAND_BBT_VERSION	0x00000100
+/* Create a bbt if none exists */
+#define NAND_BBT_CREATE		0x00000200
+/*
+ * 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	0x00000400
+/* Write bbt if necessary */
+#define NAND_BBT_WRITE		0x00002000
+/* Read and write back block contents when writing bbt */
+#define NAND_BBT_SAVECONTENT	0x00004000
+/* Search good / bad pattern on the first and the second page */
+#define NAND_BBT_SCAN2NDPAGE	0x00008000
+/* Search good / bad pattern on the last page of the eraseblock */
+#define NAND_BBT_SCANLASTPAGE	0x00010000
+/*
+ * 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	0x00020000
+/*
+ * Do not store flash based bad block table marker in the OOB area; store it
+ * in-band.
+ */
+#define NAND_BBT_NO_OOB		0x00040000
+/*
+ * 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_BBM	0x00080000
+
+/*
+ * 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	0x80000000
+
+/* The maximum number of blocks to scan for a bbt */
+#define NAND_BBT_SCAN_MAXBLOCKS	4
+
+#endif	/* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
  2016-03-14  2:47 ` [PATCH 01/11] mtd: nand_bbt: new header for nand family BBT Peter Pan
@ 2016-03-14  2:47 ` Peter Pan
  2016-03-25  8:35   ` Boris Brezillon
  2016-03-14  2:47 ` [PATCH 03/11] mtd: nand_bbt: add new API definitions Peter Pan
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:47 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, Peter Pan

From: Brian Norris <computersforpeace@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/<all-nand-core-code>
	drivers/mtd/nand/raw/<raw-nand-controller-drivers>
	drivers/mtd/nand/spi/<spi-nand-code>
	drivers/mtd/nand/onenand/<onenand-code>
	drivers/mtd/nand/chips/<manufacturer-spcific-code>

Of course, nand_bbt.c should be part of <all-nand-core-code>.

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 <computersforpeace@gmail.com>
[Peter: 1. correct comment style
	2. introduce struct nand_bbt_ops and nand_chip_layout_info]
Signed-off-by: Peter Pan <peterpandong@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 {
+	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

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 03/11] mtd: nand_bbt: add new API definitions
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
  2016-03-14  2:47 ` [PATCH 01/11] mtd: nand_bbt: new header for nand family BBT Peter Pan
  2016-03-14  2:47 ` [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure Peter Pan
@ 2016-03-14  2:47 ` Peter Pan
  2016-03-14  3:47   ` kbuild test robot
  2016-03-25  8:49   ` Boris Brezillon
  2016-03-14  2:47 ` [PATCH 04/11] mtd: nand_bbt: add nand_bbt_markbad_factory() interface Peter Pan
                   ` (10 subsequent siblings)
  13 siblings, 2 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:47 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, 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 <computersforpeace@gmail.com>
Signed-off-by: Peter Pan <peterpandong@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,
+		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);
+
 #endif	/* __LINUX_MTD_NAND_BBT_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 04/11] mtd: nand_bbt: add nand_bbt_markbad_factory() interface
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (2 preceding siblings ...)
  2016-03-14  2:47 ` [PATCH 03/11] mtd: nand_bbt: add new API definitions Peter Pan
@ 2016-03-14  2:47 ` Peter Pan
  2016-03-14  2:47 ` [PATCH 05/11] mtd: nand: use new BBT API instead of old ones Peter Pan
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:47 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, 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 <peterpandong@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

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 05/11] mtd: nand: use new BBT API instead of old ones
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (3 preceding siblings ...)
  2016-03-14  2:47 ` [PATCH 04/11] mtd: nand_bbt: add nand_bbt_markbad_factory() interface Peter Pan
@ 2016-03-14  2:47 ` Peter Pan
  2016-03-25  8:51   ` Boris Brezillon
  2016-03-14  2:47 ` [PATCH 06/11] mtd: nand_bbt: use struct nand_bbt_ops in BBT Peter Pan
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:47 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, Peter Pan

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

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Peter Pan <peterpandong@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, &bits, 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(&einfo, 0, sizeof(einfo));
+	einfo.mtd = mtd;
+	einfo.addr = addr;
+	einfo.len = 1ULL << chip->phys_erase_shift;
+
+	return nand_erase_nand(mtd, &einfo, 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->pattern = scan_ff_pattern;
+	bd->options |= NAND_BADBLOCK_PATTERN_ALLOC;
+	chip->badblock_pattern = bd;
+
+	return 0;
+}
+
+static int nand_is_bad_bbm(struct mtd_info *mtd, loff_t addr)
+{
+	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct mtd_oob_ops ops;
+	struct nand_bbt_descr *bd = chip->badblock_pattern;
+	int j, ret;
+	int numpages;
+
+	if (bd->options & NAND_BBT_SCAN2NDPAGE)
+		numpages = 2;
+	else
+		numpages = 1;
+
+	if (bd->options & NAND_BBT_SCANLASTPAGE)
+		addr += mtd->erasesize - (mtd->writesize * numpages);
+
+	ops.ooblen = mtd->oobsize;
+	ops.oobbuf = chip->buffers->databuf;
+	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 = nand_do_read_oob(mtd, addr, &ops);
+		/* Ignore ECC errors when checking for BBM */
+		if (ret && !mtd_is_bitflip_or_eccerr(ret))
+			return ret;
+
+		if (memcmp(chip->buffers->databuf + bd->offs,
+				bd->pattern, bd->len))
+			return 1;
+
+		addr += mtd->writesize;
+	}
+
+	return 0;
+}
+
+static const struct nand_bbt_ops default_bbt_ops = {
+	.erase = nand_bbt_erase_block,
+	.is_bad_bbm = nand_is_bad_bbm,
+};
+
+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);
+
+	if (!info)
+		return -ENOMEM;
+
+	info->numchips = chip->numchips;
+	info->chipsize = chip->chipsize;
+	info->chip_shift = chip->chip_shift;
+	info->bbt_erase_shift = chip->phys_erase_shift;
+	info->page_shift = chip->page_shift;
+
+	if (!chip->badblock_pattern &&
+		nand_create_factory_badblock_pattern(chip))
+		return -ENOMEM;
+
+	nand_bbt = nand_bbt_create(mtd, &default_bbt_ops,
+				info, chip->bbt_options,
+				chip->bbt_td, chip->bbt_md);
+	if (IS_ERR(nand_bbt))
+		return PTR_ERR(nand_bbt);
+	chip->nand_bbt = nand_bbt;
+
+	return 0;
+}
+
 /**
  * nand_sync - [MTD Interface] sync
  * @mtd: MTD device structure
@@ -4456,20 +4587,22 @@ EXPORT_SYMBOL(nand_scan);
 void nand_release(struct mtd_info *mtd)
 {
 	struct nand_chip *chip = mtd_to_nand(mtd);
+	struct nand_bbt *nand_bbt = nand_get_bbt(chip);
 
 	if (chip->ecc.mode == NAND_ECC_SOFT_BCH)
 		nand_bch_free((struct nand_bch_control *)chip->ecc.priv);
 
 	mtd_device_unregister(mtd);
 
-	/* Free bad block table memory */
-	kfree(chip->bbt);
+	/* Destroy bad block table */
+	if (nand_bbt)
+		nand_bbt_destroy(nand_bbt);
 	if (!(chip->options & NAND_OWN_BUFFERS))
 		kfree(chip->buffers);
 
 	/* Free bad block descriptor memory */
 	if (chip->badblock_pattern && chip->badblock_pattern->options
-			& NAND_BBT_DYNAMICSTRUCT)
+			& NAND_BADBLOCK_PATTERN_ALLOC)
 		kfree(chip->badblock_pattern);
 }
 EXPORT_SYMBOL_GPL(nand_release);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 56574ba..5072041 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -204,6 +204,12 @@ typedef enum {
  */
 #define NAND_USE_BOUNCE_BUFFER	0x00100000
 
+/*
+ * Flag to mark that the badblock_pattern is allocated dynamicaly and must
+ * be freed in nand_release().
+ */
+#define NAND_BADBLOCK_PATTERN_ALLOC	0x08000000
+
 /* Options set by nand scan */
 /* Nand scan has allocated controller struct */
 #define NAND_CONTROLLER_ALLOC	0x80000000
@@ -646,6 +652,8 @@ struct nand_buffers {
  * @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
  *			lookup.
  * @bbt_md:		[REPLACEABLE] bad block table mirror descriptor
@@ -732,6 +740,7 @@ struct nand_chip {
 	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;
 
@@ -884,7 +893,6 @@ struct nand_manufacturers {
 extern struct nand_flash_dev nand_flash_ids[];
 extern struct nand_manufacturers nand_manuf_ids[];
 
-extern int nand_default_bbt(struct mtd_info *mtd);
 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);
@@ -1014,6 +1022,11 @@ static inline int jedec_feature(struct nand_chip *chip)
 		: 0;
 }
 
+static inline struct nand_bbt *nand_get_bbt(struct nand_chip *chip)
+{
+	return chip->nand_bbt;
+}
+
 /*
  * struct nand_sdr_timings - SDR NAND chip timings
  *
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 06/11] mtd: nand_bbt: use struct nand_bbt_ops in BBT
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (4 preceding siblings ...)
  2016-03-14  2:47 ` [PATCH 05/11] mtd: nand: use new BBT API instead of old ones Peter Pan
@ 2016-03-14  2:47 ` Peter Pan
  2016-03-14  2:48 ` [PATCH 07/11] mtd: nand: make nand_erase_nand() static Peter Pan
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:47 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, Peter Pan

From: Brian Norris <computersforpeace@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 <computersforpeace@gmail.com>
[Peter: remove @buf in create_bbt()
	introduce struct nand_bbt_ops]
Signed-off-by: Peter Pan <peterpandong@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, &ops);
-		/* 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_bbt(struct mtd_info *mtd, uint8_t *buf,
 			buf[offs + (i >> sft)] &= ~(msk[dat] << sftcnt);
 		}
 
-		memset(&einfo, 0, sizeof(einfo));
-		einfo.mtd = mtd;
-		einfo.addr = to;
-		einfo.len = 1 << this->bbt_erase_shift;
-		res = nand_erase_nand(mtd, &einfo, 1);
+		res = nand_bbt->bbt_ops->erase(mtd, to);
 		if (res < 0)
 			goto outerr;
 
@@ -812,30 +747,26 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 /**
  * nand_memory_bbt - [GENERIC] create a memory based bad block table
  * @mtd: MTD device structure
- * @bd: descriptor for the good/bad block search pattern
  *
  * The function creates a memory based bbt by scanning the device for
  * manufacturer / software marked good / bad blocks.
  */
-static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static inline int nand_memory_bbt(struct mtd_info *mtd)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
-
-	return create_bbt(mtd, this->buffers->databuf, bd, -1);
+	return create_bbt(mtd, -1);
 }
 
 /**
  * check_create - [GENERIC] create and write bbt(s) if necessary
  * @mtd: MTD device structure
  * @buf: temporary buffer
- * @bd: descriptor for the good/bad block search pattern
  *
  * The function checks the results of the previous call to read_bbt and creates
  * / updates the bbt(s) if necessary. Creation is necessary if no bbt was found
  * for the chip/device. Update is necessary if one of the tables is missing or
  * the version nr. of one table is less than the other.
  */
-static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
+static int check_create(struct mtd_info *mtd, uint8_t *buf)
 {
 	int i, chips, writeops, create, chipsel, res, res2;
 	struct nand_chip *this = mtd_to_nand(mtd);
@@ -895,7 +826,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 
 			/* Create the table in memory by scanning the chip(s) */
 			if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY))
-				create_bbt(mtd, buf, bd, chipsel);
+				create_bbt(mtd, chipsel);
 
 			td->version[i] = 1;
 			if (md)
@@ -1063,7 +994,6 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 /**
  * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
  * @mtd: MTD device structure
- * @bd: descriptor for the good/bad block search pattern
  *
  * The function checks, if a bad block table(s) is/are already available. If
  * not it scans the device for manufacturer marked good / bad blocks and writes
@@ -1072,7 +1002,7 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
  * The bad block table memory is allocated here. It must be freed by calling
  * the nand_free_bbt function.
  */
-static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static int nand_scan_bbt(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd_to_nand(mtd);
 	int len, res;
@@ -1094,7 +1024,7 @@ static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 	 * memory based bad block table.
 	 */
 	if (!td) {
-		if ((res = nand_memory_bbt(mtd, bd))) {
+		if ((res = nand_memory_bbt(mtd))) {
 			pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n");
 			goto err;
 		}
@@ -1120,7 +1050,7 @@ static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 		search_read_bbts(mtd, buf, td, md);
 	}
 
-	res = check_create(mtd, buf, bd);
+	res = check_create(mtd, buf);
 	if (res)
 		goto err;
 
@@ -1193,12 +1123,6 @@ static int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
 	return res;
 }
 
-/*
- * Define some generic bad / good block scan pattern which are used
- * while scanning a device for factory marked good / bad blocks.
- */
-static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
-
 /* Generic flash bbt descriptors */
 static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
 static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
@@ -1243,35 +1167,6 @@ static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
 	.pattern = mirror_pattern
 };
 
-#define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB)
-/**
- * nand_create_badblock_pattern - [INTERN] Creates a BBT descriptor structure
- * @this: NAND chip to create descriptor for
- *
- * This function allocates and initializes a nand_bbt_descr for BBM detection
- * based on the properties of @this. The new descriptor is stored in
- * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
- * passed to this function.
- */
-static int nand_create_badblock_pattern(struct nand_chip *this)
-{
-	struct nand_bbt_descr *bd;
-	if (this->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 = this->bbt_options & BADBLOCK_SCAN_MASK;
-	bd->offs = this->badblockpos;
-	bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1;
-	bd->pattern = scan_ff_pattern;
-	bd->options |= NAND_BBT_DYNAMICSTRUCT;
-	this->badblock_pattern = bd;
-	return 0;
-}
-
 /**
  * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
  * @mtd: MTD device structure
@@ -1282,7 +1177,6 @@ static int nand_create_badblock_pattern(struct nand_chip *this)
 int nand_default_bbt(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd_to_nand(mtd);
-	int ret;
 
 	/* Is a flash based bad block table requested? */
 	if (this->bbt_options & NAND_BBT_USE_FLASH) {
@@ -1301,13 +1195,7 @@ int nand_default_bbt(struct mtd_info *mtd)
 		this->bbt_md = NULL;
 	}
 
-	if (!this->badblock_pattern) {
-		ret = nand_create_badblock_pattern(this);
-		if (ret)
-			return ret;
-	}
-
-	return nand_scan_bbt(mtd, this->badblock_pattern);
+	return nand_scan_bbt(mtd);
 }
 
 /**
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 07/11] mtd: nand: make nand_erase_nand() static
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (5 preceding siblings ...)
  2016-03-14  2:47 ` [PATCH 06/11] mtd: nand_bbt: use struct nand_bbt_ops in BBT Peter Pan
@ 2016-03-14  2:48 ` Peter Pan
  2016-03-14  2:48 ` [PATCH 08/11] mtd: nand_bbt: remove struct nand_chip from nand_bbt.c Peter Pan
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:48 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, Peter Pan

From: Brian Norris <computersforpeace@gmail.com>

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

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Peter Pan <peterpandong@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

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 08/11] mtd: nand_bbt: remove struct nand_chip from nand_bbt.c
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (6 preceding siblings ...)
  2016-03-14  2:48 ` [PATCH 07/11] mtd: nand: make nand_erase_nand() static Peter Pan
@ 2016-03-14  2:48 ` Peter Pan
  2016-03-14  2:48 ` [PATCH 09/11] mtd: nand_bbt: remove old API definitions Peter Pan
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:48 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, Peter Pan

From: Brian Norris <computersforpeace@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 <computersforpeace@gmail.com>
[Peter Pan: replacement with struct nand_chip_layout_info]
Signed-off-by: Peter Pan <peterpandong@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 <linux/slab.h>
 #include <linux/types.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/bbm.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_bbt.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
@@ -76,20 +75,20 @@
 #define BBT_ENTRY_MASK		0x03
 #define BBT_ENTRY_SHIFT		2
 
-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,
+					bbt_mark_entry(bbt, offs + act,
 							BBT_BLOCK_FACTORY_BAD);
 				else
-					bbt_mark_entry(this, offs + act,
+					bbt_mark_entry(bbt, offs + act,
 							BBT_BLOCK_WORN);
 				mtd->ecc_stats.badblocks++;
 			}
@@ -235,7 +235,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
 
 /**
  * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @td: descriptor for the bad block table
  * @chip: read the table for a specific chip, -1 read all chips; applies only if
@@ -244,25 +244,27 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
  * Read the bad block table for all chips starting at a given page. We assume
  * that the bbt bits are in consecutive order.
  */
-static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
+static int read_abs_bbt(struct nand_bbt *bbt, uint8_t *buf,
+			struct nand_bbt_descr *td, int chip)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mtd_info *mtd = bbt->mtd;
+	struct nand_chip_layout_info *info = bbt->info;
 	int res = 0, i;
 
 	if (td->options & NAND_BBT_PERCHIP) {
 		int offs = 0;
-		for (i = 0; i < this->numchips; i++) {
+		for (i = 0; i < info->numchips; i++) {
 			if (chip == -1 || chip == i)
-				res = read_bbt(mtd, buf, td->pages[i],
-					this->chipsize >> this->bbt_erase_shift,
+				res = read_bbt(bbt, buf, td->pages[i],
+					info->chipsize >> info->bbt_erase_shift,
 					td, offs);
 			if (res)
 				return res;
-			offs += this->chipsize >> this->bbt_erase_shift;
+			offs += info->chipsize >> info->bbt_erase_shift;
 		}
 	} else {
-		res = read_bbt(mtd, buf, td->pages[0],
-				mtd->size >> this->bbt_erase_shift, td, 0);
+		res = read_bbt(bbt, buf, td->pages[0],
+				mtd->size >> info->bbt_erase_shift, td, 0);
 		if (res)
 			return res;
 	}
@@ -270,7 +272,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
 }
 
 /* BBT marker is in the first page, no OOB */
-static int scan_read_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read_data(struct nand_bbt *bbt, uint8_t *buf, loff_t offs,
 			 struct nand_bbt_descr *td)
 {
 	size_t retlen;
@@ -280,12 +282,12 @@ static int scan_read_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
 	if (td->options & NAND_BBT_VERSION)
 		len++;
 
-	return mtd_read(mtd, offs, len, &retlen, buf);
+	return mtd_read(bbt->mtd, offs, len, &retlen, buf);
 }
 
 /**
  * scan_read_oob - [GENERIC] Scan data+OOB region to buffer
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @offs: offset at which to scan
  * @len: length of data region to read
@@ -294,9 +296,10 @@ static int scan_read_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
  * page,OOB,page,OOB,... in buf. Completes transfer and returns the "strongest"
  * ECC condition (error or bitflip). May quit on the first (non-ECC) error.
  */
-static int scan_read_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read_oob(struct nand_bbt *bbt, uint8_t *buf, loff_t offs,
 			 size_t len)
 {
+	struct mtd_info *mtd = bbt->mtd;
 	struct mtd_oob_ops ops;
 	int res, ret = 0;
 
@@ -324,19 +327,20 @@ static int scan_read_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
 	return ret;
 }
 
-static int scan_read(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read(struct nand_bbt *bbt, uint8_t *buf, loff_t offs,
 			 size_t len, struct nand_bbt_descr *td)
 {
 	if (td->options & NAND_BBT_NO_OOB)
-		return scan_read_data(mtd, buf, offs, td);
+		return scan_read_data(bbt, buf, offs, td);
 	else
-		return scan_read_oob(mtd, buf, offs, len);
+		return scan_read_oob(bbt, buf, offs, len);
 }
 
 /* Scan write data with oob to flash */
-static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
+static int scan_write_bbt(struct nand_bbt *bbt, loff_t offs, size_t len,
 			  uint8_t *buf, uint8_t *oob)
 {
+	struct mtd_info *mtd = bbt->mtd;
 	struct mtd_oob_ops ops;
 
 	ops.mode = MTD_OPS_PLACE_OOB;
@@ -349,18 +353,18 @@ static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
 	return mtd_write_oob(mtd, offs, &ops);
 }
 
-static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
+static u32 bbt_get_ver_offs(struct nand_bbt *bbt, struct nand_bbt_descr *td)
 {
 	u32 ver_offs = td->veroffs;
 
 	if (!(td->options & NAND_BBT_NO_OOB))
-		ver_offs += mtd->writesize;
+		ver_offs += bbt->mtd->writesize;
 	return ver_offs;
 }
 
 /**
  * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @td: descriptor for the bad block table
  * @md:	descriptor for the bad block table mirror
@@ -368,25 +372,26 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
  * Read the bad block table(s) for all chips starting at a given page. We
  * assume that the bbt bits are in consecutive order.
  */
-static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
+static void read_abs_bbts(struct nand_bbt *bbt, uint8_t *buf,
 			  struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mtd_info *mtd = bbt->mtd;
+	struct nand_chip_layout_info *info = bbt->info;
 
 	/* Read the primary version, if available */
 	if (td->options & NAND_BBT_VERSION) {
-		scan_read(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
+		scan_read(bbt, buf, (loff_t)td->pages[0] << info->page_shift,
 			      mtd->writesize, td);
-		td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
+		td->version[0] = buf[bbt_get_ver_offs(bbt, td)];
 		pr_info("Bad block table at page %d, version 0x%02X\n",
 			 td->pages[0], td->version[0]);
 	}
 
 	/* Read the mirror version, if available */
 	if (md && (md->options & NAND_BBT_VERSION)) {
-		scan_read(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
+		scan_read(bbt, buf, (loff_t)md->pages[0] << info->page_shift,
 			      mtd->writesize, md);
-		md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
+		md->version[0] = buf[bbt_get_ver_offs(bbt, md)];
 		pr_info("Bad block table at page %d, version 0x%02X\n",
 			 md->pages[0], md->version[0]);
 	}
@@ -394,60 +399,60 @@ static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
 
 /**
  * create_bbt - [GENERIC] Create a bad block table by scanning the device
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @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, int chip)
+static int create_bbt(struct nand_bbt *bbt, int chip)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mtd_info *mtd = bbt->mtd;
+	struct nand_chip_layout_info *info = bbt->info;
 	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 (chip == -1) {
-		numblocks = mtd->size >> this->bbt_erase_shift;
+		numblocks = mtd->size >> info->bbt_erase_shift;
 		startblock = 0;
 		from = 0;
 	} else {
-		if (chip >= this->numchips) {
+		if (chip >= info->numchips) {
 			pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n",
-			       chip + 1, this->numchips);
+			       chip + 1, info->numchips);
 			return -EINVAL;
 		}
-		numblocks = this->chipsize >> this->bbt_erase_shift;
+		numblocks = info->chipsize >> info->bbt_erase_shift;
 		startblock = chip * numblocks;
 		numblocks += startblock;
-		from = (loff_t)startblock << this->bbt_erase_shift;
+		from = (loff_t)startblock << info->bbt_erase_shift;
 	}
 
 	for (i = startblock; i < numblocks; i++) {
 		int ret;
 
-		ret = nand_bbt->bbt_ops->is_bad_bbm(mtd, from);
+		ret = bbt->bbt_ops->is_bad_bbm(mtd, from);
 		if (ret < 0)
 			return ret;
 
 		if (ret) {
-			bbt_mark_entry(this, i, BBT_BLOCK_FACTORY_BAD);
+			bbt_mark_entry(bbt, i, BBT_BLOCK_FACTORY_BAD);
 			pr_warn("Bad eraseblock %d at 0x%012llx\n",
 				i, (unsigned long long)from);
 			mtd->ecc_stats.badblocks++;
 		}
 
-		from += (1 << this->bbt_erase_shift);
+		from += (1 << info->bbt_erase_shift);
 	}
 	return 0;
 }
 
 /**
  * search_bbt - [GENERIC] scan the device for a specific bad block table
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @td: descriptor for the bad block table
  *
@@ -460,18 +465,20 @@ static int create_bbt(struct mtd_info *mtd, int chip)
  *
  * The bbt ident pattern resides in the oob area of the first page in a block.
  */
-static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
+static int search_bbt(struct nand_bbt *bbt, uint8_t *buf,
+			struct nand_bbt_descr *td)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mtd_info *mtd = bbt->mtd;
+	struct nand_chip_layout_info *info = bbt->info;
 	int i, chips;
 	int startblock, block, dir;
 	int scanlen = mtd->writesize + mtd->oobsize;
 	int bbtblocks;
-	int blocktopage = this->bbt_erase_shift - this->page_shift;
+	int blocktopage = info->bbt_erase_shift - info->page_shift;
 
 	/* Search direction top -> down? */
 	if (td->options & NAND_BBT_LASTBLOCK) {
-		startblock = (mtd->size >> this->bbt_erase_shift) - 1;
+		startblock = (mtd->size >> info->bbt_erase_shift) - 1;
 		dir = -1;
 	} else {
 		startblock = 0;
@@ -480,12 +487,12 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
-		chips = this->numchips;
-		bbtblocks = this->chipsize >> this->bbt_erase_shift;
+		chips = info->numchips;
+		bbtblocks = info->chipsize >> info->bbt_erase_shift;
 		startblock &= bbtblocks - 1;
 	} else {
 		chips = 1;
-		bbtblocks = mtd->size >> this->bbt_erase_shift;
+		bbtblocks = mtd->size >> info->bbt_erase_shift;
 	}
 
 	for (i = 0; i < chips; i++) {
@@ -496,20 +503,20 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
 		for (block = 0; block < td->maxblocks; block++) {
 
 			int actblock = startblock + dir * block;
-			loff_t offs = (loff_t)actblock << this->bbt_erase_shift;
+			loff_t offs = (loff_t)actblock << info->bbt_erase_shift;
 
 			/* Read first page */
-			scan_read(mtd, buf, offs, mtd->writesize, td);
+			scan_read(bbt, buf, offs, mtd->writesize, td);
 			if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
 				td->pages[i] = actblock << blocktopage;
 				if (td->options & NAND_BBT_VERSION) {
-					offs = bbt_get_ver_offs(mtd, td);
+					offs = bbt_get_ver_offs(bbt, td);
 					td->version[i] = buf[offs];
 				}
 				break;
 			}
 		}
-		startblock += this->chipsize >> this->bbt_erase_shift;
+		startblock += info->chipsize >> info->bbt_erase_shift;
 	}
 	/* Check, if we found a bbt for each requested chip */
 	for (i = 0; i < chips; i++) {
@@ -524,28 +531,28 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
 
 /**
  * search_read_bbts - [GENERIC] scan the device for bad block table(s)
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @td: descriptor for the bad block table
  * @md: descriptor for the bad block table mirror
  *
  * Search and read the bad block table(s).
  */
-static void search_read_bbts(struct mtd_info *mtd, uint8_t *buf,
+static void search_read_bbts(struct nand_bbt *bbt, uint8_t *buf,
 			     struct nand_bbt_descr *td,
 			     struct nand_bbt_descr *md)
 {
 	/* Search the primary table */
-	search_bbt(mtd, buf, td);
+	search_bbt(bbt, buf, td);
 
 	/* Search the mirror table */
 	if (md)
-		search_bbt(mtd, buf, md);
+		search_bbt(bbt, buf, md);
 }
 
 /**
  * write_bbt - [GENERIC] (Re)write the bad block table
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  * @td: descriptor for the bad block table
  * @md: descriptor for the bad block table mirror
@@ -553,11 +560,12 @@ static void search_read_bbts(struct mtd_info *mtd, uint8_t *buf,
  *
  * (Re)write the bad block table.
  */
-static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
+static int write_bbt(struct nand_bbt *bbt, uint8_t *buf,
 		     struct nand_bbt_descr *td, struct nand_bbt_descr *md,
 		     int chipsel)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mtd_info *mtd = bbt->mtd;
+	struct nand_chip_layout_info *info = bbt->info;
 	int i, res, chip = 0;
 	int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
 	int nrchips, pageoffs, ooboffs;
@@ -566,7 +574,6 @@ 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;
@@ -577,16 +584,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 = (int)(info->chipsize >> info->bbt_erase_shift);
 		/* Full device write or specific chip? */
 		if (chipsel == -1) {
-			nrchips = this->numchips;
+			nrchips = info->numchips;
 		} else {
 			nrchips = chipsel + 1;
 			chip = chipsel;
 		}
 	} else {
-		numblocks = (int)(mtd->size >> this->bbt_erase_shift);
+		numblocks = (int)(mtd->size >> info->bbt_erase_shift);
 		nrchips = 1;
 	}
 
@@ -617,13 +624,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 		for (i = 0; i < td->maxblocks; i++) {
 			int block = startblock + dir * i;
 			/* Check, if the block is bad */
-			switch (bbt_get_entry(this, block)) {
+			switch (bbt_get_entry(bbt, block)) {
 			case BBT_BLOCK_WORN:
 			case BBT_BLOCK_FACTORY_BAD:
 				continue;
 			}
 			page = block <<
-				(this->bbt_erase_shift - this->page_shift);
+				(info->bbt_erase_shift - info->page_shift);
 			/* Check, if the block is used by the mirror table */
 			if (!md || md->pages[chip] != page)
 				goto write;
@@ -651,13 +658,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 		default: return -EINVAL;
 		}
 
-		to = ((loff_t)page) << this->page_shift;
+		to = ((loff_t)page) << info->page_shift;
 
 		/* Must we save the block contents? */
 		if (td->options & NAND_BBT_SAVECONTENT) {
 			/* Make it block aligned */
-			to &= ~(((loff_t)1 << this->bbt_erase_shift) - 1);
-			len = 1 << this->bbt_erase_shift;
+			to &= ~(((loff_t)1 << info->bbt_erase_shift) - 1);
+			len = 1 << info->bbt_erase_shift;
 			res = mtd_read(mtd, to, len, &retlen, buf);
 			if (res < 0) {
 				if (retlen != len) {
@@ -667,15 +674,15 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 				pr_warn("nand_bbt: ECC error while reading block for writing bad block table\n");
 			}
 			/* Read oob data */
-			ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
+			ops.ooblen = (len >> info->page_shift) * mtd->oobsize;
 			ops.oobbuf = &buf[len];
 			res = mtd_read_oob(mtd, to + mtd->writesize, &ops);
 			if (res < 0 || ops.oobretlen != ops.ooblen)
 				goto outerr;
 
 			/* Calc the byte offset in the buffer */
-			pageoffs = page - (int)(to >> this->page_shift);
-			offs = pageoffs << this->page_shift;
+			pageoffs = page - (int)(to >> info->page_shift);
+			offs = pageoffs << info->page_shift;
 			/* Preset the bbt area with 0xff */
 			memset(&buf[offs], 0xff, (size_t)(numblocks >> sft));
 			ooboffs = len + (pageoffs * mtd->oobsize);
@@ -702,7 +709,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 			len = ALIGN(len, mtd->writesize);
 			/* Preset the buffer with 0xff */
 			memset(buf, 0xff, len +
-			       (len >> this->page_shift)* mtd->oobsize);
+			       (len >> info->page_shift) * mtd->oobsize);
 			offs = 0;
 			ooboffs = len;
 			/* Pattern is located in oob area of first page */
@@ -716,16 +723,16 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 		for (i = 0; i < numblocks; i++) {
 			uint8_t dat;
 			int sftcnt = (i << (3 - sft)) & sftmsk;
-			dat = bbt_get_entry(this, chip * numblocks + i);
+			dat = bbt_get_entry(bbt, chip * numblocks + i);
 			/* Do not store the reserved bbt blocks! */
 			buf[offs + (i >> sft)] &= ~(msk[dat] << sftcnt);
 		}
 
-		res = nand_bbt->bbt_ops->erase(mtd, to);
+		res = bbt->bbt_ops->erase(mtd, to);
 		if (res < 0)
 			goto outerr;
 
-		res = scan_write_bbt(mtd, to, len, buf,
+		res = scan_write_bbt(bbt, to, len, buf,
 				td->options & NAND_BBT_NO_OOB ? NULL :
 				&buf[len]);
 		if (res < 0)
@@ -746,19 +753,19 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
 
 /**
  * nand_memory_bbt - [GENERIC] create a memory based bad block table
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  *
  * The function creates a memory based bbt by scanning the device for
  * manufacturer / software marked good / bad blocks.
  */
-static inline int nand_memory_bbt(struct mtd_info *mtd)
+static inline int nand_memory_bbt(struct nand_bbt *bbt)
 {
-	return create_bbt(mtd, -1);
+	return create_bbt(bbt, -1);
 }
 
 /**
  * check_create - [GENERIC] create and write bbt(s) if necessary
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @buf: temporary buffer
  *
  * The function checks the results of the previous call to read_bbt and creates
@@ -766,17 +773,17 @@ static inline int nand_memory_bbt(struct mtd_info *mtd)
  * for the chip/device. Update is necessary if one of the tables is missing or
  * the version nr. of one table is less than the other.
  */
-static int check_create(struct mtd_info *mtd, uint8_t *buf)
+static int check_create(struct nand_bbt *bbt, uint8_t *buf)
 {
+	struct nand_chip_layout_info *info = bbt->info;
 	int i, chips, writeops, create, chipsel, res, res2;
-	struct nand_chip *this = mtd_to_nand(mtd);
-	struct nand_bbt_descr *td = this->bbt_td;
-	struct nand_bbt_descr *md = this->bbt_md;
+	struct nand_bbt_descr *td = bbt->bbt_td;
+	struct nand_bbt_descr *md = bbt->bbt_md;
 	struct nand_bbt_descr *rd, *rd2;
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP)
-		chips = this->numchips;
+		chips = info->numchips;
 	else
 		chips = 1;
 
@@ -825,8 +832,8 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf)
 				continue;
 
 			/* Create the table in memory by scanning the chip(s) */
-			if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY))
-				create_bbt(mtd, chipsel);
+			if (!(bbt->bbt_options & NAND_BBT_CREATE_EMPTY))
+				create_bbt(bbt, chipsel);
 
 			td->version[i] = 1;
 			if (md)
@@ -835,7 +842,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf)
 
 		/* Read back first? */
 		if (rd) {
-			res = read_abs_bbt(mtd, buf, rd, chipsel);
+			res = read_abs_bbt(bbt, buf, rd, chipsel);
 			if (mtd_is_eccerr(res)) {
 				/* Mark table as invalid */
 				rd->pages[i] = -1;
@@ -846,7 +853,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf)
 		}
 		/* If they weren't versioned, read both */
 		if (rd2) {
-			res2 = read_abs_bbt(mtd, buf, rd2, chipsel);
+			res2 = read_abs_bbt(bbt, buf, rd2, chipsel);
 			if (mtd_is_eccerr(res2)) {
 				/* Mark table as invalid */
 				rd2->pages[i] = -1;
@@ -868,14 +875,14 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf)
 
 		/* Write the bad block table to the device? */
 		if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
-			res = write_bbt(mtd, buf, td, md, chipsel);
+			res = write_bbt(bbt, buf, td, md, chipsel);
 			if (res < 0)
 				return res;
 		}
 
 		/* Write the mirror bad block table to the device? */
 		if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
-			res = write_bbt(mtd, buf, md, td, chipsel);
+			res = write_bbt(bbt, buf, md, td, chipsel);
 			if (res < 0)
 				return res;
 		}
@@ -885,25 +892,26 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf)
 
 /**
  * mark_bbt_regions - [GENERIC] mark the bad block table regions
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @td: bad block table descriptor
  *
  * The bad block table regions are marked as "bad" to prevent accidental
  * erasures / writes. The regions are identified by the mark 0x02.
  */
-static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
+static void mark_bbt_region(struct nand_bbt *bbt, struct nand_bbt_descr *td)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mtd_info *mtd = bbt->mtd;
+	struct nand_chip_layout_info *info = bbt->info;
 	int i, j, chips, block, nrblocks, update;
 	uint8_t oldval;
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
-		chips = this->numchips;
-		nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
+		chips = info->numchips;
+		nrblocks = (int)(info->chipsize >> info->bbt_erase_shift);
 	} else {
 		chips = 1;
-		nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
+		nrblocks = (int)(mtd->size >> info->bbt_erase_shift);
 	}
 
 	for (i = 0; i < chips; i++) {
@@ -911,13 +919,14 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 		    !(td->options & NAND_BBT_WRITE)) {
 			if (td->pages[i] == -1)
 				continue;
-			block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
-			oldval = bbt_get_entry(this, block);
-			bbt_mark_entry(this, block, BBT_BLOCK_RESERVED);
+			block = td->pages[i] >>
+				(info->bbt_erase_shift - info->page_shift);
+			oldval = bbt_get_entry(bbt, block);
+			bbt_mark_entry(bbt, block, BBT_BLOCK_RESERVED);
 			if ((oldval != BBT_BLOCK_RESERVED) &&
 					td->reserved_block_code)
-				nand_update_bbt(mtd, (loff_t)block <<
-						this->bbt_erase_shift);
+				nand_update_bbt(bbt, (loff_t)block <<
+						info->bbt_erase_shift);
 			continue;
 		}
 		update = 0;
@@ -926,8 +935,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 		else
 			block = i * nrblocks;
 		for (j = 0; j < td->maxblocks; j++) {
-			oldval = bbt_get_entry(this, block);
-			bbt_mark_entry(this, block, BBT_BLOCK_RESERVED);
+			oldval = bbt_get_entry(bbt, block);
+			bbt_mark_entry(bbt, block, BBT_BLOCK_RESERVED);
 			if (oldval != BBT_BLOCK_RESERVED)
 				update = 1;
 			block++;
@@ -938,22 +947,23 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
 		 * bbts.  This should only happen once.
 		 */
 		if (update && td->reserved_block_code)
-			nand_update_bbt(mtd, (loff_t)(block - 1) <<
-					this->bbt_erase_shift);
+			nand_update_bbt(bbt, (loff_t)(block - 1) <<
+					info->bbt_erase_shift);
 	}
 }
 
 /**
  * verify_bbt_descr - verify the bad block description
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @bd: the table to verify
  *
  * This functions performs a few sanity checks on the bad block description
  * table.
  */
-static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static void verify_bbt_descr(struct nand_bbt *bbt, struct nand_bbt_descr *bd)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mtd_info *mtd = bbt->mtd;
+	struct nand_chip_layout_info *info = bbt->info;
 	u32 pattern_len;
 	u32 bits;
 	u32 table_size;
@@ -964,16 +974,16 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 	pattern_len = bd->len;
 	bits = bd->options & NAND_BBT_NRBITS_MSK;
 
-	BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) &&
-			!(this->bbt_options & NAND_BBT_USE_FLASH));
+	BUG_ON((bbt->bbt_options & NAND_BBT_NO_OOB) &&
+			!(bbt->bbt_options & NAND_BBT_USE_FLASH));
 	BUG_ON(!bits);
 
 	if (bd->options & NAND_BBT_VERSION)
 		pattern_len++;
 
 	if (bd->options & NAND_BBT_NO_OOB) {
-		BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH));
-		BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB));
+		BUG_ON(!(bbt->bbt_options & NAND_BBT_USE_FLASH));
+		BUG_ON(!(bbt->bbt_options & NAND_BBT_NO_OOB));
 		BUG_ON(bd->offs);
 		if (bd->options & NAND_BBT_VERSION)
 			BUG_ON(bd->veroffs != bd->len);
@@ -981,19 +991,19 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
 	}
 
 	if (bd->options & NAND_BBT_PERCHIP)
-		table_size = this->chipsize >> this->bbt_erase_shift;
+		table_size = info->chipsize >> info->bbt_erase_shift;
 	else
-		table_size = mtd->size >> this->bbt_erase_shift;
+		table_size = mtd->size >> info->bbt_erase_shift;
 	table_size >>= 3;
 	table_size *= bits;
 	if (bd->options & NAND_BBT_NO_OOB)
 		table_size += pattern_len;
-	BUG_ON(table_size > (1 << this->bbt_erase_shift));
+	BUG_ON(table_size > (1 << info->bbt_erase_shift));
 }
 
 /**
  * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  *
  * The function checks, if a bad block table(s) is/are already available. If
  * not it scans the device for manufacturer marked good / bad blocks and writes
@@ -1002,21 +1012,22 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
  * The bad block table memory is allocated here. It must be freed by calling
  * the nand_free_bbt function.
  */
-static int nand_scan_bbt(struct mtd_info *mtd)
+static int nand_scan_bbt(struct nand_bbt *bbt)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mtd_info *mtd = bbt->mtd;
+	struct nand_chip_layout_info *info = bbt->info;
 	int len, res;
 	uint8_t *buf;
-	struct nand_bbt_descr *td = this->bbt_td;
-	struct nand_bbt_descr *md = this->bbt_md;
+	struct nand_bbt_descr *td = bbt->bbt_td;
+	struct nand_bbt_descr *md = bbt->bbt_md;
 
-	len = (mtd->size >> (this->bbt_erase_shift + 2)) ? : 1;
+	len = (mtd->size >> (info->bbt_erase_shift + 2)) ? : 1;
 	/*
 	 * Allocate memory (2bit per block) and clear the memory bad block
 	 * table.
 	 */
-	this->bbt = kzalloc(len, GFP_KERNEL);
-	if (!this->bbt)
+	bbt->bbt = kzalloc(len, GFP_KERNEL);
+	if (!bbt->bbt)
 		return -ENOMEM;
 
 	/*
@@ -1024,18 +1035,18 @@ static int nand_scan_bbt(struct mtd_info *mtd)
 	 * memory based bad block table.
 	 */
 	if (!td) {
-		if ((res = nand_memory_bbt(mtd))) {
+		if ((res = nand_memory_bbt(bbt))) {
 			pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n");
 			goto err;
 		}
 		return 0;
 	}
-	verify_bbt_descr(mtd, td);
-	verify_bbt_descr(mtd, md);
+	verify_bbt_descr(bbt, td);
+	verify_bbt_descr(bbt, md);
 
 	/* Allocate a temporary buffer for one eraseblock incl. oob */
-	len = (1 << this->bbt_erase_shift);
-	len += (len >> this->page_shift) * mtd->oobsize;
+	len = (1 << info->bbt_erase_shift);
+	len += (len >> info->page_shift) * mtd->oobsize;
 	buf = vmalloc(len);
 	if (!buf) {
 		res = -ENOMEM;
@@ -1044,59 +1055,60 @@ static int nand_scan_bbt(struct mtd_info *mtd)
 
 	/* Is the bbt at a given page? */
 	if (td->options & NAND_BBT_ABSPAGE) {
-		read_abs_bbts(mtd, buf, td, md);
+		read_abs_bbts(bbt, buf, td, md);
 	} else {
 		/* Search the bad block table using a pattern in oob */
-		search_read_bbts(mtd, buf, td, md);
+		search_read_bbts(bbt, buf, td, md);
 	}
 
-	res = check_create(mtd, buf);
+	res = check_create(bbt, buf);
 	if (res)
 		goto err;
 
 	/* Prevent the bbt regions from erasing / writing */
-	mark_bbt_region(mtd, td);
+	mark_bbt_region(bbt, td);
 	if (md)
-		mark_bbt_region(mtd, md);
+		mark_bbt_region(bbt, md);
 
 	vfree(buf);
 	return 0;
 
 err:
-	kfree(this->bbt);
-	this->bbt = NULL;
+	kfree(bbt->bbt);
+	bbt->bbt = NULL;
 	return res;
 }
 
 /**
  * nand_update_bbt - update bad block table(s)
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @offs: the offset of the newly marked block
  *
  * The function updates the bad block table(s).
  */
-static int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
+static int nand_update_bbt(struct nand_bbt *bbt, loff_t offs)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct mtd_info *mtd = bbt->mtd;
+	struct nand_chip_layout_info *info = bbt->info;
 	int len, res = 0;
 	int chip, chipsel;
 	uint8_t *buf;
-	struct nand_bbt_descr *td = this->bbt_td;
-	struct nand_bbt_descr *md = this->bbt_md;
+	struct nand_bbt_descr *td = bbt->bbt_td;
+	struct nand_bbt_descr *md = bbt->bbt_md;
 
-	if (!this->bbt || !td)
+	if (!bbt->bbt || !td)
 		return -EINVAL;
 
 	/* Allocate a temporary buffer for one eraseblock incl. oob */
-	len = (1 << this->bbt_erase_shift);
-	len += (len >> this->page_shift) * mtd->oobsize;
+	len = (1 << info->bbt_erase_shift);
+	len += (len >> info->page_shift) * mtd->oobsize;
 	buf = kmalloc(len, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
-		chip = (int)(offs >> this->chip_shift);
+		chip = (int)(offs >> info->chip_shift);
 		chipsel = chip;
 	} else {
 		chip = 0;
@@ -1109,13 +1121,13 @@ static int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
 
 	/* Write the bad block table to the device? */
 	if (td->options & NAND_BBT_WRITE) {
-		res = write_bbt(mtd, buf, td, md, chipsel);
+		res = write_bbt(bbt, buf, td, md, chipsel);
 		if (res < 0)
 			goto out;
 	}
 	/* Write the mirror bad block table to the device? */
 	if (md && (md->options & NAND_BBT_WRITE)) {
-		res = write_bbt(mtd, buf, md, td, chipsel);
+		res = write_bbt(bbt, buf, md, td, chipsel);
 	}
 
  out:
@@ -1169,62 +1181,60 @@ static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
 
 /**
  * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  *
  * This function selects the default bad block table support for the device and
  * calls the nand_scan_bbt function.
  */
-int nand_default_bbt(struct mtd_info *mtd)
+int nand_default_bbt(struct nand_bbt *bbt)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
-
 	/* Is a flash based bad block table requested? */
-	if (this->bbt_options & NAND_BBT_USE_FLASH) {
+	if (bbt->bbt_options & NAND_BBT_USE_FLASH) {
 		/* Use the default pattern descriptors */
-		if (!this->bbt_td) {
-			if (this->bbt_options & NAND_BBT_NO_OOB) {
-				this->bbt_td = &bbt_main_no_oob_descr;
-				this->bbt_md = &bbt_mirror_no_oob_descr;
+		if (!bbt->bbt_td) {
+			if (bbt->bbt_options & NAND_BBT_NO_OOB) {
+				bbt->bbt_td = &bbt_main_no_oob_descr;
+				bbt->bbt_md = &bbt_mirror_no_oob_descr;
 			} else {
-				this->bbt_td = &bbt_main_descr;
-				this->bbt_md = &bbt_mirror_descr;
+				bbt->bbt_td = &bbt_main_descr;
+				bbt->bbt_md = &bbt_mirror_descr;
 			}
 		}
 	} else {
-		this->bbt_td = NULL;
-		this->bbt_md = NULL;
+		bbt->bbt_td = NULL;
+		bbt->bbt_md = NULL;
 	}
 
-	return nand_scan_bbt(mtd);
+	return nand_scan_bbt(bbt);
 }
 
 /**
  * nand_isreserved_bbt - [NAND Interface] Check if a block is reserved
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @offs: offset in the device
  */
-int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs)
+int nand_isreserved_bbt(struct nand_bbt *bbt, loff_t offs)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct nand_chip_layout_info *info = bbt->info;
 	int block;
 
-	block = (int)(offs >> this->bbt_erase_shift);
-	return bbt_get_entry(this, block) == BBT_BLOCK_RESERVED;
+	block = (int)(offs >> info->bbt_erase_shift);
+	return bbt_get_entry(bbt, block) == BBT_BLOCK_RESERVED;
 }
 
 /**
  * nand_isbad_bbt - [NAND Interface] Check if a block is bad
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @offs: offset in the device
  * @allowbbt: allow access to bad block table region
  */
-int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
+int nand_isbad_bbt(struct nand_bbt *bbt, loff_t offs, int allowbbt)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct nand_chip_layout_info *info = bbt->info;
 	int block, res;
 
-	block = (int)(offs >> this->bbt_erase_shift);
-	res = bbt_get_entry(this, block);
+	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",
 		 (unsigned int)offs, block, res);
@@ -1242,35 +1252,35 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
 
 /**
  * nand_bbt_update_mark - update mark in the BBT
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @offs: offset of the bad block
  * @mark: block type mark
  */
-static int nand_bbt_update_mark(struct mtd_info *mtd, loff_t offs, uint8_t mark)
+static int nand_bbt_update_mark(struct nand_bbt *bbt, loff_t offs, uint8_t mark)
 {
-	struct nand_chip *this = mtd_to_nand(mtd);
+	struct nand_chip_layout_info *info = bbt->info;
 	int block, ret = 0;
 
-	block = (int)(offs >> this->bbt_erase_shift);
+	block = (int)(offs >> info->bbt_erase_shift);
 
 	/* Mark bad block in memory */
-	bbt_mark_entry(this, block, mark);
+	bbt_mark_entry(bbt, block, mark);
 
 	/* Update flash-based bad block table */
-	if (this->bbt_options & NAND_BBT_USE_FLASH)
-		ret = nand_update_bbt(mtd, offs);
+	if (bbt->bbt_options & NAND_BBT_USE_FLASH)
+		ret = nand_update_bbt(bbt, offs);
 
 	return ret;
 }
 
 /**
  * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT
- * @mtd: MTD device structure
+ * @bbt: NAND BBT structure
  * @offs: offset of the bad block
  */
-int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
+int nand_markbad_bbt(struct nand_bbt *bbt, loff_t offs)
 {
-	return nand_bbt_update_mark(mtd, offs, BBT_BLOCK_WORN);
+	return nand_bbt_update_mark(bbt, offs, BBT_BLOCK_WORN);
 }
 
 /**
@@ -1286,7 +1296,7 @@ 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);
+	return nand_default_bbt(bbt);
 }
 
 static void nand_bbt_release(struct nand_bbt *bbt)
@@ -1350,7 +1360,7 @@ 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);
+	return nand_isreserved_bbt(bbt, offs);
 }
 EXPORT_SYMBOL(nand_bbt_isreserved);
 
@@ -1367,7 +1377,7 @@ int nand_bbt_isbad(struct nand_bbt *bbt, loff_t offs)
 	 * 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);
+	return nand_isbad_bbt(bbt, offs, 1);
 }
 EXPORT_SYMBOL(nand_bbt_isbad);
 
@@ -1382,7 +1392,7 @@ 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);
+	return nand_markbad_bbt(bbt, offs);
 }
 EXPORT_SYMBOL(nand_bbt_markbad);
 
@@ -1398,6 +1408,6 @@ 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);
+	return nand_bbt_update_mark(bbt, offs, BBT_BLOCK_FACTORY_BAD);
 }
 EXPORT_SYMBOL(nand_bbt_markbad_factory);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 09/11] mtd: nand_bbt: remove old API definitions
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (7 preceding siblings ...)
  2016-03-14  2:48 ` [PATCH 08/11] mtd: nand_bbt: remove struct nand_chip from nand_bbt.c Peter Pan
@ 2016-03-14  2:48 ` Peter Pan
  2016-03-14  2:48 ` [PATCH 10/11] mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro Peter Pan
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:48 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, Peter Pan

remove old BBT APIs

Signed-off-by: Peter Pan <peterpandong@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_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, 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, offs);
+	return nand_bbt_update_mark(bbt, offs, BBT_BLOCK_WORN);
 }
 EXPORT_SYMBOL(nand_bbt_markbad);
 
@@ -1404,10 +1344,6 @@ EXPORT_SYMBOL(nand_bbt_markbad);
  */
 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, offs, BBT_BLOCK_FACTORY_BAD);
 }
 EXPORT_SYMBOL(nand_bbt_markbad_factory);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 8730afd..d180e86 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -893,9 +893,6 @@ struct nand_manufacturers {
 extern struct nand_flash_dev nand_flash_ids[];
 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_do_read(struct mtd_info *mtd, loff_t from, size_t len,
 			size_t *retlen, uint8_t *buf);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 10/11] mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (8 preceding siblings ...)
  2016-03-14  2:48 ` [PATCH 09/11] mtd: nand_bbt: remove old API definitions Peter Pan
@ 2016-03-14  2:48 ` Peter Pan
  2016-03-14  2:48 ` [PATCH 11/11] mtd: nand: remove nand_chip.bbt Peter Pan
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:48 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, Peter Pan

From: Brian Norris <computersforpeace@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 <computersforpeace@gmail.com>
Signed-off-by: Peter Pan <peterpandong@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_BBM	0x00080000
 
-/*
- * 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	0x80000000
-
 /* The maximum number of blocks to scan for a bbt */
 #define NAND_BBT_SCAN_MAXBLOCKS	4
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 11/11] mtd: nand: remove nand_chip.bbt
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (9 preceding siblings ...)
  2016-03-14  2:48 ` [PATCH 10/11] mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro Peter Pan
@ 2016-03-14  2:48 ` Peter Pan
  2016-03-14  2:57 ` [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:48 UTC (permalink / raw)
  To: computersforpeace, dwmw2, boris.brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, Peter Pan

From: Brian Norris <computersforpeace@gmail.com>

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

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Peter Pan <peterpandong@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

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (10 preceding siblings ...)
  2016-03-14  2:48 ` [PATCH 11/11] mtd: nand: remove nand_chip.bbt Peter Pan
@ 2016-03-14  2:57 ` Peter Pan
  2016-03-16 12:57   ` Boris Brezillon
  2016-03-23 20:57 ` Ezequiel Garcia
  2016-03-25  8:50 ` Boris Brezillon
  13 siblings, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-03-14  2:57 UTC (permalink / raw)
  To: Brian Norris, David Woodhouse, Boris Brezillon
  Cc: linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng, 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 <peterpansjtu@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/<all-nand-core-code>
>         drivers/mtd/nand/raw/<raw-nand-controller-drivers>
>         drivers/mtd/nand/spi/<spi-nand-code>
>         drivers/mtd/nand/onenand/<onenand-code>
>         drivers/mtd/nand/chips/<manufacturer-spcific-code>
>
> Most of the patch is borrowed from Brian Norris <computersforpeace@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
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 03/11] mtd: nand_bbt: add new API definitions
  2016-03-14  2:47 ` [PATCH 03/11] mtd: nand_bbt: add new API definitions Peter Pan
@ 2016-03-14  3:47   ` kbuild test robot
  2016-03-25  8:49   ` Boris Brezillon
  1 sibling, 0 replies; 37+ messages in thread
From: kbuild test robot @ 2016-03-14  3:47 UTC (permalink / raw)
  To: Peter Pan
  Cc: kbuild-all, computersforpeace, dwmw2, boris.brezillon,
	linux-kernel, linux-mtd, karlzhang, beanhuo, xuejiancheng,
	Peter Pan

[-- Attachment #1: Type: text/plain, Size: 2470 bytes --]

Hi Peter,

[auto build test WARNING on next-20160311]
[cannot apply to mtd/master v4.5-rc7 v4.5-rc6 v4.5-rc5 v4.5-rc7]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Peter-Pan/mtd-nand_bbt-introduce-independent-nand-BBT/20160314-105725
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   drivers/mtd/nand/nand_base.c:321: warning: Excess function parameter 'getchip' description in 'nand_block_bad'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'ops'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'info'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'options'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'bbt_td'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'bbt_md'
   drivers/mtd/nand/nand_base.c:321: warning: Excess function parameter 'getchip' description in 'nand_block_bad'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'ops'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'info'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'options'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'bbt_td'
>> drivers/mtd/nand/nand_bbt.c:1409: warning: No description found for parameter 'bbt_md'

vim +/ops +1409 drivers/mtd/nand/nand_bbt.c

  1393	static void nand_bbt_release(struct nand_bbt *bbt)
  1394	{
  1395		kfree(bbt->bbt);
  1396	}
  1397	
  1398	/**
  1399	 * nand_bbt_create - [NAND BBT Interface] create BBT structures for certain
  1400	 * MTD device
  1401	 * @mtd: MTD structure
  1402	 */
  1403	struct nand_bbt *nand_bbt_create(struct mtd_info *mtd,
  1404				const struct nand_bbt_ops *ops,
  1405				struct nand_chip_layout_info *info,
  1406				unsigned int options,
  1407				struct nand_bbt_descr *bbt_td,
  1408				struct nand_bbt_descr *bbt_md)
> 1409	{
  1410		struct nand_bbt *bbt = kzalloc(sizeof(struct nand_bbt),
  1411						GFP_KERNEL);
  1412		int ret;
  1413	
  1414		if (!bbt)
  1415			return ERR_PTR(-ENOMEM);
  1416	
  1417		bbt->mtd = mtd;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 6294 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT
  2016-03-14  2:57 ` [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
@ 2016-03-16 12:57   ` Boris Brezillon
  0 siblings, 0 replies; 37+ messages in thread
From: Boris Brezillon @ 2016-03-16 12:57 UTC (permalink / raw)
  To: Peter Pan
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, xuejiancheng, Peter Pan

Hi Peter,

On Mon, 14 Mar 2016 10:57:49 +0800
Peter Pan <peterpansjtu@gmail.com> wrote:

> Sorry I forgot to add subject prefix. Should I re-send it ?

No that should be fine. Thanks for reworking this series as suggested.
I'll try to review it soon.

> 
> On Mon, Mar 14, 2016 at 10:47 AM, Peter Pan <peterpansjtu@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/<all-nand-core-code>
> >         drivers/mtd/nand/raw/<raw-nand-controller-drivers>
> >         drivers/mtd/nand/spi/<spi-nand-code>
> >         drivers/mtd/nand/onenand/<onenand-code>
> >         drivers/mtd/nand/chips/<manufacturer-spcific-code>
> >
> > Most of the patch is borrowed from Brian Norris <computersforpeace@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
> >



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (11 preceding siblings ...)
  2016-03-14  2:57 ` [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
@ 2016-03-23 20:57 ` Ezequiel Garcia
  2016-03-28  8:20   ` Peter Pan
  2016-03-25  8:50 ` Boris Brezillon
  13 siblings, 1 reply; 37+ messages in thread
From: Ezequiel Garcia @ 2016-03-23 20:57 UTC (permalink / raw)
  To: Peter Pan, Boris Brezillon, Brian Norris
  Cc: David Woodhouse, linux-kernel, linux-mtd, Jiancheng Xue, beanhuo,
	karlzhang, Peter Pan

Hello,

On 13 March 2016 at 23:47, Peter Pan <peterpansjtu@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/<all-nand-core-code>
>         drivers/mtd/nand/raw/<raw-nand-controller-drivers>
>         drivers/mtd/nand/spi/<spi-nand-code>
>         drivers/mtd/nand/onenand/<onenand-code>
>         drivers/mtd/nand/chips/<manufacturer-spcific-code>
>

You mention this structure, but nothing in the current patchset is actually
enforcing it. This is more the future direction we are going.

> Most of the patch is borrowed from Brian Norris <computersforpeace@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.

Thanks!
-- 
Ezequiel García, VanguardiaSur
www.vanguardiasur.com.ar

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-03-14  2:47 ` [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure Peter Pan
@ 2016-03-25  8:35   ` Boris Brezillon
  2016-03-28  8:09     ` Peter Pan
  2016-04-18  6:22     ` Peter Pan
  0 siblings, 2 replies; 37+ messages in thread
From: Boris Brezillon @ 2016-03-25  8:35 UTC (permalink / raw)
  To: Peter Pan
  Cc: computersforpeace, dwmw2, linux-kernel, linux-mtd, karlzhang,
	beanhuo, xuejiancheng, Peter Pan

Hi Peter,

On Mon, 14 Mar 2016 02:47:55 +0000
Peter Pan <peterpansjtu@gmail.com> wrote:

> From: Brian Norris <computersforpeace@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/<all-nand-core-code>
> 	drivers/mtd/nand/raw/<raw-nand-controller-drivers>
> 	drivers/mtd/nand/spi/<spi-nand-code>
> 	drivers/mtd/nand/onenand/<onenand-code>
> 	drivers/mtd/nand/chips/<manufacturer-spcific-code>
> 
> Of course, nand_bbt.c should be part of <all-nand-core-code>.
> 
> 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 <computersforpeace@gmail.com>
> [Peter: 1. correct comment style
> 	2. introduce struct nand_bbt_ops and nand_chip_layout_info]
> Signed-off-by: Peter Pan <peterpandong@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.

> +	u64 chipsize;

Ditto, s/chipsize/diesize/

> +	int chip_shift;

Ditto.

> +	int bbt_erase_shift;

Hm, this is not related to the memory organization. I'd prefer moving
this one directly in 

> +	int page_shift;
> +};

The structure should probably contain other info like (oob size, pages
per block, blocks per die, ...)
I know some of those information are redundant with mtd_info content,
but it would be clearer to have everything in a common place.

Also, I'd recommend using helpers to access memory organization info.
For example nand_get_die_size(mtd), nand_get_page_size(mtd), ...

On a more general note, as already said, I'd like to see more
generalization across NAND based devices, no matter the interface
they're using.
Doing that implies forcing all NAND based devices to inherit from a
common class. Something like

struct nand_device {
	struct mtd_info mtd;
	struct nand_memory_organization memorg;
	/* ... */
};

/* rawnand_device <-> nand_chip */
struct rawnand_device {
	struct nand_device base;
	/* raw NAND specific fields */
}

struct spinand_device {
	struct nand_device base;
	/* SPI NAND specific fields */
};

struct onenand_device {
	struct nand_device base;
	/* OneNAND specific fields */
};

With this design, nand_bbt and nand_bbt_ops could use the generic
nand_device instead of directly using the mtd instance.

Anyway, that's just a long term goal, and I wanted to share my
ideas. I guess your plan is to add support for SPI nand devices, so
keep this in mind ;-).

> +
> +/**
> + * 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 */



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 03/11] mtd: nand_bbt: add new API definitions
  2016-03-14  2:47 ` [PATCH 03/11] mtd: nand_bbt: add new API definitions Peter Pan
  2016-03-14  3:47   ` kbuild test robot
@ 2016-03-25  8:49   ` Boris Brezillon
  2016-03-28  7:56     ` Peter Pan
  1 sibling, 1 reply; 37+ messages in thread
From: Boris Brezillon @ 2016-03-25  8:49 UTC (permalink / raw)
  To: Peter Pan
  Cc: computersforpeace, dwmw2, linux-kernel, linux-mtd, karlzhang,
	beanhuo, xuejiancheng, Peter Pan

On Mon, 14 Mar 2016 02:47:56 +0000
Peter Pan <peterpansjtu@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 <computersforpeace@gmail.com>
> Signed-off-by: Peter Pan <peterpandong@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 *.




-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT
  2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
                   ` (12 preceding siblings ...)
  2016-03-23 20:57 ` Ezequiel Garcia
@ 2016-03-25  8:50 ` Boris Brezillon
  2016-03-28  7:56   ` Peter Pan
  13 siblings, 1 reply; 37+ messages in thread
From: Boris Brezillon @ 2016-03-25  8:50 UTC (permalink / raw)
  To: Peter Pan
  Cc: computersforpeace, dwmw2, linux-kernel, linux-mtd, karlzhang,
	beanhuo, xuejiancheng, Peter Pan

On Mon, 14 Mar 2016 02:47:53 +0000
Peter Pan <peterpansjtu@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/<all-nand-core-code>
> 	drivers/mtd/nand/raw/<raw-nand-controller-drivers>
> 	drivers/mtd/nand/spi/<spi-nand-code>
> 	drivers/mtd/nand/onenand/<onenand-code>
> 	drivers/mtd/nand/chips/<manufacturer-spcific-code>

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.


-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 05/11] mtd: nand: use new BBT API instead of old ones
  2016-03-14  2:47 ` [PATCH 05/11] mtd: nand: use new BBT API instead of old ones Peter Pan
@ 2016-03-25  8:51   ` Boris Brezillon
  2016-03-28  8:12     ` Peter Pan
  0 siblings, 1 reply; 37+ messages in thread
From: Boris Brezillon @ 2016-03-25  8:51 UTC (permalink / raw)
  To: Peter Pan
  Cc: computersforpeace, dwmw2, linux-kernel, linux-mtd, karlzhang,
	beanhuo, xuejiancheng, Peter Pan

On Mon, 14 Mar 2016 02:47:58 +0000
Peter Pan <peterpansjtu@gmail.com> wrote:

> Use new BBT APIs (nand_bbt_*()) in NAND. Keep old APIs (nand_*_bbt())
> exist temporarily.
> 
> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
> Signed-off-by: Peter Pan <peterpandong@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.

> +
> +	if (!info)
> +		return -ENOMEM;
> +
> +	info->numchips = chip->numchips;
> +	info->chipsize = chip->chipsize;
> +	info->chip_shift = chip->chip_shift;
> +	info->bbt_erase_shift = chip->phys_erase_shift;
> +	info->page_shift = chip->page_shift;
> +
> +	if (!chip->badblock_pattern &&
> +		nand_create_factory_badblock_pattern(chip))
> +		return -ENOMEM;
> +
> +	nand_bbt = nand_bbt_create(mtd, &default_bbt_ops,
> +				info, chip->bbt_options,
> +				chip->bbt_td, chip->bbt_md);
> +	if (IS_ERR(nand_bbt))
> +		return PTR_ERR(nand_bbt);
> +	chip->nand_bbt = nand_bbt;
> +
> +	return 0;
> +}



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 03/11] mtd: nand_bbt: add new API definitions
  2016-03-25  8:49   ` Boris Brezillon
@ 2016-03-28  7:56     ` Peter Pan
  0 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-28  7:56 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, xuejiancheng, Peter Pan

On Fri, Mar 25, 2016 at 4:49 PM, Boris Brezillon
<boris.brezillon@free-electrons.com> wrote:
> On Mon, 14 Mar 2016 02:47:56 +0000
> Peter Pan <peterpansjtu@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 <computersforpeace@gmail.com>
>> Signed-off-by: Peter Pan <peterpandong@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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT
  2016-03-25  8:50 ` Boris Brezillon
@ 2016-03-28  7:56   ` Peter Pan
  0 siblings, 0 replies; 37+ messages in thread
From: Peter Pan @ 2016-03-28  7:56 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, xuejiancheng, Peter Pan

On Fri, Mar 25, 2016 at 4:50 PM, Boris Brezillon
<boris.brezillon@free-electrons.com> wrote:
> On Mon, 14 Mar 2016 02:47:53 +0000
> Peter Pan <peterpansjtu@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/<all-nand-core-code>
>>       drivers/mtd/nand/raw/<raw-nand-controller-drivers>
>>       drivers/mtd/nand/spi/<spi-nand-code>
>>       drivers/mtd/nand/onenand/<onenand-code>
>>       drivers/mtd/nand/chips/<manufacturer-spcific-code>
>
> 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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-03-25  8:35   ` Boris Brezillon
@ 2016-03-28  8:09     ` Peter Pan
  2016-03-29  8:16       ` Boris Brezillon
  2016-04-18  6:22     ` Peter Pan
  1 sibling, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-03-28  8:09 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, xuejiancheng, 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.brezillon@free-electrons.com> wrote:
> Hi Peter,
>
> On Mon, 14 Mar 2016 02:47:55 +0000
> Peter Pan <peterpansjtu@gmail.com> wrote:
>
>> From: Brian Norris <computersforpeace@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/<all-nand-core-code>
>>       drivers/mtd/nand/raw/<raw-nand-controller-drivers>
>>       drivers/mtd/nand/spi/<spi-nand-code>
>>       drivers/mtd/nand/onenand/<onenand-code>
>>       drivers/mtd/nand/chips/<manufacturer-spcific-code>
>>
>> Of course, nand_bbt.c should be part of <all-nand-core-code>.
>>
>> 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 <computersforpeace@gmail.com>
>> [Peter: 1. correct comment style
>>       2. introduce struct nand_bbt_ops and nand_chip_layout_info]
>> Signed-off-by: Peter Pan <peterpandong@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.

Fix this in v4
>
>> +     int numchips;
>
> I would rename it numdies, or ndies. numchips implies you're having
> several chips, which is not the case.

Fix this in v4
>
>> +     u64 chipsize;
>
> Ditto, s/chipsize/diesize/

Fix this in v4
>
>> +     int chip_shift;
>
> Ditto.

Fix this in v4
>
>> +     int bbt_erase_shift;
>
> Hm, this is not related to the memory organization. I'd prefer moving
> this one directly in

Yes, I also realize bbt_erase_shift is not proper. How about just rename it
to erase_block_shift or block_shift ?

>
>> +     int page_shift;
>> +};
>
> The structure should probably contain other info like (oob size, pages
> per block, blocks per die, ...)
> I know some of those information are redundant with mtd_info content,
> but it would be clearer to have everything in a common place.
>
> Also, I'd recommend using helpers to access memory organization info.
> For example nand_get_die_size(mtd), nand_get_page_size(mtd), ...
>
> On a more general note, as already said, I'd like to see more
> generalization across NAND based devices, no matter the interface
> they're using.
> Doing that implies forcing all NAND based devices to inherit from a
> common class. Something like
>
> struct nand_device {
>         struct mtd_info mtd;
>         struct nand_memory_organization memorg;
>         /* ... */
> };
>
> /* rawnand_device <-> nand_chip */
> struct rawnand_device {
>         struct nand_device base;
>         /* raw NAND specific fields */
> }
>
> struct spinand_device {
>         struct nand_device base;
>         /* SPI NAND specific fields */
> };
>
> struct onenand_device {
>         struct nand_device base;
>         /* OneNAND specific fields */
> };
>
> With this design, nand_bbt and nand_bbt_ops could use the generic
> nand_device instead of directly using the mtd instance.
>
> Anyway, that's just a long term goal, and I wanted to share my
> ideas. I guess your plan is to add support for SPI nand devices, so
> keep this in mind ;-).

Acctually your idea is quite good. Actually, struct nand_chip_layout_info
shouldn't be in nand_bbt.h. It should be in nand.h or nand_base.h and embedded
in struct nand_chip (or struct nand_deivce as your said).
The reason I did't do this is I feel it will be too involved. I need
to change almost
all files under mtd/nand/, which generates a larger patch set.
So I put struct nand_chip_layout_info here temporarily. Just as you
said, it's a long
term goal. Sorry for no comments to explain this in patches.

Thanks,
Peter Pan

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 05/11] mtd: nand: use new BBT API instead of old ones
  2016-03-25  8:51   ` Boris Brezillon
@ 2016-03-28  8:12     ` Peter Pan
  2016-03-29  8:07       ` Boris Brezillon
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-03-28  8:12 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, xuejiancheng, Peter Pan

On Fri, Mar 25, 2016 at 4:51 PM, Boris Brezillon
<boris.brezillon@free-electrons.com> wrote:
> On Mon, 14 Mar 2016 02:47:58 +0000
> Peter Pan <peterpansjtu@gmail.com> wrote:
>
>> Use new BBT APIs (nand_bbt_*()) in NAND. Keep old APIs (nand_*_bbt())
>> exist temporarily.
>>
>> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
>> Signed-off-by: Peter Pan <peterpandong@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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT
  2016-03-23 20:57 ` Ezequiel Garcia
@ 2016-03-28  8:20   ` Peter Pan
  2016-03-29  8:02     ` Boris Brezillon
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-03-28  8:20 UTC (permalink / raw)
  To: Ezequiel Garcia
  Cc: Boris Brezillon, Brian Norris, David Woodhouse, linux-kernel,
	linux-mtd, Jiancheng Xue, beanhuo, karlzhang, 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
<ezequiel@vanguardiasur.com.ar> wrote:
> Hello,
>
> On 13 March 2016 at 23:47, Peter Pan <peterpansjtu@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/<all-nand-core-code>
>>         drivers/mtd/nand/raw/<raw-nand-controller-drivers>
>>         drivers/mtd/nand/spi/<spi-nand-code>
>>         drivers/mtd/nand/onenand/<onenand-code>
>>         drivers/mtd/nand/chips/<manufacturer-spcific-code>
>>
>
> 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 <computersforpeace@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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT
  2016-03-28  8:20   ` Peter Pan
@ 2016-03-29  8:02     ` Boris Brezillon
  0 siblings, 0 replies; 37+ messages in thread
From: Boris Brezillon @ 2016-03-29  8:02 UTC (permalink / raw)
  To: Peter Pan
  Cc: Ezequiel Garcia, Brian Norris, David Woodhouse, linux-kernel,
	linux-mtd, Jiancheng Xue, beanhuo, karlzhang, Peter Pan

Hi Peter,

On Mon, 28 Mar 2016 16:20:19 +0800
Peter Pan <peterpansjtu@gmail.com> wrote:

> 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
> <ezequiel@vanguardiasur.com.ar> wrote:
> > Hello,
> >
> > On 13 March 2016 at 23:47, Peter Pan <peterpansjtu@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/<all-nand-core-code>
> >>         drivers/mtd/nand/raw/<raw-nand-controller-drivers>
> >>         drivers/mtd/nand/spi/<spi-nand-code>
> >>         drivers/mtd/nand/onenand/<onenand-code>
> >>         drivers/mtd/nand/chips/<manufacturer-spcific-code>
> >>
> >
> > 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 <computersforpeace@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.

Yes, that's what I expect. And since this SPI NAND framework does not
exist yet, I think it's a good time to create the generic nand_device
struct (we'll switch other NAND based devices to this structure
afterwards).

Thanks,

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 05/11] mtd: nand: use new BBT API instead of old ones
  2016-03-28  8:12     ` Peter Pan
@ 2016-03-29  8:07       ` Boris Brezillon
  0 siblings, 0 replies; 37+ messages in thread
From: Boris Brezillon @ 2016-03-29  8:07 UTC (permalink / raw)
  To: Peter Pan
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, xuejiancheng, Peter Pan

On Mon, 28 Mar 2016 16:12:08 +0800
Peter Pan <peterpansjtu@gmail.com> wrote:

> On Fri, Mar 25, 2016 at 4:51 PM, Boris Brezillon
> <boris.brezillon@free-electrons.com> wrote:
> > On Mon, 14 Mar 2016 02:47:58 +0000
> > Peter Pan <peterpansjtu@gmail.com> wrote:
> >
> >> Use new BBT APIs (nand_bbt_*()) in NAND. Keep old APIs (nand_*_bbt())
> >> exist temporarily.
> >>
> >> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
> >> Signed-off-by: Peter Pan <peterpandong@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.

Hm, I don't like the idea of duplicating the same information in two
different places, just because we don't want to touch NAND drivers/core
code. I'll have a look, and if it's not too invasive (not sure we have
that much code using those fields), I'd prefer having them patched right
now...


-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-03-28  8:09     ` Peter Pan
@ 2016-03-29  8:16       ` Boris Brezillon
  0 siblings, 0 replies; 37+ messages in thread
From: Boris Brezillon @ 2016-03-29  8:16 UTC (permalink / raw)
  To: Peter Pan
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, xuejiancheng, Peter Pan

On Mon, 28 Mar 2016 16:09:44 +0800
Peter Pan <peterpansjtu@gmail.com> wrote:

> 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.brezillon@free-electrons.com> wrote:
> > Hi Peter,
> >
> > On Mon, 14 Mar 2016 02:47:55 +0000
> > Peter Pan <peterpansjtu@gmail.com> wrote:
> >
> >> From: Brian Norris <computersforpeace@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/<all-nand-core-code>
> >>       drivers/mtd/nand/raw/<raw-nand-controller-drivers>
> >>       drivers/mtd/nand/spi/<spi-nand-code>
> >>       drivers/mtd/nand/onenand/<onenand-code>
> >>       drivers/mtd/nand/chips/<manufacturer-spcific-code>
> >>
> >> Of course, nand_bbt.c should be part of <all-nand-core-code>.
> >>
> >> 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 <computersforpeace@gmail.com>
> >> [Peter: 1. correct comment style
> >>       2. introduce struct nand_bbt_ops and nand_chip_layout_info]
> >> Signed-off-by: Peter Pan <peterpandong@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.
> 
> Fix this in v4
> >
> >> +     int numchips;
> >
> > I would rename it numdies, or ndies. numchips implies you're having
> > several chips, which is not the case.
> 
> Fix this in v4
> >
> >> +     u64 chipsize;
> >
> > Ditto, s/chipsize/diesize/
> 
> Fix this in v4
> >
> >> +     int chip_shift;
> >
> > Ditto.
> 
> Fix this in v4
> >
> >> +     int bbt_erase_shift;
> >
> > Hm, this is not related to the memory organization. I'd prefer moving
> > this one directly in
> 
> Yes, I also realize bbt_erase_shift is not proper. How about just rename it
> to erase_block_shift or block_shift ?

eraseblock_shift sounds good as long as
bbt_erase_shift == eraseblock_shift is always true.

> 
> >
> >> +     int page_shift;
> >> +};
> >
> > The structure should probably contain other info like (oob size, pages
> > per block, blocks per die, ...)
> > I know some of those information are redundant with mtd_info content,
> > but it would be clearer to have everything in a common place.
> >
> > Also, I'd recommend using helpers to access memory organization info.
> > For example nand_get_die_size(mtd), nand_get_page_size(mtd), ...
> >
> > On a more general note, as already said, I'd like to see more
> > generalization across NAND based devices, no matter the interface
> > they're using.
> > Doing that implies forcing all NAND based devices to inherit from a
> > common class. Something like
> >
> > struct nand_device {
> >         struct mtd_info mtd;
> >         struct nand_memory_organization memorg;
> >         /* ... */
> > };
> >
> > /* rawnand_device <-> nand_chip */
> > struct rawnand_device {
> >         struct nand_device base;
> >         /* raw NAND specific fields */
> > }
> >
> > struct spinand_device {
> >         struct nand_device base;
> >         /* SPI NAND specific fields */
> > };
> >
> > struct onenand_device {
> >         struct nand_device base;
> >         /* OneNAND specific fields */
> > };
> >
> > With this design, nand_bbt and nand_bbt_ops could use the generic
> > nand_device instead of directly using the mtd instance.
> >
> > Anyway, that's just a long term goal, and I wanted to share my
> > ideas. I guess your plan is to add support for SPI nand devices, so
> > keep this in mind ;-).
> 
> Acctually your idea is quite good. Actually, struct nand_chip_layout_info
> shouldn't be in nand_bbt.h. It should be in nand.h or nand_base.h and embedded
> in struct nand_chip (or struct nand_deivce as your said).

Yes, I didn't comment on that since I don't want to create a
nand_base.h header file. The idea is to rename nand.h into rawnand.h
and then create a nand.h file containing all interface-independent
stuff (like memory organization info).

> The reason I did't do this is I feel it will be too involved. I need
> to change almost
> all files under mtd/nand/, which generates a larger patch set.

Yes, I know, that's why I'm not asking that right now. But that would
be great if we could prepare things for this move...


-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-03-25  8:35   ` Boris Brezillon
  2016-03-28  8:09     ` Peter Pan
@ 2016-04-18  6:22     ` Peter Pan
  2016-04-18  7:44       ` Boris Brezillon
  1 sibling, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-04-18  6:22 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, Jiancheng Xue, Peter Pan

Hi  Boris,

On Fri, Mar 25, 2016 at 4:35 PM, Boris Brezillon
<boris.brezillon@free-electrons.com> wrote:
> Hi Peter,
>
> On Mon, 14 Mar 2016 02:47:55 +0000
> Peter Pan <peterpansjtu@gmail.com> wrote:
>
>> From: Brian Norris <computersforpeace@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/<all-nand-core-code>
>>       drivers/mtd/nand/raw/<raw-nand-controller-drivers>
>>       drivers/mtd/nand/spi/<spi-nand-code>
>>       drivers/mtd/nand/onenand/<onenand-code>
>>       drivers/mtd/nand/chips/<manufacturer-spcific-code>
>>
>> Of course, nand_bbt.c should be part of <all-nand-core-code>.
>>
>> 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 <computersforpeace@gmail.com>
>> [Peter: 1. correct comment style
>>       2. introduce struct nand_bbt_ops and nand_chip_layout_info]
>> Signed-off-by: Peter Pan <peterpandong@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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-04-18  6:22     ` Peter Pan
@ 2016-04-18  7:44       ` Boris Brezillon
  2016-04-19  0:40         ` Peter Pan
  0 siblings, 1 reply; 37+ messages in thread
From: Boris Brezillon @ 2016-04-18  7:44 UTC (permalink / raw)
  To: Peter Pan
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, Jiancheng Xue, Peter Pan

Hi Peter,

On Mon, 18 Apr 2016 14:22:09 +0800
Peter Pan <peterpansjtu@gmail.com> wrote:

> Hi  Boris,
> 
> On Fri, Mar 25, 2016 at 4:35 PM, Boris Brezillon
> <boris.brezillon@free-electrons.com> wrote:
> > Hi Peter,
> >
> > On Mon, 14 Mar 2016 02:47:55 +0000
> > Peter Pan <peterpansjtu@gmail.com> wrote:
> >
> >> From: Brian Norris <computersforpeace@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/<all-nand-core-code>
> >>       drivers/mtd/nand/raw/<raw-nand-controller-drivers>
> >>       drivers/mtd/nand/spi/<spi-nand-code>
> >>       drivers/mtd/nand/onenand/<onenand-code>
> >>       drivers/mtd/nand/chips/<manufacturer-spcific-code>
> >>
> >> Of course, nand_bbt.c should be part of <all-nand-core-code>.
> >>
> >> 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 <computersforpeace@gmail.com>
> >> [Peter: 1. correct comment style
> >>       2. introduce struct nand_bbt_ops and nand_chip_layout_info]
> >> Signed-off-by: Peter Pan <peterpandong@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?

I don't know what was the initial meaning for ->numchips, but last time
we discussed that with Brian, he seemed to agree that this should now
encode the number of dies in a physical chip, and each physical chip
should have its own nand_chip instance. That's why I suggested to
rename this field nand_chip_layout_info. 

> 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.

Best Regards,

Boris

[1]https://github.com/bbrezillon/linux-sunxi/commits/nand/generic

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-04-18  7:44       ` Boris Brezillon
@ 2016-04-19  0:40         ` Peter Pan
  2016-04-19  7:34           ` Boris Brezillon
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-04-19  0:40 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, Jiancheng Xue, Peter Pan

Hi Boris,

On Mon, Apr 18, 2016 at 3:44 PM, Boris Brezillon
<boris.brezillon@free-electrons.com> wrote:
> Hi Peter,
>
> On Mon, 18 Apr 2016 14:22:09 +0800
> Peter Pan <peterpansjtu@gmail.com> wrote:
>
>> Hi  Boris,
>>
>> On Fri, Mar 25, 2016 at 4:35 PM, Boris Brezillon
>> <boris.brezillon@free-electrons.com> wrote:
>> > Hi Peter,
>> >
>> > On Mon, 14 Mar 2016 02:47:55 +0000
>> > Peter Pan <peterpansjtu@gmail.com> wrote:
>> >
>> >> From: Brian Norris <computersforpeace@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/<all-nand-core-code>
>> >>       drivers/mtd/nand/raw/<raw-nand-controller-drivers>
>> >>       drivers/mtd/nand/spi/<spi-nand-code>
>> >>       drivers/mtd/nand/onenand/<onenand-code>
>> >>       drivers/mtd/nand/chips/<manufacturer-spcific-code>
>> >>
>> >> Of course, nand_bbt.c should be part of <all-nand-core-code>.
>> >>
>> >> 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 <computersforpeace@gmail.com>
>> >> [Peter: 1. correct comment style
>> >>       2. introduce struct nand_bbt_ops and nand_chip_layout_info]
>> >> Signed-off-by: Peter Pan <peterpandong@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?
>
> I don't know what was the initial meaning for ->numchips, but last time
> we discussed that with Brian, he seemed to agree that this should now
> encode the number of dies in a physical chip, and each physical chip
> should have its own nand_chip instance. That's why I suggested to
> rename this field nand_chip_layout_info.

OK. This is clear. Thanks.

>
>> 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 ?

Thanks,
Peter Pan

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-04-19  0:40         ` Peter Pan
@ 2016-04-19  7:34           ` Boris Brezillon
  2016-05-04  1:36             ` Peter Pan
  0 siblings, 1 reply; 37+ messages in thread
From: Boris Brezillon @ 2016-04-19  7:34 UTC (permalink / raw)
  To: Peter Pan
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, Jiancheng Xue, Peter Pan

Hi Peter,

On Tue, 19 Apr 2016 08:40:40 +0800
Peter Pan <peterpansjtu@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).

Let me know if you think otherwise.

Best Regards,

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-04-19  7:34           ` Boris Brezillon
@ 2016-05-04  1:36             ` Peter Pan
  2016-05-04 20:33               ` Boris Brezillon
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-05-04  1:36 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, Jiancheng Xue, Peter Pan

Hi Boris,

On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
<boris.brezillon@free-electrons.com> wrote:
> Hi Peter,
>
> On Tue, 19 Apr 2016 08:40:40 +0800
> Peter Pan <peterpansjtu@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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-05-04  1:36             ` Peter Pan
@ 2016-05-04 20:33               ` Boris Brezillon
  2016-05-17  1:03                 ` Peter Pan
  0 siblings, 1 reply; 37+ messages in thread
From: Boris Brezillon @ 2016-05-04 20:33 UTC (permalink / raw)
  To: Peter Pan
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, Jiancheng Xue, Peter Pan

Hi Peter,

On Wed, 4 May 2016 09:36:05 +0800
Peter Pan <peterpansjtu@gmail.com> wrote:

> Hi Boris,
> 
> On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
> <boris.brezillon@free-electrons.com> wrote:
> > Hi Peter,
> >
> > On Tue, 19 Apr 2016 08:40:40 +0800
> > Peter Pan <peterpansjtu@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 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 SPI NAND (and other NAND based devices)
support.

Since I'm the one who pushed for this transition to an intermediate
"NAND core" layer, I'm willing to help you with this task. I actually
reworked my series [1] to move the BBT code in drivers/mtd/nand/bbt.c
and move raw NAND code into drivers/mtd/nand/rawnand/ (still have to
rework the commit logs, and test the implementation, but the different
steps are there and we end-up with something clean in
drivers/mtd/nand/).

Could you help me debug this code and base your SPI NAND framework on
top of it?

Again, I'm sorry that you had to be the one supporting this transition,
but I don't want to introduce any more quick-and-dirty hacks that we'll
have to maintain until someone decides to tackle the real problem.

Best Regards,

Boris

[1]https://github.com/bbrezillon/linux-0day/commits/nand/generic

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-05-04 20:33               ` Boris Brezillon
@ 2016-05-17  1:03                 ` Peter Pan
  2016-06-17  2:38                   ` Peter Pan
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-05-17  1:03 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, Jiancheng Xue, Peter Pan

Hi Boris,

Firstly, sorry for late reply.

On Thu, May 5, 2016 at 4:33 AM, Boris Brezillon
<boris.brezillon@free-electrons.com> wrote:
> Hi Peter,
>
> On Wed, 4 May 2016 09:36:05 +0800
> Peter Pan <peterpansjtu@gmail.com> wrote:
>
>> Hi Boris,
>>
>> On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
>> <boris.brezillon@free-electrons.com> wrote:
>> > Hi Peter,
>> >
>> > On Tue, 19 Apr 2016 08:40:40 +0800
>> > Peter Pan <peterpansjtu@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 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 SPI NAND (and other NAND based devices)
> support.
>
> Since I'm the one who pushed for this transition to an intermediate
> "NAND core" layer, I'm willing to help you with this task. I actually
> reworked my series [1] to move the BBT code in drivers/mtd/nand/bbt.c
> and move raw NAND code into drivers/mtd/nand/rawnand/ (still have to
> rework the commit logs, and test the implementation, but the different
> steps are there and we end-up with something clean in
> drivers/mtd/nand/).
>
> Could you help me debug this code and base your SPI NAND framework on
> top of it?

Yes I can. Actually I already clone your git tree and start to go
through your commits.
And I'll let you know when I have questions.

>
> Again, I'm sorry that you had to be the one supporting this transition,
> but I don't want to introduce any more quick-and-dirty hacks that we'll
> have to maintain until someone decides to tackle the real problem.

No sorry needed. I'd like to do the contribution.

Thanks
Peter Pan

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-05-17  1:03                 ` Peter Pan
@ 2016-06-17  2:38                   ` Peter Pan
  2016-06-21 13:27                     ` Boris Brezillon
  0 siblings, 1 reply; 37+ messages in thread
From: Peter Pan @ 2016-06-17  2:38 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, Jiancheng Xue, Peter Pan

Hi Boris,

On Tue, May 17, 2016 at 9:03 AM, Peter Pan <peterpansjtu@gmail.com> wrote:
> Hi Boris,
>
> Firstly, sorry for late reply.
>
> On Thu, May 5, 2016 at 4:33 AM, Boris Brezillon
> <boris.brezillon@free-electrons.com> wrote:
>> Hi Peter,
>>
>> On Wed, 4 May 2016 09:36:05 +0800
>> Peter Pan <peterpansjtu@gmail.com> wrote:
>>
>>> Hi Boris,
>>>
>>> On Tue, Apr 19, 2016 at 3:34 PM, Boris Brezillon
>>> <boris.brezillon@free-electrons.com> wrote:
>>> > Hi Peter,
>>> >
>>> > On Tue, 19 Apr 2016 08:40:40 +0800
>>> > Peter Pan <peterpansjtu@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 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 SPI NAND (and other NAND based devices)
>> support.
>>
>> Since I'm the one who pushed for this transition to an intermediate
>> "NAND core" layer, I'm willing to help you with this task. I actually
>> reworked my series [1] to move the BBT code in drivers/mtd/nand/bbt.c
>> and move raw NAND code into drivers/mtd/nand/rawnand/ (still have to
>> rework the commit logs, and test the implementation, but the different
>> steps are there and we end-up with something clean in
>> drivers/mtd/nand/).
>>
>> Could you help me debug this code and base your SPI NAND framework on
>> top of it?
>
> Yes I can. Actually I already clone your git tree and start to go
> through your commits.
> And I'll let you know when I have questions.
>
>>
>> Again, I'm sorry that you had to be the one supporting this transition,
>> but I don't want to introduce any more quick-and-dirty hacks that we'll
>> have to maintain until someone decides to tackle the real problem.
>
> No sorry needed. I'd like to do the contribution.

I did test on your nand generic patches. And I found two error about nand helper
functions. Below is my fixing. After my fixing, BBT is functional on
my platform.



>From 2162e8ece4ffa09bb00abe383714a95f4b74aad8 Mon Sep 17 00:00:00 2001
From: Peter Pan <peterpandong@micron.com>
Date: Fri, 17 Jun 2016 10:31:59 +0800
Subject: [PATCH] mtd: nand: fix nand helper function

nand_page_size() and nand_eraseblock_to_offs() return
fault value. Fix them.

Signed-off-by: Peter Pan <peterpandong@micron.com>
---
 include/linux/mtd/nand.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 583eb40..ffee2a7 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -162,7 +162,7 @@ static inline size_t nand_pages_to_len(struct
nand_device *nand, int npages)
  */
 static inline size_t nand_page_size(struct nand_device *nand)
 {
-    return nand->memorg.eraseblocksize;
+    return nand->memorg.pagesize;
 }

 /**
@@ -197,7 +197,7 @@ static inline size_t nand_eraseblock_size(struct
nand_device *nand)
 static inline loff_t nand_eraseblock_to_offs(struct nand_device *nand,
                          int block)
 {
-    return (loff_t)nand->memorg.pagesize * block;
+    return (loff_t)nand->memorg.eraseblocksize * block;
 }

 /**
-- 
1.9.1


>
> Thanks
> Peter Pan

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure
  2016-06-17  2:38                   ` Peter Pan
@ 2016-06-21 13:27                     ` Boris Brezillon
  0 siblings, 0 replies; 37+ messages in thread
From: Boris Brezillon @ 2016-06-21 13:27 UTC (permalink / raw)
  To: Peter Pan
  Cc: Brian Norris, David Woodhouse, linux-kernel, linux-mtd,
	karlzhang, beanhuo, Jiancheng Xue, Peter Pan

On Fri, 17 Jun 2016 10:38:27 +0800
Peter Pan <peterpansjtu@gmail.com> wrote:

> >>
> >> Again, I'm sorry that you had to be the one supporting this transition,
> >> but I don't want to introduce any more quick-and-dirty hacks that we'll
> >> have to maintain until someone decides to tackle the real problem.  
> >
> > No sorry needed. I'd like to do the contribution.  
> 
> I did test on your nand generic patches. And I found two error about nand helper
> functions. Below is my fixing. After my fixing, BBT is functional on
> my platform.
> 

Thanks for testing it (and fixing the implementation). I'll try to send
the series after the 4.8 merge window, unless you want to take care of
it and send a version right now.

> 
> 
> From 2162e8ece4ffa09bb00abe383714a95f4b74aad8 Mon Sep 17 00:00:00 2001
> From: Peter Pan <peterpandong@micron.com>
> Date: Fri, 17 Jun 2016 10:31:59 +0800
> Subject: [PATCH] mtd: nand: fix nand helper function
> 
> nand_page_size() and nand_eraseblock_to_offs() return
> fault value. Fix them.
> 
> Signed-off-by: Peter Pan <peterpandong@micron.com>
> ---
>  include/linux/mtd/nand.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> index 583eb40..ffee2a7 100644
> --- a/include/linux/mtd/nand.h
> +++ b/include/linux/mtd/nand.h
> @@ -162,7 +162,7 @@ static inline size_t nand_pages_to_len(struct
> nand_device *nand, int npages)
>   */
>  static inline size_t nand_page_size(struct nand_device *nand)
>  {
> -    return nand->memorg.eraseblocksize;
> +    return nand->memorg.pagesize;
>  }
> 
>  /**
> @@ -197,7 +197,7 @@ static inline size_t nand_eraseblock_size(struct
> nand_device *nand)
>  static inline loff_t nand_eraseblock_to_offs(struct nand_device *nand,
>                           int block)
>  {
> -    return (loff_t)nand->memorg.pagesize * block;
> +    return (loff_t)nand->memorg.eraseblocksize * block;
>  }
> 
>  /**

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2016-06-21 13:27 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-14  2:47 [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
2016-03-14  2:47 ` [PATCH 01/11] mtd: nand_bbt: new header for nand family BBT Peter Pan
2016-03-14  2:47 ` [PATCH 02/11] mtd: nand_bbt: introduce BBT related data structure Peter Pan
2016-03-25  8:35   ` Boris Brezillon
2016-03-28  8:09     ` Peter Pan
2016-03-29  8:16       ` Boris Brezillon
2016-04-18  6:22     ` Peter Pan
2016-04-18  7:44       ` Boris Brezillon
2016-04-19  0:40         ` Peter Pan
2016-04-19  7:34           ` Boris Brezillon
2016-05-04  1:36             ` Peter Pan
2016-05-04 20:33               ` Boris Brezillon
2016-05-17  1:03                 ` Peter Pan
2016-06-17  2:38                   ` Peter Pan
2016-06-21 13:27                     ` Boris Brezillon
2016-03-14  2:47 ` [PATCH 03/11] mtd: nand_bbt: add new API definitions Peter Pan
2016-03-14  3:47   ` kbuild test robot
2016-03-25  8:49   ` Boris Brezillon
2016-03-28  7:56     ` Peter Pan
2016-03-14  2:47 ` [PATCH 04/11] mtd: nand_bbt: add nand_bbt_markbad_factory() interface Peter Pan
2016-03-14  2:47 ` [PATCH 05/11] mtd: nand: use new BBT API instead of old ones Peter Pan
2016-03-25  8:51   ` Boris Brezillon
2016-03-28  8:12     ` Peter Pan
2016-03-29  8:07       ` Boris Brezillon
2016-03-14  2:47 ` [PATCH 06/11] mtd: nand_bbt: use struct nand_bbt_ops in BBT Peter Pan
2016-03-14  2:48 ` [PATCH 07/11] mtd: nand: make nand_erase_nand() static Peter Pan
2016-03-14  2:48 ` [PATCH 08/11] mtd: nand_bbt: remove struct nand_chip from nand_bbt.c Peter Pan
2016-03-14  2:48 ` [PATCH 09/11] mtd: nand_bbt: remove old API definitions Peter Pan
2016-03-14  2:48 ` [PATCH 10/11] mtd: nand_bbt: remove NAND_BBT_DYNAMICSTRUCT macro Peter Pan
2016-03-14  2:48 ` [PATCH 11/11] mtd: nand: remove nand_chip.bbt Peter Pan
2016-03-14  2:57 ` [PATCH 00/11] mtd: nand_bbt: introduce independent nand BBT Peter Pan
2016-03-16 12:57   ` Boris Brezillon
2016-03-23 20:57 ` Ezequiel Garcia
2016-03-28  8:20   ` Peter Pan
2016-03-29  8:02     ` Boris Brezillon
2016-03-25  8:50 ` Boris Brezillon
2016-03-28  7:56   ` Peter Pan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).