From 3ec0a17ef5f4ea922b10ebfdb99473c4d8d6120d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 7 Aug 2012 21:47:57 +0200 Subject: TTY: con3215, unset raw3215[line] raw3215[line] is set in probe, but not unset in remove. This will lead to random crashes if the device is removed and the corresponding tty opened later. open would dereference freed memory. So set raw3215[line] to NULL in remove to fix that. Signed-off-by: Jiri Slaby Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: linux390@de.ibm.com Cc: linux-s390@vger.kernel.org Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/s390/char/con3215.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/s390/char/con3215.c') diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 6c0116d48c74..16554982671c 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -716,10 +716,17 @@ static int raw3215_probe (struct ccw_device *cdev) static void raw3215_remove (struct ccw_device *cdev) { struct raw3215_info *raw; + unsigned int line; ccw_device_set_offline(cdev); raw = dev_get_drvdata(&cdev->dev); if (raw) { + spin_lock(&raw3215_device_lock); + for (line = 0; line < NR_3215; line++) + if (raw3215[line] == raw) + break; + raw3215[line] = NULL; + spin_unlock(&raw3215_device_lock); dev_set_drvdata(&cdev->dev, NULL); raw3215_free_info(raw); } -- cgit v1.2.2 From d2281107457cacf44d60b8a97c5db1af27c3a716 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 7 Aug 2012 21:47:58 +0200 Subject: TTY: con3215, add tty install This has two outcomes: * we give the TTY layer a tty_port * we do not find the info structure every time open is called on that tty Signed-off-by: Jiri Slaby Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: linux390@de.ibm.com Cc: linux-s390@vger.kernel.org Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/s390/char/con3215.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers/s390/char/con3215.c') diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 16554982671c..9ffb6d5f17aa 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -942,6 +942,19 @@ static int __init con3215_init(void) console_initcall(con3215_init); #endif +static int tty3215_install(struct tty_driver *driver, struct tty_struct *tty) +{ + struct raw3215_info *raw; + + raw = raw3215[tty->index]; + if (raw == NULL) + return -ENODEV; + + tty->driver_data = raw; + + return tty_port_install(&raw->port, driver, tty); +} + /* * tty3215_open * @@ -949,14 +962,9 @@ console_initcall(con3215_init); */ static int tty3215_open(struct tty_struct *tty, struct file * filp) { - struct raw3215_info *raw; + struct raw3215_info *raw = tty->driver_data; int retval; - raw = raw3215[tty->index]; - if (raw == NULL) - return -ENODEV; - - tty->driver_data = raw; tty_port_tty_set(&raw->port, tty); tty->low_latency = 0; /* don't use bottom half for pushing chars */ @@ -1117,6 +1125,7 @@ static void tty3215_start(struct tty_struct *tty) } static const struct tty_operations tty3215_ops = { + .install = tty3215_install, .open = tty3215_open, .close = tty3215_close, .write = tty3215_write, -- cgit v1.2.2