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);
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;
}
*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;
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;
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);
#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;
const int write_irq;
const char *write_irq_name;
struct mc_device mc;
+ struct tty_driver *driver;
};
struct line {
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);
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)
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)
static int ssl_init(void)
{
char *new_title;
+ int err;
int i;
printk(KERN_INFO "Initializing software serial port version %d\n",
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)
#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,
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)
static int stdio_init(void)
{
char *new_title;
+ int err;
int i;
for (i = 0; i < MAX_TTYS; i++) {
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);