diff options
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r-- | drivers/char/mem.c | 82 |
1 files changed, 40 insertions, 42 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 645237bda682..0491cdf63f2a 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -864,71 +864,67 @@ static const struct file_operations kmsg_fops = { | |||
864 | .write = kmsg_write, | 864 | .write = kmsg_write, |
865 | }; | 865 | }; |
866 | 866 | ||
867 | static const struct { | 867 | static const struct memdev { |
868 | unsigned int minor; | 868 | const char *name; |
869 | char *name; | 869 | const struct file_operations *fops; |
870 | umode_t mode; | 870 | struct backing_dev_info *dev_info; |
871 | const struct file_operations *fops; | 871 | } devlist[] = { |
872 | struct backing_dev_info *dev_info; | 872 | [ 1] = { "mem", &mem_fops, &directly_mappable_cdev_bdi }, |
873 | } devlist[] = { /* list of minor devices */ | ||
874 | {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops, | ||
875 | &directly_mappable_cdev_bdi}, | ||
876 | #ifdef CONFIG_DEVKMEM | 873 | #ifdef CONFIG_DEVKMEM |
877 | {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops, | 874 | [ 2] = { "kmem", &kmem_fops, &directly_mappable_cdev_bdi }, |
878 | &directly_mappable_cdev_bdi}, | ||
879 | #endif | 875 | #endif |
880 | {3, "null", S_IRUGO | S_IWUGO, &null_fops, NULL}, | 876 | [ 3] = {"null", &null_fops, NULL }, |
881 | #ifdef CONFIG_DEVPORT | 877 | #ifdef CONFIG_DEVPORT |
882 | {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops, NULL}, | 878 | [ 4] = { "port", &port_fops, NULL }, |
883 | #endif | 879 | #endif |
884 | {5, "zero", S_IRUGO | S_IWUGO, &zero_fops, &zero_bdi}, | 880 | [ 5] = { "zero", &zero_fops, &zero_bdi }, |
885 | {7, "full", S_IRUGO | S_IWUGO, &full_fops, NULL}, | 881 | [ 7] = { "full", &full_fops, NULL }, |
886 | {8, "random", S_IRUGO | S_IWUSR, &random_fops, NULL}, | 882 | [ 8] = { "random", &random_fops, NULL }, |
887 | {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops, NULL}, | 883 | [ 9] = { "urandom", &urandom_fops, NULL }, |
888 | {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops, NULL}, | 884 | [11] = { "kmsg", &kmsg_fops, NULL }, |
889 | #ifdef CONFIG_CRASH_DUMP | 885 | #ifdef CONFIG_CRASH_DUMP |
890 | {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops, NULL}, | 886 | [12] = { "oldmem", &oldmem_fops, NULL }, |
891 | #endif | 887 | #endif |
892 | }; | 888 | }; |
893 | 889 | ||
894 | static int memory_open(struct inode *inode, struct file *filp) | 890 | static int memory_open(struct inode *inode, struct file *filp) |
895 | { | 891 | { |
896 | int ret = 0; | 892 | int minor; |
897 | int i; | 893 | const struct memdev *dev; |
894 | int ret = -ENXIO; | ||
898 | 895 | ||
899 | lock_kernel(); | 896 | lock_kernel(); |
900 | 897 | ||
901 | for (i = 0; i < ARRAY_SIZE(devlist); i++) { | 898 | minor = iminor(inode); |
902 | if (devlist[i].minor == iminor(inode)) { | 899 | if (minor >= ARRAY_SIZE(devlist)) |
903 | filp->f_op = devlist[i].fops; | 900 | goto out; |
904 | if (devlist[i].dev_info) { | ||
905 | filp->f_mapping->backing_dev_info = | ||
906 | devlist[i].dev_info; | ||
907 | } | ||
908 | 901 | ||
909 | break; | 902 | dev = &devlist[minor]; |
910 | } | 903 | if (!dev->fops) |
911 | } | 904 | goto out; |
912 | 905 | ||
913 | if (i == ARRAY_SIZE(devlist)) | 906 | filp->f_op = dev->fops; |
914 | ret = -ENXIO; | 907 | if (dev->dev_info) |
915 | else | 908 | filp->f_mapping->backing_dev_info = dev->dev_info; |
916 | if (filp->f_op && filp->f_op->open) | ||
917 | ret = filp->f_op->open(inode, filp); | ||
918 | 909 | ||
910 | if (dev->fops->open) | ||
911 | ret = dev->fops->open(inode, filp); | ||
912 | else | ||
913 | ret = 0; | ||
914 | out: | ||
919 | unlock_kernel(); | 915 | unlock_kernel(); |
920 | return ret; | 916 | return ret; |
921 | } | 917 | } |
922 | 918 | ||
923 | static const struct file_operations memory_fops = { | 919 | static const struct file_operations memory_fops = { |
924 | .open = memory_open, /* just a selector for the real open */ | 920 | .open = memory_open, |
925 | }; | 921 | }; |
926 | 922 | ||
927 | static struct class *mem_class; | 923 | static struct class *mem_class; |
928 | 924 | ||
929 | static int __init chr_dev_init(void) | 925 | static int __init chr_dev_init(void) |
930 | { | 926 | { |
931 | int i; | 927 | int minor; |
932 | int err; | 928 | int err; |
933 | 929 | ||
934 | err = bdi_init(&zero_bdi); | 930 | err = bdi_init(&zero_bdi); |
@@ -939,10 +935,12 @@ static int __init chr_dev_init(void) | |||
939 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); | 935 | printk("unable to get major %d for memory devs\n", MEM_MAJOR); |
940 | 936 | ||
941 | mem_class = class_create(THIS_MODULE, "mem"); | 937 | mem_class = class_create(THIS_MODULE, "mem"); |
942 | for (i = 0; i < ARRAY_SIZE(devlist); i++) | 938 | for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) { |
943 | device_create(mem_class, NULL, | 939 | if (!devlist[minor].name) |
944 | MKDEV(MEM_MAJOR, devlist[i].minor), NULL, | 940 | continue; |
945 | devlist[i].name); | 941 | device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor), |
942 | NULL, devlist[minor].name); | ||
943 | } | ||
946 | 944 | ||
947 | return 0; | 945 | return 0; |
948 | } | 946 | } |