diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2013-02-20 11:19:28 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-02-21 08:58:45 +0100 |
commit | 22d747e264d7dacebaaa0d2759e6aace78355f8c (patch) | |
tree | 10f15f91cbdef040057edb6bf9bf62db9c686c53 /drivers | |
parent | 19f8f1166d925277ac463cdceac2ced39ed5602e (diff) | |
download | barebox-22d747e264d7dacebaaa0d2759e6aace78355f8c.tar.gz barebox-22d747e264d7dacebaaa0d2759e6aace78355f8c.tar.xz |
mtd: nand: do not write empty pages
Do not write pages which only contain 0xff. UBI expects pages which
seem empty to be writable. This got lost with:
| commit 3139c3e9a61e70846be8c4f95bb9cffd4465d88a
| Author: Sascha Hauer <s.hauer@pengutronix.de>
| Date: Thu Nov 29 11:16:40 2012 +0100
|
| mtd core: call driver write function with complete buffer
|
| mtd->write is supposed to loop around pages internally, no need
| to do this in mtd_write. This fixes a huge write performance drop
| with the m25p80 driver when it was converted to a mtd driver recently.
| Since mtd->writesize is 1 for this driver mtd_write ended up doing
| single byte writes on the flash.
Introduce mtd_all_ff as a global function since UBI currently has its own
implementation.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/core.c | 32 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_write.c | 10 |
2 files changed, 38 insertions, 4 deletions
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c index 070fda652b..ef985564b5 100644 --- a/drivers/mtd/core.c +++ b/drivers/mtd/core.c @@ -30,6 +30,38 @@ static LIST_HEAD(mtd_register_hooks); +int mtd_all_ff(const void *buf, unsigned int len) +{ + while ((unsigned long)buf & 0x3) { + if (*(const uint8_t *)buf != 0xff) + return 0; + len--; + if (!len) + return 1; + buf++; + } + + while (len > 0x3) { + if (*(const uint32_t *)buf != 0xffffffff) + return 0; + + len -= sizeof(uint32_t); + if (!len) + return 1; + + buf += sizeof(uint32_t); + } + + while (len) { + if (*(const uint8_t *)buf != 0xff) + return 0; + len--; + buf++; + } + + return 1; +} + int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) { if (!mtd->block_isbad) diff --git a/drivers/mtd/nand/nand_write.c b/drivers/mtd/nand/nand_write.c index 12a57a0e4d..cd8ee062a7 100644 --- a/drivers/mtd/nand/nand_write.c +++ b/drivers/mtd/nand/nand_write.c @@ -320,10 +320,12 @@ int nand_do_write_ops(struct mtd_info *mtd, loff_t to, memset(chip->oob_poi, 0xff, mtd->oobsize); } - ret = chip->write_page(mtd, chip, wbuf, page, cached, - (ops->mode == MTD_OOB_RAW)); - if (ret) - break; + if (!mtd_all_ff(wbuf, mtd->writesize)) { + ret = chip->write_page(mtd, chip, wbuf, page, cached, + (ops->mode == MTD_OOB_RAW)); + if (ret) + break; + } writelen -= bytes; if (!writelen) |