From a0dc552951dcbb2b28a8a2ffb5fa966613e8c025 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 31 May 2011 16:31:20 -0700 Subject: mtd: nand: remove NAND_BBT_SCANBYTE1AND6 option This patch reverts most of: commit 58373ff0afff4cc8ac40608872995f4d87eb72ec mtd: nand: more BB Detection refactoring and dynamic scan options According to the discussion at: http://lists.infradead.org/pipermail/linux-mtd/2011-May/035696.html the NAND_BBT_SCANBYTE1AND6 flag, although technically valid, can break some existing ECC layouts that use the 6th byte in the OOB for ECC data. Furthermore, we apparently do not need to scan both bytes 1 and 6 in the OOB region of the devices under consideration; instead, we only need to scan one or the other. Thus, the NAND_BBT_SCANBYTE1AND6 flag is at best unnecessary and at worst a regression. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index ccbeaa1e4a8e..5ffb9a4632ca 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -114,28 +114,6 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc return -1; } - /* Check both positions 1 and 6 for pattern? */ - if (td->options & NAND_BBT_SCANBYTE1AND6) { - if (td->options & NAND_BBT_SCANEMPTY) { - p += td->len; - end += NAND_SMALL_BADBLOCK_POS - td->offs; - /* Check region between positions 1 and 6 */ - for (i = 0; i < NAND_SMALL_BADBLOCK_POS - td->offs - td->len; - i++) { - if (*p++ != 0xff) - return -1; - } - } - else { - p += NAND_SMALL_BADBLOCK_POS - td->offs; - } - /* Compare the pattern */ - for (i = 0; i < td->len; i++) { - if (p[i] != td->pattern[i]) - return -1; - } - } - if (td->options & NAND_BBT_SCANEMPTY) { p += td->len; end += td->len; @@ -167,13 +145,6 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) if (p[td->offs + i] != td->pattern[i]) return -1; } - /* Need to check location 1 AND 6? */ - if (td->options & NAND_BBT_SCANBYTE1AND6) { - for (i = 0; i < td->len; i++) { - if (p[NAND_SMALL_BADBLOCK_POS + i] != td->pattern[i]) - return -1; - } - } return 0; } @@ -1330,8 +1301,7 @@ static struct nand_bbt_descr bbt_mirror_no_bbt_descr = { .pattern = mirror_pattern }; -#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \ - NAND_BBT_SCANBYTE1AND6) +#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE) /** * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure * @this: NAND chip to create descriptor for -- cgit v1.2.1 From 5fb1549dfc40f3b589dae560ea21535cdc5f64e0 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 31 May 2011 16:31:21 -0700 Subject: mtd: nand: separate chip options / bbt_options This patch handles the problems we've been having with using conflicting flags from nand.h and bbm.h in the same nand_chip.options field. We should try to separate these two spaces a little more clearly, and so I have added a bbt_options field to nand_chip. Important notes about nand_chip fields: * bbt_options field should contain ONLY flags from bbm.h. They should be able to pass safely to a nand_bbt_descr data structure. - BBT option flags start with the "NAND_BBT_" prefix. * options field should contian ONLY flags from nand.h. Ideally, they should not be involved in any BBT related options. - NAND chip option flags start with the "NAND_" prefix. * Every flag should have a nice comment explaining what the flag is. While this is not yet the case on all existing flags, please be sure to write one for new flags. Even better, you can help document the code better yourself! Please try to follow these conventions to make everyone's lives easier. Among the flags that are being moved to the new bbt_options field throughout various drivers, etc. are: * NAND_BBT_SCANLASTPAGE * NAND_BBT_SCAN2NDPAGE and there will be more to come. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 5ffb9a4632ca..5df01d8efd92 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -517,7 +517,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, from = (loff_t)startblock << (this->bbt_erase_shift - 1); } - if (this->options & NAND_BBT_SCANLASTPAGE) + if (this->bbt_options & NAND_BBT_SCANLASTPAGE) from += mtd->erasesize - (mtd->writesize * len); for (i = startblock; i < numblocks;) { @@ -1301,7 +1301,6 @@ static struct nand_bbt_descr bbt_mirror_no_bbt_descr = { .pattern = mirror_pattern }; -#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE) /** * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure * @this: NAND chip to create descriptor for @@ -1324,7 +1323,7 @@ static int nand_create_default_bbt_descr(struct nand_chip *this) printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n"); return -ENOMEM; } - bd->options = this->options & BBT_SCAN_OPTIONS; + bd->options = this->bbt_options; bd->offs = this->badblockpos; bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1; bd->pattern = scan_ff_pattern; -- cgit v1.2.1 From a40f73419f02e40555f692785ea1c1813d5b4c12 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 31 May 2011 16:31:22 -0700 Subject: mtd: nand: consolidate redundant flash-based BBT flags This patch works with the following three flags from two headers (nand.h and bbm.h): (1) NAND_USE_FLASH_BBT (nand.h) (2) NAND_USE_FLASH_BBT_NO_OOB (nand.h) (3) NAND_BBT_NO_OOB (bbm.h) These flags are all related and interdependent, yet they were in different headers. Flag (2) is simply the combination of (1) and (3) and can be eliminated. This patch accomplishes the following: * eliminate NAND_USE_FLASH_BBT_NO_OOB (i.e., flag (2)) * move NAND_USE_FLASH_BBT (i.e., flag (1)) to bbm.h It's important to note that because (1) and (3) are now both found in bbm.h, they should NOT be used in the "nand_chip.options" field. I removed a small section from the mtdnand DocBook because it referes to NAND_USE_FLASH_BBT in nand.h, which has been moved to bbm.h. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 5df01d8efd92..66f93e2ac16b 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -36,9 +36,9 @@ * The table is marked in the OOB area with an ident pattern and a version * number which indicates which of both tables is more up to date. If the NAND * controller needs the complete OOB area for the ECC information then the - * option NAND_USE_FLASH_BBT_NO_OOB should be used: it moves the ident pattern - * and the version byte into the data area and the OOB area will remain - * untouched. + * option NAND_BBT_NO_OOB should be used (along with NAND_USE_FLASH_BBT, of + * course): it moves the ident pattern and the version byte into the data area + * and the OOB area will remain untouched. * * The table uses 2 bits per block * 11b: block is good @@ -1082,16 +1082,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->options & NAND_USE_FLASH_BBT_NO_OOB) && - !(this->options & NAND_USE_FLASH_BBT)); + BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) && + !(this->bbt_options & NAND_USE_FLASH_BBT)); BUG_ON(!bits); if (bd->options & NAND_BBT_VERSION) pattern_len++; if (bd->options & NAND_BBT_NO_OOB) { - BUG_ON(!(this->options & NAND_USE_FLASH_BBT)); - BUG_ON(!(this->options & NAND_USE_FLASH_BBT_NO_OOB)); + BUG_ON(!(this->bbt_options & NAND_USE_FLASH_BBT)); + BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB)); BUG_ON(bd->offs); if (bd->options & NAND_BBT_VERSION) BUG_ON(bd->veroffs != bd->len); @@ -1357,15 +1357,15 @@ int nand_default_bbt(struct mtd_info *mtd) this->bbt_td = &bbt_main_descr; this->bbt_md = &bbt_mirror_descr; } - this->options |= NAND_USE_FLASH_BBT; + this->bbt_options |= NAND_USE_FLASH_BBT; return nand_scan_bbt(mtd, &agand_flashbased); } /* Is a flash based bad block table requested ? */ - if (this->options & NAND_USE_FLASH_BBT) { + if (this->bbt_options & NAND_USE_FLASH_BBT) { /* Use the default pattern descriptors */ if (!this->bbt_td) { - if (this->options & NAND_USE_FLASH_BBT_NO_OOB) { + if (this->bbt_options & NAND_BBT_NO_OOB) { this->bbt_td = &bbt_main_no_bbt_descr; this->bbt_md = &bbt_mirror_no_bbt_descr; } else { -- cgit v1.2.1 From bb9ebd4e714385a2592a482845865ef2d58b2868 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 31 May 2011 16:31:23 -0700 Subject: mtd: nand: rename NAND_USE_FLASH_BBT Recall the recently added prefix requirements: * "NAND_" for flags in nand.h, used in nand_chip.options * "NAND_BBT_" for flags in bbm.h, used in nand_chip.bbt_options or in nand_bbt_descr.options Thus, I am changing NAND_USE_FLASH_BBT to NAND_BBT_USE_FLASH. Again, this flag is found in bbm.h and so should NOT be used in the "nand_chip.options" field. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 66f93e2ac16b..dfea9fd1d61c 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -14,7 +14,7 @@ * * When nand_scan_bbt is called, then it tries to find the bad block table * depending on the options in the BBT descriptor(s). If no flash based BBT - * (NAND_USE_FLASH_BBT) is specified then the device is scanned for factory + * (NAND_BBT_USE_FLASH) is specified then the device is scanned for factory * marked good / bad blocks. This information is used to create a memory BBT. * Once a new bad block is discovered then the "factory" information is updated * on the device. @@ -36,7 +36,7 @@ * The table is marked in the OOB area with an ident pattern and a version * number which indicates which of both tables is more up to date. If the NAND * controller needs the complete OOB area for the ECC information then the - * option NAND_BBT_NO_OOB should be used (along with NAND_USE_FLASH_BBT, of + * option NAND_BBT_NO_OOB should be used (along with NAND_BBT_USE_FLASH, of * course): it moves the ident pattern and the version byte into the data area * and the OOB area will remain untouched. * @@ -1083,14 +1083,14 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) bits = bd->options & NAND_BBT_NRBITS_MSK; BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) && - !(this->bbt_options & NAND_USE_FLASH_BBT)); + !(this->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_USE_FLASH_BBT)); + BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH)); BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB)); BUG_ON(bd->offs); if (bd->options & NAND_BBT_VERSION) @@ -1357,12 +1357,12 @@ int nand_default_bbt(struct mtd_info *mtd) this->bbt_td = &bbt_main_descr; this->bbt_md = &bbt_mirror_descr; } - this->bbt_options |= NAND_USE_FLASH_BBT; + this->bbt_options |= NAND_BBT_USE_FLASH; return nand_scan_bbt(mtd, &agand_flashbased); } /* Is a flash based bad block table requested ? */ - if (this->bbt_options & NAND_USE_FLASH_BBT) { + if (this->bbt_options & NAND_BBT_USE_FLASH) { /* Use the default pattern descriptors */ if (!this->bbt_td) { if (this->bbt_options & NAND_BBT_NO_OOB) { -- cgit v1.2.1 From b8f80684054ec8a3bcdf35dc9c76ddf629a36482 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 31 May 2011 16:31:24 -0700 Subject: mtd: nand: move NAND_CREATE_EMPTY_BBT flag The NAND_CREATE_EMPTY_BBT flag was added by commit: 453281a973c10bce941b240d1c654d536623b16b mtd: nand: introduce NAND_CREATE_EMPTY_BBT This flag is not used within the kernel and not explained well, so I took the liberty to edit its comments. Also, this is a BBT-related flag (and closely tied with NAND_BBT_CREATE) so I'm moving it to bbm.h next to NAND_BBT_CREATE, thus requiring that we use the flag in nand_chip.bbt_options, *not* in nand_chip.options. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index dfea9fd1d61c..2e4e25996f03 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -970,7 +970,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc continue; /* Create the table in memory by scanning the chip(s) */ - if (!(this->options & NAND_CREATE_EMPTY_BBT)) + if (!(this->bbt_options & NAND_CREATE_EMPTY_BBT)) create_bbt(mtd, buf, bd, chipsel); td->version[i] = 1; -- cgit v1.2.1 From 53d5d8885089b8abeb487392311ed18f897deb93 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 31 May 2011 16:31:25 -0700 Subject: mtd: nand: rename CREATE_EMPTY bbt flag with proper prefix According to our new prefix rules, we should rename NAND_CREATE_EMPTY_BBT with a NAND_BBT prefix, i.e., NAND_BBT_CREATE_EMPTY. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 2e4e25996f03..9af703def4aa 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -970,7 +970,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc continue; /* Create the table in memory by scanning the chip(s) */ - if (!(this->bbt_options & NAND_CREATE_EMPTY_BBT)) + if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY)) create_bbt(mtd, buf, bd, chipsel); td->version[i] = 1; -- cgit v1.2.1 From 8b6e50c9eba8bf44b2dfd931d359706a461d2cfd Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 25 May 2011 14:59:01 -0700 Subject: mtd: nand: multi-line comment style fixups Artem: while on it, do other commentaries clean-ups: 1. Start one-line comments with capital letter and no dot at the end 2. Turn sparse multi-line comments into one-line comments 3. Change "phrase ?" to "phrase?" and the same with "!". 4. Remove tabs from the kerneldoc parameters comments - they are mixed with tabs often, and inconsistent. 5. Put dot at the end of descriptions in kerneldoc comments. 6. Some other small commentaries clean-ups Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 365 +++++++++++++++++++++----------------------- 1 file changed, 175 insertions(+), 190 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 9af703def4aa..ba401662835e 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -80,17 +80,15 @@ static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td) /** * check_pattern - [GENERIC] check if a pattern is in the buffer - * @buf: the buffer to search - * @len: the length of buffer to search - * @paglen: the pagelength - * @td: search pattern descriptor + * @buf: the buffer to search + * @len: the length of buffer to search + * @paglen: the pagelength + * @td: search pattern descriptor * - * Check for a pattern at the given place. Used to search bad block - * tables and good / bad block identifiers. - * If the SCAN_EMPTY option is set then check, if all bytes except the - * pattern area contain 0xff - * -*/ + * Check for a pattern at the given place. Used to search bad block tables and + * good / bad block identifiers. If the SCAN_EMPTY option is set then check, if + * all bytes except the pattern area contain 0xff. + */ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) { int i, end = 0; @@ -127,14 +125,13 @@ 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 + * @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) { int i; @@ -150,7 +147,7 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) /** * add_marker_len - compute the length of the marker in data area - * @td: BBT descriptor used for computation + * @td: BBT descriptor used for computation * * The length will be 0 if the markeris located in OOB area. */ @@ -169,15 +166,14 @@ 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 - * @buf: temporary buffer - * @page: the starting page - * @num: the number of bbt descriptors to read - * @td: the bbt describtion table - * @offs: offset in the memory table + * @mtd: MTD device structure + * @buf: temporary buffer + * @page: the starting page + * @num: the number of bbt descriptors to read + * @td: the bbt describtion table + * @offs: offset in the memory table * * Read the bad block table starting from page. - * */ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, struct nand_bbt_descr *td, int offs) @@ -229,11 +225,13 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, mtd->ecc_stats.bbtblocks++; continue; } - /* Leave it for now, if its matured we can move this - * message to MTD_DEBUG_LEVEL0 */ + /* + * Leave it for now, if it's matured we can + * move this message to MTD_DEBUG_LEVEL0. + */ printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%012llx\n", (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); - /* Factory marked bad or worn out ? */ + /* Factory marked bad or worn out? */ if (tmp == 0) this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); else @@ -249,15 +247,15 @@ 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 - * @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 NAND_BBT_PERCHIP option is set + * @mtd: MTD device structure + * @buf: temporary buffer + * @td: descriptor for the bad block table + * @chip: read the table for a specific chip, -1 read all chips; aplies only if + * NAND_BBT_PERCHIP option is set * - * Read the bad block table for all chips starting at a given page - * We assume that the bbt bits are in consecutive order. -*/ + * 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) { struct nand_chip *this = mtd->priv; @@ -283,9 +281,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc return 0; } -/* - * BBT marker is in the first page, no OOB. - */ +/* BBT marker is in the first page, no OOB */ static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs, struct nand_bbt_descr *td) { @@ -299,9 +295,7 @@ static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs, return mtd->read(mtd, offs, len, &retlen, buf); } -/* - * Scan read raw data from flash - */ +/* Scan read raw data from flash */ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs, size_t len) { @@ -344,9 +338,7 @@ static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs, return scan_read_raw_oob(mtd, buf, offs, len); } -/* - * Scan write data with oob to flash - */ +/* Scan write data with oob to flash */ static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len, uint8_t *buf, uint8_t *oob) { @@ -373,15 +365,14 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td) /** * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page - * @mtd: MTD device structure - * @buf: temporary buffer - * @td: descriptor for the bad block table - * @md: descriptor for the bad block table mirror - * - * Read the bad block table(s) for all chips starting at a given page - * We assume that the bbt bits are in consecutive order. + * @mtd: MTD device structure + * @buf: temporary buffer + * @td: descriptor for the bad block table + * @md: descriptor for the bad block table mirror * -*/ + * 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 int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md) { @@ -407,9 +398,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, return 1; } -/* - * Scan a given block full - */ +/* Scan a given block full */ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, loff_t offs, uint8_t *buf, size_t readlen, int scanlen, int len) @@ -427,9 +416,7 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, return 0; } -/* - * Scan a given block partially - */ +/* 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 len) { @@ -444,9 +431,8 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, for (j = 0; j < len; j++) { /* - * Read the full oob until read_oob is fixed to - * handle single byte reads for 16 bit - * buswidth + * 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); if (ret) @@ -462,14 +448,14 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, /** * 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 + * @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 + * 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) @@ -500,8 +486,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, } if (chip == -1) { - /* Note that numblocks is 2 * (real numblocks) here, see i+=2 - * below as it makes shifting and masking less painful */ + /* + * Note that numblocks is 2 * (real numblocks) here, see i+=2 + * below as it makes shifting and masking less painful + */ numblocks = mtd->size >> (this->bbt_erase_shift - 1); startblock = 0; from = 0; @@ -549,20 +537,18 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, /** * search_bbt - [GENERIC] scan the device for a specific bad block table - * @mtd: MTD device structure - * @buf: temporary buffer - * @td: descriptor for the bad block table + * @mtd: MTD device structure + * @buf: temporary buffer + * @td: descriptor for the bad block table * - * Read the bad block table by searching for a given ident pattern. - * Search is preformed either from the beginning up or from the end of - * the device downwards. The search starts always at the start of a - * block. - * If the option NAND_BBT_PERCHIP is given, each chip is searched - * for a bbt, which contains the bad block information of this chip. - * This is necessary to provide support for certain DOC devices. + * Read the bad block table by searching for a given ident pattern. Search is + * preformed either from the beginning up or from the end of the device + * downwards. The search starts always at the start of a block. If the option + * NAND_BBT_PERCHIP is given, each chip is searched for a bbt, which contains + * the bad block information of this chip. This is necessary to provide support + * for certain DOC devices. * - * The bbt ident pattern resides in the oob area of the first page - * in a block. + * 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) { @@ -573,7 +559,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr int bbtblocks; int blocktopage = this->bbt_erase_shift - this->page_shift; - /* Search direction top -> down ? */ + /* Search direction top -> down? */ if (td->options & NAND_BBT_LASTBLOCK) { startblock = (mtd->size >> this->bbt_erase_shift) - 1; dir = -1; @@ -582,7 +568,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr dir = 1; } - /* Do we have a bbt per chip ? */ + /* Do we have a bbt per chip? */ if (td->options & NAND_BBT_PERCHIP) { chips = this->numchips; bbtblocks = this->chipsize >> this->bbt_erase_shift; @@ -631,13 +617,13 @@ 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 - * @buf: temporary buffer - * @td: descriptor for the bad block table - * @md: descriptor for the bad block table mirror + * @mtd: MTD device 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) -*/ + * Search and read the bad block table(s). + */ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md) { /* Search the primary table */ @@ -653,16 +639,14 @@ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt /** * write_bbt - [GENERIC] (Re)write the bad block table + * @mtd: MTD device structure + * @buf: temporary buffer + * @td: descriptor for the bad block table + * @md: descriptor for the bad block table mirror + * @chipsel: selector for a specific chip, -1 for all * - * @mtd: MTD device structure - * @buf: temporary buffer - * @td: descriptor for the bad block table - * @md: descriptor for the bad block table mirror - * @chipsel: selector for a specific chip, -1 for all - * - * (Re)write the bad block table - * -*/ + * (Re)write the bad block table. + */ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) @@ -685,10 +669,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (!rcode) rcode = 0xff; - /* Write bad block table per chip rather than per device ? */ + /* Write bad block table per chip rather than per device? */ if (td->options & NAND_BBT_PERCHIP) { numblocks = (int)(this->chipsize >> this->bbt_erase_shift); - /* Full device write or specific chip ? */ + /* Full device write or specific chip? */ if (chipsel == -1) { nrchips = this->numchips; } else { @@ -702,8 +686,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, /* Loop through the chips */ for (; chip < nrchips; chip++) { - - /* There was already a version of the table, reuse the page + /* + * There was already a version of the table, reuse the page * This applies for absolute placement too, as we have the * page nr. in td->pages. */ @@ -712,8 +696,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, goto write; } - /* Automatic placement of the bad block table */ - /* Search direction top -> down ? */ + /* + * Automatic placement of the bad block table. Search direction + * top -> down? + */ if (td->options & NAND_BBT_LASTBLOCK) { startblock = numblocks * (chip + 1) - 1; dir = -1; @@ -764,7 +750,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, to = ((loff_t) page) << this->page_shift; - /* Must we save the block contents ? */ + /* 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)); @@ -798,13 +784,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, } else if (td->options & NAND_BBT_NO_OOB) { ooboffs = 0; offs = td->len; - /* the version byte */ + /* The version byte */ if (td->options & NAND_BBT_VERSION) offs++; /* Calc length */ len = (size_t) (numblocks >> sft); len += offs; - /* Make it page aligned ! */ + /* Make it page aligned! */ len = ALIGN(len, mtd->writesize); /* Preset the buffer with 0xff */ memset(buf, 0xff, len); @@ -813,7 +799,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, } else { /* Calc length */ len = (size_t) (numblocks >> sft); - /* Make it page aligned ! */ + /* Make it page aligned! */ len = ALIGN(len, mtd->writesize); /* Preset the buffer with 0xff */ memset(buf, 0xff, len + @@ -827,13 +813,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (td->options & NAND_BBT_VERSION) buf[ooboffs + td->veroffs] = td->version[chip]; - /* walk through the memory table */ + /* Walk through the memory table */ for (i = 0; i < numblocks;) { uint8_t dat; dat = this->bbt[bbtoffs + (i >> 2)]; for (j = 0; j < 4; j++, i++) { int sftcnt = (i << (3 - sft)) & sftmsk; - /* Do not store the reserved bbt blocks ! */ + /* Do not store the reserved bbt blocks! */ buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt); dat >>= 2; @@ -870,12 +856,12 @@ 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 + * @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 -*/ + * 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) { struct nand_chip *this = mtd->priv; @@ -886,16 +872,15 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b /** * 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 + * @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 -*/ + * 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) { int i, chips, writeops, chipsel, res; @@ -904,7 +889,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc struct nand_bbt_descr *md = this->bbt_md; struct nand_bbt_descr *rd, *rd2; - /* Do we have a bbt per chip ? */ + /* Do we have a bbt per chip? */ if (td->options & NAND_BBT_PERCHIP) chips = this->numchips; else @@ -914,9 +899,9 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc writeops = 0; rd = NULL; rd2 = NULL; - /* Per chip or per device ? */ + /* Per chip or per device? */ chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; - /* Mirrored table available ? */ + /* Mirrored table available? */ if (md) { if (td->pages[i] == -1 && md->pages[i] == -1) { writeops = 0x03; @@ -965,7 +950,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc goto writecheck; } create: - /* Create the bad block table by scanning the device ? */ + /* Create the bad block table by scanning the device? */ if (!(td->options & NAND_BBT_CREATE)) continue; @@ -977,21 +962,21 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc if (md) md->version[i] = 1; writecheck: - /* read back first ? */ + /* Read back first? */ if (rd) read_abs_bbt(mtd, buf, rd, chipsel); - /* If they weren't versioned, read both. */ + /* If they weren't versioned, read both */ if (rd2) read_abs_bbt(mtd, buf, rd2, chipsel); - /* Write the bad block table to the device ? */ + /* Write the bad block table to the device? */ if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { res = write_bbt(mtd, buf, td, md, chipsel); if (res < 0) return res; } - /* Write the mirror bad block table to the device ? */ + /* 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); if (res < 0) @@ -1003,20 +988,19 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc /** * mark_bbt_regions - [GENERIC] mark the bad block table regions - * @mtd: MTD device structure - * @td: bad block table descriptor + * @mtd: MTD device 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. -*/ + * 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) { struct nand_chip *this = mtd->priv; int i, j, chips, block, nrblocks, update; uint8_t oldval, newval; - /* Do we have a bbt per chip ? */ + /* Do we have a bbt per chip? */ if (td->options & NAND_BBT_PERCHIP) { chips = this->numchips; nrblocks = (int)(this->chipsize >> this->bbt_erase_shift); @@ -1053,9 +1037,11 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) update = 1; block += 2; } - /* If we want reserved blocks to be recorded to flash, and some - new ones have been marked, then we need to update the stored - bbts. This should only happen once. */ + /* + * If we want reserved blocks to be recorded to flash, and some + * new ones have been marked, then we need to update the stored + * bbts. This should only happen once. + */ if (update && td->reserved_block_code) nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1)); } @@ -1063,8 +1049,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) /** * verify_bbt_descr - verify the bad block description - * @mtd: MTD device structure - * @bd: the table to verify + * @mtd: MTD device structure + * @bd: the table to verify * * This functions performs a few sanity checks on the bad block description * table. @@ -1111,18 +1097,16 @@ 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 + * @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 the bad block table(s) to - * the selected place. + * 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 + * the bad block table(s) to the selected place. * - * The bad block table memory is allocated here. It must be freed - * by calling the nand_free_bbt function. - * -*/ + * The bad block table memory is allocated here. It must be freed by calling + * the nand_free_bbt function. + */ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) { struct nand_chip *this = mtd->priv; @@ -1132,15 +1116,19 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) struct nand_bbt_descr *md = this->bbt_md; len = mtd->size >> (this->bbt_erase_shift + 2); - /* Allocate memory (2bit per block) and clear the memory bad block table */ + /* + * Allocate memory (2bit per block) and clear the memory bad block + * table. + */ this->bbt = kzalloc(len, GFP_KERNEL); if (!this->bbt) { printk(KERN_ERR "nand_scan_bbt: Out of memory\n"); return -ENOMEM; } - /* If no primary table decriptor is given, scan the device - * to build a memory based bad block table + /* + * If no primary table decriptor is given, scan the device to build a + * memory based bad block table. */ if (!td) { if ((res = nand_memory_bbt(mtd, bd))) { @@ -1164,7 +1152,7 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) return -ENOMEM; } - /* Is the bbt at a given page ? */ + /* Is the bbt at a given page? */ if (td->options & NAND_BBT_ABSPAGE) { res = read_abs_bbts(mtd, buf, td, md); } else { @@ -1186,11 +1174,11 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) /** * nand_update_bbt - [NAND Interface] update bad block table(s) - * @mtd: MTD device structure - * @offs: the offset of the newly marked block + * @mtd: MTD device structure + * @offs: the offset of the newly marked block * - * The function updates the bad block table(s) -*/ + * The function updates the bad block table(s). + */ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) { struct nand_chip *this = mtd->priv; @@ -1214,7 +1202,7 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) writeops = md != NULL ? 0x03 : 0x01; - /* Do we have a bbt per chip ? */ + /* Do we have a bbt per chip? */ if (td->options & NAND_BBT_PERCHIP) { chip = (int)(offs >> this->chip_shift); chipsel = chip; @@ -1227,13 +1215,13 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) if (md) md->version[chip]++; - /* Write the bad block table to the device ? */ + /* Write the bad block table to the device? */ if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { res = write_bbt(mtd, buf, td, md, chipsel); if (res < 0) goto out; } - /* Write the mirror bad block table to the device ? */ + /* 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); } @@ -1243,8 +1231,10 @@ 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. */ +/* + * 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 }; static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 }; @@ -1256,8 +1246,7 @@ static struct nand_bbt_descr agand_flashbased = { .pattern = scan_agand_pattern }; -/* Generic flash bbt decriptors -*/ +/* Generic flash bbt decriptors */ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; @@ -1303,13 +1292,12 @@ static struct nand_bbt_descr bbt_mirror_no_bbt_descr = { /** * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure - * @this: NAND chip to create descriptor for + * @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_default_bbt_descr(struct nand_chip *this) { @@ -1334,22 +1322,20 @@ static int nand_create_default_bbt_descr(struct nand_chip *this) /** * nand_default_bbt - [NAND Interface] Select a default bad block table for the device - * @mtd: MTD device structure - * - * This function selects the default bad block table - * support for the device and calls the nand_scan_bbt function + * @mtd: MTD device 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) { struct nand_chip *this = mtd->priv; - /* Default for AG-AND. We must use a flash based - * bad block table as the devices have factory marked - * _good_ blocks. Erasing those blocks leads to loss - * of the good / bad information, so we _must_ store - * this information in a good / bad table during - * startup + /* + * Default for AG-AND. We must use a flash based bad block table as the + * devices have factory marked _good_ blocks. Erasing those blocks + * leads to loss of the good / bad information, so we _must_ store this + * information in a good / bad table during startup. */ if (this->options & NAND_IS_AND) { /* Use the default pattern descriptors */ @@ -1361,7 +1347,7 @@ int nand_default_bbt(struct mtd_info *mtd) return nand_scan_bbt(mtd, &agand_flashbased); } - /* Is a flash based bad block table requested ? */ + /* Is a flash based bad block table requested? */ if (this->bbt_options & NAND_BBT_USE_FLASH) { /* Use the default pattern descriptors */ if (!this->bbt_td) { @@ -1386,11 +1372,10 @@ int nand_default_bbt(struct mtd_info *mtd) /** * nand_isbad_bbt - [NAND Interface] Check if a block is bad - * @mtd: MTD device structure - * @offs: offset in the device - * @allowbbt: allow access to bad block table region - * -*/ + * @mtd: MTD device 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) { struct nand_chip *this = mtd->priv; -- cgit v1.2.1 From 0870066d7e6c85bbe37741137e4c4731501a98e0 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 7 Jun 2011 16:01:54 -0700 Subject: mtd: remove printk's for [kv][mz]alloc failures When a memory allocation fails, the kernel will print out a backtrace automatically. These print statements are unnecessary. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index ba401662835e..8875d6db2455 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -1121,10 +1121,8 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) * table. */ this->bbt = kzalloc(len, GFP_KERNEL); - if (!this->bbt) { - printk(KERN_ERR "nand_scan_bbt: Out of memory\n"); + if (!this->bbt) return -ENOMEM; - } /* * If no primary table decriptor is given, scan the device to build a @@ -1146,7 +1144,6 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) len += (len >> this->page_shift) * mtd->oobsize; buf = vmalloc(len); if (!buf) { - printk(KERN_ERR "nand_bbt: Out of memory\n"); kfree(this->bbt); this->bbt = NULL; return -ENOMEM; @@ -1195,10 +1192,8 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) len = (1 << this->bbt_erase_shift); len += (len >> this->page_shift) * mtd->oobsize; buf = kmalloc(len, GFP_KERNEL); - if (!buf) { - printk(KERN_ERR "nand_update_bbt: Out of memory\n"); + if (!buf) return -ENOMEM; - } writeops = md != NULL ? 0x03 : 0x01; @@ -1307,10 +1302,8 @@ static int nand_create_default_bbt_descr(struct nand_chip *this) return -EINVAL; } bd = kzalloc(sizeof(*bd), GFP_KERNEL); - if (!bd) { - printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n"); + if (!bd) return -ENOMEM; - } bd->options = this->bbt_options; bd->offs = this->badblockpos; bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1; -- cgit v1.2.1 From 7854d3f7495b11be1570cd3e2318674d8f9ed797 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 23 Jun 2011 14:12:08 -0700 Subject: mtd: spelling, capitalization, uniformity Therefor -> Therefore [Intern], [Internal] -> [INTERN] [REPLACABLE] -> [REPLACEABLE] syndrom, syndom -> syndrome ecc -> ECC buswith -> buswidth endianess -> endianness dont -> don't occures -> occurs independend -> independent wihin -> within erease -> erase blockes -> blocks ... Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 8875d6db2455..f30807c3a48d 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -149,7 +149,7 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) * add_marker_len - compute the length of the marker in data area * @td: BBT descriptor used for computation * - * The length will be 0 if the markeris located in OOB area. + * The length will be 0 if the marker is located in OOB area. */ static u32 add_marker_len(struct nand_bbt_descr *td) { @@ -170,7 +170,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td) * @buf: temporary buffer * @page: the starting page * @num: the number of bbt descriptors to read - * @td: the bbt describtion table + * @td: the bbt describtion table * @offs: offset in the memory table * * Read the bad block table starting from page. @@ -1241,7 +1241,7 @@ static struct nand_bbt_descr agand_flashbased = { .pattern = scan_agand_pattern }; -/* Generic flash bbt decriptors */ +/* Generic flash bbt descriptors */ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; @@ -1286,7 +1286,7 @@ static struct nand_bbt_descr bbt_mirror_no_bbt_descr = { }; /** - * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure + * nand_create_default_bbt_descr - [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 -- cgit v1.2.1 From 903cd06cd6ece7f9050a3ad5b03e0b76be2882ff Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 28 Jun 2011 16:28:58 -0700 Subject: mtd: nand: ignore ECC errors for simple BBM scans Now that nand_do_readoob() may return -EUCLEAN or -EBADMSG on ECC errors, we need to handle the return value specially in some cases. When scanning for simple bad block markers, reacting to an ECC error is not very useful, as we assume that the relevant markers are still non-0xFF for true bad blocks. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index f30807c3a48d..a4fcbf1cbc76 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -312,14 +312,20 @@ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs, ops.oobbuf = buf + len; ops.datbuf = buf; ops.len = len; - return mtd->read_oob(mtd, offs, &ops); + res = mtd->read_oob(mtd, offs, &ops); + + /* Ignore ECC errors when checking for BBM */ + if (res != -EUCLEAN && res != -EBADMSG) + return res; + return 0; } else { ops.oobbuf = buf + mtd->writesize; ops.datbuf = buf; ops.len = mtd->writesize; res = mtd->read_oob(mtd, offs, &ops); - if (res) + /* Ignore ECC errors when checking for BBM */ + if (res && res != -EUCLEAN && res != -EBADMSG) return res; } @@ -435,7 +441,8 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, * byte reads for 16 bit buswidth. */ ret = mtd->read_oob(mtd, offs, &ops); - if (ret) + /* Ignore ECC errors when checking for BBM */ + if (ret && ret != -EUCLEAN && ret != -EBADMSG) return ret; if (check_short_pattern(buf, bd)) -- cgit v1.2.1 From a0f5080ecc1c75f9c08591d9b0f48451e7ac8ddc Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 19 Jul 2011 10:06:06 -0700 Subject: mtd: nand: change KERN_DEBUG to KERN_INFO Soon we will change many printk statements into pr_* statements, i.e., 'printk(KERN_INFO, ...)' becomes 'pr_info(...)'. However, this means that KERN_DEBUG messages will become pr_debug() statements and therefore will not be activated by default - they must be enabled using dynamic debug. So, for important DEBUG messages, we will simply upgrade these to INFO so that they appear by default. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index a4fcbf1cbc76..0d2eaa72288f 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -219,7 +219,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, if (tmp == msk) continue; if (reserved_block_code && (tmp == reserved_block_code)) { - printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%012llx\n", + printk(KERN_INFO "nand_read_bbt: Reserved block at 0x%012llx\n", (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); mtd->ecc_stats.bbtblocks++; @@ -227,9 +227,9 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, } /* * Leave it for now, if it's matured we can - * move this message to MTD_DEBUG_LEVEL0. + * move this message to pr_debug. */ - printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%012llx\n", + printk(KERN_INFO "nand_read_bbt: Bad block at 0x%012llx\n", (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); /* Factory marked bad or worn out? */ if (tmp == 0) @@ -389,7 +389,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift, mtd->writesize, td); td->version[0] = buf[bbt_get_ver_offs(mtd, td)]; - printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", + printk(KERN_INFO "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); } @@ -398,7 +398,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift, mtd->writesize, td); md->version[0] = buf[bbt_get_ver_offs(mtd, md)]; - printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", + printk(KERN_INFO "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); } return 1; @@ -616,7 +616,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr if (td->pages[i] == -1) printk(KERN_WARNING "Bad block table not found for chip %d\n", i); else - printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], + printk(KERN_INFO "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); } return 0; @@ -847,7 +847,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (res < 0) goto outerr; - printk(KERN_DEBUG "Bad block table written to 0x%012llx, version " + printk(KERN_INFO "Bad block table written to 0x%012llx, version " "0x%02X\n", (unsigned long long)to, td->version[chip]); /* Mark it as used */ -- cgit v1.2.1 From 9a4d4d69018e7b719ba58fa30fcdd60e547776b8 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 19 Jul 2011 10:06:07 -0700 Subject: mtd: nand: convert printk() to pr_*() Instead of directly calling printk, it's simpler to use the built-in pr_* functions. This shortens code and allows easy customization through the definition of a pr_fmt() macro (not used currently). Ideally, we could implement much of this with dev_* functions, but the MTD subsystem does not necessarily register all its master `mtd_info.dev` device, so we cannot use dev_* consistently. See: http://lists.infradead.org/pipermail/linux-mtd/2011-July/036950.html Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 0d2eaa72288f..76f496d2bfed 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -205,10 +205,10 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, res = mtd->read(mtd, from, len, &retlen, buf); if (res < 0) { if (retlen != len) { - printk(KERN_INFO "nand_bbt: Error reading bad block table\n"); + pr_info("nand_bbt: Error reading bad block table\n"); return res; } - printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); + pr_warn("nand_bbt: ECC error while reading bad block table\n"); } /* Analyse data */ @@ -219,7 +219,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, if (tmp == msk) continue; if (reserved_block_code && (tmp == reserved_block_code)) { - printk(KERN_INFO "nand_read_bbt: Reserved block at 0x%012llx\n", + pr_info("nand_read_bbt: Reserved block at 0x%012llx\n", (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); mtd->ecc_stats.bbtblocks++; @@ -229,7 +229,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, * Leave it for now, if it's matured we can * move this message to pr_debug. */ - printk(KERN_INFO "nand_read_bbt: Bad block at 0x%012llx\n", + pr_info("nand_read_bbt: Bad block at 0x%012llx\n", (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); /* Factory marked bad or worn out? */ if (tmp == 0) @@ -389,7 +389,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift, mtd->writesize, td); td->version[0] = buf[bbt_get_ver_offs(mtd, td)]; - printk(KERN_INFO "Bad block table at page %d, version 0x%02X\n", + pr_info("Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); } @@ -398,7 +398,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift, mtd->writesize, td); md->version[0] = buf[bbt_get_ver_offs(mtd, md)]; - printk(KERN_INFO "Bad block table at page %d, version 0x%02X\n", + pr_info("Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); } return 1; @@ -473,7 +473,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, loff_t from; size_t readlen; - printk(KERN_INFO "Scanning device for bad blocks\n"); + pr_info("Scanning device for bad blocks\n"); if (bd->options & NAND_BBT_SCANALLPAGES) len = 1 << (this->bbt_erase_shift - this->page_shift); @@ -502,7 +502,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, from = 0; } else { if (chip >= this->numchips) { - printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", + pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n", chip + 1, this->numchips); return -EINVAL; } @@ -531,7 +531,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, if (ret) { this->bbt[i >> 3] |= 0x03 << (i & 0x6); - printk(KERN_WARNING "Bad eraseblock %d at 0x%012llx\n", + pr_warn("Bad eraseblock %d at 0x%012llx\n", i >> 1, (unsigned long long)from); mtd->ecc_stats.badblocks++; } @@ -614,9 +614,9 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr /* Check, if we found a bbt for each requested chip */ for (i = 0; i < chips; i++) { if (td->pages[i] == -1) - printk(KERN_WARNING "Bad block table not found for chip %d\n", i); + pr_warn("Bad block table not found for chip %d\n", i); else - printk(KERN_INFO "Bad block table found at page %d, version 0x%02X\n", td->pages[i], + pr_info("Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); } return 0; @@ -730,7 +730,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (!md || md->pages[chip] != page) goto write; } - printk(KERN_ERR "No space left to write bad block table\n"); + pr_err("No space left to write bad block table\n"); return -ENOSPC; write: @@ -765,12 +765,12 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, res = mtd->read(mtd, to, len, &retlen, buf); if (res < 0) { if (retlen != len) { - printk(KERN_INFO "nand_bbt: Error " + pr_info("nand_bbt: Error " "reading block for writing " "the bad block table\n"); return res; } - printk(KERN_WARNING "nand_bbt: ECC error " + pr_warn("nand_bbt: ECC error " "while reading block for writing " "bad block table\n"); } @@ -847,7 +847,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (res < 0) goto outerr; - printk(KERN_INFO "Bad block table written to 0x%012llx, version " + pr_info("Bad block table written to 0x%012llx, version " "0x%02X\n", (unsigned long long)to, td->version[chip]); /* Mark it as used */ @@ -1137,7 +1137,7 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) */ if (!td) { if ((res = nand_memory_bbt(mtd, bd))) { - printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n"); + pr_err("nand_bbt: Can't scan flash and build the RAM-based BBT\n"); kfree(this->bbt); this->bbt = NULL; } @@ -1305,7 +1305,7 @@ static int nand_create_default_bbt_descr(struct nand_chip *this) { struct nand_bbt_descr *bd; if (this->badblock_pattern) { - printk(KERN_WARNING "BBT descr already allocated; not replacing.\n"); + pr_warn("BBT descr already allocated; not replacing.\n"); return -EINVAL; } bd = kzalloc(sizeof(*bd), GFP_KERNEL); -- cgit v1.2.1 From d037021953922ebdbc34b98b8c4648017b1c6e89 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 19 Jul 2011 10:06:08 -0700 Subject: mtd: nand: style fixups in pr_* messages This is a cleanup of some punctuation, indentation, and capitalization on the lines affected affected by the last patch. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 76f496d2bfed..dba332327d4f 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -205,7 +205,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, res = mtd->read(mtd, from, len, &retlen, buf); if (res < 0) { if (retlen != len) { - pr_info("nand_bbt: Error reading bad block table\n"); + pr_info("nand_bbt: error reading bad block table\n"); return res; } pr_warn("nand_bbt: ECC error while reading bad block table\n"); @@ -219,8 +219,8 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, if (tmp == msk) continue; if (reserved_block_code && (tmp == reserved_block_code)) { - pr_info("nand_read_bbt: Reserved block at 0x%012llx\n", - (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); + pr_info("nand_read_bbt: reserved block at 0x%012llx\n", + (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); mtd->ecc_stats.bbtblocks++; continue; @@ -229,8 +229,8 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, * Leave it for now, if it's matured we can * move this message to pr_debug. */ - pr_info("nand_read_bbt: Bad block at 0x%012llx\n", - (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); + pr_info("nand_read_bbt: bad block at 0x%012llx\n", + (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); /* Factory marked bad or worn out? */ if (tmp == 0) this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); @@ -390,7 +390,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, mtd->writesize, td); td->version[0] = buf[bbt_get_ver_offs(mtd, td)]; pr_info("Bad block table at page %d, version 0x%02X\n", - td->pages[0], td->version[0]); + td->pages[0], td->version[0]); } /* Read the mirror version, if available */ @@ -399,7 +399,7 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, mtd->writesize, td); md->version[0] = buf[bbt_get_ver_offs(mtd, md)]; pr_info("Bad block table at page %d, version 0x%02X\n", - md->pages[0], md->version[0]); + md->pages[0], md->version[0]); } return 1; } @@ -532,7 +532,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, if (ret) { this->bbt[i >> 3] |= 0x03 << (i & 0x6); pr_warn("Bad eraseblock %d at 0x%012llx\n", - i >> 1, (unsigned long long)from); + i >> 1, (unsigned long long)from); mtd->ecc_stats.badblocks++; } @@ -616,8 +616,8 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr if (td->pages[i] == -1) pr_warn("Bad block table not found for chip %d\n", i); else - pr_info("Bad block table found at page %d, version 0x%02X\n", td->pages[i], - td->version[i]); + pr_info("Bad block table found at page %d, version " + "0x%02X\n", td->pages[i], td->version[i]); } return 0; } @@ -765,14 +765,12 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, res = mtd->read(mtd, to, len, &retlen, buf); if (res < 0) { if (retlen != len) { - pr_info("nand_bbt: Error " - "reading block for writing " - "the bad block table\n"); + pr_info("nand_bbt: error reading block " + "for writing the bad block table\n"); return res; } - pr_warn("nand_bbt: ECC error " - "while reading block for writing " - "bad block table\n"); + 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; @@ -847,8 +845,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (res < 0) goto outerr; - pr_info("Bad block table written to 0x%012llx, version " - "0x%02X\n", (unsigned long long)to, td->version[chip]); + pr_info("Bad block table written to 0x%012llx, version 0x%02X\n", + (unsigned long long)to, td->version[chip]); /* Mark it as used */ td->pages[chip] = page; @@ -856,8 +854,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, return 0; outerr: - printk(KERN_WARNING - "nand_bbt: Error while writing bad block table %d\n", res); + pr_warn("nand_bbt: error while writing bad block table %d\n", res); return res; } @@ -1137,7 +1134,7 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) */ if (!td) { if ((res = nand_memory_bbt(mtd, bd))) { - pr_err("nand_bbt: Can't scan flash and build the RAM-based BBT\n"); + pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n"); kfree(this->bbt); this->bbt = NULL; } @@ -1305,7 +1302,7 @@ static int nand_create_default_bbt_descr(struct nand_chip *this) { struct nand_bbt_descr *bd; if (this->badblock_pattern) { - pr_warn("BBT descr already allocated; not replacing.\n"); + pr_warn("BBT descr already allocated; not replacing\n"); return -EINVAL; } bd = kzalloc(sizeof(*bd), GFP_KERNEL); -- cgit v1.2.1 From 289c05222172b51401dbbb017115655f241d94ab Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 19 Jul 2011 10:06:09 -0700 Subject: mtd: replace DEBUG() with pr_debug() Start moving away from the MTD_DEBUG_LEVEL messages. The dynamic debugging feature is a generic kernel feature that provides more flexibility. (See Documentation/dynamic-debug-howto.txt) Also fix some punctuation, indentation, and capitalization that went along with the affected lines. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index dba332327d4f..6aa8125772b8 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -1383,8 +1383,9 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) block = (int)(offs >> (this->bbt_erase_shift - 1)); res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; - DEBUG(MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", - (unsigned int)offs, block >> 1, res); + pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: " + "(block %d) 0x%02x\n", + (unsigned int)offs, block >> 1, res); switch ((int)res) { case 0x00: -- cgit v1.2.1 From 0612b9ddc2eeda014dd805c87c752b342d8f80f0 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 30 Aug 2011 18:45:40 -0700 Subject: mtd: rename MTD_OOB_* to MTD_OPS_* These modes are not necessarily for OOB only. Particularly, MTD_OOB_RAW affected operations on in-band page data as well. To clarify these options and to emphasize that their effect is applied per-operation, we change the primary prefix to MTD_OPS_. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 6aa8125772b8..c488bcb84c90 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -302,7 +302,7 @@ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs, struct mtd_oob_ops ops; int res; - ops.mode = MTD_OOB_RAW; + ops.mode = MTD_OPS_RAW; ops.ooboffs = 0; ops.ooblen = mtd->oobsize; @@ -350,7 +350,7 @@ static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len, { struct mtd_oob_ops ops; - ops.mode = MTD_OOB_PLACE; + ops.mode = MTD_OPS_PLACE_OOB; ops.ooboffs = 0; ops.ooblen = mtd->oobsize; ops.datbuf = buf; @@ -433,7 +433,7 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, ops.oobbuf = buf; ops.ooboffs = 0; ops.datbuf = NULL; - ops.mode = MTD_OOB_PLACE; + ops.mode = MTD_OPS_PLACE_OOB; for (j = 0; j < len; j++) { /* @@ -672,7 +672,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, ops.ooblen = mtd->oobsize; ops.ooboffs = 0; ops.datbuf = NULL; - ops.mode = MTD_OOB_PLACE; + ops.mode = MTD_OPS_PLACE_OOB; if (!rcode) rcode = 0xff; -- cgit v1.2.1 From 105513cc4a25522f959788371bd612f987d4d184 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 7 Sep 2011 13:13:28 -0700 Subject: mtd: nand: refactor scanning code A few pieces of code are unnecessarily duplicated. For easier maintenance, we should fix this. This should have no functional effect. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index c488bcb84c90..cbf9b695c6f2 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -306,28 +306,16 @@ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs, ops.ooboffs = 0; ops.ooblen = mtd->oobsize; - while (len > 0) { - if (len <= mtd->writesize) { - ops.oobbuf = buf + len; - ops.datbuf = buf; - ops.len = len; - res = mtd->read_oob(mtd, offs, &ops); - - /* Ignore ECC errors when checking for BBM */ - if (res != -EUCLEAN && res != -EBADMSG) - return res; - return 0; - } else { - ops.oobbuf = buf + mtd->writesize; - ops.datbuf = buf; - ops.len = mtd->writesize; - res = mtd->read_oob(mtd, offs, &ops); + ops.datbuf = buf; + ops.len = min(len, (size_t)mtd->writesize); + ops.oobbuf = buf + ops.len; - /* Ignore ECC errors when checking for BBM */ - if (res && res != -EUCLEAN && res != -EBADMSG) - return res; - } + res = mtd->read_oob(mtd, offs, &ops); + + /* Ignore ECC errors when checking for BBM */ + if (res && res != -EUCLEAN && res != -EBADMSG) + return res; buf += mtd->oobsize + mtd->writesize; len -= mtd->writesize; -- cgit v1.2.1 From afa17de262633603dd65f89e9370f48e56b8c557 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 7 Sep 2011 13:13:29 -0700 Subject: mtd: nand: do not ignore all ECC errors There are a few reasons not to ignore ECC errors here. First, mtd->read_oob is being called in raw mode, so there should be no error correction in the first place. Second, if we change this such that there *is* error correction in this function, then we will want to pass the error message upward. In fact, the code I introduced to "ignore ECC errors" would have been better if it had just placed this test down in `scan_block_full()' in the first place. We would like to ignore ECC errors when we are simply checking for bad block markers (e.g., factory marked), but we may not want to ignore ECC errors when scanning OOB for a flash-based BBT pattern (in `scan_read_raw()'; note that the return codes from `scan_read_raw()' are not actually handled yet). Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index cbf9b695c6f2..fcfaf06beaaf 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -313,8 +313,7 @@ static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs, res = mtd->read_oob(mtd, offs, &ops); - /* Ignore ECC errors when checking for BBM */ - if (res && res != -EUCLEAN && res != -EBADMSG) + if (res) return res; buf += mtd->oobsize + mtd->writesize; @@ -400,7 +399,8 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, int ret, j; ret = scan_read_raw_oob(mtd, buf, offs, readlen); - if (ret) + /* Ignore ECC errors when checking for BBM */ + if (ret && ret != -EUCLEAN && ret != -EBADMSG) return ret; for (j = 0; j < len; j++, buf += scanlen) { -- cgit v1.2.1 From 1196ac5a9969f180c67e9a4454384250ab034452 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 7 Sep 2011 13:13:32 -0700 Subject: mtd: nand: remove unnecessary variable `writeops' is unnecessary in the function `nand_update_bbt()' Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index fcfaf06beaaf..c1074ac9bdac 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -1171,7 +1171,7 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) int nand_update_bbt(struct mtd_info *mtd, loff_t offs) { struct nand_chip *this = mtd->priv; - int len, res = 0, writeops = 0; + int len, res = 0; int chip, chipsel; uint8_t *buf; struct nand_bbt_descr *td = this->bbt_td; @@ -1187,8 +1187,6 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) if (!buf) return -ENOMEM; - writeops = md != NULL ? 0x03 : 0x01; - /* Do we have a bbt per chip? */ if (td->options & NAND_BBT_PERCHIP) { chip = (int)(offs >> this->chip_shift); @@ -1203,13 +1201,13 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) md->version[chip]++; /* Write the bad block table to the device? */ - if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { + if (td->options & NAND_BBT_WRITE) { res = write_bbt(mtd, buf, td, md, chipsel); if (res < 0) goto out; } /* Write the mirror bad block table to the device? */ - if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { + if (md && (md->options & NAND_BBT_WRITE)) { res = write_bbt(mtd, buf, md, td, chipsel); } -- cgit v1.2.1 From 596d74527a804418d88e1178c9d72aff5649e89c Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 7 Sep 2011 13:13:33 -0700 Subject: mtd: nand: fix style Remove some extra spaces Consistently use '0x' prefix for bitfield-like constants Spelling: "aplies" -> "applies" Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index c1074ac9bdac..e962167c9b71 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -183,16 +183,16 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, size_t retlen, len, totlen; loff_t from; int bits = td->options & NAND_BBT_NRBITS_MSK; - uint8_t msk = (uint8_t) ((1 << bits) - 1); + uint8_t msk = (uint8_t)((1 << bits) - 1); u32 marker_len; int reserved_block_code = td->reserved_block_code; totlen = (num * bits) >> 3; marker_len = add_marker_len(td); - from = ((loff_t) page) << this->page_shift; + from = ((loff_t)page) << this->page_shift; while (totlen) { - len = min(totlen, (size_t) (1 << this->bbt_erase_shift)); + len = min(totlen, (size_t)(1 << this->bbt_erase_shift)); if (marker_len) { /* * In case the BBT marker is not in the OOB area it @@ -250,7 +250,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, * @mtd: MTD device structure * @buf: temporary buffer * @td: descriptor for the bad block table - * @chip: read the table for a specific chip, -1 read all chips; aplies only if + * @chip: read the table for a specific chip, -1 read all chips; applies only if * NAND_BBT_PERCHIP option is set * * Read the bad block table for all chips starting at a given page. We assume @@ -743,12 +743,12 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, bbtoffs = chip * (numblocks >> 2); - to = ((loff_t) page) << this->page_shift; + to = ((loff_t)page) << this->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)); + to &= ~((loff_t)((1 << this->bbt_erase_shift) - 1)); len = 1 << this->bbt_erase_shift; res = mtd->read(mtd, to, len, &retlen, buf); if (res < 0) { @@ -771,7 +771,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, pageoffs = page - (int)(to >> this->page_shift); offs = pageoffs << this->page_shift; /* Preset the bbt area with 0xff */ - memset(&buf[offs], 0xff, (size_t) (numblocks >> sft)); + memset(&buf[offs], 0xff, (size_t)(numblocks >> sft)); ooboffs = len + (pageoffs * mtd->oobsize); } else if (td->options & NAND_BBT_NO_OOB) { @@ -781,7 +781,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, if (td->options & NAND_BBT_VERSION) offs++; /* Calc length */ - len = (size_t) (numblocks >> sft); + len = (size_t)(numblocks >> sft); len += offs; /* Make it page aligned! */ len = ALIGN(len, mtd->writesize); @@ -791,7 +791,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, memcpy(buf, td->pattern, td->len); } else { /* Calc length */ - len = (size_t) (numblocks >> sft); + len = (size_t)(numblocks >> sft); /* Make it page aligned! */ len = ALIGN(len, mtd->writesize); /* Preset the buffer with 0xff */ @@ -903,14 +903,14 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc if (td->pages[i] == -1) { rd = md; td->version[i] = md->version[i]; - writeops = 1; + writeops = 0x01; goto writecheck; } if (md->pages[i] == -1) { rd = td; md->version[i] = td->version[i]; - writeops = 2; + writeops = 0x02; goto writecheck; } @@ -921,14 +921,14 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc goto writecheck; } - if (((int8_t) (td->version[i] - md->version[i])) > 0) { + if (((int8_t)(td->version[i] - md->version[i])) > 0) { rd = td; md->version[i] = td->version[i]; - writeops = 2; + writeops = 0x02; } else { rd = md; td->version[i] = md->version[i]; - writeops = 1; + writeops = 0x01; } goto writecheck; -- cgit v1.2.1 From c5e8ef9c21a492f1e0436b350bbc3e916f93e506 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 7 Sep 2011 13:13:34 -0700 Subject: mtd: nand: begin restructuring check_create We will begin restructuring the code for check_create so that we can make some important changes. For now, we should just begin to get rid of some goto statements to make things cleaner. This is the first step of a few, which are separated to make them easier to follow. This step should just be a code refactor. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index e962167c9b71..42b523a84fc6 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -898,30 +898,19 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc if (td->pages[i] == -1 && md->pages[i] == -1) { writeops = 0x03; goto create; - } - - if (td->pages[i] == -1) { + } else if (td->pages[i] == -1) { rd = md; td->version[i] = md->version[i]; writeops = 0x01; - goto writecheck; - } - - if (md->pages[i] == -1) { + } else if (md->pages[i] == -1) { rd = td; md->version[i] = td->version[i]; writeops = 0x02; - goto writecheck; - } - - if (td->version[i] == md->version[i]) { + } else if (td->version[i] == md->version[i]) { rd = td; if (!(td->options & NAND_BBT_VERSION)) rd2 = md; - goto writecheck; - } - - if (((int8_t)(td->version[i] - md->version[i])) > 0) { + } else if (((int8_t)(td->version[i] - md->version[i])) > 0) { rd = td; md->version[i] = td->version[i]; writeops = 0x02; @@ -930,17 +919,14 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc td->version[i] = md->version[i]; writeops = 0x01; } - - goto writecheck; - } else { if (td->pages[i] == -1) { writeops = 0x01; goto create; } rd = td; - goto writecheck; } + goto writecheck; create: /* Create the bad block table by scanning the device? */ if (!(td->options & NAND_BBT_CREATE)) -- cgit v1.2.1 From b61bf5bbf619fc66ca866a27038da0b91cafb92d Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 7 Sep 2011 13:13:35 -0700 Subject: mtd: nand: remove gotos in `check_create()' This is a second step in restructuring `check_create()'. When we don't rely on goto statements for our main functionality, the code will become a little easier to manipulate. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 42b523a84fc6..7dbfce4a1a5b 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -875,7 +875,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b */ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) { - int i, chips, writeops, chipsel, res; + int i, chips, writeops, create, chipsel, res; struct nand_chip *this = mtd->priv; struct nand_bbt_descr *td = this->bbt_td; struct nand_bbt_descr *md = this->bbt_md; @@ -889,6 +889,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc for (i = 0; i < chips; i++) { writeops = 0; + create = 0; rd = NULL; rd2 = NULL; /* Per chip or per device? */ @@ -896,8 +897,8 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc /* Mirrored table available? */ if (md) { if (td->pages[i] == -1 && md->pages[i] == -1) { + create = 1; writeops = 0x03; - goto create; } else if (td->pages[i] == -1) { rd = md; td->version[i] = md->version[i]; @@ -921,25 +922,27 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc } } else { if (td->pages[i] == -1) { + create = 1; writeops = 0x01; - goto create; + } else { + rd = td; } - rd = td; } - goto writecheck; - create: - /* Create the bad block table by scanning the device? */ - if (!(td->options & NAND_BBT_CREATE)) - continue; - /* Create the table in memory by scanning the chip(s) */ - if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY)) - create_bbt(mtd, buf, bd, chipsel); + if (create) { + /* Create the bad block table by scanning the device? */ + if (!(td->options & NAND_BBT_CREATE)) + continue; + + /* Create the table in memory by scanning the chip(s) */ + if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY)) + create_bbt(mtd, buf, bd, chipsel); + + td->version[i] = 1; + if (md) + md->version[i] = 1; + } - td->version[i] = 1; - if (md) - md->version[i] = 1; - writecheck: /* Read back first? */ if (rd) read_abs_bbt(mtd, buf, rd, chipsel); -- cgit v1.2.1 From d57f40544a41fdfe90fd863b6865138c5a82f1cc Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 20 Sep 2011 18:34:25 -0700 Subject: mtd: utilize `mtd_is_*()' functions Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 7dbfce4a1a5b..584bdcb3c61a 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -400,7 +400,7 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, ret = scan_read_raw_oob(mtd, buf, offs, readlen); /* Ignore ECC errors when checking for BBM */ - if (ret && ret != -EUCLEAN && ret != -EBADMSG) + if (ret && !mtd_is_bitflip_or_eccerr(ret)) return ret; for (j = 0; j < len; j++, buf += scanlen) { @@ -430,7 +430,7 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, */ ret = mtd->read_oob(mtd, offs, &ops); /* Ignore ECC errors when checking for BBM */ - if (ret && ret != -EUCLEAN && ret != -EBADMSG) + if (ret && !mtd_is_bitflip_or_eccerr(ret)) return ret; if (check_short_pattern(buf, bd)) -- cgit v1.2.1 From 167a8d52509a0f7d6728a79e2588b800e866c147 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 20 Sep 2011 18:35:08 -0700 Subject: mtd: nand: report ECC errors properly when reading BBT Instead of just printing a warning when encountering ECC errors, we should return a proper error status and print a more informative warning. Later, we will handle these error messages in the upper layers of the BBT scan. Note that this patch makes our check for ECC error codes a little bit more restrictive, leaving all unrecognized errors to the generic "else" clause. This shouldn't cause problems and could even be a benefit. This code is based on some findings reported by Matthieu Castet. Reported-by: Matthieu CASTET Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 584bdcb3c61a..0ed8591dbd26 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -178,7 +178,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td) static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, struct nand_bbt_descr *td, int offs) { - int res, i, j, act = 0; + int res, ret = 0, i, j, act = 0; struct nand_chip *this = mtd->priv; size_t retlen, len, totlen; loff_t from; @@ -204,11 +204,18 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, } res = mtd->read(mtd, from, len, &retlen, buf); if (res < 0) { - if (retlen != len) { - pr_info("nand_bbt: error reading bad block table\n"); + if (mtd_is_eccerr(res)) { + pr_info("nand_bbt: ECC error in BBT at " + "0x%012llx\n", from & ~mtd->writesize); + return res; + } else if (mtd_is_bitflip(res)) { + pr_info("nand_bbt: corrected error in BBT at " + "0x%012llx\n", from & ~mtd->writesize); + ret = res; + } else { + pr_info("nand_bbt: error reading BBT\n"); return res; } - pr_warn("nand_bbt: ECC error while reading bad block table\n"); } /* Analyse data */ @@ -242,7 +249,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, totlen -= len; from += len; } - return 0; + return ret; } /** -- cgit v1.2.1 From 623978de362a5faeb18d8395fa86089650642626 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 20 Sep 2011 18:35:34 -0700 Subject: mtd: nand: scrub BBT on ECC errors Now that `read_bbt()' returns ECC error codes properly, we handle those codes when checking the integrity of our flash-based BBT. The modifications can be described by this new policy: *) On any uncorrected ECC error, we invalidate the corresponding table and retry our version-checking integrity logic. *) On corrected bitflips, we mark both tables for re-writing to flash (a.k.a. scrubbing). Current integrity checks (i.e., comparing version numbers, etc.) should take care of all the cases that result in rescanning the device for bad blocks or falling back to the BBT as found in the mirror descriptor. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 0ed8591dbd26..11185aa6273c 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -882,7 +882,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b */ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) { - int i, chips, writeops, create, chipsel, res; + int i, chips, writeops, create, chipsel, res, res2; struct nand_chip *this = mtd->priv; struct nand_bbt_descr *td = this->bbt_td; struct nand_bbt_descr *md = this->bbt_md; @@ -899,6 +899,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc create = 0; rd = NULL; rd2 = NULL; + res = res2 = 0; /* Per chip or per device? */ chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; /* Mirrored table available? */ @@ -951,11 +952,29 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc } /* Read back first? */ - if (rd) - read_abs_bbt(mtd, buf, rd, chipsel); + if (rd) { + res = read_abs_bbt(mtd, buf, rd, chipsel); + if (mtd_is_eccerr(res)) { + /* Mark table as invalid */ + rd->pages[i] = -1; + i--; + continue; + } + } /* If they weren't versioned, read both */ - if (rd2) - read_abs_bbt(mtd, buf, rd2, chipsel); + if (rd2) { + res2 = read_abs_bbt(mtd, buf, rd2, chipsel); + if (mtd_is_eccerr(res2)) { + /* Mark table as invalid */ + rd2->pages[i] = -1; + i--; + continue; + } + } + + /* Scrub the flash table(s)? */ + if (mtd_is_bitflip(res) || mtd_is_bitflip(res2)) + writeops = 0x03; /* Write the bad block table to the device? */ if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { -- cgit v1.2.1 From dadc17a3e34810ed411a62e6b4cafdf3e5e1d5c8 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 20 Sep 2011 18:35:57 -0700 Subject: mtd: nand: wait to set BBT version Because there are so many cases of checking, writing, and re-writing of the bad block table(s), we might as well wait until the we've settled on a valid, clean copy of the table. This also prevents us from falsely incrementing the table version. For example, we may have the following: Primary table, with version 0x02 Mirror table, with version 0x01 Primary table has uncorrectable ECC errors If we don't have this fix applied, then we will: Choose to read the primary table (higher version) Set mirror table version to 0x02 Read back primary table Invalidate table because of ECC errors Retry readback operation with mirror table, now version 0x02 Mirrored table reads cleanly Writeback BBT to primary table location (with "version 0x02") However, the mirrored table shouldn't have a new version number. Instead, we actually want: Choose to read the primary table (higher version) Read back primary table Invalidate table because of ECC errors Retry readback with mirror table (version 0x01) Mirrored table reads cleanly Set both tables to version 0x01 Writeback BBT to primary table location (version 0x01) Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 11185aa6273c..e7976c7a7bb0 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -909,11 +909,9 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc writeops = 0x03; } else if (td->pages[i] == -1) { rd = md; - td->version[i] = md->version[i]; writeops = 0x01; } else if (md->pages[i] == -1) { rd = td; - md->version[i] = td->version[i]; writeops = 0x02; } else if (td->version[i] == md->version[i]) { rd = td; @@ -921,11 +919,9 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc rd2 = md; } else if (((int8_t)(td->version[i] - md->version[i])) > 0) { rd = td; - md->version[i] = td->version[i]; writeops = 0x02; } else { rd = md; - td->version[i] = md->version[i]; writeops = 0x01; } } else { @@ -957,6 +953,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc if (mtd_is_eccerr(res)) { /* Mark table as invalid */ rd->pages[i] = -1; + rd->version[i] = 0; i--; continue; } @@ -967,6 +964,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc if (mtd_is_eccerr(res2)) { /* Mark table as invalid */ rd2->pages[i] = -1; + rd2->version[i] = 0; i--; continue; } @@ -976,6 +974,12 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc if (mtd_is_bitflip(res) || mtd_is_bitflip(res2)) writeops = 0x03; + /* Update version numbers before writing */ + if (md) { + td->version[i] = max(td->version[i], md->version[i]); + md->version[i] = td->version[i]; + } + /* Write the bad block table to the device? */ if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { res = write_bbt(mtd, buf, td, md, chipsel); -- cgit v1.2.1 From 752ed6c5f8c0ee182219ff8682f5a98e47ee866f Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 20 Sep 2011 18:36:42 -0700 Subject: mtd: nand: do not scan bad blocks with NAND_BBT_NO_OOB set Updates to our default function for creating bad block patterns have broken the "no OOB" feature. The NAND_BBT_NO_OOB option should not be set while scanning for bad blocks, but we've been passing all BBT options from nand_chip.bbt_options to the bad block scan. This causes us to hit the: BUG_ON(bd->options & NAND_BBT_NO_OOB); in create_bbt() when we scan the flash for bad blocks. Thus, while it can be legal to set NAND_BBT_NO_OOB in a custom badblock pattern descriptor (presumably with NAND_BBT_CREATE disabled?), we should not pass it through in our default function. Also, to help clarify and emphasize that the function creates bad block patterns only (not, for example, table descriptors for locating flash-based BBT), I renamed `nand_create_default_bbt_descr' to `nand_create_badblock_pattern'. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index e7976c7a7bb0..783093d1a2e5 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -1294,26 +1294,27 @@ static struct nand_bbt_descr bbt_mirror_no_bbt_descr = { .pattern = mirror_pattern }; +#define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB) /** - * nand_create_default_bbt_descr - [INTERN] Creates a BBT descriptor structure + * 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 + * 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_default_bbt_descr(struct nand_chip *this) +static int nand_create_badblock_pattern(struct nand_chip *this) { struct nand_bbt_descr *bd; if (this->badblock_pattern) { - pr_warn("BBT descr already allocated; not replacing\n"); + 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; + 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; @@ -1367,7 +1368,7 @@ int nand_default_bbt(struct mtd_info *mtd) } if (!this->badblock_pattern) - nand_create_default_bbt_descr(this); + nand_create_badblock_pattern(this); return nand_scan_bbt(mtd, this->badblock_pattern); } -- cgit v1.2.1 From 75b66d8ccd5772b00a7328c2cf75bc506ec532a1 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 7 Sep 2011 13:13:41 -0700 Subject: mtd: nand: switch `check_pattern()' to standard `memcmp()' A portion of the `check_pattern()' function is basically a `memcmp()'. Since it's possible for `memcmp()' to be optimized for a particular architecture, we should use it instead. Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_bbt.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/mtd/nand/nand_bbt.c') diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 783093d1a2e5..5c9c0b2f09d4 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -107,10 +107,8 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc p += end; /* Compare the pattern */ - for (i = 0; i < td->len; i++) { - if (p[i] != td->pattern[i]) - return -1; - } + if (memcmp(p, td->pattern, td->len)) + return -1; if (td->options & NAND_BBT_SCANEMPTY) { p += td->len; -- cgit v1.2.1