Branch data Line data Source code
1 : : /*
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>
10 : : #include <linux/serial.h>
11 : : #include <linux/timer.h>
12 : : #include <linux/string.h>
13 : : #include <linux/slab.h>
14 : : #include <linux/sched.h>
15 : : #include <linux/wait.h>
16 : : #include <linux/bitops.h>
17 : : #include <linux/delay.h>
18 : : #include <linux/module.h>
19 : :
20 : 0 : void tty_port_init(struct tty_port *port)
21 : : {
22 : 244 : memset(port, 0, sizeof(*port));
23 : 244 : tty_buffer_init(port);
24 : 244 : init_waitqueue_head(&port->open_wait);
25 : 244 : init_waitqueue_head(&port->close_wait);
26 : 244 : init_waitqueue_head(&port->delta_msr_wait);
27 : 244 : mutex_init(&port->mutex);
28 : 244 : mutex_init(&port->buf_mutex);
29 : 244 : spin_lock_init(&port->lock);
30 : 244 : port->close_delay = (50 * HZ) / 100;
31 : 244 : port->closing_wait = (3000 * HZ) / 100;
32 : : kref_init(&port->kref);
33 : 244 : }
34 : : EXPORT_SYMBOL(tty_port_init);
35 : :
36 : : /**
37 : : * 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 : : */
47 : 0 : void tty_port_link_device(struct tty_port *port,
48 : : struct tty_driver *driver, unsigned index)
49 : : {
50 [ # # ][ # # ]: 0 : if (WARN_ON(index >= driver->num))
51 : 0 : return;
52 : 0 : driver->ports[index] = port;
53 : : }
54 : : EXPORT_SYMBOL_GPL(tty_port_link_device);
55 : :
56 : : /**
57 : : * 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 : : */
67 : 0 : struct device *tty_port_register_device(struct tty_port *port,
68 : : struct tty_driver *driver, unsigned index,
69 : : struct device *device)
70 : : {
71 : 0 : tty_port_link_device(port, driver, index);
72 : 0 : return tty_register_device(driver, index, device);
73 : : }
74 : : EXPORT_SYMBOL_GPL(tty_port_register_device);
75 : :
76 : : /**
77 : : * tty_port_register_device_attr - register tty device
78 : : * @port: tty_port of the device
79 : : * @driver: tty_driver for this device
80 : : * @index: index of the tty
81 : : * @device: parent if exists, otherwise NULL
82 : : * @drvdata: Driver data to be set to device.
83 : : * @attr_grp: Attribute group to be set on device.
84 : : *
85 : : * It is the same as tty_register_device_attr except the provided @port is
86 : : * linked to a concrete tty specified by @index. Use this or tty_port_install
87 : : * (or both). Call tty_port_link_device as a last resort.
88 : : */
89 : 0 : struct device *tty_port_register_device_attr(struct tty_port *port,
90 : : struct tty_driver *driver, unsigned index,
91 : : struct device *device, void *drvdata,
92 : : const struct attribute_group **attr_grp)
93 : : {
94 : 0 : tty_port_link_device(port, driver, index);
95 : 0 : return tty_register_device_attr(driver, index, device, drvdata,
96 : : attr_grp);
97 : : }
98 : : EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
99 : :
100 : 0 : int tty_port_alloc_xmit_buf(struct tty_port *port)
101 : : {
102 : : /* We may sleep in get_zeroed_page() */
103 : 0 : mutex_lock(&port->buf_mutex);
104 [ # # ]: 0 : if (port->xmit_buf == NULL)
105 : 0 : port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
106 : 0 : mutex_unlock(&port->buf_mutex);
107 [ # # ]: 0 : if (port->xmit_buf == NULL)
108 : : return -ENOMEM;
109 : 0 : return 0;
110 : : }
111 : : EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
112 : :
113 : 0 : void tty_port_free_xmit_buf(struct tty_port *port)
114 : : {
115 : 0 : mutex_lock(&port->buf_mutex);
116 [ # # ]: 0 : if (port->xmit_buf != NULL) {
117 : 0 : free_page((unsigned long)port->xmit_buf);
118 : 0 : port->xmit_buf = NULL;
119 : : }
120 : 0 : mutex_unlock(&port->buf_mutex);
121 : 0 : }
122 : : EXPORT_SYMBOL(tty_port_free_xmit_buf);
123 : :
124 : : /**
125 : : * tty_port_destroy -- destroy inited port
126 : : * @port: tty port to be doestroyed
127 : : *
128 : : * When a port was initialized using tty_port_init, one has to destroy the
129 : : * port by this function. Either indirectly by using tty_port refcounting
130 : : * (tty_port_put) or directly if refcounting is not used.
131 : : */
132 : 0 : void tty_port_destroy(struct tty_port *port)
133 : : {
134 : 188 : cancel_work_sync(&port->buf.work);
135 : 188 : tty_buffer_free_all(port);
136 : 0 : }
137 : : EXPORT_SYMBOL(tty_port_destroy);
138 : :
139 : 0 : static void tty_port_destructor(struct kref *kref)
140 : : {
141 : 188 : struct tty_port *port = container_of(kref, struct tty_port, kref);
142 : :
143 : : /* check if last port ref was dropped before tty release */
144 [ - + ][ + - ]: 188 : if (WARN_ON(port->itty))
145 : 188 : return;
146 [ - + ]: 188 : if (port->xmit_buf)
147 : 0 : free_page((unsigned long)port->xmit_buf);
148 : : tty_port_destroy(port);
149 [ - + ][ # # ]: 188 : if (port->ops && port->ops->destruct)
150 : 0 : port->ops->destruct(port);
151 : : else
152 : 188 : kfree(port);
153 : : }
154 : :
155 : 0 : void tty_port_put(struct tty_port *port)
156 : : {
157 [ + - ]: 188 : if (port)
158 : 188 : kref_put(&port->kref, tty_port_destructor);
159 : 188 : }
160 : : EXPORT_SYMBOL(tty_port_put);
161 : :
162 : : /**
163 : : * tty_port_tty_get - get a tty reference
164 : : * @port: tty port
165 : : *
166 : : * Return a refcount protected tty instance or NULL if the port is not
167 : : * associated with a tty (eg due to close or hangup)
168 : : */
169 : :
170 : 0 : struct tty_struct *tty_port_tty_get(struct tty_port *port)
171 : : {
172 : : unsigned long flags;
173 : : struct tty_struct *tty;
174 : :
175 : 0 : spin_lock_irqsave(&port->lock, flags);
176 : 0 : tty = tty_kref_get(port->tty);
177 : : spin_unlock_irqrestore(&port->lock, flags);
178 : 0 : return tty;
179 : : }
180 : : EXPORT_SYMBOL(tty_port_tty_get);
181 : :
182 : : /**
183 : : * tty_port_tty_set - set the tty of a port
184 : : * @port: tty port
185 : : * @tty: the tty
186 : : *
187 : : * Associate the port and tty pair. Manages any internal refcounts.
188 : : * Pass NULL to deassociate a port
189 : : */
190 : :
191 : 0 : void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
192 : : {
193 : : unsigned long flags;
194 : :
195 : 0 : spin_lock_irqsave(&port->lock, flags);
196 [ # # ]: 0 : if (port->tty)
197 : 0 : tty_kref_put(port->tty);
198 : 0 : port->tty = tty_kref_get(tty);
199 : : spin_unlock_irqrestore(&port->lock, flags);
200 : 0 : }
201 : : EXPORT_SYMBOL(tty_port_tty_set);
202 : :
203 : 0 : static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
204 : : {
205 : 0 : mutex_lock(&port->mutex);
206 [ # # ]: 0 : if (port->console)
207 : : goto out;
208 : :
209 [ # # ]: 0 : if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) {
210 : : /*
211 : : * Drop DTR/RTS if HUPCL is set. This causes any attached
212 : : * modem to hang up the line.
213 : : */
214 [ # # ][ # # ]: 0 : if (tty && C_HUPCL(tty))
215 : : tty_port_lower_dtr_rts(port);
216 : :
217 [ # # ]: 0 : if (port->ops->shutdown)
218 : 0 : port->ops->shutdown(port);
219 : : }
220 : : out:
221 : 0 : mutex_unlock(&port->mutex);
222 : 0 : }
223 : :
224 : : /**
225 : : * tty_port_hangup - hangup helper
226 : : * @port: tty port
227 : : *
228 : : * Perform port level tty hangup flag and count changes. Drop the tty
229 : : * reference.
230 : : */
231 : :
232 : 0 : void tty_port_hangup(struct tty_port *port)
233 : : {
234 : : struct tty_struct *tty;
235 : : unsigned long flags;
236 : :
237 : 0 : spin_lock_irqsave(&port->lock, flags);
238 : 0 : port->count = 0;
239 : 0 : port->flags &= ~ASYNC_NORMAL_ACTIVE;
240 : 0 : tty = port->tty;
241 [ # # ]: 0 : if (tty)
242 : 0 : set_bit(TTY_IO_ERROR, &tty->flags);
243 : 0 : port->tty = NULL;
244 : : spin_unlock_irqrestore(&port->lock, flags);
245 : 0 : tty_port_shutdown(port, tty);
246 : 0 : tty_kref_put(tty);
247 : 0 : wake_up_interruptible(&port->open_wait);
248 : 0 : wake_up_interruptible(&port->delta_msr_wait);
249 : 0 : }
250 : : EXPORT_SYMBOL(tty_port_hangup);
251 : :
252 : : /**
253 : : * tty_port_tty_hangup - helper to hang up a tty
254 : : *
255 : : * @port: tty port
256 : : * @check_clocal: hang only ttys with CLOCAL unset?
257 : : */
258 : 0 : void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
259 : : {
260 : 0 : struct tty_struct *tty = tty_port_tty_get(port);
261 : :
262 [ # # ][ # # ]: 0 : if (tty && (!check_clocal || !C_CLOCAL(tty)))
[ # # ]
263 : 0 : tty_hangup(tty);
264 : 0 : tty_kref_put(tty);
265 : 0 : }
266 : : EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
267 : :
268 : : /**
269 : : * tty_port_tty_wakeup - helper to wake up a tty
270 : : *
271 : : * @port: tty port
272 : : */
273 : 0 : void tty_port_tty_wakeup(struct tty_port *port)
274 : : {
275 : 0 : struct tty_struct *tty = tty_port_tty_get(port);
276 : :
277 [ # # ]: 0 : if (tty) {
278 : 0 : tty_wakeup(tty);
279 : 0 : tty_kref_put(tty);
280 : : }
281 : 0 : }
282 : : EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
283 : :
284 : : /**
285 : : * tty_port_carrier_raised - carrier raised check
286 : : * @port: tty port
287 : : *
288 : : * Wrapper for the carrier detect logic. For the moment this is used
289 : : * to hide some internal details. This will eventually become entirely
290 : : * internal to the tty port.
291 : : */
292 : :
293 : 0 : int tty_port_carrier_raised(struct tty_port *port)
294 : : {
295 [ # # ][ # # ]: 0 : if (port->ops->carrier_raised == NULL)
296 : : return 1;
297 : 0 : return port->ops->carrier_raised(port);
298 : : }
299 : : EXPORT_SYMBOL(tty_port_carrier_raised);
300 : :
301 : : /**
302 : : * tty_port_raise_dtr_rts - Raise DTR/RTS
303 : : * @port: tty port
304 : : *
305 : : * Wrapper for the DTR/RTS raise logic. For the moment this is used
306 : : * to hide some internal details. This will eventually become entirely
307 : : * internal to the tty port.
308 : : */
309 : :
310 : 0 : void tty_port_raise_dtr_rts(struct tty_port *port)
311 : : {
312 [ # # ][ # # ]: 0 : if (port->ops->dtr_rts)
[ # # ]
313 : 0 : port->ops->dtr_rts(port, 1);
314 : 0 : }
315 : : EXPORT_SYMBOL(tty_port_raise_dtr_rts);
316 : :
317 : : /**
318 : : * tty_port_lower_dtr_rts - Lower DTR/RTS
319 : : * @port: tty port
320 : : *
321 : : * Wrapper for the DTR/RTS raise logic. For the moment this is used
322 : : * to hide some internal details. This will eventually become entirely
323 : : * internal to the tty port.
324 : : */
325 : :
326 : 0 : void tty_port_lower_dtr_rts(struct tty_port *port)
327 : : {
328 [ # # ][ # # ]: 0 : if (port->ops->dtr_rts)
329 : 0 : port->ops->dtr_rts(port, 0);
330 : 0 : }
331 : : EXPORT_SYMBOL(tty_port_lower_dtr_rts);
332 : :
333 : : /**
334 : : * tty_port_block_til_ready - Waiting logic for tty open
335 : : * @port: the tty port being opened
336 : : * @tty: the tty device being bound
337 : : * @filp: the file pointer of the opener
338 : : *
339 : : * Implement the core POSIX/SuS tty behaviour when opening a tty device.
340 : : * Handles:
341 : : * - hangup (both before and during)
342 : : * - non blocking open
343 : : * - rts/dtr/dcd
344 : : * - signals
345 : : * - port flags and counts
346 : : *
347 : : * The passed tty_port must implement the carrier_raised method if it can
348 : : * do carrier detect and the dtr_rts method if it supports software
349 : : * management of these lines. Note that the dtr/rts raise is done each
350 : : * iteration as a hangup may have previously dropped them while we wait.
351 : : */
352 : :
353 : 0 : int tty_port_block_til_ready(struct tty_port *port,
354 : : struct tty_struct *tty, struct file *filp)
355 : : {
356 : : int do_clocal = 0, retval;
357 : : unsigned long flags;
358 : 0 : DEFINE_WAIT(wait);
359 : :
360 : : /* block if port is in the process of being closed */
361 [ # # ][ # # ]: 0 : if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
362 [ # # ][ # # ]: 0 : wait_event_interruptible_tty(tty, port->close_wait,
[ # # ]
363 : : !(port->flags & ASYNC_CLOSING));
364 [ # # ]: 0 : if (port->flags & ASYNC_HUP_NOTIFY)
365 : : return -EAGAIN;
366 : : else
367 : 0 : return -ERESTARTSYS;
368 : : }
369 : :
370 : : /* if non-blocking mode is set we can pass directly to open unless
371 : : the port has just hung up or is in another error state */
372 [ # # ]: 0 : if (tty->flags & (1 << TTY_IO_ERROR)) {
373 : 0 : port->flags |= ASYNC_NORMAL_ACTIVE;
374 : 0 : return 0;
375 : : }
376 [ # # ]: 0 : if (filp->f_flags & O_NONBLOCK) {
377 : : /* Indicate we are open */
378 [ # # ]: 0 : if (tty->termios.c_cflag & CBAUD)
379 : : tty_port_raise_dtr_rts(port);
380 : 0 : port->flags |= ASYNC_NORMAL_ACTIVE;
381 : 0 : return 0;
382 : : }
383 : :
384 [ # # ]: 0 : if (C_CLOCAL(tty))
385 : : do_clocal = 1;
386 : :
387 : : /* Block waiting until we can proceed. We may need to wait for the
388 : : carrier, but we must also wait for any close that is in progress
389 : : before the next open may complete */
390 : :
391 : : retval = 0;
392 : :
393 : : /* The port lock protects the port counts */
394 : 0 : spin_lock_irqsave(&port->lock, flags);
395 [ # # ]: 0 : if (!tty_hung_up_p(filp))
396 : 0 : port->count--;
397 : 0 : port->blocked_open++;
398 : : spin_unlock_irqrestore(&port->lock, flags);
399 : :
400 : : while (1) {
401 : : /* Indicate we are open */
402 [ # # ][ # # ]: 0 : if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags))
403 : : tty_port_raise_dtr_rts(port);
404 : :
405 : 0 : prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
406 : : /* Check for a hangup or uninitialised port.
407 : : Return accordingly */
408 [ # # ][ # # ]: 0 : if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
409 [ # # ]: 0 : if (port->flags & ASYNC_HUP_NOTIFY)
410 : : retval = -EAGAIN;
411 : : else
412 : : retval = -ERESTARTSYS;
413 : : break;
414 : : }
415 : : /*
416 : : * Probe the carrier. For devices with no carrier detect
417 : : * tty_port_carrier_raised will always return true.
418 : : * Never ask drivers if CLOCAL is set, this causes troubles
419 : : * on some hardware.
420 : : */
421 [ # # ][ # # ]: 0 : if (!(port->flags & ASYNC_CLOSING) &&
422 [ # # ]: 0 : (do_clocal || tty_port_carrier_raised(port)))
423 : : break;
424 [ # # ]: 0 : if (signal_pending(current)) {
425 : : retval = -ERESTARTSYS;
426 : : break;
427 : : }
428 : 0 : tty_unlock(tty);
429 : 0 : schedule();
430 : 0 : tty_lock(tty);
431 : 0 : }
432 : 0 : finish_wait(&port->open_wait, &wait);
433 : :
434 : : /* Update counts. A parallel hangup will have set count to zero and
435 : : we must not mess that up further */
436 : 0 : spin_lock_irqsave(&port->lock, flags);
437 [ # # ]: 0 : if (!tty_hung_up_p(filp))
438 : 0 : port->count++;
439 : 0 : port->blocked_open--;
440 [ # # ]: 0 : if (retval == 0)
441 : 0 : port->flags |= ASYNC_NORMAL_ACTIVE;
442 : : spin_unlock_irqrestore(&port->lock, flags);
443 : 0 : return retval;
444 : : }
445 : : EXPORT_SYMBOL(tty_port_block_til_ready);
446 : :
447 : 0 : static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty)
448 : : {
449 : : unsigned int bps = tty_get_baud_rate(tty);
450 : : long timeout;
451 : :
452 [ # # ]: 0 : if (bps > 1200) {
453 : 0 : timeout = (HZ * 10 * port->drain_delay) / bps;
454 : 0 : timeout = max_t(long, timeout, HZ / 10);
455 : : } else {
456 : : timeout = 2 * HZ;
457 : : }
458 : 0 : schedule_timeout_interruptible(timeout);
459 : 0 : }
460 : :
461 : 0 : int tty_port_close_start(struct tty_port *port,
462 : : struct tty_struct *tty, struct file *filp)
463 : : {
464 : : unsigned long flags;
465 : :
466 : 0 : spin_lock_irqsave(&port->lock, flags);
467 [ # # ]: 0 : if (tty_hung_up_p(filp)) {
468 : : spin_unlock_irqrestore(&port->lock, flags);
469 : 0 : return 0;
470 : : }
471 : :
472 [ # # ][ # # ]: 0 : if (tty->count == 1 && port->count != 1) {
473 : 0 : printk(KERN_WARNING
474 : : "tty_port_close_start: tty->count = 1 port count = %d.\n",
475 : : port->count);
476 : 0 : port->count = 1;
477 : : }
478 [ # # ]: 0 : if (--port->count < 0) {
479 : 0 : printk(KERN_WARNING "tty_port_close_start: count = %d\n",
480 : : port->count);
481 : 0 : port->count = 0;
482 : : }
483 : :
484 [ # # ]: 0 : if (port->count) {
485 : : spin_unlock_irqrestore(&port->lock, flags);
486 : 0 : return 0;
487 : : }
488 : 0 : set_bit(ASYNCB_CLOSING, &port->flags);
489 : 0 : tty->closing = 1;
490 : : spin_unlock_irqrestore(&port->lock, flags);
491 : :
492 [ # # ]: 0 : if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
493 : : /* Don't block on a stalled port, just pull the chain */
494 [ # # ]: 0 : if (tty->flow_stopped)
495 : 0 : tty_driver_flush_buffer(tty);
496 [ # # ]: 0 : if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
497 : 0 : tty_wait_until_sent_from_close(tty, port->closing_wait);
498 [ # # ]: 0 : if (port->drain_delay)
499 : 0 : tty_port_drain_delay(port, tty);
500 : : }
501 : : /* Flush the ldisc buffering */
502 : 0 : tty_ldisc_flush(tty);
503 : :
504 : : /* Report to caller this is the last port reference */
505 : 0 : return 1;
506 : : }
507 : : EXPORT_SYMBOL(tty_port_close_start);
508 : :
509 : 0 : void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
510 : : {
511 : : unsigned long flags;
512 : :
513 : 0 : spin_lock_irqsave(&port->lock, flags);
514 : 0 : tty->closing = 0;
515 : :
516 [ # # ]: 0 : if (port->blocked_open) {
517 : : spin_unlock_irqrestore(&port->lock, flags);
518 [ # # ]: 0 : if (port->close_delay) {
519 : 0 : msleep_interruptible(
520 : : jiffies_to_msecs(port->close_delay));
521 : : }
522 : 0 : spin_lock_irqsave(&port->lock, flags);
523 : 0 : wake_up_interruptible(&port->open_wait);
524 : : }
525 : 0 : port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
526 : 0 : wake_up_interruptible(&port->close_wait);
527 : : spin_unlock_irqrestore(&port->lock, flags);
528 : 0 : }
529 : : EXPORT_SYMBOL(tty_port_close_end);
530 : :
531 : 0 : void tty_port_close(struct tty_port *port, struct tty_struct *tty,
532 : : struct file *filp)
533 : : {
534 [ # # ]: 0 : if (tty_port_close_start(port, tty, filp) == 0)
535 : 0 : return;
536 : 0 : tty_port_shutdown(port, tty);
537 : 0 : set_bit(TTY_IO_ERROR, &tty->flags);
538 : 0 : tty_port_close_end(port, tty);
539 : 0 : tty_port_tty_set(port, NULL);
540 : : }
541 : : EXPORT_SYMBOL(tty_port_close);
542 : :
543 : : /**
544 : : * tty_port_install - generic tty->ops->install handler
545 : : * @port: tty_port of the device
546 : : * @driver: tty_driver for this device
547 : : * @tty: tty to be installed
548 : : *
549 : : * It is the same as tty_standard_install except the provided @port is linked
550 : : * to a concrete tty specified by @tty. Use this or tty_port_register_device
551 : : * (or both). Call tty_port_link_device as a last resort.
552 : : */
553 : 0 : int tty_port_install(struct tty_port *port, struct tty_driver *driver,
554 : : struct tty_struct *tty)
555 : : {
556 : 285 : tty->port = port;
557 : 285 : return tty_standard_install(driver, tty);
558 : : }
559 : : EXPORT_SYMBOL_GPL(tty_port_install);
560 : :
561 : 0 : int tty_port_open(struct tty_port *port, struct tty_struct *tty,
562 : : struct file *filp)
563 : : {
564 : : spin_lock_irq(&port->lock);
565 [ # # ]: 0 : if (!tty_hung_up_p(filp))
566 : 0 : ++port->count;
567 : : spin_unlock_irq(&port->lock);
568 : 0 : tty_port_tty_set(port, tty);
569 : :
570 : : /*
571 : : * Do the device-specific open only if the hardware isn't
572 : : * already initialized. Serialize open and shutdown using the
573 : : * port mutex.
574 : : */
575 : :
576 : 0 : mutex_lock(&port->mutex);
577 : :
578 [ # # ]: 0 : if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
579 : 0 : clear_bit(TTY_IO_ERROR, &tty->flags);
580 [ # # ]: 0 : if (port->ops->activate) {
581 : 0 : int retval = port->ops->activate(port, tty);
582 [ # # ]: 0 : if (retval) {
583 : 0 : mutex_unlock(&port->mutex);
584 : 0 : return retval;
585 : : }
586 : : }
587 : 0 : set_bit(ASYNCB_INITIALIZED, &port->flags);
588 : : }
589 : 0 : mutex_unlock(&port->mutex);
590 : 0 : return tty_port_block_til_ready(port, tty, filp);
591 : : }
592 : :
593 : : EXPORT_SYMBOL(tty_port_open);
|