summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKevin Cernekee <kpc.mtd@gmail.com>2009-04-08 22:52:28 -0700
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-05-29 15:13:47 +0100
commit0dc54e9f33e2fbcea28356bc2c8c931cb307d3b3 (patch)
treec358aa55f18745b12fb9d62629289291b8a80c0b /drivers
parent19fe7f1a00023d2aa97617655b7ea56eb72f4db8 (diff)
mtd: add MEMERASE64 ioctl for >4GiB devices
New MEMERASE/MEMREADOOB/MEMWRITEOOB ioctls are needed in order to support 64-bit offsets into large NAND flash devices. Signed-off-by: Kevin Cernekee <kpc.mtd@gmail.com> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/mtdchar.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 763d3f0a1f42..ad4b8618977d 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -417,6 +417,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
break;
case MEMERASE:
+ case MEMERASE64:
{
struct erase_info *erase;
@@ -427,20 +428,32 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
if (!erase)
ret = -ENOMEM;
else {
- struct erase_info_user einfo;
-
wait_queue_head_t waitq;
DECLARE_WAITQUEUE(wait, current);
init_waitqueue_head(&waitq);
- if (copy_from_user(&einfo, argp,
- sizeof(struct erase_info_user))) {
- kfree(erase);
- return -EFAULT;
+ if (cmd == MEMERASE64) {
+ struct erase_info_user64 einfo64;
+
+ if (copy_from_user(&einfo64, argp,
+ sizeof(struct erase_info_user64))) {
+ kfree(erase);
+ return -EFAULT;
+ }
+ erase->addr = einfo64.start;
+ erase->len = einfo64.length;
+ } else {
+ struct erase_info_user einfo32;
+
+ if (copy_from_user(&einfo32, argp,
+ sizeof(struct erase_info_user))) {
+ kfree(erase);
+ return -EFAULT;
+ }
+ erase->addr = einfo32.start;
+ erase->len = einfo32.length;
}
- erase->addr = einfo.start;
- erase->len = einfo.length;
erase->mtd = mtd;
erase->callback = mtdchar_erase_callback;
erase->priv = (unsigned long)&waitq;