diff options
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); | ||