linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* mtdchar : writing image with oob and NOP=1
@ 2010-08-02  8:21 Matthieu CASTET
  2010-08-04 15:07 ` Matthieu CASTET
  2010-08-24  8:02 ` Artem Bityutskiy
  0 siblings, 2 replies; 3+ messages in thread
From: Matthieu CASTET @ 2010-08-02  8:21 UTC (permalink / raw)
  To: Linux mtd

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 ?

Matthieu

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: mtdchar : writing image with oob and NOP=1
  2010-08-02  8:21 mtdchar : writing image with oob and NOP=1 Matthieu CASTET
@ 2010-08-04 15:07 ` Matthieu CASTET
  2010-08-24  8:02 ` Artem Bityutskiy
  1 sibling, 0 replies; 3+ messages in thread
From: Matthieu CASTET @ 2010-08-04 15:07 UTC (permalink / raw)
  To: Linux mtd

[-- 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

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: mtdchar : writing image with oob and NOP=1
  2010-08-02  8:21 mtdchar : writing image with oob and NOP=1 Matthieu CASTET
  2010-08-04 15:07 ` Matthieu CASTET
@ 2010-08-24  8:02 ` Artem Bityutskiy
  1 sibling, 0 replies; 3+ messages in thread
From: Artem Bityutskiy @ 2010-08-24  8:02 UTC (permalink / raw)
  To: Matthieu CASTET; +Cc: Linux mtd

On Mon, 2010-08-02 at 10:21 +0200, Matthieu CASTET wrote:
> 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 ?

Certainly not ioctl. MEMWRITEOOB should handle this and hide from users,
I think.

-- 
Best Regards,
Artem Bityutskiy (Артём Битюцкий)

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-08-24  8:04 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-02  8:21 mtdchar : writing image with oob and NOP=1 Matthieu CASTET
2010-08-04 15:07 ` Matthieu CASTET
2010-08-24  8:02 ` Artem Bityutskiy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).