diff options
Diffstat (limited to 'drivers/char/vt.c')
-rw-r--r-- | drivers/char/vt.c | 84 |
1 files changed, 31 insertions, 53 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 60359c3..57029fe 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -100,10 +100,10 @@ #include <linux/font.h> #include <linux/bitops.h> #include <linux/notifier.h> - -#include <asm/io.h> +#include <linux/device.h> +#include <linux/io.h> #include <asm/system.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #define MAX_NR_CON_DRIVER 16 @@ -2136,27 +2136,9 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co release_console_sem(); return 0; } - release_console_sem(); - orig_buf = buf; orig_count = count; - /* At this point 'buf' is guaranteed to be a kernel buffer - * and therefore no access to userspace (and therefore sleeping) - * will be needed. The con_buf_mtx serializes all tty based - * console rendering and vcs write/read operations. We hold - * the console spinlock during the entire write. - */ - - acquire_console_sem(); - - vc = tty->driver_data; - if (vc == NULL) { - printk(KERN_ERR "vt: argh, driver_data _became_ NULL !\n"); - release_console_sem(); - goto out; - } - himask = vc->vc_hi_font_mask; charmask = himask ? 0x1ff : 0xff; @@ -2370,8 +2352,6 @@ rescan_last_byte: FLUSH console_conditional_schedule(); release_console_sem(); - -out: notify_update(vc); return n; #undef FLUSH @@ -2583,8 +2563,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) int lines; int ret; - if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE) - return -EINVAL; if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(type, p)) @@ -2778,6 +2756,12 @@ static int con_open(struct tty_struct *tty, struct file *filp) ret = vc_allocate(currcons); if (ret == 0) { struct vc_data *vc = vc_cons[currcons].d; + + /* Still being freed */ + if (vc->vc_tty) { + release_console_sem(); + return -ERESTARTSYS; + } tty->driver_data = vc; vc->vc_tty = tty; @@ -2798,34 +2782,20 @@ static int con_open(struct tty_struct *tty, struct file *filp) return ret; } -/* - * We take tty_mutex in here to prevent another thread from coming in via init_dev - * and taking a ref against the tty while we're in the process of forgetting - * about it and cleaning things up. - * - * This is because vcs_remove_sysfs() can sleep and will drop the BKL. - */ static void con_close(struct tty_struct *tty, struct file *filp) { - mutex_lock(&tty_mutex); - acquire_console_sem(); - if (tty && tty->count == 1) { - struct vc_data *vc = tty->driver_data; + /* Nothing to do - we defer to shutdown */ +} - if (vc) - vc->vc_tty = NULL; - tty->driver_data = NULL; - vcs_remove_sysfs(tty); - release_console_sem(); - mutex_unlock(&tty_mutex); - /* - * tty_mutex is released, but we still hold BKL, so there is - * still exclusion against init_dev() - */ - return; - } +static void con_shutdown(struct tty_struct *tty) +{ + struct vc_data *vc = tty->driver_data; + BUG_ON(vc == NULL); + acquire_console_sem(); + vc->vc_tty = NULL; + vcs_remove_sysfs(tty); release_console_sem(); - mutex_unlock(&tty_mutex); + tty_shutdown(tty); } static int default_italic_color = 2; // green (ASCII) @@ -2950,10 +2920,19 @@ static const struct tty_operations con_ops = { .throttle = con_throttle, .unthrottle = con_unthrottle, .resize = vt_resize, + .shutdown = con_shutdown }; -int __init vty_init(void) +static struct cdev vc0_cdev; + +int __init vty_init(const struct file_operations *console_fops) { + cdev_init(&vc0_cdev, console_fops); + if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || + register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) + panic("Couldn't register /dev/tty0 driver\n"); + device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); + vcs_init(); console_driver = alloc_tty_driver(MAX_NR_CONSOLES); @@ -2972,7 +2951,6 @@ int __init vty_init(void) tty_set_operations(console_driver, &con_ops); if (tty_register_driver(console_driver)) panic("Couldn't register console driver\n"); - kbd_init(); console_map_init(); #ifdef CONFIG_PROM_CONSOLE @@ -3466,7 +3444,7 @@ int register_con_driver(const struct consw *csw, int first, int last) if (retval) goto err; - con_driver->dev = device_create_drvdata(vtconsole_class, NULL, + con_driver->dev = device_create(vtconsole_class, NULL, MKDEV(0, con_driver->node), NULL, "vtcon%i", con_driver->node); @@ -3577,7 +3555,7 @@ static int __init vtconsole_class_init(void) struct con_driver *con = ®istered_con_driver[i]; if (con->con && !con->dev) { - con->dev = device_create_drvdata(vtconsole_class, NULL, + con->dev = device_create(vtconsole_class, NULL, MKDEV(0, con->node), NULL, "vtcon%i", con->node); |