From: Kyungmin Park <kmpark@infradead.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] OneNAND partial read/write support
Date: Mon, 12 Oct 2009 16:27:10 +0900 [thread overview]
Message-ID: <20091012072710.GA4113@july> (raw)
Now OneNAND handles block operation only.
With this patch OneNAND handles all read/write size.
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
index 9090940..2b8f01b 100644
--- a/common/cmd_onenand.c
+++ b/common/cmd_onenand.c
@@ -36,7 +36,7 @@ static inline int str2long(char *p, ulong *num)
return (*p != '\0' && *endptr == '\0') ? 1 : 0;
}
-static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size)
+static int arg_off_size(int argc, char *argv[], ulong *off, ssize_t *size)
{
if (argc >= 1) {
if (!(str2long(argv[0], off))) {
@@ -69,61 +69,65 @@ static int arg_off_size(int argc, char *argv[], ulong *off, size_t *size)
return 0;
}
-static int onenand_block_read(loff_t from, size_t len,
- size_t *retlen, u_char *buf, int oob)
+static int onenand_block_read(loff_t from, ssize_t len,
+ ssize_t *retlen, u_char *buf, int oob)
{
struct onenand_chip *this = mtd->priv;
- int blocks = (int) len >> this->erase_shift;
int blocksize = (1 << this->erase_shift);
loff_t ofs = from;
struct mtd_oob_ops ops = {
.retlen = 0,
};
+ ssize_t thislen;
int ret;
- if (oob)
- ops.ooblen = blocksize;
- else
- ops.len = blocksize;
+ while (len > 0) {
+ thislen = min_t(ssize_t, len, blocksize);
+ thislen = ALIGN(thislen, mtd->writesize);
- while (blocks) {
ret = mtd->block_isbad(mtd, ofs);
if (ret) {
printk("Bad blocks %d at 0x%x\n",
(u32)(ofs >> this->erase_shift), (u32)ofs);
- ofs += blocksize;
+ ofs += thislen;
continue;
}
- if (oob)
+ if (oob) {
ops.oobbuf = buf;
- else
+ ops.ooblen = thislen;
+ } else {
ops.datbuf = buf;
+ ops.len = thislen;
+ }
ops.retlen = 0;
ret = mtd->read_oob(mtd, ofs, &ops);
if (ret) {
printk("Read failed 0x%x, %d\n", (u32)ofs, ret);
- ofs += blocksize;
+ ofs += thislen;
continue;
}
- ofs += blocksize;
- buf += blocksize;
- blocks--;
+ ofs += thislen;
+ buf += thislen;
+ len -= thislen;
*retlen += ops.retlen;
}
return 0;
}
-static int onenand_block_write(loff_t to, size_t len,
- size_t *retlen, const u_char * buf)
+static int onenand_block_write(loff_t to, ssize_t len,
+ ssize_t *retlen, const u_char * buf)
{
struct onenand_chip *this = mtd->priv;
- int blocks = len >> this->erase_shift;
int blocksize = (1 << this->erase_shift);
+ struct mtd_oob_ops ops = {
+ .retlen = 0,
+ .oobbuf = NULL,
+ };
loff_t ofs;
- size_t _retlen = 0;
+ ssize_t thislen;
int ret;
if (to == next_ofs) {
@@ -135,27 +139,34 @@ static int onenand_block_write(loff_t to, size_t len,
}
ofs = to;
- while (blocks) {
+ while (len > 0) {
+ thislen = min_t(ssize_t, len, blocksize);
+ thislen = ALIGN(thislen, mtd->writesize);
+
ret = mtd->block_isbad(mtd, ofs);
if (ret) {
printk("Bad blocks %d at 0x%x\n",
(u32)(ofs >> this->erase_shift), (u32)ofs);
- skip_ofs += blocksize;
+ skip_ofs += thislen;
goto next;
}
- ret = mtd->write(mtd, ofs, blocksize, &_retlen, buf);
+
+ ops.datbuf = (u_char *) buf;
+ ops.len = thislen;
+ ops.retlen = 0;
+ ret = mtd->write_oob(mtd, ofs, &ops);
if (ret) {
printk("Write failed 0x%x, %d", (u32)ofs, ret);
- skip_ofs += blocksize;
+ skip_ofs += thislen;
goto next;
}
- buf += blocksize;
- blocks--;
- *retlen += _retlen;
+ buf += thislen;
+ len -= thislen;
+ *retlen += ops.retlen;
next:
- ofs += blocksize;
+ ofs += thislen;
}
return 0;
@@ -234,7 +245,7 @@ static int onenand_block_test(u32 start, u32 size)
end_block = mtd->size >> this->erase_shift;
blocks = start_block;
- ofs = start;
+ ofs = start_block << this->erase_shift;
while (blocks < end_block) {
printf("\rTesting block %d@0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs);
@@ -265,9 +276,10 @@ static int onenand_block_test(u32 start, u32 size)
goto next;
}
- if (memcmp(buf, verify_buf, blocksize))
+ if (memcmp(buf, verify_buf, blocksize)) {
printk("\nRead/Write test failed at 0x%x\n", (u32)ofs);
-
+ break;
+ }
next:
ofs += blocksize;
blocks++;
@@ -322,6 +334,7 @@ static int onenand_dump(struct mtd_info *mtd, ulong off, int only_oob)
p += 16;
}
puts("OOB:\n");
+ p = oobbuf;
i = mtd->oobsize >> 3;
while (i--) {
printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
@@ -339,7 +352,7 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
struct onenand_chip *this;
int blocksize;
ulong addr, ofs;
- size_t len, retlen = 0;
+ ssize_t len, retlen = 0;
int ret = 0;
char *cmd, *s;
@@ -385,7 +398,8 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
int erase;
erase = strcmp(cmd, "erase") == 0; /* 1 = erase, 0 = test */
- printf("\nOneNAND %s: ", erase ? "erase" : "test");
+ printf("\nOneNAND %s %s: ", erase ? "erase" : "test",
+ force ? "force" : "");
/* skip first two or three arguments, look for offset and size */
if (arg_off_size(argc - o, argv + o, &ofs, &len) != 0)
next reply other threads:[~2009-10-12 7:27 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-12 7:27 Kyungmin Park [this message]
2009-10-12 8:51 ` [U-Boot] [PATCH] OneNAND partial read/write support Tuma
2009-10-13 1:45 ` Kyungmin Park
2009-10-20 22:48 ` Scott Wood
2009-10-21 0:21 ` Kyungmin Park
2009-10-21 17:06 ` Scott Wood
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20091012072710.GA4113@july \
--to=kmpark@infradead.org \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.