patch-2.4.21 linux-2.4.21/drivers/mtd/mtdchar.c
Next file: linux-2.4.21/drivers/mtd/mtdconcat.c
Previous file: linux-2.4.21/drivers/mtd/mtdblock_ro.c
Back to the patch index
Back to the overall index
- Lines: 130
- Date:
2003-06-13 07:51:34.000000000 -0700
- Orig file:
linux-2.4.20/drivers/mtd/mtdchar.c
- Orig date:
2001-10-04 15:14:59.000000000 -0700
diff -urN linux-2.4.20/drivers/mtd/mtdchar.c linux-2.4.21/drivers/mtd/mtdchar.c
@@ -1,5 +1,5 @@
/*
- * $Id: mtdchar.c,v 1.44 2001/10/02 15:05:11 dwmw2 Exp $
+ * $Id: mtdchar.c,v 1.49 2003/01/24 12:02:58 dwmw2 Exp $
*
* Character-device access to raw MTD devices.
* Pure 2.4 version - compatibility cruft removed to mtdchar-compat.c
@@ -60,7 +60,7 @@
static int mtd_open(struct inode *inode, struct file *file)
{
- int minor = MINOR(inode->i_rdev);
+ int minor = minor(inode->i_rdev);
int devnum = minor >> 1;
struct mtd_info *mtd;
@@ -287,7 +287,12 @@
case MEMERASE:
{
- struct erase_info *erase=kmalloc(sizeof(struct erase_info),GFP_KERNEL);
+ struct erase_info *erase;
+
+ if(!(file->f_mode & 2))
+ return -EPERM;
+
+ erase=kmalloc(sizeof(struct erase_info),GFP_KERNEL);
if (!erase)
ret = -ENOMEM;
else {
@@ -338,6 +343,9 @@
void *databuf;
ssize_t retlen;
+ if(!(file->f_mode & 2))
+ return -EPERM;
+
if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf)))
return -EFAULT;
@@ -434,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, 0);
+
+ 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, 0);
+
+ 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);
@@ -474,7 +556,7 @@
sprintf(name, "%dro", mtd->index);
devfs_ro_handle[mtd->index] = devfs_register(devfs_dir_handle, name,
DEVFS_FL_DEFAULT, MTD_CHAR_MAJOR, mtd->index*2+1,
- S_IFCHR | S_IRUGO | S_IWUGO,
+ S_IFCHR | S_IRUGO,
&mtd_fops, NULL);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)