Skip to content

Commit

Permalink
Allow setting of number of raw devices as a module parameter
Browse files Browse the repository at this point in the history
Allow setting of maximal number of raw devices as a module parameter. This
requires changing of static array into a vmalloced one (the array is going to
be too large for kmalloc).

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Jan Kara authored and Greg Kroah-Hartman committed May 7, 2011
1 parent a1d9a09 commit 0078bff
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
2 changes: 1 addition & 1 deletion drivers/char/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ config RAW_DRIVER
with the O_DIRECT flag.

config MAX_RAW_DEVS
int "Maximum number of RAW devices to support (1-8192)"
int "Maximum number of RAW devices to support (1-65536)"
depends on RAW_DRIVER
default "256"
help
Expand Down
33 changes: 27 additions & 6 deletions drivers/char/raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/mutex.h>
#include <linux/gfp.h>
#include <linux/compat.h>
#include <linux/vmalloc.h>

#include <asm/uaccess.h>

Expand All @@ -30,10 +31,15 @@ struct raw_device_data {
};

static struct class *raw_class;
static struct raw_device_data raw_devices[MAX_RAW_MINORS];
static struct raw_device_data *raw_devices;
static DEFINE_MUTEX(raw_mutex);
static const struct file_operations raw_ctl_fops; /* forward declaration */

static int max_raw_minors = MAX_RAW_MINORS;

module_param(max_raw_minors, int, 0);
MODULE_PARM_DESC(max_raw_minors, "Maximum number of raw devices (1-65536)");

/*
* Open/close code for raw IO.
*
Expand Down Expand Up @@ -125,7 +131,7 @@ static int bind_set(int number, u64 major, u64 minor)
struct raw_device_data *rawdev;
int err = 0;

if (number <= 0 || number >= MAX_RAW_MINORS)
if (number <= 0 || number >= max_raw_minors)
return -EINVAL;

if (MAJOR(dev) != major || MINOR(dev) != minor)
Expand Down Expand Up @@ -312,12 +318,26 @@ static int __init raw_init(void)
dev_t dev = MKDEV(RAW_MAJOR, 0);
int ret;

ret = register_chrdev_region(dev, MAX_RAW_MINORS, "raw");
if (max_raw_minors < 1 || max_raw_minors > 65536) {
printk(KERN_WARNING "raw: invalid max_raw_minors (must be"
" between 1 and 65536), using %d\n", MAX_RAW_MINORS);
max_raw_minors = MAX_RAW_MINORS;
}

raw_devices = vmalloc(sizeof(struct raw_device_data) * max_raw_minors);
if (!raw_devices) {
printk(KERN_ERR "Not enough memory for raw device structures\n");
ret = -ENOMEM;
goto error;
}
memset(raw_devices, 0, sizeof(struct raw_device_data) * max_raw_minors);

ret = register_chrdev_region(dev, max_raw_minors, "raw");
if (ret)
goto error;

cdev_init(&raw_cdev, &raw_fops);
ret = cdev_add(&raw_cdev, dev, MAX_RAW_MINORS);
ret = cdev_add(&raw_cdev, dev, max_raw_minors);
if (ret) {
kobject_put(&raw_cdev.kobj);
goto error_region;
Expand All @@ -336,8 +356,9 @@ static int __init raw_init(void)
return 0;

error_region:
unregister_chrdev_region(dev, MAX_RAW_MINORS);
unregister_chrdev_region(dev, max_raw_minors);
error:
vfree(raw_devices);
return ret;
}

Expand All @@ -346,7 +367,7 @@ static void __exit raw_exit(void)
device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
class_destroy(raw_class);
cdev_del(&raw_cdev);
unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS);
unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), max_raw_minors);
}

module_init(raw_init);
Expand Down

0 comments on commit 0078bff

Please sign in to comment.