Commit 4460bbfd authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] register_chrdev_region() cleanup

register_chrdev_region() sanitized, code in tty_io.c that dealt with it
cleaned up.
parent 106a92d1
......@@ -2242,53 +2242,6 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index)
EXPORT_SYMBOL(tty_register_device);
EXPORT_SYMBOL(tty_unregister_device);
/* that should be handled by register_chrdev_region() */
static int get_range(struct tty_driver *driver)
{
dev_t from = MKDEV(driver->major, driver->minor_start);
dev_t to = from + driver->num;
dev_t n, next;
int error = 0;
for (n = from; MAJOR(n) < MAJOR(to); n = next) {
next = MKDEV(MAJOR(n)+1, 0);
error = register_chrdev_region(MAJOR(n), MINOR(n),
next - n, driver->name, &tty_fops);
if (error)
goto fail;
}
if (n != to)
error = register_chrdev_region(MAJOR(n), MINOR(n),
to - n, driver->name, &tty_fops);
if (!error)
return 0;
fail:
to = n;
for (n = from; MAJOR(n) < MAJOR(to); n = next) {
next = MKDEV(MAJOR(n)+1, 0);
unregister_chrdev_region(MAJOR(n), MINOR(n),
next - n, driver->name);
}
return error;
}
/* that should be handled by unregister_chrdev_region() */
static void put_range(struct tty_driver *driver)
{
dev_t from = MKDEV(driver->major, driver->minor_start);
dev_t to = from + driver->num;
dev_t n, next;
for (n = from; MAJOR(n) < MAJOR(to); n = next) {
next = MKDEV(MAJOR(n)+1, 0);
unregister_chrdev_region(MAJOR(n), MINOR(n),
next - n, driver->name);
}
if (n != to)
unregister_chrdev_region(MAJOR(n), MINOR(n),
to - n, driver->name);
}
/*
* Called by a tty driver to register itself.
*/
......@@ -2296,17 +2249,22 @@ int tty_register_driver(struct tty_driver *driver)
{
int error;
int i;
dev_t dev;
if (driver->flags & TTY_DRIVER_INSTALLED)
return 0;
if (!driver->major) {
error = register_chrdev_region(0, driver->minor_start,
driver->num, driver->name, &tty_fops);
if (error > 0)
driver->major = error;
error = alloc_chrdev_region(&dev, driver->num,
(char*)driver->name, &tty_fops);
if (!error) {
driver->major = MAJOR(dev);
driver->minor_start = MINOR(dev);
}
} else {
error = get_range(driver);
dev = MKDEV(driver->major, driver->minor_start);
error = register_chrdev_region(dev, driver->num,
(char*)driver->name, &tty_fops);
}
if (error < 0)
return error;
......@@ -2335,7 +2293,8 @@ int tty_unregister_driver(struct tty_driver *driver)
if (*driver->refcount)
return -EBUSY;
put_range(driver);
unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
driver->num);
list_del(&driver->tty_drivers);
......@@ -2412,20 +2371,20 @@ postcore_initcall(tty_class_init);
*/
void __init tty_init(void)
{
if (register_chrdev_region(TTYAUX_MAJOR, 0, 1,
if (register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1,
"/dev/tty", &tty_fops) < 0)
panic("Couldn't register /dev/tty driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
tty_add_class_device ("tty", MKDEV(TTYAUX_MAJOR, 0), NULL);
if (register_chrdev_region(TTYAUX_MAJOR, 1, 1,
if (register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1,
"/dev/console", &tty_fops) < 0)
panic("Couldn't register /dev/console driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
tty_add_class_device ("console", MKDEV(TTYAUX_MAJOR, 1), NULL);
#ifdef CONFIG_UNIX98_PTYS
if (register_chrdev_region(TTYAUX_MAJOR, 2, 1,
if (register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1,
"/dev/ptmx", &tty_fops) < 0)
panic("Couldn't register /dev/ptmx driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
......@@ -2433,7 +2392,7 @@ void __init tty_init(void)
#endif
#ifdef CONFIG_VT
if (register_chrdev_region(TTY_MAJOR, 0, 1,
if (register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1,
"/dev/vc/0", &tty_fops) < 0)
panic("Couldn't register /dev/tty0 driver\n");
devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
......
......@@ -123,7 +123,8 @@ get_chrfops(unsigned int major, unsigned int minor)
*
* Returns a -ve errno on failure.
*/
int register_chrdev_region(unsigned int major, unsigned int baseminor,
static struct char_device_struct *
__register_chrdev_region(unsigned int major, unsigned int baseminor,
int minorct, const char *name,
struct file_operations *fops)
{
......@@ -133,7 +134,7 @@ int register_chrdev_region(unsigned int major, unsigned int baseminor,
cd = kmalloc(sizeof(struct char_device_struct), GFP_KERNEL);
if (cd == NULL)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
write_lock_irq(&chrdevs_lock);
......@@ -167,32 +168,23 @@ int register_chrdev_region(unsigned int major, unsigned int baseminor,
if (*cp && (*cp)->major == major &&
(*cp)->baseminor < baseminor + minorct) {
ret = -EBUSY;
} else {
cd->next = *cp;
*cp = cd;
goto out;
}
cd->next = *cp;
*cp = cd;
write_unlock_irq(&chrdevs_lock);
return cd;
out:
write_unlock_irq(&chrdevs_lock);
if (ret < 0)
kfree(cd);
return ret;
kfree(cd);
return ERR_PTR(ret);
}
int register_chrdev(unsigned int major, const char *name,
struct file_operations *fops)
static struct char_device_struct *
__unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
{
return register_chrdev_region(major, 0, 256, name, fops);
}
/* todo: make void - error printk here */
int unregister_chrdev_region(unsigned int major, unsigned int baseminor,
int minorct, const char *name)
{
struct char_device_struct *cd, **cp;
int ret = 0;
int i;
i = major_to_index(major);
struct char_device_struct *cd = NULL, **cp;
int i = major_to_index(major);
write_lock_irq(&chrdevs_lock);
for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
......@@ -200,21 +192,79 @@ int unregister_chrdev_region(unsigned int major, unsigned int baseminor,
(*cp)->baseminor == baseminor &&
(*cp)->minorct == minorct)
break;
if (!*cp || strcmp((*cp)->name, name))
ret = -EINVAL;
else {
if (*cp) {
cd = *cp;
*cp = cd->next;
kfree(cd);
}
write_unlock_irq(&chrdevs_lock);
return cd;
}
return ret;
int register_chrdev_region(dev_t from, unsigned count, char *name,
struct file_operations *fops)
{
struct char_device_struct *cd;
dev_t to = from + count;
dev_t n, next;
for (n = from; n < to; n = next) {
next = MKDEV(MAJOR(n)+1, 0);
if (next > to)
next = to;
cd = __register_chrdev_region(MAJOR(n), MINOR(n),
next - n, name, fops);
if (IS_ERR(cd))
goto fail;
}
return 0;
fail:
to = n;
for (n = from; n < to; n = next) {
next = MKDEV(MAJOR(n)+1, 0);
kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
}
return PTR_ERR(cd);
}
int alloc_chrdev_region(dev_t *dev, unsigned count, char *name,
struct file_operations *fops)
{
struct char_device_struct *cd;
cd = __register_chrdev_region(0, 0, count, name, fops);
if (IS_ERR(cd))
return PTR_ERR(cd);
*dev = MKDEV(cd->major, cd->baseminor);
return 0;
}
int register_chrdev(unsigned int major, const char *name,
struct file_operations *fops)
{
struct char_device_struct *cd;
cd = __register_chrdev_region(major, 0, 256, name, fops);
if (IS_ERR(cd))
return PTR_ERR(cd);
return cd->major;
}
void unregister_chrdev_region(dev_t from, unsigned count)
{
dev_t to = from + count;
dev_t n, next;
for (n = from; n < to; n = next) {
next = MKDEV(MAJOR(n)+1, 0);
if (next > to)
next = to;
kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
}
}
int unregister_chrdev(unsigned int major, const char *name)
{
return unregister_chrdev_region(major, 0, 256, name);
kfree(__unregister_chrdev_region(major, 0, 256));
return 0;
}
/*
......
......@@ -1056,13 +1056,14 @@ extern void bd_release(struct block_device *);
extern void blk_run_queues(void);
/* fs/char_dev.c */
extern int register_chrdev_region(unsigned int, unsigned int, int,
const char *, struct file_operations *);
extern int alloc_chrdev_region(dev_t *, unsigned, char *,
struct file_operations *);
extern int register_chrdev_region(dev_t, unsigned, char *,
struct file_operations *);
extern int register_chrdev(unsigned int, const char *,
struct file_operations *);
extern int unregister_chrdev(unsigned int, const char *);
extern int unregister_chrdev_region(unsigned int, unsigned int, int,
const char *);
extern void unregister_chrdev_region(dev_t, unsigned);
extern int chrdev_open(struct inode *, struct file *);
/* fs/block_dev.c */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment