All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthieu CASTET <matthieu.castet@parrot.com>
To: Linux mtd <linux-mtd@lists.infradead.org>
Subject: Re: mtdchar : writing image with oob and NOP=1
Date: Wed, 4 Aug 2010 17:07:48 +0200	[thread overview]
Message-ID: <4C598244.9060901@parrot.com> (raw)
In-Reply-To: <4C56801D.3040300@parrot.com>

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

Matthieu CASTET a écrit :
> Hi,
> 
> We need to write our bootloader with a special ecc (use by cpu rom).
> 
> For that we use MTD_MODE_RAW, write and MEMWRITEOOB. This work fine, but 
> from my understanding this will do a first page program with oob set to 
> 0xff and then program again oob.
> 
> But some recent nand support only 1 program per page (NOP=1).
> How can we program nand with NOP=1 with a custom ecc ?
> 
>  From what I see in mtdchar either datbuf is set (and oobbuf is null) or 
> oobbuf is set (and datbuf is null).
> 
> So this mean we need to add an ioctl to do that ?
> 
For info here what we did for our 2.6.27 kernel.

Matthieu

[-- Attachment #2: memwritepage.diff --]
[-- Type: text/x-diff, Size: 2730 bytes --]

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index e00d424..7621449 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -547,6 +547,84 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
 		break;
 
 	}
+	case MEMWRITEPAGE:
+	{
+		struct mtd_page_buf buf;
+		struct mtd_oob_ops ops;
+		struct mtd_page_buf __user *user_buf = argp;
+	        uint32_t retlen;
+
+		if(!(file->f_mode & 2))
+			return -EPERM;
+
+		if (copy_from_user(&buf, argp, sizeof(struct mtd_page_buf)))
+			return -EFAULT;
+
+		if (buf.length != mtd->writesize || buf.oob_length != mtd->oobsize)
+			return -EINVAL;
+
+		if (!mtd->write_oob)
+			return -EOPNOTSUPP;
+
+		ret = access_ok(VERIFY_READ, buf.ptr,
+					buf.length) ? 0 : EFAULT;
+		if (ret)
+			return ret;
+
+		ret = access_ok(VERIFY_READ, buf.oob_ptr,
+					buf.oob_length) ? 0 : EFAULT;
+		if (ret)
+			return ret;
+
+		ops.ooblen = mtd->oobsize;
+		ops.ooboffs = 0;
+		ops.len = mtd->writesize;
+		ops.mode = MTD_OOB_RAW;
+
+		if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
+			return -EINVAL;
+
+		ops.datbuf = kmalloc(buf.length, GFP_KERNEL);
+		if (!ops.datbuf)
+			return -ENOMEM;
+
+		if (copy_from_user(ops.datbuf, buf.ptr, buf.length)) {
+			kfree(ops.datbuf);
+			return -EFAULT;
+		}
+
+		ops.oobbuf = kmalloc(buf.oob_length, GFP_KERNEL);
+		if (!ops.oobbuf) {
+			kfree(ops.datbuf);
+			return -ENOMEM;
+		}
+
+		if (copy_from_user(ops.oobbuf, buf.oob_ptr, buf.oob_length)) {
+			kfree(ops.datbuf);
+			kfree(ops.oobbuf);
+			return -EFAULT;
+		}
+
+		ret = mtd->write_oob(mtd, buf.start, &ops);
+
+		if (!ret) {
+			retlen = ops.retlen;
+			if (copy_to_user(&user_buf->length, &retlen, sizeof(buf.length)))
+				ret = -EFAULT;
+		}
+
+		if (!ret) {
+			retlen = ops.oobretlen;
+			if (copy_to_user(&user_buf->oob_length, &retlen, sizeof(buf.oob_length)))
+				ret = -EFAULT;
+		}
+
+
+		kfree(ops.datbuf);
+		kfree(ops.oobbuf);
+		break;
+
+	}
 
 	case MEMREADOOB:
 	{
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index c6c61cd..3d9e3bc 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -16,6 +16,13 @@ struct mtd_oob_buf {
 	unsigned char __user *ptr;
 };
 
+struct mtd_page_buf {
+	uint32_t start;
+	uint32_t length;
+	unsigned char __user *ptr;
+	uint32_t oob_length;
+	unsigned char __user *oob_ptr;
+};
 #define MTD_ABSENT		0
 #define MTD_RAM			1
 #define MTD_ROM			2
@@ -93,6 +100,7 @@ struct otp_info {
 #define ECCGETLAYOUT		_IOR('M', 17, struct nand_ecclayout)
 #define ECCGETSTATS		_IOR('M', 18, struct mtd_ecc_stats)
 #define MTDFILEMODE		_IO('M', 19)
+#define MEMWRITEPAGE		_IOWR('M', 30, struct mtd_page_buf)
 
 /*
  * Obsolete legacy interface. Keep it in order not to break userspace

  reply	other threads:[~2010-08-04 15:07 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-02  8:21 mtdchar : writing image with oob and NOP=1 Matthieu CASTET
2010-08-04 15:07 ` Matthieu CASTET [this message]
2010-08-24  8:02 ` Artem Bityutskiy

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=4C598244.9060901@parrot.com \
    --to=matthieu.castet@parrot.com \
    --cc=linux-mtd@lists.infradead.org \
    /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.