From: Andries.Brouwer@cwi.nl Adding the unregister_chrdev_region call that is the counterpart to register_chrdev_region, we get a nice cleanup of tty_io.c. drivers/char/tty_io.c | 27 ++++++--------------------- fs/char_dev.c | 12 ++++++++++-- include/linux/fs.h | 2 ++ 3 files changed, 18 insertions(+), 23 deletions(-) diff -puN drivers/char/tty_io.c~tty_io-cleanup drivers/char/tty_io.c --- 25/drivers/char/tty_io.c~tty_io-cleanup 2003-03-25 18:41:57.000000000 -0800 +++ 25-akpm/drivers/char/tty_io.c 2003-03-25 18:41:57.000000000 -0800 @@ -2143,31 +2143,16 @@ int tty_register_driver(struct tty_drive */ int tty_unregister_driver(struct tty_driver *driver) { - int retval; - struct tty_driver *p; - int i, found = 0; + int retval, i; struct termios *tp; - const char *othername = NULL; - + if (*driver->refcount) return -EBUSY; - list_for_each_entry(p, &tty_drivers, tty_drivers) { - if (p == driver) - found++; - else if (p->major == driver->major) - othername = p->name; - } - - if (!found) - return -ENOENT; - - if (othername == NULL) { - retval = unregister_chrdev(driver->major, driver->name); - if (retval) - return retval; - } else - register_chrdev(driver->major, othername, &tty_fops); + retval = unregister_chrdev_region(driver->major, driver->minor_start, + driver->num, driver->name); + if (retval) + return retval; list_del(&driver->tty_drivers); diff -puN fs/char_dev.c~tty_io-cleanup fs/char_dev.c --- 25/fs/char_dev.c~tty_io-cleanup 2003-03-25 18:41:57.000000000 -0800 +++ 25-akpm/fs/char_dev.c 2003-03-25 18:41:57.000000000 -0800 @@ -174,7 +174,8 @@ int register_chrdev(unsigned int major, } /* todo: make void - error printk here */ -int unregister_chrdev(unsigned int major, const char * name) +int unregister_chrdev_region(unsigned int major, unsigned int baseminor, + int minorct, const char *name) { struct char_device_struct *cd, **cp; int ret = 0; @@ -184,7 +185,9 @@ int unregister_chrdev(unsigned int major write_lock(&chrdevs_lock); for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) - if ((*cp)->major == major) + if ((*cp)->major == major && + (*cp)->baseminor == baseminor && + (*cp)->minorct == minorct) break; if (!*cp || strcmp((*cp)->name, name)) ret = -EINVAL; @@ -198,6 +201,11 @@ int unregister_chrdev(unsigned int major return ret; } +int unregister_chrdev(unsigned int major, const char *name) +{ + return unregister_chrdev_region(major, 0, 256, name); +} + /* * Called every time a character special file is opened */ diff -puN include/linux/fs.h~tty_io-cleanup include/linux/fs.h --- 25/include/linux/fs.h~tty_io-cleanup 2003-03-25 18:41:57.000000000 -0800 +++ 25-akpm/include/linux/fs.h 2003-03-25 18:41:57.000000000 -0800 @@ -1060,6 +1060,8 @@ extern int register_chrdev_region(unsign 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 int chrdev_open(struct inode *, struct file *); /* fs/block_dev.c */ _