mtd/drivers/mtd mtdchar.c,1.45,1.46
Greg Ungerer
gerg at infradead.org
Fri Sep 20 09:04:05 EDT 2002
Update of /home/cvs/mtd/drivers/mtd
In directory phoenix.infradead.org:/tmp/cvs-serv6100/drivers/mtd
Modified Files:
mtdchar.c
Log Message:
Added new ioctl commands, MEMREADDATA and MEMWRITEDATA, to allow
for non-ecc reads and writes of flash sector data. The commands use
the same arguments as the MEMREADOOB and MEMWRITEOOB ioctls.
Index: mtdchar.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/mtdchar.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- mtdchar.c 16 Jul 2002 16:28:45 -0000 1.45
+++ mtdchar.c 20 Sep 2002 13:04:03 -0000 1.46
@@ -442,6 +442,80 @@
break;
}
+ case MEMWRITEDATA:
+ {
+ struct mtd_oob_buf buf;
+ void *databuf;
+ ssize_t retlen;
+
+ if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf)))
+ return -EFAULT;
+
+ if (buf.length > 0x4096)
+ return -EINVAL;
+
+ if (!mtd->write_ecc)
+ ret = -EOPNOTSUPP;
+ else
+ ret = verify_area(VERIFY_READ, (char *)buf.ptr, buf.length);
+
+ if (ret)
+ return ret;
+
+ databuf = kmalloc(buf.length, GFP_KERNEL);
+ if (!databuf)
+ return -ENOMEM;
+
+ if (copy_from_user(databuf, buf.ptr, buf.length)) {
+ kfree(databuf);
+ return -EFAULT;
+ }
+
+ ret = (mtd->write_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL);
+
+ if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
+ ret = -EFAULT;
+
+ kfree(databuf);
+ break;
+
+ }
+
+ case MEMREADDATA:
+ {
+ struct mtd_oob_buf buf;
+ void *databuf;
+ ssize_t retlen = 0;
+
+ if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf)))
+ return -EFAULT;
+
+ if (buf.length > 0x4096)
+ return -EINVAL;
+
+ if (!mtd->read_ecc)
+ ret = -EOPNOTSUPP;
+ else
+ ret = verify_area(VERIFY_WRITE, (char *)buf.ptr, buf.length);
+
+ if (ret)
+ return ret;
+
+ databuf = kmalloc(buf.length, GFP_KERNEL);
+ if (!databuf)
+ return -ENOMEM;
+
+ ret = (mtd->read_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL);
+
+ if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
+ ret = -EFAULT;
+ else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
+ ret = -EFAULT;
+
+ kfree(databuf);
+ break;
+ }
+
default:
DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO);
More information about the linux-mtd-cvs
mailing list