From 81f5835eae424be646753ec5a044ed4db1fcc09a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:30 +0100 Subject: TTY: use tty_standard_install Use the helper in the rest of the tty drivers. This is a simple replacement. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/isdn') diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index e44933d58790..94948be5d366 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1015,14 +1015,11 @@ capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty) { int idx = tty->index; struct capiminor *mp = capiminor_get(idx); - int ret = tty_init_termios(tty); + int ret = tty_standard_install(driver, tty); - if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; + if (ret == 0) tty->driver_data = mp; - driver->ttys[idx] = tty; - } else + else capiminor_put(mp); return ret; } -- cgit v1.2.1 From 2f16669d322e05171c9e1cfd94f402f7399bd2a3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 5 Mar 2012 14:51:52 +0100 Subject: TTY: remove re-assignments to tty_driver members All num, magic and owner are set by alloc_tty_driver. No need to re-set them on each allocation site. pti driver sets something different to what it passes to alloc_tty_driver. It is not a bug, since we don't use the lines parameter in any way. Anyway this is fixed, and now we do the right thing. Signed-off-by: Jiri Slaby Acked-by: Tilman Schmidt Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 1 - drivers/isdn/gigaset/interface.c | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/isdn') diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 94948be5d366..baf08eba495c 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1287,7 +1287,6 @@ static int __init capinc_tty_init(void) kfree(capiminors); return -ENOMEM; } - drv->owner = THIS_MODULE; drv->driver_name = "capi_nc"; drv->name = "capi"; drv->major = 0; diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index ee0a549a933a..648260b07f1a 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -669,17 +669,15 @@ EXPORT_SYMBOL_GPL(gigaset_if_receive); void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, const char *devname) { - unsigned minors = drv->minors; int ret; struct tty_driver *tty; drv->have_tty = 0; - drv->tty = tty = alloc_tty_driver(minors); + drv->tty = tty = alloc_tty_driver(drv->minors); if (tty == NULL) goto enomem; - tty->magic = TTY_DRIVER_MAGIC, tty->type = TTY_DRIVER_TYPE_SERIAL, tty->subtype = SERIAL_TYPE_NORMAL, tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; @@ -687,9 +685,6 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, tty->driver_name = procname; tty->name = devname; tty->minor_start = drv->minor; - tty->num = drv->minors; - - tty->owner = THIS_MODULE; tty->init_termios = tty_std_termios; tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; -- cgit v1.2.1 From 410235fd4d20b8feaf8930a0575d23acc088aa87 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 5 Mar 2012 14:52:01 +0100 Subject: TTY: remove unneeded tty->index checks Checking if tty->index is in bounds is not needed. The tty has the index set in the initial open. This is done in get_tty_driver. And it can be only in interval <0,driver->num). So remove the tests which check exactly this interval. Some are left untouched as they check against the current backing device count. (Leaving apart that the check is racy in most of the cases.) Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 3 +-- drivers/isdn/gigaset/common.c | 2 -- drivers/isdn/i4l/isdn_tty.c | 7 ++----- 3 files changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers/isdn') diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index baf08eba495c..3a7905b06e53 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1013,8 +1013,7 @@ static const struct file_operations capi_fops = static int capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty) { - int idx = tty->index; - struct capiminor *mp = capiminor_get(idx); + struct capiminor *mp = capiminor_get(tty->index); int ret = tty_standard_install(driver, tty); if (ret == 0) diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index db621db67f61..ac0186e54bf4 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -1051,8 +1051,6 @@ static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty) { - if (tty->index < 0 || tty->index >= tty->driver->num) - return NULL; return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start); } diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 2c26b64ebbea..ac4840124bc0 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1590,12 +1590,9 @@ static int isdn_tty_open(struct tty_struct *tty, struct file *filp) { modem_info *info; - int retval, line; + int retval; - line = tty->index; - if (line < 0 || line >= ISDN_MAX_CHANNELS) - return -ENODEV; - info = &dev->mdm.info[line]; + info = &dev->mdm.info[tty->index]; if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) return -ENODEV; if (!try_module_get(info->owner)) { -- cgit v1.2.1 From fc258f89405f63b379324d1f8388ae4810297997 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 5 Mar 2012 14:52:54 +0100 Subject: TTY: isdn/gigaset, do not set tty->driver_data to NULL Close the window in open where driver_data is reset to NULL on each open. It could cause other processes to get invalid retval from the tty->ops operations because of the checks all over the code. With this change we may do other cleanups. Now, the only valid check for tty->driver_data != NULL is in close. This can happen only if open fails at gigaset_get_cs_by_tty or try_module_get. The rest of checks in various tty->ops->* are invalid as driver_data cannot be NULL there. The same holds for cs->open_count. So remove them. Signed-off-by: Jiri Slaby Cc: Hansjoerg Lipp Cc: Tilman Schmidt Cc: gigaset307x-common@lists.sourceforge.net Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/gigaset/interface.c | 105 ++++++--------------------------------- 1 file changed, 14 insertions(+), 91 deletions(-) (limited to 'drivers/isdn') diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 648260b07f1a..8ff50b056285 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -151,8 +151,6 @@ static int if_open(struct tty_struct *tty, struct file *filp) gig_dbg(DEBUG_IF, "%d+%d: %s()", tty->driver->minor_start, tty->index, __func__); - tty->driver_data = NULL; - cs = gigaset_get_cs_by_tty(tty); if (!cs || !try_module_get(cs->driver->owner)) return -ENODEV; @@ -178,12 +176,11 @@ static int if_open(struct tty_struct *tty, struct file *filp) static void if_close(struct tty_struct *tty, struct file *filp) { - struct cardstate *cs; + struct cardstate *cs = tty->driver_data; unsigned long flags; - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); + if (!cs) { /* happens if we didn't find cs in open */ + printk(KERN_DEBUG "%s: no cardstate\n", __func__); return; } @@ -211,18 +208,12 @@ static void if_close(struct tty_struct *tty, struct file *filp) static int if_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct cardstate *cs; + struct cardstate *cs = tty->driver_data; int retval = -ENODEV; int int_arg; unsigned char buf[6]; unsigned version[4]; - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); - return -ENODEV; - } - gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd); if (mutex_lock_interruptible(&cs->mutex)) @@ -231,9 +222,7 @@ static int if_ioctl(struct tty_struct *tty, if (!cs->connected) { gig_dbg(DEBUG_IF, "not connected"); retval = -ENODEV; - } else if (!cs->open_count) - dev_warn(cs->dev, "%s: device not opened\n", __func__); - else { + } else { retval = 0; switch (cmd) { case GIGASET_REDIR: @@ -285,15 +274,9 @@ static int if_ioctl(struct tty_struct *tty, static int if_tiocmget(struct tty_struct *tty) { - struct cardstate *cs; + struct cardstate *cs = tty->driver_data; int retval; - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); - return -ENODEV; - } - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); if (mutex_lock_interruptible(&cs->mutex)) @@ -309,16 +292,10 @@ static int if_tiocmget(struct tty_struct *tty) static int if_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { - struct cardstate *cs; + struct cardstate *cs = tty->driver_data; int retval; unsigned mc; - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); - return -ENODEV; - } - gig_dbg(DEBUG_IF, "%u: %s(0x%x, 0x%x)", cs->minor_index, __func__, set, clear); @@ -341,16 +318,10 @@ static int if_tiocmset(struct tty_struct *tty, static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) { - struct cardstate *cs; + struct cardstate *cs = tty->driver_data; struct cmdbuf_t *cb; int retval; - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); - return -ENODEV; - } - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); if (mutex_lock_interruptible(&cs->mutex)) @@ -361,11 +332,6 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) retval = -ENODEV; goto done; } - if (!cs->open_count) { - dev_warn(cs->dev, "%s: device not opened\n", __func__); - retval = -ENODEV; - goto done; - } if (cs->mstate != MS_LOCKED) { dev_warn(cs->dev, "can't write to unlocked device\n"); retval = -EBUSY; @@ -397,15 +363,9 @@ done: static int if_write_room(struct tty_struct *tty) { - struct cardstate *cs; + struct cardstate *cs = tty->driver_data; int retval = -ENODEV; - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); - return -ENODEV; - } - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); if (mutex_lock_interruptible(&cs->mutex)) @@ -414,9 +374,7 @@ static int if_write_room(struct tty_struct *tty) if (!cs->connected) { gig_dbg(DEBUG_IF, "not connected"); retval = -ENODEV; - } else if (!cs->open_count) - dev_warn(cs->dev, "%s: device not opened\n", __func__); - else if (cs->mstate != MS_LOCKED) { + } else if (cs->mstate != MS_LOCKED) { dev_warn(cs->dev, "can't write to unlocked device\n"); retval = -EBUSY; } else @@ -429,23 +387,15 @@ static int if_write_room(struct tty_struct *tty) static int if_chars_in_buffer(struct tty_struct *tty) { - struct cardstate *cs; + struct cardstate *cs = tty->driver_data; int retval = 0; - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); - return 0; - } - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); mutex_lock(&cs->mutex); if (!cs->connected) gig_dbg(DEBUG_IF, "not connected"); - else if (!cs->open_count) - dev_warn(cs->dev, "%s: device not opened\n", __func__); else if (cs->mstate != MS_LOCKED) dev_warn(cs->dev, "can't write to unlocked device\n"); else @@ -458,13 +408,7 @@ static int if_chars_in_buffer(struct tty_struct *tty) static void if_throttle(struct tty_struct *tty) { - struct cardstate *cs; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); - return; - } + struct cardstate *cs = tty->driver_data; gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); @@ -472,8 +416,6 @@ static void if_throttle(struct tty_struct *tty) if (!cs->connected) gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ - else if (!cs->open_count) - dev_warn(cs->dev, "%s: device not opened\n", __func__); else gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__); @@ -482,13 +424,7 @@ static void if_throttle(struct tty_struct *tty) static void if_unthrottle(struct tty_struct *tty) { - struct cardstate *cs; - - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); - return; - } + struct cardstate *cs = tty->driver_data; gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); @@ -496,8 +432,6 @@ static void if_unthrottle(struct tty_struct *tty) if (!cs->connected) gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ - else if (!cs->open_count) - dev_warn(cs->dev, "%s: device not opened\n", __func__); else gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__); @@ -506,18 +440,12 @@ static void if_unthrottle(struct tty_struct *tty) static void if_set_termios(struct tty_struct *tty, struct ktermios *old) { - struct cardstate *cs; + struct cardstate *cs = tty->driver_data; unsigned int iflag; unsigned int cflag; unsigned int old_cflag; unsigned int control_state, new_state; - cs = (struct cardstate *) tty->driver_data; - if (!cs) { - pr_err("%s: no cardstate\n", __func__); - return; - } - gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); mutex_lock(&cs->mutex); @@ -527,11 +455,6 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old) goto out; } - if (!cs->open_count) { - dev_warn(cs->dev, "%s: device not opened\n", __func__); - goto out; - } - iflag = tty->termios->c_iflag; cflag = tty->termios->c_cflag; old_cflag = old ? old->c_cflag : cflag; -- cgit v1.2.1 From 48a7466f4dd0104d87a6d8dd0f25027be89c8453 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 5 Mar 2012 14:52:55 +0100 Subject: TTY: isdn/gigaset, use tty_port Let us port the code to use tty_port. We now use open_count and tty from there. This allows us also to use tty_port_tty_set with tty refcounting instead of hand-written locking and logic. Note that tty and open_count are no longer protected by cs->lock. It is protected by tty_port->lock. But since all the places where they were used are now switched to the helpers, we are fine. Signed-off-by: Jiri Slaby Cc: Hansjoerg Lipp Acked-by: Tilman Schmidt Cc: Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/gigaset/common.c | 3 +-- drivers/isdn/gigaset/gigaset.h | 3 +-- drivers/isdn/gigaset/interface.c | 46 +++++++++++++++++----------------------- 3 files changed, 21 insertions(+), 31 deletions(-) (limited to 'drivers/isdn') diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index ac0186e54bf4..880f6ef0e18d 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -720,12 +720,11 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, tasklet_init(&cs->event_tasklet, gigaset_handle_event, (unsigned long) cs); + tty_port_init(&cs->port); cs->commands_pending = 0; cs->cur_at_seq = 0; cs->gotfwver = -1; - cs->open_count = 0; cs->dev = NULL; - cs->tty = NULL; cs->tty_dev = NULL; cs->cidmode = cidmode != 0; cs->tabnocid = gigaset_tab_nocid; diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 212efaf9a4e4..f877726d664b 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h @@ -433,8 +433,7 @@ struct cardstate { spinlock_t cmdlock; unsigned curlen, cmdbytes; - unsigned open_count; - struct tty_struct *tty; + struct tty_port port; struct tasklet_struct if_wake_tasklet; unsigned control_state; diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 8ff50b056285..8f8814afce86 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -146,7 +146,6 @@ static const struct tty_operations if_ops = { static int if_open(struct tty_struct *tty, struct file *filp) { struct cardstate *cs; - unsigned long flags; gig_dbg(DEBUG_IF, "%d+%d: %s()", tty->driver->minor_start, tty->index, __func__); @@ -161,12 +160,10 @@ static int if_open(struct tty_struct *tty, struct file *filp) } tty->driver_data = cs; - ++cs->open_count; + ++cs->port.count; - if (cs->open_count == 1) { - spin_lock_irqsave(&cs->lock, flags); - cs->tty = tty; - spin_unlock_irqrestore(&cs->lock, flags); + if (cs->port.count == 1) { + tty_port_tty_set(&cs->port, tty); tty->low_latency = 1; } @@ -177,7 +174,6 @@ static int if_open(struct tty_struct *tty, struct file *filp) static void if_close(struct tty_struct *tty, struct file *filp) { struct cardstate *cs = tty->driver_data; - unsigned long flags; if (!cs) { /* happens if we didn't find cs in open */ printk(KERN_DEBUG "%s: no cardstate\n", __func__); @@ -190,15 +186,10 @@ static void if_close(struct tty_struct *tty, struct file *filp) if (!cs->connected) gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ - else if (!cs->open_count) + else if (!cs->port.count) dev_warn(cs->dev, "%s: device not opened\n", __func__); - else { - if (!--cs->open_count) { - spin_lock_irqsave(&cs->lock, flags); - cs->tty = NULL; - spin_unlock_irqrestore(&cs->lock, flags); - } - } + else if (!--cs->port.count) + tty_port_tty_set(&cs->port, NULL); mutex_unlock(&cs->mutex); @@ -511,10 +502,13 @@ out: /* wakeup tasklet for the write operation */ static void if_wake(unsigned long data) { - struct cardstate *cs = (struct cardstate *) data; + struct cardstate *cs = (struct cardstate *)data; + struct tty_struct *tty = tty_port_tty_get(&cs->port); - if (cs->tty) - tty_wakeup(cs->tty); + if (tty) { + tty_wakeup(tty); + tty_kref_put(tty); + } } /*** interface to common ***/ @@ -567,18 +561,16 @@ void gigaset_if_free(struct cardstate *cs) void gigaset_if_receive(struct cardstate *cs, unsigned char *buffer, size_t len) { - unsigned long flags; - struct tty_struct *tty; + struct tty_struct *tty = tty_port_tty_get(&cs->port); - spin_lock_irqsave(&cs->lock, flags); - tty = cs->tty; - if (tty == NULL) + if (tty == NULL) { gig_dbg(DEBUG_IF, "receive on closed device"); - else { - tty_insert_flip_string(tty, buffer, len); - tty_flip_buffer_push(tty); + return; } - spin_unlock_irqrestore(&cs->lock, flags); + + tty_insert_flip_string(tty, buffer, len); + tty_flip_buffer_push(tty); + tty_kref_put(tty); } EXPORT_SYMBOL_GPL(gigaset_if_receive); -- cgit v1.2.1