diff options
author | Alan Cox <alan@redhat.com> | 2009-01-02 08:46:50 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:40 -0500 |
commit | a6614999e800cf3a134ce93ea46ef837e3c0e76e (patch) | |
tree | 56b0a29ed004a284561a4c3ff3ee52075acabb65 /drivers/char/tty_port.c | |
parent | 7834909f1eb96ba7c49ca2b9e3a69b500a2cff76 (diff) |
tty: Introduce some close helpers for ports
Again this is a lot of common code we can unify
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_port.c')
-rw-r--r-- | drivers/char/tty_port.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index 0723664fe0ab..b3175f54fe05 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c | |||
@@ -257,3 +257,61 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
257 | } | 257 | } |
258 | EXPORT_SYMBOL(tty_port_block_til_ready); | 258 | EXPORT_SYMBOL(tty_port_block_til_ready); |
259 | 259 | ||
260 | int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp) | ||
261 | { | ||
262 | unsigned long flags; | ||
263 | |||
264 | spin_lock_irqsave(&port->lock, flags); | ||
265 | if (tty_hung_up_p(filp)) { | ||
266 | spin_unlock_irqrestore(&port->lock, flags); | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | if( tty->count == 1 && port->count != 1) { | ||
271 | printk(KERN_WARNING | ||
272 | "tty_port_close_start: tty->count = 1 port count = %d.\n", | ||
273 | port->count); | ||
274 | port->count = 1; | ||
275 | } | ||
276 | if (--port->count < 0) { | ||
277 | printk(KERN_WARNING "tty_port_close_start: count = %d\n", | ||
278 | port->count); | ||
279 | port->count = 0; | ||
280 | } | ||
281 | |||
282 | if (port->count) { | ||
283 | spin_unlock_irqrestore(&port->lock, flags); | ||
284 | return 0; | ||
285 | } | ||
286 | port->flags |= ASYNC_CLOSING; | ||
287 | tty->closing = 1; | ||
288 | spin_unlock_irqrestore(&port->lock, flags); | ||
289 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
290 | tty_wait_until_sent(tty, port->closing_wait); | ||
291 | return 1; | ||
292 | } | ||
293 | EXPORT_SYMBOL(tty_port_close_start); | ||
294 | |||
295 | void tty_port_close_end(struct tty_port *port, struct tty_struct *tty) | ||
296 | { | ||
297 | unsigned long flags; | ||
298 | |||
299 | tty_ldisc_flush(tty); | ||
300 | |||
301 | spin_lock_irqsave(&port->lock, flags); | ||
302 | tty->closing = 0; | ||
303 | |||
304 | if (port->blocked_open) { | ||
305 | spin_unlock_irqrestore(&port->lock, flags); | ||
306 | if (port->close_delay) { | ||
307 | msleep_interruptible( | ||
308 | jiffies_to_msecs(port->close_delay)); | ||
309 | } | ||
310 | spin_lock_irqsave(&port->lock, flags); | ||
311 | wake_up_interruptible(&port->open_wait); | ||
312 | } | ||
313 | port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | ||
314 | wake_up_interruptible(&port->close_wait); | ||
315 | spin_unlock_irqrestore(&port->lock, flags); | ||
316 | } | ||
317 | EXPORT_SYMBOL(tty_port_close_end); | ||