* [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).