netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 02/24] TTY: ircomm, add tty_port
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
@ 2012-06-04 11:35 ` Jiri Slaby
  2012-06-04 11:35 ` [PATCH 03/24] TTY: ircomm, use close times from tty_port Jiri Slaby
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

And use close/open_wait from there.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 include/net/irda/ircomm_tty.h       |    3 +--
 net/irda/ircomm/ircomm_tty.c        |   21 +++++++++++----------
 net/irda/ircomm/ircomm_tty_attach.c |    2 +-
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
index 59ba38bc..365fa6e 100644
--- a/include/net/irda/ircomm_tty.h
+++ b/include/net/irda/ircomm_tty.h
@@ -62,6 +62,7 @@
  */
 struct ircomm_tty_cb {
 	irda_queue_t queue;            /* Must be first */
+	struct tty_port port;
 	magic_t magic;
 
 	int state;                /* Connect state */
@@ -97,8 +98,6 @@ struct ircomm_tty_cb {
 	void *skey;
 	void *ckey;
 
-	wait_queue_head_t open_wait;
-	wait_queue_head_t close_wait;
 	struct timer_list watchdog_timer;
 	struct work_struct  tqueue;
 
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 6b9d5a0..8eeaa8b 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -278,7 +278,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 	 */
 
 	retval = 0;
-	add_wait_queue(&self->open_wait, &wait);
+	add_wait_queue(&self->port.open_wait, &wait);
 
 	IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
 	      __FILE__,__LINE__, tty->driver->name, self->open_count );
@@ -336,7 +336,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 	}
 
 	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&self->open_wait, &wait);
+	remove_wait_queue(&self->port.open_wait, &wait);
 
 	if (extra_count) {
 		/* ++ is not atomic, so this should be protected - Jean II */
@@ -381,6 +381,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 			return -ENOMEM;
 		}
 
+		tty_port_init(&self->port);
 		self->magic = IRCOMM_TTY_MAGIC;
 		self->flow = FLOW_STOP;
 
@@ -393,8 +394,6 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 
 		/* Init some important stuff */
 		init_timer(&self->watchdog_timer);
-		init_waitqueue_head(&self->open_wait);
-		init_waitqueue_head(&self->close_wait);
 		spin_lock_init(&self->spinlock);
 
 		/*
@@ -408,6 +407,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 		tty->termios->c_oflag = 0;
 
 		/* Insert into hash */
+		/* FIXME there is a window from find to here */
 		hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL);
 	}
 	/* ++ is not atomic, so this should be protected - Jean II */
@@ -438,7 +438,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 		 * probably better sleep uninterruptible?
 		 */
 
-		if (wait_event_interruptible(self->close_wait, !test_bit(ASYNC_B_CLOSING, &self->flags))) {
+		if (wait_event_interruptible(self->port.close_wait,
+				!test_bit(ASYNC_B_CLOSING, &self->flags))) {
 			IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
 				     __func__);
 			return -ERESTARTSYS;
@@ -559,11 +560,11 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	if (self->blocked_open) {
 		if (self->close_delay)
 			schedule_timeout_interruptible(self->close_delay);
-		wake_up_interruptible(&self->open_wait);
+		wake_up_interruptible(&self->port.open_wait);
 	}
 
 	self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-	wake_up_interruptible(&self->close_wait);
+	wake_up_interruptible(&self->port.close_wait);
 }
 
 /*
@@ -1011,7 +1012,7 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
 	self->open_count = 0;
 	spin_unlock_irqrestore(&self->spinlock, flags);
 
-	wake_up_interruptible(&self->open_wait);
+	wake_up_interruptible(&self->port.open_wait);
 }
 
 /*
@@ -1084,7 +1085,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
 			   (status & IRCOMM_CD) ? "on" : "off");
 
 		if (status & IRCOMM_CD) {
-			wake_up_interruptible(&self->open_wait);
+			wake_up_interruptible(&self->port.open_wait);
 		} else {
 			IRDA_DEBUG(2,
 				   "%s(), Doing serial hangup..\n", __func__ );
@@ -1103,7 +1104,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
 				tty->hw_stopped = 0;
 
 				/* Wake up processes blocked on open */
-				wake_up_interruptible(&self->open_wait);
+				wake_up_interruptible(&self->port.open_wait);
 
 				schedule_work(&self->tqueue);
 				return;
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
index b65d66e..bb1e935 100644
--- a/net/irda/ircomm/ircomm_tty_attach.c
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -575,7 +575,7 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self)
 		self->tty->hw_stopped = 0;
 
 		/* Wake up processes blocked on open */
-		wake_up_interruptible(&self->open_wait);
+		wake_up_interruptible(&self->port.open_wait);
 	}
 
 	schedule_work(&self->tqueue);
-- 
1.7.10.3

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

* [PATCH 03/24] TTY: ircomm, use close times from tty_port
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
  2012-06-04 11:35 ` [PATCH 02/24] TTY: ircomm, add tty_port Jiri Slaby
@ 2012-06-04 11:35 ` Jiri Slaby
  2012-06-04 11:35 ` [PATCH 04/24] TTY: ircomm, use open counts " Jiri Slaby
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

Switch to tty_port->close_delay and closing_wait.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 include/net/irda/ircomm_tty.h      |    3 ---
 net/irda/ircomm/ircomm_tty.c       |   10 ++++------
 net/irda/ircomm/ircomm_tty_ioctl.c |    4 ++--
 3 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
index 365fa6e..b4184d0 100644
--- a/include/net/irda/ircomm_tty.h
+++ b/include/net/irda/ircomm_tty.h
@@ -101,9 +101,6 @@ struct ircomm_tty_cb {
 	struct timer_list watchdog_timer;
 	struct work_struct  tqueue;
 
-        unsigned short    close_delay;
-        unsigned short    closing_wait; /* time to wait before closing */
-
 	int  open_count;
 	int  blocked_open;	/* # of blocked opens */
 
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 8eeaa8b..61e0adc 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -389,8 +389,6 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 		INIT_WORK(&self->tqueue, ircomm_tty_do_softint);
 		self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED;
 		self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED;
-		self->close_delay = 5*HZ/10;
-		self->closing_wait = 30*HZ;
 
 		/* Init some important stuff */
 		init_timer(&self->watchdog_timer);
@@ -546,8 +544,8 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent_from_close(tty, self->closing_wait);
+	if (self->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent_from_close(tty, self->port.closing_wait);
 
 	ircomm_tty_shutdown(self);
 
@@ -558,8 +556,8 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	self->tty = NULL;
 
 	if (self->blocked_open) {
-		if (self->close_delay)
-			schedule_timeout_interruptible(self->close_delay);
+		if (self->port.close_delay)
+			schedule_timeout_interruptible(self->port.close_delay);
 		wake_up_interruptible(&self->port.open_wait);
 	}
 
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c
index d0667d6..a6d25e3 100644
--- a/net/irda/ircomm/ircomm_tty_ioctl.c
+++ b/net/irda/ircomm/ircomm_tty_ioctl.c
@@ -272,8 +272,8 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
 	info.line = self->line;
 	info.flags = self->flags;
 	info.baud_base = self->settings.data_rate;
-	info.close_delay = self->close_delay;
-	info.closing_wait = self->closing_wait;
+	info.close_delay = self->port.close_delay;
+	info.closing_wait = self->port.closing_wait;
 
 	/* For compatibility  */
 	info.type = PORT_16550A;
-- 
1.7.10.3

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

* [PATCH 04/24] TTY: ircomm, use open counts from tty_port
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
  2012-06-04 11:35 ` [PATCH 02/24] TTY: ircomm, add tty_port Jiri Slaby
  2012-06-04 11:35 ` [PATCH 03/24] TTY: ircomm, use close times from tty_port Jiri Slaby
@ 2012-06-04 11:35 ` Jiri Slaby
  2012-06-04 16:36   ` Alan Cox
  2012-06-04 11:35 ` [PATCH 05/24] TTY: ircomm, use flags " Jiri Slaby
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

Switch to tty_port->count and blocked_open.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 include/net/irda/ircomm_tty.h |    3 ---
 net/irda/ircomm/ircomm_tty.c  |   42 ++++++++++++++++++++---------------------
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
index b4184d0..5e94bad 100644
--- a/include/net/irda/ircomm_tty.h
+++ b/include/net/irda/ircomm_tty.h
@@ -101,9 +101,6 @@ struct ircomm_tty_cb {
 	struct timer_list watchdog_timer;
 	struct work_struct  tqueue;
 
-	int  open_count;
-	int  blocked_open;	/* # of blocked opens */
-
 	/* Protect concurent access to :
 	 *	o self->open_count
 	 *	o self->ctrl_skb
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 61e0adc..787578f 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -272,7 +272,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 
 	/* Wait for carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, self->open_count is dropped by one, so that
+	 * this loop, self->port.count is dropped by one, so that
 	 * mgsl_close() knows when to free things.  We restore it upon
 	 * exit, either normal or abnormal.
 	 */
@@ -281,16 +281,16 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 	add_wait_queue(&self->port.open_wait, &wait);
 
 	IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
-	      __FILE__,__LINE__, tty->driver->name, self->open_count );
+	      __FILE__, __LINE__, tty->driver->name, self->port.count);
 
-	/* As far as I can see, we protect open_count - Jean II */
+	/* As far as I can see, we protect port.count - Jean II */
 	spin_lock_irqsave(&self->spinlock, flags);
 	if (!tty_hung_up_p(filp)) {
 		extra_count = 1;
-		self->open_count--;
+		self->port.count--;
 	}
 	spin_unlock_irqrestore(&self->spinlock, flags);
-	self->blocked_open++;
+	self->port.blocked_open++;
 
 	while (1) {
 		if (tty->termios->c_cflag & CBAUD) {
@@ -330,7 +330,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 		}
 
 		IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
-		      __FILE__,__LINE__, tty->driver->name, self->open_count );
+		      __FILE__, __LINE__, tty->driver->name, self->port.count);
 
 		schedule();
 	}
@@ -341,13 +341,13 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 	if (extra_count) {
 		/* ++ is not atomic, so this should be protected - Jean II */
 		spin_lock_irqsave(&self->spinlock, flags);
-		self->open_count++;
+		self->port.count++;
 		spin_unlock_irqrestore(&self->spinlock, flags);
 	}
-	self->blocked_open--;
+	self->port.blocked_open--;
 
 	IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
-	      __FILE__,__LINE__, tty->driver->name, self->open_count);
+	      __FILE__, __LINE__, tty->driver->name, self->port.count);
 
 	if (!retval)
 		self->flags |= ASYNC_NORMAL_ACTIVE;
@@ -410,14 +410,14 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 	}
 	/* ++ is not atomic, so this should be protected - Jean II */
 	spin_lock_irqsave(&self->spinlock, flags);
-	self->open_count++;
+	self->port.count++;
 
 	tty->driver_data = self;
 	self->tty = tty;
 	spin_unlock_irqrestore(&self->spinlock, flags);
 
 	IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name,
-		   self->line, self->open_count);
+		   self->line, self->port.count);
 
 	/* Not really used by us, but lets do it anyway */
 	self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
@@ -504,7 +504,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 		return;
 	}
 
-	if ((tty->count == 1) && (self->open_count != 1)) {
+	if ((tty->count == 1) && (self->port.count != 1)) {
 		/*
 		 * Uh, oh.  tty->count is 1, which means that the tty
 		 * structure will be freed.  state->count should always
@@ -514,16 +514,16 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 		 */
 		IRDA_DEBUG(0, "%s(), bad serial port count; "
 			   "tty->count is 1, state->count is %d\n", __func__ ,
-			   self->open_count);
-		self->open_count = 1;
+			   self->port.count);
+		self->port.count = 1;
 	}
 
-	if (--self->open_count < 0) {
+	if (--self->port.count < 0) {
 		IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
-			   __func__, self->line, self->open_count);
-		self->open_count = 0;
+			   __func__, self->line, self->port.count);
+		self->port.count = 0;
 	}
-	if (self->open_count) {
+	if (self->port.count) {
 		spin_unlock_irqrestore(&self->spinlock, flags);
 
 		IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ );
@@ -555,7 +555,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	tty->closing = 0;
 	self->tty = NULL;
 
-	if (self->blocked_open) {
+	if (self->port.blocked_open) {
 		if (self->port.close_delay)
 			schedule_timeout_interruptible(self->port.close_delay);
 		wake_up_interruptible(&self->port.open_wait);
@@ -1007,7 +1007,7 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
 	spin_lock_irqsave(&self->spinlock, flags);
 	self->flags &= ~ASYNC_NORMAL_ACTIVE;
 	self->tty = NULL;
-	self->open_count = 0;
+	self->port.count = 0;
 	spin_unlock_irqrestore(&self->spinlock, flags);
 
 	wake_up_interruptible(&self->port.open_wait);
@@ -1354,7 +1354,7 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
 	seq_putc(m, '\n');
 
 	seq_printf(m, "Role: %s\n", self->client ? "client" : "server");
-	seq_printf(m, "Open count: %d\n", self->open_count);
+	seq_printf(m, "Open count: %d\n", self->port.count);
 	seq_printf(m, "Max data size: %d\n", self->max_data_size);
 	seq_printf(m, "Max header size: %d\n", self->max_header_size);
 
-- 
1.7.10.3

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

* [PATCH 05/24] TTY: ircomm, use flags from tty_port
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
                   ` (2 preceding siblings ...)
  2012-06-04 11:35 ` [PATCH 04/24] TTY: ircomm, use open counts " Jiri Slaby
@ 2012-06-04 11:35 ` Jiri Slaby
  2012-06-04 11:35 ` [PATCH 06/24] TTY: ircomm, revamp locking Jiri Slaby
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

Switch to tty_port->flags. And while at it, remove redefined flags for
them.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 include/net/irda/ircomm_tty.h       |    6 -----
 net/irda/ircomm/ircomm_tty.c        |   46 +++++++++++++++++------------------
 net/irda/ircomm/ircomm_tty_attach.c |    5 ++--
 net/irda/ircomm/ircomm_tty_ioctl.c  |   10 ++++----
 4 files changed, 31 insertions(+), 36 deletions(-)

diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
index 5e94bad..e4db3b5 100644
--- a/include/net/irda/ircomm_tty.h
+++ b/include/net/irda/ircomm_tty.h
@@ -52,11 +52,6 @@
 /* Same for payload size. See qos.c for the smallest max data size */
 #define IRCOMM_TTY_DATA_UNINITIALISED	(64 - IRCOMM_TTY_HDR_UNINITIALISED)
 
-/* Those are really defined in include/linux/serial.h - Jean II */
-#define ASYNC_B_INITIALIZED	31	/* Serial port was initialized */
-#define ASYNC_B_NORMAL_ACTIVE	29	/* Normal device is active */
-#define ASYNC_B_CLOSING		27	/* Serial port is closing */
-
 /*
  * IrCOMM TTY driver state
  */
@@ -81,7 +76,6 @@ struct ircomm_tty_cb {
 	LOCAL_FLOW flow;          /* IrTTP flow status */
 
 	int line;
-	unsigned long flags;
 
 	__u8 dlsap_sel;
 	__u8 slsap_sel;
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 787578f..8e61026 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -194,7 +194,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
 	/* Check if already open */
-	if (test_and_set_bit(ASYNC_B_INITIALIZED, &self->flags)) {
+	if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) {
 		IRDA_DEBUG(2, "%s(), already open so break out!\n", __func__ );
 		return 0;
 	}
@@ -231,7 +231,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
 
 	return 0;
 err:
-	clear_bit(ASYNC_B_INITIALIZED, &self->flags);
+	clear_bit(ASYNCB_INITIALIZED, &self->port.flags);
 	return ret;
 }
 
@@ -260,7 +260,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 	 */
 	if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
 		/* nonblock mode is set or port is not enabled */
-		self->flags |= ASYNC_NORMAL_ACTIVE;
+		self->port.flags |= ASYNC_NORMAL_ACTIVE;
 		IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ );
 		return 0;
 	}
@@ -306,8 +306,8 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 		current->state = TASK_INTERRUPTIBLE;
 
 		if (tty_hung_up_p(filp) ||
-		    !test_bit(ASYNC_B_INITIALIZED, &self->flags)) {
-			retval = (self->flags & ASYNC_HUP_NOTIFY) ?
+		    !test_bit(ASYNCB_INITIALIZED, &self->port.flags)) {
+			retval = (self->port.flags & ASYNC_HUP_NOTIFY) ?
 					-EAGAIN : -ERESTARTSYS;
 			break;
 		}
@@ -317,7 +317,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 		 * specified, we cannot return before the IrCOMM link is
 		 * ready
 		 */
-		if (!test_bit(ASYNC_B_CLOSING, &self->flags) &&
+		if (!test_bit(ASYNCB_CLOSING, &self->port.flags) &&
 		    (do_clocal || (self->settings.dce & IRCOMM_CD)) &&
 		    self->state == IRCOMM_TTY_READY)
 		{
@@ -350,7 +350,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 	      __FILE__, __LINE__, tty->driver->name, self->port.count);
 
 	if (!retval)
-		self->flags |= ASYNC_NORMAL_ACTIVE;
+		self->port.flags |= ASYNC_NORMAL_ACTIVE;
 
 	return retval;
 }
@@ -420,13 +420,13 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 		   self->line, self->port.count);
 
 	/* Not really used by us, but lets do it anyway */
-	self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+	tty->low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
 	/*
 	 * If the port is the middle of closing, bail out now
 	 */
 	if (tty_hung_up_p(filp) ||
-	    test_bit(ASYNC_B_CLOSING, &self->flags)) {
+	    test_bit(ASYNCB_CLOSING, &self->port.flags)) {
 
 		/* Hm, why are we blocking on ASYNC_CLOSING if we
 		 * do return -EAGAIN/-ERESTARTSYS below anyway?
@@ -437,14 +437,14 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 		 */
 
 		if (wait_event_interruptible(self->port.close_wait,
-				!test_bit(ASYNC_B_CLOSING, &self->flags))) {
+				!test_bit(ASYNCB_CLOSING, &self->port.flags))) {
 			IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
 				     __func__);
 			return -ERESTARTSYS;
 		}
 
 #ifdef SERIAL_DO_RESTART
-		return (self->flags & ASYNC_HUP_NOTIFY) ?
+		return (self->port.flags & ASYNC_HUP_NOTIFY) ?
 			-EAGAIN : -ERESTARTSYS;
 #else
 		return -EAGAIN;
@@ -531,7 +531,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	}
 
 	/* Hum... Should be test_and_set_bit ??? - Jean II */
-	set_bit(ASYNC_B_CLOSING, &self->flags);
+	set_bit(ASYNCB_CLOSING, &self->port.flags);
 
 	/* We need to unlock here (we were unlocking at the end of this
 	 * function), because tty_wait_until_sent() may schedule.
@@ -561,7 +561,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 		wake_up_interruptible(&self->port.open_wait);
 	}
 
-	self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+	self->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	wake_up_interruptible(&self->port.close_wait);
 }
 
@@ -954,7 +954,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
 
 	IRDA_DEBUG(0, "%s()\n", __func__ );
 
-	if (!test_and_clear_bit(ASYNC_B_INITIALIZED, &self->flags))
+	if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags))
 		return;
 
 	ircomm_tty_detach_cable(self);
@@ -1005,7 +1005,7 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
 
 	/* I guess we need to lock here - Jean II */
 	spin_lock_irqsave(&self->spinlock, flags);
-	self->flags &= ~ASYNC_NORMAL_ACTIVE;
+	self->port.flags &= ~ASYNC_NORMAL_ACTIVE;
 	self->tty = NULL;
 	self->port.count = 0;
 	spin_unlock_irqrestore(&self->spinlock, flags);
@@ -1077,7 +1077,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
 	if (status & IRCOMM_DCE_DELTA_ANY) {
 		/*wake_up_interruptible(&self->delta_msr_wait);*/
 	}
-	if ((self->flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) {
+	if ((self->port.flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) {
 		IRDA_DEBUG(2,
 			   "%s(), ircomm%d CD now %s...\n", __func__ , self->line,
 			   (status & IRCOMM_CD) ? "on" : "off");
@@ -1094,7 +1094,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
 			return;
 		}
 	}
-	if (self->flags & ASYNC_CTS_FLOW) {
+	if (self->port.flags & ASYNC_CTS_FLOW) {
 		if (tty->hw_stopped) {
 			if (status & IRCOMM_CTS) {
 				IRDA_DEBUG(2,
@@ -1327,27 +1327,27 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
 
 	seq_puts(m, "Flags:");
 	sep = ' ';
-	if (self->flags & ASYNC_CTS_FLOW) {
+	if (self->port.flags & ASYNC_CTS_FLOW) {
 		seq_printf(m, "%cASYNC_CTS_FLOW", sep);
 		sep = '|';
 	}
-	if (self->flags & ASYNC_CHECK_CD) {
+	if (self->port.flags & ASYNC_CHECK_CD) {
 		seq_printf(m, "%cASYNC_CHECK_CD", sep);
 		sep = '|';
 	}
-	if (self->flags & ASYNC_INITIALIZED) {
+	if (self->port.flags & ASYNC_INITIALIZED) {
 		seq_printf(m, "%cASYNC_INITIALIZED", sep);
 		sep = '|';
 	}
-	if (self->flags & ASYNC_LOW_LATENCY) {
+	if (self->port.flags & ASYNC_LOW_LATENCY) {
 		seq_printf(m, "%cASYNC_LOW_LATENCY", sep);
 		sep = '|';
 	}
-	if (self->flags & ASYNC_CLOSING) {
+	if (self->port.flags & ASYNC_CLOSING) {
 		seq_printf(m, "%cASYNC_CLOSING", sep);
 		sep = '|';
 	}
-	if (self->flags & ASYNC_NORMAL_ACTIVE) {
+	if (self->port.flags & ASYNC_NORMAL_ACTIVE) {
 		seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep);
 		sep = '|';
 	}
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
index bb1e935..bed311a 100644
--- a/net/irda/ircomm/ircomm_tty_attach.c
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -566,7 +566,8 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self)
 	 * will have to wait for the peer device (DCE) to raise the CTS
 	 * line.
 	 */
-	if ((self->flags & ASYNC_CTS_FLOW) && ((self->settings.dce & IRCOMM_CTS) == 0)) {
+	if ((self->port.flags & ASYNC_CTS_FLOW) &&
+			((self->settings.dce & IRCOMM_CTS) == 0)) {
 		IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __func__ );
 		return;
 	} else {
@@ -977,7 +978,7 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
 		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
 		ircomm_tty_start_watchdog_timer(self, 3*HZ);
 
-		if (self->flags & ASYNC_CHECK_CD) {
+		if (self->port.flags & ASYNC_CHECK_CD) {
 			/* Drop carrier */
 			self->settings.dce = IRCOMM_DELTA_CD;
 			ircomm_tty_check_modem_status(self);
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c
index a6d25e3..31b917e 100644
--- a/net/irda/ircomm/ircomm_tty_ioctl.c
+++ b/net/irda/ircomm/ircomm_tty_ioctl.c
@@ -90,19 +90,19 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
 
 	/* CTS flow control flag and modem status interrupts */
 	if (cflag & CRTSCTS) {
-		self->flags |= ASYNC_CTS_FLOW;
+		self->port.flags |= ASYNC_CTS_FLOW;
 		self->settings.flow_control |= IRCOMM_RTS_CTS_IN;
 		/* This got me. Bummer. Jean II */
 		if (self->service_type == IRCOMM_3_WIRE_RAW)
 			IRDA_WARNING("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", __func__);
 	} else {
-		self->flags &= ~ASYNC_CTS_FLOW;
+		self->port.flags &= ~ASYNC_CTS_FLOW;
 		self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN;
 	}
 	if (cflag & CLOCAL)
-		self->flags &= ~ASYNC_CHECK_CD;
+		self->port.flags &= ~ASYNC_CHECK_CD;
 	else
-		self->flags |= ASYNC_CHECK_CD;
+		self->port.flags |= ASYNC_CHECK_CD;
 #if 0
 	/*
 	 * Set up parity check flag
@@ -270,7 +270,7 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
 
 	memset(&info, 0, sizeof(info));
 	info.line = self->line;
-	info.flags = self->flags;
+	info.flags = self->port.flags;
 	info.baud_base = self->settings.data_rate;
 	info.close_delay = self->port.close_delay;
 	info.closing_wait = self->port.closing_wait;
-- 
1.7.10.3

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

* [PATCH 06/24] TTY: ircomm, revamp locking
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
                   ` (3 preceding siblings ...)
  2012-06-04 11:35 ` [PATCH 05/24] TTY: ircomm, use flags " Jiri Slaby
@ 2012-06-04 11:35 ` Jiri Slaby
  2012-06-04 16:57   ` Alan Cox
  2012-06-04 11:35 ` [PATCH 07/24] TTY: ircomm, use tty from tty_port Jiri Slaby
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

Use self->spinlock only for ctrl_skb and tx_skb. TTY stuff is now
protected by tty_port->lock. This is needed for further cleanup (and
conversion to tty_port helpers).

This also closes the race in the end of close.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 include/net/irda/ircomm_tty.h |    1 -
 net/irda/ircomm/ircomm_tty.c  |   38 ++++++++++++++++++--------------------
 2 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
index e4db3b5..a9027d8 100644
--- a/include/net/irda/ircomm_tty.h
+++ b/include/net/irda/ircomm_tty.h
@@ -96,7 +96,6 @@ struct ircomm_tty_cb {
 	struct work_struct  tqueue;
 
 	/* Protect concurent access to :
-	 *	o self->open_count
 	 *	o self->ctrl_skb
 	 *	o self->tx_skb
 	 * Maybe other things may gain to be protected as well...
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 8e61026..7b2152c 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -283,13 +283,12 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 	IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
 	      __FILE__, __LINE__, tty->driver->name, self->port.count);
 
-	/* As far as I can see, we protect port.count - Jean II */
-	spin_lock_irqsave(&self->spinlock, flags);
+	spin_lock_irqsave(&self->port.lock, flags);
 	if (!tty_hung_up_p(filp)) {
 		extra_count = 1;
 		self->port.count--;
 	}
-	spin_unlock_irqrestore(&self->spinlock, flags);
+	spin_unlock_irqrestore(&self->port.lock, flags);
 	self->port.blocked_open++;
 
 	while (1) {
@@ -340,9 +339,9 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 
 	if (extra_count) {
 		/* ++ is not atomic, so this should be protected - Jean II */
-		spin_lock_irqsave(&self->spinlock, flags);
+		spin_lock_irqsave(&self->port.lock, flags);
 		self->port.count++;
-		spin_unlock_irqrestore(&self->spinlock, flags);
+		spin_unlock_irqrestore(&self->port.lock, flags);
 	}
 	self->port.blocked_open--;
 
@@ -409,12 +408,12 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 		hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL);
 	}
 	/* ++ is not atomic, so this should be protected - Jean II */
-	spin_lock_irqsave(&self->spinlock, flags);
+	spin_lock_irqsave(&self->port.lock, flags);
 	self->port.count++;
 
 	tty->driver_data = self;
 	self->tty = tty;
-	spin_unlock_irqrestore(&self->spinlock, flags);
+	spin_unlock_irqrestore(&self->port.lock, flags);
 
 	IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name,
 		   self->line, self->port.count);
@@ -495,10 +494,10 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	IRDA_ASSERT(self != NULL, return;);
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-	spin_lock_irqsave(&self->spinlock, flags);
+	spin_lock_irqsave(&self->port.lock, flags);
 
 	if (tty_hung_up_p(filp)) {
-		spin_unlock_irqrestore(&self->spinlock, flags);
+		spin_unlock_irqrestore(&self->port.lock, flags);
 
 		IRDA_DEBUG(0, "%s(), returning 1\n", __func__ );
 		return;
@@ -524,20 +523,15 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 		self->port.count = 0;
 	}
 	if (self->port.count) {
-		spin_unlock_irqrestore(&self->spinlock, flags);
+		spin_unlock_irqrestore(&self->port.lock, flags);
 
 		IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ );
 		return;
 	}
 
-	/* Hum... Should be test_and_set_bit ??? - Jean II */
 	set_bit(ASYNCB_CLOSING, &self->port.flags);
 
-	/* We need to unlock here (we were unlocking at the end of this
-	 * function), because tty_wait_until_sent() may schedule.
-	 * I don't know if the rest should be protected somehow,
-	 * so someone should check. - Jean II */
-	spin_unlock_irqrestore(&self->spinlock, flags);
+	spin_unlock_irqrestore(&self->port.lock, flags);
 
 	/*
 	 * Now we wait for the transmit buffer to clear; and we notify
@@ -552,16 +546,21 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	tty_driver_flush_buffer(tty);
 	tty_ldisc_flush(tty);
 
+	spin_lock_irqsave(&self->port.lock, flags);
 	tty->closing = 0;
 	self->tty = NULL;
 
 	if (self->port.blocked_open) {
-		if (self->port.close_delay)
+		if (self->port.close_delay) {
+			spin_unlock_irqrestore(&self->port.lock, flags);
 			schedule_timeout_interruptible(self->port.close_delay);
+			spin_lock_irqsave(&self->port.lock, flags);
+		}
 		wake_up_interruptible(&self->port.open_wait);
 	}
 
 	self->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+	spin_unlock_irqrestore(&self->port.lock, flags);
 	wake_up_interruptible(&self->port.close_wait);
 }
 
@@ -1003,12 +1002,11 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
 	/* ircomm_tty_flush_buffer(tty); */
 	ircomm_tty_shutdown(self);
 
-	/* I guess we need to lock here - Jean II */
-	spin_lock_irqsave(&self->spinlock, flags);
+	spin_lock_irqsave(&self->port.lock, flags);
 	self->port.flags &= ~ASYNC_NORMAL_ACTIVE;
 	self->tty = NULL;
 	self->port.count = 0;
-	spin_unlock_irqrestore(&self->spinlock, flags);
+	spin_unlock_irqrestore(&self->port.lock, flags);
 
 	wake_up_interruptible(&self->port.open_wait);
 }
-- 
1.7.10.3

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

* [PATCH 07/24] TTY: ircomm, use tty from tty_port
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
                   ` (4 preceding siblings ...)
  2012-06-04 11:35 ` [PATCH 06/24] TTY: ircomm, revamp locking Jiri Slaby
@ 2012-06-04 11:35 ` Jiri Slaby
  2012-06-04 11:35 ` [PATCH 08/24] TTY: ircomm, define local tty_port Jiri Slaby
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

This also includes a switch to tty refcounting. It makes sure, the
code no longer can access a freed TTY struct.

Sometimes the only thing needed is to pass tty down to the callies.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 include/net/irda/ircomm_tty.h       |    1 -
 net/irda/ircomm/ircomm_param.c      |    5 ---
 net/irda/ircomm/ircomm_tty.c        |   62 ++++++++++++++++++++++-------------
 net/irda/ircomm/ircomm_tty_attach.c |   33 ++++++++++++++-----
 net/irda/ircomm/ircomm_tty_ioctl.c  |   11 ++++---
 5 files changed, 70 insertions(+), 42 deletions(-)

diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
index a9027d8..80ffde3 100644
--- a/include/net/irda/ircomm_tty.h
+++ b/include/net/irda/ircomm_tty.h
@@ -62,7 +62,6 @@ struct ircomm_tty_cb {
 
 	int state;                /* Connect state */
 
-	struct tty_struct *tty;
 	struct ircomm_cb *ircomm; /* IrCOMM layer instance */
 
 	struct sk_buff *tx_skb;   /* Transmit buffer */
diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c
index 8b915f3..3089391 100644
--- a/net/irda/ircomm/ircomm_param.c
+++ b/net/irda/ircomm/ircomm_param.c
@@ -99,7 +99,6 @@ pi_param_info_t ircomm_param_info = { pi_major_call_table, 3, 0x0f, 4 };
  */
 int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
 {
-	struct tty_struct *tty;
 	unsigned long flags;
 	struct sk_buff *skb;
 	int count;
@@ -109,10 +108,6 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
 	IRDA_ASSERT(self != NULL, return -1;);
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
-	tty = self->tty;
-	if (!tty)
-		return 0;
-
 	/* Make sure we don't send parameters for raw mode */
 	if (self->service_type == IRCOMM_3_WIRE_RAW)
 		return 0;
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 7b2152c..03acc07 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -242,18 +242,15 @@ err:
  *
  */
 static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
-				      struct file *filp)
+		struct tty_struct *tty, struct file *filp)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	int		retval;
 	int		do_clocal = 0, extra_count = 0;
 	unsigned long	flags;
-	struct tty_struct *tty;
 
 	IRDA_DEBUG(2, "%s()\n", __func__ );
 
-	tty = self->tty;
-
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
@@ -412,8 +409,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 	self->port.count++;
 
 	tty->driver_data = self;
-	self->tty = tty;
 	spin_unlock_irqrestore(&self->port.lock, flags);
+	tty_port_tty_set(&self->port, tty);
 
 	IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name,
 		   self->line, self->port.count);
@@ -467,7 +464,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 	if (ret)
 		return ret;
 
-	ret = ircomm_tty_block_til_ready(self, filp);
+	ret = ircomm_tty_block_til_ready(self, tty, filp);
 	if (ret) {
 		IRDA_DEBUG(2,
 		      "%s(), returning after block_til_ready with %d\n", __func__ ,
@@ -548,7 +545,6 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 
 	spin_lock_irqsave(&self->port.lock, flags);
 	tty->closing = 0;
-	self->tty = NULL;
 
 	if (self->port.blocked_open) {
 		if (self->port.close_delay) {
@@ -562,6 +558,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	self->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
 	spin_unlock_irqrestore(&self->port.lock, flags);
 	wake_up_interruptible(&self->port.close_wait);
+	tty_port_tty_set(&self->port, NULL);
 }
 
 /*
@@ -604,7 +601,7 @@ static void ircomm_tty_do_softint(struct work_struct *work)
 	if (!self || self->magic != IRCOMM_TTY_MAGIC)
 		return;
 
-	tty = self->tty;
+	tty = tty_port_tty_get(&self->port);
 	if (!tty)
 		return;
 
@@ -625,7 +622,7 @@ static void ircomm_tty_do_softint(struct work_struct *work)
 	}
 
 	if (tty->hw_stopped)
-		return;
+		goto put;
 
 	/* Unlink transmit buffer */
 	spin_lock_irqsave(&self->spinlock, flags);
@@ -644,6 +641,8 @@ static void ircomm_tty_do_softint(struct work_struct *work)
 
 	/* Check if user (still) wants to be waken up */
 	tty_wakeup(tty);
+put:
+	tty_kref_put(tty);
 }
 
 /*
@@ -1004,7 +1003,11 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
 
 	spin_lock_irqsave(&self->port.lock, flags);
 	self->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	self->tty = NULL;
+	if (self->port.tty) {
+		set_bit(TTY_IO_ERROR, &self->port.tty->flags);
+		tty_kref_put(self->port.tty);
+	}
+	self->port.tty = NULL;
 	self->port.count = 0;
 	spin_unlock_irqrestore(&self->port.lock, flags);
 
@@ -1068,7 +1071,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
 	IRDA_ASSERT(self != NULL, return;);
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-	tty = self->tty;
+	tty = tty_port_tty_get(&self->port);
 
 	status = self->settings.dce;
 
@@ -1089,10 +1092,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
 				tty_hangup(tty);
 
 			/* Hangup will remote the tty, so better break out */
-			return;
+			goto put;
 		}
 	}
-	if (self->port.flags & ASYNC_CTS_FLOW) {
+	if (tty && self->port.flags & ASYNC_CTS_FLOW) {
 		if (tty->hw_stopped) {
 			if (status & IRCOMM_CTS) {
 				IRDA_DEBUG(2,
@@ -1103,7 +1106,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
 				wake_up_interruptible(&self->port.open_wait);
 
 				schedule_work(&self->tqueue);
-				return;
+				goto put;
 			}
 		} else {
 			if (!(status & IRCOMM_CTS)) {
@@ -1113,6 +1116,8 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
 			}
 		}
 	}
+put:
+	tty_kref_put(tty);
 }
 
 /*
@@ -1125,6 +1130,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
 				      struct sk_buff *skb)
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
+	struct tty_struct *tty;
 
 	IRDA_DEBUG(2, "%s()\n", __func__ );
 
@@ -1132,7 +1138,8 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 	IRDA_ASSERT(skb != NULL, return -1;);
 
-	if (!self->tty) {
+	tty = tty_port_tty_get(&self->port);
+	if (!tty) {
 		IRDA_DEBUG(0, "%s(), no tty!\n", __func__ );
 		return 0;
 	}
@@ -1143,7 +1150,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
 	 * Devices like WinCE can do this, and since they don't send any
 	 * params, we can just as well declare the hardware for running.
 	 */
-	if (self->tty->hw_stopped && (self->flow == FLOW_START)) {
+	if (tty->hw_stopped && (self->flow == FLOW_START)) {
 		IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ );
 		ircomm_param_request(self, IRCOMM_POLL, TRUE);
 
@@ -1156,8 +1163,9 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
 	 * Use flip buffer functions since the code may be called from interrupt
 	 * context
 	 */
-	tty_insert_flip_string(self->tty, skb->data, skb->len);
-	tty_flip_buffer_push(self->tty);
+	tty_insert_flip_string(tty, skb->data, skb->len);
+	tty_flip_buffer_push(tty);
+	tty_kref_put(tty);
 
 	/* No need to kfree_skb - see ircomm_ttp_data_indication() */
 
@@ -1208,12 +1216,13 @@ static void ircomm_tty_flow_indication(void *instance, void *sap,
 	IRDA_ASSERT(self != NULL, return;);
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-	tty = self->tty;
+	tty = tty_port_tty_get(&self->port);
 
 	switch (cmd) {
 	case FLOW_START:
 		IRDA_DEBUG(2, "%s(), hw start!\n", __func__ );
-		tty->hw_stopped = 0;
+		if (tty)
+			tty->hw_stopped = 0;
 
 		/* ircomm_tty_do_softint will take care of the rest */
 		schedule_work(&self->tqueue);
@@ -1221,15 +1230,19 @@ static void ircomm_tty_flow_indication(void *instance, void *sap,
 	default:  /* If we get here, something is very wrong, better stop */
 	case FLOW_STOP:
 		IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ );
-		tty->hw_stopped = 1;
+		if (tty)
+			tty->hw_stopped = 1;
 		break;
 	}
+
+	tty_kref_put(tty);
 	self->flow = cmd;
 }
 
 #ifdef CONFIG_PROC_FS
 static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
 {
+	struct tty_struct *tty;
 	char sep;
 
 	seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]);
@@ -1356,9 +1369,12 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
 	seq_printf(m, "Max data size: %d\n", self->max_data_size);
 	seq_printf(m, "Max header size: %d\n", self->max_header_size);
 
-	if (self->tty)
+	tty = tty_port_tty_get(&self->port);
+	if (tty) {
 		seq_printf(m, "Hardware: %s\n",
-			       self->tty->hw_stopped ? "Stopped" : "Running");
+			       tty->hw_stopped ? "Stopped" : "Running");
+		tty_kref_put(tty);
+	}
 }
 
 static int ircomm_tty_proc_show(struct seq_file *m, void *v)
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
index bed311a..3ab70e7 100644
--- a/net/irda/ircomm/ircomm_tty_attach.c
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -130,6 +130,8 @@ static int (*state[])(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
  */
 int ircomm_tty_attach_cable(struct ircomm_tty_cb *self)
 {
+	struct tty_struct *tty;
+
 	IRDA_DEBUG(0, "%s()\n", __func__ );
 
 	IRDA_ASSERT(self != NULL, return -1;);
@@ -142,7 +144,11 @@ int ircomm_tty_attach_cable(struct ircomm_tty_cb *self)
 	}
 
 	/* Make sure nobody tries to write before the link is up */
-	self->tty->hw_stopped = 1;
+	tty = tty_port_tty_get(&self->port);
+	if (tty) {
+		tty->hw_stopped = 1;
+		tty_kref_put(tty);
+	}
 
 	ircomm_tty_ias_register(self);
 
@@ -398,23 +404,26 @@ void ircomm_tty_disconnect_indication(void *instance, void *sap,
 				      struct sk_buff *skb)
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
+	struct tty_struct *tty;
 
 	IRDA_DEBUG(2, "%s()\n", __func__ );
 
 	IRDA_ASSERT(self != NULL, return;);
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-	if (!self->tty)
+	tty = tty_port_tty_get(&self->port);
+	if (!tty)
 		return;
 
 	/* This will stop control data transfers */
 	self->flow = FLOW_STOP;
 
 	/* Stop data transfers */
-	self->tty->hw_stopped = 1;
+	tty->hw_stopped = 1;
 
 	ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL,
 			    NULL);
+	tty_kref_put(tty);
 }
 
 /*
@@ -550,12 +559,15 @@ void ircomm_tty_connect_indication(void *instance, void *sap,
  */
 void ircomm_tty_link_established(struct ircomm_tty_cb *self)
 {
+	struct tty_struct *tty;
+
 	IRDA_DEBUG(2, "%s()\n", __func__ );
 
 	IRDA_ASSERT(self != NULL, return;);
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-	if (!self->tty)
+	tty = tty_port_tty_get(&self->port);
+	if (!tty)
 		return;
 
 	del_timer(&self->watchdog_timer);
@@ -569,17 +581,19 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self)
 	if ((self->port.flags & ASYNC_CTS_FLOW) &&
 			((self->settings.dce & IRCOMM_CTS) == 0)) {
 		IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __func__ );
-		return;
+		goto put;
 	} else {
 		IRDA_DEBUG(1, "%s(), starting hardware!\n", __func__ );
 
-		self->tty->hw_stopped = 0;
+		tty->hw_stopped = 0;
 
 		/* Wake up processes blocked on open */
 		wake_up_interruptible(&self->port.open_wait);
 	}
 
 	schedule_work(&self->tqueue);
+put:
+	tty_kref_put(tty);
 }
 
 /*
@@ -983,9 +997,12 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
 			self->settings.dce = IRCOMM_DELTA_CD;
 			ircomm_tty_check_modem_status(self);
 		} else {
+			struct tty_struct *tty = tty_port_tty_get(&self->port);
 			IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ );
-			if (self->tty)
-				tty_hangup(self->tty);
+			if (tty) {
+				tty_hangup(tty);
+				tty_kref_put(tty);
+			}
 		}
 		break;
 	default:
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c
index 31b917e..0eab650 100644
--- a/net/irda/ircomm/ircomm_tty_ioctl.c
+++ b/net/irda/ircomm/ircomm_tty_ioctl.c
@@ -52,17 +52,18 @@
  *    Change speed of the driver. If the remote device is a DCE, then this
  *    should make it change the speed of its serial port
  */
-static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
+static void ircomm_tty_change_speed(struct ircomm_tty_cb *self,
+		struct tty_struct *tty)
 {
 	unsigned int cflag, cval;
 	int baud;
 
 	IRDA_DEBUG(2, "%s()\n", __func__ );
 
-	if (!self->tty || !self->tty->termios || !self->ircomm)
+	if (!self->ircomm)
 		return;
 
-	cflag = self->tty->termios->c_cflag;
+	cflag = tty->termios->c_cflag;
 
 	/*  byte size and parity */
 	switch (cflag & CSIZE) {
@@ -81,7 +82,7 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
 		cval |= IRCOMM_PARITY_EVEN;
 
 	/* Determine divisor based on baud rate */
-	baud = tty_get_baud_rate(self->tty);
+	baud = tty_get_baud_rate(tty);
 	if (!baud)
 		baud = 9600;	/* B0 transition handled in rs_set_termios */
 
@@ -159,7 +160,7 @@ void ircomm_tty_set_termios(struct tty_struct *tty,
 		return;
 	}
 
-	ircomm_tty_change_speed(self);
+	ircomm_tty_change_speed(self, tty);
 
 	/* Handle transition to B0 status */
 	if ((old_termios->c_cflag & CBAUD) &&
-- 
1.7.10.3

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

* [PATCH 08/24] TTY: ircomm, define local tty_port
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
                   ` (5 preceding siblings ...)
  2012-06-04 11:35 ` [PATCH 07/24] TTY: ircomm, use tty from tty_port Jiri Slaby
@ 2012-06-04 11:35 ` Jiri Slaby
  2012-06-04 11:35 ` [PATCH 09/24] TTY: ircomm, define carrier routines Jiri Slaby
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

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

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 net/irda/ircomm/ircomm_tty.c |  109 ++++++++++++++++++++++--------------------
 1 file changed, 56 insertions(+), 53 deletions(-)

diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 03acc07..199d9cb 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -244,6 +244,7 @@ err:
 static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 		struct tty_struct *tty, struct file *filp)
 {
+	struct tty_port *port = &self->port;
 	DECLARE_WAITQUEUE(wait, current);
 	int		retval;
 	int		do_clocal = 0, extra_count = 0;
@@ -257,7 +258,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 	 */
 	if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
 		/* nonblock mode is set or port is not enabled */
-		self->port.flags |= ASYNC_NORMAL_ACTIVE;
+		port->flags |= ASYNC_NORMAL_ACTIVE;
 		IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ );
 		return 0;
 	}
@@ -269,24 +270,24 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 
 	/* Wait for carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, self->port.count is dropped by one, so that
+	 * this loop, port->count is dropped by one, so that
 	 * mgsl_close() knows when to free things.  We restore it upon
 	 * exit, either normal or abnormal.
 	 */
 
 	retval = 0;
-	add_wait_queue(&self->port.open_wait, &wait);
+	add_wait_queue(&port->open_wait, &wait);
 
 	IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
-	      __FILE__, __LINE__, tty->driver->name, self->port.count);
+	      __FILE__, __LINE__, tty->driver->name, port->count);
 
-	spin_lock_irqsave(&self->port.lock, flags);
+	spin_lock_irqsave(&port->lock, flags);
 	if (!tty_hung_up_p(filp)) {
 		extra_count = 1;
-		self->port.count--;
+		port->count--;
 	}
-	spin_unlock_irqrestore(&self->port.lock, flags);
-	self->port.blocked_open++;
+	spin_unlock_irqrestore(&port->lock, flags);
+	port->blocked_open++;
 
 	while (1) {
 		if (tty->termios->c_cflag & CBAUD) {
@@ -302,8 +303,8 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 		current->state = TASK_INTERRUPTIBLE;
 
 		if (tty_hung_up_p(filp) ||
-		    !test_bit(ASYNCB_INITIALIZED, &self->port.flags)) {
-			retval = (self->port.flags & ASYNC_HUP_NOTIFY) ?
+		    !test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+			retval = (port->flags & ASYNC_HUP_NOTIFY) ?
 					-EAGAIN : -ERESTARTSYS;
 			break;
 		}
@@ -313,7 +314,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 		 * specified, we cannot return before the IrCOMM link is
 		 * ready
 		 */
-		if (!test_bit(ASYNCB_CLOSING, &self->port.flags) &&
+		if (!test_bit(ASYNCB_CLOSING, &port->flags) &&
 		    (do_clocal || (self->settings.dce & IRCOMM_CD)) &&
 		    self->state == IRCOMM_TTY_READY)
 		{
@@ -326,27 +327,27 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 		}
 
 		IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
-		      __FILE__, __LINE__, tty->driver->name, self->port.count);
+		      __FILE__, __LINE__, tty->driver->name, port->count);
 
 		schedule();
 	}
 
 	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&self->port.open_wait, &wait);
+	remove_wait_queue(&port->open_wait, &wait);
 
 	if (extra_count) {
 		/* ++ is not atomic, so this should be protected - Jean II */
-		spin_lock_irqsave(&self->port.lock, flags);
-		self->port.count++;
-		spin_unlock_irqrestore(&self->port.lock, flags);
+		spin_lock_irqsave(&port->lock, flags);
+		port->count++;
+		spin_unlock_irqrestore(&port->lock, flags);
 	}
-	self->port.blocked_open--;
+	port->blocked_open--;
 
 	IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
-	      __FILE__, __LINE__, tty->driver->name, self->port.count);
+	      __FILE__, __LINE__, tty->driver->name, port->count);
 
 	if (!retval)
-		self->port.flags |= ASYNC_NORMAL_ACTIVE;
+		port->flags |= ASYNC_NORMAL_ACTIVE;
 
 	return retval;
 }
@@ -484,6 +485,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
+	struct tty_port *port = &self->port;
 	unsigned long flags;
 
 	IRDA_DEBUG(0, "%s()\n", __func__ );
@@ -491,16 +493,16 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	IRDA_ASSERT(self != NULL, return;);
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-	spin_lock_irqsave(&self->port.lock, flags);
+	spin_lock_irqsave(&port->lock, flags);
 
 	if (tty_hung_up_p(filp)) {
-		spin_unlock_irqrestore(&self->port.lock, flags);
+		spin_unlock_irqrestore(&port->lock, flags);
 
 		IRDA_DEBUG(0, "%s(), returning 1\n", __func__ );
 		return;
 	}
 
-	if ((tty->count == 1) && (self->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.  state->count should always
@@ -510,55 +512,55 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 		 */
 		IRDA_DEBUG(0, "%s(), bad serial port count; "
 			   "tty->count is 1, state->count is %d\n", __func__ ,
-			   self->port.count);
-		self->port.count = 1;
+			   port->count);
+		port->count = 1;
 	}
 
-	if (--self->port.count < 0) {
+	if (--port->count < 0) {
 		IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
-			   __func__, self->line, self->port.count);
-		self->port.count = 0;
+			   __func__, self->line, port->count);
+		port->count = 0;
 	}
-	if (self->port.count) {
-		spin_unlock_irqrestore(&self->port.lock, flags);
+	if (port->count) {
+		spin_unlock_irqrestore(&port->lock, flags);
 
 		IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ );
 		return;
 	}
 
-	set_bit(ASYNCB_CLOSING, &self->port.flags);
+	set_bit(ASYNCB_CLOSING, &port->flags);
 
-	spin_unlock_irqrestore(&self->port.lock, flags);
+	spin_unlock_irqrestore(&port->lock, flags);
 
 	/*
 	 * 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 (self->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent_from_close(tty, self->port.closing_wait);
+	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent_from_close(tty, port->closing_wait);
 
 	ircomm_tty_shutdown(self);
 
 	tty_driver_flush_buffer(tty);
 	tty_ldisc_flush(tty);
 
-	spin_lock_irqsave(&self->port.lock, flags);
+	spin_lock_irqsave(&port->lock, flags);
 	tty->closing = 0;
 
-	if (self->port.blocked_open) {
-		if (self->port.close_delay) {
-			spin_unlock_irqrestore(&self->port.lock, flags);
-			schedule_timeout_interruptible(self->port.close_delay);
-			spin_lock_irqsave(&self->port.lock, flags);
+	if (port->blocked_open) {
+		if (port->close_delay) {
+			spin_unlock_irqrestore(&port->lock, flags);
+			schedule_timeout_interruptible(port->close_delay);
+			spin_lock_irqsave(&port->lock, flags);
 		}
-		wake_up_interruptible(&self->port.open_wait);
+		wake_up_interruptible(&port->open_wait);
 	}
 
-	self->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-	spin_unlock_irqrestore(&self->port.lock, flags);
-	wake_up_interruptible(&self->port.close_wait);
-	tty_port_tty_set(&self->port, NULL);
+	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+	spin_unlock_irqrestore(&port->lock, flags);
+	wake_up_interruptible(&port->close_wait);
+	tty_port_tty_set(port, NULL);
 }
 
 /*
@@ -991,6 +993,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
 static void ircomm_tty_hangup(struct tty_struct *tty)
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
+	struct tty_port *port = &self->port;
 	unsigned long	flags;
 
 	IRDA_DEBUG(0, "%s()\n", __func__ );
@@ -1001,17 +1004,17 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
 	/* ircomm_tty_flush_buffer(tty); */
 	ircomm_tty_shutdown(self);
 
-	spin_lock_irqsave(&self->port.lock, flags);
-	self->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	if (self->port.tty) {
-		set_bit(TTY_IO_ERROR, &self->port.tty->flags);
-		tty_kref_put(self->port.tty);
+	spin_lock_irqsave(&port->lock, flags);
+	port->flags &= ~ASYNC_NORMAL_ACTIVE;
+	if (port->tty) {
+		set_bit(TTY_IO_ERROR, &port->tty->flags);
+		tty_kref_put(port->tty);
 	}
-	self->port.tty = NULL;
-	self->port.count = 0;
-	spin_unlock_irqrestore(&self->port.lock, flags);
+	port->tty = NULL;
+	port->count = 0;
+	spin_unlock_irqrestore(&port->lock, flags);
 
-	wake_up_interruptible(&self->port.open_wait);
+	wake_up_interruptible(&port->open_wait);
 }
 
 /*
-- 
1.7.10.3

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

* [PATCH 09/24] TTY: ircomm, define carrier routines
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
                   ` (6 preceding siblings ...)
  2012-06-04 11:35 ` [PATCH 08/24] TTY: ircomm, define local tty_port Jiri Slaby
@ 2012-06-04 11:35 ` Jiri Slaby
  2012-06-04 11:35 ` [PATCH 10/24] TTY: ircomm, use tty_port_close_end helper Jiri Slaby
  2012-06-04 11:35 ` [PATCH 11/24] TTY: ircomm, use tty_port_close_start helper Jiri Slaby
  9 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

These will be used by the tty_port wait_til_ready later. (Now they are
used by our code.)

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 net/irda/ircomm/ircomm_tty.c |   43 ++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 199d9cb..3fdce18 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -104,6 +104,35 @@ static const struct tty_operations ops = {
 #endif /* CONFIG_PROC_FS */
 };
 
+static void ircomm_port_raise_dtr_rts(struct tty_port *port, int raise)
+{
+	struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb,
+			port);
+	/*
+	 * Here, we use to lock those two guys, but as ircomm_param_request()
+	 * does it itself, I don't see the point (and I see the deadlock).
+	 * Jean II
+	 */
+	if (raise)
+		self->settings.dte |= IRCOMM_RTS | IRCOMM_DTR;
+	else
+		self->settings.dte &= ~(IRCOMM_RTS | IRCOMM_DTR);
+
+	ircomm_param_request(self, IRCOMM_DTE, TRUE);
+}
+
+static int ircomm_port_carrier_raised(struct tty_port *port)
+{
+	struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb,
+			port);
+	return self->settings.dce & IRCOMM_CD;
+}
+
+static const struct tty_port_operations ircomm_port_ops = {
+	.dtr_rts = ircomm_port_raise_dtr_rts,
+	.carrier_raised = ircomm_port_carrier_raised,
+};
+
 /*
  * Function ircomm_tty_init()
  *
@@ -290,15 +319,8 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 	port->blocked_open++;
 
 	while (1) {
-		if (tty->termios->c_cflag & CBAUD) {
-			/* Here, we use to lock those two guys, but
-			 * as ircomm_param_request() does it itself,
-			 * I don't see the point (and I see the deadlock).
-			 * Jean II */
-			self->settings.dte |= IRCOMM_RTS + IRCOMM_DTR;
-
-			ircomm_param_request(self, IRCOMM_DTE, TRUE);
-		}
+		if (tty->termios->c_cflag & CBAUD)
+			tty_port_raise_dtr_rts(port);
 
 		current->state = TASK_INTERRUPTIBLE;
 
@@ -315,7 +337,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
 		 * ready
 		 */
 		if (!test_bit(ASYNCB_CLOSING, &port->flags) &&
-		    (do_clocal || (self->settings.dce & IRCOMM_CD)) &&
+		    (do_clocal || tty_port_carrier_raised(port)) &&
 		    self->state == IRCOMM_TTY_READY)
 		{
 			break;
@@ -379,6 +401,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 		}
 
 		tty_port_init(&self->port);
+		self->port.ops = &ircomm_port_ops;
 		self->magic = IRCOMM_TTY_MAGIC;
 		self->flow = FLOW_STOP;
 
-- 
1.7.10.3

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

* [PATCH 10/24] TTY: ircomm, use tty_port_close_end helper
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
                   ` (7 preceding siblings ...)
  2012-06-04 11:35 ` [PATCH 09/24] TTY: ircomm, define carrier routines Jiri Slaby
@ 2012-06-04 11:35 ` Jiri Slaby
  2012-06-04 11:35 ` [PATCH 11/24] TTY: ircomm, use tty_port_close_start helper Jiri Slaby
  9 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

Again, the code is identical, so leverage the helper code.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 net/irda/ircomm/ircomm_tty.c |   16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 3fdce18..cfe352d 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -568,21 +568,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	tty_driver_flush_buffer(tty);
 	tty_ldisc_flush(tty);
 
-	spin_lock_irqsave(&port->lock, flags);
-	tty->closing = 0;
-
-	if (port->blocked_open) {
-		if (port->close_delay) {
-			spin_unlock_irqrestore(&port->lock, flags);
-			schedule_timeout_interruptible(port->close_delay);
-			spin_lock_irqsave(&port->lock, flags);
-		}
-		wake_up_interruptible(&port->open_wait);
-	}
-
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-	spin_unlock_irqrestore(&port->lock, flags);
-	wake_up_interruptible(&port->close_wait);
+	tty_port_close_end(port, tty);
 	tty_port_tty_set(port, NULL);
 }
 
-- 
1.7.10.3

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

* [PATCH 11/24] TTY: ircomm, use tty_port_close_start helper
       [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
                   ` (8 preceding siblings ...)
  2012-06-04 11:35 ` [PATCH 10/24] TTY: ircomm, use tty_port_close_end helper Jiri Slaby
@ 2012-06-04 11:35 ` Jiri Slaby
  9 siblings, 0 replies; 12+ messages in thread
From: Jiri Slaby @ 2012-06-04 11:35 UTC (permalink / raw)
  To: gregkh; +Cc: alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

Again, the code is identical, so leverage the helper code.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
---
 net/irda/ircomm/ircomm_tty.c |   48 +-----------------------------------------
 1 file changed, 1 insertion(+), 47 deletions(-)

diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index cfe352d..4e35b45 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -509,64 +509,18 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	struct tty_port *port = &self->port;
-	unsigned long flags;
 
 	IRDA_DEBUG(0, "%s()\n", __func__ );
 
 	IRDA_ASSERT(self != NULL, return;);
 	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-	spin_lock_irqsave(&port->lock, flags);
-
-	if (tty_hung_up_p(filp)) {
-		spin_unlock_irqrestore(&port->lock, flags);
-
-		IRDA_DEBUG(0, "%s(), returning 1\n", __func__ );
-		return;
-	}
-
-	if ((tty->count == 1) && (port->count != 1)) {
-		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  state->count should always
-		 * be one in these conditions.  If it's greater than
-		 * one, we've got real problems, since it means the
-		 * serial port won't be shutdown.
-		 */
-		IRDA_DEBUG(0, "%s(), bad serial port count; "
-			   "tty->count is 1, state->count is %d\n", __func__ ,
-			   port->count);
-		port->count = 1;
-	}
-
-	if (--port->count < 0) {
-		IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
-			   __func__, self->line, port->count);
-		port->count = 0;
-	}
-	if (port->count) {
-		spin_unlock_irqrestore(&port->lock, flags);
-
-		IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ );
+	if (tty_port_close_start(port, tty, filp) == 0)
 		return;
-	}
-
-	set_bit(ASYNCB_CLOSING, &port->flags);
-
-	spin_unlock_irqrestore(&port->lock, flags);
-
-	/*
-	 * 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 (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent_from_close(tty, port->closing_wait);
 
 	ircomm_tty_shutdown(self);
 
 	tty_driver_flush_buffer(tty);
-	tty_ldisc_flush(tty);
 
 	tty_port_close_end(port, tty);
 	tty_port_tty_set(port, NULL);
-- 
1.7.10.3

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

* Re: [PATCH 04/24] TTY: ircomm, use open counts from tty_port
  2012-06-04 11:35 ` [PATCH 04/24] TTY: ircomm, use open counts " Jiri Slaby
@ 2012-06-04 16:36   ` Alan Cox
  0 siblings, 0 replies; 12+ messages in thread
From: Alan Cox @ 2012-06-04 16:36 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: gregkh, alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

On Mon,  4 Jun 2012 13:35:18 +0200
Jiri Slaby <jslaby@suse.cz> wrote:

> Switch to tty_port->count and blocked_open.

Only question here is tty_port->count should be under the port lock, so
code which plays with the count itself like this probably needs to be
using the port lock ?

Alan

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

* Re: [PATCH 06/24] TTY: ircomm, revamp locking
  2012-06-04 11:35 ` [PATCH 06/24] TTY: ircomm, revamp locking Jiri Slaby
@ 2012-06-04 16:57   ` Alan Cox
  0 siblings, 0 replies; 12+ messages in thread
From: Alan Cox @ 2012-06-04 16:57 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: gregkh, alan, linux-kernel, jirislaby, Samuel Ortiz, netdev

On Mon,  4 Jun 2012 13:35:20 +0200
Jiri Slaby <jslaby@suse.cz> wrote:

> Use self->spinlock only for ctrl_skb and tx_skb. TTY stuff is now
> protected by tty_port->lock. This is needed for further cleanup (and
> conversion to tty_port helpers).
> 
> This also closes the race in the end of close.

Ah ok.. fixed here

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

end of thread, other threads:[~2012-06-04 16:57 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1338809738-18967-1-git-send-email-jslaby@suse.cz>
2012-06-04 11:35 ` [PATCH 02/24] TTY: ircomm, add tty_port Jiri Slaby
2012-06-04 11:35 ` [PATCH 03/24] TTY: ircomm, use close times from tty_port Jiri Slaby
2012-06-04 11:35 ` [PATCH 04/24] TTY: ircomm, use open counts " Jiri Slaby
2012-06-04 16:36   ` Alan Cox
2012-06-04 11:35 ` [PATCH 05/24] TTY: ircomm, use flags " Jiri Slaby
2012-06-04 11:35 ` [PATCH 06/24] TTY: ircomm, revamp locking Jiri Slaby
2012-06-04 16:57   ` Alan Cox
2012-06-04 11:35 ` [PATCH 07/24] TTY: ircomm, use tty from tty_port Jiri Slaby
2012-06-04 11:35 ` [PATCH 08/24] TTY: ircomm, define local tty_port Jiri Slaby
2012-06-04 11:35 ` [PATCH 09/24] TTY: ircomm, define carrier routines Jiri Slaby
2012-06-04 11:35 ` [PATCH 10/24] TTY: ircomm, use tty_port_close_end helper Jiri Slaby
2012-06-04 11:35 ` [PATCH 11/24] TTY: ircomm, use tty_port_close_start helper 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).