aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-19 21:24:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-19 21:24:11 -0400
commit39ab05c8e0b519ff0a04a869f065746e6e8c3d95 (patch)
treee73f0ba74c4ea7a80dff9b2dd9445a3a74190e28 /drivers/char
parent1477fcc290b3d5c2614bde98bf3b1154c538860d (diff)
parentc42d2237143fcf35cff642cefe2bcf7786aae312 (diff)
Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (44 commits) debugfs: Silence DEBUG_STRICT_USER_COPY_CHECKS=y warning sysfs: remove "last sysfs file:" line from the oops messages drivers/base/memory.c: fix warning due to "memory hotplug: Speed up add/remove when blocks are larger than PAGES_PER_SECTION" memory hotplug: Speed up add/remove when blocks are larger than PAGES_PER_SECTION SYSFS: Fix erroneous comments for sysfs_update_group(). driver core: remove the driver-model structures from the documentation driver core: Add the device driver-model structures to kerneldoc Translated Documentation/email-clients.txt RAW driver: Remove call to kobject_put(). reboot: disable usermodehelper to prevent fs access efivars: prevent oops on unload when efi is not enabled Allow setting of number of raw devices as a module parameter Introduce CONFIG_GOOGLE_FIRMWARE driver: Google Memory Console driver: Google EFI SMI x86: Better comments for get_bios_ebda() x86: get_bios_ebda_length() misc: fix ti-st build issues params.c: Use new strtobool function to process boolean inputs debugfs: move to new strtobool ... Fix up trivial conflicts in fs/debugfs/file.c due to the same patch being applied twice, and an unrelated cleanup nearby.
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/mem.c42
-rw-r--r--drivers/char/raw.c34
3 files changed, 55 insertions, 23 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index ad59b4e0a9b5..49502bc5360a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -523,7 +523,7 @@ config RAW_DRIVER
523 with the O_DIRECT flag. 523 with the O_DIRECT flag.
524 524
525config MAX_RAW_DEVS 525config MAX_RAW_DEVS
526 int "Maximum number of RAW devices to support (1-8192)" 526 int "Maximum number of RAW devices to support (1-65536)"
527 depends on RAW_DRIVER 527 depends on RAW_DRIVER
528 default "256" 528 default "256"
529 help 529 help
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 436a99017998..8fc04b4f311f 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -806,29 +806,41 @@ static const struct file_operations oldmem_fops = {
806}; 806};
807#endif 807#endif
808 808
809static ssize_t kmsg_write(struct file *file, const char __user *buf, 809static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv,
810 size_t count, loff_t *ppos) 810 unsigned long count, loff_t pos)
811{ 811{
812 char *tmp; 812 char *line, *p;
813 ssize_t ret; 813 int i;
814 ssize_t ret = -EFAULT;
815 size_t len = iov_length(iv, count);
814 816
815 tmp = kmalloc(count + 1, GFP_KERNEL); 817 line = kmalloc(len + 1, GFP_KERNEL);
816 if (tmp == NULL) 818 if (line == NULL)
817 return -ENOMEM; 819 return -ENOMEM;
818 ret = -EFAULT; 820
819 if (!copy_from_user(tmp, buf, count)) { 821 /*
820 tmp[count] = 0; 822 * copy all vectors into a single string, to ensure we do
821 ret = printk("%s", tmp); 823 * not interleave our log line with other printk calls
822 if (ret > count) 824 */
823 /* printk can add a prefix */ 825 p = line;
824 ret = count; 826 for (i = 0; i < count; i++) {
827 if (copy_from_user(p, iv[i].iov_base, iv[i].iov_len))
828 goto out;
829 p += iv[i].iov_len;
825 } 830 }
826 kfree(tmp); 831 p[0] = '\0';
832
833 ret = printk("%s", line);
834 /* printk can add a prefix */
835 if (ret > len)
836 ret = len;
837out:
838 kfree(line);
827 return ret; 839 return ret;
828} 840}
829 841
830static const struct file_operations kmsg_fops = { 842static const struct file_operations kmsg_fops = {
831 .write = kmsg_write, 843 .aio_write = kmsg_writev,
832 .llseek = noop_llseek, 844 .llseek = noop_llseek,
833}; 845};
834 846
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index b4b9d5a47885..b33e8ea314ed 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -21,6 +21,7 @@
21#include <linux/mutex.h> 21#include <linux/mutex.h>
22#include <linux/gfp.h> 22#include <linux/gfp.h>
23#include <linux/compat.h> 23#include <linux/compat.h>
24#include <linux/vmalloc.h>
24 25
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26 27
@@ -30,10 +31,15 @@ struct raw_device_data {
30}; 31};
31 32
32static struct class *raw_class; 33static struct class *raw_class;
33static struct raw_device_data raw_devices[MAX_RAW_MINORS]; 34static struct raw_device_data *raw_devices;
34static DEFINE_MUTEX(raw_mutex); 35static DEFINE_MUTEX(raw_mutex);
35static const struct file_operations raw_ctl_fops; /* forward declaration */ 36static const struct file_operations raw_ctl_fops; /* forward declaration */
36 37
38static int max_raw_minors = MAX_RAW_MINORS;
39
40module_param(max_raw_minors, int, 0);
41MODULE_PARM_DESC(max_raw_minors, "Maximum number of raw devices (1-65536)");
42
37/* 43/*
38 * Open/close code for raw IO. 44 * Open/close code for raw IO.
39 * 45 *
@@ -125,7 +131,7 @@ static int bind_set(int number, u64 major, u64 minor)
125 struct raw_device_data *rawdev; 131 struct raw_device_data *rawdev;
126 int err = 0; 132 int err = 0;
127 133
128 if (number <= 0 || number >= MAX_RAW_MINORS) 134 if (number <= 0 || number >= max_raw_minors)
129 return -EINVAL; 135 return -EINVAL;
130 136
131 if (MAJOR(dev) != major || MINOR(dev) != minor) 137 if (MAJOR(dev) != major || MINOR(dev) != minor)
@@ -312,14 +318,27 @@ static int __init raw_init(void)
312 dev_t dev = MKDEV(RAW_MAJOR, 0); 318 dev_t dev = MKDEV(RAW_MAJOR, 0);
313 int ret; 319 int ret;
314 320
315 ret = register_chrdev_region(dev, MAX_RAW_MINORS, "raw"); 321 if (max_raw_minors < 1 || max_raw_minors > 65536) {
322 printk(KERN_WARNING "raw: invalid max_raw_minors (must be"
323 " between 1 and 65536), using %d\n", MAX_RAW_MINORS);
324 max_raw_minors = MAX_RAW_MINORS;
325 }
326
327 raw_devices = vmalloc(sizeof(struct raw_device_data) * max_raw_minors);
328 if (!raw_devices) {
329 printk(KERN_ERR "Not enough memory for raw device structures\n");
330 ret = -ENOMEM;
331 goto error;
332 }
333 memset(raw_devices, 0, sizeof(struct raw_device_data) * max_raw_minors);
334
335 ret = register_chrdev_region(dev, max_raw_minors, "raw");
316 if (ret) 336 if (ret)
317 goto error; 337 goto error;
318 338
319 cdev_init(&raw_cdev, &raw_fops); 339 cdev_init(&raw_cdev, &raw_fops);
320 ret = cdev_add(&raw_cdev, dev, MAX_RAW_MINORS); 340 ret = cdev_add(&raw_cdev, dev, max_raw_minors);
321 if (ret) { 341 if (ret) {
322 kobject_put(&raw_cdev.kobj);
323 goto error_region; 342 goto error_region;
324 } 343 }
325 344
@@ -336,8 +355,9 @@ static int __init raw_init(void)
336 return 0; 355 return 0;
337 356
338error_region: 357error_region:
339 unregister_chrdev_region(dev, MAX_RAW_MINORS); 358 unregister_chrdev_region(dev, max_raw_minors);
340error: 359error:
360 vfree(raw_devices);
341 return ret; 361 return ret;
342} 362}
343 363
@@ -346,7 +366,7 @@ static void __exit raw_exit(void)
346 device_destroy(raw_class, MKDEV(RAW_MAJOR, 0)); 366 device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
347 class_destroy(raw_class); 367 class_destroy(raw_class);
348 cdev_del(&raw_cdev); 368 cdev_del(&raw_cdev);
349 unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS); 369 unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), max_raw_minors);
350} 370}
351 371
352module_init(raw_init); 372module_init(raw_init);