diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-12-18 11:23:39 -0500 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-12-26 12:15:17 -0500 |
commit | 897a316c9e6f7fea6f1d3759797b75c0ebaec479 (patch) | |
tree | 487f211f3a862d8948ba19ca3f645c7a37f4d547 /drivers/mtd/ubi/cdev.c | |
parent | 9b79cc0f84edecceb04b806b9014fcec1306c34d (diff) |
UBI: handle attach ioctl
Actually implement the MTD device attach/detach handlers.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi/cdev.c')
-rw-r--r-- | drivers/mtd/ubi/cdev.c | 95 |
1 files changed, 80 insertions, 15 deletions
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 01978b57e9cb..a60a3a24c2a1 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -44,17 +44,6 @@ | |||
44 | #include <asm/div64.h> | 44 | #include <asm/div64.h> |
45 | #include "ubi.h" | 45 | #include "ubi.h" |
46 | 46 | ||
47 | /* | ||
48 | * Maximum sequence numbers of UBI and volume character device IOCTLs (direct | ||
49 | * logical eraseblock erase is a debug-only feature). | ||
50 | */ | ||
51 | #define UBI_CDEV_IOC_MAX_SEQ 2 | ||
52 | #ifndef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO | ||
53 | #define VOL_CDEV_IOC_MAX_SEQ 1 | ||
54 | #else | ||
55 | #define VOL_CDEV_IOC_MAX_SEQ 2 | ||
56 | #endif | ||
57 | |||
58 | /** | 47 | /** |
59 | * get_exclusive - get exclusive access to an UBI volume. | 48 | * get_exclusive - get exclusive access to an UBI volume. |
60 | * @desc: volume descriptor | 49 | * @desc: volume descriptor |
@@ -582,8 +571,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
582 | struct ubi_mkvol_req req; | 571 | struct ubi_mkvol_req req; |
583 | 572 | ||
584 | dbg_msg("create volume"); | 573 | dbg_msg("create volume"); |
585 | err = copy_from_user(&req, argp, | 574 | err = copy_from_user(&req, argp, sizeof(struct ubi_mkvol_req)); |
586 | sizeof(struct ubi_mkvol_req)); | ||
587 | if (err) { | 575 | if (err) { |
588 | err = -EFAULT; | 576 | err = -EFAULT; |
589 | break; | 577 | break; |
@@ -647,8 +635,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
647 | struct ubi_rsvol_req req; | 635 | struct ubi_rsvol_req req; |
648 | 636 | ||
649 | dbg_msg("re-size volume"); | 637 | dbg_msg("re-size volume"); |
650 | err = copy_from_user(&req, argp, | 638 | err = copy_from_user(&req, argp, sizeof(struct ubi_rsvol_req)); |
651 | sizeof(struct ubi_rsvol_req)); | ||
652 | if (err) { | 639 | if (err) { |
653 | err = -EFAULT; | 640 | err = -EFAULT; |
654 | break; | 641 | break; |
@@ -684,8 +671,86 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
684 | return err; | 671 | return err; |
685 | } | 672 | } |
686 | 673 | ||
674 | static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, | ||
675 | unsigned int cmd, unsigned long arg) | ||
676 | { | ||
677 | int err = 0; | ||
678 | void __user *argp = (void __user *)arg; | ||
679 | |||
680 | if (!capable(CAP_SYS_RESOURCE)) | ||
681 | return -EPERM; | ||
682 | |||
683 | switch (cmd) { | ||
684 | /* Attach an MTD device command */ | ||
685 | case UBI_IOCATT: | ||
686 | { | ||
687 | struct ubi_attach_req req; | ||
688 | struct mtd_info *mtd; | ||
689 | |||
690 | dbg_msg("attach MTD device"); | ||
691 | err = copy_from_user(&req, argp, sizeof(struct ubi_attach_req)); | ||
692 | if (err) { | ||
693 | err = -EFAULT; | ||
694 | break; | ||
695 | } | ||
696 | |||
697 | if (req.mtd_num < 0 || | ||
698 | (req.ubi_num < 0 && req.ubi_num != UBI_DEV_NUM_AUTO)) { | ||
699 | err = -EINVAL; | ||
700 | break; | ||
701 | } | ||
702 | |||
703 | mtd = get_mtd_device(NULL, req.mtd_num); | ||
704 | if (IS_ERR(mtd)) { | ||
705 | err = PTR_ERR(mtd); | ||
706 | break; | ||
707 | } | ||
708 | |||
709 | /* | ||
710 | * Note, further request verification is done by | ||
711 | * 'ubi_attach_mtd_dev()'. | ||
712 | */ | ||
713 | mutex_lock(&ubi_devices_mutex); | ||
714 | err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset); | ||
715 | mutex_unlock(&ubi_devices_mutex); | ||
716 | if (err < 0) | ||
717 | put_mtd_device(mtd); | ||
718 | else | ||
719 | /* @err contains UBI device number */ | ||
720 | err = put_user(err, (__user int32_t *)argp); | ||
721 | |||
722 | break; | ||
723 | } | ||
724 | |||
725 | /* Detach an MTD device command */ | ||
726 | case UBI_IOCDET: | ||
727 | { | ||
728 | int ubi_num; | ||
729 | |||
730 | dbg_msg("dettach MTD device"); | ||
731 | err = get_user(ubi_num, (__user int32_t *)argp); | ||
732 | if (err) { | ||
733 | err = -EFAULT; | ||
734 | break; | ||
735 | } | ||
736 | |||
737 | mutex_lock(&ubi_devices_mutex); | ||
738 | err = ubi_detach_mtd_dev(ubi_num, 0); | ||
739 | mutex_unlock(&ubi_devices_mutex); | ||
740 | break; | ||
741 | } | ||
742 | |||
743 | default: | ||
744 | err = -ENOTTY; | ||
745 | break; | ||
746 | } | ||
747 | |||
748 | return err; | ||
749 | } | ||
750 | |||
687 | /* UBI control character device operations */ | 751 | /* UBI control character device operations */ |
688 | struct file_operations ubi_ctrl_cdev_operations = { | 752 | struct file_operations ubi_ctrl_cdev_operations = { |
753 | .ioctl = ctrl_cdev_ioctl, | ||
689 | .owner = THIS_MODULE, | 754 | .owner = THIS_MODULE, |
690 | }; | 755 | }; |
691 | 756 | ||