Browse Source

TTY: add ports array to tty_driver

It will hold tty_port structures for all drivers which do not want to
define tty->ops->install hook.

We ignore PTY here because it wants 1 million lines and it installs
tty_port in ->install anyway.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Jiri Slaby 13 years ago
parent
commit
04831dc154
2 changed files with 18 additions and 1 deletions
  1. 17 1
      drivers/tty/tty_io.c
  2. 1 0
      include/linux/tty_driver.h

+ 17 - 1
drivers/tty/tty_io.c

@@ -1407,6 +1407,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
 	if (retval < 0)
 		goto err_deinit_tty;
 
+	if (!tty->port)
+		tty->port = driver->ports[idx];
+
 	/*
 	 * Structures all installed ... call the ldisc open routines.
 	 * If we fail here just call release_tty to clean up.  No need
@@ -3094,6 +3097,7 @@ static void destruct_tty_driver(struct kref *kref)
 		kfree(p);
 		cdev_del(&driver->cdev);
 	}
+	kfree(driver->ports);
 	kfree(driver);
 }
 
@@ -3132,6 +3136,18 @@ int tty_register_driver(struct tty_driver *driver)
 		if (!p)
 			return -ENOMEM;
 	}
+	/*
+	 * There is too many lines in PTY and we won't need the array there
+	 * since it has an ->install hook where it assigns ports properly.
+	 */
+	if (driver->type != TTY_DRIVER_TYPE_PTY) {
+		driver->ports = kcalloc(driver->num, sizeof(struct tty_port *),
+				GFP_KERNEL);
+		if (!driver->ports) {
+			error = -ENOMEM;
+			goto err_free_p;
+		}
+	}
 
 	if (!driver->major) {
 		error = alloc_chrdev_region(&dev, driver->minor_start,
@@ -3190,7 +3206,7 @@ err_unreg_char:
 	unregister_chrdev_region(dev, driver->num);
 	driver->ttys = NULL;
 	driver->termios = NULL;
-err_free_p:
+err_free_p: /* destruct_tty_driver will free driver->ports */
 	kfree(p);
 	return error;
 }

+ 1 - 0
include/linux/tty_driver.h

@@ -313,6 +313,7 @@ struct tty_driver {
 	 * Pointer to the tty data structures
 	 */
 	struct tty_struct **ttys;
+	struct tty_port **ports;
 	struct ktermios **termios;
 	void *driver_state;