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