linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/69] TTY buffer in tty_port -- prep no. 2
@ 2012-04-02 11:53 Jiri Slaby
  2012-04-02 11:53 ` [PATCH 01/69] TTY: crisv10, remove unused tmp_buf Jiri Slaby
                   ` (68 more replies)
  0 siblings, 69 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby

Hi,

this is the second series of patches which allow tty buffers to be
moved from tty_struct (present from open to close/hangup) to tty_port
(present as long as the device). This will allow us to get rid of the
tty refcounting in the interrupt service routines and other hot paths
after we are done. This is because we won't need to handle races among
ISRs, timers, hangups and others, because tty_port lives as long as an
interrupt/timer tick may occur. Unlike tty_struct.

In this series, second batch of drivers is converted to use tty_port.
The final few pieces are to come in the next window. Read: only very
few drivers are remaining. Then the whole switch will start.

Standard x86 stuff was runtime-tested. The rest is only checked to be
compilation-errors free.

Jiri Slaby (69):
  TTY: crisv10, remove unused tmp_buf
  TTY: crisv10, initialize tty_port
  TTY: deprecate linux/generic_serial.h
  ISDN: i4l, remove cvs crap
  TTY: isdn, remove callout
  TTY: isdn, remove ISDN_ASYNC_* flags
  TTY: isdn, do not play with module refcounts
  TTY: isdn, make some functions readable
  TTY: isdn, remove unused members from modem_info
  TTY: isdn, add tty_port
  TTY: isdn, use open/close_wait from tty_port
  TTY: isdn, use counts from tty_port
  TTY: isdn, use tty from tty_port
  TTY: isdn, use xmit_buf from tty_port
  TTY: isdn, define local tty_port
  TTY: isdn, use tty_port_close_end helper
  TTY: isdn, define tty_port_operations
  TTY: isdn, use tty_port_block_til_ready helper
  TTY: hso, do not set TTY MAGIC
  TTY: hso, free tty_driver
  TTY: hso, add tty_port
  TTY: hso, remove tty NULL checks fro tty->ops
  TTY: hso, use tty from tty_port
  TTY: con3215, centralize allocation
  TTY: con3215, remove tasklet for tty_wakeup
  TTY: con3215, add tty_port
  TTY: con3215, use tty from tty_port
  TTY: sclp_tty, add tty_port
  TTY: sclp_vt220, add tty_port
  TTY: sclp_vt220, remove unused allocation
  TTY: tty3270, move initialization to allocation
  TTY: tty3270, get rid of ugly aliasing
  TTY: tty3270, push tty down to tty3270_do_write
  TTY: tty3270, add tty_port
  TTY: bfin_jtag_comm, add tty_port
  TTY: bfin_jtag_comm, use tty from tty_port
  TTY: HVC, add tty_port
  TTY: HVC, use tty from tty_port
  TTY: HVC, use count from tty_port
  TTY: hvcs, add tty_port
  TTY: hvcs, use kref from tty_port
  TTY: hvcs, use tty from tty_port
  TTY: hvsi, CLOCAL is not in tty->flags
  TTY: hvsi, add tty_port
  TTY: hvsi, sanitize uses of tty
  TTY: hvsi, use tty from tty_port
  TTY: ipwireless, use synchronous hangup
  TTY: ipwireless, move prints to appropriate places
  TTY: ipwireless, add tty_port
  TTY: ipwireless, use tty from tty_port
  TTY: 68328serial, remove serial_state and friends
  TTY: 68328serial, remove unused stuff from m68k_serial
  TTY: 68328serial, remove garbage
  TTY: 68328serial, use ulong flags for interrupts status
  TTY: 68328serial, remove 68328serial.h
  TTY: 68328serial, add tty_port
  TTY: 68328serial, use open/close_wait from tty_port
  TTY: 68328serial, use close_delay/closing_wait from tty_port
  TTY: 68328serial, use flags from tty_port
  TTY: 68328serial, propagate tty
  TTY: 68328serial, use tty from tty_port
  TTY: 68328serial, use tty_port_block_til_ready
  TTY: usb/u_serial, add tty_port
  TTY: usb/u_serial, use tty from tty_port
  TTY: usb/u_serial use close_wait from tty_port
  TTY: rfcomm/tty, add tty_port
  TTY: rfcomm/tty, use tty_port refcounting
  TTY: rfcomm/tty, remove work for tty_wakeup
  TTY: rfcomm/tty, use count from tty_port

 drivers/isdn/i4l/isdn_common.c   |    2 -
 drivers/isdn/i4l/isdn_tty.c      |  466 +++++++++++++++-----------------------
 drivers/net/usb/hso.c            |  105 ++++-----
 drivers/s390/char/con3215.c      |  148 ++++++------
 drivers/s390/char/keyboard.c     |   30 +--
 drivers/s390/char/keyboard.h     |   14 +-
 drivers/s390/char/sclp_tty.c     |   33 +--
 drivers/s390/char/sclp_vt220.c   |   33 ++-
 drivers/s390/char/tty3270.c      |  121 +++++-----
 drivers/tty/bfin_jtag_comm.c     |   44 ++--
 drivers/tty/hvc/hvc_console.c    |   93 ++++----
 drivers/tty/hvc/hvc_console.h    |    4 +-
 drivers/tty/hvc/hvcs.c           |   74 +++---
 drivers/tty/hvc/hvsi.c           |  128 +++++------
 drivers/tty/hvc/hvsi_lib.c       |    2 +-
 drivers/tty/ipwireless/tty.c     |   81 +++----
 drivers/tty/serial/68328serial.c |  383 +++++++++++++------------------
 drivers/tty/serial/68328serial.h |  186 ---------------
 drivers/tty/serial/crisv10.c     |   28 +--
 drivers/usb/gadget/u_serial.c    |   51 ++---
 include/linux/generic_serial.h   |   64 +-----
 include/linux/isdn.h             |   26 +--
 net/bluetooth/rfcomm/tty.c       |  133 +++++------
 23 files changed, 851 insertions(+), 1398 deletions(-)
 delete mode 100644 drivers/tty/serial/68328serial.h

-- 
1.7.9.2



^ permalink raw reply	[flat|nested] 81+ messages in thread

* [PATCH 01/69] TTY: crisv10, remove unused tmp_buf
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-03 11:47   ` Jesper Nilsson
  2012-04-02 11:53 ` [PATCH 02/69] TTY: crisv10, initialize tty_port Jiri Slaby
                   ` (67 subsequent siblings)
  68 siblings, 1 reply; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Mikael Starvik, Jesper Nilsson,
	linux-cris-kernel

This used to be a helper buffer for generic_serial. generic_serial is
gone, tmp_buf shall be removed.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Mikael Starvik <starvik@axis.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: linux-cris-kernel@axis.com
---
 drivers/tty/serial/crisv10.c |   27 +--------------------------
 1 file changed, 1 insertion(+), 26 deletions(-)

diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c
index 5b07c0c..004ee2e 100644
--- a/drivers/tty/serial/crisv10.c
+++ b/drivers/tty/serial/crisv10.c
@@ -952,19 +952,6 @@ static const struct control_pins e100_modem_pins[NR_PORTS] =
 /* Input */
 #define E100_DSR_GET(info) ((*e100_modem_pins[(info)->line].dsr_port) & e100_modem_pins[(info)->line].dsr_mask)
 
-
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the memcpy_fromfs blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf;
-static DEFINE_MUTEX(tmp_buf_mutex);
-
 /* Calculate the chartime depending on baudrate, numbor of bits etc. */
 static void update_char_time(struct e100_serial * info)
 {
@@ -3150,7 +3137,7 @@ static int rs_raw_write(struct tty_struct *tty,
 
 	/* first some sanity checks */
 
-	if (!tty || !info->xmit.buf || !tmp_buf)
+	if (!tty || !info->xmit.buf)
 		return 0;
 
 #ifdef SERIAL_DEBUG_DATA
@@ -4106,7 +4093,6 @@ rs_open(struct tty_struct *tty, struct file * filp)
 {
 	struct e100_serial	*info;
 	int 			retval;
-	unsigned long           page;
 	int                     allocated_resources = 0;
 
 	info = rs_table + tty->index;
@@ -4124,17 +4110,6 @@ rs_open(struct tty_struct *tty, struct file * filp)
 
 	tty->low_latency = !!(info->flags & ASYNC_LOW_LATENCY);
 
-	if (!tmp_buf) {
-		page = get_zeroed_page(GFP_KERNEL);
-		if (!page) {
-			return -ENOMEM;
-		}
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-	}
-
 	/*
 	 * If the port is in the middle of closing, bail out now
 	 */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 02/69] TTY: crisv10, initialize tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
  2012-04-02 11:53 ` [PATCH 01/69] TTY: crisv10, remove unused tmp_buf Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-03 11:47   ` Jesper Nilsson
  2012-04-02 11:53 ` [PATCH 03/69] TTY: deprecate linux/generic_serial.h Jiri Slaby
                   ` (66 subsequent siblings)
  68 siblings, 1 reply; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Mikael Starvik, Jesper Nilsson,
	linux-cris-kernel

The tty_port used in the driver is left uninitialized. Add the
initialization there.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Mikael Starvik <starvik@axis.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: linux-cris-kernel@axis.com
---
 drivers/tty/serial/crisv10.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c
index 004ee2e..80b6b1b 100644
--- a/drivers/tty/serial/crisv10.c
+++ b/drivers/tty/serial/crisv10.c
@@ -4462,6 +4462,7 @@ static int __init rs_init(void)
 				info->enabled = 0;
 			}
 		}
+		tty_port_init(&info->port);
 		info->uses_dma_in = 0;
 		info->uses_dma_out = 0;
 		info->line = i;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 03/69] TTY: deprecate linux/generic_serial.h
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
  2012-04-02 11:53 ` [PATCH 01/69] TTY: crisv10, remove unused tmp_buf Jiri Slaby
  2012-04-02 11:53 ` [PATCH 02/69] TTY: crisv10, initialize tty_port Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 04/69] ISDN: i4l, remove cvs crap Jiri Slaby
                   ` (65 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby

Since nobody in the kernel includes that file, let us remove the
structs visible to the kernel.

However since the userspace sees the file, it still may include that.
hence deprecate the use of the header by an added cpp #warning.

We should remove the file completely after a couple of years.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/generic_serial.h |   64 ++--------------------------------------
 1 file changed, 2 insertions(+), 62 deletions(-)

diff --git a/include/linux/generic_serial.h b/include/linux/generic_serial.h
index fadff28..79b3eb3 100644
--- a/include/linux/generic_serial.h
+++ b/include/linux/generic_serial.h
@@ -4,7 +4,6 @@
  *  Copyright (C) 1998 R.E.Wolff@BitWizard.nl
  *
  *  written for the SX serial driver.
- *     Contains the code that should be shared over all the serial drivers.
  *
  *  Version 0.1 -- December, 1998.
  */
@@ -12,45 +11,8 @@
 #ifndef GENERIC_SERIAL_H
 #define GENERIC_SERIAL_H
 
-#ifdef __KERNEL__
-#include <linux/mutex.h>
-#include <linux/tty.h>
-
-struct real_driver {
-  void                    (*disable_tx_interrupts) (void *);
-  void                    (*enable_tx_interrupts) (void *);
-  void                    (*disable_rx_interrupts) (void *);
-  void                    (*enable_rx_interrupts) (void *);
-  void                    (*shutdown_port) (void*);
-  int                     (*set_real_termios) (void*);
-  int                     (*chars_in_buffer) (void*);
-  void                    (*close) (void*);
-  void                    (*hungup) (void*);
-  void                    (*getserial) (void*, struct serial_struct *sp);
-};
-
-
-
-struct gs_port {
-  int                     magic;
-  struct tty_port	  port;
-  unsigned char           *xmit_buf; 
-  int                     xmit_head;
-  int                     xmit_tail;
-  int                     xmit_cnt;
-  struct mutex            port_write_mutex;
-  unsigned long           event;
-  unsigned short          closing_wait;
-  int                     close_delay;
-  struct real_driver      *rd;
-  int                     wakeup_chars;
-  int                     baud_base;
-  int                     baud;
-  int                     custom_divisor;
-  spinlock_t              driver_lock;
-};
-
-#endif /* __KERNEL__ */
+#warning Use of this header is deprecated.
+#warning Since nobody sets the constants defined here for you, you should not, in any case, use them. Including the header is thus pointless.
 
 /* Flags */
 /* Warning: serial.h defines some ASYNC_ flags, they say they are "only"
@@ -60,8 +22,6 @@ struct gs_port {
 #define GS_RX_INTEN      0x00400000
 #define GS_ACTIVE        0x00200000
 
-
-
 #define GS_TYPE_NORMAL   1
 
 #define GS_DEBUG_FLUSH   0x00000001
@@ -72,24 +32,4 @@ struct gs_port {
 #define GS_DEBUG_FLOW    0x00000020
 #define GS_DEBUG_WRITE   0x00000040
 
-#ifdef __KERNEL__
-int gs_put_char(struct tty_struct *tty, unsigned char ch);
-int  gs_write(struct tty_struct *tty, 
-             const unsigned char *buf, int count);
-int  gs_write_room(struct tty_struct *tty);
-int  gs_chars_in_buffer(struct tty_struct *tty);
-void gs_flush_buffer(struct tty_struct *tty);
-void gs_flush_chars(struct tty_struct *tty);
-void gs_stop(struct tty_struct *tty);
-void gs_start(struct tty_struct *tty);
-void gs_hangup(struct tty_struct *tty);
-int  gs_block_til_ready(void *port, struct file *filp);
-void gs_close(struct tty_struct *tty, struct file *filp);
-void gs_set_termios (struct tty_struct * tty, 
-                     struct ktermios * old_termios);
-int  gs_init_port(struct gs_port *port);
-int  gs_setserial(struct gs_port *port, struct serial_struct __user *sp);
-int  gs_getserial(struct gs_port *port, struct serial_struct __user *sp);
-void gs_got_break(struct gs_port *port);
-#endif /* __KERNEL__ */
 #endif
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 04/69] ISDN: i4l, remove cvs crap
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (2 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 03/69] TTY: deprecate linux/generic_serial.h Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 05/69] TTY: isdn, remove callout Jiri Slaby
                   ` (64 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

CVS $Id$ is unused and makes no sense in our tree. Get rid of that.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |    6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 3831abd..1d701cd 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1,5 +1,4 @@
-/* $Id: isdn_tty.c,v 1.1.2.3 2004/02/10 01:07:13 keil Exp $
- *
+/*
  * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
  *
  * Copyright 1994-1999  by Fritz Elfert (fritz@isdn4linux.de)
@@ -48,9 +47,6 @@ static int bit2si[8] =
 static int si2bit[8] =
 {4, 1, 4, 4, 4, 4, 4, 4};
 
-char *isdn_tty_revision = "$Revision: 1.1.2.3 $";
-
-
 /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
  * to stuff incoming data directly into a tty's flip-buffer. This
  * is done to speed up tty-receiving if the receive-queue is empty.
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 05/69] TTY: isdn, remove callout
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (3 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 04/69] ISDN: i4l, remove cvs crap Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 06/69] TTY: isdn, remove ISDN_ASYNC_* flags Jiri Slaby
                   ` (63 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

I wonder how this survived there during the whole 2.6 series until now
:D.

Callouts are not used for a decade, so let us remove it also from
isdn. This means removal of ISDN_ASYNC_CALLOUT_ACTIVE which is never
raised in info->flags and callout_termios which are never used.

This will help us to get rid of ISDN_ASYNC_* flags and use ASYNC ones
from serial.h. And then we will switch to tty_port.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   32 ++++++--------------------------
 include/linux/isdn.h        |    3 ---
 2 files changed, 6 insertions(+), 29 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 1d701cd..27f7092 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1504,18 +1504,11 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
 		info->flags |= ISDN_ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
-	if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1546,8 +1539,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 #endif
 			break;
 		}
-		if (!(info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ISDN_ASYNC_CLOSING) &&
+		if (!(info->flags & ISDN_ASYNC_CLOSING) &&
 		    (do_clocal || (info->msr & UART_MSR_DCD))) {
 			break;
 		}
@@ -1670,14 +1662,6 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 		return;
 	}
 	info->flags |= ISDN_ASYNC_CLOSING;
-	/*
-	 * Save the termios structure, since this port may have
-	 * separate termios for callout and dialin.
-	 */
-	if (info->flags & ISDN_ASYNC_NORMAL_ACTIVE)
-		info->normal_termios = *tty->termios;
-	if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
 
 	tty->closing = 1;
 	/*
@@ -1731,7 +1715,7 @@ isdn_tty_hangup(struct tty_struct *tty)
 		return;
 	isdn_tty_shutdown(info);
 	info->count = 0;
-	info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~ISDN_ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -2116,8 +2100,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
 	return (wret == 2) ? 3 : 0;
 }
 
-#define TTY_IS_ACTIVE(info)						\
-	(info->flags & (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE))
+#define TTY_IS_ACTIVE(info)	(info->flags & ISDN_ASYNC_NORMAL_ACTIVE)
 
 int
 isdn_tty_stat_callback(int i, isdn_ctrl *c)
@@ -2628,11 +2611,8 @@ isdn_tty_modem_result(int code, modem_info *info)
 		if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) {
 			return;
 		}
-		if ((info->flags & ISDN_ASYNC_CHECK_CD) &&
-		    (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
-		       (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) {
+		if (info->flags & ISDN_ASYNC_CHECK_CD)
 			tty_hangup(info->tty);
-		}
 	}
 }
 
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index 292f27a..d13b76d 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -393,7 +393,6 @@ typedef struct isdn_net_dev_s {
 
 #define ISDN_ASYNC_MAGIC          0x49344C01 /* for paranoia-checking        */
 #define ISDN_ASYNC_INITIALIZED	  0x80000000 /* port was initialized         */
-#define ISDN_ASYNC_CALLOUT_ACTIVE 0x40000000 /* Call out device active       */
 #define ISDN_ASYNC_NORMAL_ACTIVE  0x20000000 /* Normal device active         */
 #define ISDN_ASYNC_CLOSING	  0x08000000 /* Serial port is closing       */
 #define ISDN_ASYNC_CTS_FLOW	  0x04000000 /* Do CTS flow control          */
@@ -498,8 +497,6 @@ typedef struct modem_info {
 #endif
   struct tty_struct 	*tty;            /* Pointer to corresponding tty   */
   atemu                 emu;             /* AT-emulator data               */
-  struct ktermios	normal_termios;  /* For saving termios structs     */
-  struct ktermios	callout_termios;
   wait_queue_head_t	open_wait, close_wait;
   spinlock_t	        readlock;
 } modem_info;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 06/69] TTY: isdn, remove ISDN_ASYNC_* flags
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (4 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 05/69] TTY: isdn, remove callout Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 07/69] TTY: isdn, do not play with module refcounts Jiri Slaby
                   ` (62 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

They are the same as TTY ones. So there is no need to redefine them.
Remove ISDN_ASYNC_* and use only ASYNC_*. Except the MAGIC number, of
course.

While we are there, remove also the SERIAL_TYPE flags which are
unused.

Perhaps we should move the ASYNC flags from serial.h to tty.h given
they are used by the tty layer and tty drivers, not only serial?

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   59 ++++++++++++++++++++++---------------------
 include/linux/isdn.h        |   12 ---------
 2 files changed, 30 insertions(+), 41 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 27f7092..bcf4bbe 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -11,6 +11,7 @@
 #undef ISDN_TTY_STAT_DEBUG
 
 #include <linux/isdn.h>
+#include <linux/serial.h> /* ASYNC_* flags */
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
@@ -1036,20 +1037,20 @@ isdn_tty_change_speed(modem_info *info)
 
 	/* CTS flow control flag and modem status interrupts */
 	if (cflag & CRTSCTS) {
-		info->flags |= ISDN_ASYNC_CTS_FLOW;
+		info->flags |= ASYNC_CTS_FLOW;
 	} else
-		info->flags &= ~ISDN_ASYNC_CTS_FLOW;
+		info->flags &= ~ASYNC_CTS_FLOW;
 	if (cflag & CLOCAL)
-		info->flags &= ~ISDN_ASYNC_CHECK_CD;
+		info->flags &= ~ASYNC_CHECK_CD;
 	else {
-		info->flags |= ISDN_ASYNC_CHECK_CD;
+		info->flags |= ASYNC_CHECK_CD;
 	}
 }
 
 static int
 isdn_tty_startup(modem_info *info)
 {
-	if (info->flags & ISDN_ASYNC_INITIALIZED)
+	if (info->flags & ASYNC_INITIALIZED)
 		return 0;
 	isdn_lock_drivers();
 #ifdef ISDN_DEBUG_MODEM_OPEN
@@ -1066,7 +1067,7 @@ isdn_tty_startup(modem_info *info)
 	 */
 	isdn_tty_change_speed(info);
 
-	info->flags |= ISDN_ASYNC_INITIALIZED;
+	info->flags |= ASYNC_INITIALIZED;
 	info->msr |= (UART_MSR_DSR | UART_MSR_CTS);
 	info->send_outstanding = 0;
 	return 0;
@@ -1079,7 +1080,7 @@ isdn_tty_startup(modem_info *info)
 static void
 isdn_tty_shutdown(modem_info *info)
 {
-	if (!(info->flags & ISDN_ASYNC_INITIALIZED))
+	if (!(info->flags & ASYNC_INITIALIZED))
 		return;
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line);
@@ -1099,7 +1100,7 @@ isdn_tty_shutdown(modem_info *info)
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
-	info->flags &= ~ISDN_ASYNC_INITIALIZED;
+	info->flags &= ~ASYNC_INITIALIZED;
 }
 
 /* isdn_tty_write() is the main send-routine. It is called from the upper
@@ -1486,11 +1487,11 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	 * until it's done, and then try again.
 	 */
 	if (tty_hung_up_p(filp) ||
-	    (info->flags & ISDN_ASYNC_CLOSING)) {
-		if (info->flags & ISDN_ASYNC_CLOSING)
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
 			interruptible_sleep_on(&info->close_wait);
 #ifdef MODEM_DO_RESTART
-		if (info->flags & ISDN_ASYNC_HUP_NOTIFY)
+		if (info->flags & ASYNC_HUP_NOTIFY)
 			return -EAGAIN;
 		else
 			return -ERESTARTSYS;
@@ -1504,7 +1505,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		info->flags |= ISDN_ASYNC_NORMAL_ACTIVE;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 	if (tty->termios->c_cflag & CLOCAL)
@@ -1528,9 +1529,9 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	while (1) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
-		    !(info->flags & ISDN_ASYNC_INITIALIZED)) {
+		    !(info->flags & ASYNC_INITIALIZED)) {
 #ifdef MODEM_DO_RESTART
-			if (info->flags & ISDN_ASYNC_HUP_NOTIFY)
+			if (info->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
 				retval = -ERESTARTSYS;
@@ -1539,7 +1540,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 #endif
 			break;
 		}
-		if (!(info->flags & ISDN_ASYNC_CLOSING) &&
+		if (!(info->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (info->msr & UART_MSR_DCD))) {
 			break;
 		}
@@ -1564,7 +1565,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 #endif
 	if (retval)
 		return retval;
-	info->flags |= ISDN_ASYNC_NORMAL_ACTIVE;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
 	return 0;
 }
 
@@ -1661,7 +1662,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 		module_put(info->owner);
 		return;
 	}
-	info->flags |= ISDN_ASYNC_CLOSING;
+	info->flags |= ASYNC_CLOSING;
 
 	tty->closing = 1;
 	/*
@@ -1670,7 +1671,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	 * interrupt driver to stop checking the data ready bit in the
 	 * line status register.
 	 */
-	if (info->flags & ISDN_ASYNC_INITIALIZED) {
+	if (info->flags & ASYNC_INITIALIZED) {
 		tty_wait_until_sent_from_close(tty, 3000);	/* 30 seconds timeout */
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
@@ -1696,7 +1697,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 		msleep_interruptible(500);
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_close normal exit\n");
@@ -1715,7 +1716,7 @@ isdn_tty_hangup(struct tty_struct *tty)
 		return;
 	isdn_tty_shutdown(info);
 	info->count = 0;
-	info->flags &= ~ISDN_ASYNC_NORMAL_ACTIVE;
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -2061,7 +2062,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
 #endif
 			if (
 #ifndef FIX_FILE_TRANSFER
-				(info->flags & ISDN_ASYNC_NORMAL_ACTIVE) &&
+				(info->flags & ASYNC_NORMAL_ACTIVE) &&
 #endif
 				(info->isdn_driver == -1) &&
 				(info->isdn_channel == -1) &&
@@ -2100,7 +2101,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
 	return (wret == 2) ? 3 : 0;
 }
 
-#define TTY_IS_ACTIVE(info)	(info->flags & ISDN_ASYNC_NORMAL_ACTIVE)
+#define TTY_IS_ACTIVE(info)	(info->flags & ASYNC_NORMAL_ACTIVE)
 
 int
 isdn_tty_stat_callback(int i, isdn_ctrl *c)
@@ -2319,7 +2320,7 @@ isdn_tty_at_cout(char *msg, modem_info *info)
 
 	spin_lock_irqsave(&info->readlock, flags);
 	tty = info->tty;
-	if ((info->flags & ISDN_ASYNC_CLOSING) || (!tty)) {
+	if ((info->flags & ASYNC_CLOSING) || (!tty)) {
 		spin_unlock_irqrestore(&info->readlock, flags);
 		return;
 	}
@@ -2469,15 +2470,15 @@ isdn_tty_modem_result(int code, modem_info *info)
 	case RESULT_NO_CARRIER:
 #ifdef ISDN_DEBUG_MODEM_HUP
 		printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n",
-		       (info->flags & ISDN_ASYNC_CLOSING),
+		       (info->flags & ASYNC_CLOSING),
 		       (!info->tty));
 #endif
 		m->mdmreg[REG_RINGCNT] = 0;
 		del_timer(&info->nc_timer);
 		info->ncarrier = 0;
-		if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) {
+		if ((info->flags & ASYNC_CLOSING) || (!info->tty))
 			return;
-		}
+
 #ifdef CONFIG_ISDN_AUDIO
 		if (info->vonline & 1) {
 #ifdef ISDN_DEBUG_MODEM_VOICE
@@ -2608,10 +2609,10 @@ isdn_tty_modem_result(int code, modem_info *info)
 		}
 	}
 	if (code == RESULT_NO_CARRIER) {
-		if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) {
+		if ((info->flags & ASYNC_CLOSING) || (!info->tty))
 			return;
-		}
-		if (info->flags & ISDN_ASYNC_CHECK_CD)
+
+		if (info->flags & ASYNC_CHECK_CD)
 			tty_hangup(info->tty);
 	}
 }
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index d13b76d..1b4b4c1 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -392,20 +392,8 @@ typedef struct isdn_net_dev_s {
 /*======================= Start of ISDN-tty stuff ===========================*/
 
 #define ISDN_ASYNC_MAGIC          0x49344C01 /* for paranoia-checking        */
-#define ISDN_ASYNC_INITIALIZED	  0x80000000 /* port was initialized         */
-#define ISDN_ASYNC_NORMAL_ACTIVE  0x20000000 /* Normal device active         */
-#define ISDN_ASYNC_CLOSING	  0x08000000 /* Serial port is closing       */
-#define ISDN_ASYNC_CTS_FLOW	  0x04000000 /* Do CTS flow control          */
-#define ISDN_ASYNC_CHECK_CD	  0x02000000 /* i.e., CLOCAL                 */
-#define ISDN_ASYNC_HUP_NOTIFY         0x0001 /* Notify tty on hangups/closes */
-#define ISDN_ASYNC_SESSION_LOCKOUT    0x0100 /* Lock cua opens on session    */
-#define ISDN_ASYNC_PGRP_LOCKOUT       0x0200 /* Lock cua opens on pgrp       */
-#define ISDN_ASYNC_CALLOUT_NOHUP      0x0400 /* No hangup for cui            */
-#define ISDN_ASYNC_SPLIT_TERMIOS      0x0008 /* Sep. termios for dialin/out  */
 #define ISDN_SERIAL_XMIT_SIZE           1024 /* Default bufsize for write    */
 #define ISDN_SERIAL_XMIT_MAX            4000 /* Maximum bufsize for write    */
-#define ISDN_SERIAL_TYPE_NORMAL            1
-#define ISDN_SERIAL_TYPE_CALLOUT           2
 
 #ifdef CONFIG_ISDN_AUDIO
 /* For using sk_buffs with audio we need some private variables
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 07/69] TTY: isdn, do not play with module refcounts
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (5 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 06/69] TTY: isdn, remove ISDN_ASYNC_* flags Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 08/69] TTY: isdn, make some functions readable Jiri Slaby
                   ` (61 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

The module which called allocate_tty_driver is already refcounted by
the TTY layer automatically. And since THIS_MODULE is isdn_tty and it
allocated the tty_driver, there is no need to do the counts in isdn's
tty->ops->open/close.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   11 -----------
 include/linux/isdn.h        |    1 -
 2 files changed, 12 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index bcf4bbe..1ff3072 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1584,10 +1584,6 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
 	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)) {
-		printk(KERN_WARNING "%s: cannot reserve module\n", __func__);
-		return -ENODEV;
-	}
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name,
 	       info->count);
@@ -1603,7 +1599,6 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
 #ifdef ISDN_DEBUG_MODEM_OPEN
 		printk(KERN_DEBUG "isdn_tty_open return after startup\n");
 #endif
-		module_put(info->owner);
 		return retval;
 	}
 	retval = isdn_tty_block_til_ready(tty, filp, info);
@@ -1611,7 +1606,6 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
 #ifdef ISDN_DEBUG_MODEM_OPEN
 		printk(KERN_DEBUG "isdn_tty_open return after isdn_tty_block_til_ready \n");
 #endif
-		module_put(info->owner);
 		return retval;
 	}
 #ifdef ISDN_DEBUG_MODEM_OPEN
@@ -1659,7 +1653,6 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 #ifdef ISDN_DEBUG_MODEM_OPEN
 		printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n");
 #endif
-		module_put(info->owner);
 		return;
 	}
 	info->flags |= ASYNC_CLOSING;
@@ -1692,7 +1685,6 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	info->tty = NULL;
 	info->ncarrier = 0;
 	tty->closing = 0;
-	module_put(info->owner);
 	if (info->blocked_open) {
 		msleep_interruptible(500);
 		wake_up_interruptible(&info->open_wait);
@@ -1880,9 +1872,6 @@ isdn_tty_modem_init(void)
 			goto err_unregister;
 		}
 #endif
-#ifdef MODULE
-		info->owner = THIS_MODULE;
-#endif
 		spin_lock_init(&info->readlock);
 		sprintf(info->last_cause, "0000");
 		sprintf(info->last_num, "none");
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index 1b4b4c1..66d9d71 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -435,7 +435,6 @@ typedef struct atemu {
 /* Private data (similar to async_struct in <linux/serial.h>) */
 typedef struct modem_info {
   int			magic;
-  struct module		*owner;
   int			flags;		 /* defined in tty.h               */
   int			x_char;		 /* xon/xoff character             */
   int			mcr;		 /* Modem control register         */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 08/69] TTY: isdn, make some functions readable
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (6 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 07/69] TTY: isdn, do not play with module refcounts Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 09/69] TTY: isdn, remove unused members from modem_info Jiri Slaby
                   ` (60 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

Huh, this was a mess.

* Remove the 5 indent levels by just returning from isdn_tty_try_read
  when the conditions there are not satisfied.
* Use 'continue' in loop in isdn_tty_readmodem to save 2 levels.
* Chain 'if's in isdn_tty_modem_escape.
* Use 'continue' in loop in isdn_tty_carrier_timeout to save 1 level.

Better to look at this patch with -w -b.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |  178 ++++++++++++++++++++++---------------------
 1 file changed, 93 insertions(+), 85 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 1ff3072..74b0518 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -65,49 +65,54 @@ isdn_tty_try_read(modem_info *info, struct sk_buff *skb)
 	struct tty_struct *tty;
 	char last;
 
-	if (info->online) {
-		if ((tty = info->tty)) {
-			if (info->mcr & UART_MCR_RTS) {
-				len = skb->len
+	if (!info->online)
+		return 0;
+
+	tty = info->tty;
+	if (!tty)
+		return 0;
+
+	if (!(info->mcr & UART_MCR_RTS))
+		return 0;
+
+	len = skb->len
 #ifdef CONFIG_ISDN_AUDIO
-					+ ISDN_AUDIO_SKB_DLECOUNT(skb)
+		+ ISDN_AUDIO_SKB_DLECOUNT(skb)
 #endif
-					;
+		;
+
+	c = tty_buffer_request_room(tty, len);
+	if (c < len)
+		return 0;
 
-				c = tty_buffer_request_room(tty, len);
-				if (c >= len) {
-#ifdef CONFIG_ISDN_AUDIO
-					if (ISDN_AUDIO_SKB_DLECOUNT(skb)) {
-						int l = skb->len;
-						unsigned char *dp = skb->data;
-						while (--l) {
-							if (*dp == DLE)
-								tty_insert_flip_char(tty, DLE, 0);
-							tty_insert_flip_char(tty, *dp++, 0);
-						}
-						if (*dp == DLE)
-							tty_insert_flip_char(tty, DLE, 0);
-						last = *dp;
-					} else {
-#endif
-						if (len > 1)
-							tty_insert_flip_string(tty, skb->data, len - 1);
-						last = skb->data[len - 1];
 #ifdef CONFIG_ISDN_AUDIO
-					}
+	if (ISDN_AUDIO_SKB_DLECOUNT(skb)) {
+		int l = skb->len;
+		unsigned char *dp = skb->data;
+		while (--l) {
+			if (*dp == DLE)
+				tty_insert_flip_char(tty, DLE, 0);
+			tty_insert_flip_char(tty, *dp++, 0);
+		}
+		if (*dp == DLE)
+			tty_insert_flip_char(tty, DLE, 0);
+		last = *dp;
+	} else {
 #endif
-					if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP)
-						tty_insert_flip_char(tty, last, 0xFF);
-					else
-						tty_insert_flip_char(tty, last, TTY_NORMAL);
-					tty_flip_buffer_push(tty);
-					kfree_skb(skb);
-					return 1;
-				}
-			}
-		}
+		if (len > 1)
+			tty_insert_flip_string(tty, skb->data, len - 1);
+		last = skb->data[len - 1];
+#ifdef CONFIG_ISDN_AUDIO
 	}
-	return 0;
+#endif
+	if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP)
+		tty_insert_flip_char(tty, last, 0xFF);
+	else
+		tty_insert_flip_char(tty, last, TTY_NORMAL);
+	tty_flip_buffer_push(tty);
+	kfree_skb(skb);
+
+	return 1;
 }
 
 /* isdn_tty_readmodem() is called periodically from within timer-interrupt.
@@ -125,35 +130,39 @@ isdn_tty_readmodem(void)
 	modem_info *info;
 
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		if ((midx = dev->m_idx[i]) >= 0) {
-			info = &dev->mdm.info[midx];
-			if (info->online) {
-				r = 0;
+		midx = dev->m_idx[i];
+		if (midx < 0)
+			continue;
+
+		info = &dev->mdm.info[midx];
+		if (!info->online)
+			continue;
+
+		r = 0;
 #ifdef CONFIG_ISDN_AUDIO
-				isdn_audio_eval_dtmf(info);
-				if ((info->vonline & 1) && (info->emu.vpar[1]))
-					isdn_audio_eval_silence(info);
-#endif
-				if ((tty = info->tty)) {
-					if (info->mcr & UART_MCR_RTS) {
-						/* CISCO AsyncPPP Hack */
-						if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
-							r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0);
-						else
-							r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1);
-						if (r)
-							tty_flip_buffer_push(tty);
-					} else
-						r = 1;
-				} else
-					r = 1;
-				if (r) {
-					info->rcvsched = 0;
-					resched = 1;
-				} else
-					info->rcvsched = 1;
-			}
-		}
+		isdn_audio_eval_dtmf(info);
+		if ((info->vonline & 1) && (info->emu.vpar[1]))
+			isdn_audio_eval_silence(info);
+#endif
+		tty = info->tty;
+		if (tty) {
+			if (info->mcr & UART_MCR_RTS) {
+				/* CISCO AsyncPPP Hack */
+				if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
+					r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0);
+				else
+					r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1);
+				if (r)
+					tty_flip_buffer_push(tty);
+			} else
+				r = 1;
+		} else
+			r = 1;
+		if (r) {
+			info->rcvsched = 0;
+			resched = 1;
+		} else
+			info->rcvsched = 1;
 	}
 	if (!resched)
 		isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 0);
@@ -3769,19 +3778,19 @@ isdn_tty_modem_escape(void)
 	int midx;
 
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-		if (USG_MODEM(dev->usage[i]))
-			if ((midx = dev->m_idx[i]) >= 0) {
-				modem_info *info = &dev->mdm.info[midx];
-				if (info->online) {
-					ton = 1;
-					if ((info->emu.pluscount == 3) &&
-					    time_after(jiffies , info->emu.lastplus + PLUSWAIT2)) {
-						info->emu.pluscount = 0;
-						info->online = 0;
-						isdn_tty_modem_result(RESULT_OK, info);
-					}
+		if (USG_MODEM(dev->usage[i]) && (midx = dev->m_idx[i]) >= 0) {
+			modem_info *info = &dev->mdm.info[midx];
+			if (info->online) {
+				ton = 1;
+				if ((info->emu.pluscount == 3) &&
+				    time_after(jiffies,
+					    info->emu.lastplus + PLUSWAIT2)) {
+					info->emu.pluscount = 0;
+					info->online = 0;
+					isdn_tty_modem_result(RESULT_OK, info);
 				}
 			}
+		}
 	isdn_timer_ctrl(ISDN_TIMER_MODEMPLUS, ton);
 }
 
@@ -3839,15 +3848,14 @@ isdn_tty_carrier_timeout(void)
 
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 		modem_info *info = &dev->mdm.info[i];
-		if (info->dialing) {
-			if (info->emu.carrierwait++ > info->emu.mdmreg[REG_WAITC]) {
-				info->dialing = 0;
-				isdn_tty_modem_result(RESULT_NO_CARRIER, info);
-				isdn_tty_modem_hup(info, 1);
-			}
-			else
-				ton = 1;
-		}
+		if (!info->dialing)
+			continue;
+		if (info->emu.carrierwait++ > info->emu.mdmreg[REG_WAITC]) {
+			info->dialing = 0;
+			isdn_tty_modem_result(RESULT_NO_CARRIER, info);
+			isdn_tty_modem_hup(info, 1);
+		} else
+			ton = 1;
 	}
 	isdn_timer_ctrl(ISDN_TIMER_CARRIER, ton);
 }
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 09/69] TTY: isdn, remove unused members from modem_info
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (7 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 08/69] TTY: isdn, make some functions readable Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 10/69] TTY: isdn, add tty_port Jiri Slaby
                   ` (59 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

session and pgrp are unused. Prune them.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 include/linux/isdn.h |    2 --
 1 file changed, 2 deletions(-)

diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index 66d9d71..63af320 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -443,8 +443,6 @@ typedef struct modem_info {
   int			line;
   int			count;		 /* # of fd on device              */
   int			blocked_open;	 /* # of blocked opens             */
-  long			session;	 /* Session of opening process     */
-  long			pgrp;		 /* pgrp of opening process        */
   int                   online;          /* 1 = B-Channel is up, drop data */
 					 /* 2 = B-Channel is up, deliver d.*/
   int                   dialing;         /* Dial in progress or ATA        */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 10/69] TTY: isdn, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (8 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 09/69] TTY: isdn, remove unused members from modem_info Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 11/69] TTY: isdn, use open/close_wait from tty_port Jiri Slaby
                   ` (58 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

And use tty_port->flags now. Other members will follow.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   60 ++++++++++++++++++++++---------------------
 include/linux/isdn.h        |    3 ++-
 2 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 74b0518..8ba526d 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1046,20 +1046,20 @@ isdn_tty_change_speed(modem_info *info)
 
 	/* CTS flow control flag and modem status interrupts */
 	if (cflag & CRTSCTS) {
-		info->flags |= ASYNC_CTS_FLOW;
+		info->port.flags |= ASYNC_CTS_FLOW;
 	} else
-		info->flags &= ~ASYNC_CTS_FLOW;
+		info->port.flags &= ~ASYNC_CTS_FLOW;
 	if (cflag & CLOCAL)
-		info->flags &= ~ASYNC_CHECK_CD;
+		info->port.flags &= ~ASYNC_CHECK_CD;
 	else {
-		info->flags |= ASYNC_CHECK_CD;
+		info->port.flags |= ASYNC_CHECK_CD;
 	}
 }
 
 static int
 isdn_tty_startup(modem_info *info)
 {
-	if (info->flags & ASYNC_INITIALIZED)
+	if (info->port.flags & ASYNC_INITIALIZED)
 		return 0;
 	isdn_lock_drivers();
 #ifdef ISDN_DEBUG_MODEM_OPEN
@@ -1076,7 +1076,7 @@ isdn_tty_startup(modem_info *info)
 	 */
 	isdn_tty_change_speed(info);
 
-	info->flags |= ASYNC_INITIALIZED;
+	info->port.flags |= ASYNC_INITIALIZED;
 	info->msr |= (UART_MSR_DSR | UART_MSR_CTS);
 	info->send_outstanding = 0;
 	return 0;
@@ -1089,7 +1089,7 @@ isdn_tty_startup(modem_info *info)
 static void
 isdn_tty_shutdown(modem_info *info)
 {
-	if (!(info->flags & ASYNC_INITIALIZED))
+	if (!(info->port.flags & ASYNC_INITIALIZED))
 		return;
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line);
@@ -1109,7 +1109,7 @@ isdn_tty_shutdown(modem_info *info)
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
-	info->flags &= ~ASYNC_INITIALIZED;
+	info->port.flags &= ~ASYNC_INITIALIZED;
 }
 
 /* isdn_tty_write() is the main send-routine. It is called from the upper
@@ -1496,11 +1496,11 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	 * until it's done, and then try again.
 	 */
 	if (tty_hung_up_p(filp) ||
-	    (info->flags & ASYNC_CLOSING)) {
-		if (info->flags & ASYNC_CLOSING)
+	    (info->port.flags & ASYNC_CLOSING)) {
+		if (info->port.flags & ASYNC_CLOSING)
 			interruptible_sleep_on(&info->close_wait);
 #ifdef MODEM_DO_RESTART
-		if (info->flags & ASYNC_HUP_NOTIFY)
+		if (info->port.flags & ASYNC_HUP_NOTIFY)
 			return -EAGAIN;
 		else
 			return -ERESTARTSYS;
@@ -1514,7 +1514,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		info->flags |= ASYNC_NORMAL_ACTIVE;
+		info->port.flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 	if (tty->termios->c_cflag & CLOCAL)
@@ -1538,9 +1538,9 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	while (1) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
-		    !(info->flags & ASYNC_INITIALIZED)) {
+		    !(info->port.flags & ASYNC_INITIALIZED)) {
 #ifdef MODEM_DO_RESTART
-			if (info->flags & ASYNC_HUP_NOTIFY)
+			if (info->port.flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
 				retval = -ERESTARTSYS;
@@ -1549,7 +1549,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CLOSING) &&
+		if (!(info->port.flags & ASYNC_CLOSING) &&
 		    (do_clocal || (info->msr & UART_MSR_DCD))) {
 			break;
 		}
@@ -1574,7 +1574,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 #endif
 	if (retval)
 		return retval;
-	info->flags |= ASYNC_NORMAL_ACTIVE;
+	info->port.flags |= ASYNC_NORMAL_ACTIVE;
 	return 0;
 }
 
@@ -1600,6 +1600,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
 	info->count++;
 	tty->driver_data = info;
 	info->tty = tty;
+	tty->port = &info->port;
 	/*
 	 * Start up serial port
 	 */
@@ -1664,7 +1665,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 #endif
 		return;
 	}
-	info->flags |= ASYNC_CLOSING;
+	info->port.flags |= ASYNC_CLOSING;
 
 	tty->closing = 1;
 	/*
@@ -1673,7 +1674,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	 * interrupt driver to stop checking the data ready bit in the
 	 * line status register.
 	 */
-	if (info->flags & ASYNC_INITIALIZED) {
+	if (info->port.flags & ASYNC_INITIALIZED) {
 		tty_wait_until_sent_from_close(tty, 3000);	/* 30 seconds timeout */
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
@@ -1698,7 +1699,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 		msleep_interruptible(500);
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+	info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_close normal exit\n");
@@ -1717,7 +1718,7 @@ isdn_tty_hangup(struct tty_struct *tty)
 		return;
 	isdn_tty_shutdown(info);
 	info->count = 0;
-	info->flags &= ~ASYNC_NORMAL_ACTIVE;
+	info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1881,6 +1882,7 @@ isdn_tty_modem_init(void)
 			goto err_unregister;
 		}
 #endif
+		tty_port_init(&info->port);
 		spin_lock_init(&info->readlock);
 		sprintf(info->last_cause, "0000");
 		sprintf(info->last_num, "none");
@@ -2055,12 +2057,12 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
 #ifdef ISDN_DEBUG_MODEM_ICALL
 			printk(KERN_DEBUG "m_fi: match1 wret=%d\n", wret);
 			printk(KERN_DEBUG "m_fi: idx=%d flags=%08lx drv=%d ch=%d usg=%d\n", idx,
-			       info->flags, info->isdn_driver, info->isdn_channel,
-			       dev->usage[idx]);
+			       info->port.flags, info->isdn_driver,
+			       info->isdn_channel, dev->usage[idx]);
 #endif
 			if (
 #ifndef FIX_FILE_TRANSFER
-				(info->flags & ASYNC_NORMAL_ACTIVE) &&
+				(info->port.flags & ASYNC_NORMAL_ACTIVE) &&
 #endif
 				(info->isdn_driver == -1) &&
 				(info->isdn_channel == -1) &&
@@ -2099,7 +2101,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
 	return (wret == 2) ? 3 : 0;
 }
 
-#define TTY_IS_ACTIVE(info)	(info->flags & ASYNC_NORMAL_ACTIVE)
+#define TTY_IS_ACTIVE(info)	(info->port.flags & ASYNC_NORMAL_ACTIVE)
 
 int
 isdn_tty_stat_callback(int i, isdn_ctrl *c)
@@ -2318,7 +2320,7 @@ isdn_tty_at_cout(char *msg, modem_info *info)
 
 	spin_lock_irqsave(&info->readlock, flags);
 	tty = info->tty;
-	if ((info->flags & ASYNC_CLOSING) || (!tty)) {
+	if ((info->port.flags & ASYNC_CLOSING) || (!tty)) {
 		spin_unlock_irqrestore(&info->readlock, flags);
 		return;
 	}
@@ -2468,13 +2470,13 @@ isdn_tty_modem_result(int code, modem_info *info)
 	case RESULT_NO_CARRIER:
 #ifdef ISDN_DEBUG_MODEM_HUP
 		printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n",
-		       (info->flags & ASYNC_CLOSING),
+		       (info->port.flags & ASYNC_CLOSING),
 		       (!info->tty));
 #endif
 		m->mdmreg[REG_RINGCNT] = 0;
 		del_timer(&info->nc_timer);
 		info->ncarrier = 0;
-		if ((info->flags & ASYNC_CLOSING) || (!info->tty))
+		if ((info->port.flags & ASYNC_CLOSING) || (!info->tty))
 			return;
 
 #ifdef CONFIG_ISDN_AUDIO
@@ -2607,10 +2609,10 @@ isdn_tty_modem_result(int code, modem_info *info)
 		}
 	}
 	if (code == RESULT_NO_CARRIER) {
-		if ((info->flags & ASYNC_CLOSING) || (!info->tty))
+		if ((info->port.flags & ASYNC_CLOSING) || (!info->tty))
 			return;
 
-		if (info->flags & ASYNC_CHECK_CD)
+		if (info->port.flags & ASYNC_CHECK_CD)
 			tty_hangup(info->tty);
 	}
 }
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index 63af320..bb71041 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -15,6 +15,7 @@
 #define __ISDN_H__
 
 #include <linux/ioctl.h>
+#include <linux/tty.h>
 
 #define ISDN_MAX_DRIVERS    32
 #define ISDN_MAX_CHANNELS   64
@@ -435,7 +436,7 @@ typedef struct atemu {
 /* Private data (similar to async_struct in <linux/serial.h>) */
 typedef struct modem_info {
   int			magic;
-  int			flags;		 /* defined in tty.h               */
+  struct tty_port	port;
   int			x_char;		 /* xon/xoff character             */
   int			mcr;		 /* Modem control register         */
   int                   msr;             /* Modem status register          */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 11/69] TTY: isdn, use open/close_wait from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (9 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 10/69] TTY: isdn, add tty_port Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 12/69] TTY: isdn, use counts " Jiri Slaby
                   ` (57 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

Hmm, the isdn ones were initialized twice.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_common.c |    2 --
 drivers/isdn/i4l/isdn_tty.c    |   16 +++++++---------
 include/linux/isdn.h           |    1 -
 3 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index d9f5524..2ffa0b73 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -2327,8 +2327,6 @@ static int __init isdn_init(void)
 		dev->chanmap[i] = -1;
 		dev->m_idx[i] = -1;
 		strcpy(dev->num[i], "???");
-		init_waitqueue_head(&dev->mdm.info[i].open_wait);
-		init_waitqueue_head(&dev->mdm.info[i].close_wait);
 	}
 	if (register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops)) {
 		printk(KERN_WARNING "isdn: Could not register control devices\n");
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 8ba526d..33764d0 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1498,7 +1498,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	if (tty_hung_up_p(filp) ||
 	    (info->port.flags & ASYNC_CLOSING)) {
 		if (info->port.flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&info->close_wait);
+			interruptible_sleep_on(&info->port.close_wait);
 #ifdef MODEM_DO_RESTART
 		if (info->port.flags & ASYNC_HUP_NOTIFY)
 			return -EAGAIN;
@@ -1527,7 +1527,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	 * exit, either normal or abnormal.
 	 */
 	retval = 0;
-	add_wait_queue(&info->open_wait, &wait);
+	add_wait_queue(&info->port.open_wait, &wait);
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_block_til_ready before block: ttyi%d, count = %d\n",
 	       info->line, info->count);
@@ -1564,7 +1564,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 		schedule();
 	}
 	current->state = TASK_RUNNING;
-	remove_wait_queue(&info->open_wait, &wait);
+	remove_wait_queue(&info->port.open_wait, &wait);
 	if (!tty_hung_up_p(filp))
 		info->count++;
 	info->blocked_open--;
@@ -1697,10 +1697,10 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	tty->closing = 0;
 	if (info->blocked_open) {
 		msleep_interruptible(500);
-		wake_up_interruptible(&info->open_wait);
+		wake_up_interruptible(&info->port.open_wait);
 	}
 	info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
-	wake_up_interruptible(&info->close_wait);
+	wake_up_interruptible(&info->port.close_wait);
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_close normal exit\n");
 #endif
@@ -1720,7 +1720,7 @@ isdn_tty_hangup(struct tty_struct *tty)
 	info->count = 0;
 	info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
-	wake_up_interruptible(&info->open_wait);
+	wake_up_interruptible(&info->port.open_wait);
 }
 
 /* This routine initializes all emulator-data.
@@ -1898,8 +1898,6 @@ isdn_tty_modem_init(void)
 		info->x_char = 0;
 		info->count = 0;
 		info->blocked_open = 0;
-		init_waitqueue_head(&info->open_wait);
-		init_waitqueue_head(&info->close_wait);
 		info->isdn_driver = -1;
 		info->isdn_channel = -1;
 		info->drv_index = -1;
@@ -2194,7 +2192,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
 			 */
 			if (info->blocked_open &&
 			    (info->emu.mdmreg[REG_DCD] & BIT_DCD)) {
-				wake_up_interruptible(&info->open_wait);
+				wake_up_interruptible(&info->port.open_wait);
 			}
 
 			/* Schedule CONNECT-Message to any tty
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index bb71041..c3ddf20 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -483,7 +483,6 @@ typedef struct modem_info {
 #endif
   struct tty_struct 	*tty;            /* Pointer to corresponding tty   */
   atemu                 emu;             /* AT-emulator data               */
-  wait_queue_head_t	open_wait, close_wait;
   spinlock_t	        readlock;
 } modem_info;
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 12/69] TTY: isdn, use counts from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (10 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 11/69] TTY: isdn, use open/close_wait from tty_port Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 13/69] TTY: isdn, use tty " Jiri Slaby
                   ` (56 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

blocked_open and count this time.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   43 +++++++++++++++++++++----------------------
 include/linux/isdn.h        |    2 --
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 33764d0..c81a725 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1533,8 +1533,8 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	       info->line, info->count);
 #endif
 	if (!(tty_hung_up_p(filp)))
-		info->count--;
-	info->blocked_open++;
+		info->port.count--;
+	info->port.blocked_open++;
 	while (1) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
@@ -1559,18 +1559,18 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 		}
 #ifdef ISDN_DEBUG_MODEM_OPEN
 		printk(KERN_DEBUG "isdn_tty_block_til_ready blocking: ttyi%d, count = %d\n",
-		       info->line, info->count);
+		       info->line, info->port.count);
 #endif
 		schedule();
 	}
 	current->state = TASK_RUNNING;
 	remove_wait_queue(&info->port.open_wait, &wait);
 	if (!tty_hung_up_p(filp))
-		info->count++;
-	info->blocked_open--;
+		info->port.count++;
+	info->port.blocked_open--;
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_block_til_ready after blocking: ttyi%d, count = %d\n",
-	       info->line, info->count);
+	       info->line, info->port.count);
 #endif
 	if (retval)
 		return retval;
@@ -1595,9 +1595,9 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
 		return -ENODEV;
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name,
-	       info->count);
+	       info->port.count);
 #endif
-	info->count++;
+	info->port.count++;
 	tty->driver_data = info;
 	info->tty = tty;
 	tty->port = &info->port;
@@ -1642,7 +1642,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 #endif
 		return;
 	}
-	if ((tty->count == 1) && (info->count != 1)) {
+	if ((tty->count == 1) && (info->port.count != 1)) {
 		/*
 		 * Uh, oh.  tty->count is 1, which means that the tty
 		 * structure will be freed.  Info->count should always
@@ -1651,15 +1651,15 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 		 * serial port won't be shutdown.
 		 */
 		printk(KERN_ERR "isdn_tty_close: bad port count; tty->count is 1, "
-		       "info->count is %d\n", info->count);
-		info->count = 1;
+		       "info->count is %d\n", info->port.count);
+		info->port.count = 1;
 	}
-	if (--info->count < 0) {
+	if (--info->port.count < 0) {
 		printk(KERN_ERR "isdn_tty_close: bad port count for ttyi%d: %d\n",
-		       info->line, info->count);
-		info->count = 0;
+		       info->line, info->port.count);
+		info->port.count = 0;
 	}
-	if (info->count) {
+	if (info->port.count) {
 #ifdef ISDN_DEBUG_MODEM_OPEN
 		printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n");
 #endif
@@ -1695,7 +1695,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	info->tty = NULL;
 	info->ncarrier = 0;
 	tty->closing = 0;
-	if (info->blocked_open) {
+	if (info->port.blocked_open) {
 		msleep_interruptible(500);
 		wake_up_interruptible(&info->port.open_wait);
 	}
@@ -1717,7 +1717,7 @@ isdn_tty_hangup(struct tty_struct *tty)
 	if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_hangup"))
 		return;
 	isdn_tty_shutdown(info);
-	info->count = 0;
+	info->port.count = 0;
 	info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
 	wake_up_interruptible(&info->port.open_wait);
@@ -1896,8 +1896,6 @@ isdn_tty_modem_init(void)
 		info->line = i;
 		info->tty = NULL;
 		info->x_char = 0;
-		info->count = 0;
-		info->blocked_open = 0;
 		info->isdn_driver = -1;
 		info->isdn_channel = -1;
 		info->drv_index = -1;
@@ -2047,7 +2045,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 		modem_info *info = &dev->mdm.info[i];
 
-		if (info->count == 0)
+		if (info->port.count == 0)
 			continue;
 		if ((info->emu.mdmreg[REG_SI1] & si2bit[si1]) &&  /* SI1 is matching */
 		    (info->emu.mdmreg[REG_SI2] == si2))	{         /* SI2 is matching */
@@ -2190,7 +2188,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
 			 * for incoming call of this device when
 			 * DCD follow the state of incoming carrier
 			 */
-			if (info->blocked_open &&
+			if (info->port.blocked_open &&
 			    (info->emu.mdmreg[REG_DCD] & BIT_DCD)) {
 				wake_up_interruptible(&info->port.open_wait);
 			}
@@ -2200,7 +2198,8 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
 			 * set DCD-bit of its modem-status.
 			 */
 			if (TTY_IS_ACTIVE(info) ||
-			    (info->blocked_open && (info->emu.mdmreg[REG_DCD] & BIT_DCD))) {
+			    (info->port.blocked_open &&
+			     (info->emu.mdmreg[REG_DCD] & BIT_DCD))) {
 				info->msr |= UART_MSR_DCD;
 				info->emu.charge = 0;
 				if (info->dialing & 0xf)
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index c3ddf20..a4b71fe 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -442,8 +442,6 @@ typedef struct modem_info {
   int                   msr;             /* Modem status register          */
   int                   lsr;             /* Line status register           */
   int			line;
-  int			count;		 /* # of fd on device              */
-  int			blocked_open;	 /* # of blocked opens             */
   int                   online;          /* 1 = B-Channel is up, drop data */
 					 /* 2 = B-Channel is up, deliver d.*/
   int                   dialing;         /* Dial in progress or ATA        */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 13/69] TTY: isdn, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (11 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 12/69] TTY: isdn, use counts " Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 14/69] TTY: isdn, use xmit_buf " Jiri Slaby
                   ` (55 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

No recounting this time, just a plain switch.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   41 ++++++++++++++++++++---------------------
 include/linux/isdn.h        |    1 -
 2 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index c81a725..8698856 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -68,7 +68,7 @@ isdn_tty_try_read(modem_info *info, struct sk_buff *skb)
 	if (!info->online)
 		return 0;
 
-	tty = info->tty;
+	tty = info->port.tty;
 	if (!tty)
 		return 0;
 
@@ -144,7 +144,7 @@ isdn_tty_readmodem(void)
 		if ((info->vonline & 1) && (info->emu.vpar[1]))
 			isdn_audio_eval_silence(info);
 #endif
-		tty = info->tty;
+		tty = info->port.tty;
 		if (tty) {
 			if (info->mcr & UART_MCR_RTS) {
 				/* CISCO AsyncPPP Hack */
@@ -300,7 +300,7 @@ isdn_tty_tint(modem_info *info)
 	len = skb->len;
 	if ((slen = isdn_writebuf_skb_stub(info->isdn_driver,
 					   info->isdn_channel, 1, skb)) == len) {
-		struct tty_struct *tty = info->tty;
+		struct tty_struct *tty = info->port.tty;
 		info->send_outstanding++;
 		info->msr &= ~UART_MSR_CTS;
 		info->lsr &= ~UART_LSR_TEMT;
@@ -705,7 +705,7 @@ isdn_tty_modem_hup(modem_info *info, int local)
 	printk(KERN_DEBUG "Mhup ttyI%d\n", info->line);
 #endif
 	info->rcvsched = 0;
-	isdn_tty_flush_buffer(info->tty);
+	isdn_tty_flush_buffer(info->port.tty);
 	if (info->online) {
 		info->last_lhup = local;
 		info->online = 0;
@@ -1008,15 +1008,15 @@ isdn_tty_change_speed(modem_info *info)
 		quot;
 	int i;
 
-	if (!info->tty || !info->tty->termios)
+	if (!info->port.tty || !info->port.tty->termios)
 		return;
-	cflag = info->tty->termios->c_cflag;
+	cflag = info->port.tty->termios->c_cflag;
 
 	quot = i = cflag & CBAUD;
 	if (i & CBAUDEX) {
 		i &= ~CBAUDEX;
 		if (i < 1 || i > 2)
-			info->tty->termios->c_cflag &= ~CBAUDEX;
+			info->port.tty->termios->c_cflag &= ~CBAUDEX;
 		else
 			i += 15;
 	}
@@ -1069,8 +1069,8 @@ isdn_tty_startup(modem_info *info)
 	 * Now, initialize the UART
 	 */
 	info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
-	if (info->tty)
-		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	if (info->port.tty)
+		clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
 	/*
 	 * and set the speed of the serial port
 	 */
@@ -1096,7 +1096,7 @@ isdn_tty_shutdown(modem_info *info)
 #endif
 	isdn_unlock_drivers();
 	info->msr &= ~UART_MSR_RI;
-	if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+	if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
 		info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
 		if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) {
 			isdn_tty_modem_reset_regs(info, 0);
@@ -1106,8 +1106,8 @@ isdn_tty_shutdown(modem_info *info)
 			isdn_tty_modem_hup(info, 1);
 		}
 	}
-	if (info->tty)
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
+	if (info->port.tty)
+		set_bit(TTY_IO_ERROR, &info->port.tty->flags);
 
 	info->port.flags &= ~ASYNC_INITIALIZED;
 }
@@ -1599,7 +1599,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
 #endif
 	info->port.count++;
 	tty->driver_data = info;
-	info->tty = tty;
+	info->port.tty = tty;
 	tty->port = &info->port;
 	/*
 	 * Start up serial port
@@ -1692,7 +1692,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	isdn_tty_shutdown(info);
 	isdn_tty_flush_buffer(tty);
 	tty_ldisc_flush(tty);
-	info->tty = NULL;
+	info->port.tty = NULL;
 	info->ncarrier = 0;
 	tty->closing = 0;
 	if (info->port.blocked_open) {
@@ -1719,7 +1719,7 @@ isdn_tty_hangup(struct tty_struct *tty)
 	isdn_tty_shutdown(info);
 	info->port.count = 0;
 	info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	info->tty = NULL;
+	info->port.tty = NULL;
 	wake_up_interruptible(&info->port.open_wait);
 }
 
@@ -1894,7 +1894,6 @@ isdn_tty_modem_init(void)
 		isdn_tty_modem_reset_regs(info, 1);
 		info->magic = ISDN_ASYNC_MAGIC;
 		info->line = i;
-		info->tty = NULL;
 		info->x_char = 0;
 		info->isdn_driver = -1;
 		info->isdn_channel = -1;
@@ -2316,7 +2315,7 @@ isdn_tty_at_cout(char *msg, modem_info *info)
 	l = strlen(msg);
 
 	spin_lock_irqsave(&info->readlock, flags);
-	tty = info->tty;
+	tty = info->port.tty;
 	if ((info->port.flags & ASYNC_CLOSING) || (!tty)) {
 		spin_unlock_irqrestore(&info->readlock, flags);
 		return;
@@ -2468,12 +2467,12 @@ isdn_tty_modem_result(int code, modem_info *info)
 #ifdef ISDN_DEBUG_MODEM_HUP
 		printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n",
 		       (info->port.flags & ASYNC_CLOSING),
-		       (!info->tty));
+		       (!info->port.tty));
 #endif
 		m->mdmreg[REG_RINGCNT] = 0;
 		del_timer(&info->nc_timer);
 		info->ncarrier = 0;
-		if ((info->port.flags & ASYNC_CLOSING) || (!info->tty))
+		if ((info->port.flags & ASYNC_CLOSING) || (!info->port.tty))
 			return;
 
 #ifdef CONFIG_ISDN_AUDIO
@@ -2606,11 +2605,11 @@ isdn_tty_modem_result(int code, modem_info *info)
 		}
 	}
 	if (code == RESULT_NO_CARRIER) {
-		if ((info->port.flags & ASYNC_CLOSING) || (!info->tty))
+		if ((info->port.flags & ASYNC_CLOSING) || (!info->port.tty))
 			return;
 
 		if (info->port.flags & ASYNC_CHECK_CD)
-			tty_hangup(info->tty);
+			tty_hangup(info->port.tty);
 	}
 }
 
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index a4b71fe..95883ac 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -479,7 +479,6 @@ typedef struct modem_info {
   struct T30_s		*fax;		 /* T30 Fax Group 3 data/interface */
   int			faxonline;	 /* Fax-channel status             */
 #endif
-  struct tty_struct 	*tty;            /* Pointer to corresponding tty   */
   atemu                 emu;             /* AT-emulator data               */
   spinlock_t	        readlock;
 } modem_info;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 14/69] TTY: isdn, use xmit_buf from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (12 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 13/69] TTY: isdn, use tty " Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:53 ` [PATCH 15/69] TTY: isdn, define local tty_port Jiri Slaby
                   ` (54 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   16 +++++++++-------
 include/linux/isdn.h        |    1 -
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 8698856..dfb83e6 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -333,7 +333,7 @@ isdn_tty_countDLE(unsigned char *buf, int len)
 static int
 isdn_tty_handleDLEdown(modem_info *info, atemu *m, int len)
 {
-	unsigned char *p = &info->xmit_buf[info->xmit_count];
+	unsigned char *p = &info->port.xmit_buf[info->xmit_count];
 	int count = 0;
 
 	while (len > 0) {
@@ -477,7 +477,7 @@ isdn_tty_senddown(modem_info *info)
 		return;
 	}
 	skb_reserve(skb, skb_res);
-	memcpy(skb_put(skb, buflen), info->xmit_buf, buflen);
+	memcpy(skb_put(skb, buflen), info->port.xmit_buf, buflen);
 	info->xmit_count = 0;
 #ifdef CONFIG_ISDN_AUDIO
 	if (info->vonline & 2) {
@@ -1152,7 +1152,7 @@ isdn_tty_write(struct tty_struct *tty, const u_char *buf, int count)
 				isdn_tty_check_esc(buf, m->mdmreg[REG_ESC], c,
 						   &(m->pluscount),
 						   &(m->lastplus));
-			memcpy(&(info->xmit_buf[info->xmit_count]), buf, c);
+			memcpy(&info->port.xmit_buf[info->xmit_count], buf, c);
 #ifdef CONFIG_ISDN_AUDIO
 			if (info->vonline) {
 				int cc = isdn_tty_handleDLEdown(info, m, c);
@@ -1906,13 +1906,15 @@ isdn_tty_modem_init(void)
 #ifdef CONFIG_ISDN_AUDIO
 		skb_queue_head_init(&info->dtmf_queue);
 #endif
-		if (!(info->xmit_buf = kmalloc(ISDN_SERIAL_XMIT_MAX + 5, GFP_KERNEL))) {
+		info->port.xmit_buf = kmalloc(ISDN_SERIAL_XMIT_MAX + 5,
+				GFP_KERNEL);
+		if (!info->port.xmit_buf) {
 			printk(KERN_ERR "Could not allocate modem xmit-buffer\n");
 			retval = -ENOMEM;
 			goto err_unregister;
 		}
 		/* Make room for T.70 header */
-		info->xmit_buf += 4;
+		info->port.xmit_buf += 4;
 	}
 	return 0;
 err_unregister:
@@ -1921,7 +1923,7 @@ err_unregister:
 #ifdef CONFIG_ISDN_TTY_FAX
 		kfree(info->fax);
 #endif
-		kfree(info->xmit_buf - 4);
+		kfree(info->port.xmit_buf - 4);
 	}
 	tty_unregister_driver(m->tty_modem);
 err:
@@ -1942,7 +1944,7 @@ isdn_tty_exit(void)
 #ifdef CONFIG_ISDN_TTY_FAX
 		kfree(info->fax);
 #endif
-		kfree(info->xmit_buf - 4);
+		kfree(info->port.xmit_buf - 4);
 	}
 	tty_unregister_driver(dev->mdm.tty_modem);
 	put_tty_driver(dev->mdm.tty_modem);
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index 95883ac..215c416 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -461,7 +461,6 @@ typedef struct modem_info {
   int                   send_outstanding;/* # of outstanding send-requests */
   int                   xmit_size;       /* max. # of chars in xmit_buf    */
   int                   xmit_count;      /* # of chars in xmit_buf         */
-  unsigned char         *xmit_buf;       /* transmit buffer                */
   struct sk_buff_head   xmit_queue;      /* transmit queue                 */
   atomic_t              xmit_lock;       /* Semaphore for isdn_tty_write   */
 #ifdef CONFIG_ISDN_AUDIO
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 15/69] TTY: isdn, define local tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (13 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 14/69] TTY: isdn, use xmit_buf " Jiri Slaby
@ 2012-04-02 11:53 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 16/69] TTY: isdn, use tty_port_close_end helper Jiri Slaby
                   ` (53 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:53 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

In some functions we use tty_port much. So let us have a local pointer
to that variable instead of having info->port all over the code.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   98 +++++++++++++++++++++++--------------------
 1 file changed, 52 insertions(+), 46 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index dfb83e6..ee8ba87 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1003,20 +1003,21 @@ isdn_tty_paranoia_check(modem_info *info, char *name, const char *routine)
 static void
 isdn_tty_change_speed(modem_info *info)
 {
+	struct tty_port *port = &info->port;
 	uint cflag,
 		cval,
 		quot;
 	int i;
 
-	if (!info->port.tty || !info->port.tty->termios)
+	if (!port->tty || !port->tty->termios)
 		return;
-	cflag = info->port.tty->termios->c_cflag;
+	cflag = port->tty->termios->c_cflag;
 
 	quot = i = cflag & CBAUD;
 	if (i & CBAUDEX) {
 		i &= ~CBAUDEX;
 		if (i < 1 || i > 2)
-			info->port.tty->termios->c_cflag &= ~CBAUDEX;
+			port->tty->termios->c_cflag &= ~CBAUDEX;
 		else
 			i += 15;
 	}
@@ -1046,13 +1047,13 @@ isdn_tty_change_speed(modem_info *info)
 
 	/* CTS flow control flag and modem status interrupts */
 	if (cflag & CRTSCTS) {
-		info->port.flags |= ASYNC_CTS_FLOW;
+		port->flags |= ASYNC_CTS_FLOW;
 	} else
-		info->port.flags &= ~ASYNC_CTS_FLOW;
+		port->flags &= ~ASYNC_CTS_FLOW;
 	if (cflag & CLOCAL)
-		info->port.flags &= ~ASYNC_CHECK_CD;
+		port->flags &= ~ASYNC_CHECK_CD;
 	else {
-		info->port.flags |= ASYNC_CHECK_CD;
+		port->flags |= ASYNC_CHECK_CD;
 	}
 }
 
@@ -1487,6 +1488,7 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 static int
 isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *info)
 {
+	struct tty_port *port = &info->port;
 	DECLARE_WAITQUEUE(wait, NULL);
 	int do_clocal = 0;
 	int retval;
@@ -1496,11 +1498,11 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	 * until it's done, and then try again.
 	 */
 	if (tty_hung_up_p(filp) ||
-	    (info->port.flags & ASYNC_CLOSING)) {
-		if (info->port.flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&info->port.close_wait);
+	    (port->flags & ASYNC_CLOSING)) {
+		if (port->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&port->close_wait);
 #ifdef MODEM_DO_RESTART
-		if (info->port.flags & ASYNC_HUP_NOTIFY)
+		if (port->flags & ASYNC_HUP_NOTIFY)
 			return -EAGAIN;
 		else
 			return -ERESTARTSYS;
@@ -1514,7 +1516,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		info->port.flags |= ASYNC_NORMAL_ACTIVE;
+		port->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 	if (tty->termios->c_cflag & CLOCAL)
@@ -1527,20 +1529,20 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 	 * exit, either normal or abnormal.
 	 */
 	retval = 0;
-	add_wait_queue(&info->port.open_wait, &wait);
+	add_wait_queue(&port->open_wait, &wait);
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_block_til_ready before block: ttyi%d, count = %d\n",
 	       info->line, info->count);
 #endif
 	if (!(tty_hung_up_p(filp)))
-		info->port.count--;
-	info->port.blocked_open++;
+		port->count--;
+	port->blocked_open++;
 	while (1) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
-		    !(info->port.flags & ASYNC_INITIALIZED)) {
+		    !(port->flags & ASYNC_INITIALIZED)) {
 #ifdef MODEM_DO_RESTART
-			if (info->port.flags & ASYNC_HUP_NOTIFY)
+			if (port->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
 				retval = -ERESTARTSYS;
@@ -1549,7 +1551,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 #endif
 			break;
 		}
-		if (!(info->port.flags & ASYNC_CLOSING) &&
+		if (!(port->flags & ASYNC_CLOSING) &&
 		    (do_clocal || (info->msr & UART_MSR_DCD))) {
 			break;
 		}
@@ -1559,22 +1561,22 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 		}
 #ifdef ISDN_DEBUG_MODEM_OPEN
 		printk(KERN_DEBUG "isdn_tty_block_til_ready blocking: ttyi%d, count = %d\n",
-		       info->line, info->port.count);
+		       info->line, port->count);
 #endif
 		schedule();
 	}
 	current->state = TASK_RUNNING;
-	remove_wait_queue(&info->port.open_wait, &wait);
+	remove_wait_queue(&port->open_wait, &wait);
 	if (!tty_hung_up_p(filp))
-		info->port.count++;
-	info->port.blocked_open--;
+		port->count++;
+	port->blocked_open--;
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_block_til_ready after blocking: ttyi%d, count = %d\n",
-	       info->line, info->port.count);
+	       info->line, port->count);
 #endif
 	if (retval)
 		return retval;
-	info->port.flags |= ASYNC_NORMAL_ACTIVE;
+	port->flags |= ASYNC_NORMAL_ACTIVE;
 	return 0;
 }
 
@@ -1587,20 +1589,22 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 static int
 isdn_tty_open(struct tty_struct *tty, struct file *filp)
 {
+	struct tty_port *port;
 	modem_info *info;
 	int retval;
 
 	info = &dev->mdm.info[tty->index];
 	if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open"))
 		return -ENODEV;
+	port = &info->port;
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name,
-	       info->port.count);
+	       port->count);
 #endif
-	info->port.count++;
+	port->count++;
 	tty->driver_data = info;
-	info->port.tty = tty;
-	tty->port = &info->port;
+	port->tty = tty;
+	tty->port = port;
 	/*
 	 * Start up serial port
 	 */
@@ -1632,6 +1636,7 @@ static void
 isdn_tty_close(struct tty_struct *tty, struct file *filp)
 {
 	modem_info *info = (modem_info *) tty->driver_data;
+	struct tty_port *port = &info->port;
 	ulong timeout;
 
 	if (!info || isdn_tty_paranoia_check(info, tty->name, "isdn_tty_close"))
@@ -1642,7 +1647,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 #endif
 		return;
 	}
-	if ((tty->count == 1) && (info->port.count != 1)) {
+	if ((tty->count == 1) && (port->count != 1)) {
 		/*
 		 * Uh, oh.  tty->count is 1, which means that the tty
 		 * structure will be freed.  Info->count should always
@@ -1651,21 +1656,21 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 		 * serial port won't be shutdown.
 		 */
 		printk(KERN_ERR "isdn_tty_close: bad port count; tty->count is 1, "
-		       "info->count is %d\n", info->port.count);
-		info->port.count = 1;
+		       "info->count is %d\n", port->count);
+		port->count = 1;
 	}
-	if (--info->port.count < 0) {
+	if (--port->count < 0) {
 		printk(KERN_ERR "isdn_tty_close: bad port count for ttyi%d: %d\n",
-		       info->line, info->port.count);
-		info->port.count = 0;
+		       info->line, port->count);
+		port->count = 0;
 	}
-	if (info->port.count) {
+	if (port->count) {
 #ifdef ISDN_DEBUG_MODEM_OPEN
 		printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n");
 #endif
 		return;
 	}
-	info->port.flags |= ASYNC_CLOSING;
+	port->flags |= ASYNC_CLOSING;
 
 	tty->closing = 1;
 	/*
@@ -1674,7 +1679,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	 * interrupt driver to stop checking the data ready bit in the
 	 * line status register.
 	 */
-	if (info->port.flags & ASYNC_INITIALIZED) {
+	if (port->flags & ASYNC_INITIALIZED) {
 		tty_wait_until_sent_from_close(tty, 3000);	/* 30 seconds timeout */
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
@@ -1692,15 +1697,15 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	isdn_tty_shutdown(info);
 	isdn_tty_flush_buffer(tty);
 	tty_ldisc_flush(tty);
-	info->port.tty = NULL;
+	port->tty = NULL;
 	info->ncarrier = 0;
 	tty->closing = 0;
-	if (info->port.blocked_open) {
+	if (port->blocked_open) {
 		msleep_interruptible(500);
-		wake_up_interruptible(&info->port.open_wait);
+		wake_up_interruptible(&port->open_wait);
 	}
-	info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
-	wake_up_interruptible(&info->port.close_wait);
+	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+	wake_up_interruptible(&port->close_wait);
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_close normal exit\n");
 #endif
@@ -1713,14 +1718,15 @@ static void
 isdn_tty_hangup(struct tty_struct *tty)
 {
 	modem_info *info = (modem_info *) tty->driver_data;
+	struct tty_port *port = &info->port;
 
 	if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_hangup"))
 		return;
 	isdn_tty_shutdown(info);
-	info->port.count = 0;
-	info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	info->port.tty = NULL;
-	wake_up_interruptible(&info->port.open_wait);
+	port->count = 0;
+	port->flags &= ~ASYNC_NORMAL_ACTIVE;
+	port->tty = NULL;
+	wake_up_interruptible(&port->open_wait);
 }
 
 /* This routine initializes all emulator-data.
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 16/69] TTY: isdn, use tty_port_close_end helper
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (14 preceding siblings ...)
  2012-04-02 11:53 ` [PATCH 15/69] TTY: isdn, define local tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 17/69] TTY: isdn, define tty_port_operations Jiri Slaby
                   ` (52 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

The code does almost the same, so there we can leverage the helper's
code. The only difference is locking. The helper protects counts by a
spinlock. This never hurts and should be added to other code parts
too.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index ee8ba87..50d7246 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1699,13 +1699,8 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	tty_ldisc_flush(tty);
 	port->tty = NULL;
 	info->ncarrier = 0;
-	tty->closing = 0;
-	if (port->blocked_open) {
-		msleep_interruptible(500);
-		wake_up_interruptible(&port->open_wait);
-	}
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
-	wake_up_interruptible(&port->close_wait);
+
+	tty_port_close_end(port, tty);
 #ifdef ISDN_DEBUG_MODEM_OPEN
 	printk(KERN_DEBUG "isdn_tty_close normal exit\n");
 #endif
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 17/69] TTY: isdn, define tty_port_operations
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (15 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 16/69] TTY: isdn, use tty_port_close_end helper Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 18/69] TTY: isdn, use tty_port_block_til_ready helper Jiri Slaby
                   ` (51 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

Add there .carrier_raised. It is taken from current block_til_ready.
We will need tty_port->ops->carrier_raised for
tty_port_block_til_ready helper.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 50d7246..b41a80a 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1485,6 +1485,7 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
  * isdn_tty_open() and friends
  * ------------------------------------------------------------
  */
+
 static int
 isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *info)
 {
@@ -1552,7 +1553,7 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
 			break;
 		}
 		if (!(port->flags & ASYNC_CLOSING) &&
-		    (do_clocal || (info->msr & UART_MSR_DCD))) {
+		    (do_clocal || tty_port_carrier_raised(port))) {
 			break;
 		}
 		if (signal_pending(current)) {
@@ -1848,6 +1849,16 @@ static const struct tty_operations modem_ops = {
 	.tiocmset = isdn_tty_tiocmset,
 };
 
+static int isdn_tty_carrier_raised(struct tty_port *port)
+{
+	modem_info *info = container_of(port, modem_info, port);
+	return info->msr & UART_MSR_DCD;
+}
+
+static const struct tty_port_operations isdn_tty_port_ops = {
+	.carrier_raised = isdn_tty_carrier_raised,
+};
+
 int
 isdn_tty_modem_init(void)
 {
@@ -1884,6 +1895,7 @@ isdn_tty_modem_init(void)
 		}
 #endif
 		tty_port_init(&info->port);
+		info->port.ops = &isdn_tty_port_ops;
 		spin_lock_init(&info->readlock);
 		sprintf(info->last_cause, "0000");
 		sprintf(info->last_num, "none");
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 18/69] TTY: isdn, use tty_port_block_til_ready helper
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (16 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 17/69] TTY: isdn, define tty_port_operations Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 19/69] TTY: hso, do not set TTY MAGIC Jiri Slaby
                   ` (50 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Karsten Keil

This removes a bunch of duplicated code which does the same as
tty_port_block_til_ready does.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Karsten Keil <isdn@linux-pingi.de>
---
 drivers/isdn/i4l/isdn_tty.c |   97 +------------------------------------------
 1 file changed, 1 insertion(+), 96 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index b41a80a..7bc5067 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1486,101 +1486,6 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
  * ------------------------------------------------------------
  */
 
-static int
-isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *info)
-{
-	struct tty_port *port = &info->port;
-	DECLARE_WAITQUEUE(wait, NULL);
-	int do_clocal = 0;
-	int retval;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (port->flags & ASYNC_CLOSING)) {
-		if (port->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&port->close_wait);
-#ifdef MODEM_DO_RESTART
-		if (port->flags & ASYNC_HUP_NOTIFY)
-			return -EAGAIN;
-		else
-			return -ERESTARTSYS;
-#else
-		return -EAGAIN;
-#endif
-	}
-	/*
-	 * If non-blocking mode is set, then make the check up front
-	 * and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		port->flags |= ASYNC_NORMAL_ACTIVE;
-		return 0;
-	}
-	if (tty->termios->c_cflag & CLOCAL)
-		do_clocal = 1;
-	/*
-	 * Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, info->count is dropped by one, so that
-	 * isdn_tty_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&port->open_wait, &wait);
-#ifdef ISDN_DEBUG_MODEM_OPEN
-	printk(KERN_DEBUG "isdn_tty_block_til_ready before block: ttyi%d, count = %d\n",
-	       info->line, info->count);
-#endif
-	if (!(tty_hung_up_p(filp)))
-		port->count--;
-	port->blocked_open++;
-	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(port->flags & ASYNC_INITIALIZED)) {
-#ifdef MODEM_DO_RESTART
-			if (port->flags & ASYNC_HUP_NOTIFY)
-				retval = -EAGAIN;
-			else
-				retval = -ERESTARTSYS;
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-		if (!(port->flags & ASYNC_CLOSING) &&
-		    (do_clocal || tty_port_carrier_raised(port))) {
-			break;
-		}
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-#ifdef ISDN_DEBUG_MODEM_OPEN
-		printk(KERN_DEBUG "isdn_tty_block_til_ready blocking: ttyi%d, count = %d\n",
-		       info->line, port->count);
-#endif
-		schedule();
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&port->open_wait, &wait);
-	if (!tty_hung_up_p(filp))
-		port->count++;
-	port->blocked_open--;
-#ifdef ISDN_DEBUG_MODEM_OPEN
-	printk(KERN_DEBUG "isdn_tty_block_til_ready after blocking: ttyi%d, count = %d\n",
-	       info->line, port->count);
-#endif
-	if (retval)
-		return retval;
-	port->flags |= ASYNC_NORMAL_ACTIVE;
-	return 0;
-}
-
 /*
  * This routine is called whenever a serial port is opened.  It
  * enables interrupts for a serial port, linking in its async structure into
@@ -1616,7 +1521,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
 #endif
 		return retval;
 	}
-	retval = isdn_tty_block_til_ready(tty, filp, info);
+	retval = tty_port_block_til_ready(port, tty, filp);
 	if (retval) {
 #ifdef ISDN_DEBUG_MODEM_OPEN
 		printk(KERN_DEBUG "isdn_tty_open return after isdn_tty_block_til_ready \n");
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 19/69] TTY: hso, do not set TTY MAGIC
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (17 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 18/69] TTY: isdn, use tty_port_block_til_ready helper Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 20/69] TTY: hso, free tty_driver Jiri Slaby
                   ` (49 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Jan Dumon

It is set in alloc_tty_driver already. No need to re-set.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jan Dumon <j.dumon@option.com>
---
 drivers/net/usb/hso.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 2d2a688..abe47ad 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -3312,7 +3312,6 @@ static int __init hso_init(void)
 		return -ENOMEM;
 
 	/* fill in all needed values */
-	tty_drv->magic = TTY_DRIVER_MAGIC;
 	tty_drv->driver_name = driver_name;
 	tty_drv->name = tty_filename;
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 20/69] TTY: hso, free tty_driver
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (18 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 19/69] TTY: hso, do not set TTY MAGIC Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 21/69] TTY: hso, add tty_port Jiri Slaby
                   ` (48 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Jan Dumon

Do not leak tty_driver structure on each module removal. Also do
proper frees in fail paths of module_init.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jan Dumon <j.dumon@option.com>
---
 drivers/net/usb/hso.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index abe47ad..cdc589e 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -3332,7 +3332,7 @@ static int __init hso_init(void)
 	if (result) {
 		printk(KERN_ERR "%s - tty_register_driver failed(%d)\n",
 			__func__, result);
-		return result;
+		goto err_free_tty;
 	}
 
 	/* register this module as an usb driver */
@@ -3340,13 +3340,16 @@ static int __init hso_init(void)
 	if (result) {
 		printk(KERN_ERR "Could not register hso driver? error: %d\n",
 			result);
-		/* cleanup serial interface */
-		tty_unregister_driver(tty_drv);
-		return result;
+		goto err_unreg_tty;
 	}
 
 	/* done */
 	return 0;
+err_unreg_tty:
+	tty_unregister_driver(tty_drv);
+err_free_tty:
+	put_tty_driver(tty_drv);
+	return result;
 }
 
 static void __exit hso_exit(void)
@@ -3354,6 +3357,7 @@ static void __exit hso_exit(void)
 	printk(KERN_INFO "hso: unloaded\n");
 
 	tty_unregister_driver(tty_drv);
+	put_tty_driver(tty_drv);
 	/* deregister the usb driver */
 	usb_deregister(&hso_driver);
 }
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 21/69] TTY: hso, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (19 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 20/69] TTY: hso, free tty_driver Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 22/69] TTY: hso, remove tty NULL checks fro tty->ops Jiri Slaby
                   ` (47 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Jan Dumon

And use open count from there. Other members will follow.

Remark: port.count is (and never was) properly protected. Only a mutex
is held, so ISR and all the functions it calls may see an invalid
state.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jan Dumon <j.dumon@option.com>
---
 drivers/net/usb/hso.c |   25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index cdc589e..0b26d75 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -255,9 +255,9 @@ struct hso_serial {
 	u8 dtr_state;
 	unsigned tx_urb_used:1;
 
+	struct tty_port port;
 	/* from usb_serial_port */
 	struct tty_struct *tty;
-	int open_count;
 	spinlock_t serial_lock;
 
 	int (*write_data) (struct hso_serial *serial);
@@ -1190,7 +1190,7 @@ static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
 	struct urb *urb;
 
 	urb = serial->rx_urb[0];
-	if (serial->open_count > 0) {
+	if (serial->port.count > 0) {
 		count = put_rxbuf_data(urb, serial);
 		if (count == -1)
 			return;
@@ -1226,7 +1226,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb)
 	DUMP1(urb->transfer_buffer, urb->actual_length);
 
 	/* Anyone listening? */
-	if (serial->open_count == 0)
+	if (serial->port.count == 0)
 		return;
 
 	if (status == 0) {
@@ -1311,8 +1311,8 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
 	spin_unlock_irq(&serial->serial_lock);
 
 	/* check for port already opened, if not set the termios */
-	serial->open_count++;
-	if (serial->open_count == 1) {
+	serial->port.count++;
+	if (serial->port.count == 1) {
 		serial->rx_state = RX_IDLE;
 		/* Force default termio settings */
 		_hso_serial_set_termios(tty, NULL);
@@ -1324,7 +1324,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
 		result = hso_start_serial_device(serial->parent, GFP_KERNEL);
 		if (result) {
 			hso_stop_serial_device(serial->parent);
-			serial->open_count--;
+			serial->port.count--;
 			kref_put(&serial->parent->ref, hso_serial_ref_free);
 		}
 	} else {
@@ -1361,10 +1361,10 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
 
 	/* reset the rts and dtr */
 	/* do the actual close */
-	serial->open_count--;
+	serial->port.count--;
 
-	if (serial->open_count <= 0) {
-		serial->open_count = 0;
+	if (serial->port.count <= 0) {
+		serial->port.count = 0;
 		spin_lock_irq(&serial->serial_lock);
 		if (serial->tty == tty) {
 			serial->tty->driver_data = NULL;
@@ -1446,7 +1446,7 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
 
 	/* the actual setup */
 	spin_lock_irqsave(&serial->serial_lock, flags);
-	if (serial->open_count)
+	if (serial->port.count)
 		_hso_serial_set_termios(tty, old);
 	else
 		tty->termios = old;
@@ -1905,7 +1905,7 @@ static void intr_callback(struct urb *urb)
 				D1("Pending read interrupt on port %d\n", i);
 				spin_lock(&serial->serial_lock);
 				if (serial->rx_state == RX_IDLE &&
-					serial->open_count > 0) {
+					serial->port.count > 0) {
 					/* Setup and send a ctrl req read on
 					 * port i */
 					if (!serial->rx_urb_filled[0]) {
@@ -2320,6 +2320,7 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
 	serial->minor = minor;
 	serial->magic = HSO_SERIAL_MAGIC;
 	spin_lock_init(&serial->serial_lock);
+	tty_port_init(&serial->port);
 	serial->num_rx_urbs = num_urbs;
 
 	/* RX, allocate urb and initialize */
@@ -3098,7 +3099,7 @@ static int hso_resume(struct usb_interface *iface)
 	/* Start all serial ports */
 	for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
 		if (serial_table[i] && (serial_table[i]->interface == iface)) {
-			if (dev2ser(serial_table[i])->open_count) {
+			if (dev2ser(serial_table[i])->port.count) {
 				result =
 				    hso_start_serial_device(serial_table[i], GFP_NOIO);
 				hso_kick_transmit(dev2ser(serial_table[i]));
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 22/69] TTY: hso, remove tty NULL checks fro tty->ops
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (20 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 21/69] TTY: hso, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 23/69] TTY: hso, use tty from tty_port Jiri Slaby
                   ` (46 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Jan Dumon

tty is never NULL in tty->ops->* while the device is open. (And they
are not called otherwise.) So remove pointless checks and use
tty->driver_data directly.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jan Dumon <j.dumon@option.com>
---
 drivers/net/usb/hso.c |   27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 0b26d75..ec782c7 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -106,13 +106,6 @@
 
 #define MAX_RX_URBS			2
 
-static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty)
-{
-	if (tty)
-		return tty->driver_data;
-	return NULL;
-}
-
 /*****************************************************************************/
 /* Debugging functions                                                       */
 /*****************************************************************************/
@@ -1114,7 +1107,7 @@ static void hso_init_termios(struct ktermios *termios)
 static void _hso_serial_set_termios(struct tty_struct *tty,
 				    struct ktermios *old)
 {
-	struct hso_serial *serial = get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 	struct ktermios *termios;
 
 	if (!serial) {
@@ -1268,7 +1261,7 @@ static void hso_unthrottle_tasklet(struct hso_serial *serial)
 
 static	void hso_unthrottle(struct tty_struct *tty)
 {
-	struct hso_serial *serial = get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 
 	tasklet_hi_schedule(&serial->unthrottle_tasklet);
 }
@@ -1390,7 +1383,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
 static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf,
 			    int count)
 {
-	struct hso_serial *serial = get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 	int space, tx_bytes;
 	unsigned long flags;
 
@@ -1422,7 +1415,7 @@ out:
 /* how much room is there for writing */
 static int hso_serial_write_room(struct tty_struct *tty)
 {
-	struct hso_serial *serial = get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 	int room;
 	unsigned long flags;
 
@@ -1437,7 +1430,7 @@ static int hso_serial_write_room(struct tty_struct *tty)
 /* setup the term */
 static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
 {
-	struct hso_serial *serial = get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 	unsigned long flags;
 
 	if (old)
@@ -1458,7 +1451,7 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
 /* how many characters in the buffer */
 static int hso_serial_chars_in_buffer(struct tty_struct *tty)
 {
-	struct hso_serial *serial = get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 	int chars;
 	unsigned long flags;
 
@@ -1629,7 +1622,7 @@ static int hso_get_count(struct tty_struct *tty,
 		  struct serial_icounter_struct *icount)
 {
 	struct uart_icount cnow;
-	struct hso_serial *serial = get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 	struct hso_tiocmget  *tiocmget = serial->tiocmget;
 
 	memset(icount, 0, sizeof(struct serial_icounter_struct));
@@ -1659,7 +1652,7 @@ static int hso_get_count(struct tty_struct *tty,
 static int hso_serial_tiocmget(struct tty_struct *tty)
 {
 	int retval;
-	struct hso_serial *serial = get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 	struct hso_tiocmget  *tiocmget;
 	u16 UART_state_bitmap;
 
@@ -1693,7 +1686,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty,
 	int val = 0;
 	unsigned long flags;
 	int if_num;
-	struct hso_serial *serial = get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 
 	/* sanity check */
 	if (!serial) {
@@ -1733,7 +1726,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty,
 static int hso_serial_ioctl(struct tty_struct *tty,
 			    unsigned int cmd, unsigned long arg)
 {
-	struct hso_serial *serial =  get_serial_by_tty(tty);
+	struct hso_serial *serial = tty->driver_data;
 	int ret = 0;
 	D4("IOCTL cmd: %d, arg: %ld", cmd, arg);
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 23/69] TTY: hso, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (21 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 22/69] TTY: hso, remove tty NULL checks fro tty->ops Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 24/69] TTY: con3215, centralize allocation Jiri Slaby
                   ` (45 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Jan Dumon

We switched tty refcounting there to the one provided by tty_port
helpers. So tty_port->tty is now protected by tty_port->lock, not by
hso_serial->serial_lock.

Side note: tty->driver_data does not need the lock, so it is needed
neither in open, nor in close paths.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jan Dumon <j.dumon@option.com>
---
 drivers/net/usb/hso.c |   40 +++++++++++++---------------------------
 1 file changed, 13 insertions(+), 27 deletions(-)

diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index ec782c7..813d709 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -250,7 +250,6 @@ struct hso_serial {
 
 	struct tty_port port;
 	/* from usb_serial_port */
-	struct tty_struct *tty;
 	spinlock_t serial_lock;
 
 	int (*write_data) (struct hso_serial *serial);
@@ -1297,11 +1296,8 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
 	kref_get(&serial->parent->ref);
 
 	/* setup */
-	spin_lock_irq(&serial->serial_lock);
 	tty->driver_data = serial;
-	tty_kref_put(serial->tty);
-	serial->tty = tty_kref_get(tty);
-	spin_unlock_irq(&serial->serial_lock);
+	tty_port_tty_set(&serial->port, tty);
 
 	/* check for port already opened, if not set the termios */
 	serial->port.count++;
@@ -1358,13 +1354,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
 
 	if (serial->port.count <= 0) {
 		serial->port.count = 0;
-		spin_lock_irq(&serial->serial_lock);
-		if (serial->tty == tty) {
-			serial->tty->driver_data = NULL;
-			serial->tty = NULL;
-			tty_kref_put(tty);
-		}
-		spin_unlock_irq(&serial->serial_lock);
+		tty_port_tty_set(&serial->port, NULL);
 		if (!usb_gone)
 			hso_stop_serial_device(serial->parent);
 		tasklet_kill(&serial->unthrottle_tasklet);
@@ -1947,14 +1937,13 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
 
 	spin_lock(&serial->serial_lock);
 	serial->tx_urb_used = 0;
-	tty = tty_kref_get(serial->tty);
 	spin_unlock(&serial->serial_lock);
 	if (status) {
 		handle_usb_error(status, __func__, serial->parent);
-		tty_kref_put(tty);
 		return;
 	}
 	hso_put_activity(serial->parent);
+	tty = tty_port_tty_get(&serial->port);
 	if (tty) {
 		tty_wakeup(tty);
 		tty_kref_put(tty);
@@ -1994,7 +1983,6 @@ static void ctrl_callback(struct urb *urb)
 	struct hso_serial *serial = urb->context;
 	struct usb_ctrlrequest *req;
 	int status = urb->status;
-	struct tty_struct *tty;
 
 	/* sanity check */
 	if (!serial)
@@ -2002,11 +1990,9 @@ static void ctrl_callback(struct urb *urb)
 
 	spin_lock(&serial->serial_lock);
 	serial->tx_urb_used = 0;
-	tty = tty_kref_get(serial->tty);
 	spin_unlock(&serial->serial_lock);
 	if (status) {
 		handle_usb_error(status, __func__, serial->parent);
-		tty_kref_put(tty);
 		return;
 	}
 
@@ -2024,13 +2010,15 @@ static void ctrl_callback(struct urb *urb)
 		put_rxbuf_data_and_resubmit_ctrl_urb(serial);
 		spin_unlock(&serial->serial_lock);
 	} else {
+		struct tty_struct *tty = tty_port_tty_get(&serial->port);
 		hso_put_activity(serial->parent);
-		if (tty)
+		if (tty) {
 			tty_wakeup(tty);
+			tty_kref_put(tty);
+		}
 		/* response to a write command */
 		hso_kick_transmit(serial);
 	}
-	tty_kref_put(tty);
 }
 
 /* handle RX data for serial port */
@@ -2046,8 +2034,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
 		return -2;
 	}
 
-	/* All callers to put_rxbuf_data hold serial_lock */
-	tty = tty_kref_get(serial->tty);
+	tty = tty_port_tty_get(&serial->port);
 
 	/* Push data to tty */
 	if (tty) {
@@ -2067,12 +2054,12 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
 			write_length_remaining -= curr_write_len;
 			tty_flip_buffer_push(tty);
 		}
+		tty_kref_put(tty);
 	}
 	if (write_length_remaining == 0) {
 		serial->curr_rx_urb_offset = 0;
 		serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
 	}
-	tty_kref_put(tty);
 	return write_length_remaining;
 }
 
@@ -3166,13 +3153,12 @@ static void hso_free_interface(struct usb_interface *interface)
 		if (serial_table[i] &&
 		    (serial_table[i]->interface == interface)) {
 			hso_dev = dev2ser(serial_table[i]);
-			spin_lock_irq(&hso_dev->serial_lock);
-			tty = tty_kref_get(hso_dev->tty);
-			spin_unlock_irq(&hso_dev->serial_lock);
-			if (tty)
+			tty = tty_port_tty_get(&hso_dev->port);
+			if (tty) {
 				tty_hangup(tty);
+				tty_kref_put(tty);
+			}
 			mutex_lock(&hso_dev->parent->mutex);
-			tty_kref_put(tty);
 			hso_dev->parent->usb_gone = 1;
 			mutex_unlock(&hso_dev->parent->mutex);
 			kref_put(&serial_table[i]->ref, hso_serial_ref_free);
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 24/69] TTY: con3215, centralize allocation
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (22 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 23/69] TTY: hso, use tty from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-03  5:56   ` Heiko Carstens
  2012-04-02 11:54 ` [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup Jiri Slaby
                   ` (44 subsequent siblings)
  68 siblings, 1 reply; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

There are two copies of allocations of device information. One of them
is totally broken. See:
raw->cdev = cdev;
raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
memset(raw, 0, sizeof(struct raw3215_info));

It suggests that this path was never executed. The code uses both
raw->cdev and raw->inbuf all over. And it is NULL due to the memset
here, so it would panic immediately. I believe nobody used that driver
without being a system console.

Either way, let us fix it by moving the allocations (and
initializations) to a single place. This will save us some double
initializations later too.

And while at it, initialize the timer properly -- once, at the
allocation.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/con3215.c |   74 +++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 35 deletions(-)

diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 4f9f1dc..7e30f85 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -324,10 +324,7 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
 			}
 		} else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
 			/* delay small writes */
-			init_timer(&raw->timer);
 			raw->timer.expires = RAW3215_TIMEOUT + jiffies;
-			raw->timer.data = (unsigned long) raw;
-			raw->timer.function = raw3215_timeout;
 			add_timer(&raw->timer);
 			raw->flags |= RAW3215_TIMER_RUNS;
 		}
@@ -648,6 +645,35 @@ static void raw3215_shutdown(struct raw3215_info *raw)
 	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
 }
 
+static struct raw3215_info *raw3215_alloc_info(void)
+{
+	struct raw3215_info *info;
+
+	info = kzalloc(sizeof(struct raw3215_info), GFP_KERNEL | GFP_DMA);
+	if (!info)
+		return NULL;
+
+	info->buffer = kzalloc(RAW3215_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
+	info->inbuf = kzalloc(RAW3215_INBUF_SIZE, GFP_KERNEL | GFP_DMA);
+	if (!info->buffer || !info->inbuf) {
+		kfree(info);
+		return NULL;
+	}
+
+	setup_timer(&info->timer, raw3215_timeout, (unsigned long)info);
+	init_waitqueue_head(&info->empty_wait);
+	tasklet_init(&info->tlet, raw3215_wakeup, (unsigned long)info);
+
+	return info;
+}
+
+static void raw3215_free_info(struct raw3215_info *raw)
+{
+	kfree(raw->inbuf);
+	kfree(raw->buffer);
+	kfree(raw);
+}
+
 static int raw3215_probe (struct ccw_device *cdev)
 {
 	struct raw3215_info *raw;
@@ -656,11 +682,15 @@ static int raw3215_probe (struct ccw_device *cdev)
 	/* Console is special. */
 	if (raw3215[0] && (raw3215[0] == dev_get_drvdata(&cdev->dev)))
 		return 0;
-	raw = kmalloc(sizeof(struct raw3215_info) +
-		      RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA);
+
+	raw = raw3215_alloc_info();
 	if (raw == NULL)
 		return -ENOMEM;
 
+	raw->cdev = cdev;
+	dev_set_drvdata(&cdev->dev, raw);
+	cdev->handler = raw3215_irq;
+
 	spin_lock(&raw3215_device_lock);
 	for (line = 0; line < NR_3215; line++) {
 		if (!raw3215[line]) {
@@ -670,28 +700,10 @@ static int raw3215_probe (struct ccw_device *cdev)
 	}
 	spin_unlock(&raw3215_device_lock);
 	if (line == NR_3215) {
-		kfree(raw);
+		raw3215_free_info(raw);
 		return -ENODEV;
 	}
 
-	raw->cdev = cdev;
-	raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
-	memset(raw, 0, sizeof(struct raw3215_info));
-	raw->buffer = kmalloc(RAW3215_BUFFER_SIZE,
-				       GFP_KERNEL|GFP_DMA);
-	if (raw->buffer == NULL) {
-		spin_lock(&raw3215_device_lock);
-		raw3215[line] = NULL;
-		spin_unlock(&raw3215_device_lock);
-		kfree(raw);
-		return -ENOMEM;
-	}
-	init_waitqueue_head(&raw->empty_wait);
-	tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
-
-	dev_set_drvdata(&cdev->dev, raw);
-	cdev->handler = raw3215_irq;
-
 	return 0;
 }
 
@@ -703,8 +715,7 @@ static void raw3215_remove (struct ccw_device *cdev)
 	raw = dev_get_drvdata(&cdev->dev);
 	if (raw) {
 		dev_set_drvdata(&cdev->dev, NULL);
-		kfree(raw->buffer);
-		kfree(raw);
+		raw3215_free_info(raw);
 	}
 }
 
@@ -897,23 +908,16 @@ static int __init con3215_init(void)
 	if (IS_ERR(cdev))
 		return -ENODEV;
 
-	raw3215[0] = raw = (struct raw3215_info *)
-		kzalloc(sizeof(struct raw3215_info), GFP_KERNEL | GFP_DMA);
-	raw->buffer = kzalloc(RAW3215_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
-	raw->inbuf = kzalloc(RAW3215_INBUF_SIZE, GFP_KERNEL | GFP_DMA);
+	raw3215[0] = raw = raw3215_alloc_info();
 	raw->cdev = cdev;
 	dev_set_drvdata(&cdev->dev, raw);
 	cdev->handler = raw3215_irq;
 
 	raw->flags |= RAW3215_FIXED;
-	init_waitqueue_head(&raw->empty_wait);
-	tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
 
 	/* Request the console irq */
 	if (raw3215_startup(raw) != 0) {
-		kfree(raw->inbuf);
-		kfree(raw->buffer);
-		kfree(raw);
+		raw3215_free_info(raw);
 		raw3215[0] = NULL;
 		return -ENODEV;
 	}
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (23 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 24/69] TTY: con3215, centralize allocation Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-03  5:42   ` Heiko Carstens
  2012-04-02 11:54 ` [PATCH 26/69] TTY: con3215, add tty_port Jiri Slaby
                   ` (43 subsequent siblings)
  68 siblings, 1 reply; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

tty_wakeup is safe to be called from all contexts. No need to schedule
a tasklet for that. Let us call it directly like in other drivers.

And delete the tasklet completely.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/con3215.c |   14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 7e30f85..fb195f3 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -87,7 +87,6 @@ struct raw3215_info {
 	struct tty_struct *tty;	      /* pointer to tty structure if present */
 	struct raw3215_req *queued_read; /* pointer to queued read requests */
 	struct raw3215_req *queued_write;/* pointer to queued write requests */
-	struct tasklet_struct tlet;   /* tasklet to invoke tty_wakeup */
 	wait_queue_head_t empty_wait; /* wait queue for flushing */
 	struct timer_list timer;      /* timer for delayed output */
 	int line_pos;		      /* position on the line (for tabs) */
@@ -332,15 +331,6 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
 }
 
 /*
- * Call tty_wakeup from tasklet context
- */
-static void raw3215_wakeup(unsigned long data)
-{
-	struct raw3215_info *raw = (struct raw3215_info *) data;
-	tty_wakeup(raw->tty);
-}
-
-/*
  * Try to start the next IO and wake up processes waiting on the tty.
  */
 static void raw3215_next_io(struct raw3215_info *raw)
@@ -348,7 +338,7 @@ static void raw3215_next_io(struct raw3215_info *raw)
 	raw3215_mk_write_req(raw);
 	raw3215_try_io(raw);
 	if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
-		tasklet_schedule(&raw->tlet);
+		tty_wakeup(raw->tty);
 }
 
 /*
@@ -662,7 +652,6 @@ static struct raw3215_info *raw3215_alloc_info(void)
 
 	setup_timer(&info->timer, raw3215_timeout, (unsigned long)info);
 	init_waitqueue_head(&info->empty_wait);
-	tasklet_init(&info->tlet, raw3215_wakeup, (unsigned long)info);
 
 	return info;
 }
@@ -973,7 +962,6 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp)
 	tty->closing = 1;
 	/* Shutdown the terminal */
 	raw3215_shutdown(raw);
-	tasklet_kill(&raw->tlet);
 	tty->closing = 0;
 	raw->tty = NULL;
 }
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 26/69] TTY: con3215, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (24 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 27/69] TTY: con3215, use tty from tty_port Jiri Slaby
                   ` (42 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

And use flags from that. But first we have to get rid of duplicated
flag names. From now on, for the standard ones that are stored in
tty_port->flags, we use ASYNC_* ones.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/con3215.c |   30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index fb195f3..9a76614 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -20,6 +20,7 @@
 #include <linux/interrupt.h>
 #include <linux/err.h>
 #include <linux/reboot.h>
+#include <linux/serial.h> /* ASYNC_* flags */
 #include <linux/slab.h>
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
@@ -44,14 +45,11 @@
 #define RAW3215_TIMEOUT	    HZ/10     /* time for delayed output */
 
 #define RAW3215_FIXED	    1	      /* 3215 console device is not be freed */
-#define RAW3215_ACTIVE	    2	      /* set if the device is in use */
 #define RAW3215_WORKING	    4	      /* set if a request is being worked on */
 #define RAW3215_THROTTLED   8	      /* set if reading is disabled */
 #define RAW3215_STOPPED	    16	      /* set if writing is disabled */
-#define RAW3215_CLOSING	    32	      /* set while in close process */
 #define RAW3215_TIMER_RUNS  64	      /* set if the output delay timer is on */
 #define RAW3215_FLUSHING    128	      /* set to flush buffer (no delay) */
-#define RAW3215_FROZEN	    256	      /* set if 3215 is frozen for suspend */
 
 #define TAB_STOP_SIZE	    8	      /* tab stop size */
 
@@ -76,6 +74,7 @@ struct raw3215_req {
 } __attribute__ ((aligned(8)));
 
 struct raw3215_info {
+	struct tty_port port;
 	struct ccw_device *cdev;      /* device for tty driver */
 	spinlock_t *lock;	      /* pointer to irq lock */
 	int flags;		      /* state flags */
@@ -292,7 +291,7 @@ static void raw3215_timeout(unsigned long __data)
 	if (raw->flags & RAW3215_TIMER_RUNS) {
 		del_timer(&raw->timer);
 		raw->flags &= ~RAW3215_TIMER_RUNS;
-		if (!(raw->flags & RAW3215_FROZEN)) {
+		if (!(raw->port.flags & ASYNC_SUSPENDED)) {
 			raw3215_mk_write_req(raw);
 			raw3215_start_io(raw);
 		}
@@ -308,7 +307,8 @@ static void raw3215_timeout(unsigned long __data)
  */
 static inline void raw3215_try_io(struct raw3215_info *raw)
 {
-	if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FROZEN))
+	if (!(raw->port.flags & ASYNC_INITIALIZED) ||
+			(raw->port.flags & ASYNC_SUSPENDED))
 		return;
 	if (raw->queued_read != NULL)
 		raw3215_start_io(raw);
@@ -474,7 +474,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length)
 		/* While console is frozen for suspend we have no other
 		 * choice but to drop message from the buffer to make
 		 * room for even more messages. */
-		if (raw->flags & RAW3215_FROZEN) {
+		if (raw->port.flags & ASYNC_SUSPENDED) {
 			raw3215_drop_line(raw);
 			continue;
 		}
@@ -596,10 +596,10 @@ static int raw3215_startup(struct raw3215_info *raw)
 {
 	unsigned long flags;
 
-	if (raw->flags & RAW3215_ACTIVE)
+	if (raw->port.flags & ASYNC_INITIALIZED)
 		return 0;
 	raw->line_pos = 0;
-	raw->flags |= RAW3215_ACTIVE;
+	raw->port.flags |= ASYNC_INITIALIZED;
 	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
 	raw3215_try_io(raw);
 	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -615,14 +615,15 @@ static void raw3215_shutdown(struct raw3215_info *raw)
 	DECLARE_WAITQUEUE(wait, current);
 	unsigned long flags;
 
-	if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED))
+	if (!(raw->port.flags & ASYNC_INITIALIZED) ||
+			(raw->flags & RAW3215_FIXED))
 		return;
 	/* Wait for outstanding requests, then free irq */
 	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
 	if ((raw->flags & RAW3215_WORKING) ||
 	    raw->queued_write != NULL ||
 	    raw->queued_read != NULL) {
-		raw->flags |= RAW3215_CLOSING;
+		raw->port.flags |= ASYNC_CLOSING;
 		add_wait_queue(&raw->empty_wait, &wait);
 		set_current_state(TASK_INTERRUPTIBLE);
 		spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -630,7 +631,7 @@ static void raw3215_shutdown(struct raw3215_info *raw)
 		spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
 		remove_wait_queue(&raw->empty_wait, &wait);
 		set_current_state(TASK_RUNNING);
-		raw->flags &= ~(RAW3215_ACTIVE | RAW3215_CLOSING);
+		raw->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING);
 	}
 	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
 }
@@ -652,6 +653,7 @@ static struct raw3215_info *raw3215_alloc_info(void)
 
 	setup_timer(&info->timer, raw3215_timeout, (unsigned long)info);
 	init_waitqueue_head(&info->empty_wait);
+	tty_port_init(&info->port);
 
 	return info;
 }
@@ -741,7 +743,7 @@ static int raw3215_pm_stop(struct ccw_device *cdev)
 	raw = dev_get_drvdata(&cdev->dev);
 	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
 	raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
-	raw->flags |= RAW3215_FROZEN;
+	raw->port.flags |= ASYNC_SUSPENDED;
 	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
 	return 0;
 }
@@ -754,7 +756,7 @@ static int raw3215_pm_start(struct ccw_device *cdev)
 	/* Allow I/O again and flush output buffer. */
 	raw = dev_get_drvdata(&cdev->dev);
 	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
-	raw->flags &= ~RAW3215_FROZEN;
+	raw->port.flags &= ~ASYNC_SUSPENDED;
 	raw->flags |= RAW3215_FLUSHING;
 	raw3215_try_io(raw);
 	raw->flags &= ~RAW3215_FLUSHING;
@@ -827,7 +829,7 @@ static void con3215_flush(void)
 	unsigned long flags;
 
 	raw = raw3215[0];  /* console 3215 is the first one */
-	if (raw->flags & RAW3215_FROZEN)
+	if (raw->port.flags & ASYNC_SUSPENDED)
 		/* The console is still frozen for suspend. */
 		if (ccw_device_force_console())
 			/* Forcing didn't work, no panic message .. */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 27/69] TTY: con3215, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (25 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 26/69] TTY: con3215, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 28/69] TTY: sclp_tty, add tty_port Jiri Slaby
                   ` (41 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

Obtain tty_struct only once in ISR and pass it down to
raw3215_next_io. Other than that, we just use the tty with raised
reference. And set it properly in open and close.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/con3215.c |   34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 9a76614..3e01756 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -83,7 +83,6 @@ struct raw3215_info {
 	int head;		      /* first free byte in output buffer */
 	int count;		      /* number of bytes in output buffer */
 	int written;		      /* number of bytes in write requests */
-	struct tty_struct *tty;	      /* pointer to tty structure if present */
 	struct raw3215_req *queued_read; /* pointer to queued read requests */
 	struct raw3215_req *queued_write;/* pointer to queued write requests */
 	wait_queue_head_t empty_wait; /* wait queue for flushing */
@@ -333,12 +332,12 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
 /*
  * Try to start the next IO and wake up processes waiting on the tty.
  */
-static void raw3215_next_io(struct raw3215_info *raw)
+static void raw3215_next_io(struct raw3215_info *raw, struct tty_struct *tty)
 {
 	raw3215_mk_write_req(raw);
 	raw3215_try_io(raw);
-	if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
-		tty_wakeup(raw->tty);
+	if (tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
+		tty_wakeup(tty);
 }
 
 /*
@@ -355,10 +354,11 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
 
 	raw = dev_get_drvdata(&cdev->dev);
 	req = (struct raw3215_req *) intparm;
+	tty = tty_port_tty_get(&raw->port);
 	cstat = irb->scsw.cmd.cstat;
 	dstat = irb->scsw.cmd.dstat;
 	if (cstat != 0)
-		raw3215_next_io(raw);
+		raw3215_next_io(raw, tty);
 	if (dstat & 0x01) { /* we got a unit exception */
 		dstat &= ~0x01;	 /* we can ignore it */
 	}
@@ -368,13 +368,13 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
 			break;
 		/* Attention interrupt, someone hit the enter key */
 		raw3215_mk_read_req(raw);
-		raw3215_next_io(raw);
+		raw3215_next_io(raw, tty);
 		break;
 	case 0x08:
 	case 0x0C:
 		/* Channel end interrupt. */
 		if ((raw = req->info) == NULL)
-			return;		     /* That shouldn't happen ... */
+			goto put_tty;	     /* That shouldn't happen ... */
 		if (req->type == RAW3215_READ) {
 			/* store residual count, then wait for device end */
 			req->residual = irb->scsw.cmd.count;
@@ -384,11 +384,10 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
 	case 0x04:
 		/* Device end interrupt. */
 		if ((raw = req->info) == NULL)
-			return;		     /* That shouldn't happen ... */
-		if (req->type == RAW3215_READ && raw->tty != NULL) {
+			goto put_tty;	     /* That shouldn't happen ... */
+		if (req->type == RAW3215_READ && tty != NULL) {
 			unsigned int cchar;
 
-			tty = raw->tty;
 			count = 160 - req->residual;
 			EBCASC(raw->inbuf, count);
 			cchar = ctrlchar_handle(raw->inbuf, count, tty);
@@ -398,7 +397,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
 
 			case CTRLCHAR_CTRL:
 				tty_insert_flip_char(tty, cchar, TTY_NORMAL);
-				tty_flip_buffer_push(raw->tty);
+				tty_flip_buffer_push(tty);
 				break;
 
 			case CTRLCHAR_NONE:
@@ -411,7 +410,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
 				} else
 					count -= 2;
 				tty_insert_flip_string(tty, raw->inbuf, count);
-				tty_flip_buffer_push(raw->tty);
+				tty_flip_buffer_push(tty);
 				break;
 			}
 		} else if (req->type == RAW3215_WRITE) {
@@ -426,7 +425,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
 		    raw->queued_read == NULL) {
 			wake_up_interruptible(&raw->empty_wait);
 		}
-		raw3215_next_io(raw);
+		raw3215_next_io(raw, tty);
 		break;
 	default:
 		/* Strange interrupt, I'll do my best to clean up */
@@ -438,9 +437,10 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
 			raw->flags &= ~RAW3215_WORKING;
 			raw3215_free_req(req);
 		}
-		raw3215_next_io(raw);
+		raw3215_next_io(raw, tty);
 	}
-	return;
+put_tty:
+	tty_kref_put(tty);
 }
 
 /*
@@ -935,7 +935,7 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp)
 		return -ENODEV;
 
 	tty->driver_data = raw;
-	raw->tty = tty;
+	tty_port_tty_set(&raw->port, tty);
 
 	tty->low_latency = 0;  /* don't use bottom half for pushing chars */
 	/*
@@ -965,7 +965,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp)
 	/* Shutdown the terminal */
 	raw3215_shutdown(raw);
 	tty->closing = 0;
-	raw->tty = NULL;
+	tty_port_tty_set(&raw->port, NULL);
 }
 
 /*
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 28/69] TTY: sclp_tty, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (26 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 27/69] TTY: con3215, use tty from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 29/69] TTY: sclp_vt220, " Jiri Slaby
                   ` (40 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

tty_port will hold tty buffers in the future. So we need to have it
even here. The only needed member here is tty, so let us store it in
the structure now.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/sclp_tty.c |   33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 40a9d69..e66a75b 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -48,7 +48,7 @@ static struct sclp_buffer *sclp_ttybuf;
 /* Timer for delayed output of console messages. */
 static struct timer_list sclp_tty_timer;
 
-static struct tty_struct *sclp_tty;
+static struct tty_port sclp_port;
 static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE];
 static unsigned short int sclp_tty_chars_count;
 
@@ -64,7 +64,7 @@ static int sclp_tty_columns = 80;
 static int
 sclp_tty_open(struct tty_struct *tty, struct file *filp)
 {
-	sclp_tty = tty;
+	tty_port_tty_set(&sclp_port, tty);
 	tty->driver_data = NULL;
 	tty->low_latency = 0;
 	return 0;
@@ -76,7 +76,7 @@ sclp_tty_close(struct tty_struct *tty, struct file *filp)
 {
 	if (tty->count > 1)
 		return;
-	sclp_tty = NULL;
+	tty_port_tty_set(&sclp_port, NULL);
 }
 
 /*
@@ -108,6 +108,7 @@ sclp_tty_write_room (struct tty_struct *tty)
 static void
 sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
 {
+	struct tty_struct *tty;
 	unsigned long flags;
 	void *page;
 
@@ -126,8 +127,10 @@ sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
 		spin_unlock_irqrestore(&sclp_tty_lock, flags);
 	} while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback));
 	/* check if the tty needs a wake up call */
-	if (sclp_tty != NULL) {
-		tty_wakeup(sclp_tty);
+	tty = tty_port_tty_get(&sclp_port);
+	if (tty != NULL) {
+		tty_wakeup(tty);
+		tty_kref_put(tty);
 	}
 }
 
@@ -326,21 +329,22 @@ sclp_tty_flush_buffer(struct tty_struct *tty)
 static void
 sclp_tty_input(unsigned char* buf, unsigned int count)
 {
+	struct tty_struct *tty = tty_port_tty_get(&sclp_port);
 	unsigned int cchar;
 
 	/*
 	 * If this tty driver is currently closed
 	 * then throw the received input away.
 	 */
-	if (sclp_tty == NULL)
+	if (tty == NULL)
 		return;
-	cchar = ctrlchar_handle(buf, count, sclp_tty);
+	cchar = ctrlchar_handle(buf, count, tty);
 	switch (cchar & CTRLCHAR_MASK) {
 	case CTRLCHAR_SYSRQ:
 		break;
 	case CTRLCHAR_CTRL:
-		tty_insert_flip_char(sclp_tty, cchar, TTY_NORMAL);
-		tty_flip_buffer_push(sclp_tty);
+		tty_insert_flip_char(tty, cchar, TTY_NORMAL);
+		tty_flip_buffer_push(tty);
 		break;
 	case CTRLCHAR_NONE:
 		/* send (normal) input to line discipline */
@@ -348,13 +352,14 @@ sclp_tty_input(unsigned char* buf, unsigned int count)
 		    (strncmp((const char *) buf + count - 2, "^n", 2) &&
 		     strncmp((const char *) buf + count - 2, "\252n", 2))) {
 			/* add the auto \n */
-			tty_insert_flip_string(sclp_tty, buf, count);
-			tty_insert_flip_char(sclp_tty, '\n', TTY_NORMAL);
+			tty_insert_flip_string(tty, buf, count);
+			tty_insert_flip_char(tty, '\n', TTY_NORMAL);
 		} else
-			tty_insert_flip_string(sclp_tty, buf, count - 2);
-		tty_flip_buffer_push(sclp_tty);
+			tty_insert_flip_string(tty, buf, count - 2);
+		tty_flip_buffer_push(tty);
 		break;
 	}
+	tty_kref_put(tty);
 }
 
 /*
@@ -543,7 +548,7 @@ sclp_tty_init(void)
 		sclp_tty_tolower = 1;
 	}
 	sclp_tty_chars_count = 0;
-	sclp_tty = NULL;
+	tty_port_init(&sclp_port);
 
 	rc = sclp_register(&sclp_input_event);
 	if (rc) {
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 29/69] TTY: sclp_vt220, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (27 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 28/69] TTY: sclp_tty, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 30/69] TTY: sclp_vt220, remove unused allocation Jiri Slaby
                   ` (39 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

tty_port will hold tty buffers in the future. So we need to have it
even here. The only needed member here is tty, so let us store it in
the structure now.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/sclp_vt220.c |   24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index b635472..25cf2e8 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -56,8 +56,7 @@ struct sclp_vt220_sccb {
 /* Structures and data needed to register tty driver */
 static struct tty_driver *sclp_vt220_driver;
 
-/* The tty_struct that the kernel associated with us */
-static struct tty_struct *sclp_vt220_tty;
+static struct tty_port sclp_vt220_port;
 
 /* Lock to protect internal data from concurrent access */
 static spinlock_t sclp_vt220_lock;
@@ -116,6 +115,7 @@ static struct sclp_register sclp_vt220_register = {
 static void
 sclp_vt220_process_queue(struct sclp_vt220_request *request)
 {
+	struct tty_struct *tty;
 	unsigned long flags;
 	void *page;
 
@@ -141,8 +141,10 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request)
 	if (request == NULL && sclp_vt220_flush_later)
 		sclp_vt220_emit_current();
 	/* Check if the tty needs a wake up call */
-	if (sclp_vt220_tty != NULL) {
-		tty_wakeup(sclp_vt220_tty);
+	tty = tty_port_tty_get(&sclp_vt220_port);
+	if (tty) {
+		tty_wakeup(tty);
+		tty_kref_put(tty);
 	}
 }
 
@@ -460,11 +462,12 @@ sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count)
 static void
 sclp_vt220_receiver_fn(struct evbuf_header *evbuf)
 {
+	struct tty_struct *tty = tty_port_tty_get(&sclp_vt220_port);
 	char *buffer;
 	unsigned int count;
 
 	/* Ignore input if device is not open */
-	if (sclp_vt220_tty == NULL)
+	if (tty == NULL)
 		return;
 
 	buffer = (char *) ((addr_t) evbuf + sizeof(struct evbuf_header));
@@ -478,10 +481,11 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf)
 		/* Send input to line discipline */
 		buffer++;
 		count--;
-		tty_insert_flip_string(sclp_vt220_tty, buffer, count);
-		tty_flip_buffer_push(sclp_vt220_tty);
+		tty_insert_flip_string(tty, buffer, count);
+		tty_flip_buffer_push(tty);
 		break;
 	}
+	tty_kref_put(tty);
 }
 
 /*
@@ -491,7 +495,7 @@ static int
 sclp_vt220_open(struct tty_struct *tty, struct file *filp)
 {
 	if (tty->count == 1) {
-		sclp_vt220_tty = tty;
+		tty_port_tty_set(&sclp_vt220_port, tty);
 		tty->driver_data = kmalloc(SCLP_VT220_BUF_SIZE, GFP_KERNEL);
 		if (tty->driver_data == NULL)
 			return -ENOMEM;
@@ -511,7 +515,7 @@ static void
 sclp_vt220_close(struct tty_struct *tty, struct file *filp)
 {
 	if (tty->count == 1) {
-		sclp_vt220_tty = NULL;
+		tty_port_tty_set(&sclp_vt220_port, NULL);
 		kfree(tty->driver_data);
 		tty->driver_data = NULL;
 	}
@@ -635,9 +639,9 @@ static int __init __sclp_vt220_init(int num_pages)
 	INIT_LIST_HEAD(&sclp_vt220_empty);
 	INIT_LIST_HEAD(&sclp_vt220_outqueue);
 	init_timer(&sclp_vt220_timer);
+	tty_port_init(&sclp_vt220_port);
 	sclp_vt220_current_request = NULL;
 	sclp_vt220_buffered_chars = 0;
-	sclp_vt220_tty = NULL;
 	sclp_vt220_flush_later = 0;
 
 	/* Allocate pages for output buffering */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 30/69] TTY: sclp_vt220, remove unused allocation
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (28 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 29/69] TTY: sclp_vt220, " Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 31/69] TTY: tty3270, move initialization to allocation Jiri Slaby
                   ` (38 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

80 bytes which are allocated in tty->ops->open and assigned to
tty->driver_data are never used. Remove that.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/sclp_vt220.c |    9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 25cf2e8..edfc0fd 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -34,7 +34,6 @@
 #define SCLP_VT220_DEVICE_NAME		"ttysclp"
 #define SCLP_VT220_CONSOLE_NAME		"ttyS"
 #define SCLP_VT220_CONSOLE_INDEX	1	/* console=ttyS1 */
-#define SCLP_VT220_BUF_SIZE		80
 
 /* Representation of a single write request */
 struct sclp_vt220_request {
@@ -496,9 +495,6 @@ sclp_vt220_open(struct tty_struct *tty, struct file *filp)
 {
 	if (tty->count == 1) {
 		tty_port_tty_set(&sclp_vt220_port, tty);
-		tty->driver_data = kmalloc(SCLP_VT220_BUF_SIZE, GFP_KERNEL);
-		if (tty->driver_data == NULL)
-			return -ENOMEM;
 		tty->low_latency = 0;
 		if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
 			tty->winsize.ws_row = 24;
@@ -514,11 +510,8 @@ sclp_vt220_open(struct tty_struct *tty, struct file *filp)
 static void
 sclp_vt220_close(struct tty_struct *tty, struct file *filp)
 {
-	if (tty->count == 1) {
+	if (tty->count == 1)
 		tty_port_tty_set(&sclp_vt220_port, NULL);
-		kfree(tty->driver_data);
-		tty->driver_data = NULL;
-	}
 }
 
 /*
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 31/69] TTY: tty3270, move initialization to allocation
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (29 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 30/69] TTY: sclp_vt220, remove unused allocation Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 32/69] TTY: tty3270, get rid of ugly aliasing Jiri Slaby
                   ` (37 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

Let us initialize all the tty3270's members at the place where the
structure is allocated.

It cleans up tty->ops->open a bit.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/tty3270.c |   20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index b43445a..f3837da 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -690,6 +690,16 @@ tty3270_alloc_view(void)
 	if (!tp->freemem_pages)
 		goto out_tp;
 	INIT_LIST_HEAD(&tp->freemem);
+	INIT_LIST_HEAD(&tp->lines);
+	INIT_LIST_HEAD(&tp->update);
+	INIT_LIST_HEAD(&tp->rcl_lines);
+	tp->rcl_max = 20;
+	setup_timer(&tp->timer, (void (*)(unsigned long)) tty3270_update,
+		    (unsigned long) tp);
+	tasklet_init(&tp->readlet,
+		     (void (*)(unsigned long)) tty3270_read_tasklet,
+		     (unsigned long) tp->read);
+
 	for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) {
 		tp->freemem_pages[pages] = (void *)
 			__get_free_pages(GFP_KERNEL|GFP_DMA, 0);
@@ -879,16 +889,6 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
 	if (IS_ERR(tp))
 		return PTR_ERR(tp);
 
-	INIT_LIST_HEAD(&tp->lines);
-	INIT_LIST_HEAD(&tp->update);
-	INIT_LIST_HEAD(&tp->rcl_lines);
-	tp->rcl_max = 20;
-	setup_timer(&tp->timer, (void (*)(unsigned long)) tty3270_update,
-		    (unsigned long) tp);
-	tasklet_init(&tp->readlet, 
-		     (void (*)(unsigned long)) tty3270_read_tasklet,
-		     (unsigned long) tp->read);
-
 	rc = raw3270_add_view(&tp->view, &tty3270_fn,
 			      tty->index + RAW3270_FIRSTMINOR);
 	if (rc) {
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 32/69] TTY: tty3270, get rid of ugly aliasing
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (30 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 31/69] TTY: tty3270, move initialization to allocation Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 33/69] TTY: tty3270, push tty down to tty3270_do_write Jiri Slaby
                   ` (36 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

Blah, do not assume that raw3270_view is at the beginning of tty3270.
Use proper types and container_of wherever needed.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/tty3270.c |   42 +++++++++++++++++++-----------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index f3837da..bb1514a 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -324,9 +324,8 @@ tty3270_blank_line(struct tty3270 *tp)
 static void
 tty3270_write_callback(struct raw3270_request *rq, void *data)
 {
-	struct tty3270 *tp;
+	struct tty3270 *tp = container_of(rq->view, struct tty3270, view);
 
-	tp = (struct tty3270 *) rq->view;
 	if (rq->rc != 0) {
 		/* Write wasn't successful. Refresh all. */
 		tp->update_flags = TTY_UPDATE_ALL;
@@ -537,11 +536,10 @@ static void
 tty3270_read_tasklet(struct raw3270_request *rrq)
 {
 	static char kreset_data = TW_KR;
-	struct tty3270 *tp;
+	struct tty3270 *tp = container_of(rrq->view, struct tty3270, view);
 	char *input;
 	int len;
 
-	tp = (struct tty3270 *) rrq->view;
 	spin_lock_bh(&tp->view.lock);
 	/*
 	 * Two AID keys are special: For 0x7d (enter) the input line
@@ -596,9 +594,10 @@ tty3270_read_tasklet(struct raw3270_request *rrq)
 static void
 tty3270_read_callback(struct raw3270_request *rq, void *data)
 {
+	struct tty3270 *tp = container_of(rq->view, struct tty3270, view);
 	raw3270_get_view(rq->view);
 	/* Schedule tasklet to pass input to tty. */
-	tasklet_schedule(&((struct tty3270 *) rq->view)->readlet);
+	tasklet_schedule(&tp->readlet);
 }
 
 /*
@@ -635,9 +634,8 @@ tty3270_issue_read(struct tty3270 *tp, int lock)
 static int
 tty3270_activate(struct raw3270_view *view)
 {
-	struct tty3270 *tp;
+	struct tty3270 *tp = container_of(view, struct tty3270, view);
 
-	tp = (struct tty3270 *) view;
 	tp->update_flags = TTY_UPDATE_ALL;
 	tty3270_set_timer(tp, 1);
 	return 0;
@@ -646,9 +644,8 @@ tty3270_activate(struct raw3270_view *view)
 static void
 tty3270_deactivate(struct raw3270_view *view)
 {
-	struct tty3270 *tp;
+	struct tty3270 *tp = container_of(view, struct tty3270, view);
 
-	tp = (struct tty3270 *) view;
 	del_timer(&tp->timer);
 }
 
@@ -804,10 +801,9 @@ tty3270_free_screen(struct tty3270 *tp)
 static void
 tty3270_release(struct raw3270_view *view)
 {
-	struct tty3270 *tp;
+	struct tty3270 *tp = container_of(view, struct tty3270, view);
 	struct tty_struct *tty;
 
-	tp = (struct tty3270 *) view;
 	tty = tp->tty;
 	if (tty) {
 		tty->driver_data = NULL;
@@ -823,8 +819,9 @@ tty3270_release(struct raw3270_view *view)
 static void
 tty3270_free(struct raw3270_view *view)
 {
-	tty3270_free_screen((struct tty3270 *) view);
-	tty3270_free_view((struct tty3270 *) view);
+	struct tty3270 *tp = container_of(view, struct tty3270, view);
+	tty3270_free_screen(tp);
+	tty3270_free_view(tp);
 }
 
 /*
@@ -833,14 +830,13 @@ tty3270_free(struct raw3270_view *view)
 static void
 tty3270_del_views(void)
 {
-	struct tty3270 *tp;
 	int i;
 
 	for (i = 0; i < tty3270_max_index; i++) {
-		tp = (struct tty3270 *)
+		struct raw3270_view *view =
 			raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
-		if (!IS_ERR(tp))
-			raw3270_del_view(&tp->view);
+		if (!IS_ERR(view))
+			raw3270_del_view(view);
 	}
 }
 
@@ -858,16 +854,17 @@ static struct raw3270_fn tty3270_fn = {
 static int
 tty3270_open(struct tty_struct *tty, struct file * filp)
 {
+	struct raw3270_view *view;
 	struct tty3270 *tp;
 	int i, rc;
 
 	if (tty->count > 1)
 		return 0;
 	/* Check if the tty3270 is already there. */
-	tp = (struct tty3270 *)
-		raw3270_find_view(&tty3270_fn,
+	view = raw3270_find_view(&tty3270_fn,
 				  tty->index + RAW3270_FIRSTMINOR);
-	if (!IS_ERR(tp)) {
+	if (!IS_ERR(view)) {
+		tp = container_of(view, struct tty3270, view);
 		tty->driver_data = tp;
 		tty->winsize.ws_row = tp->view.rows - 2;
 		tty->winsize.ws_col = tp->view.cols;
@@ -881,7 +878,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
 		tty3270_max_index = tty->index + 1;
 
 	/* Quick exit if there is no device for tty->index. */
-	if (PTR_ERR(tp) == -ENODEV)
+	if (PTR_ERR(view) == -ENODEV)
 		return -ENODEV;
 
 	/* Allocate tty3270 structure on first open. */
@@ -935,11 +932,10 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
 static void
 tty3270_close(struct tty_struct *tty, struct file * filp)
 {
-	struct tty3270 *tp;
+	struct tty3270 *tp = tty->driver_data;
 
 	if (tty->count > 1)
 		return;
-	tp = (struct tty3270 *) tty->driver_data;
 	if (tp) {
 		tty->driver_data = NULL;
 		tp->tty = tp->kbd->tty = NULL;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 33/69] TTY: tty3270, push tty down to tty3270_do_write
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (31 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 32/69] TTY: tty3270, get rid of ugly aliasing Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 34/69] TTY: tty3270, add tty_port Jiri Slaby
                   ` (35 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

So that we do not need to access tp->tty there. It is going away.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/tty3270.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index bb1514a..1f4aff7 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -1509,12 +1509,13 @@ tty3270_escape_sequence(struct tty3270 *tp, char ch)
  * String write routine for 3270 ttys
  */
 static void
-tty3270_do_write(struct tty3270 *tp, const unsigned char *buf, int count)
+tty3270_do_write(struct tty3270 *tp, struct tty_struct *tty,
+		const unsigned char *buf, int count)
 {
 	int i_msg, i;
 
 	spin_lock_bh(&tp->view.lock);
-	for (i_msg = 0; !tp->tty->stopped && i_msg < count; i_msg++) {
+	for (i_msg = 0; !tty->stopped && i_msg < count; i_msg++) {
 		if (tp->esc_state != 0) {
 			/* Continue escape sequence. */
 			tty3270_escape_sequence(tp, buf[i_msg]);
@@ -1591,10 +1592,10 @@ tty3270_write(struct tty_struct * tty,
 	if (!tp)
 		return 0;
 	if (tp->char_count > 0) {
-		tty3270_do_write(tp, tp->char_buf, tp->char_count);
+		tty3270_do_write(tp, tty, tp->char_buf, tp->char_count);
 		tp->char_count = 0;
 	}
-	tty3270_do_write(tp, buf, count);
+	tty3270_do_write(tp, tty, buf, count);
 	return count;
 }
 
@@ -1625,7 +1626,7 @@ tty3270_flush_chars(struct tty_struct *tty)
 	if (!tp)
 		return;
 	if (tp->char_count > 0) {
-		tty3270_do_write(tp, tp->char_buf, tp->char_count);
+		tty3270_do_write(tp, tty, tp->char_buf, tp->char_count);
 		tp->char_count = 0;
 	}
 }
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 34/69] TTY: tty3270, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (32 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 33/69] TTY: tty3270, push tty down to tty3270_do_write Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 35/69] TTY: bfin_jtag_comm, " Jiri Slaby
                   ` (34 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh
  Cc: alan, linux-kernel, jirislaby, Martin Schwidefsky,
	Heiko Carstens, linux390, linux-s390

And use tty from that. This means, we convert most of the users to
accept tty_port instead. This is not racy and ensures the tty to be
properly refcounted.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
---
 drivers/s390/char/keyboard.c |   30 ++++++++++++++------------
 drivers/s390/char/keyboard.h |   14 +++++++++---
 drivers/s390/char/tty3270.c  |   48 ++++++++++++++++++------------------------
 3 files changed, 49 insertions(+), 43 deletions(-)

diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index 8065881..7ef9cfd 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -199,7 +199,7 @@ handle_diacr(struct kbd_data *kbd, unsigned int ch)
 	if (ch == ' ' || ch == d)
 		return d;
 
-	kbd_put_queue(kbd->tty, d);
+	kbd_put_queue(kbd->port, d);
 	return ch;
 }
 
@@ -221,7 +221,7 @@ k_self(struct kbd_data *kbd, unsigned char value)
 {
 	if (kbd->diacr)
 		value = handle_diacr(kbd, value);
-	kbd_put_queue(kbd->tty, value);
+	kbd_put_queue(kbd->port, value);
 }
 
 /*
@@ -239,7 +239,7 @@ static void
 k_fn(struct kbd_data *kbd, unsigned char value)
 {
 	if (kbd->func_table[value])
-		kbd_puts_queue(kbd->tty, kbd->func_table[value]);
+		kbd_puts_queue(kbd->port, kbd->func_table[value]);
 }
 
 static void
@@ -257,20 +257,20 @@ k_spec(struct kbd_data *kbd, unsigned char value)
  * but we need only 16 bits here
  */
 static void
-to_utf8(struct tty_struct *tty, ushort c) 
+to_utf8(struct tty_port *port, ushort c)
 {
 	if (c < 0x80)
 		/*  0******* */
-		kbd_put_queue(tty, c);
+		kbd_put_queue(port, c);
 	else if (c < 0x800) {
 		/* 110***** 10****** */
-		kbd_put_queue(tty, 0xc0 | (c >> 6));
-		kbd_put_queue(tty, 0x80 | (c & 0x3f));
+		kbd_put_queue(port, 0xc0 | (c >> 6));
+		kbd_put_queue(port, 0x80 | (c & 0x3f));
 	} else {
 		/* 1110**** 10****** 10****** */
-		kbd_put_queue(tty, 0xe0 | (c >> 12));
-		kbd_put_queue(tty, 0x80 | ((c >> 6) & 0x3f));
-		kbd_put_queue(tty, 0x80 | (c & 0x3f));
+		kbd_put_queue(port, 0xe0 | (c >> 12));
+		kbd_put_queue(port, 0x80 | ((c >> 6) & 0x3f));
+		kbd_put_queue(port, 0x80 | (c & 0x3f));
 	}
 }
 
@@ -283,7 +283,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode)
 	unsigned short keysym;
 	unsigned char type, value;
 
-	if (!kbd || !kbd->tty)
+	if (!kbd)
 		return;
 
 	if (keycode >= 384)
@@ -323,7 +323,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode)
 #endif
 		(*k_handler[type])(kbd, value);
 	} else
-		to_utf8(kbd->tty, keysym);
+		to_utf8(kbd->port, keysym);
 }
 
 /*
@@ -457,6 +457,7 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
 
 int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg)
 {
+	struct tty_struct *tty;
 	void __user *argp;
 	unsigned int ct;
 	int perm;
@@ -467,7 +468,10 @@ int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg)
 	 * To have permissions to do most of the vt ioctls, we either have
 	 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
 	 */
-	perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG);
+	tty = tty_port_tty_get(kbd->port);
+	/* FIXME this test is pretty racy */
+	perm = current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG);
+	tty_kref_put(tty);
 	switch (cmd) {
 	case KDGKBTYPE:
 		return put_user(KB_101, (char __user *)argp);
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index 7e736aa..f682f4e 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -21,7 +21,7 @@ typedef void (fn_handler_fn)(struct kbd_data *);
  */
 
 struct kbd_data {
-	struct tty_struct *tty;
+	struct tty_port *port;
 	unsigned short **key_maps;
 	char **func_table;
 	fn_handler_fn **fn_handler;
@@ -42,16 +42,24 @@ int kbd_ioctl(struct kbd_data *, unsigned int, unsigned long);
  * Helper Functions.
  */
 static inline void
-kbd_put_queue(struct tty_struct *tty, int ch)
+kbd_put_queue(struct tty_port *port, int ch)
 {
+	struct tty_struct *tty = tty_port_tty_get(port);
+	if (!tty)
+		return;
 	tty_insert_flip_char(tty, ch, 0);
 	tty_schedule_flip(tty);
+	tty_kref_put(tty);
 }
 
 static inline void
-kbd_puts_queue(struct tty_struct *tty, char *cp)
+kbd_puts_queue(struct tty_port *port, char *cp)
 {
+	struct tty_struct *tty = tty_port_tty_get(port);
+	if (!tty)
+		return;
 	while (*cp)
 		tty_insert_flip_char(tty, *cp++, 0);
 	tty_schedule_flip(tty);
+	tty_kref_put(tty);
 }
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 1f4aff7..10ec690 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -61,7 +61,7 @@ struct tty3270_line {
  */
 struct tty3270 {
 	struct raw3270_view view;
-	struct tty_struct *tty;		/* Pointer to tty structure */
+	struct tty_port port;
 	void **freemem_pages;		/* Array of pages used for freemem. */
 	struct list_head freemem;	/* List of free memory for strings. */
 
@@ -449,10 +449,9 @@ tty3270_rcl_add(struct tty3270 *tp, char *input, int len)
 static void
 tty3270_rcl_backward(struct kbd_data *kbd)
 {
-	struct tty3270 *tp;
+	struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
 	struct string *s;
 
-	tp = kbd->tty->driver_data;
 	spin_lock_bh(&tp->view.lock);
 	if (tp->inattr == TF_INPUT) {
 		if (tp->rcl_walk && tp->rcl_walk->prev != &tp->rcl_lines)
@@ -477,9 +476,8 @@ tty3270_rcl_backward(struct kbd_data *kbd)
 static void
 tty3270_exit_tty(struct kbd_data *kbd)
 {
-	struct tty3270 *tp;
+	struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
 
-	tp = kbd->tty->driver_data;
 	raw3270_deactivate_view(&tp->view);
 }
 
@@ -489,10 +487,9 @@ tty3270_exit_tty(struct kbd_data *kbd)
 static void
 tty3270_scroll_forward(struct kbd_data *kbd)
 {
-	struct tty3270 *tp;
+	struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
 	int nr_up;
 
-	tp = kbd->tty->driver_data;
 	spin_lock_bh(&tp->view.lock);
 	nr_up = tp->nr_up - tp->view.rows + 2;
 	if (nr_up < 0)
@@ -512,10 +509,9 @@ tty3270_scroll_forward(struct kbd_data *kbd)
 static void
 tty3270_scroll_backward(struct kbd_data *kbd)
 {
-	struct tty3270 *tp;
+	struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
 	int nr_up;
 
-	tp = kbd->tty->driver_data;
 	spin_lock_bh(&tp->view.lock);
 	nr_up = tp->nr_up + tp->view.rows - 2;
 	if (nr_up + tp->view.rows - 2 > tp->nr_lines)
@@ -575,13 +571,10 @@ tty3270_read_tasklet(struct raw3270_request *rrq)
 	raw3270_request_add_data(tp->kreset, &kreset_data, 1);
 	raw3270_start(&tp->view, tp->kreset);
 
-	/* Emit input string. */
-	if (tp->tty) {
-		while (len-- > 0)
-			kbd_keycode(tp->kbd, *input++);
-		/* Emit keycode for AID byte. */
-		kbd_keycode(tp->kbd, 256 + tp->input->string[0]);
-	}
+	while (len-- > 0)
+		kbd_keycode(tp->kbd, *input++);
+	/* Emit keycode for AID byte. */
+	kbd_keycode(tp->kbd, 256 + tp->input->string[0]);
 
 	raw3270_request_reset(rrq);
 	xchg(&tp->read, rrq);
@@ -691,6 +684,7 @@ tty3270_alloc_view(void)
 	INIT_LIST_HEAD(&tp->update);
 	INIT_LIST_HEAD(&tp->rcl_lines);
 	tp->rcl_max = 20;
+	tty_port_init(&tp->port);
 	setup_timer(&tp->timer, (void (*)(unsigned long)) tty3270_update,
 		    (unsigned long) tp);
 	tasklet_init(&tp->readlet,
@@ -802,14 +796,14 @@ static void
 tty3270_release(struct raw3270_view *view)
 {
 	struct tty3270 *tp = container_of(view, struct tty3270, view);
-	struct tty_struct *tty;
+	struct tty_struct *tty = tty_port_tty_get(&tp->port);
 
-	tty = tp->tty;
 	if (tty) {
 		tty->driver_data = NULL;
-		tp->tty = tp->kbd->tty = NULL;
+		tty_port_tty_set(&tp->port, NULL);
 		tty_hangup(tty);
 		raw3270_put_view(&tp->view);
+		tty_kref_put(tty);
 	}
 }
 
@@ -869,8 +863,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
 		tty->winsize.ws_row = tp->view.rows - 2;
 		tty->winsize.ws_col = tp->view.cols;
 		tty->low_latency = 0;
-		tp->tty = tty;
-		tp->kbd->tty = tty;
+		/* why to reassign? */
+		tty_port_tty_set(&tp->port, tty);
 		tp->inattr = TF_INPUT;
 		return 0;
 	}
@@ -900,7 +894,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
 		return rc;
 	}
 
-	tp->tty = tty;
+	tty_port_tty_set(&tp->port, tty);
 	tty->low_latency = 0;
 	tty->driver_data = tp;
 	tty->winsize.ws_row = tp->view.rows - 2;
@@ -914,7 +908,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
 	for (i = 0; i < tp->view.rows - 2; i++)
 		tty3270_blank_line(tp);
 
-	tp->kbd->tty = tty;
+	tp->kbd->port = &tp->port;
 	tp->kbd->fn_handler[KVAL(K_INCRCONSOLE)] = tty3270_exit_tty;
 	tp->kbd->fn_handler[KVAL(K_SCROLLBACK)] = tty3270_scroll_backward;
 	tp->kbd->fn_handler[KVAL(K_SCROLLFORW)] = tty3270_scroll_forward;
@@ -938,7 +932,7 @@ tty3270_close(struct tty_struct *tty, struct file * filp)
 		return;
 	if (tp) {
 		tty->driver_data = NULL;
-		tp->tty = tp->kbd->tty = NULL;
+		tty_port_tty_set(&tp->port, NULL);
 		raw3270_put_view(&tp->view);
 	}
 }
@@ -1387,7 +1381,7 @@ tty3270_escape_sequence(struct tty3270 *tp, char ch)
 			tty3270_lf(tp);
 			break;
 		case 'Z':		/* Respond ID. */
-			kbd_puts_queue(tp->tty, "\033[?6c");
+			kbd_puts_queue(&tp->port, "\033[?6c");
 			break;
 		case '7':		/* Save cursor position. */
 			tp->saved_cx = tp->cx;
@@ -1433,11 +1427,11 @@ tty3270_escape_sequence(struct tty3270 *tp, char ch)
 	tp->esc_state = ESnormal;
 	if (ch == 'n' && !tp->esc_ques) {
 		if (tp->esc_par[0] == 5)		/* Status report. */
-			kbd_puts_queue(tp->tty, "\033[0n");
+			kbd_puts_queue(&tp->port, "\033[0n");
 		else if (tp->esc_par[0] == 6) {	/* Cursor report. */
 			char buf[40];
 			sprintf(buf, "\033[%d;%dR", tp->cy + 1, tp->cx + 1);
-			kbd_puts_queue(tp->tty, buf);
+			kbd_puts_queue(&tp->port, buf);
 		}
 		return;
 	}
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 35/69] TTY: bfin_jtag_comm, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (33 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 34/69] TTY: tty3270, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 36/69] TTY: bfin_jtag_comm, use tty from tty_port Jiri Slaby
                   ` (33 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Mike Frysinger, uclinux-dist-devel

And use open count from there. Switch to tty from there will follow.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: uclinux-dist-devel@blackfin.uclinux.org
---
 drivers/tty/bfin_jtag_comm.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c
index 946f799..d81013c 100644
--- a/drivers/tty/bfin_jtag_comm.c
+++ b/drivers/tty/bfin_jtag_comm.c
@@ -63,8 +63,8 @@ static inline uint32_t bfin_write_emudat_chars(char a, char b, char c, char d)
 static struct tty_driver *bfin_jc_driver;
 static struct task_struct *bfin_jc_kthread;
 static struct tty_struct * volatile bfin_jc_tty;
-static unsigned long bfin_jc_count;
 static DEFINE_MUTEX(bfin_jc_tty_mutex);
+static struct tty_port port;
 static volatile struct circ_buf bfin_jc_write_buf;
 
 static int
@@ -150,8 +150,7 @@ static int
 bfin_jc_open(struct tty_struct *tty, struct file *filp)
 {
 	mutex_lock(&bfin_jc_tty_mutex);
-	pr_debug("open %lu\n", bfin_jc_count);
-	++bfin_jc_count;
+	port.count++;
 	bfin_jc_tty = tty;
 	wake_up_process(bfin_jc_kthread);
 	mutex_unlock(&bfin_jc_tty_mutex);
@@ -162,8 +161,7 @@ static void
 bfin_jc_close(struct tty_struct *tty, struct file *filp)
 {
 	mutex_lock(&bfin_jc_tty_mutex);
-	pr_debug("close %lu\n", bfin_jc_count);
-	if (--bfin_jc_count == 0)
+	if (--port.count == 0)
 		bfin_jc_tty = NULL;
 	wake_up_process(bfin_jc_kthread);
 	mutex_unlock(&bfin_jc_tty_mutex);
@@ -242,6 +240,8 @@ static int __init bfin_jc_init(void)
 {
 	int ret;
 
+	tty_port_init(&port);
+
 	bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME);
 	if (IS_ERR(bfin_jc_kthread))
 		return PTR_ERR(bfin_jc_kthread);
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 36/69] TTY: bfin_jtag_comm, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (34 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 35/69] TTY: bfin_jtag_comm, " Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 37/69] TTY: HVC, add tty_port Jiri Slaby
                   ` (32 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Mike Frysinger, uclinux-dist-devel

Switch from mutex to tty_port->lock and to tty refcounting. This needs
a 'continue' to be added to re-grab a tty after schedule returns.

And since tty is not protected by bfin_jc_tty_mutex remove it as well.
But this needs tty_port->count to be protected by tty_port->lock now.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: uclinux-dist-devel@blackfin.uclinux.org
---
 drivers/tty/bfin_jtag_comm.c |   36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c
index d81013c..61fc74f 100644
--- a/drivers/tty/bfin_jtag_comm.c
+++ b/drivers/tty/bfin_jtag_comm.c
@@ -62,8 +62,6 @@ static inline uint32_t bfin_write_emudat_chars(char a, char b, char c, char d)
 
 static struct tty_driver *bfin_jc_driver;
 static struct task_struct *bfin_jc_kthread;
-static struct tty_struct * volatile bfin_jc_tty;
-static DEFINE_MUTEX(bfin_jc_tty_mutex);
 static struct tty_port port;
 static volatile struct circ_buf bfin_jc_write_buf;
 
@@ -73,18 +71,21 @@ bfin_jc_emudat_manager(void *arg)
 	uint32_t inbound_len = 0, outbound_len = 0;
 
 	while (!kthread_should_stop()) {
+		struct tty_struct *tty = tty_port_tty_get(&port);
 		/* no one left to give data to, so sleep */
-		if (bfin_jc_tty == NULL && circ_empty(&bfin_jc_write_buf)) {
+		if (tty == NULL && circ_empty(&bfin_jc_write_buf)) {
 			pr_debug("waiting for readers\n");
 			__set_current_state(TASK_UNINTERRUPTIBLE);
 			schedule();
 			__set_current_state(TASK_RUNNING);
+			continue;
 		}
 
 		/* no data available, so just chill */
 		if (!(bfin_read_DBGSTAT() & EMUDIF) && circ_empty(&bfin_jc_write_buf)) {
 			pr_debug("waiting for data (in_len = %i) (circ: %i %i)\n",
 				inbound_len, bfin_jc_write_buf.tail, bfin_jc_write_buf.head);
+			tty_kref_put(tty);
 			if (inbound_len)
 				schedule();
 			else
@@ -94,9 +95,6 @@ bfin_jc_emudat_manager(void *arg)
 
 		/* if incoming data is ready, eat it */
 		if (bfin_read_DBGSTAT() & EMUDIF) {
-			struct tty_struct *tty;
-			mutex_lock(&bfin_jc_tty_mutex);
-			tty = (struct tty_struct *)bfin_jc_tty;
 			if (tty != NULL) {
 				uint32_t emudat = bfin_read_emudat();
 				if (inbound_len == 0) {
@@ -110,7 +108,6 @@ bfin_jc_emudat_manager(void *arg)
 					tty_flip_buffer_push(tty);
 				}
 			}
-			mutex_unlock(&bfin_jc_tty_mutex);
 		}
 
 		/* if outgoing data is ready, post it */
@@ -120,7 +117,6 @@ bfin_jc_emudat_manager(void *arg)
 				bfin_write_emudat(outbound_len);
 				pr_debug("outgoing length: 0x%08x\n", outbound_len);
 			} else {
-				struct tty_struct *tty;
 				int tail = bfin_jc_write_buf.tail;
 				size_t ate = (4 <= outbound_len ? 4 : outbound_len);
 				uint32_t emudat =
@@ -132,14 +128,12 @@ bfin_jc_emudat_manager(void *arg)
 				);
 				bfin_jc_write_buf.tail += ate;
 				outbound_len -= ate;
-				mutex_lock(&bfin_jc_tty_mutex);
-				tty = (struct tty_struct *)bfin_jc_tty;
 				if (tty)
 					tty_wakeup(tty);
-				mutex_unlock(&bfin_jc_tty_mutex);
 				pr_debug("  outgoing data: 0x%08x (pushing %zu)\n", emudat, ate);
 			}
 		}
+		tty_kref_put(tty);
 	}
 
 	__set_current_state(TASK_RUNNING);
@@ -149,22 +143,28 @@ bfin_jc_emudat_manager(void *arg)
 static int
 bfin_jc_open(struct tty_struct *tty, struct file *filp)
 {
-	mutex_lock(&bfin_jc_tty_mutex);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port.lock, flags);
 	port.count++;
-	bfin_jc_tty = tty;
+	spin_unlock_irqrestore(&port.lock, flags);
+	tty_port_tty_set(&port, tty);
 	wake_up_process(bfin_jc_kthread);
-	mutex_unlock(&bfin_jc_tty_mutex);
 	return 0;
 }
 
 static void
 bfin_jc_close(struct tty_struct *tty, struct file *filp)
 {
-	mutex_lock(&bfin_jc_tty_mutex);
-	if (--port.count == 0)
-		bfin_jc_tty = NULL;
+	unsigned long flags;
+	bool last;
+
+	spin_lock_irqsave(&port.lock, flags);
+	last = --port.count == 0;
+	spin_unlock_irqrestore(&port.lock, flags);
+	if (last)
+		tty_port_tty_set(&port, NULL);
 	wake_up_process(bfin_jc_kthread);
-	mutex_unlock(&bfin_jc_tty_mutex);
 }
 
 /* XXX: we dont handle the put_char() case where we must handle count = 1 */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 37/69] TTY: HVC, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (35 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 36/69] TTY: bfin_jtag_comm, use tty from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 38/69] TTY: HVC, use tty from tty_port Jiri Slaby
                   ` (31 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

And use kref from that. This means we need tty_port->ops->destruct to
properly free the structure. This is what destroy_hvc_struct used to
do so we leverage that.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvc_console.c |   23 ++++++++++++++---------
 drivers/tty/hvc/hvc_console.h |    2 +-
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 8880adf..12a4273 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -107,7 +107,7 @@ static struct hvc_struct *hvc_get_by_index(int index)
 	list_for_each_entry(hp, &hvc_structs, next) {
 		spin_lock_irqsave(&hp->lock, flags);
 		if (hp->index == index) {
-			kref_get(&hp->kref);
+			tty_port_get(&hp->port);
 			spin_unlock_irqrestore(&hp->lock, flags);
 			spin_unlock(&hvc_structs_lock);
 			return hp;
@@ -229,9 +229,9 @@ static int __init hvc_console_init(void)
 console_initcall(hvc_console_init);
 
 /* callback when the kboject ref count reaches zero. */
-static void destroy_hvc_struct(struct kref *kref)
+static void hvc_port_destruct(struct tty_port *port)
 {
-	struct hvc_struct *hp = container_of(kref, struct hvc_struct, kref);
+	struct hvc_struct *hp = container_of(port, struct hvc_struct, port);
 	unsigned long flags;
 
 	spin_lock(&hvc_structs_lock);
@@ -264,7 +264,7 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
 	/* make sure no no tty has been registered in this index */
 	hp = hvc_get_by_index(index);
 	if (hp) {
-		kref_put(&hp->kref, destroy_hvc_struct);
+		tty_port_put(&hp->port);
 		return -1;
 	}
 
@@ -343,7 +343,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
 		spin_unlock_irqrestore(&hp->lock, flags);
 		tty_kref_put(tty);
 		tty->driver_data = NULL;
-		kref_put(&hp->kref, destroy_hvc_struct);
+		tty_port_put(&hp->port);
 		printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
 	}
 	/* Force wakeup of the polling thread */
@@ -397,7 +397,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
 	}
 
 	tty_kref_put(tty);
-	kref_put(&hp->kref, destroy_hvc_struct);
+	tty_port_put(&hp->port);
 }
 
 static void hvc_hangup(struct tty_struct *tty)
@@ -437,7 +437,7 @@ static void hvc_hangup(struct tty_struct *tty)
 	while(temp_open_count) {
 		--temp_open_count;
 		tty_kref_put(tty);
-		kref_put(&hp->kref, destroy_hvc_struct);
+		tty_port_put(&hp->port);
 	}
 }
 
@@ -817,6 +817,10 @@ static const struct tty_operations hvc_ops = {
 #endif
 };
 
+static const struct tty_port_operations hvc_port_ops = {
+	.destruct = hvc_port_destruct,
+};
+
 struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
 			     const struct hv_ops *ops,
 			     int outbuf_size)
@@ -842,7 +846,8 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
 	hp->outbuf_size = outbuf_size;
 	hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
 
-	kref_init(&hp->kref);
+	tty_port_init(&hp->port);
+	hp->port.ops = &hvc_port_ops;
 
 	INIT_WORK(&hp->tty_resize, hvc_set_winsz);
 	spin_lock_init(&hp->lock);
@@ -891,7 +896,7 @@ int hvc_remove(struct hvc_struct *hp)
 	 * kref cause it to be removed, which will probably be the tty_vhangup
 	 * below.
 	 */
-	kref_put(&hp->kref, destroy_hvc_struct);
+	tty_port_put(&hp->port);
 
 	/*
 	 * This function call will auto chain call hvc_hangup.
diff --git a/drivers/tty/hvc/hvc_console.h b/drivers/tty/hvc/hvc_console.h
index c335a14..926d9e4 100644
--- a/drivers/tty/hvc/hvc_console.h
+++ b/drivers/tty/hvc/hvc_console.h
@@ -46,6 +46,7 @@
 #define HVC_ALLOC_TTY_ADAPTERS	8
 
 struct hvc_struct {
+	struct tty_port port;
 	spinlock_t lock;
 	int index;
 	struct tty_struct *tty;
@@ -61,7 +62,6 @@ struct hvc_struct {
 	struct winsize ws;
 	struct work_struct tty_resize;
 	struct list_head next;
-	struct kref kref; /* ref count & hvc_struct lifetime */
 };
 
 /* implemented by a low level driver */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 38/69] TTY: HVC, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (36 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 37/69] TTY: HVC, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 39/69] TTY: HVC, use count " Jiri Slaby
                   ` (30 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

The driver already used refcounting. So we just switch it to tty_port
helpers. And switch to tty_port->lock for tty.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvc_console.c |   36 +++++++++++++++---------------------
 drivers/tty/hvc/hvc_console.h |    1 -
 drivers/tty/hvc/hvsi_lib.c    |    2 +-
 3 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 12a4273..92b7f5d 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -323,11 +323,10 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
 	} /* else count == 0 */
 
 	tty->driver_data = hp;
-
-	hp->tty = tty_kref_get(tty);
-
 	spin_unlock_irqrestore(&hp->lock, flags);
 
+	tty_port_tty_set(&hp->port, tty);
+
 	if (hp->ops->notifier_add)
 		rc = hp->ops->notifier_add(hp, hp->data);
 
@@ -338,9 +337,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
 	 * tty fields and return the kref reference.
 	 */
 	if (rc) {
-		spin_lock_irqsave(&hp->lock, flags);
-		hp->tty = NULL;
-		spin_unlock_irqrestore(&hp->lock, flags);
+		tty_port_tty_set(&hp->port, NULL);
 		tty_kref_put(tty);
 		tty->driver_data = NULL;
 		tty_port_put(&hp->port);
@@ -373,9 +370,9 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
 	spin_lock_irqsave(&hp->lock, flags);
 
 	if (--hp->count == 0) {
-		/* We are done with the tty pointer now. */
-		hp->tty = NULL;
 		spin_unlock_irqrestore(&hp->lock, flags);
+		/* We are done with the tty pointer now. */
+		tty_port_tty_set(&hp->port, NULL);
 
 		if (hp->ops->notifier_del)
 			hp->ops->notifier_del(hp, hp->data);
@@ -427,9 +424,8 @@ static void hvc_hangup(struct tty_struct *tty)
 	temp_open_count = hp->count;
 	hp->count = 0;
 	hp->n_outbuf = 0;
-	hp->tty = NULL;
-
 	spin_unlock_irqrestore(&hp->lock, flags);
+	tty_port_tty_set(&hp->port, NULL);
 
 	if (hp->ops->notifier_hangup)
 		hp->ops->notifier_hangup(hp, hp->data);
@@ -526,13 +522,12 @@ static void hvc_set_winsz(struct work_struct *work)
 
 	hp = container_of(work, struct hvc_struct, tty_resize);
 
-	spin_lock_irqsave(&hp->lock, hvc_flags);
-	if (!hp->tty) {
-		spin_unlock_irqrestore(&hp->lock, hvc_flags);
+	tty = tty_port_tty_get(&hp->port);
+	if (!tty)
 		return;
-	}
-	ws  = hp->ws;
-	tty = tty_kref_get(hp->tty);
+
+	spin_lock_irqsave(&hp->lock, hvc_flags);
+	ws = hp->ws;
 	spin_unlock_irqrestore(&hp->lock, hvc_flags);
 
 	tty_do_resize(tty, &ws);
@@ -601,7 +596,7 @@ int hvc_poll(struct hvc_struct *hp)
 	}
 
 	/* No tty attached, just skip */
-	tty = tty_kref_get(hp->tty);
+	tty = tty_port_tty_get(&hp->port);
 	if (tty == NULL)
 		goto bail;
 
@@ -681,8 +676,7 @@ int hvc_poll(struct hvc_struct *hp)
 
 		tty_flip_buffer_push(tty);
 	}
-	if (tty)
-		tty_kref_put(tty);
+	tty_kref_put(tty);
 
 	return poll_mask;
 }
@@ -880,9 +874,9 @@ int hvc_remove(struct hvc_struct *hp)
 	unsigned long flags;
 	struct tty_struct *tty;
 
-	spin_lock_irqsave(&hp->lock, flags);
-	tty = tty_kref_get(hp->tty);
+	tty = tty_port_tty_get(&hp->port);
 
+	spin_lock_irqsave(&hp->lock, flags);
 	if (hp->index < MAX_NR_HVC_CONSOLES)
 		vtermnos[hp->index] = -1;
 
diff --git a/drivers/tty/hvc/hvc_console.h b/drivers/tty/hvc/hvc_console.h
index 926d9e4..594a28f 100644
--- a/drivers/tty/hvc/hvc_console.h
+++ b/drivers/tty/hvc/hvc_console.h
@@ -49,7 +49,6 @@ struct hvc_struct {
 	struct tty_port port;
 	spinlock_t lock;
 	int index;
-	struct tty_struct *tty;
 	int count;
 	int do_wakeup;
 	char *outbuf;
diff --git a/drivers/tty/hvc/hvsi_lib.c b/drivers/tty/hvc/hvsi_lib.c
index 6f4dd83..59c135d 100644
--- a/drivers/tty/hvc/hvsi_lib.c
+++ b/drivers/tty/hvc/hvsi_lib.c
@@ -377,7 +377,7 @@ int hvsilib_open(struct hvsi_priv *pv, struct hvc_struct *hp)
 	pr_devel("HVSI@%x: open !\n", pv->termno);
 
 	/* Keep track of the tty data structure */
-	pv->tty = tty_kref_get(hp->tty);
+	pv->tty = tty_port_tty_get(&hp->port);
 
 	hvsilib_establish(pv);
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 39/69] TTY: HVC, use count from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (37 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 38/69] TTY: HVC, use tty from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 40/69] TTY: hvcs, add tty_port Jiri Slaby
                   ` (29 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

Now, count is used from tty_port and protected by tty_port->lock.

n_outbuf is left unprotected in hvc_hangup now, because there is no
point to hold any lock, since other uses are unprotected too.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvc_console.c |   40 +++++++++++++++++++++-------------------
 drivers/tty/hvc/hvc_console.h |    1 -
 2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 92b7f5d..6c45cbf 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -313,18 +313,18 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
 	if (!(hp = hvc_get_by_index(tty->index)))
 		return -ENODEV;
 
-	spin_lock_irqsave(&hp->lock, flags);
+	spin_lock_irqsave(&hp->port.lock, flags);
 	/* Check and then increment for fast path open. */
-	if (hp->count++ > 0) {
+	if (hp->port.count++ > 0) {
+		spin_unlock_irqrestore(&hp->port.lock, flags);
+		/* FIXME why taking a reference here? */
 		tty_kref_get(tty);
-		spin_unlock_irqrestore(&hp->lock, flags);
 		hvc_kick();
 		return 0;
 	} /* else count == 0 */
+	spin_unlock_irqrestore(&hp->port.lock, flags);
 
 	tty->driver_data = hp;
-	spin_unlock_irqrestore(&hp->lock, flags);
-
 	tty_port_tty_set(&hp->port, tty);
 
 	if (hp->ops->notifier_add)
@@ -367,10 +367,10 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
 
 	hp = tty->driver_data;
 
-	spin_lock_irqsave(&hp->lock, flags);
+	spin_lock_irqsave(&hp->port.lock, flags);
 
-	if (--hp->count == 0) {
-		spin_unlock_irqrestore(&hp->lock, flags);
+	if (--hp->port.count == 0) {
+		spin_unlock_irqrestore(&hp->port.lock, flags);
 		/* We are done with the tty pointer now. */
 		tty_port_tty_set(&hp->port, NULL);
 
@@ -387,10 +387,10 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
 		 */
 		tty_wait_until_sent_from_close(tty, HVC_CLOSE_WAIT);
 	} else {
-		if (hp->count < 0)
+		if (hp->port.count < 0)
 			printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
-				hp->vtermno, hp->count);
-		spin_unlock_irqrestore(&hp->lock, flags);
+				hp->vtermno, hp->port.count);
+		spin_unlock_irqrestore(&hp->port.lock, flags);
 	}
 
 	tty_kref_put(tty);
@@ -409,24 +409,25 @@ static void hvc_hangup(struct tty_struct *tty)
 	/* cancel pending tty resize work */
 	cancel_work_sync(&hp->tty_resize);
 
-	spin_lock_irqsave(&hp->lock, flags);
+	spin_lock_irqsave(&hp->port.lock, flags);
 
 	/*
 	 * The N_TTY line discipline has problems such that in a close vs
 	 * open->hangup case this can be called after the final close so prevent
 	 * that from happening for now.
 	 */
-	if (hp->count <= 0) {
-		spin_unlock_irqrestore(&hp->lock, flags);
+	if (hp->port.count <= 0) {
+		spin_unlock_irqrestore(&hp->port.lock, flags);
 		return;
 	}
 
-	temp_open_count = hp->count;
-	hp->count = 0;
-	hp->n_outbuf = 0;
-	spin_unlock_irqrestore(&hp->lock, flags);
+	temp_open_count = hp->port.count;
+	hp->port.count = 0;
+	spin_unlock_irqrestore(&hp->port.lock, flags);
 	tty_port_tty_set(&hp->port, NULL);
 
+	hp->n_outbuf = 0;
+
 	if (hp->ops->notifier_hangup)
 		hp->ops->notifier_hangup(hp, hp->data);
 
@@ -474,7 +475,8 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
 	if (!hp)
 		return -EPIPE;
 
-	if (hp->count <= 0)
+	/* FIXME what's this (unprotected) check for? */
+	if (hp->port.count <= 0)
 		return -EIO;
 
 	spin_lock_irqsave(&hp->lock, flags);
diff --git a/drivers/tty/hvc/hvc_console.h b/drivers/tty/hvc/hvc_console.h
index 594a28f..674d23c 100644
--- a/drivers/tty/hvc/hvc_console.h
+++ b/drivers/tty/hvc/hvc_console.h
@@ -49,7 +49,6 @@ struct hvc_struct {
 	struct tty_port port;
 	spinlock_t lock;
 	int index;
-	int count;
 	int do_wakeup;
 	char *outbuf;
 	int outbuf_size;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 40/69] TTY: hvcs, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (38 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 39/69] TTY: HVC, use count " Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 41/69] TTY: hvcs, use kref from tty_port Jiri Slaby
                   ` (28 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

And use count from there.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvcs.c |   24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index 3436436..a049ced 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -261,6 +261,7 @@ static DEFINE_SPINLOCK(hvcs_pi_lock);
 
 /* One vty-server per hvcs_struct */
 struct hvcs_struct {
+	struct tty_port port;
 	spinlock_t lock;
 
 	/*
@@ -270,7 +271,6 @@ struct hvcs_struct {
 	unsigned int index;
 
 	struct tty_struct *tty;
-	int open_count;
 
 	/*
 	 * Used to tell the driver kernel_thread what operations need to take
@@ -422,7 +422,7 @@ static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribut
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
 
-	if (hvcsd->open_count > 0) {
+	if (hvcsd->port.count > 0) {
 		spin_unlock_irqrestore(&hvcsd->lock, flags);
 		printk(KERN_INFO "HVCS: vterm state unchanged.  "
 				"The hvcs device node is still in use.\n");
@@ -789,7 +789,7 @@ static int __devinit hvcs_probe(
 	if (!hvcsd)
 		return -ENODEV;
 
-
+	tty_port_init(&hvcsd->port);
 	spin_lock_init(&hvcsd->lock);
 	/* Automatically incs the refcount the first time */
 	kref_init(&hvcsd->kref);
@@ -1138,7 +1138,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
 		if ((retval = hvcs_partner_connect(hvcsd)))
 			goto error_release;
 
-	hvcsd->open_count = 1;
+	hvcsd->port.count = 1;
 	hvcsd->tty = tty;
 	tty->driver_data = hvcsd;
 
@@ -1172,7 +1172,7 @@ fast_open:
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
 	kref_get(&hvcsd->kref);
-	hvcsd->open_count++;
+	hvcsd->port.count++;
 	hvcsd->todo_mask |= HVCS_SCHED_READ;
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
 
@@ -1216,7 +1216,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 	hvcsd = tty->driver_data;
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
-	if (--hvcsd->open_count == 0) {
+	if (--hvcsd->port.count == 0) {
 
 		vio_disable_interrupts(hvcsd->vdev);
 
@@ -1242,10 +1242,10 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 		free_irq(irq, hvcsd);
 		kref_put(&hvcsd->kref, destroy_hvcs_struct);
 		return;
-	} else if (hvcsd->open_count < 0) {
+	} else if (hvcsd->port.count < 0) {
 		printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
 				" is missmanaged.\n",
-		hvcsd->vdev->unit_address, hvcsd->open_count);
+		hvcsd->vdev->unit_address, hvcsd->port.count);
 	}
 
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
@@ -1261,7 +1261,7 @@ static void hvcs_hangup(struct tty_struct * tty)
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
 	/* Preserve this so that we know how many kref refs to put */
-	temp_open_count = hvcsd->open_count;
+	temp_open_count = hvcsd->port.count;
 
 	/*
 	 * Don't kref put inside the spinlock because the destruction
@@ -1276,7 +1276,7 @@ static void hvcs_hangup(struct tty_struct * tty)
 	hvcsd->tty->driver_data = NULL;
 	hvcsd->tty = NULL;
 
-	hvcsd->open_count = 0;
+	hvcsd->port.count = 0;
 
 	/* This will drop any buffered data on the floor which is OK in a hangup
 	 * scenario. */
@@ -1347,7 +1347,7 @@ static int hvcs_write(struct tty_struct *tty,
 	 * the middle of a write operation?  This is a crummy place to do this
 	 * but we want to keep it all in the spinlock.
 	 */
-	if (hvcsd->open_count <= 0) {
+	if (hvcsd->port.count <= 0) {
 		spin_unlock_irqrestore(&hvcsd->lock, flags);
 		return -ENODEV;
 	}
@@ -1421,7 +1421,7 @@ static int hvcs_write_room(struct tty_struct *tty)
 {
 	struct hvcs_struct *hvcsd = tty->driver_data;
 
-	if (!hvcsd || hvcsd->open_count <= 0)
+	if (!hvcsd || hvcsd->port.count <= 0)
 		return 0;
 
 	return HVCS_BUFF_LEN - hvcsd->chars_in_buffer;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 41/69] TTY: hvcs, use kref from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (39 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 40/69] TTY: hvcs, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 42/69] TTY: hvcs, use tty " Jiri Slaby
                   ` (27 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

A simple switch. Except we convert destroy_hvcs_struct to be
tty_port_operations->destruct...

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvcs.c |   34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index a049ced..817f94b 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -290,12 +290,11 @@ struct hvcs_struct {
 	int chars_in_buffer;
 
 	/*
-	 * Any variable below the kref is valid before a tty is connected and
+	 * Any variable below is valid before a tty is connected and
 	 * stays valid after the tty is disconnected.  These shouldn't be
 	 * whacked until the kobject refcount reaches zero though some entries
 	 * may be changed via sysfs initiatives.
 	 */
-	struct kref kref; /* ref count & hvcs_struct lifetime */
 	int connected; /* is the vty-server currently connected to a vty? */
 	uint32_t p_unit_address; /* partner unit address */
 	uint32_t p_partition_ID; /* partner partition ID */
@@ -304,9 +303,6 @@ struct hvcs_struct {
 	struct vio_dev *vdev;
 };
 
-/* Required to back map a kref to its containing object */
-#define from_kref(k) container_of(k, struct hvcs_struct, kref)
-
 static LIST_HEAD(hvcs_structs);
 static DEFINE_SPINLOCK(hvcs_structs_lock);
 static DEFINE_MUTEX(hvcs_init_mutex);
@@ -701,10 +697,9 @@ static void hvcs_return_index(int index)
 		hvcs_index_list[index] = -1;
 }
 
-/* callback when the kref ref count reaches zero */
-static void destroy_hvcs_struct(struct kref *kref)
+static void hvcs_destruct_port(struct tty_port *p)
 {
-	struct hvcs_struct *hvcsd = from_kref(kref);
+	struct hvcs_struct *hvcsd = container_of(p, struct hvcs_struct, port);
 	struct vio_dev *vdev;
 	unsigned long flags;
 
@@ -741,6 +736,10 @@ static void destroy_hvcs_struct(struct kref *kref)
 	kfree(hvcsd);
 }
 
+static const struct tty_port_operations hvcs_port_ops = {
+	.destruct = hvcs_destruct_port,
+};
+
 static int hvcs_get_index(void)
 {
 	int i;
@@ -790,9 +789,8 @@ static int __devinit hvcs_probe(
 		return -ENODEV;
 
 	tty_port_init(&hvcsd->port);
+	hvcsd->port.ops = &hvcs_port_ops;
 	spin_lock_init(&hvcsd->lock);
-	/* Automatically incs the refcount the first time */
-	kref_init(&hvcsd->kref);
 
 	hvcsd->vdev = dev;
 	dev_set_drvdata(&dev->dev, hvcsd);
@@ -860,7 +858,7 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
 	 * Let the last holder of this object cause it to be removed, which
 	 * would probably be tty_hangup below.
 	 */
-	kref_put(&hvcsd->kref, destroy_hvcs_struct);
+	tty_port_put(&hvcsd->port);
 
 	/*
 	 * The hangup is a scheduled function which will auto chain call
@@ -1094,7 +1092,7 @@ static struct hvcs_struct *hvcs_get_by_index(int index)
 	list_for_each_entry(hvcsd, &hvcs_structs, next) {
 		spin_lock_irqsave(&hvcsd->lock, flags);
 		if (hvcsd->index == index) {
-			kref_get(&hvcsd->kref);
+			tty_port_get(&hvcsd->port);
 			spin_unlock_irqrestore(&hvcsd->lock, flags);
 			spin_unlock(&hvcs_structs_lock);
 			return hvcsd;
@@ -1160,7 +1158,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
 	 * and will grab the spinlock and free the connection if it fails.
 	 */
 	if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) {
-		kref_put(&hvcsd->kref, destroy_hvcs_struct);
+		tty_port_put(&hvcsd->port);
 		printk(KERN_WARNING "HVCS: enable device failed.\n");
 		return rc;
 	}
@@ -1171,7 +1169,7 @@ fast_open:
 	hvcsd = tty->driver_data;
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
-	kref_get(&hvcsd->kref);
+	tty_port_get(&hvcsd->port);
 	hvcsd->port.count++;
 	hvcsd->todo_mask |= HVCS_SCHED_READ;
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
@@ -1186,7 +1184,7 @@ open_success:
 
 error_release:
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
-	kref_put(&hvcsd->kref, destroy_hvcs_struct);
+	tty_port_put(&hvcsd->port);
 
 	printk(KERN_WARNING "HVCS: partner connect failed.\n");
 	return retval;
@@ -1240,7 +1238,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 		tty->driver_data = NULL;
 
 		free_irq(irq, hvcsd);
-		kref_put(&hvcsd->kref, destroy_hvcs_struct);
+		tty_port_put(&hvcsd->port);
 		return;
 	} else if (hvcsd->port.count < 0) {
 		printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
@@ -1249,7 +1247,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 	}
 
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
-	kref_put(&hvcsd->kref, destroy_hvcs_struct);
+	tty_port_put(&hvcsd->port);
 }
 
 static void hvcs_hangup(struct tty_struct * tty)
@@ -1301,7 +1299,7 @@ static void hvcs_hangup(struct tty_struct * tty)
 		 * NOTE:  If this hangup was signaled from user space then the
 		 * final put will never happen.
 		 */
-		kref_put(&hvcsd->kref, destroy_hvcs_struct);
+		tty_port_put(&hvcsd->port);
 	}
 }
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 42/69] TTY: hvcs, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (40 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 41/69] TTY: hvcs, use kref from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 43/69] TTY: hvsi, CLOCAL is not in tty->flags Jiri Slaby
                   ` (26 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

No refcounting, just a switch. The locking in the driver prevents
races, so in fact the refcounting is not needed. But while we have a
tty in tty_port, don't duplicate that and remove the one from
hvcs_struct.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvcs.c |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index 817f94b..d56788c 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -270,8 +270,6 @@ struct hvcs_struct {
 	 */
 	unsigned int index;
 
-	struct tty_struct *tty;
-
 	/*
 	 * Used to tell the driver kernel_thread what operations need to take
 	 * place upon this hvcs_struct instance.
@@ -560,7 +558,7 @@ static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance)
 static void hvcs_try_write(struct hvcs_struct *hvcsd)
 {
 	uint32_t unit_address = hvcsd->vdev->unit_address;
-	struct tty_struct *tty = hvcsd->tty;
+	struct tty_struct *tty = hvcsd->port.tty;
 	int sent;
 
 	if (hvcsd->todo_mask & HVCS_TRY_WRITE) {
@@ -598,7 +596,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
 	spin_lock_irqsave(&hvcsd->lock, flags);
 
 	unit_address = hvcsd->vdev->unit_address;
-	tty = hvcsd->tty;
+	tty = hvcsd->port.tty;
 
 	hvcs_try_write(hvcsd);
 
@@ -850,7 +848,7 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
 
-	tty = hvcsd->tty;
+	tty = hvcsd->port.tty;
 
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
 
@@ -1137,7 +1135,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
 			goto error_release;
 
 	hvcsd->port.count = 1;
-	hvcsd->tty = tty;
+	hvcsd->port.tty = tty;
 	tty->driver_data = hvcsd;
 
 	memset(&hvcsd->buffer[0], 0x00, HVCS_BUFF_LEN);
@@ -1223,7 +1221,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 		 * execute any operations on the TTY even though it is obligated
 		 * to deliver any pending I/O to the hypervisor.
 		 */
-		hvcsd->tty = NULL;
+		hvcsd->port.tty = NULL;
 
 		irq = hvcsd->vdev->irq;
 		spin_unlock_irqrestore(&hvcsd->lock, flags);
@@ -1271,8 +1269,8 @@ static void hvcs_hangup(struct tty_struct * tty)
 	hvcsd->todo_mask = 0;
 
 	/* I don't think the tty needs the hvcs_struct pointer after a hangup */
-	hvcsd->tty->driver_data = NULL;
-	hvcsd->tty = NULL;
+	tty->driver_data = NULL;
+	hvcsd->port.tty = NULL;
 
 	hvcsd->port.count = 0;
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 43/69] TTY: hvsi, CLOCAL is not in tty->flags
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (41 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 42/69] TTY: hvcs, use tty " Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 44/69] TTY: hvsi, add tty_port Jiri Slaby
                   ` (25 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

It is in termios cflags. So change the test in hvsi_recv_control to do
the right thing. Previously it was actually testing TTY_LDISC_OPEN
bit, i.e. whether an ldisc is active. And yes, it is most of the time.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvsi.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
index a7488b7..4006aed 100644
--- a/drivers/tty/hvc/hvsi.c
+++ b/drivers/tty/hvc/hvsi.c
@@ -248,7 +248,7 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
 				pr_debug("hvsi%i: CD dropped\n", hp->index);
 				hp->mctrl &= TIOCM_CD;
 				/* If userland hasn't done an open(2) yet, hp->tty is NULL. */
-				if (hp->tty && !(hp->tty->flags & CLOCAL))
+				if (hp->tty && !C_CLOCAL(hp->tty))
 					*to_hangup = hp->tty;
 			}
 			break;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 44/69] TTY: hvsi, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (42 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 43/69] TTY: hvsi, CLOCAL is not in tty->flags Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 45/69] TTY: hvsi, sanitize uses of tty Jiri Slaby
                   ` (24 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

And use count from there.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvsi.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
index 4006aed..113a09a 100644
--- a/drivers/tty/hvc/hvsi.c
+++ b/drivers/tty/hvc/hvsi.c
@@ -69,6 +69,7 @@
 #define __ALIGNED__	__attribute__((__aligned__(sizeof(long))))
 
 struct hvsi_struct {
+	struct tty_port port;
 	struct delayed_work writer;
 	struct work_struct handshaker;
 	wait_queue_head_t emptyq; /* woken when outbuf is emptied */
@@ -76,7 +77,6 @@ struct hvsi_struct {
 	spinlock_t lock;
 	int index;
 	struct tty_struct *tty;
-	int count;
 	uint8_t throttle_buf[128];
 	uint8_t outbuf[N_OUTBUF]; /* to implement write_room and chars_in_buffer */
 	/* inbuf is for packet reassembly. leave a little room for leftovers. */
@@ -751,7 +751,7 @@ static int hvsi_open(struct tty_struct *tty, struct file *filp)
 
 	spin_lock_irqsave(&hp->lock, flags);
 	hp->tty = tty;
-	hp->count++;
+	hp->port.count++;
 	atomic_set(&hp->seqno, 0);
 	h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
 	spin_unlock_irqrestore(&hp->lock, flags);
@@ -808,7 +808,7 @@ static void hvsi_close(struct tty_struct *tty, struct file *filp)
 
 	spin_lock_irqsave(&hp->lock, flags);
 
-	if (--hp->count == 0) {
+	if (--hp->port.count == 0) {
 		hp->tty = NULL;
 		hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */
 
@@ -841,9 +841,9 @@ static void hvsi_close(struct tty_struct *tty, struct file *filp)
 
 			spin_lock_irqsave(&hp->lock, flags);
 		}
-	} else if (hp->count < 0)
+	} else if (hp->port.count < 0)
 		printk(KERN_ERR "hvsi_close %lu: oops, count is %d\n",
-		       hp - hvsi_ports, hp->count);
+		       hp - hvsi_ports, hp->port.count);
 
 	spin_unlock_irqrestore(&hp->lock, flags);
 }
@@ -857,7 +857,7 @@ static void hvsi_hangup(struct tty_struct *tty)
 
 	spin_lock_irqsave(&hp->lock, flags);
 
-	hp->count = 0;
+	hp->port.count = 0;
 	hp->n_outbuf = 0;
 	hp->tty = NULL;
 
@@ -1228,6 +1228,7 @@ static int __init hvsi_console_init(void)
 		init_waitqueue_head(&hp->emptyq);
 		init_waitqueue_head(&hp->stateq);
 		spin_lock_init(&hp->lock);
+		tty_port_init(&hp->port);
 		hp->index = hvsi_count;
 		hp->inbuf_end = hp->inbuf;
 		hp->state = HVSI_CLOSED;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 45/69] TTY: hvsi, sanitize uses of tty
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (43 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 44/69] TTY: hvsi, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 46/69] TTY: hvsi, use tty from tty_port Jiri Slaby
                   ` (23 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

- use tty, not hp->tty wherever possible
- pass tty down to some functions and go to step one
- do not defer tty_hangup calls -- it is as simple as schedule_work,
  so might be called with hp->lock held
- do not defer tty buffer flips -- since the driver does not use
  low_latency (it cannot actually), the flip is a simple tail move
  plus schedule_work. It will make our life easier in the next patch.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvsi.c |   88 +++++++++++++++++-------------------------------
 1 file changed, 30 insertions(+), 58 deletions(-)

diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
index 113a09a..68b729b 100644
--- a/drivers/tty/hvc/hvsi.c
+++ b/drivers/tty/hvc/hvsi.c
@@ -237,7 +237,7 @@ static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
 }
 
 static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
-	struct tty_struct **to_hangup, struct hvsi_struct **to_handshake)
+	struct tty_struct *tty, struct hvsi_struct **to_handshake)
 {
 	struct hvsi_control *header = (struct hvsi_control *)packet;
 
@@ -247,9 +247,8 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
 				/* CD went away; no more connection */
 				pr_debug("hvsi%i: CD dropped\n", hp->index);
 				hp->mctrl &= TIOCM_CD;
-				/* If userland hasn't done an open(2) yet, hp->tty is NULL. */
-				if (hp->tty && !C_CLOCAL(hp->tty))
-					*to_hangup = hp->tty;
+				if (tty && !C_CLOCAL(tty))
+					tty_hangup(tty);
 			}
 			break;
 		case VSV_CLOSE_PROTOCOL:
@@ -331,7 +330,8 @@ static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet)
 	}
 }
 
-static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
+static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty,
+		const char *buf, int len)
 {
 	int i;
 
@@ -347,7 +347,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
 			continue;
 		}
 #endif /* CONFIG_MAGIC_SYSRQ */
-		tty_insert_flip_char(hp->tty, c, 0);
+		tty_insert_flip_char(tty, c, 0);
 	}
 }
 
@@ -360,7 +360,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
  * revisited.
  */
 #define TTY_THRESHOLD_THROTTLE 128
-static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
+static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty,
 		const uint8_t *packet)
 {
 	const struct hvsi_header *header = (const struct hvsi_header *)packet;
@@ -371,14 +371,14 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
 	pr_debug("queueing %i chars '%.*s'\n", datalen, datalen, data);
 
 	if (datalen == 0)
-		return NULL;
+		return false;
 
 	if (overflow > 0) {
 		pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __func__);
 		datalen = TTY_THRESHOLD_THROTTLE;
 	}
 
-	hvsi_insert_chars(hp, data, datalen);
+	hvsi_insert_chars(hp, tty, data, datalen);
 
 	if (overflow > 0) {
 		/*
@@ -390,7 +390,7 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
 		hp->n_throttle = overflow;
 	}
 
-	return hp->tty;
+	return true;
 }
 
 /*
@@ -399,14 +399,13 @@ static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
  * machine during console handshaking (in which case tty = NULL and we ignore
  * incoming data).
  */
-static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
-		struct tty_struct **hangup, struct hvsi_struct **handshake)
+static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty,
+		struct hvsi_struct **handshake)
 {
 	uint8_t *packet = hp->inbuf;
 	int chunklen;
+	bool flip = false;
 
-	*flip = NULL;
-	*hangup = NULL;
 	*handshake = NULL;
 
 	chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ);
@@ -440,12 +439,12 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
 			case VS_DATA_PACKET_HEADER:
 				if (!is_open(hp))
 					break;
-				if (hp->tty == NULL)
+				if (tty == NULL)
 					break; /* no tty buffer to put data in */
-				*flip = hvsi_recv_data(hp, packet);
+				flip = hvsi_recv_data(hp, tty, packet);
 				break;
 			case VS_CONTROL_PACKET_HEADER:
-				hvsi_recv_control(hp, packet, hangup, handshake);
+				hvsi_recv_control(hp, packet, tty, handshake);
 				break;
 			case VS_QUERY_RESPONSE_PACKET_HEADER:
 				hvsi_recv_response(hp, packet);
@@ -462,28 +461,26 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
 
 		packet += len_packet(packet);
 
-		if (*hangup || *handshake) {
-			pr_debug("%s: hangup or handshake\n", __func__);
-			/*
-			 * we need to send the hangup now before receiving any more data.
-			 * If we get "data, hangup, data", we can't deliver the second
-			 * data before the hangup.
-			 */
+		if (*handshake) {
+			pr_debug("%s: handshake\n", __func__);
 			break;
 		}
 	}
 
 	compact_inbuf(hp, packet);
 
+	if (flip)
+		tty_flip_buffer_push(tty);
+
 	return 1;
 }
 
-static void hvsi_send_overflow(struct hvsi_struct *hp)
+static void hvsi_send_overflow(struct hvsi_struct *hp, struct tty_struct *tty)
 {
 	pr_debug("%s: delivering %i bytes overflow\n", __func__,
 			hp->n_throttle);
 
-	hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle);
+	hvsi_insert_chars(hp, tty, hp->throttle_buf, hp->n_throttle);
 	hp->n_throttle = 0;
 }
 
@@ -494,8 +491,6 @@ static void hvsi_send_overflow(struct hvsi_struct *hp)
 static irqreturn_t hvsi_interrupt(int irq, void *arg)
 {
 	struct hvsi_struct *hp = (struct hvsi_struct *)arg;
-	struct tty_struct *flip;
-	struct tty_struct *hangup;
 	struct hvsi_struct *handshake;
 	unsigned long flags;
 	int again = 1;
@@ -504,25 +499,9 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
 
 	while (again) {
 		spin_lock_irqsave(&hp->lock, flags);
-		again = hvsi_load_chunk(hp, &flip, &hangup, &handshake);
+		again = hvsi_load_chunk(hp, hp->tty, &handshake);
 		spin_unlock_irqrestore(&hp->lock, flags);
 
-		/*
-		 * we have to call tty_flip_buffer_push() and tty_hangup() outside our
-		 * spinlock. But we also have to keep going until we've read all the
-		 * available data.
-		 */
-
-		if (flip) {
-			/* there was data put in the tty flip buffer */
-			tty_flip_buffer_push(flip);
-			flip = NULL;
-		}
-
-		if (hangup) {
-			tty_hangup(hangup);
-		}
-
 		if (handshake) {
 			pr_debug("hvsi%i: attempting re-handshake\n", handshake->index);
 			schedule_work(&handshake->handshaker);
@@ -534,15 +513,11 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
 			&& (!test_bit(TTY_THROTTLED, &hp->tty->flags))) {
 		/* we weren't hung up and we weren't throttled, so we can deliver the
 		 * rest now */
-		flip = hp->tty;
-		hvsi_send_overflow(hp);
+		hvsi_send_overflow(hp, hp->tty);
+		tty_flip_buffer_push(hp->tty);
 	}
 	spin_unlock_irqrestore(&hp->lock, flags);
 
-	if (flip) {
-		tty_flip_buffer_push(flip);
-	}
-
 	return IRQ_HANDLED;
 }
 
@@ -966,8 +941,8 @@ static int hvsi_write(struct tty_struct *tty,
 	 * and hvsi_write_worker will be scheduled. subsequent hvsi_write() calls
 	 * will see there is no room in outbuf and return.
 	 */
-	while ((count > 0) && (hvsi_write_room(hp->tty) > 0)) {
-		int chunksize = min(count, hvsi_write_room(hp->tty));
+	while ((count > 0) && (hvsi_write_room(tty) > 0)) {
+		int chunksize = min(count, hvsi_write_room(tty));
 
 		BUG_ON(hp->n_outbuf < 0);
 		memcpy(hp->outbuf + hp->n_outbuf, source, chunksize);
@@ -1014,19 +989,16 @@ static void hvsi_unthrottle(struct tty_struct *tty)
 {
 	struct hvsi_struct *hp = tty->driver_data;
 	unsigned long flags;
-	int shouldflip = 0;
 
 	pr_debug("%s\n", __func__);
 
 	spin_lock_irqsave(&hp->lock, flags);
 	if (hp->n_throttle) {
-		hvsi_send_overflow(hp);
-		shouldflip = 1;
+		hvsi_send_overflow(hp, tty);
+		tty_flip_buffer_push(tty);
 	}
 	spin_unlock_irqrestore(&hp->lock, flags);
 
-	if (shouldflip)
-		tty_flip_buffer_push(hp->tty);
 
 	h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
 }
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 46/69] TTY: hvsi, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (44 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 45/69] TTY: hvsi, sanitize uses of tty Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 47/69] TTY: ipwireless, use synchronous hangup Jiri Slaby
                   ` (22 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, linuxppc-dev

Now, we switch to the refcounted model and do not need hp->lock to
protect hp->tty anymore.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/tty/hvc/hvsi.c |   35 +++++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
index 68b729b..6f5bc49 100644
--- a/drivers/tty/hvc/hvsi.c
+++ b/drivers/tty/hvc/hvsi.c
@@ -76,7 +76,6 @@ struct hvsi_struct {
 	wait_queue_head_t stateq; /* woken when HVSI state changes */
 	spinlock_t lock;
 	int index;
-	struct tty_struct *tty;
 	uint8_t throttle_buf[128];
 	uint8_t outbuf[N_OUTBUF]; /* to implement write_room and chars_in_buffer */
 	/* inbuf is for packet reassembly. leave a little room for leftovers. */
@@ -492,14 +491,17 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
 {
 	struct hvsi_struct *hp = (struct hvsi_struct *)arg;
 	struct hvsi_struct *handshake;
+	struct tty_struct *tty;
 	unsigned long flags;
 	int again = 1;
 
 	pr_debug("%s\n", __func__);
 
+	tty = tty_port_tty_get(&hp->port);
+
 	while (again) {
 		spin_lock_irqsave(&hp->lock, flags);
-		again = hvsi_load_chunk(hp, hp->tty, &handshake);
+		again = hvsi_load_chunk(hp, tty, &handshake);
 		spin_unlock_irqrestore(&hp->lock, flags);
 
 		if (handshake) {
@@ -509,15 +511,16 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
 	}
 
 	spin_lock_irqsave(&hp->lock, flags);
-	if (hp->tty && hp->n_throttle
-			&& (!test_bit(TTY_THROTTLED, &hp->tty->flags))) {
-		/* we weren't hung up and we weren't throttled, so we can deliver the
-		 * rest now */
-		hvsi_send_overflow(hp, hp->tty);
-		tty_flip_buffer_push(hp->tty);
+	if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) {
+		/* we weren't hung up and we weren't throttled, so we can
+		 * deliver the rest now */
+		hvsi_send_overflow(hp, tty);
+		tty_flip_buffer_push(tty);
 	}
 	spin_unlock_irqrestore(&hp->lock, flags);
 
+	tty_kref_put(tty);
+
 	return IRQ_HANDLED;
 }
 
@@ -724,8 +727,8 @@ static int hvsi_open(struct tty_struct *tty, struct file *filp)
 	if (hp->state == HVSI_FSP_DIED)
 		return -EIO;
 
+	tty_port_tty_set(&hp->port, tty);
 	spin_lock_irqsave(&hp->lock, flags);
-	hp->tty = tty;
 	hp->port.count++;
 	atomic_set(&hp->seqno, 0);
 	h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
@@ -784,7 +787,7 @@ static void hvsi_close(struct tty_struct *tty, struct file *filp)
 	spin_lock_irqsave(&hp->lock, flags);
 
 	if (--hp->port.count == 0) {
-		hp->tty = NULL;
+		tty_port_tty_set(&hp->port, NULL);
 		hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */
 
 		/* only close down connection if it is not the console */
@@ -830,12 +833,11 @@ static void hvsi_hangup(struct tty_struct *tty)
 
 	pr_debug("%s\n", __func__);
 
-	spin_lock_irqsave(&hp->lock, flags);
+	tty_port_tty_set(&hp->port, NULL);
 
+	spin_lock_irqsave(&hp->lock, flags);
 	hp->port.count = 0;
 	hp->n_outbuf = 0;
-	hp->tty = NULL;
-
 	spin_unlock_irqrestore(&hp->lock, flags);
 }
 
@@ -863,6 +865,7 @@ static void hvsi_write_worker(struct work_struct *work)
 {
 	struct hvsi_struct *hp =
 		container_of(work, struct hvsi_struct, writer.work);
+	struct tty_struct *tty;
 	unsigned long flags;
 #ifdef DEBUG
 	static long start_j = 0;
@@ -896,7 +899,11 @@ static void hvsi_write_worker(struct work_struct *work)
 		start_j = 0;
 #endif /* DEBUG */
 		wake_up_all(&hp->emptyq);
-		tty_wakeup(hp->tty);
+		tty = tty_port_tty_get(&hp->port);
+		if (tty) {
+			tty_wakeup(tty);
+			tty_kref_put(tty);
+		}
 	}
 
 out:
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 47/69] TTY: ipwireless, use synchronous hangup
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (45 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 46/69] TTY: hvsi, use tty from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 12:42   ` David Sterba
  2012-04-02 11:54 ` [PATCH 48/69] TTY: ipwireless, move prints to appropriate places Jiri Slaby
                   ` (21 subsequent siblings)
  68 siblings, 1 reply; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Jiri Kosina, David Sterba

Do not touch internal workqueue. Call tty_vhangup instead.

Note that finished hangup does not necessarily mean that all processes
are dead. Especially when the tty is a console. The code assumes that
right now.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: David Sterba <dsterba@suse.cz>
---
 drivers/tty/ipwireless/tty.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c
index 4daf962..e539621 100644
--- a/drivers/tty/ipwireless/tty.c
+++ b/drivers/tty/ipwireless/tty.c
@@ -565,11 +565,11 @@ void ipwireless_tty_free(struct ipw_tty *tty)
 			ttyj->closing = 1;
 			if (ttyj->linux_tty != NULL) {
 				mutex_unlock(&ttyj->ipw_tty_mutex);
-				tty_hangup(ttyj->linux_tty);
-				/* Wait till the tty_hangup has completed */
-				flush_work_sync(&ttyj->linux_tty->hangup_work);
+				tty_vhangup(ttyj->linux_tty);
 				/* FIXME: Exactly how is the tty object locked here
 				   against a parallel ioctl etc */
+				/* FIXME2: hangup does not mean all processes
+				 * are gone */
 				mutex_lock(&ttyj->ipw_tty_mutex);
 			}
 			while (ttyj->open_count)
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 48/69] TTY: ipwireless, move prints to appropriate places
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (46 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 47/69] TTY: ipwireless, use synchronous hangup Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 49/69] TTY: ipwireless, add tty_port Jiri Slaby
                   ` (20 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Jiri Kosina, David Sterba

There are two functions which only print a status. Let us do that
directly at places where they are called.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: David Sterba <dsterba@suse.cz>
---
 drivers/tty/ipwireless/tty.c |   31 ++++++++++---------------------
 1 file changed, 10 insertions(+), 21 deletions(-)

diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c
index e539621..4270bfd 100644
--- a/drivers/tty/ipwireless/tty.c
+++ b/drivers/tty/ipwireless/tty.c
@@ -73,23 +73,6 @@ static char *tty_type_name(int tty_type)
 	return channel_names[tty_type];
 }
 
-static void report_registering(struct ipw_tty *tty)
-{
-	char *iftype = tty_type_name(tty->tty_type);
-
-	printk(KERN_INFO IPWIRELESS_PCCARD_NAME
-	       ": registering %s device ttyIPWp%d\n", iftype, tty->index);
-}
-
-static void report_deregistering(struct ipw_tty *tty)
-{
-	char *iftype = tty_type_name(tty->tty_type);
-
-	printk(KERN_INFO IPWIRELESS_PCCARD_NAME
-	       ": deregistering %s device ttyIPWp%d\n", iftype,
-	       tty->index);
-}
-
 static struct ipw_tty *get_tty(int index)
 {
 	/*
@@ -500,8 +483,12 @@ static int add_tty(int j,
 		ipwireless_associate_network_tty(network,
 						 secondary_channel_idx,
 						 ttys[j]);
-	if (get_tty(j) == ttys[j])
-		report_registering(ttys[j]);
+	/* check if we provide raw device (if loopback is enabled) */
+	if (get_tty(j))
+		printk(KERN_INFO IPWIRELESS_PCCARD_NAME
+		       ": registering %s device ttyIPWp%d\n",
+		       tty_type_name(tty_type), j);
+
 	return 0;
 }
 
@@ -560,8 +547,10 @@ void ipwireless_tty_free(struct ipw_tty *tty)
 
 		if (ttyj) {
 			mutex_lock(&ttyj->ipw_tty_mutex);
-			if (get_tty(j) == ttyj)
-				report_deregistering(ttyj);
+			if (get_tty(j))
+				printk(KERN_INFO IPWIRELESS_PCCARD_NAME
+				       ": deregistering %s device ttyIPWp%d\n",
+				       tty_type_name(ttyj->tty_type), j);
 			ttyj->closing = 1;
 			if (ttyj->linux_tty != NULL) {
 				mutex_unlock(&ttyj->ipw_tty_mutex);
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 49/69] TTY: ipwireless, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (47 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 48/69] TTY: ipwireless, move prints to appropriate places Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 50/69] TTY: ipwireless, use tty from tty_port Jiri Slaby
                   ` (19 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Jiri Kosina, David Sterba

And use count from that.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: David Sterba <dsterba@suse.cz>
---
 drivers/tty/ipwireless/tty.c |   29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c
index 4270bfd..0b4964d 100644
--- a/drivers/tty/ipwireless/tty.c
+++ b/drivers/tty/ipwireless/tty.c
@@ -44,6 +44,7 @@
 #define TTYTYPE_RAS_RAW  (2)
 
 struct ipw_tty {
+	struct tty_port port;
 	int index;
 	struct ipw_hardware *hardware;
 	unsigned int channel_idx;
@@ -51,7 +52,6 @@ struct ipw_tty {
 	int tty_type;
 	struct ipw_network *network;
 	struct tty_struct *linux_tty;
-	int open_count;
 	unsigned int control_lines;
 	struct mutex ipw_tty_mutex;
 	int tx_bytes_queued;
@@ -100,10 +100,10 @@ static int ipw_open(struct tty_struct *linux_tty, struct file *filp)
 		mutex_unlock(&tty->ipw_tty_mutex);
 		return -ENODEV;
 	}
-	if (tty->open_count == 0)
+	if (tty->port.count == 0)
 		tty->tx_bytes_queued = 0;
 
-	tty->open_count++;
+	tty->port.count++;
 
 	tty->linux_tty = linux_tty;
 	linux_tty->driver_data = tty;
@@ -119,9 +119,9 @@ static int ipw_open(struct tty_struct *linux_tty, struct file *filp)
 
 static void do_ipw_close(struct ipw_tty *tty)
 {
-	tty->open_count--;
+	tty->port.count--;
 
-	if (tty->open_count == 0) {
+	if (tty->port.count == 0) {
 		struct tty_struct *linux_tty = tty->linux_tty;
 
 		if (linux_tty != NULL) {
@@ -142,7 +142,7 @@ static void ipw_hangup(struct tty_struct *linux_tty)
 		return;
 
 	mutex_lock(&tty->ipw_tty_mutex);
-	if (tty->open_count == 0) {
+	if (tty->port.count == 0) {
 		mutex_unlock(&tty->ipw_tty_mutex);
 		return;
 	}
@@ -171,7 +171,7 @@ void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data,
 		return;
 	}
 
-	if (!tty->open_count) {
+	if (!tty->port.count) {
 		mutex_unlock(&tty->ipw_tty_mutex);
 		return;
 	}
@@ -213,7 +213,7 @@ static int ipw_write(struct tty_struct *linux_tty,
 		return -ENODEV;
 
 	mutex_lock(&tty->ipw_tty_mutex);
-	if (!tty->open_count) {
+	if (!tty->port.count) {
 		mutex_unlock(&tty->ipw_tty_mutex);
 		return -EINVAL;
 	}
@@ -253,7 +253,7 @@ static int ipw_write_room(struct tty_struct *linux_tty)
 	if (!tty)
 		return -ENODEV;
 
-	if (!tty->open_count)
+	if (!tty->port.count)
 		return -EINVAL;
 
 	room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued;
@@ -295,7 +295,7 @@ static int ipw_chars_in_buffer(struct tty_struct *linux_tty)
 	if (!tty)
 		return 0;
 
-	if (!tty->open_count)
+	if (!tty->port.count)
 		return 0;
 
 	return tty->tx_bytes_queued;
@@ -376,7 +376,7 @@ static int ipw_tiocmget(struct tty_struct *linux_tty)
 	if (!tty)
 		return -ENODEV;
 
-	if (!tty->open_count)
+	if (!tty->port.count)
 		return -EINVAL;
 
 	return get_control_lines(tty);
@@ -392,7 +392,7 @@ ipw_tiocmset(struct tty_struct *linux_tty,
 	if (!tty)
 		return -ENODEV;
 
-	if (!tty->open_count)
+	if (!tty->port.count)
 		return -EINVAL;
 
 	return set_control_lines(tty, set, clear);
@@ -406,7 +406,7 @@ static int ipw_ioctl(struct tty_struct *linux_tty,
 	if (!tty)
 		return -ENODEV;
 
-	if (!tty->open_count)
+	if (!tty->port.count)
 		return -EINVAL;
 
 	/* FIXME: Exactly how is the tty object locked here .. */
@@ -475,6 +475,7 @@ static int add_tty(int j,
 	ttys[j]->network = network;
 	ttys[j]->tty_type = tty_type;
 	mutex_init(&ttys[j]->ipw_tty_mutex);
+	tty_port_init(&ttys[j]->port);
 
 	tty_register_device(ipw_tty_driver, j, NULL);
 	ipwireless_associate_network_tty(network, channel_idx, ttys[j]);
@@ -561,7 +562,7 @@ void ipwireless_tty_free(struct ipw_tty *tty)
 				 * are gone */
 				mutex_lock(&ttyj->ipw_tty_mutex);
 			}
-			while (ttyj->open_count)
+			while (ttyj->port.count)
 				do_ipw_close(ttyj);
 			ipwireless_disassociate_network_ttys(network,
 							     ttyj->channel_idx);
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 50/69] TTY: ipwireless, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (48 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 49/69] TTY: ipwireless, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 51/69] TTY: 68328serial, remove serial_state and friends Jiri Slaby
                   ` (18 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Jiri Kosina, David Sterba

It does not make the driver less racy though. Close and hangup should
be rewritten and tty refcounting used properly.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: David Sterba <dsterba@suse.cz>
---
 drivers/tty/ipwireless/tty.c |   17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c
index 0b4964d..f8b5fa0 100644
--- a/drivers/tty/ipwireless/tty.c
+++ b/drivers/tty/ipwireless/tty.c
@@ -51,7 +51,6 @@ struct ipw_tty {
 	unsigned int secondary_channel_idx;
 	int tty_type;
 	struct ipw_network *network;
-	struct tty_struct *linux_tty;
 	unsigned int control_lines;
 	struct mutex ipw_tty_mutex;
 	int tx_bytes_queued;
@@ -105,7 +104,7 @@ static int ipw_open(struct tty_struct *linux_tty, struct file *filp)
 
 	tty->port.count++;
 
-	tty->linux_tty = linux_tty;
+	tty->port.tty = linux_tty;
 	linux_tty->driver_data = tty;
 	linux_tty->low_latency = 1;
 
@@ -122,10 +121,10 @@ static void do_ipw_close(struct ipw_tty *tty)
 	tty->port.count--;
 
 	if (tty->port.count == 0) {
-		struct tty_struct *linux_tty = tty->linux_tty;
+		struct tty_struct *linux_tty = tty->port.tty;
 
 		if (linux_tty != NULL) {
-			tty->linux_tty = NULL;
+			tty->port.tty = NULL;
 			linux_tty->driver_data = NULL;
 
 			if (tty->tty_type == TTYTYPE_MODEM)
@@ -165,7 +164,7 @@ void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data,
 	int work = 0;
 
 	mutex_lock(&tty->ipw_tty_mutex);
-	linux_tty = tty->linux_tty;
+	linux_tty = tty->port.tty;
 	if (linux_tty == NULL) {
 		mutex_unlock(&tty->ipw_tty_mutex);
 		return;
@@ -553,9 +552,9 @@ void ipwireless_tty_free(struct ipw_tty *tty)
 				       ": deregistering %s device ttyIPWp%d\n",
 				       tty_type_name(ttyj->tty_type), j);
 			ttyj->closing = 1;
-			if (ttyj->linux_tty != NULL) {
+			if (ttyj->port.tty != NULL) {
 				mutex_unlock(&ttyj->ipw_tty_mutex);
-				tty_vhangup(ttyj->linux_tty);
+				tty_vhangup(ttyj->port.tty);
 				/* FIXME: Exactly how is the tty object locked here
 				   against a parallel ioctl etc */
 				/* FIXME2: hangup does not mean all processes
@@ -651,8 +650,8 @@ ipwireless_tty_notify_control_line_change(struct ipw_tty *tty,
 	 */
 	if ((old_control_lines & IPW_CONTROL_LINE_DCD)
 			&& !(tty->control_lines & IPW_CONTROL_LINE_DCD)
-			&& tty->linux_tty) {
-		tty_hangup(tty->linux_tty);
+			&& tty->port.tty) {
+		tty_hangup(tty->port.tty);
 	}
 }
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 51/69] TTY: 68328serial, remove serial_state and friends
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (49 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 50/69] TTY: ipwireless, use tty from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-03 12:48   ` Geert Uytterhoeven
  2012-04-02 11:54 ` [PATCH 52/69] TTY: 68328serial, remove unused stuff from m68k_serial Jiri Slaby
                   ` (17 subsequent siblings)
  68 siblings, 1 reply; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

serial_state in 68328serial.h is a duplicated structure. One is
defined in linux/serial.h. So let us use that instead. And since the
serial flags are identical, use ones from there too.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   55 +++++++++++----------------
 drivers/tty/serial/68328serial.h |   76 --------------------------------------
 2 files changed, 22 insertions(+), 109 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index 5ce7825..bf5f811 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -17,6 +17,7 @@
 #include <asm/dbg.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/serial.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
@@ -79,18 +80,6 @@ struct m68k_serial *m68k_consinfo = 0;
 
 struct tty_driver *serial_driver;
 
-/* number of characters left in xmit buffer before we ask for more */
-#define WAKEUP_CHARS 256
-
-/* Debugging... DEBUG_INTR is bad to use when one of the zs
- * lines is your console ;(
- */
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-
-#define RS_ISR_PASS_LIMIT 256
-
 static void change_speed(struct m68k_serial *info);
 
 /*
@@ -363,7 +352,7 @@ static int startup(struct m68k_serial * info)
 	m68328_uart *uart = &uart_addr[info->line];
 	unsigned long flags;
 	
-	if (info->flags & S_INITIALIZED)
+	if (info->flags & ASYNC_INITIALIZED)
 		return 0;
 
 	if (!info->xmit_buf) {
@@ -404,7 +393,7 @@ static int startup(struct m68k_serial * info)
 
 	change_speed(info);
 
-	info->flags |= S_INITIALIZED;
+	info->flags |= ASYNC_INITIALIZED;
 	local_irq_restore(flags);
 	return 0;
 }
@@ -419,7 +408,7 @@ static void shutdown(struct m68k_serial * info)
 	unsigned long	flags;
 
 	uart->ustcnt = 0; /* All off! */
-	if (!(info->flags & S_INITIALIZED))
+	if (!(info->flags & ASYNC_INITIALIZED))
 		return;
 
 	local_irq_save(flags);
@@ -432,7 +421,7 @@ static void shutdown(struct m68k_serial * info)
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 	
-	info->flags &= ~S_INITIALIZED;
+	info->flags &= ~ASYNC_INITIALIZED;
 	local_irq_restore(flags);
 }
 
@@ -835,11 +824,11 @@ static int set_serial_info(struct m68k_serial * info,
 		if ((new_serial.baud_base != info->baud_base) ||
 		    (new_serial.type != info->type) ||
 		    (new_serial.close_delay != info->close_delay) ||
-		    ((new_serial.flags & ~S_USR_MASK) !=
-		     (info->flags & ~S_USR_MASK)))
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		     (info->flags & ~ASYNC_USR_MASK)))
 			return -EPERM;
-		info->flags = ((info->flags & ~S_USR_MASK) |
-			       (new_serial.flags & S_USR_MASK));
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
 		info->custom_divisor = new_serial.custom_divisor;
 		goto check_and_exit;
 	}
@@ -853,8 +842,8 @@ static int set_serial_info(struct m68k_serial * info,
 	 */
 
 	info->baud_base = new_serial.baud_base;
-	info->flags = ((info->flags & ~S_FLAGS) |
-			(new_serial.flags & S_FLAGS));
+	info->flags = ((info->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
 	info->type = new_serial.type;
 	info->close_delay = new_serial.close_delay;
 	info->closing_wait = new_serial.closing_wait;
@@ -1022,13 +1011,13 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 		local_irq_restore(flags);
 		return;
 	}
-	info->flags |= S_CLOSING;
+	info->flags |= ASYNC_CLOSING;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (info->closing_wait != S_CLOSING_WAIT_NONE)
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
 		tty_wait_until_sent(tty, info->closing_wait);
 	/*
 	 * At this point we stop accepting input.  To do this, we
@@ -1064,7 +1053,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
-	info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&info->close_wait);
 	local_irq_restore(flags);
 }
@@ -1083,7 +1072,7 @@ void rs_hangup(struct tty_struct *tty)
 	shutdown(info);
 	info->event = 0;
 	info->count = 0;
-	info->flags &= ~S_NORMAL_ACTIVE;
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
 	wake_up_interruptible(&info->open_wait);
 }
@@ -1104,10 +1093,10 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	 * If the device is in the middle of being closed, then block
 	 * until it's done, and then try again.
 	 */
-	if (info->flags & S_CLOSING) {
+	if (info->flags & ASYNC_CLOSING) {
 		interruptible_sleep_on(&info->close_wait);
 #ifdef SERIAL_DO_RESTART
-		if (info->flags & S_HUP_NOTIFY)
+		if (info->flags & ASYNC_HUP_NOTIFY)
 			return -EAGAIN;
 		else
 			return -ERESTARTSYS;
@@ -1122,7 +1111,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		info->flags |= S_NORMAL_ACTIVE;
+		info->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
@@ -1147,9 +1136,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 		local_irq_enable();
 		current->state = TASK_INTERRUPTIBLE;
 		if (tty_hung_up_p(filp) ||
-		    !(info->flags & S_INITIALIZED)) {
+		    !(info->flags & ASYNC_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
-			if (info->flags & S_HUP_NOTIFY)
+			if (info->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
 				retval = -ERESTARTSYS;	
@@ -1158,7 +1147,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 #endif
 			break;
 		}
-		if (!(info->flags & S_CLOSING) && do_clocal)
+		if (!(info->flags & ASYNC_CLOSING) && do_clocal)
 			break;
                 if (signal_pending(current)) {
 			retval = -ERESTARTSYS;
@@ -1176,7 +1165,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 
 	if (retval)
 		return retval;
-	info->flags |= S_NORMAL_ACTIVE;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
 	return 0;
 }	
 
diff --git a/drivers/tty/serial/68328serial.h b/drivers/tty/serial/68328serial.h
index 3d2faab..a804ea5 100644
--- a/drivers/tty/serial/68328serial.h
+++ b/drivers/tty/serial/68328serial.h
@@ -11,69 +11,6 @@
 #ifndef _MC683XX_SERIAL_H
 #define _MC683XX_SERIAL_H
 
-
-struct serial_struct {
-	int	type;
-	int	line;
-	int	port;
-	int	irq;
-	int	flags;
-	int	xmit_fifo_size;
-	int	custom_divisor;
-	int	baud_base;
-	unsigned short	close_delay;
-	char	reserved_char[2];
-	int	hub6;  /* FIXME: We don't have AT&T Hub6 boards! */
-	unsigned short	closing_wait; /* time to wait before closing */
-	unsigned short	closing_wait2; /* no longer used... */
-	int	reserved[4];
-};
-
-/*
- * For the close wait times, 0 means wait forever for serial port to
- * flush its output.  65535 means don't wait at all.
- */
-#define S_CLOSING_WAIT_INF	0
-#define S_CLOSING_WAIT_NONE	65535
-
-/*
- * Definitions for S_struct (and serial_struct) flags field
- */
-#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
-				   on the callout port */
-#define S_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
-#define S_SAK	0x0004	/* Secure Attention Key (Orange book) */
-#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
-
-#define S_SPD_MASK	0x0030
-#define S_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
-
-#define S_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
-#define S_SPD_CUST	0x0030  /* Use user-specified divisor */
-
-#define S_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
-#define S_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
-#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
-#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
-#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
-
-#define S_FLAGS	0x0FFF	/* Possible legal S flags */
-#define S_USR_MASK 0x0430	/* Legal flags that non-privileged
-				 * users can set or reset */
-
-/* Internal flags used only by kernel/chr_drv/serial.c */
-#define S_INITIALIZED	0x80000000 /* Serial port was initialized */
-#define S_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
-#define S_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
-#define S_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
-#define S_CLOSING		0x08000000 /* Serial port is closing */
-#define S_CTS_FLOW		0x04000000 /* Do CTS flow control */
-#define S_CHECK_CD		0x02000000 /* i.e., CLOCAL */
-
-/* Software state per channel */
-
-#ifdef __KERNEL__
-
 /*
  * I believe this is the optimal setting that reduces the number of interrupts.
  * At high speeds the output might become a little "bursted" (use USTCNT_TXHE
@@ -162,25 +99,12 @@ struct m68k_serial {
 	wait_queue_head_t	close_wait;
 };
 
-
 #define SERIAL_MAGIC 0x5301
 
-/*
- * The size of the serial xmit buffer is 1 page, or 4096 bytes
- */
-#define SERIAL_XMIT_SIZE 4096
-
-/*
- * Events are used to schedule things to happen at timer-interrupt
- * time, instead of at rs interrupt time.
- */
-#define RS_EVENT_WRITE_WAKEUP	0
-
 /* 
  * Define the number of ports supported and their irqs.
  */
 #define NR_PORTS 1
 #define UART_IRQ_DEFNS {UART_IRQ_NUM}
 
-#endif /* __KERNEL__ */
 #endif /* !(_MC683XX_SERIAL_H) */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 52/69] TTY: 68328serial, remove unused stuff from m68k_serial
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (50 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 51/69] TTY: 68328serial, remove serial_state and friends Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 53/69] TTY: 68328serial, remove garbage Jiri Slaby
                   ` (16 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

Not everything from struct m68k_serial is really used. So remove
unused or only-set members of that structure. Next step is to move it
to 68328serial.c and remove 68328serial.h completely.

This change also takes status_handle and batten_down_hatches away
since they use break_abort but do nothing.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   36 ++++--------------------------------
 drivers/tty/serial/68328serial.h |   16 ----------------
 2 files changed, 4 insertions(+), 48 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index bf5f811..c1cd214 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -213,25 +213,6 @@ static void rs_start(struct tty_struct *tty)
 	local_irq_restore(flags);
 }
 
-/* Drop into either the boot monitor or kadb upon receiving a break
- * from keyboard/console input.
- */
-static void batten_down_hatches(void)
-{
-	/* Drop into the debugger */
-}
-
-static void status_handle(struct m68k_serial *info, unsigned short status)
-{
-	/* If this is console input and this is a
-	 * 'break asserted' status change interrupt
-	 * see if we can drop into the debugger
-	 */
-	if((status & URX_BREAK) && info->break_abort)
-		batten_down_hatches();
-	return;
-}
-
 static void receive_chars(struct m68k_serial *info, unsigned short rx)
 {
 	struct tty_struct *tty = info->tty;
@@ -248,7 +229,6 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx)
 	
 		if(info->is_cons) {
 			if(URX_BREAK & rx) { /* whee, break received */
-				status_handle(info, rx);
 				return;
 #ifdef CONFIG_MAGIC_SYSRQ
 			} else if (ch == 0x10) { /* ^P */
@@ -269,16 +249,13 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx)
 		
 		flag = TTY_NORMAL;
 
-		if(rx & URX_PARITY_ERROR) {
+		if (rx & URX_PARITY_ERROR)
 			flag = TTY_PARITY;
-			status_handle(info, rx);
-		} else if(rx & URX_OVRUN) {
+		else if (rx & URX_OVRUN)
 			flag = TTY_OVERRUN;
-			status_handle(info, rx);
-		} else if(rx & URX_FRAME_ERROR) {
+		else if (rx & URX_FRAME_ERROR)
 			flag = TTY_FRAME;
-			status_handle(info, rx);
-		}
+
 		tty_insert_flip_char(tty, ch, flag);
 #ifndef CONFIG_XCOPILOT_BUGS
 	} while((rx = uart->urx.w) & URX_DATA_READY);
@@ -369,7 +346,6 @@ static int startup(struct m68k_serial * info)
 	 */
 
 	uart->ustcnt = USTCNT_UEN;
-	info->xmit_fifo_size = 1;
 	uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_TXEN;
 	(void)uart->urx.w;
 
@@ -499,7 +475,6 @@ static void change_speed(struct m68k_serial *info)
                 i = (i & ~CBAUDEX) + B38400;
         }
 
-	info->baud = baud_table[i];
 	uart->ubaud = PUT_FIELD(UBAUD_DIVIDE,    hw_baud_table[i].divisor) | 
 		PUT_FIELD(UBAUD_PRESCALER, hw_baud_table[i].prescale);
 
@@ -1034,7 +1009,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 		
 	tty_ldisc_flush(tty);
 	tty->closing = 0;
-	info->event = 0;
 	info->tty = NULL;
 #warning "This is not and has never been valid so fix it"	
 #if 0
@@ -1070,7 +1044,6 @@ void rs_hangup(struct tty_struct *tty)
 	
 	rs_flush_buffer(tty);
 	shutdown(info);
-	info->event = 0;
 	info->count = 0;
 	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
@@ -1270,7 +1243,6 @@ rs68328_init(void)
 	    info->close_delay = 50;
 	    info->closing_wait = 3000;
 	    info->x_char = 0;
-	    info->event = 0;
 	    info->count = 0;
 	    info->blocked_open = 0;
 	    init_waitqueue_head(&info->open_wait);
diff --git a/drivers/tty/serial/68328serial.h b/drivers/tty/serial/68328serial.h
index a804ea5..971ead5 100644
--- a/drivers/tty/serial/68328serial.h
+++ b/drivers/tty/serial/68328serial.h
@@ -60,16 +60,7 @@
  */
 
 struct m68k_serial {
-	char soft_carrier;  /* Use soft carrier on this channel */
-	char break_abort;   /* Is serial console in, so process brk/abrt */
 	char is_cons;       /* Is this our console. */
-
-	/* We need to know the current clock divisor
-	 * to read the bps rate the chip has currently
-	 * loaded.
-	 */
-	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
-	int baud;
 	int			magic;
 	int			baud_base;
 	int			port;
@@ -77,17 +68,10 @@ struct m68k_serial {
 	int			flags; 		/* defined in tty.h */
 	int			type; 		/* UART type */
 	struct tty_struct 	*tty;
-	int			read_status_mask;
-	int			ignore_status_mask;
-	int			timeout;
-	int			xmit_fifo_size;
 	int			custom_divisor;
 	int			x_char;	/* xon/xoff character */
 	int			close_delay;
 	unsigned short		closing_wait;
-	unsigned short		closing_wait2;
-	unsigned long		event;
-	unsigned long		last_active;
 	int			line;
 	int			count;	    /* # of fd on device */
 	int			blocked_open; /* # of blocked opens */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 53/69] TTY: 68328serial, remove garbage
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (51 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 52/69] TTY: 68328serial, remove unused stuff from m68k_serial Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 54/69] TTY: 68328serial, use ulong flags for interrupts status Jiri Slaby
                   ` (15 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

- empty functions
- unused global variables

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   19 -------------------
 1 file changed, 19 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index c1cd214..81ed91e 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -73,11 +73,6 @@ static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS;
 /* multiple ports are contiguous in memory */
 m68328_uart *uart_addr = (m68328_uart *)USTCNT_ADDR;
 
-struct tty_struct m68k_ttys;
-struct m68k_serial *m68k_consinfo = 0;
-
-#define M68K_CLOCK (16667000) /* FIXME: 16MHz is likely wrong */
-
 struct tty_driver *serial_driver;
 
 static void change_speed(struct m68k_serial *info);
@@ -132,17 +127,6 @@ static int baud_table[] = {
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 	9600, 19200, 38400, 57600, 115200, 0 };
 
-/* Sets or clears DTR/RTS on the requested line */
-static inline void m68k_rtsdtr(struct m68k_serial *ss, int set)
-{
-	if (set) {
-		/* set the RTS/CTS line */
-	} else {
-		/* clear it */
-	}
-	return;
-}
-
 /* Utility routines */
 static inline int get_baud(struct m68k_serial *ss)
 {
@@ -1104,9 +1088,6 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	info->count--;
 	info->blocked_open++;
 	while (1) {
-		local_irq_disable();
-		m68k_rtsdtr(info, 1);
-		local_irq_enable();
 		current->state = TASK_INTERRUPTIBLE;
 		if (tty_hung_up_p(filp) ||
 		    !(info->flags & ASYNC_INITIALIZED)) {
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 54/69] TTY: 68328serial, use ulong flags for interrupts status
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (52 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 53/69] TTY: 68328serial, remove garbage Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 55/69] TTY: 68328serial, remove 68328serial.h Jiri Slaby
                   ` (14 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

flags passed to local_irq_save/restore should be ulong. Switch tehem
to that. Otherwise we get compilation warnings:
.../68328serial.c:248:9: warning: comparison of distinct pointer types lacks a cast [enabled by default]
.../68328serial.c:257:9: warning: comparison of distinct pointer types lacks a cast [enabled by default]

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index 81ed91e..f0d5039 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -162,7 +162,8 @@ static void rs_stop(struct tty_struct *tty)
 
 static int rs_put_char(char ch)
 {
-        int flags, loops = 0;
+	unsigned long flags;
+	int loops = 0;
 
         local_irq_save(flags);
 
@@ -1182,7 +1183,8 @@ static const struct tty_operations rs_ops = {
 static int __init
 rs68328_init(void)
 {
-	int flags, i;
+	unsigned long flags;
+	int i;
 	struct m68k_serial *info;
 
 	serial_driver = alloc_tty_driver(NR_PORTS);
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 55/69] TTY: 68328serial, remove 68328serial.h
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (53 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 54/69] TTY: 68328serial, use ulong flags for interrupts status Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 56/69] TTY: 68328serial, add tty_port Jiri Slaby
                   ` (13 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

All the needed stuff is moved to 68328serial.c now.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   79 ++++++++++++++++++++++++++++++--
 drivers/tty/serial/68328serial.h |   94 --------------------------------------
 2 files changed, 76 insertions(+), 97 deletions(-)
 delete mode 100644 drivers/tty/serial/68328serial.h

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index f0d5039..116d932 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -57,8 +57,6 @@
 #endif /* CONFIG_M68VZ328 */
 #endif /* CONFIG_M68EZ328 */
 
-#include "68328serial.h"
-
 /* Turn off usage of real serial interrupt code, to "support" Copilot */
 #ifdef CONFIG_XCOPILOT_BUGS
 #undef USE_INTS
@@ -66,9 +64,84 @@
 #define USE_INTS
 #endif
 
+/*
+ * I believe this is the optimal setting that reduces the number of interrupts.
+ * At high speeds the output might become a little "bursted" (use USTCNT_TXHE
+ * if that bothers you), but in most cases it will not, since we try to
+ * transmit characters every time rs_interrupt is called. Thus, quite often
+ * you'll see that a receive interrupt occures before the transmit one.
+ *                                  -- Vladimir Gurevich
+ */
+#define USTCNT_TX_INTR_MASK (USTCNT_TXEE)
+
+/*
+ * 68328 and 68EZ328 UARTS are a little bit different. EZ328 has special
+ * "Old data interrupt" which occures whenever the data stay in the FIFO
+ * longer than 30 bits time. This allows us to use FIFO without compromising
+ * latency. '328 does not have this feature and without the real  328-based
+ * board I would assume that RXRE is the safest setting.
+ *
+ * For EZ328 I use RXHE (Half empty) interrupt to reduce the number of
+ * interrupts. RXFE (receive queue full) causes the system to lose data
+ * at least at 115200 baud
+ *
+ * If your board is busy doing other stuff, you might consider to use
+ * RXRE (data ready intrrupt) instead.
+ *
+ * The other option is to make these INTR masks run-time configurable, so
+ * that people can dynamically adapt them according to the current usage.
+ *                                  -- Vladimir Gurevich
+ */
+
+/* (es) */
+#if defined(CONFIG_M68EZ328) || defined(CONFIG_M68VZ328)
+#define USTCNT_RX_INTR_MASK (USTCNT_RXHE | USTCNT_ODEN)
+#elif defined(CONFIG_M68328)
+#define USTCNT_RX_INTR_MASK (USTCNT_RXRE)
+#else
+#error Please, define the Rx interrupt events for your CPU
+#endif
+/* (/es) */
+
+/*
+ * This is our internal structure for each serial port's state.
+ *
+ * For definitions of the flags field, see serial.h
+ */
+struct m68k_serial {
+	char			is_cons;	/* Is this our console. */
+	int			magic;
+	int			baud_base;
+	int			port;
+	int			irq;
+	int			flags;		/* defined in tty.h */
+	int			type;		/* UART type */
+	struct tty_struct	*tty;
+	int			custom_divisor;
+	int			x_char;		/* xon/xoff character */
+	int			close_delay;
+	unsigned short		closing_wait;
+	int			line;
+	int			count;		/* # of fd on device */
+	int			blocked_open;	/* # of blocked opens */
+	unsigned char		*xmit_buf;
+	int			xmit_head;
+	int			xmit_tail;
+	int			xmit_cnt;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+};
+
+#define SERIAL_MAGIC 0x5301
+
+/*
+ * Define the number of ports supported and their irqs.
+ */
+#define NR_PORTS 1
+
 static struct m68k_serial m68k_soft[NR_PORTS];
 
-static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS;
+static unsigned int uart_irqs[NR_PORTS] = { UART_IRQ_NUM };
 
 /* multiple ports are contiguous in memory */
 m68328_uart *uart_addr = (m68328_uart *)USTCNT_ADDR;
diff --git a/drivers/tty/serial/68328serial.h b/drivers/tty/serial/68328serial.h
deleted file mode 100644
index 971ead5..0000000
--- a/drivers/tty/serial/68328serial.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* 68328serial.h: Definitions for the mc68328 serial driver.
- *
- * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
- * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
- * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@uclinux.org>
- * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
- *
- * VZ Support/Fixes             Evan Stawnyczy <e@lineo.ca>
- */
-
-#ifndef _MC683XX_SERIAL_H
-#define _MC683XX_SERIAL_H
-
-/*
- * I believe this is the optimal setting that reduces the number of interrupts.
- * At high speeds the output might become a little "bursted" (use USTCNT_TXHE
- * if that bothers you), but in most cases it will not, since we try to 
- * transmit characters every time rs_interrupt is called. Thus, quite often
- * you'll see that a receive interrupt occures before the transmit one.
- *                                  -- Vladimir Gurevich
- */
-#define USTCNT_TX_INTR_MASK (USTCNT_TXEE)
-
-/*
- * 68328 and 68EZ328 UARTS are a little bit different. EZ328 has special
- * "Old data interrupt" which occures whenever the data stay in the FIFO
- * longer than 30 bits time. This allows us to use FIFO without compromising
- * latency. '328 does not have this feature and without the real  328-based
- * board I would assume that RXRE is the safest setting.
- *
- * For EZ328 I use RXHE (Half empty) interrupt to reduce the number of
- * interrupts. RXFE (receive queue full) causes the system to lose data
- * at least at 115200 baud
- *
- * If your board is busy doing other stuff, you might consider to use
- * RXRE (data ready intrrupt) instead.
- *
- * The other option is to make these INTR masks run-time configurable, so
- * that people can dynamically adapt them according to the current usage.
- *                                  -- Vladimir Gurevich
- */
-
-/* (es) */
-#if defined(CONFIG_M68EZ328) || defined(CONFIG_M68VZ328)
-#define USTCNT_RX_INTR_MASK (USTCNT_RXHE | USTCNT_ODEN)
-#elif defined(CONFIG_M68328)
-#define USTCNT_RX_INTR_MASK (USTCNT_RXRE)
-#else
-#error Please, define the Rx interrupt events for your CPU
-#endif
-/* (/es) */
-
-/*
- * This is our internal structure for each serial port's state.
- * 
- * Many fields are paralleled by the structure used by the serial_struct
- * structure.
- *
- * For definitions of the flags field, see tty.h
- */
-
-struct m68k_serial {
-	char is_cons;       /* Is this our console. */
-	int			magic;
-	int			baud_base;
-	int			port;
-	int			irq;
-	int			flags; 		/* defined in tty.h */
-	int			type; 		/* UART type */
-	struct tty_struct 	*tty;
-	int			custom_divisor;
-	int			x_char;	/* xon/xoff character */
-	int			close_delay;
-	unsigned short		closing_wait;
-	int			line;
-	int			count;	    /* # of fd on device */
-	int			blocked_open; /* # of blocked opens */
-	unsigned char 		*xmit_buf;
-	int			xmit_head;
-	int			xmit_tail;
-	int			xmit_cnt;
-	wait_queue_head_t	open_wait;
-	wait_queue_head_t	close_wait;
-};
-
-#define SERIAL_MAGIC 0x5301
-
-/* 
- * Define the number of ports supported and their irqs.
- */
-#define NR_PORTS 1
-#define UART_IRQ_DEFNS {UART_IRQ_NUM}
-
-#endif /* !(_MC683XX_SERIAL_H) */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 56/69] TTY: 68328serial, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (54 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 55/69] TTY: 68328serial, remove 68328serial.h Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 57/69] TTY: 68328serial, use open/close_wait from tty_port Jiri Slaby
                   ` (12 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

And use count and blocked_count from that.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   40 +++++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index 116d932..848662c 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -109,6 +109,7 @@
  * For definitions of the flags field, see serial.h
  */
 struct m68k_serial {
+	struct tty_port		tport;
 	char			is_cons;	/* Is this our console. */
 	int			magic;
 	int			baud_base;
@@ -122,8 +123,6 @@ struct m68k_serial {
 	int			close_delay;
 	unsigned short		closing_wait;
 	int			line;
-	int			count;		/* # of fd on device */
-	int			blocked_open;	/* # of blocked opens */
 	unsigned char		*xmit_buf;
 	int			xmit_head;
 	int			xmit_tail;
@@ -866,7 +865,7 @@ static int set_serial_info(struct m68k_serial * info,
 		goto check_and_exit;
 	}
 
-	if (info->count > 1)
+	if (info->tport.count > 1)
 		return -EBUSY;
 
 	/*
@@ -1010,6 +1009,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 static void rs_close(struct tty_struct *tty, struct file * filp)
 {
 	struct m68k_serial * info = (struct m68k_serial *)tty->driver_data;
+	struct tty_port *port = &info->tport;
 	m68328_uart *uart = &uart_addr[info->line];
 	unsigned long flags;
 
@@ -1023,7 +1023,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 		return;
 	}
 	
-	if ((tty->count == 1) && (info->count != 1)) {
+	if ((tty->count == 1) && (port->count != 1)) {
 		/*
 		 * Uh, oh.  tty->count is 1, which means that the tty
 		 * structure will be freed.  Info->count should always
@@ -1032,15 +1032,15 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 		 * serial port won't be shutdown.
 		 */
 		printk("rs_close: bad serial port count; tty->count is 1, "
-		       "info->count is %d\n", info->count);
-		info->count = 1;
+		       "port->count is %d\n", port->count);
+		port->count = 1;
 	}
-	if (--info->count < 0) {
+	if (--port->count < 0) {
 		printk("rs_close: bad serial port count for ttyS%d: %d\n",
-		       info->line, info->count);
-		info->count = 0;
+		       info->line, port->count);
+		port->count = 0;
 	}
-	if (info->count) {
+	if (port->count) {
 		local_irq_restore(flags);
 		return;
 	}
@@ -1079,7 +1079,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 			(tty->ldisc.open)(tty);
 	}
 #endif	
-	if (info->blocked_open) {
+	if (port->blocked_open) {
 		if (info->close_delay) {
 			msleep_interruptible(jiffies_to_msecs(info->close_delay));
 		}
@@ -1102,7 +1102,7 @@ void rs_hangup(struct tty_struct *tty)
 	
 	rs_flush_buffer(tty);
 	shutdown(info);
-	info->count = 0;
+	info->tport.count = 0;
 	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
 	wake_up_interruptible(&info->open_wait);
@@ -1116,6 +1116,7 @@ void rs_hangup(struct tty_struct *tty)
 static int block_til_ready(struct tty_struct *tty, struct file * filp,
 			   struct m68k_serial *info)
 {
+	struct tty_port *port = &info->tport;
 	DECLARE_WAITQUEUE(wait, current);
 	int		retval;
 	int		do_clocal = 0;
@@ -1152,15 +1153,15 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, info->count is dropped by one, so that
+	 * this loop, port->count is dropped by one, so that
 	 * rs_close() knows when to free things.  We restore it upon
 	 * exit, either normal or abnormal.
 	 */
 	retval = 0;
 	add_wait_queue(&info->open_wait, &wait);
 
-	info->count--;
-	info->blocked_open++;
+	port->count--;
+	port->blocked_open++;
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		if (tty_hung_up_p(filp) ||
@@ -1188,8 +1189,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	current->state = TASK_RUNNING;
 	remove_wait_queue(&info->open_wait, &wait);
 	if (!tty_hung_up_p(filp))
-		info->count++;
-	info->blocked_open--;
+		port->count++;
+	port->blocked_open--;
 
 	if (retval)
 		return retval;
@@ -1213,7 +1214,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
 	if (serial_paranoia_check(info, tty->name, "rs_open"))
 		return -ENODEV;
 
-	info->count++;
+	info->tport.count++;
 	tty->driver_data = info;
 	info->tty = tty;
 
@@ -1291,6 +1292,7 @@ rs68328_init(void)
 	for(i=0;i<NR_PORTS;i++) {
 
 	    info = &m68k_soft[i];
+	    tty_port_init(&info->tport);
 	    info->magic = SERIAL_MAGIC;
 	    info->port = (int) &uart_addr[i];
 	    info->tty = NULL;
@@ -1299,8 +1301,6 @@ rs68328_init(void)
 	    info->close_delay = 50;
 	    info->closing_wait = 3000;
 	    info->x_char = 0;
-	    info->count = 0;
-	    info->blocked_open = 0;
 	    init_waitqueue_head(&info->open_wait);
 	    init_waitqueue_head(&info->close_wait);
 	    info->line = i;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 57/69] TTY: 68328serial, use open/close_wait from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (55 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 56/69] TTY: 68328serial, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 58/69] TTY: 68328serial, use close_delay/closing_wait " Jiri Slaby
                   ` (11 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index 848662c..0c50f2e 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -127,8 +127,6 @@ struct m68k_serial {
 	int			xmit_head;
 	int			xmit_tail;
 	int			xmit_cnt;
-	wait_queue_head_t	open_wait;
-	wait_queue_head_t	close_wait;
 };
 
 #define SERIAL_MAGIC 0x5301
@@ -1083,10 +1081,10 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 		if (info->close_delay) {
 			msleep_interruptible(jiffies_to_msecs(info->close_delay));
 		}
-		wake_up_interruptible(&info->open_wait);
+		wake_up_interruptible(&port->open_wait);
 	}
 	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-	wake_up_interruptible(&info->close_wait);
+	wake_up_interruptible(&port->close_wait);
 	local_irq_restore(flags);
 }
 
@@ -1105,7 +1103,7 @@ void rs_hangup(struct tty_struct *tty)
 	info->tport.count = 0;
 	info->flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
-	wake_up_interruptible(&info->open_wait);
+	wake_up_interruptible(&info->tport.open_wait);
 }
 
 /*
@@ -1126,7 +1124,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	 * until it's done, and then try again.
 	 */
 	if (info->flags & ASYNC_CLOSING) {
-		interruptible_sleep_on(&info->close_wait);
+		interruptible_sleep_on(&port->close_wait);
 #ifdef SERIAL_DO_RESTART
 		if (info->flags & ASYNC_HUP_NOTIFY)
 			return -EAGAIN;
@@ -1158,7 +1156,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	 * exit, either normal or abnormal.
 	 */
 	retval = 0;
-	add_wait_queue(&info->open_wait, &wait);
+	add_wait_queue(&port->open_wait, &wait);
 
 	port->count--;
 	port->blocked_open++;
@@ -1187,7 +1185,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 		tty_lock();
 	}
 	current->state = TASK_RUNNING;
-	remove_wait_queue(&info->open_wait, &wait);
+	remove_wait_queue(&port->open_wait, &wait);
 	if (!tty_hung_up_p(filp))
 		port->count++;
 	port->blocked_open--;
@@ -1301,8 +1299,6 @@ rs68328_init(void)
 	    info->close_delay = 50;
 	    info->closing_wait = 3000;
 	    info->x_char = 0;
-	    init_waitqueue_head(&info->open_wait);
-	    init_waitqueue_head(&info->close_wait);
 	    info->line = i;
 	    info->is_cons = 1; /* Means shortcuts work */
 	    
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 58/69] TTY: 68328serial, use close_delay/closing_wait from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (56 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 57/69] TTY: 68328serial, use open/close_wait from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 59/69] TTY: 68328serial, use flags " Jiri Slaby
                   ` (10 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index 0c50f2e..e9fd13e 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -120,8 +120,6 @@ struct m68k_serial {
 	struct tty_struct	*tty;
 	int			custom_divisor;
 	int			x_char;		/* xon/xoff character */
-	int			close_delay;
-	unsigned short		closing_wait;
 	int			line;
 	unsigned char		*xmit_buf;
 	int			xmit_head;
@@ -828,8 +826,8 @@ static int get_serial_info(struct m68k_serial * info,
 	tmp.irq = info->irq;
 	tmp.flags = info->flags;
 	tmp.baud_base = info->baud_base;
-	tmp.close_delay = info->close_delay;
-	tmp.closing_wait = info->closing_wait;
+	tmp.close_delay = info->tport.close_delay;
+	tmp.closing_wait = info->tport.closing_wait;
 	tmp.custom_divisor = info->custom_divisor;
 	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
 		return -EFAULT;
@@ -840,6 +838,7 @@ static int get_serial_info(struct m68k_serial * info,
 static int set_serial_info(struct m68k_serial * info,
 			   struct serial_struct * new_info)
 {
+	struct tty_port *port = &info->tport;
 	struct serial_struct new_serial;
 	struct m68k_serial old_info;
 	int 			retval = 0;
@@ -853,7 +852,7 @@ static int set_serial_info(struct m68k_serial * info,
 	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.baud_base != info->baud_base) ||
 		    (new_serial.type != info->type) ||
-		    (new_serial.close_delay != info->close_delay) ||
+		    (new_serial.close_delay != port->close_delay) ||
 		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
 		     (info->flags & ~ASYNC_USR_MASK)))
 			return -EPERM;
@@ -863,7 +862,7 @@ static int set_serial_info(struct m68k_serial * info,
 		goto check_and_exit;
 	}
 
-	if (info->tport.count > 1)
+	if (port->count > 1)
 		return -EBUSY;
 
 	/*
@@ -875,8 +874,8 @@ static int set_serial_info(struct m68k_serial * info,
 	info->flags = ((info->flags & ~ASYNC_FLAGS) |
 			(new_serial.flags & ASYNC_FLAGS));
 	info->type = new_serial.type;
-	info->close_delay = new_serial.close_delay;
-	info->closing_wait = new_serial.closing_wait;
+	port->close_delay = new_serial.close_delay;
+	port->closing_wait = new_serial.closing_wait;
 
 check_and_exit:
 	retval = startup(info);
@@ -1048,8 +1047,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
+	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, port->closing_wait);
 	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
@@ -1078,9 +1077,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 	}
 #endif	
 	if (port->blocked_open) {
-		if (info->close_delay) {
-			msleep_interruptible(jiffies_to_msecs(info->close_delay));
-		}
+		if (port->close_delay)
+			msleep_interruptible(jiffies_to_msecs(port->close_delay));
 		wake_up_interruptible(&port->open_wait);
 	}
 	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -1296,8 +1294,6 @@ rs68328_init(void)
 	    info->tty = NULL;
 	    info->irq = uart_irqs[i];
 	    info->custom_divisor = 16;
-	    info->close_delay = 50;
-	    info->closing_wait = 3000;
 	    info->x_char = 0;
 	    info->line = i;
 	    info->is_cons = 1; /* Means shortcuts work */
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 59/69] TTY: 68328serial, use flags from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (57 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 58/69] TTY: 68328serial, use close_delay/closing_wait " Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 60/69] TTY: 68328serial, propagate tty Jiri Slaby
                   ` (9 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   39 ++++++++++++++++++--------------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index e9fd13e..e3a1c55 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -105,8 +105,6 @@
 
 /*
  * This is our internal structure for each serial port's state.
- *
- * For definitions of the flags field, see serial.h
  */
 struct m68k_serial {
 	struct tty_port		tport;
@@ -115,7 +113,6 @@ struct m68k_serial {
 	int			baud_base;
 	int			port;
 	int			irq;
-	int			flags;		/* defined in tty.h */
 	int			type;		/* UART type */
 	struct tty_struct	*tty;
 	int			custom_divisor;
@@ -382,7 +379,7 @@ static int startup(struct m68k_serial * info)
 	m68328_uart *uart = &uart_addr[info->line];
 	unsigned long flags;
 	
-	if (info->flags & ASYNC_INITIALIZED)
+	if (info->tport.flags & ASYNC_INITIALIZED)
 		return 0;
 
 	if (!info->xmit_buf) {
@@ -422,7 +419,7 @@ static int startup(struct m68k_serial * info)
 
 	change_speed(info);
 
-	info->flags |= ASYNC_INITIALIZED;
+	info->tport.flags |= ASYNC_INITIALIZED;
 	local_irq_restore(flags);
 	return 0;
 }
@@ -437,7 +434,7 @@ static void shutdown(struct m68k_serial * info)
 	unsigned long	flags;
 
 	uart->ustcnt = 0; /* All off! */
-	if (!(info->flags & ASYNC_INITIALIZED))
+	if (!(info->tport.flags & ASYNC_INITIALIZED))
 		return;
 
 	local_irq_save(flags);
@@ -450,7 +447,7 @@ static void shutdown(struct m68k_serial * info)
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 	
-	info->flags &= ~ASYNC_INITIALIZED;
+	info->tport.flags &= ~ASYNC_INITIALIZED;
 	local_irq_restore(flags);
 }
 
@@ -824,7 +821,7 @@ static int get_serial_info(struct m68k_serial * info,
 	tmp.line = info->line;
 	tmp.port = info->port;
 	tmp.irq = info->irq;
-	tmp.flags = info->flags;
+	tmp.flags = info->tport.flags;
 	tmp.baud_base = info->baud_base;
 	tmp.close_delay = info->tport.close_delay;
 	tmp.closing_wait = info->tport.closing_wait;
@@ -854,9 +851,9 @@ static int set_serial_info(struct m68k_serial * info,
 		    (new_serial.type != info->type) ||
 		    (new_serial.close_delay != port->close_delay) ||
 		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
-		     (info->flags & ~ASYNC_USR_MASK)))
+		     (port->flags & ~ASYNC_USR_MASK)))
 			return -EPERM;
-		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+		port->flags = ((port->flags & ~ASYNC_USR_MASK) |
 			       (new_serial.flags & ASYNC_USR_MASK));
 		info->custom_divisor = new_serial.custom_divisor;
 		goto check_and_exit;
@@ -871,7 +868,7 @@ static int set_serial_info(struct m68k_serial * info,
 	 */
 
 	info->baud_base = new_serial.baud_base;
-	info->flags = ((info->flags & ~ASYNC_FLAGS) |
+	port->flags = ((port->flags & ~ASYNC_FLAGS) |
 			(new_serial.flags & ASYNC_FLAGS));
 	info->type = new_serial.type;
 	port->close_delay = new_serial.close_delay;
@@ -1041,7 +1038,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 		local_irq_restore(flags);
 		return;
 	}
-	info->flags |= ASYNC_CLOSING;
+	port->flags |= ASYNC_CLOSING;
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
@@ -1081,7 +1078,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 			msleep_interruptible(jiffies_to_msecs(port->close_delay));
 		wake_up_interruptible(&port->open_wait);
 	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&port->close_wait);
 	local_irq_restore(flags);
 }
@@ -1099,7 +1096,7 @@ void rs_hangup(struct tty_struct *tty)
 	rs_flush_buffer(tty);
 	shutdown(info);
 	info->tport.count = 0;
-	info->flags &= ~ASYNC_NORMAL_ACTIVE;
+	info->tport.flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
 	wake_up_interruptible(&info->tport.open_wait);
 }
@@ -1121,10 +1118,10 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	 * If the device is in the middle of being closed, then block
 	 * until it's done, and then try again.
 	 */
-	if (info->flags & ASYNC_CLOSING) {
+	if (port->flags & ASYNC_CLOSING) {
 		interruptible_sleep_on(&port->close_wait);
 #ifdef SERIAL_DO_RESTART
-		if (info->flags & ASYNC_HUP_NOTIFY)
+		if (port->flags & ASYNC_HUP_NOTIFY)
 			return -EAGAIN;
 		else
 			return -ERESTARTSYS;
@@ -1139,7 +1136,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	 */
 	if ((filp->f_flags & O_NONBLOCK) ||
 	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		info->flags |= ASYNC_NORMAL_ACTIVE;
+		port->flags |= ASYNC_NORMAL_ACTIVE;
 		return 0;
 	}
 
@@ -1161,9 +1158,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		if (tty_hung_up_p(filp) ||
-		    !(info->flags & ASYNC_INITIALIZED)) {
+		    !(port->flags & ASYNC_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
-			if (info->flags & ASYNC_HUP_NOTIFY)
+			if (port->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
 				retval = -ERESTARTSYS;	
@@ -1172,7 +1169,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 #endif
 			break;
 		}
-		if (!(info->flags & ASYNC_CLOSING) && do_clocal)
+		if (!(port->flags & ASYNC_CLOSING) && do_clocal)
 			break;
                 if (signal_pending(current)) {
 			retval = -ERESTARTSYS;
@@ -1190,7 +1187,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 
 	if (retval)
 		return retval;
-	info->flags |= ASYNC_NORMAL_ACTIVE;
+	port->flags |= ASYNC_NORMAL_ACTIVE;
 	return 0;
 }	
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 60/69] TTY: 68328serial, propagate tty
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (58 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 59/69] TTY: 68328serial, use flags " Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 61/69] TTY: 68328serial, use tty from tty_port Jiri Slaby
                   ` (8 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

We need tty at some places, but info->tty might be NULL at those. Let
us propagate tty from callers where we know we have a valid tty. This
will make a switch to tty refcounting simpler.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   53 +++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 26 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index e3a1c55..fde573b 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -140,7 +140,7 @@ m68328_uart *uart_addr = (m68328_uart *)USTCNT_ADDR;
 
 struct tty_driver *serial_driver;
 
-static void change_speed(struct m68k_serial *info);
+static void change_speed(struct m68k_serial *info, struct tty_struct *tty);
 
 /*
  *	Setup for console. Argument comes from the boot command line.
@@ -263,9 +263,9 @@ static void rs_start(struct tty_struct *tty)
 	local_irq_restore(flags);
 }
 
-static void receive_chars(struct m68k_serial *info, unsigned short rx)
+static void receive_chars(struct m68k_serial *info, struct tty_struct *tty,
+		unsigned short rx)
 {
-	struct tty_struct *tty = info->tty;
 	m68328_uart *uart = &uart_addr[info->line];
 	unsigned char ch, flag;
 
@@ -317,7 +317,7 @@ clear_and_exit:
 	return;
 }
 
-static void transmit_chars(struct m68k_serial *info)
+static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty)
 {
 	m68328_uart *uart = &uart_addr[info->line];
 
@@ -328,7 +328,7 @@ static void transmit_chars(struct m68k_serial *info)
 		goto clear_and_return;
 	}
 
-	if((info->xmit_cnt <= 0) || info->tty->stopped) {
+	if ((info->xmit_cnt <= 0) || !tty || tty->stopped) {
 		/* That's peculiar... TX ints off */
 		uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
 		goto clear_and_return;
@@ -356,6 +356,7 @@ clear_and_return:
 irqreturn_t rs_interrupt(int irq, void *dev_id)
 {
 	struct m68k_serial *info = dev_id;
+	struct tty_struct *tty = info->tty;
 	m68328_uart *uart;
 	unsigned short rx;
 	unsigned short tx;
@@ -366,15 +367,17 @@ irqreturn_t rs_interrupt(int irq, void *dev_id)
 #ifdef USE_INTS
 	tx = uart->utx.w;
 
-	if (rx & URX_DATA_READY) receive_chars(info, rx);
-	if (tx & UTX_TX_AVAIL)   transmit_chars(info);
+	if (rx & URX_DATA_READY)
+		receive_chars(info, tty, rx);
+	if (tx & UTX_TX_AVAIL)
+		transmit_chars(info, tty);
 #else
-	receive_chars(info, rx);		
+	receive_chars(info, tty, rx);
 #endif
 	return IRQ_HANDLED;
 }
 
-static int startup(struct m68k_serial * info)
+static int startup(struct m68k_serial *info, struct tty_struct *tty)
 {
 	m68328_uart *uart = &uart_addr[info->line];
 	unsigned long flags;
@@ -409,15 +412,15 @@ static int startup(struct m68k_serial * info)
 	uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK;
 #endif
 
-	if (info->tty)
-		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	if (tty)
+		clear_bit(TTY_IO_ERROR, &tty->flags);
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 
 	/*
 	 * and set the speed of the serial port
 	 */
 
-	change_speed(info);
+	change_speed(info, tty);
 
 	info->tport.flags |= ASYNC_INITIALIZED;
 	local_irq_restore(flags);
@@ -428,7 +431,7 @@ static int startup(struct m68k_serial * info)
  * This routine will shutdown a serial port; interrupts are disabled, and
  * DTR is dropped if the hangup on close termio flag is on.
  */
-static void shutdown(struct m68k_serial * info)
+static void shutdown(struct m68k_serial *info, struct tty_struct *tty)
 {
 	m68328_uart *uart = &uart_addr[info->line];
 	unsigned long	flags;
@@ -444,8 +447,8 @@ static void shutdown(struct m68k_serial * info)
 		info->xmit_buf = 0;
 	}
 
-	if (info->tty)
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
+	if (tty)
+		set_bit(TTY_IO_ERROR, &tty->flags);
 	
 	info->tport.flags &= ~ASYNC_INITIALIZED;
 	local_irq_restore(flags);
@@ -503,7 +506,7 @@ struct {
  * This routine is called to set the UART divisor registers to match
  * the specified baud rate for a serial port.
  */
-static void change_speed(struct m68k_serial *info)
+static void change_speed(struct m68k_serial *info, struct tty_struct *tty)
 {
 	m68328_uart *uart = &uart_addr[info->line];
 	unsigned short port;
@@ -511,9 +514,7 @@ static void change_speed(struct m68k_serial *info)
 	unsigned cflag;
 	int	i;
 
-	if (!info->tty || !info->tty->termios)
-		return;
-	cflag = info->tty->termios->c_cflag;
+	cflag = tty->termios->c_cflag;
 	if (!(port = info->port))
 		return;
 
@@ -832,7 +833,7 @@ static int get_serial_info(struct m68k_serial * info,
 	return 0;
 }
 
-static int set_serial_info(struct m68k_serial * info,
+static int set_serial_info(struct m68k_serial *info, struct tty_struct *tty,
 			   struct serial_struct * new_info)
 {
 	struct tty_port *port = &info->tport;
@@ -875,7 +876,7 @@ static int set_serial_info(struct m68k_serial * info,
 	port->closing_wait = new_serial.closing_wait;
 
 check_and_exit:
-	retval = startup(info);
+	retval = startup(info, tty);
 	return retval;
 }
 
@@ -961,7 +962,7 @@ static int rs_ioctl(struct tty_struct *tty,
 			return get_serial_info(info,
 				       (struct serial_struct *) arg);
 		case TIOCSSERIAL:
-			return set_serial_info(info,
+			return set_serial_info(info, tty,
 					       (struct serial_struct *) arg);
 		case TIOCSERGETLSR: /* Get line status register */
 			return get_lsr_info(info, (unsigned int *) arg);
@@ -980,7 +981,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
 
-	change_speed(info);
+	change_speed(info, tty);
 
 	if ((old_termios->c_cflag & CRTSCTS) &&
 	    !(tty->termios->c_cflag & CRTSCTS)) {
@@ -1056,7 +1057,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 	uart->ustcnt &= ~USTCNT_RXEN;
 	uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK);
 
-	shutdown(info);
+	shutdown(info, tty);
 	rs_flush_buffer(tty);
 		
 	tty_ldisc_flush(tty);
@@ -1094,7 +1095,7 @@ void rs_hangup(struct tty_struct *tty)
 		return;
 	
 	rs_flush_buffer(tty);
-	shutdown(info);
+	shutdown(info, tty);
 	info->tport.count = 0;
 	info->tport.flags &= ~ASYNC_NORMAL_ACTIVE;
 	info->tty = NULL;
@@ -1214,7 +1215,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
 	/*
 	 * Start up serial port
 	 */
-	retval = startup(info);
+	retval = startup(info, tty);
 	if (retval)
 		return retval;
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 61/69] TTY: 68328serial, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (59 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 60/69] TTY: 68328serial, propagate tty Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 62/69] TTY: 68328serial, use tty_port_block_til_ready Jiri Slaby
                   ` (7 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

And refcount that properly.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index fde573b..77e10bb 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -114,7 +114,6 @@ struct m68k_serial {
 	int			port;
 	int			irq;
 	int			type;		/* UART type */
-	struct tty_struct	*tty;
 	int			custom_divisor;
 	int			x_char;		/* xon/xoff character */
 	int			line;
@@ -356,7 +355,7 @@ clear_and_return:
 irqreturn_t rs_interrupt(int irq, void *dev_id)
 {
 	struct m68k_serial *info = dev_id;
-	struct tty_struct *tty = info->tty;
+	struct tty_struct *tty = tty_port_tty_get(&info->tport);
 	m68328_uart *uart;
 	unsigned short rx;
 	unsigned short tx;
@@ -374,6 +373,8 @@ irqreturn_t rs_interrupt(int irq, void *dev_id)
 #else
 	receive_chars(info, tty, rx);
 #endif
+	tty_kref_put(tty);
+
 	return IRQ_HANDLED;
 }
 
@@ -1062,7 +1063,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 		
 	tty_ldisc_flush(tty);
 	tty->closing = 0;
-	info->tty = NULL;
+	tty_port_tty_set(&info->tport, NULL);
 #warning "This is not and has never been valid so fix it"	
 #if 0
 	if (tty->ldisc.num != ldiscs[N_TTY].num) {
@@ -1098,7 +1099,7 @@ void rs_hangup(struct tty_struct *tty)
 	shutdown(info, tty);
 	info->tport.count = 0;
 	info->tport.flags &= ~ASYNC_NORMAL_ACTIVE;
-	info->tty = NULL;
+	tty_port_tty_set(&info->tport, NULL);
 	wake_up_interruptible(&info->tport.open_wait);
 }
 
@@ -1210,7 +1211,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
 
 	info->tport.count++;
 	tty->driver_data = info;
-	info->tty = tty;
+	tty_port_tty_set(&info->tport, tty);
 
 	/*
 	 * Start up serial port
@@ -1289,7 +1290,6 @@ rs68328_init(void)
 	    tty_port_init(&info->tport);
 	    info->magic = SERIAL_MAGIC;
 	    info->port = (int) &uart_addr[i];
-	    info->tty = NULL;
 	    info->irq = uart_irqs[i];
 	    info->custom_divisor = 16;
 	    info->x_char = 0;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 62/69] TTY: 68328serial, use tty_port_block_til_ready
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (60 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 61/69] TTY: 68328serial, use tty from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-04 12:25   ` Greg Ungerer
  2012-04-02 11:54 ` [PATCH 63/69] TTY: usb/u_serial, add tty_port Jiri Slaby
                   ` (6 subsequent siblings)
  68 siblings, 1 reply; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

Since the code is identical, use the tty_port_block_til_ready helper
instead of re-implemented variant.

The code does not perform rtsdts handling, hence we do not need to
provide tty port hooks for them. The default ones will be used
instead. The only necessary thing is to provide tty_port_operations.
It is empty, but has to be there...

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
---
 drivers/tty/serial/68328serial.c |   96 ++------------------------------------
 1 file changed, 5 insertions(+), 91 deletions(-)

diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
index 77e10bb..3ed20e4 100644
--- a/drivers/tty/serial/68328serial.c
+++ b/drivers/tty/serial/68328serial.c
@@ -1104,96 +1104,6 @@ void rs_hangup(struct tty_struct *tty)
 }
 
 /*
- * ------------------------------------------------------------
- * rs_open() and friends
- * ------------------------------------------------------------
- */
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
-			   struct m68k_serial *info)
-{
-	struct tty_port *port = &info->tport;
-	DECLARE_WAITQUEUE(wait, current);
-	int		retval;
-	int		do_clocal = 0;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (port->flags & ASYNC_CLOSING) {
-		interruptible_sleep_on(&port->close_wait);
-#ifdef SERIAL_DO_RESTART
-		if (port->flags & ASYNC_HUP_NOTIFY)
-			return -EAGAIN;
-		else
-			return -ERESTARTSYS;
-#else
-		return -EAGAIN;
-#endif
-	}
-	
-	/*
-	 * If non-blocking mode is set, or the port is not enabled,
-	 * then make the check up front and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		port->flags |= ASYNC_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	if (tty->termios->c_cflag & CLOCAL)
-		do_clocal = 1;
-
-	/*
-	 * Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, port->count is dropped by one, so that
-	 * rs_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&port->open_wait, &wait);
-
-	port->count--;
-	port->blocked_open++;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		if (tty_hung_up_p(filp) ||
-		    !(port->flags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
-			if (port->flags & ASYNC_HUP_NOTIFY)
-				retval = -EAGAIN;
-			else
-				retval = -ERESTARTSYS;	
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-		if (!(port->flags & ASYNC_CLOSING) && do_clocal)
-			break;
-                if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-		tty_unlock();
-		schedule();
-		tty_lock();
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&port->open_wait, &wait);
-	if (!tty_hung_up_p(filp))
-		port->count++;
-	port->blocked_open--;
-
-	if (retval)
-		return retval;
-	port->flags |= ASYNC_NORMAL_ACTIVE;
-	return 0;
-}	
-
-/*
  * This routine is called whenever a serial port is opened.  It
  * enables interrupts for a serial port, linking in its S structure into
  * the IRQ chain.   It also performs the serial-specific
@@ -1220,7 +1130,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
 	if (retval)
 		return retval;
 
-	return block_til_ready(tty, filp, info);
+	return tty_port_block_til_ready(&info->tport, tty, filp);
 }
 
 /* Finally, routines used to initialize the serial driver. */
@@ -1248,6 +1158,9 @@ static const struct tty_operations rs_ops = {
 	.set_ldisc = rs_set_ldisc,
 };
 
+static const struct tty_port_operations rs_port_ops = {
+};
+
 /* rs_init inits the driver */
 static int __init
 rs68328_init(void)
@@ -1288,6 +1201,7 @@ rs68328_init(void)
 
 	    info = &m68k_soft[i];
 	    tty_port_init(&info->tport);
+	    info->tport.ops = &rs_port_ops;
 	    info->magic = SERIAL_MAGIC;
 	    info->port = (int) &uart_addr[i];
 	    info->irq = uart_irqs[i];
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 63/69] TTY: usb/u_serial, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (61 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 62/69] TTY: 68328serial, use tty_port_block_til_ready Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 64/69] TTY: usb/u_serial, use tty from tty_port Jiri Slaby
                   ` (5 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby

And use count from there.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/usb/gadget/u_serial.c |   25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 6c23938..a6212ff 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -94,12 +94,12 @@ struct gs_buf {
  * (and thus for each /dev/ node).
  */
 struct gs_port {
+	struct tty_port		port;
 	spinlock_t		port_lock;	/* guard port_* access */
 
 	struct gserial		*port_usb;
 	struct tty_struct	*port_tty;
 
-	unsigned		open_count;
 	bool			openclose;	/* open/close in progress */
 	u8			port_num;
 
@@ -734,9 +734,9 @@ static int gs_open(struct tty_struct *tty, struct file *file)
 			spin_lock_irq(&port->port_lock);
 
 			/* already open?  Great. */
-			if (port->open_count) {
+			if (port->port.count) {
 				status = 0;
-				port->open_count++;
+				port->port.count++;
 
 			/* currently opening/closing? wait ... */
 			} else if (port->openclose) {
@@ -795,7 +795,7 @@ static int gs_open(struct tty_struct *tty, struct file *file)
 	tty->driver_data = port;
 	port->port_tty = tty;
 
-	port->open_count = 1;
+	port->port.count = 1;
 	port->openclose = false;
 
 	/* if connected, start the I/O stream */
@@ -837,11 +837,11 @@ static void gs_close(struct tty_struct *tty, struct file *file)
 
 	spin_lock_irq(&port->port_lock);
 
-	if (port->open_count != 1) {
-		if (port->open_count == 0)
+	if (port->port.count != 1) {
+		if (port->port.count == 0)
 			WARN_ON(1);
 		else
-			--port->open_count;
+			--port->port.count;
 		goto exit;
 	}
 
@@ -851,7 +851,7 @@ static void gs_close(struct tty_struct *tty, struct file *file)
 	 * and sleep if necessary
 	 */
 	port->openclose = true;
-	port->open_count = 0;
+	port->port.count = 0;
 
 	gser = port->port_usb;
 	if (gser && gser->disconnect)
@@ -1034,6 +1034,7 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
 	if (port == NULL)
 		return -ENOMEM;
 
+	tty_port_init(&port->port);
 	spin_lock_init(&port->port_lock);
 	init_waitqueue_head(&port->close_wait);
 	init_waitqueue_head(&port->drain_wait);
@@ -1155,7 +1156,7 @@ static int gs_closed(struct gs_port *port)
 	int cond;
 
 	spin_lock_irq(&port->port_lock);
-	cond = (port->open_count == 0) && !port->openclose;
+	cond = (port->port.count == 0) && !port->openclose;
 	spin_unlock_irq(&port->port_lock);
 	return cond;
 }
@@ -1268,7 +1269,7 @@ int gserial_connect(struct gserial *gser, u8 port_num)
 	/* if it's already open, start I/O ... and notify the serial
 	 * protocol about open/close status (connect/disconnect).
 	 */
-	if (port->open_count) {
+	if (port->port.count) {
 		pr_debug("gserial_connect: start ttyGS%d\n", port->port_num);
 		gs_start_io(port);
 		if (gser->connect)
@@ -1315,7 +1316,7 @@ void gserial_disconnect(struct gserial *gser)
 
 	port->port_usb = NULL;
 	gser->ioport = NULL;
-	if (port->open_count > 0 || port->openclose) {
+	if (port->port.count > 0 || port->openclose) {
 		wake_up_interruptible(&port->drain_wait);
 		if (port->port_tty)
 			tty_hangup(port->port_tty);
@@ -1331,7 +1332,7 @@ void gserial_disconnect(struct gserial *gser)
 
 	/* finally, free any unused/unusable I/O buffers */
 	spin_lock_irqsave(&port->port_lock, flags);
-	if (port->open_count == 0 && !port->openclose)
+	if (port->port.count == 0 && !port->openclose)
 		gs_buf_free(&port->port_write_buf);
 	gs_free_requests(gser->out, &port->read_pool, NULL);
 	gs_free_requests(gser->out, &port->read_queue, NULL);
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 64/69] TTY: usb/u_serial, use tty from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (62 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 63/69] TTY: usb/u_serial, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 65/69] TTY: usb/u_serial use close_wait " Jiri Slaby
                   ` (4 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/usb/gadget/u_serial.c |   19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index a6212ff..d038a90 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -98,7 +98,6 @@ struct gs_port {
 	spinlock_t		port_lock;	/* guard port_* access */
 
 	struct gserial		*port_usb;
-	struct tty_struct	*port_tty;
 
 	bool			openclose;	/* open/close in progress */
 	u8			port_num;
@@ -412,8 +411,8 @@ __acquires(&port->port_lock)
 			break;
 	}
 
-	if (do_tty_wake && port->port_tty)
-		tty_wakeup(port->port_tty);
+	if (do_tty_wake && port->port.tty)
+		tty_wakeup(port->port.tty);
 	return status;
 }
 
@@ -435,7 +434,7 @@ __acquires(&port->port_lock)
 		struct tty_struct	*tty;
 
 		/* no more rx if closed */
-		tty = port->port_tty;
+		tty = port->port.tty;
 		if (!tty)
 			break;
 
@@ -488,7 +487,7 @@ static void gs_rx_push(unsigned long _port)
 
 	/* hand any queued data to the tty */
 	spin_lock_irq(&port->port_lock);
-	tty = port->port_tty;
+	tty = port->port.tty;
 	while (!list_empty(queue)) {
 		struct usb_request	*req;
 
@@ -699,7 +698,7 @@ static int gs_start_io(struct gs_port *port)
 
 	/* unblock any pending writes into our circular buffer */
 	if (started) {
-		tty_wakeup(port->port_tty);
+		tty_wakeup(port->port.tty);
 	} else {
 		gs_free_requests(ep, head, &port->read_allocated);
 		gs_free_requests(port->port_usb->in, &port->write_pool,
@@ -793,7 +792,7 @@ static int gs_open(struct tty_struct *tty, struct file *file)
 	/* REVISIT maybe wait for "carrier detect" */
 
 	tty->driver_data = port;
-	port->port_tty = tty;
+	port->port.tty = tty;
 
 	port->port.count = 1;
 	port->openclose = false;
@@ -879,7 +878,7 @@ static void gs_close(struct tty_struct *tty, struct file *file)
 		gs_buf_clear(&port->port_write_buf);
 
 	tty->driver_data = NULL;
-	port->port_tty = NULL;
+	port->port.tty = NULL;
 
 	port->openclose = false;
 
@@ -1318,8 +1317,8 @@ void gserial_disconnect(struct gserial *gser)
 	gser->ioport = NULL;
 	if (port->port.count > 0 || port->openclose) {
 		wake_up_interruptible(&port->drain_wait);
-		if (port->port_tty)
-			tty_hangup(port->port_tty);
+		if (port->port.tty)
+			tty_hangup(port->port.tty);
 	}
 	spin_unlock_irqrestore(&port->port_lock, flags);
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 65/69] TTY: usb/u_serial use close_wait from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (63 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 64/69] TTY: usb/u_serial, use tty from tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 66/69] TTY: rfcomm/tty, add tty_port Jiri Slaby
                   ` (3 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/usb/gadget/u_serial.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index d038a90..71ecae7 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -102,8 +102,6 @@ struct gs_port {
 	bool			openclose;	/* open/close in progress */
 	u8			port_num;
 
-	wait_queue_head_t	close_wait;	/* wait for last close */
-
 	struct list_head	read_pool;
 	int read_started;
 	int read_allocated;
@@ -885,7 +883,7 @@ static void gs_close(struct tty_struct *tty, struct file *file)
 	pr_debug("gs_close: ttyGS%d (%p,%p) done!\n",
 			port->port_num, tty, file);
 
-	wake_up_interruptible(&port->close_wait);
+	wake_up_interruptible(&port->port.close_wait);
 exit:
 	spin_unlock_irq(&port->port_lock);
 }
@@ -1035,7 +1033,6 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
 
 	tty_port_init(&port->port);
 	spin_lock_init(&port->port_lock);
-	init_waitqueue_head(&port->close_wait);
 	init_waitqueue_head(&port->drain_wait);
 
 	tasklet_init(&port->push, gs_rx_push, (unsigned long) port);
@@ -1194,7 +1191,7 @@ void gserial_cleanup(void)
 		tasklet_kill(&port->push);
 
 		/* wait for old opens to finish */
-		wait_event(port->close_wait, gs_closed(port));
+		wait_event(port->port.close_wait, gs_closed(port));
 
 		WARN_ON(port->port_usb != NULL);
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 66/69] TTY: rfcomm/tty, add tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (64 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 65/69] TTY: usb/u_serial use close_wait " Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 67/69] TTY: rfcomm/tty, use tty_port refcounting Jiri Slaby
                   ` (2 subsequent siblings)
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby

And use tty from there.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/bluetooth/rfcomm/tty.c |   25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 4bf54b3..97c2a08 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -48,6 +48,7 @@
 static struct tty_driver *rfcomm_tty_driver;
 
 struct rfcomm_dev {
+	struct tty_port		port;
 	struct list_head	list;
 	atomic_t		refcnt;
 
@@ -64,7 +65,6 @@ struct rfcomm_dev {
 	uint			modem_status;
 
 	struct rfcomm_dlc	*dlc;
-	struct tty_struct	*tty;
 	wait_queue_head_t       wait;
 	struct work_struct	wakeup_task;
 
@@ -252,6 +252,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 
 	atomic_set(&dev->opened, 0);
 
+	tty_port_init(&dev->port);
 	init_waitqueue_head(&dev->wait);
 	INIT_WORK(&dev->wakeup_task, rfcomm_tty_wakeup);
 
@@ -440,8 +441,8 @@ static int rfcomm_release_dev(void __user *arg)
 		rfcomm_dlc_close(dev->dlc, 0);
 
 	/* Shut down TTY synchronously before freeing rfcomm_dev */
-	if (dev->tty)
-		tty_vhangup(dev->tty);
+	if (dev->port.tty)
+		tty_vhangup(dev->port.tty);
 
 	if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
 		rfcomm_dev_del(dev);
@@ -559,7 +560,7 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
 		return;
 	}
 
-	tty = dev->tty;
+	tty = dev->port.tty;
 	if (!tty || !skb_queue_empty(&dev->pending)) {
 		skb_queue_tail(&dev->pending, skb);
 		return;
@@ -585,7 +586,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
 	wake_up_interruptible(&dev->wait);
 
 	if (dlc->state == BT_CLOSED) {
-		if (!dev->tty) {
+		if (!dev->port.tty) {
 			if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
 				/* Drop DLC lock here to avoid deadlock
 				 * 1. rfcomm_dev_get will take rfcomm_dev_lock
@@ -605,7 +606,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
 				rfcomm_dlc_lock(dlc);
 			}
 		} else
-			tty_hangup(dev->tty);
+			tty_hangup(dev->port.tty);
 	}
 }
 
@@ -618,8 +619,8 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
 	BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
 
 	if ((dev->modem_status & TIOCM_CD) && !(v24_sig & RFCOMM_V24_DV)) {
-		if (dev->tty && !C_CLOCAL(dev->tty))
-			tty_hangup(dev->tty);
+		if (dev->port.tty && !C_CLOCAL(dev->port.tty))
+			tty_hangup(dev->port.tty);
 	}
 
 	dev->modem_status =
@@ -634,7 +635,7 @@ static void rfcomm_tty_wakeup(struct work_struct *work)
 {
 	struct rfcomm_dev *dev = container_of(work, struct rfcomm_dev,
 								wakeup_task);
-	struct tty_struct *tty = dev->tty;
+	struct tty_struct *tty = dev->port.tty;
 	if (!tty)
 		return;
 
@@ -644,7 +645,7 @@ static void rfcomm_tty_wakeup(struct work_struct *work)
 
 static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
 {
-	struct tty_struct *tty = dev->tty;
+	struct tty_struct *tty = dev->port.tty;
 	struct sk_buff *skb;
 	int inserted = 0;
 
@@ -697,7 +698,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 
 	rfcomm_dlc_lock(dlc);
 	tty->driver_data = dev;
-	dev->tty = tty;
+	dev->port.tty = tty;
 	rfcomm_dlc_unlock(dlc);
 	set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
 
@@ -762,7 +763,7 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
 
 		rfcomm_dlc_lock(dev->dlc);
 		tty->driver_data = NULL;
-		dev->tty = NULL;
+		dev->port.tty = NULL;
 		rfcomm_dlc_unlock(dev->dlc);
 
 		if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags)) {
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 67/69] TTY: rfcomm/tty, use tty_port refcounting
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (65 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 66/69] TTY: rfcomm/tty, add tty_port Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 68/69] TTY: rfcomm/tty, remove work for tty_wakeup Jiri Slaby
  2012-04-02 11:54 ` [PATCH 69/69] TTY: rfcomm/tty, use count from tty_port Jiri Slaby
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby

Switch the refcounting from manual atomic plays with refcounter to the
one offered by tty_port.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/bluetooth/rfcomm/tty.c |   58 ++++++++++++++++++++------------------------
 1 file changed, 26 insertions(+), 32 deletions(-)

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 97c2a08..da4f545 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -50,7 +50,6 @@ static struct tty_driver *rfcomm_tty_driver;
 struct rfcomm_dev {
 	struct tty_port		port;
 	struct list_head	list;
-	atomic_t		refcnt;
 
 	char			name[12];
 	int			id;
@@ -85,8 +84,17 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
 static void rfcomm_tty_wakeup(struct work_struct *work);
 
 /* ---- Device functions ---- */
-static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
+
+/*
+ * The reason this isn't actually a race, as you no doubt have a little voice
+ * screaming at you in your head, is that the refcount should never actually
+ * reach zero unless the device has already been taken off the list, in
+ * rfcomm_dev_del(). And if that's not true, we'll hit the BUG() in
+ * rfcomm_dev_destruct() anyway.
+ */
+static void rfcomm_dev_destruct(struct tty_port *port)
 {
+	struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
 	struct rfcomm_dlc *dlc = dev->dlc;
 
 	BT_DBG("dev %p dlc %p", dev, dlc);
@@ -113,23 +121,9 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
 	module_put(THIS_MODULE);
 }
 
-static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
-{
-	atomic_inc(&dev->refcnt);
-}
-
-static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
-{
-	/* The reason this isn't actually a race, as you no
-	   doubt have a little voice screaming at you in your
-	   head, is that the refcount should never actually
-	   reach zero unless the device has already been taken
-	   off the list, in rfcomm_dev_del(). And if that's not
-	   true, we'll hit the BUG() in rfcomm_dev_destruct()
-	   anyway. */
-	if (atomic_dec_and_test(&dev->refcnt))
-		rfcomm_dev_destruct(dev);
-}
+static const struct tty_port_operations rfcomm_port_ops = {
+	.destruct = rfcomm_dev_destruct,
+};
 
 static struct rfcomm_dev *__rfcomm_dev_get(int id)
 {
@@ -154,7 +148,7 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
 		if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
 			dev = NULL;
 		else
-			rfcomm_dev_hold(dev);
+			tty_port_get(&dev->port);
 	}
 
 	spin_unlock(&rfcomm_dev_lock);
@@ -241,7 +235,6 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 	sprintf(dev->name, "rfcomm%d", dev->id);
 
 	list_add(&dev->list, head);
-	atomic_set(&dev->refcnt, 1);
 
 	bacpy(&dev->src, &req->src);
 	bacpy(&dev->dst, &req->dst);
@@ -253,6 +246,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 	atomic_set(&dev->opened, 0);
 
 	tty_port_init(&dev->port);
+	dev->port.ops = &rfcomm_port_ops;
 	init_waitqueue_head(&dev->wait);
 	INIT_WORK(&dev->wakeup_task, rfcomm_tty_wakeup);
 
@@ -332,7 +326,7 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
 	list_del_init(&dev->list);
 	spin_unlock(&rfcomm_dev_lock);
 
-	rfcomm_dev_put(dev);
+	tty_port_put(&dev->port);
 }
 
 /* ---- Send buffer ---- */
@@ -349,12 +343,12 @@ static void rfcomm_wfree(struct sk_buff *skb)
 	atomic_sub(skb->truesize, &dev->wmem_alloc);
 	if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
 		queue_work(system_nrt_wq, &dev->wakeup_task);
-	rfcomm_dev_put(dev);
+	tty_port_put(&dev->port);
 }
 
 static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
 {
-	rfcomm_dev_hold(dev);
+	tty_port_get(&dev->port);
 	atomic_add(skb->truesize, &dev->wmem_alloc);
 	skb->sk = (void *) dev;
 	skb->destructor = rfcomm_wfree;
@@ -433,7 +427,7 @@ static int rfcomm_release_dev(void __user *arg)
 		return -ENODEV;
 
 	if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
-		rfcomm_dev_put(dev);
+		tty_port_put(&dev->port);
 		return -EPERM;
 	}
 
@@ -446,7 +440,7 @@ static int rfcomm_release_dev(void __user *arg)
 
 	if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
 		rfcomm_dev_del(dev);
-	rfcomm_dev_put(dev);
+	tty_port_put(&dev->port);
 	return 0;
 }
 
@@ -524,7 +518,7 @@ static int rfcomm_get_dev_info(void __user *arg)
 	if (copy_to_user(arg, &di, sizeof(di)))
 		err = -EFAULT;
 
-	rfcomm_dev_put(dev);
+	tty_port_put(&dev->port);
 	return err;
 }
 
@@ -592,7 +586,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
 				 * 1. rfcomm_dev_get will take rfcomm_dev_lock
 				 *    but in rfcomm_dev_add there's lock order:
 				 *    rfcomm_dev_lock -> dlc lock
-				 * 2. rfcomm_dev_put will deadlock if it's
+				 * 2. tty_port_put will deadlock if it's
 				 *    the last reference
 				 */
 				rfcomm_dlc_unlock(dlc);
@@ -602,7 +596,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
 				}
 
 				rfcomm_dev_del(dev);
-				rfcomm_dev_put(dev);
+				tty_port_put(&dev->port);
 				rfcomm_dlc_lock(dlc);
 			}
 		} else
@@ -771,11 +765,11 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
 			list_del_init(&dev->list);
 			spin_unlock(&rfcomm_dev_lock);
 
-			rfcomm_dev_put(dev);
+			tty_port_put(&dev->port);
 		}
 	}
 
-	rfcomm_dev_put(dev);
+	tty_port_put(&dev->port);
 }
 
 static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1084,7 +1078,7 @@ static void rfcomm_tty_hangup(struct tty_struct *tty)
 		if (rfcomm_dev_get(dev->id) == NULL)
 			return;
 		rfcomm_dev_del(dev);
-		rfcomm_dev_put(dev);
+		tty_port_put(&dev->port);
 	}
 }
 
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 68/69] TTY: rfcomm/tty, remove work for tty_wakeup
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (66 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 67/69] TTY: rfcomm/tty, use tty_port refcounting Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  2012-04-02 11:54 ` [PATCH 69/69] TTY: rfcomm/tty, use count from tty_port Jiri Slaby
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby

tty_wakeup is safe to be called from all contexts. No need to schedule
a work for that. Let us call it directly like in other drivers.

This allows us to kill another member of rfcomm_dev structure.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/bluetooth/rfcomm/tty.c |   22 +++-------------------
 1 file changed, 3 insertions(+), 19 deletions(-)

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index da4f545..0433d26 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -65,7 +65,6 @@ struct rfcomm_dev {
 
 	struct rfcomm_dlc	*dlc;
 	wait_queue_head_t       wait;
-	struct work_struct	wakeup_task;
 
 	struct device		*tty_dev;
 
@@ -81,8 +80,6 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
 static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
 static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
 
-static void rfcomm_tty_wakeup(struct work_struct *work);
-
 /* ---- Device functions ---- */
 
 /*
@@ -248,7 +245,6 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 	tty_port_init(&dev->port);
 	dev->port.ops = &rfcomm_port_ops;
 	init_waitqueue_head(&dev->wait);
-	INIT_WORK(&dev->wakeup_task, rfcomm_tty_wakeup);
 
 	skb_queue_head_init(&dev->pending);
 
@@ -340,9 +336,10 @@ static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
 static void rfcomm_wfree(struct sk_buff *skb)
 {
 	struct rfcomm_dev *dev = (void *) skb->sk;
+	struct tty_struct *tty = dev->port.tty;
 	atomic_sub(skb->truesize, &dev->wmem_alloc);
-	if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
-		queue_work(system_nrt_wq, &dev->wakeup_task);
+	if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags) && tty)
+		tty_wakeup(tty);
 	tty_port_put(&dev->port);
 }
 
@@ -625,18 +622,6 @@ static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
 }
 
 /* ---- TTY functions ---- */
-static void rfcomm_tty_wakeup(struct work_struct *work)
-{
-	struct rfcomm_dev *dev = container_of(work, struct rfcomm_dev,
-								wakeup_task);
-	struct tty_struct *tty = dev->port.tty;
-	if (!tty)
-		return;
-
-	BT_DBG("dev %p tty %p", dev, tty);
-	tty_wakeup(tty);
-}
-
 static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev)
 {
 	struct tty_struct *tty = dev->port.tty;
@@ -753,7 +738,6 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
 		rfcomm_dlc_close(dev->dlc, 0);
 
 		clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
-		cancel_work_sync(&dev->wakeup_task);
 
 		rfcomm_dlc_lock(dev->dlc);
 		tty->driver_data = NULL;
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* [PATCH 69/69] TTY: rfcomm/tty, use count from tty_port
  2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
                   ` (67 preceding siblings ...)
  2012-04-02 11:54 ` [PATCH 68/69] TTY: rfcomm/tty, remove work for tty_wakeup Jiri Slaby
@ 2012-04-02 11:54 ` Jiri Slaby
  68 siblings, 0 replies; 81+ messages in thread
From: Jiri Slaby @ 2012-04-02 11:54 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby

This means converting an atomic counter to a counter protected by
lock. This is the first step needed to convert the rest of the code to
the tty_port helpers.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 net/bluetooth/rfcomm/tty.c |   30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 0433d26..d1820ff 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -54,7 +54,6 @@ struct rfcomm_dev {
 	char			name[12];
 	int			id;
 	unsigned long		flags;
-	atomic_t		opened;
 	int			err;
 
 	bdaddr_t		src;
@@ -240,8 +239,6 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 	dev->flags = req->flags &
 		((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
 
-	atomic_set(&dev->opened, 0);
-
 	tty_port_init(&dev->port);
 	dev->port.ops = &rfcomm_port_ops;
 	init_waitqueue_head(&dev->wait);
@@ -311,12 +308,17 @@ free:
 
 static void rfcomm_dev_del(struct rfcomm_dev *dev)
 {
+	unsigned long flags;
 	BT_DBG("dev %p", dev);
 
 	BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
 
-	if (atomic_read(&dev->opened) > 0)
+	spin_lock_irqsave(&dev->port.lock, flags);
+	if (dev->port.count > 0) {
+		spin_unlock_irqrestore(&dev->port.lock, flags);
 		return;
+	}
+	spin_unlock_irqrestore(&dev->port.lock, flags);
 
 	spin_lock(&rfcomm_dev_lock);
 	list_del_init(&dev->list);
@@ -651,6 +653,7 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 	DECLARE_WAITQUEUE(wait, current);
 	struct rfcomm_dev *dev;
 	struct rfcomm_dlc *dlc;
+	unsigned long flags;
 	int err, id;
 
 	id = tty->index;
@@ -666,10 +669,14 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 		return -ENODEV;
 
 	BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
-				dev->channel, atomic_read(&dev->opened));
+				dev->channel, dev->port.count);
 
-	if (atomic_inc_return(&dev->opened) > 1)
+	spin_lock_irqsave(&dev->port.lock, flags);
+	if (++dev->port.count > 1) {
+		spin_unlock_irqrestore(&dev->port.lock, flags);
 		return 0;
+	}
+	spin_unlock_irqrestore(&dev->port.lock, flags);
 
 	dlc = dev->dlc;
 
@@ -724,13 +731,17 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
 {
 	struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
+	unsigned long flags;
+
 	if (!dev)
 		return;
 
 	BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
-						atomic_read(&dev->opened));
+						dev->port.count);
 
-	if (atomic_dec_and_test(&dev->opened)) {
+	spin_lock_irqsave(&dev->port.lock, flags);
+	if (!--dev->port.count) {
+		spin_unlock_irqrestore(&dev->port.lock, flags);
 		if (dev->tty_dev->parent)
 			device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
 
@@ -751,7 +762,8 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
 
 			tty_port_put(&dev->port);
 		}
-	}
+	} else
+		spin_unlock_irqrestore(&dev->port.lock, flags);
 
 	tty_port_put(&dev->port);
 }
-- 
1.7.9.2



^ permalink raw reply related	[flat|nested] 81+ messages in thread

* Re: [PATCH 47/69] TTY: ipwireless, use synchronous hangup
  2012-04-02 11:54 ` [PATCH 47/69] TTY: ipwireless, use synchronous hangup Jiri Slaby
@ 2012-04-02 12:42   ` David Sterba
  0 siblings, 0 replies; 81+ messages in thread
From: David Sterba @ 2012-04-02 12:42 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: gregkh, alan, linux-kernel, jirislaby, Jiri Kosina, David Sterba

Hi,

for the ipwireless bits

[PATCH 47/69] TTY: ipwireless, use synchronous hangup
[PATCH 48/69] TTY: ipwireless, move prints to appropriate places
[PATCH 49/69] TTY: ipwireless, add tty_port
[PATCH 50/69] TTY: ipwireless, use tty from tty_port

Acked-by: David Sterba <dsterba@suse.cz>


thanks,
david

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup
  2012-04-02 11:54 ` [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup Jiri Slaby
@ 2012-04-03  5:42   ` Heiko Carstens
  2012-04-03  7:59     ` Jiri Slaby
  0 siblings, 1 reply; 81+ messages in thread
From: Heiko Carstens @ 2012-04-03  5:42 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: gregkh, alan, linux-kernel, jirislaby, Martin Schwidefsky,
	linux390, linux-s390

On Mon, Apr 02, 2012 at 01:54:09PM +0200, Jiri Slaby wrote:
> tty_wakeup is safe to be called from all contexts. No need to schedule
> a tasklet for that. Let us call it directly like in other drivers.
> 
> And delete the tasklet completely.

Your patch actually reverts Martin's recent commit 656d912537
"[S390] 3215 deadlock with tty_wakeup".
I'm quite sure the reason for the deadlock still exists.
Unfortunately the commit doesn't contain the call chain that
led to fix.


^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 24/69] TTY: con3215, centralize allocation
  2012-04-02 11:54 ` [PATCH 24/69] TTY: con3215, centralize allocation Jiri Slaby
@ 2012-04-03  5:56   ` Heiko Carstens
  0 siblings, 0 replies; 81+ messages in thread
From: Heiko Carstens @ 2012-04-03  5:56 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: gregkh, alan, linux-kernel, jirislaby, Martin Schwidefsky,
	linux390, linux-s390

On Mon, Apr 02, 2012 at 01:54:08PM +0200, Jiri Slaby wrote:
> There are two copies of allocations of device information. One of them
> is totally broken. See:
> raw->cdev = cdev;
> raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
> memset(raw, 0, sizeof(struct raw3215_info));
> 
> It suggests that this path was never executed. The code uses both
> raw->cdev and raw->inbuf all over. And it is NULL due to the memset
> here, so it would panic immediately. I believe nobody used that driver
> without being a system console.
> 
> Either way, let us fix it by moving the allocations (and
> initializations) to a single place. This will save us some double
> initializations later too.
> 
> And while at it, initialize the timer properly -- once, at the
> allocation.
> 
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
> Cc: linux390@de.ibm.com
> Cc: linux-s390@vger.kernel.org
> ---
>  drivers/s390/char/con3215.c |   74 +++++++++++++++++++++++--------------------
>  1 file changed, 39 insertions(+), 35 deletions(-)

Nice!

Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>


^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup
  2012-04-03  5:42   ` Heiko Carstens
@ 2012-04-03  7:59     ` Jiri Slaby
  2012-04-09 18:27       ` Greg KH
  0 siblings, 1 reply; 81+ messages in thread
From: Jiri Slaby @ 2012-04-03  7:59 UTC (permalink / raw)
  To: Heiko Carstens
  Cc: gregkh, alan, linux-kernel, jirislaby, Martin Schwidefsky,
	linux390, linux-s390

On 04/03/2012 07:42 AM, Heiko Carstens wrote:
> On Mon, Apr 02, 2012 at 01:54:09PM +0200, Jiri Slaby wrote:
>> tty_wakeup is safe to be called from all contexts. No need to schedule
>> a tasklet for that. Let us call it directly like in other drivers.
>>
>> And delete the tasklet completely.
> 
> Your patch actually reverts Martin's recent commit 656d912537
> "[S390] 3215 deadlock with tty_wakeup".
> I'm quite sure the reason for the deadlock still exists.
> Unfortunately the commit doesn't contain the call chain that
> led to fix.

Ok, I would really appreciate the trace.

If this is really an issue, we should provide a helper in the TTY layer
like tty_schedule_wakeup.

thanks,
-- 
js
suse labs



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 02/69] TTY: crisv10, initialize tty_port
  2012-04-02 11:53 ` [PATCH 02/69] TTY: crisv10, initialize tty_port Jiri Slaby
@ 2012-04-03 11:47   ` Jesper Nilsson
  0 siblings, 0 replies; 81+ messages in thread
From: Jesper Nilsson @ 2012-04-03 11:47 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: gregkh, alan, linux-kernel, jirislaby, Mikael Starvik, linux-cris-kernel

On Mon, Apr 02, 2012 at 01:53:46PM +0200, Jiri Slaby wrote:
> The tty_port used in the driver is left uninitialized. Add the
> initialization there.
> 
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Cc: Mikael Starvik <starvik@axis.com>

Looks good!

Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>

> Cc: linux-cris-kernel@axis.com
> ---
>  drivers/tty/serial/crisv10.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c
> index 004ee2e..80b6b1b 100644
> --- a/drivers/tty/serial/crisv10.c
> +++ b/drivers/tty/serial/crisv10.c
> @@ -4462,6 +4462,7 @@ static int __init rs_init(void)
>  				info->enabled = 0;
>  			}
>  		}
> +		tty_port_init(&info->port);
>  		info->uses_dma_in = 0;
>  		info->uses_dma_out = 0;
>  		info->line = i;
> -- 
> 1.7.9.2
> 
/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson@axis.com

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 01/69] TTY: crisv10, remove unused tmp_buf
  2012-04-02 11:53 ` [PATCH 01/69] TTY: crisv10, remove unused tmp_buf Jiri Slaby
@ 2012-04-03 11:47   ` Jesper Nilsson
  0 siblings, 0 replies; 81+ messages in thread
From: Jesper Nilsson @ 2012-04-03 11:47 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: gregkh, alan, linux-kernel, jirislaby, Mikael Starvik, linux-cris-kernel

On Mon, Apr 02, 2012 at 01:53:45PM +0200, Jiri Slaby wrote:
> This used to be a helper buffer for generic_serial. generic_serial is
> gone, tmp_buf shall be removed.
> 
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Cc: Mikael Starvik <starvik@axis.com>

Looks good!

Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>

> Cc: linux-cris-kernel@axis.com
> ---
>  drivers/tty/serial/crisv10.c |   27 +--------------------------
>  1 file changed, 1 insertion(+), 26 deletions(-)
> 
> diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c
> index 5b07c0c..004ee2e 100644
> --- a/drivers/tty/serial/crisv10.c
> +++ b/drivers/tty/serial/crisv10.c
> @@ -952,19 +952,6 @@ static const struct control_pins e100_modem_pins[NR_PORTS] =
>  /* Input */
>  #define E100_DSR_GET(info) ((*e100_modem_pins[(info)->line].dsr_port) & e100_modem_pins[(info)->line].dsr_mask)
>  
> -
> -/*
> - * tmp_buf is used as a temporary buffer by serial_write.  We need to
> - * lock it in case the memcpy_fromfs blocks while swapping in a page,
> - * and some other program tries to do a serial write at the same time.
> - * Since the lock will only come under contention when the system is
> - * swapping and available memory is low, it makes sense to share one
> - * buffer across all the serial ports, since it significantly saves
> - * memory if large numbers of serial ports are open.
> - */
> -static unsigned char *tmp_buf;
> -static DEFINE_MUTEX(tmp_buf_mutex);
> -
>  /* Calculate the chartime depending on baudrate, numbor of bits etc. */
>  static void update_char_time(struct e100_serial * info)
>  {
> @@ -3150,7 +3137,7 @@ static int rs_raw_write(struct tty_struct *tty,
>  
>  	/* first some sanity checks */
>  
> -	if (!tty || !info->xmit.buf || !tmp_buf)
> +	if (!tty || !info->xmit.buf)
>  		return 0;
>  
>  #ifdef SERIAL_DEBUG_DATA
> @@ -4106,7 +4093,6 @@ rs_open(struct tty_struct *tty, struct file * filp)
>  {
>  	struct e100_serial	*info;
>  	int 			retval;
> -	unsigned long           page;
>  	int                     allocated_resources = 0;
>  
>  	info = rs_table + tty->index;
> @@ -4124,17 +4110,6 @@ rs_open(struct tty_struct *tty, struct file * filp)
>  
>  	tty->low_latency = !!(info->flags & ASYNC_LOW_LATENCY);
>  
> -	if (!tmp_buf) {
> -		page = get_zeroed_page(GFP_KERNEL);
> -		if (!page) {
> -			return -ENOMEM;
> -		}
> -		if (tmp_buf)
> -			free_page(page);
> -		else
> -			tmp_buf = (unsigned char *) page;
> -	}
> -
>  	/*
>  	 * If the port is in the middle of closing, bail out now
>  	 */
> -- 
> 1.7.9.2
> 
/^JN - Jesper Nilsson
-- 
               Jesper Nilsson -- jesper.nilsson@axis.com

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 51/69] TTY: 68328serial, remove serial_state and friends
  2012-04-02 11:54 ` [PATCH 51/69] TTY: 68328serial, remove serial_state and friends Jiri Slaby
@ 2012-04-03 12:48   ` Geert Uytterhoeven
  0 siblings, 0 replies; 81+ messages in thread
From: Geert Uytterhoeven @ 2012-04-03 12:48 UTC (permalink / raw)
  To: linux-m68k, Greg Ungerer; +Cc: gregkh, alan, linux-kernel, jirislaby

[ Added Greg as this is m68knommu territory, but I guess he go all 12 patches
  through linux-m68k anyway ]

On Mon, Apr 2, 2012 at 13:54, Jiri Slaby <jslaby@suse.cz> wrote:
> serial_state in 68328serial.h is a duplicated structure. One is
> defined in linux/serial.h. So let us use that instead. And since the
> serial flags are identical, use ones from there too.
>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: linux-m68k@lists.linux-m68k.org
> ---
>  drivers/tty/serial/68328serial.c |   55 +++++++++++----------------
>  drivers/tty/serial/68328serial.h |   76 --------------------------------------
>  2 files changed, 22 insertions(+), 109 deletions(-)
>
> diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
> index 5ce7825..bf5f811 100644
> --- a/drivers/tty/serial/68328serial.c
> +++ b/drivers/tty/serial/68328serial.c
> @@ -17,6 +17,7 @@
>  #include <asm/dbg.h>
>  #include <linux/module.h>
>  #include <linux/errno.h>
> +#include <linux/serial.h>
>  #include <linux/signal.h>
>  #include <linux/sched.h>
>  #include <linux/timer.h>
> @@ -79,18 +80,6 @@ struct m68k_serial *m68k_consinfo = 0;
>
>  struct tty_driver *serial_driver;
>
> -/* number of characters left in xmit buffer before we ask for more */
> -#define WAKEUP_CHARS 256
> -
> -/* Debugging... DEBUG_INTR is bad to use when one of the zs
> - * lines is your console ;(
> - */
> -#undef SERIAL_DEBUG_INTR
> -#undef SERIAL_DEBUG_OPEN
> -#undef SERIAL_DEBUG_FLOW
> -
> -#define RS_ISR_PASS_LIMIT 256
> -
>  static void change_speed(struct m68k_serial *info);
>
>  /*
> @@ -363,7 +352,7 @@ static int startup(struct m68k_serial * info)
>        m68328_uart *uart = &uart_addr[info->line];
>        unsigned long flags;
>
> -       if (info->flags & S_INITIALIZED)
> +       if (info->flags & ASYNC_INITIALIZED)
>                return 0;
>
>        if (!info->xmit_buf) {
> @@ -404,7 +393,7 @@ static int startup(struct m68k_serial * info)
>
>        change_speed(info);
>
> -       info->flags |= S_INITIALIZED;
> +       info->flags |= ASYNC_INITIALIZED;
>        local_irq_restore(flags);
>        return 0;
>  }
> @@ -419,7 +408,7 @@ static void shutdown(struct m68k_serial * info)
>        unsigned long   flags;
>
>        uart->ustcnt = 0; /* All off! */
> -       if (!(info->flags & S_INITIALIZED))
> +       if (!(info->flags & ASYNC_INITIALIZED))
>                return;
>
>        local_irq_save(flags);
> @@ -432,7 +421,7 @@ static void shutdown(struct m68k_serial * info)
>        if (info->tty)
>                set_bit(TTY_IO_ERROR, &info->tty->flags);
>
> -       info->flags &= ~S_INITIALIZED;
> +       info->flags &= ~ASYNC_INITIALIZED;
>        local_irq_restore(flags);
>  }
>
> @@ -835,11 +824,11 @@ static int set_serial_info(struct m68k_serial * info,
>                if ((new_serial.baud_base != info->baud_base) ||
>                    (new_serial.type != info->type) ||
>                    (new_serial.close_delay != info->close_delay) ||
> -                   ((new_serial.flags & ~S_USR_MASK) !=
> -                    (info->flags & ~S_USR_MASK)))
> +                   ((new_serial.flags & ~ASYNC_USR_MASK) !=
> +                    (info->flags & ~ASYNC_USR_MASK)))
>                        return -EPERM;
> -               info->flags = ((info->flags & ~S_USR_MASK) |
> -                              (new_serial.flags & S_USR_MASK));
> +               info->flags = ((info->flags & ~ASYNC_USR_MASK) |
> +                              (new_serial.flags & ASYNC_USR_MASK));
>                info->custom_divisor = new_serial.custom_divisor;
>                goto check_and_exit;
>        }
> @@ -853,8 +842,8 @@ static int set_serial_info(struct m68k_serial * info,
>         */
>
>        info->baud_base = new_serial.baud_base;
> -       info->flags = ((info->flags & ~S_FLAGS) |
> -                       (new_serial.flags & S_FLAGS));
> +       info->flags = ((info->flags & ~ASYNC_FLAGS) |
> +                       (new_serial.flags & ASYNC_FLAGS));
>        info->type = new_serial.type;
>        info->close_delay = new_serial.close_delay;
>        info->closing_wait = new_serial.closing_wait;
> @@ -1022,13 +1011,13 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
>                local_irq_restore(flags);
>                return;
>        }
> -       info->flags |= S_CLOSING;
> +       info->flags |= ASYNC_CLOSING;
>        /*
>         * Now we wait for the transmit buffer to clear; and we notify
>         * the line discipline to only process XON/XOFF characters.
>         */
>        tty->closing = 1;
> -       if (info->closing_wait != S_CLOSING_WAIT_NONE)
> +       if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
>                tty_wait_until_sent(tty, info->closing_wait);
>        /*
>         * At this point we stop accepting input.  To do this, we
> @@ -1064,7 +1053,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
>                }
>                wake_up_interruptible(&info->open_wait);
>        }
> -       info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING);
> +       info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
>        wake_up_interruptible(&info->close_wait);
>        local_irq_restore(flags);
>  }
> @@ -1083,7 +1072,7 @@ void rs_hangup(struct tty_struct *tty)
>        shutdown(info);
>        info->event = 0;
>        info->count = 0;
> -       info->flags &= ~S_NORMAL_ACTIVE;
> +       info->flags &= ~ASYNC_NORMAL_ACTIVE;
>        info->tty = NULL;
>        wake_up_interruptible(&info->open_wait);
>  }
> @@ -1104,10 +1093,10 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
>         * If the device is in the middle of being closed, then block
>         * until it's done, and then try again.
>         */
> -       if (info->flags & S_CLOSING) {
> +       if (info->flags & ASYNC_CLOSING) {
>                interruptible_sleep_on(&info->close_wait);
>  #ifdef SERIAL_DO_RESTART
> -               if (info->flags & S_HUP_NOTIFY)
> +               if (info->flags & ASYNC_HUP_NOTIFY)
>                        return -EAGAIN;
>                else
>                        return -ERESTARTSYS;
> @@ -1122,7 +1111,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
>         */
>        if ((filp->f_flags & O_NONBLOCK) ||
>            (tty->flags & (1 << TTY_IO_ERROR))) {
> -               info->flags |= S_NORMAL_ACTIVE;
> +               info->flags |= ASYNC_NORMAL_ACTIVE;
>                return 0;
>        }
>
> @@ -1147,9 +1136,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
>                local_irq_enable();
>                current->state = TASK_INTERRUPTIBLE;
>                if (tty_hung_up_p(filp) ||
> -                   !(info->flags & S_INITIALIZED)) {
> +                   !(info->flags & ASYNC_INITIALIZED)) {
>  #ifdef SERIAL_DO_RESTART
> -                       if (info->flags & S_HUP_NOTIFY)
> +                       if (info->flags & ASYNC_HUP_NOTIFY)
>                                retval = -EAGAIN;
>                        else
>                                retval = -ERESTARTSYS;
> @@ -1158,7 +1147,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
>  #endif
>                        break;
>                }
> -               if (!(info->flags & S_CLOSING) && do_clocal)
> +               if (!(info->flags & ASYNC_CLOSING) && do_clocal)
>                        break;
>                 if (signal_pending(current)) {
>                        retval = -ERESTARTSYS;
> @@ -1176,7 +1165,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
>
>        if (retval)
>                return retval;
> -       info->flags |= S_NORMAL_ACTIVE;
> +       info->flags |= ASYNC_NORMAL_ACTIVE;
>        return 0;
>  }
>
> diff --git a/drivers/tty/serial/68328serial.h b/drivers/tty/serial/68328serial.h
> index 3d2faab..a804ea5 100644
> --- a/drivers/tty/serial/68328serial.h
> +++ b/drivers/tty/serial/68328serial.h
> @@ -11,69 +11,6 @@
>  #ifndef _MC683XX_SERIAL_H
>  #define _MC683XX_SERIAL_H
>
> -
> -struct serial_struct {
> -       int     type;
> -       int     line;
> -       int     port;
> -       int     irq;
> -       int     flags;
> -       int     xmit_fifo_size;
> -       int     custom_divisor;
> -       int     baud_base;
> -       unsigned short  close_delay;
> -       char    reserved_char[2];
> -       int     hub6;  /* FIXME: We don't have AT&T Hub6 boards! */
> -       unsigned short  closing_wait; /* time to wait before closing */
> -       unsigned short  closing_wait2; /* no longer used... */
> -       int     reserved[4];
> -};
> -
> -/*
> - * For the close wait times, 0 means wait forever for serial port to
> - * flush its output.  65535 means don't wait at all.
> - */
> -#define S_CLOSING_WAIT_INF     0
> -#define S_CLOSING_WAIT_NONE    65535
> -
> -/*
> - * Definitions for S_struct (and serial_struct) flags field
> - */
> -#define S_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes
> -                                  on the callout port */
> -#define S_FOURPORT  0x0002     /* Set OU1, OUT2 per AST Fourport settings */
> -#define S_SAK  0x0004  /* Secure Attention Key (Orange book) */
> -#define S_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
> -
> -#define S_SPD_MASK     0x0030
> -#define S_SPD_HI       0x0010  /* Use 56000 instead of 38400 bps */
> -
> -#define S_SPD_VHI      0x0020  /* Use 115200 instead of 38400 bps */
> -#define S_SPD_CUST     0x0030  /* Use user-specified divisor */
> -
> -#define S_SKIP_TEST    0x0040 /* Skip UART test during autoconfiguration */
> -#define S_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
> -#define S_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
> -#define S_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
> -#define S_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
> -
> -#define S_FLAGS        0x0FFF  /* Possible legal S flags */
> -#define S_USR_MASK 0x0430      /* Legal flags that non-privileged
> -                                * users can set or reset */
> -
> -/* Internal flags used only by kernel/chr_drv/serial.c */
> -#define S_INITIALIZED  0x80000000 /* Serial port was initialized */
> -#define S_CALLOUT_ACTIVE       0x40000000 /* Call out device is active */
> -#define S_NORMAL_ACTIVE        0x20000000 /* Normal device is active */
> -#define S_BOOT_AUTOCONF        0x10000000 /* Autoconfigure port on bootup */
> -#define S_CLOSING              0x08000000 /* Serial port is closing */
> -#define S_CTS_FLOW             0x04000000 /* Do CTS flow control */
> -#define S_CHECK_CD             0x02000000 /* i.e., CLOCAL */
> -
> -/* Software state per channel */
> -
> -#ifdef __KERNEL__
> -
>  /*
>  * I believe this is the optimal setting that reduces the number of interrupts.
>  * At high speeds the output might become a little "bursted" (use USTCNT_TXHE
> @@ -162,25 +99,12 @@ struct m68k_serial {
>        wait_queue_head_t       close_wait;
>  };
>
> -
>  #define SERIAL_MAGIC 0x5301
>
> -/*
> - * The size of the serial xmit buffer is 1 page, or 4096 bytes
> - */
> -#define SERIAL_XMIT_SIZE 4096
> -
> -/*
> - * Events are used to schedule things to happen at timer-interrupt
> - * time, instead of at rs interrupt time.
> - */
> -#define RS_EVENT_WRITE_WAKEUP  0
> -
>  /*
>  * Define the number of ports supported and their irqs.
>  */
>  #define NR_PORTS 1
>  #define UART_IRQ_DEFNS {UART_IRQ_NUM}
>
> -#endif /* __KERNEL__ */
>  #endif /* !(_MC683XX_SERIAL_H) */
> --
> 1.7.9.2

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 62/69] TTY: 68328serial, use tty_port_block_til_ready
  2012-04-02 11:54 ` [PATCH 62/69] TTY: 68328serial, use tty_port_block_til_ready Jiri Slaby
@ 2012-04-04 12:25   ` Greg Ungerer
  0 siblings, 0 replies; 81+ messages in thread
From: Greg Ungerer @ 2012-04-04 12:25 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: gregkh, alan, linux-kernel, jirislaby, Geert Uytterhoeven, linux-m68k

Hi Jiri,

On 04/02/2012 09:54 PM, Jiri Slaby wrote:
> Since the code is identical, use the tty_port_block_til_ready helper
> instead of re-implemented variant.
>
> The code does not perform rtsdts handling, hence we do not need to
> provide tty port hooks for them. The default ones will be used
> instead. The only necessary thing is to provide tty_port_operations.
> It is empty, but has to be there...
>
> Signed-off-by: Jiri Slaby<jslaby@suse.cz>
> Cc: Geert Uytterhoeven<geert@linux-m68k.org>
> Cc: linux-m68k@lists.linux-m68k.org

I have no problem with any of the 12 patches that work on 68328serial.
So for me:

Acked-by: Greg Ungerer <gerg@uclinux.org>

I myself have nothing to test it on though.

Really the only thing remaining is to convert it to a new style serial
driver. Don't suppose you want to take that on :-)

Regards
Greg



> ---
>   drivers/tty/serial/68328serial.c |   96 ++------------------------------------
>   1 file changed, 5 insertions(+), 91 deletions(-)
>
> diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c
> index 77e10bb..3ed20e4 100644
> --- a/drivers/tty/serial/68328serial.c
> +++ b/drivers/tty/serial/68328serial.c
> @@ -1104,96 +1104,6 @@ void rs_hangup(struct tty_struct *tty)
>   }
>
>   /*
> - * ------------------------------------------------------------
> - * rs_open() and friends
> - * ------------------------------------------------------------
> - */
> -static int block_til_ready(struct tty_struct *tty, struct file * filp,
> -			   struct m68k_serial *info)
> -{
> -	struct tty_port *port =&info->tport;
> -	DECLARE_WAITQUEUE(wait, current);
> -	int		retval;
> -	int		do_clocal = 0;
> -
> -	/*
> -	 * If the device is in the middle of being closed, then block
> -	 * until it's done, and then try again.
> -	 */
> -	if (port->flags&  ASYNC_CLOSING) {
> -		interruptible_sleep_on(&port->close_wait);
> -#ifdef SERIAL_DO_RESTART
> -		if (port->flags&  ASYNC_HUP_NOTIFY)
> -			return -EAGAIN;
> -		else
> -			return -ERESTARTSYS;
> -#else
> -		return -EAGAIN;
> -#endif
> -	}
> -	
> -	/*
> -	 * If non-blocking mode is set, or the port is not enabled,
> -	 * then make the check up front and then exit.
> -	 */
> -	if ((filp->f_flags&  O_NONBLOCK) ||
> -	    (tty->flags&  (1<<  TTY_IO_ERROR))) {
> -		port->flags |= ASYNC_NORMAL_ACTIVE;
> -		return 0;
> -	}
> -
> -	if (tty->termios->c_cflag&  CLOCAL)
> -		do_clocal = 1;
> -
> -	/*
> -	 * Block waiting for the carrier detect and the line to become
> -	 * free (i.e., not in use by the callout).  While we are in
> -	 * this loop, port->count is dropped by one, so that
> -	 * rs_close() knows when to free things.  We restore it upon
> -	 * exit, either normal or abnormal.
> -	 */
> -	retval = 0;
> -	add_wait_queue(&port->open_wait,&wait);
> -
> -	port->count--;
> -	port->blocked_open++;
> -	while (1) {
> -		current->state = TASK_INTERRUPTIBLE;
> -		if (tty_hung_up_p(filp) ||
> -		    !(port->flags&  ASYNC_INITIALIZED)) {
> -#ifdef SERIAL_DO_RESTART
> -			if (port->flags&  ASYNC_HUP_NOTIFY)
> -				retval = -EAGAIN;
> -			else
> -				retval = -ERESTARTSYS;	
> -#else
> -			retval = -EAGAIN;
> -#endif
> -			break;
> -		}
> -		if (!(port->flags&  ASYNC_CLOSING)&&  do_clocal)
> -			break;
> -                if (signal_pending(current)) {
> -			retval = -ERESTARTSYS;
> -			break;
> -		}
> -		tty_unlock();
> -		schedule();
> -		tty_lock();
> -	}
> -	current->state = TASK_RUNNING;
> -	remove_wait_queue(&port->open_wait,&wait);
> -	if (!tty_hung_up_p(filp))
> -		port->count++;
> -	port->blocked_open--;
> -
> -	if (retval)
> -		return retval;
> -	port->flags |= ASYNC_NORMAL_ACTIVE;
> -	return 0;
> -}	
> -
> -/*
>    * This routine is called whenever a serial port is opened.  It
>    * enables interrupts for a serial port, linking in its S structure into
>    * the IRQ chain.   It also performs the serial-specific
> @@ -1220,7 +1130,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
>   	if (retval)
>   		return retval;
>
> -	return block_til_ready(tty, filp, info);
> +	return tty_port_block_til_ready(&info->tport, tty, filp);
>   }
>
>   /* Finally, routines used to initialize the serial driver. */
> @@ -1248,6 +1158,9 @@ static const struct tty_operations rs_ops = {
>   	.set_ldisc = rs_set_ldisc,
>   };
>
> +static const struct tty_port_operations rs_port_ops = {
> +};
> +
>   /* rs_init inits the driver */
>   static int __init
>   rs68328_init(void)
> @@ -1288,6 +1201,7 @@ rs68328_init(void)
>
>   	    info =&m68k_soft[i];
>   	    tty_port_init(&info->tport);
> +	    info->tport.ops =&rs_port_ops;
>   	    info->magic = SERIAL_MAGIC;
>   	    info->port = (int)&uart_addr[i];
>   	    info->irq = uart_irqs[i];


-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg@snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close,                            FAX:         +61 7 3891 3630
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup
  2012-04-03  7:59     ` Jiri Slaby
@ 2012-04-09 18:27       ` Greg KH
  2012-04-09 18:30         ` Jiri Slaby
  0 siblings, 1 reply; 81+ messages in thread
From: Greg KH @ 2012-04-09 18:27 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Heiko Carstens, alan, linux-kernel, jirislaby,
	Martin Schwidefsky, linux390, linux-s390

On Tue, Apr 03, 2012 at 09:59:19AM +0200, Jiri Slaby wrote:
> On 04/03/2012 07:42 AM, Heiko Carstens wrote:
> > On Mon, Apr 02, 2012 at 01:54:09PM +0200, Jiri Slaby wrote:
> >> tty_wakeup is safe to be called from all contexts. No need to schedule
> >> a tasklet for that. Let us call it directly like in other drivers.
> >>
> >> And delete the tasklet completely.
> > 
> > Your patch actually reverts Martin's recent commit 656d912537
> > "[S390] 3215 deadlock with tty_wakeup".
> > I'm quite sure the reason for the deadlock still exists.
> > Unfortunately the commit doesn't contain the call chain that
> > led to fix.
> 
> Ok, I would really appreciate the trace.
> 
> If this is really an issue, we should provide a helper in the TTY layer
> like tty_schedule_wakeup.

Jiri, should I not apply this patch?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup
  2012-04-09 18:27       ` Greg KH
@ 2012-04-09 18:30         ` Jiri Slaby
  2012-04-09 19:07           ` Greg KH
  0 siblings, 1 reply; 81+ messages in thread
From: Jiri Slaby @ 2012-04-09 18:30 UTC (permalink / raw)
  To: Greg KH
  Cc: Heiko Carstens, alan, linux-kernel, jirislaby,
	Martin Schwidefsky, linux390, linux-s390

On 04/09/2012 08:27 PM, Greg KH wrote:
> On Tue, Apr 03, 2012 at 09:59:19AM +0200, Jiri Slaby wrote:
>> On 04/03/2012 07:42 AM, Heiko Carstens wrote:
>>> On Mon, Apr 02, 2012 at 01:54:09PM +0200, Jiri Slaby wrote:
>>>> tty_wakeup is safe to be called from all contexts. No need to schedule
>>>> a tasklet for that. Let us call it directly like in other drivers.
>>>>
>>>> And delete the tasklet completely.
>>>
>>> Your patch actually reverts Martin's recent commit 656d912537
>>> "[S390] 3215 deadlock with tty_wakeup".
>>> I'm quite sure the reason for the deadlock still exists.
>>> Unfortunately the commit doesn't contain the call chain that
>>> led to fix.
>>
>> Ok, I would really appreciate the trace.
>>
>> If this is really an issue, we should provide a helper in the TTY layer
>> like tty_schedule_wakeup.
> 
> Jiri, should I not apply this patch?

Yes, please skip it until this is sorted out. And also the other con3215
patches if they don't apply cleanly now.

thanks,
-- 
js
suse labs



^ permalink raw reply	[flat|nested] 81+ messages in thread

* Re: [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup
  2012-04-09 18:30         ` Jiri Slaby
@ 2012-04-09 19:07           ` Greg KH
  0 siblings, 0 replies; 81+ messages in thread
From: Greg KH @ 2012-04-09 19:07 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Heiko Carstens, alan, linux-kernel, jirislaby,
	Martin Schwidefsky, linux390, linux-s390

On Mon, Apr 09, 2012 at 08:30:23PM +0200, Jiri Slaby wrote:
> On 04/09/2012 08:27 PM, Greg KH wrote:
> > On Tue, Apr 03, 2012 at 09:59:19AM +0200, Jiri Slaby wrote:
> >> On 04/03/2012 07:42 AM, Heiko Carstens wrote:
> >>> On Mon, Apr 02, 2012 at 01:54:09PM +0200, Jiri Slaby wrote:
> >>>> tty_wakeup is safe to be called from all contexts. No need to schedule
> >>>> a tasklet for that. Let us call it directly like in other drivers.
> >>>>
> >>>> And delete the tasklet completely.
> >>>
> >>> Your patch actually reverts Martin's recent commit 656d912537
> >>> "[S390] 3215 deadlock with tty_wakeup".
> >>> I'm quite sure the reason for the deadlock still exists.
> >>> Unfortunately the commit doesn't contain the call chain that
> >>> led to fix.
> >>
> >> Ok, I would really appreciate the trace.
> >>
> >> If this is really an issue, we should provide a helper in the TTY layer
> >> like tty_schedule_wakeup.
> > 
> > Jiri, should I not apply this patch?
> 
> Yes, please skip it until this is sorted out. And also the other con3215
> patches if they don't apply cleanly now.

Ok, I've not applied patches 25, 26, and 27 in this series, but have
applied all others, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 81+ messages in thread

end of thread, other threads:[~2012-04-09 19:07 UTC | newest]

Thread overview: 81+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-02 11:53 [PATCH 00/69] TTY buffer in tty_port -- prep no. 2 Jiri Slaby
2012-04-02 11:53 ` [PATCH 01/69] TTY: crisv10, remove unused tmp_buf Jiri Slaby
2012-04-03 11:47   ` Jesper Nilsson
2012-04-02 11:53 ` [PATCH 02/69] TTY: crisv10, initialize tty_port Jiri Slaby
2012-04-03 11:47   ` Jesper Nilsson
2012-04-02 11:53 ` [PATCH 03/69] TTY: deprecate linux/generic_serial.h Jiri Slaby
2012-04-02 11:53 ` [PATCH 04/69] ISDN: i4l, remove cvs crap Jiri Slaby
2012-04-02 11:53 ` [PATCH 05/69] TTY: isdn, remove callout Jiri Slaby
2012-04-02 11:53 ` [PATCH 06/69] TTY: isdn, remove ISDN_ASYNC_* flags Jiri Slaby
2012-04-02 11:53 ` [PATCH 07/69] TTY: isdn, do not play with module refcounts Jiri Slaby
2012-04-02 11:53 ` [PATCH 08/69] TTY: isdn, make some functions readable Jiri Slaby
2012-04-02 11:53 ` [PATCH 09/69] TTY: isdn, remove unused members from modem_info Jiri Slaby
2012-04-02 11:53 ` [PATCH 10/69] TTY: isdn, add tty_port Jiri Slaby
2012-04-02 11:53 ` [PATCH 11/69] TTY: isdn, use open/close_wait from tty_port Jiri Slaby
2012-04-02 11:53 ` [PATCH 12/69] TTY: isdn, use counts " Jiri Slaby
2012-04-02 11:53 ` [PATCH 13/69] TTY: isdn, use tty " Jiri Slaby
2012-04-02 11:53 ` [PATCH 14/69] TTY: isdn, use xmit_buf " Jiri Slaby
2012-04-02 11:53 ` [PATCH 15/69] TTY: isdn, define local tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 16/69] TTY: isdn, use tty_port_close_end helper Jiri Slaby
2012-04-02 11:54 ` [PATCH 17/69] TTY: isdn, define tty_port_operations Jiri Slaby
2012-04-02 11:54 ` [PATCH 18/69] TTY: isdn, use tty_port_block_til_ready helper Jiri Slaby
2012-04-02 11:54 ` [PATCH 19/69] TTY: hso, do not set TTY MAGIC Jiri Slaby
2012-04-02 11:54 ` [PATCH 20/69] TTY: hso, free tty_driver Jiri Slaby
2012-04-02 11:54 ` [PATCH 21/69] TTY: hso, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 22/69] TTY: hso, remove tty NULL checks fro tty->ops Jiri Slaby
2012-04-02 11:54 ` [PATCH 23/69] TTY: hso, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 24/69] TTY: con3215, centralize allocation Jiri Slaby
2012-04-03  5:56   ` Heiko Carstens
2012-04-02 11:54 ` [PATCH 25/69] TTY: con3215, remove tasklet for tty_wakeup Jiri Slaby
2012-04-03  5:42   ` Heiko Carstens
2012-04-03  7:59     ` Jiri Slaby
2012-04-09 18:27       ` Greg KH
2012-04-09 18:30         ` Jiri Slaby
2012-04-09 19:07           ` Greg KH
2012-04-02 11:54 ` [PATCH 26/69] TTY: con3215, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 27/69] TTY: con3215, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 28/69] TTY: sclp_tty, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 29/69] TTY: sclp_vt220, " Jiri Slaby
2012-04-02 11:54 ` [PATCH 30/69] TTY: sclp_vt220, remove unused allocation Jiri Slaby
2012-04-02 11:54 ` [PATCH 31/69] TTY: tty3270, move initialization to allocation Jiri Slaby
2012-04-02 11:54 ` [PATCH 32/69] TTY: tty3270, get rid of ugly aliasing Jiri Slaby
2012-04-02 11:54 ` [PATCH 33/69] TTY: tty3270, push tty down to tty3270_do_write Jiri Slaby
2012-04-02 11:54 ` [PATCH 34/69] TTY: tty3270, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 35/69] TTY: bfin_jtag_comm, " Jiri Slaby
2012-04-02 11:54 ` [PATCH 36/69] TTY: bfin_jtag_comm, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 37/69] TTY: HVC, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 38/69] TTY: HVC, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 39/69] TTY: HVC, use count " Jiri Slaby
2012-04-02 11:54 ` [PATCH 40/69] TTY: hvcs, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 41/69] TTY: hvcs, use kref from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 42/69] TTY: hvcs, use tty " Jiri Slaby
2012-04-02 11:54 ` [PATCH 43/69] TTY: hvsi, CLOCAL is not in tty->flags Jiri Slaby
2012-04-02 11:54 ` [PATCH 44/69] TTY: hvsi, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 45/69] TTY: hvsi, sanitize uses of tty Jiri Slaby
2012-04-02 11:54 ` [PATCH 46/69] TTY: hvsi, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 47/69] TTY: ipwireless, use synchronous hangup Jiri Slaby
2012-04-02 12:42   ` David Sterba
2012-04-02 11:54 ` [PATCH 48/69] TTY: ipwireless, move prints to appropriate places Jiri Slaby
2012-04-02 11:54 ` [PATCH 49/69] TTY: ipwireless, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 50/69] TTY: ipwireless, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 51/69] TTY: 68328serial, remove serial_state and friends Jiri Slaby
2012-04-03 12:48   ` Geert Uytterhoeven
2012-04-02 11:54 ` [PATCH 52/69] TTY: 68328serial, remove unused stuff from m68k_serial Jiri Slaby
2012-04-02 11:54 ` [PATCH 53/69] TTY: 68328serial, remove garbage Jiri Slaby
2012-04-02 11:54 ` [PATCH 54/69] TTY: 68328serial, use ulong flags for interrupts status Jiri Slaby
2012-04-02 11:54 ` [PATCH 55/69] TTY: 68328serial, remove 68328serial.h Jiri Slaby
2012-04-02 11:54 ` [PATCH 56/69] TTY: 68328serial, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 57/69] TTY: 68328serial, use open/close_wait from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 58/69] TTY: 68328serial, use close_delay/closing_wait " Jiri Slaby
2012-04-02 11:54 ` [PATCH 59/69] TTY: 68328serial, use flags " Jiri Slaby
2012-04-02 11:54 ` [PATCH 60/69] TTY: 68328serial, propagate tty Jiri Slaby
2012-04-02 11:54 ` [PATCH 61/69] TTY: 68328serial, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 62/69] TTY: 68328serial, use tty_port_block_til_ready Jiri Slaby
2012-04-04 12:25   ` Greg Ungerer
2012-04-02 11:54 ` [PATCH 63/69] TTY: usb/u_serial, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 64/69] TTY: usb/u_serial, use tty from tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 65/69] TTY: usb/u_serial use close_wait " Jiri Slaby
2012-04-02 11:54 ` [PATCH 66/69] TTY: rfcomm/tty, add tty_port Jiri Slaby
2012-04-02 11:54 ` [PATCH 67/69] TTY: rfcomm/tty, use tty_port refcounting Jiri Slaby
2012-04-02 11:54 ` [PATCH 68/69] TTY: rfcomm/tty, remove work for tty_wakeup Jiri Slaby
2012-04-02 11:54 ` [PATCH 69/69] TTY: rfcomm/tty, use count from tty_port Jiri Slaby

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).