diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-14 22:41:27 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-14 22:41:27 -0700 |
commit | c362495586e8a3a6487a318fcd82eaf15ffe2142 (patch) | |
tree | 86f7b195d36ba198f24f86be327f21a8d24ec248 /drivers/tty | |
parent | b70936d9ffbf0f45f4fa13a03122f015f13ecdb0 (diff) | |
parent | ddffeb8c4d0331609ef2581d84de4d763607bd37 (diff) |
Merge 3.7-rc1 into tty-linus
This syncs up the tty-linus branch to the latest in Linus's tree to get all of
the UAPI stuff needed for the next set of patches to merge.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/hvc/hvc_console.c | 33 | ||||
-rw-r--r-- | drivers/tty/hvc/hvc_vio.c | 123 | ||||
-rw-r--r-- | drivers/tty/hvc/hvc_xen.c | 5 | ||||
-rw-r--r-- | drivers/tty/serial/kgdboc.c | 3 | ||||
-rw-r--r-- | drivers/tty/vt/vt.c | 13 |
5 files changed, 115 insertions, 62 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 4a652999380..a5dec1ca1b8 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -245,6 +245,20 @@ static void hvc_port_destruct(struct tty_port *port) kfree(hp); } +static void hvc_check_console(int index) +{ + /* Already enabled, bail out */ + if (hvc_console.flags & CON_ENABLED) + return; + + /* If this index is what the user requested, then register + * now (setup won't fail at this point). It's ok to just + * call register again if previously .setup failed. + */ + if (index == hvc_console.index) + register_console(&hvc_console); +} + /* * hvc_instantiate() is an early console discovery method which locates * consoles * prior to the vio subsystem discovering them. Hotplugged @@ -275,12 +289,8 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops) if (last_hvc < index) last_hvc = index; - /* if this index is what the user requested, then register - * now (setup won't fail at this point). It's ok to just - * call register again if previously .setup failed. - */ - if (index == hvc_console.index) - register_console(&hvc_console); + /* check if we need to re-register the kernel console */ + hvc_check_console(index); return 0; } @@ -877,10 +887,15 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, i = ++last_hvc; hp->index = i; + cons_ops[i] = ops; + vtermnos[i] = vtermno; list_add_tail(&(hp->next), &hvc_structs); spin_unlock(&hvc_structs_lock); + /* check if we need to re-register the kernel console */ + hvc_check_console(i); + return hp; } EXPORT_SYMBOL_GPL(hvc_alloc); @@ -893,8 +908,12 @@ int hvc_remove(struct hvc_struct *hp) tty = tty_port_tty_get(&hp->port); spin_lock_irqsave(&hp->lock, flags); - if (hp->index < MAX_NR_HVC_CONSOLES) + if (hp->index < MAX_NR_HVC_CONSOLES) { + console_lock(); vtermnos[hp->index] = -1; + cons_ops[hp->index] = NULL; + console_unlock(); + } /* Don't whack hp->irq because tty_hangup() will need to free the irq. */ diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index ee307799271..070c0ee6864 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c @@ -230,6 +230,69 @@ static const struct hv_ops hvterm_hvsi_ops = { .tiocmset = hvterm_hvsi_tiocmset, }; +static void udbg_hvc_putc(char c) +{ + int count = -1; + + if (!hvterm_privs[0]) + return; + + if (c == '\n') + udbg_hvc_putc('\r'); + + do { + switch(hvterm_privs[0]->proto) { + case HV_PROTOCOL_RAW: + count = hvterm_raw_put_chars(0, &c, 1); + break; + case HV_PROTOCOL_HVSI: + count = hvterm_hvsi_put_chars(0, &c, 1); + break; + } + } while(count == 0); +} + +static int udbg_hvc_getc_poll(void) +{ + int rc = 0; + char c; + + if (!hvterm_privs[0]) + return -1; + + switch(hvterm_privs[0]->proto) { + case HV_PROTOCOL_RAW: + rc = hvterm_raw_get_chars(0, &c, 1); + break; + case HV_PROTOCOL_HVSI: + rc = hvterm_hvsi_get_chars(0, &c, 1); + break; + } + if (!rc) + return -1; + return c; +} + +static int udbg_hvc_getc(void) +{ + int ch; + + if (!hvterm_privs[0]) + return -1; + + for (;;) { + ch = udbg_hvc_getc_poll(); + if (ch == -1) { + /* This shouldn't be needed...but... */ + volatile unsigned long delay; + for (delay=0; delay < 2000000; delay++) + ; + } else { + return ch; + } + } +} + static int __devinit hvc_vio_probe(struct vio_dev *vdev, const struct vio_device_id *id) { @@ -289,6 +352,13 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev, return PTR_ERR(hp); dev_set_drvdata(&vdev->dev, hp); + /* register udbg if it's not there already for console 0 */ + if (hp->index == 0 && !udbg_putc) { + udbg_putc = udbg_hvc_putc; + udbg_getc = udbg_hvc_getc; + udbg_getc_poll = udbg_hvc_getc_poll; + } + return 0; } @@ -331,59 +401,6 @@ static void __exit hvc_vio_exit(void) } module_exit(hvc_vio_exit); -static void udbg_hvc_putc(char c) -{ - int count = -1; - - if (c == '\n') - udbg_hvc_putc('\r'); - - do { - switch(hvterm_priv0.proto) { - case HV_PROTOCOL_RAW: - count = hvterm_raw_put_chars(0, &c, 1); - break; - case HV_PROTOCOL_HVSI: - count = hvterm_hvsi_put_chars(0, &c, 1); - break; - } - } while(count == 0); -} - -static int udbg_hvc_getc_poll(void) -{ - int rc = 0; - char c; - - switch(hvterm_priv0.proto) { - case HV_PROTOCOL_RAW: - rc = hvterm_raw_get_chars(0, &c, 1); - break; - case HV_PROTOCOL_HVSI: - rc = hvterm_hvsi_get_chars(0, &c, 1); - break; - } - if (!rc) - return -1; - return c; -} - -static int udbg_hvc_getc(void) -{ - int ch; - for (;;) { - ch = udbg_hvc_getc_poll(); - if (ch == -1) { - /* This shouldn't be needed...but... */ - volatile unsigned long delay; - for (delay=0; delay < 2000000; delay++) - ; - } else { - return ch; - } - } -} - void __init hvc_vio_init_early(void) { struct device_node *stdout_node; diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 2944ff88fdc..f4abfe238f9 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -478,7 +478,6 @@ static void xencons_backend_changed(struct xenbus_device *dev, case XenbusStateInitialising: case XenbusStateInitialised: case XenbusStateUnknown: - case XenbusStateClosed: break; case XenbusStateInitWait: @@ -488,6 +487,10 @@ static void xencons_backend_changed(struct xenbus_device *dev, xenbus_switch_state(dev, XenbusStateConnected); break; + case XenbusStateClosed: + if (dev->state == XenbusStateClosed) + break; + /* Missed the backend's CLOSING state -- fallthrough */ case XenbusStateClosing: xenbus_frontend_closed(dev); break; diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index c0b334327d9..10020547c60 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c @@ -97,7 +97,8 @@ static void kgdboc_restore_input(void) static int kgdboc_register_kbd(char **cptr) { - if (strncmp(*cptr, "kbd", 3) == 0) { + if (strncmp(*cptr, "kbd", 3) == 0 || + strncmp(*cptr, "kdb", 3) == 0) { if (kdb_poll_idx < KDB_POLL_FUNC_MAX) { kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char; kdb_poll_idx++; diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 999ca63afde..f87d7e8964b 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3442,6 +3442,19 @@ int con_debug_enter(struct vc_data *vc) kdb_set(2, setargs); } } + if (vc->vc_cols < 999) { + int colcount; + char cols[4]; + const char *setargs[3] = { + "set", + "COLUMNS", + cols, + }; + if (kdbgetintenv(setargs[0], &colcount)) { + snprintf(cols, 4, "%i", vc->vc_cols); + kdb_set(2, setargs); + } + } #endif /* CONFIG_KGDB_KDB */ return ret; } |