aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKevin Cernekee <kpc.mtd@gmail.com>2009-04-09 01:52:28 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-05-29 10:13:47 -0400
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,
417 break; 417 break;
418 418
419 case MEMERASE: 419 case MEMERASE:
420 case MEMERASE64:
420 { 421 {
421 struct erase_info *erase; 422 struct erase_info *erase;
422 423
@@ -427,20 +428,32 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
427 if (!erase) 428 if (!erase)
428 ret = -ENOMEM; 429 ret = -ENOMEM;
429 else { 430 else {
430 struct erase_info_user einfo;
431
432 wait_queue_head_t waitq; 431 wait_queue_head_t waitq;
433 DECLARE_WAITQUEUE(wait, current); 432 DECLARE_WAITQUEUE(wait, current);
434 433
435 init_waitqueue_head(&waitq); 434 init_waitqueue_head(&waitq);
436 435
437 if (copy_from_user(&einfo, argp, 436 if (cmd == MEMERASE64) {
438 sizeof(struct erase_info_user))) { 437 struct erase_info_user64 einfo64;
439 kfree(erase); 438
440 return -EFAULT; 439 if (copy_from_user(&einfo64, argp,
440 sizeof(struct erase_info_user64))) {
441 kfree(erase);
442 return -EFAULT;
443 }
444 erase->addr = einfo64.start;
445 erase->len = einfo64.length;
446 } else {
447 struct erase_info_user einfo32;
448
449 if (copy_from_user(&einfo32, argp,
450 sizeof(struct erase_info_user))) {
451 kfree(erase);
452 return -EFAULT;
453 }
454 erase->addr = einfo32.start;
455 erase->len = einfo32.length;
441 } 456 }
442 erase->addr = einfo.start;
443 erase->len = einfo.length;
444 erase->mtd = mtd; 457 erase->mtd = mtd;
445 erase->callback = mtdchar_erase_callback; 458 erase->callback = mtdchar_erase_callback;
446 erase->priv = (unsigned long)&waitq; 459 erase->priv = (unsigned long)&waitq;