blob: 96302f4c707984f34f1530a91452144b7008c86f [file] [log] [blame]
Alan Cox9e485652008-10-13 10:37:07 +01001/*
2 * Tty port functions
3 */
4
5#include <linux/types.h>
6#include <linux/errno.h>
7#include <linux/tty.h>
8#include <linux/tty_driver.h>
9#include <linux/tty_flip.h>
Alan Cox3e616962009-01-02 13:45:26 +000010#include <linux/serial.h>
Alan Cox9e485652008-10-13 10:37:07 +010011#include <linux/timer.h>
12#include <linux/string.h>
13#include <linux/slab.h>
14#include <linux/sched.h>
15#include <linux/init.h>
16#include <linux/wait.h>
17#include <linux/bitops.h>
18#include <linux/delay.h>
19#include <linux/module.h>
20
21void tty_port_init(struct tty_port *port)
22{
23 memset(port, 0, sizeof(*port));
24 init_waitqueue_head(&port->open_wait);
25 init_waitqueue_head(&port->close_wait);
Alan Coxbdc04e32009-09-19 13:13:31 -070026 init_waitqueue_head(&port->delta_msr_wait);
Alan Cox9e485652008-10-13 10:37:07 +010027 mutex_init(&port->mutex);
Alan Cox44e49092009-11-30 13:16:41 +000028 mutex_init(&port->buf_mutex);
Alan Cox4a90f092008-10-13 10:39:46 +010029 spin_lock_init(&port->lock);
Alan Cox9e485652008-10-13 10:37:07 +010030 port->close_delay = (50 * HZ) / 100;
31 port->closing_wait = (3000 * HZ) / 100;
Alan Cox568aafc2009-11-30 13:17:14 +000032 kref_init(&port->kref);
Alan Cox9e485652008-10-13 10:37:07 +010033}
34EXPORT_SYMBOL(tty_port_init);
35
Jiri Slaby72a33bf2012-08-07 21:47:49 +020036/**
Jiri Slaby2cb4ca02012-08-07 21:47:50 +020037 * tty_port_link_device - link tty and tty_port
38 * @port: tty_port of the device
39 * @driver: tty_driver for this device
40 * @index: index of the tty
41 *
42 * Provide the tty layer wit ha link from a tty (specified by @index) to a
43 * tty_port (@port). Use this only if neither tty_port_register_device nor
44 * tty_port_install is used in the driver. If used, this has to be called before
45 * tty_register_driver.
46 */
47void tty_port_link_device(struct tty_port *port,
48 struct tty_driver *driver, unsigned index)
49{
50 if (WARN_ON(index >= driver->num))
51 return;
52 driver->ports[index] = port;
53}
54EXPORT_SYMBOL_GPL(tty_port_link_device);
55
56/**
Jiri Slaby72a33bf2012-08-07 21:47:49 +020057 * tty_port_register_device - register tty device
58 * @port: tty_port of the device
59 * @driver: tty_driver for this device
60 * @index: index of the tty
61 * @device: parent if exists, otherwise NULL
62 *
63 * It is the same as tty_register_device except the provided @port is linked to
64 * a concrete tty specified by @index. Use this or tty_port_install (or both).
65 * Call tty_port_link_device as a last resort.
66 */
Jiri Slaby057eb852012-06-04 13:35:37 +020067struct device *tty_port_register_device(struct tty_port *port,
68 struct tty_driver *driver, unsigned index,
69 struct device *device)
70{
Jiri Slaby2cb4ca02012-08-07 21:47:50 +020071 tty_port_link_device(port, driver, index);
Jiri Slaby057eb852012-06-04 13:35:37 +020072 return tty_register_device(driver, index, device);
73}
74EXPORT_SYMBOL_GPL(tty_port_register_device);
75
Alan Cox9e485652008-10-13 10:37:07 +010076int tty_port_alloc_xmit_buf(struct tty_port *port)
77{
78 /* We may sleep in get_zeroed_page() */
Alan Cox44e49092009-11-30 13:16:41 +000079 mutex_lock(&port->buf_mutex);
Alan Cox9e485652008-10-13 10:37:07 +010080 if (port->xmit_buf == NULL)
81 port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
Alan Cox44e49092009-11-30 13:16:41 +000082 mutex_unlock(&port->buf_mutex);
Alan Cox9e485652008-10-13 10:37:07 +010083 if (port->xmit_buf == NULL)
84 return -ENOMEM;
85 return 0;
86}
87EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
88
89void tty_port_free_xmit_buf(struct tty_port *port)
90{
Alan Cox44e49092009-11-30 13:16:41 +000091 mutex_lock(&port->buf_mutex);
Alan Cox9e485652008-10-13 10:37:07 +010092 if (port->xmit_buf != NULL) {
93 free_page((unsigned long)port->xmit_buf);
94 port->xmit_buf = NULL;
95 }
Alan Cox44e49092009-11-30 13:16:41 +000096 mutex_unlock(&port->buf_mutex);
Alan Cox9e485652008-10-13 10:37:07 +010097}
98EXPORT_SYMBOL(tty_port_free_xmit_buf);
99
Alan Cox568aafc2009-11-30 13:17:14 +0000100static void tty_port_destructor(struct kref *kref)
101{
102 struct tty_port *port = container_of(kref, struct tty_port, kref);
103 if (port->xmit_buf)
104 free_page((unsigned long)port->xmit_buf);
105 if (port->ops->destruct)
106 port->ops->destruct(port);
107 else
108 kfree(port);
109}
110
111void tty_port_put(struct tty_port *port)
112{
113 if (port)
114 kref_put(&port->kref, tty_port_destructor);
115}
116EXPORT_SYMBOL(tty_port_put);
Alan Cox9e485652008-10-13 10:37:07 +0100117
Alan Cox4a90f092008-10-13 10:39:46 +0100118/**
119 * tty_port_tty_get - get a tty reference
120 * @port: tty port
121 *
122 * Return a refcount protected tty instance or NULL if the port is not
123 * associated with a tty (eg due to close or hangup)
124 */
125
126struct tty_struct *tty_port_tty_get(struct tty_port *port)
127{
128 unsigned long flags;
129 struct tty_struct *tty;
130
131 spin_lock_irqsave(&port->lock, flags);
132 tty = tty_kref_get(port->tty);
133 spin_unlock_irqrestore(&port->lock, flags);
134 return tty;
135}
136EXPORT_SYMBOL(tty_port_tty_get);
137
138/**
139 * tty_port_tty_set - set the tty of a port
140 * @port: tty port
141 * @tty: the tty
142 *
143 * Associate the port and tty pair. Manages any internal refcounts.
144 * Pass NULL to deassociate a port
145 */
146
147void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
148{
149 unsigned long flags;
150
151 spin_lock_irqsave(&port->lock, flags);
152 if (port->tty)
153 tty_kref_put(port->tty);
Alan Coxcb4bca32008-10-21 13:47:44 +0100154 port->tty = tty_kref_get(tty);
Alan Cox4a90f092008-10-13 10:39:46 +0100155 spin_unlock_irqrestore(&port->lock, flags);
156}
157EXPORT_SYMBOL(tty_port_tty_set);
Alan Cox31f35932009-01-02 13:45:05 +0000158
Alan Cox7ca0ff92009-09-19 13:13:20 -0700159static void tty_port_shutdown(struct tty_port *port)
160{
Alan Cox64bc3972009-10-06 16:06:11 +0100161 mutex_lock(&port->mutex);
Jason Wessel336cee42010-03-08 21:50:11 -0600162 if (port->ops->shutdown && !port->console &&
Alan Stern1f5c13f2009-08-20 15:23:47 -0400163 test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
Alan Cox7ca0ff92009-09-19 13:13:20 -0700164 port->ops->shutdown(port);
Alan Cox64bc3972009-10-06 16:06:11 +0100165 mutex_unlock(&port->mutex);
Alan Cox7ca0ff92009-09-19 13:13:20 -0700166}
167
Alan Cox31f35932009-01-02 13:45:05 +0000168/**
Alan Cox3e616962009-01-02 13:45:26 +0000169 * tty_port_hangup - hangup helper
170 * @port: tty port
171 *
172 * Perform port level tty hangup flag and count changes. Drop the tty
173 * reference.
174 */
175
176void tty_port_hangup(struct tty_port *port)
177{
178 unsigned long flags;
179
180 spin_lock_irqsave(&port->lock, flags);
181 port->count = 0;
182 port->flags &= ~ASYNC_NORMAL_ACTIVE;
Alan Coxd74e8282009-11-30 13:16:52 +0000183 if (port->tty) {
184 set_bit(TTY_IO_ERROR, &port->tty->flags);
Alan Cox3e616962009-01-02 13:45:26 +0000185 tty_kref_put(port->tty);
Alan Coxd74e8282009-11-30 13:16:52 +0000186 }
Alan Cox3e616962009-01-02 13:45:26 +0000187 port->tty = NULL;
188 spin_unlock_irqrestore(&port->lock, flags);
189 wake_up_interruptible(&port->open_wait);
Alan Coxbdc04e32009-09-19 13:13:31 -0700190 wake_up_interruptible(&port->delta_msr_wait);
Alan Cox7ca0ff92009-09-19 13:13:20 -0700191 tty_port_shutdown(port);
Alan Cox3e616962009-01-02 13:45:26 +0000192}
193EXPORT_SYMBOL(tty_port_hangup);
194
195/**
Alan Cox31f35932009-01-02 13:45:05 +0000196 * tty_port_carrier_raised - carrier raised check
197 * @port: tty port
198 *
199 * Wrapper for the carrier detect logic. For the moment this is used
200 * to hide some internal details. This will eventually become entirely
201 * internal to the tty port.
202 */
203
204int tty_port_carrier_raised(struct tty_port *port)
205{
206 if (port->ops->carrier_raised == NULL)
207 return 1;
208 return port->ops->carrier_raised(port);
209}
210EXPORT_SYMBOL(tty_port_carrier_raised);
Alan Cox5d951fb2009-01-02 13:45:19 +0000211
212/**
Alan Coxfcc8ac12009-06-11 12:24:17 +0100213 * tty_port_raise_dtr_rts - Raise DTR/RTS
Alan Cox5d951fb2009-01-02 13:45:19 +0000214 * @port: tty port
215 *
216 * Wrapper for the DTR/RTS raise logic. For the moment this is used
217 * to hide some internal details. This will eventually become entirely
218 * internal to the tty port.
219 */
220
221void tty_port_raise_dtr_rts(struct tty_port *port)
222{
Alan Coxfcc8ac12009-06-11 12:24:17 +0100223 if (port->ops->dtr_rts)
224 port->ops->dtr_rts(port, 1);
Alan Cox5d951fb2009-01-02 13:45:19 +0000225}
226EXPORT_SYMBOL(tty_port_raise_dtr_rts);
Alan Cox36c621d2009-01-02 13:46:10 +0000227
228/**
Alan Coxfcc8ac12009-06-11 12:24:17 +0100229 * tty_port_lower_dtr_rts - Lower DTR/RTS
230 * @port: tty port
231 *
232 * Wrapper for the DTR/RTS raise logic. For the moment this is used
233 * to hide some internal details. This will eventually become entirely
234 * internal to the tty port.
235 */
236
237void tty_port_lower_dtr_rts(struct tty_port *port)
238{
239 if (port->ops->dtr_rts)
240 port->ops->dtr_rts(port, 0);
241}
242EXPORT_SYMBOL(tty_port_lower_dtr_rts);
243
244/**
Alan Cox36c621d2009-01-02 13:46:10 +0000245 * tty_port_block_til_ready - Waiting logic for tty open
246 * @port: the tty port being opened
247 * @tty: the tty device being bound
248 * @filp: the file pointer of the opener
249 *
250 * Implement the core POSIX/SuS tty behaviour when opening a tty device.
251 * Handles:
252 * - hangup (both before and during)
253 * - non blocking open
254 * - rts/dtr/dcd
255 * - signals
256 * - port flags and counts
257 *
258 * The passed tty_port must implement the carrier_raised method if it can
Alan Coxfcc8ac12009-06-11 12:24:17 +0100259 * do carrier detect and the dtr_rts method if it supports software
Alan Cox36c621d2009-01-02 13:46:10 +0000260 * management of these lines. Note that the dtr/rts raise is done each
261 * iteration as a hangup may have previously dropped them while we wait.
262 */
Alan Coxd774a562009-10-06 16:06:21 +0100263
Alan Cox36c621d2009-01-02 13:46:10 +0000264int tty_port_block_til_ready(struct tty_port *port,
265 struct tty_struct *tty, struct file *filp)
266{
267 int do_clocal = 0, retval;
268 unsigned long flags;
Jiri Slaby6af9a432009-06-24 18:35:05 +0100269 DEFINE_WAIT(wait);
Alan Cox36c621d2009-01-02 13:46:10 +0000270
271 /* block if port is in the process of being closed */
272 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
Alan Cox89c8d912012-08-08 16:30:13 +0100273 wait_event_interruptible_tty(tty, port->close_wait,
Jiri Slaby5fc5b422009-06-11 14:32:42 +0100274 !(port->flags & ASYNC_CLOSING));
Alan Cox36c621d2009-01-02 13:46:10 +0000275 if (port->flags & ASYNC_HUP_NOTIFY)
276 return -EAGAIN;
277 else
278 return -ERESTARTSYS;
279 }
280
281 /* if non-blocking mode is set we can pass directly to open unless
282 the port has just hung up or is in another error state */
Alan Cox8627b962009-11-18 14:12:58 +0000283 if (tty->flags & (1 << TTY_IO_ERROR)) {
284 port->flags |= ASYNC_NORMAL_ACTIVE;
285 return 0;
286 }
287 if (filp->f_flags & O_NONBLOCK) {
Alan Cox4175f3e2009-10-28 21:12:32 +0100288 /* Indicate we are open */
Alan Coxadc8d742012-07-14 15:31:47 +0100289 if (tty->termios.c_cflag & CBAUD)
Alan Cox4175f3e2009-10-28 21:12:32 +0100290 tty_port_raise_dtr_rts(port);
Alan Cox36c621d2009-01-02 13:46:10 +0000291 port->flags |= ASYNC_NORMAL_ACTIVE;
292 return 0;
293 }
294
295 if (C_CLOCAL(tty))
296 do_clocal = 1;
297
298 /* Block waiting until we can proceed. We may need to wait for the
299 carrier, but we must also wait for any close that is in progress
300 before the next open may complete */
301
302 retval = 0;
Alan Cox36c621d2009-01-02 13:46:10 +0000303
304 /* The port lock protects the port counts */
305 spin_lock_irqsave(&port->lock, flags);
306 if (!tty_hung_up_p(filp))
307 port->count--;
308 port->blocked_open++;
309 spin_unlock_irqrestore(&port->lock, flags);
310
311 while (1) {
312 /* Indicate we are open */
Alan Coxadc8d742012-07-14 15:31:47 +0100313 if (tty->termios.c_cflag & CBAUD)
Alan Cox78349092009-01-02 13:46:43 +0000314 tty_port_raise_dtr_rts(port);
Alan Cox36c621d2009-01-02 13:46:10 +0000315
Jiri Slaby3e3b5c02009-06-11 14:33:37 +0100316 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
Alan Coxd774a562009-10-06 16:06:21 +0100317 /* Check for a hangup or uninitialised port.
318 Return accordingly */
Alan Cox36c621d2009-01-02 13:46:10 +0000319 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
320 if (port->flags & ASYNC_HUP_NOTIFY)
321 retval = -EAGAIN;
322 else
323 retval = -ERESTARTSYS;
324 break;
325 }
Jiri Slaby0eee50a2012-01-12 22:55:15 +0100326 /*
327 * Probe the carrier. For devices with no carrier detect
328 * tty_port_carrier_raised will always return true.
329 * Never ask drivers if CLOCAL is set, this causes troubles
330 * on some hardware.
331 */
Alan Cox36c621d2009-01-02 13:46:10 +0000332 if (!(port->flags & ASYNC_CLOSING) &&
Jiri Slaby0eee50a2012-01-12 22:55:15 +0100333 (do_clocal || tty_port_carrier_raised(port)))
Alan Cox36c621d2009-01-02 13:46:10 +0000334 break;
335 if (signal_pending(current)) {
336 retval = -ERESTARTSYS;
337 break;
338 }
Alan Cox89c8d912012-08-08 16:30:13 +0100339 tty_unlock(tty);
Alan Cox36c621d2009-01-02 13:46:10 +0000340 schedule();
Alan Cox89c8d912012-08-08 16:30:13 +0100341 tty_lock(tty);
Alan Cox36c621d2009-01-02 13:46:10 +0000342 }
Jiri Slaby3e3b5c02009-06-11 14:33:37 +0100343 finish_wait(&port->open_wait, &wait);
Alan Cox36c621d2009-01-02 13:46:10 +0000344
345 /* Update counts. A parallel hangup will have set count to zero and
346 we must not mess that up further */
347 spin_lock_irqsave(&port->lock, flags);
348 if (!tty_hung_up_p(filp))
349 port->count++;
350 port->blocked_open--;
351 if (retval == 0)
352 port->flags |= ASYNC_NORMAL_ACTIVE;
353 spin_unlock_irqrestore(&port->lock, flags);
Alan Coxecc2e052009-07-17 16:17:26 +0100354 return retval;
Alan Cox36c621d2009-01-02 13:46:10 +0000355}
356EXPORT_SYMBOL(tty_port_block_til_ready);
357
Alan Coxd774a562009-10-06 16:06:21 +0100358int tty_port_close_start(struct tty_port *port,
359 struct tty_struct *tty, struct file *filp)
Alan Coxa6614992009-01-02 13:46:50 +0000360{
361 unsigned long flags;
362
363 spin_lock_irqsave(&port->lock, flags);
364 if (tty_hung_up_p(filp)) {
365 spin_unlock_irqrestore(&port->lock, flags);
366 return 0;
367 }
368
Alan Coxd774a562009-10-06 16:06:21 +0100369 if (tty->count == 1 && port->count != 1) {
Alan Coxa6614992009-01-02 13:46:50 +0000370 printk(KERN_WARNING
371 "tty_port_close_start: tty->count = 1 port count = %d.\n",
372 port->count);
373 port->count = 1;
374 }
375 if (--port->count < 0) {
376 printk(KERN_WARNING "tty_port_close_start: count = %d\n",
377 port->count);
378 port->count = 0;
379 }
380
381 if (port->count) {
382 spin_unlock_irqrestore(&port->lock, flags);
Alan Cox7ca0ff92009-09-19 13:13:20 -0700383 if (port->ops->drop)
384 port->ops->drop(port);
Alan Coxa6614992009-01-02 13:46:50 +0000385 return 0;
386 }
Alan Stern1f5c13f2009-08-20 15:23:47 -0400387 set_bit(ASYNCB_CLOSING, &port->flags);
Alan Coxa6614992009-01-02 13:46:50 +0000388 tty->closing = 1;
389 spin_unlock_irqrestore(&port->lock, flags);
Alan Coxfba85e02009-01-02 13:48:39 +0000390 /* Don't block on a stalled port, just pull the chain */
391 if (tty->flow_stopped)
392 tty_driver_flush_buffer(tty);
Alan Cox7ca0ff92009-09-19 13:13:20 -0700393 if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
Alan Cox6ed1dba2009-01-02 13:48:11 +0000394 port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
Jiri Slaby424cc032011-08-25 15:12:07 +0200395 tty_wait_until_sent_from_close(tty, port->closing_wait);
Alan Cox1ec739b2009-06-11 12:25:25 +0100396 if (port->drain_delay) {
397 unsigned int bps = tty_get_baud_rate(tty);
398 long timeout;
399
400 if (bps > 1200)
Alan Coxd774a562009-10-06 16:06:21 +0100401 timeout = max_t(long,
402 (HZ * 10 * port->drain_delay) / bps, HZ / 10);
Alan Cox1ec739b2009-06-11 12:25:25 +0100403 else
404 timeout = 2 * HZ;
405 schedule_timeout_interruptible(timeout);
406 }
Alan Coxe707c352009-11-05 13:27:57 +0000407 /* Flush the ldisc buffering */
408 tty_ldisc_flush(tty);
409
410 /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
411 hang up the line */
Alan Coxadc8d742012-07-14 15:31:47 +0100412 if (tty->termios.c_cflag & HUPCL)
Alan Coxe707c352009-11-05 13:27:57 +0000413 tty_port_lower_dtr_rts(port);
414
Alan Cox7ca0ff92009-09-19 13:13:20 -0700415 /* Don't call port->drop for the last reference. Callers will want
416 to drop the last active reference in ->shutdown() or the tty
417 shutdown path */
Alan Coxa6614992009-01-02 13:46:50 +0000418 return 1;
419}
420EXPORT_SYMBOL(tty_port_close_start);
421
422void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
423{
424 unsigned long flags;
425
Alan Coxa6614992009-01-02 13:46:50 +0000426 spin_lock_irqsave(&port->lock, flags);
427 tty->closing = 0;
428
429 if (port->blocked_open) {
430 spin_unlock_irqrestore(&port->lock, flags);
431 if (port->close_delay) {
432 msleep_interruptible(
433 jiffies_to_msecs(port->close_delay));
434 }
435 spin_lock_irqsave(&port->lock, flags);
436 wake_up_interruptible(&port->open_wait);
437 }
438 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
439 wake_up_interruptible(&port->close_wait);
440 spin_unlock_irqrestore(&port->lock, flags);
441}
442EXPORT_SYMBOL(tty_port_close_end);
Alan Cox7ca0ff92009-09-19 13:13:20 -0700443
444void tty_port_close(struct tty_port *port, struct tty_struct *tty,
445 struct file *filp)
446{
447 if (tty_port_close_start(port, tty, filp) == 0)
448 return;
449 tty_port_shutdown(port);
Alan Coxd74e8282009-11-30 13:16:52 +0000450 set_bit(TTY_IO_ERROR, &tty->flags);
Alan Cox7ca0ff92009-09-19 13:13:20 -0700451 tty_port_close_end(port, tty);
452 tty_port_tty_set(port, NULL);
453}
454EXPORT_SYMBOL(tty_port_close);
Alan Cox64bc3972009-10-06 16:06:11 +0100455
Jiri Slaby72a33bf2012-08-07 21:47:49 +0200456/**
457 * tty_port_install - generic tty->ops->install handler
458 * @port: tty_port of the device
459 * @driver: tty_driver for this device
460 * @tty: tty to be installed
461 *
462 * It is the same as tty_standard_install except the provided @port is linked
463 * to a concrete tty specified by @tty. Use this or tty_port_register_device
464 * (or both). Call tty_port_link_device as a last resort.
465 */
Jiri Slaby695586c2012-06-04 13:35:32 +0200466int tty_port_install(struct tty_port *port, struct tty_driver *driver,
467 struct tty_struct *tty)
468{
469 tty->port = port;
470 return tty_standard_install(driver, tty);
471}
472EXPORT_SYMBOL_GPL(tty_port_install);
473
Alan Cox64bc3972009-10-06 16:06:11 +0100474int tty_port_open(struct tty_port *port, struct tty_struct *tty,
Alan Coxd774a562009-10-06 16:06:21 +0100475 struct file *filp)
Alan Cox64bc3972009-10-06 16:06:11 +0100476{
477 spin_lock_irq(&port->lock);
478 if (!tty_hung_up_p(filp))
479 ++port->count;
480 spin_unlock_irq(&port->lock);
481 tty_port_tty_set(port, tty);
482
483 /*
484 * Do the device-specific open only if the hardware isn't
485 * already initialized. Serialize open and shutdown using the
486 * port mutex.
487 */
488
489 mutex_lock(&port->mutex);
490
491 if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
Alan Coxa9a37ec2009-11-30 13:16:57 +0000492 clear_bit(TTY_IO_ERROR, &tty->flags);
Alan Cox64bc3972009-10-06 16:06:11 +0100493 if (port->ops->activate) {
494 int retval = port->ops->activate(port, tty);
495 if (retval) {
Alan Coxd774a562009-10-06 16:06:21 +0100496 mutex_unlock(&port->mutex);
497 return retval;
498 }
499 }
Alan Cox64bc3972009-10-06 16:06:11 +0100500 set_bit(ASYNCB_INITIALIZED, &port->flags);
501 }
502 mutex_unlock(&port->mutex);
503 return tty_port_block_til_ready(port, tty, filp);
504}
505
506EXPORT_SYMBOL(tty_port_open);