diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2011-09-09 19:45:42 -0400 | 
|---|---|---|
| committer | Richard Weinberger <richard@nod.at> | 2012-03-25 00:29:53 +0100 | 
| commit | cfe6b7c79daa0efa27f474f1fe2a88fd7af5cc47 (patch) | |
| tree | 5030f25d83451e3b3e579bac4b9a2e561990048d /arch/um/drivers | |
| parent | 31efcebb7d7196adcee73027f513d7c0bf572b47 (diff) | |
| download | olio-linux-3.10-cfe6b7c79daa0efa27f474f1fe2a88fd7af5cc47.tar.xz olio-linux-3.10-cfe6b7c79daa0efa27f474f1fe2a88fd7af5cc47.zip  | |
um: switch line.c tty drivers to dynamic device creation
Current code doesn't update the symlinks in /sys/dev/char when we add/remove
tty lines.  Fixing that allows to stop messing with ->valid before the driver
registration, which is a Good Thing(tm) - we shouldn't have it set before we
really have the things set up and ready for line_open().
We need tty_driver available to call tty_{un,}register_device(), so we just
stash a reference to it into struct line_driver.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um/drivers')
| -rw-r--r-- | arch/um/drivers/line.c | 37 | ||||
| -rw-r--r-- | arch/um/drivers/line.h | 9 | ||||
| -rw-r--r-- | arch/um/drivers/ssl.c | 17 | ||||
| -rw-r--r-- | arch/um/drivers/stdio_console.c | 19 | 
4 files changed, 40 insertions, 42 deletions
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 1a8d6591c20..015209a9881 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -485,6 +485,7 @@ static int setup_one_line(struct line *lines, int n, char *init,  			  const struct chan_opts *opts, char **error_out)  {  	struct line *line = &lines[n]; +	struct tty_driver *driver = line->driver->driver;  	int err = -EINVAL;  	mutex_lock(&line->count_lock); @@ -498,6 +499,7 @@ static int setup_one_line(struct line *lines, int n, char *init,  		if (line->valid) {  			line->valid = 0;  			kfree(line->init_str); +			tty_unregister_device(driver, n);  			parse_chan_pair(NULL, line, n, opts, error_out);  			err = 0;  		} @@ -507,9 +509,19 @@ static int setup_one_line(struct line *lines, int n, char *init,  			*error_out = "Failed to allocate memory";  			return -ENOMEM;  		} +		if (line->valid) +			tty_unregister_device(driver, n);  		line->init_str = new;  		line->valid = 1;  		err = parse_chan_pair(new, line, n, opts, error_out); +		if (!err) { +			struct device *d = tty_register_device(driver, n, NULL); +			if (IS_ERR(d)) { +				*error_out = "Failed to register device"; +				err = PTR_ERR(d); +				parse_chan_pair(NULL, line, n, opts, error_out); +			} +		}  		if (err) {  			line->init_str = NULL;  			line->valid = 0; @@ -640,15 +652,15 @@ int line_remove(struct line *lines, unsigned int num, int n, char **error_out)  	return setup_one_line(lines, n, "none", NULL, error_out);  } -struct tty_driver *register_lines(struct line_driver *line_driver, -				  const struct tty_operations *ops, -				  struct line *lines, int nlines) +int register_lines(struct line_driver *line_driver, +		   const struct tty_operations *ops, +		   struct line *lines, int nlines)  { -	int i;  	struct tty_driver *driver = alloc_tty_driver(nlines); +	int err;  	if (!driver) -		return NULL; +		return -ENOMEM;  	driver->driver_name = line_driver->name;  	driver->name = line_driver->device_name; @@ -656,24 +668,21 @@ struct tty_driver *register_lines(struct line_driver *line_driver,  	driver->minor_start = line_driver->minor_start;  	driver->type = line_driver->type;  	driver->subtype = line_driver->subtype; -	driver->flags = TTY_DRIVER_REAL_RAW; +	driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;  	driver->init_termios = tty_std_termios;  	tty_set_operations(driver, ops); -	if (tty_register_driver(driver)) { +	err = tty_register_driver(driver); +	if (err) {  		printk(KERN_ERR "register_lines : can't register %s driver\n",  		       line_driver->name);  		put_tty_driver(driver); -		return NULL; -	} - -	for(i = 0; i < nlines; i++) { -		if (!lines[i].valid) -			tty_unregister_device(driver, i); +		return err;  	} +	line_driver->driver = driver;  	mconsole_register_dev(&line_driver->mc); -	return driver; +	return 0;  }  static DEFINE_SPINLOCK(winch_handler_lock); diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h index 471f477b271..e3f86065e04 100644 --- a/arch/um/drivers/line.h +++ b/arch/um/drivers/line.h @@ -15,7 +15,7 @@  #include "chan_user.h"  #include "mconsole_kern.h" -/* There's only one modifiable field in this - .mc.list */ +/* There's only two modifiable fields in this - .mc.list and .driver */  struct line_driver {  	const char *name;  	const char *device_name; @@ -28,6 +28,7 @@ struct line_driver {  	const int write_irq;  	const char *write_irq_name;  	struct mc_device mc; +	struct tty_driver *driver;  };  struct line { @@ -78,9 +79,9 @@ extern char *add_xterm_umid(char *base);  extern int line_setup_irq(int fd, int input, int output, struct line *line,  			  void *data);  extern void line_close_chan(struct line *line); -extern struct tty_driver *register_lines(struct line_driver *line_driver, -					 const struct tty_operations *driver, -					 struct line *lines, int nlines); +extern int register_lines(struct line_driver *line_driver, +			  const struct tty_operations *driver, +			  struct line *lines, int nlines);  extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts);  extern void close_lines(struct line *lines, int nlines); diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 23cffd6d85a..6398a47d035 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -20,12 +20,6 @@  static const int ssl_version = 1; -/* Referenced only by tty_driver below - presumably it's locked correctly - * by the tty driver. - */ - -static struct tty_driver *ssl_driver; -  #define NR_PORTS 64  static void ssl_announce(char *dev_name, int dev) @@ -164,7 +158,7 @@ static void ssl_console_write(struct console *c, const char *string,  static struct tty_driver *ssl_console_device(struct console *c, int *index)  {  	*index = c->index; -	return ssl_driver; +	return driver.driver;  }  static int ssl_console_setup(struct console *co, char *options) @@ -187,6 +181,7 @@ static struct console ssl_cons = {  static int ssl_init(void)  {  	char *new_title; +	int err;  	int i;  	printk(KERN_INFO "Initializing software serial port version %d\n", @@ -196,16 +191,16 @@ static int ssl_init(void)  		char *s = conf[i];  		if (!s)  			s = def_conf; -		if (s && strcmp(s, "none") != 0) { +		if (s && strcmp(s, "none") != 0)  			serial_lines[i].init_str = s; -			serial_lines[i].valid = 1; -		}  		spin_lock_init(&serial_lines[i].lock);  		mutex_init(&serial_lines[i].count_lock);  		serial_lines[i].driver = &driver;  	} -	ssl_driver = register_lines(&driver, &ssl_ops, serial_lines, +	err = register_lines(&driver, &ssl_ops, serial_lines,  				    ARRAY_SIZE(serial_lines)); +	if (err) +		return err;  	new_title = add_xterm_umid(opts.xterm_title);  	if (new_title != NULL) diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index f8d4325b28b..32bd040138f 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -27,12 +27,6 @@  #define MAX_TTYS (16) -/* Referenced only by tty_driver below - presumably it's locked correctly - * by the tty driver. - */ - -static struct tty_driver *console_driver; -  static void stdio_announce(char *dev_name, int dev)  {  	printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev, @@ -137,7 +131,7 @@ static void uml_console_write(struct console *console, const char *string,  static struct tty_driver *uml_console_device(struct console *c, int *index)  {  	*index = c->index; -	return console_driver; +	return driver.driver;  }  static int uml_console_setup(struct console *co, char *options) @@ -160,6 +154,7 @@ static struct console stdiocons = {  static int stdio_init(void)  {  	char *new_title; +	int err;  	int i;  	for (i = 0; i < MAX_TTYS; i++) { @@ -168,18 +163,16 @@ static int stdio_init(void)  			s = def_conf;  		if (!s)  			s = i ? CONFIG_CON_CHAN : CONFIG_CON_ZERO_CHAN; -		if (s && strcmp(s, "none") != 0) { +		if (s && strcmp(s, "none") != 0)  			vts[i].init_str = s; -			vts[i].valid = 1; -		}  		spin_lock_init(&vts[i].lock);  		mutex_init(&vts[i].count_lock);  		vts[i].driver = &driver;  	} -	console_driver = register_lines(&driver, &console_ops, vts, +	err = register_lines(&driver, &console_ops, vts,  					ARRAY_SIZE(vts)); -	if (console_driver == NULL) -		return -1; +	if (err) +		return err;  	printk(KERN_INFO "Initialized stdio console driver\n");  	new_title = add_xterm_umid(opts.xterm_title);  |