summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2009-12-02 17:58:42 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2009-12-03 10:46:48 +0100
commiteb4c1fd6ce7f58e6e2eda485edfda15a296fc8d3 (patch)
tree9297560c3cfcfa983fd2c83f734811d9bcf48385
parentd5a23f01d7a812caa67fd8c2259724e2446d190d (diff)
downloadbarebox-eb4c1fd6ce7f58e6e2eda485edfda15a296fc8d3.tar.gz
barebox-eb4c1fd6ce7f58e6e2eda485edfda15a296fc8d3.tar.xz
nand: do not write empty pages. Needed for writing UBI images
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/nand/nand.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/nand/nand.c b/drivers/nand/nand.c
index f79f7c370f..0a6128caa5 100644
--- a/drivers/nand/nand.c
+++ b/drivers/nand/nand.c
@@ -50,11 +50,22 @@ static ssize_t nand_read(struct cdev *cdev, void* buf, size_t count, ulong offs
#define NOTALIGNED(x) (x & (info->writesize - 1)) != 0
+static int all_ff(const void *buf, int len)
+{
+ int i;
+ const uint8_t *p = buf;
+
+ for (i = 0; i < len; i++)
+ if (p[i] != 0xFF)
+ return 0;
+ return 1;
+}
+
static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count, ulong offset, ulong flags)
{
struct mtd_info *info = cdev->priv;
size_t retlen, now;
- int ret;
+ int ret = 0;
void *wrbuf = NULL;
size_t count = _count;
@@ -73,9 +84,13 @@ static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count, ulo
wrbuf = xmalloc(info->writesize);
memset(wrbuf, 0xff, info->writesize);
memcpy(wrbuf + (offset % info->writesize), buf, now);
- ret = info->write(info, offset & ~(info->writesize - 1), info->writesize, &retlen, wrbuf);
+ if (!all_ff(wrbuf, info->writesize))
+ ret = info->write(info, offset & ~(info->writesize - 1),
+ info->writesize, &retlen, wrbuf);
+ free(wrbuf);
} else {
- ret = info->write(info, offset, now, &retlen, buf);
+ if (!all_ff(buf, info->writesize))
+ ret = info->write(info, offset, now, &retlen, buf);
debug("offset: 0x%08x now: 0x%08x retlen: 0x%08x\n", offset, now, retlen);
}
if (ret)
@@ -87,9 +102,6 @@ static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count, ulo
}
out:
- if (wrbuf)
- free(wrbuf);
-
return ret ? ret : _count;
}