summaryrefslogtreecommitdiffstats
path: root/drivers/char/vt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/vt.c')
-rw-r--r--drivers/char/vt.c84
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 = &registered_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);
OpenPOWER on IntegriCloud