diff options
author | Kevin Cernekee <kpc.mtd@gmail.com> | 2009-04-09 01:52:28 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-05-29 10:13:47 -0400 |
commit | 0dc54e9f33e2fbcea28356bc2c8c931cb307d3b3 (patch) | |
tree | c358aa55f18745b12fb9d62629289291b8a80c0b /drivers/mtd | |
parent | 19fe7f1a00023d2aa97617655b7ea56eb72f4db8 (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/mtd')
-rw-r--r-- | drivers/mtd/mtdchar.c | 29 |
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; |