1
2
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
20void tty_port_init(struct tty_port *port)
21{
22 memset(port, 0, sizeof(*port));
23 tty_buffer_init(port);
24 init_waitqueue_head(&port->open_wait);
25 init_waitqueue_head(&port->close_wait);
26 init_waitqueue_head(&port->delta_msr_wait);
27 mutex_init(&port->mutex);
28 mutex_init(&port->buf_mutex);
29 spin_lock_init(&port->lock);
30 port->close_delay = (50 * HZ) / 100;
31 port->closing_wait = (3000 * HZ) / 100;
32 kref_init(&port->kref);
33}
34EXPORT_SYMBOL(tty_port_init);
35
36
37
38
39
40
41
42
43
44
45
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
57
58
59
60
61
62
63
64
65
66
67struct device *tty_port_register_device(struct tty_port *port,
68 struct tty_driver *driver, unsigned index,
69 struct device *device)
70{
71 tty_port_link_device(port, driver, index);
72 return tty_register_device(driver, index, device);
73}
74EXPORT_SYMBOL_GPL(tty_port_register_device);
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89struct 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 tty_port_link_device(port, driver, index);
95 return tty_register_device_attr(driver, index, device, drvdata,
96 attr_grp);
97}
98EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
99
100int tty_port_alloc_xmit_buf(struct tty_port *port)
101{
102
103 mutex_lock(&port->buf_mutex);
104 if (port->xmit_buf == NULL)
105 port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
106 mutex_unlock(&port->buf_mutex);
107 if (port->xmit_buf == NULL)
108 return -ENOMEM;
109 return 0;
110}
111EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
112
113void tty_port_free_xmit_buf(struct tty_port *port)
114{
115 mutex_lock(&port->buf_mutex);
116 if (port->xmit_buf != NULL) {
117 free_page((unsigned long)port->xmit_buf);
118 port->xmit_buf = NULL;
119 }
120 mutex_unlock(&port->buf_mutex);
121}
122EXPORT_SYMBOL(tty_port_free_xmit_buf);
123
124
125
126
127
128
129
130
131
132void tty_port_destroy(struct tty_port *port)
133{
134 cancel_work_sync(&port->buf.work);
135 tty_buffer_free_all(port);
136}
137EXPORT_SYMBOL(tty_port_destroy);
138
139static void tty_port_destructor(struct kref *kref)
140{
141 struct tty_port *port = container_of(kref, struct tty_port, kref);
142
143
144 if (WARN_ON(port->itty))
145 return;
146 if (port->xmit_buf)
147 free_page((unsigned long)port->xmit_buf);
148 tty_port_destroy(port);
149 if (port->ops && port->ops->destruct)
150 port->ops->destruct(port);
151 else
152 kfree(port);
153}
154
155void tty_port_put(struct tty_port *port)
156{
157 if (port)
158 kref_put(&port->kref, tty_port_destructor);
159}
160EXPORT_SYMBOL(tty_port_put);
161
162
163
164
165
166
167
168
169
170struct tty_struct *tty_port_tty_get(struct tty_port *port)
171{
172 unsigned long flags;
173 struct tty_struct *tty;
174
175 spin_lock_irqsave(&port->lock, flags);
176 tty = tty_kref_get(port->tty);
177 spin_unlock_irqrestore(&port->lock, flags);
178 return tty;
179}
180EXPORT_SYMBOL(tty_port_tty_get);
181
182
183
184
185
186
187
188
189
190
191void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
192{
193 unsigned long flags;
194
195 spin_lock_irqsave(&port->lock, flags);
196 if (port->tty)
197 tty_kref_put(port->tty);
198 port->tty = tty_kref_get(tty);
199 spin_unlock_irqrestore(&port->lock, flags);
200}
201EXPORT_SYMBOL(tty_port_tty_set);
202
203static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
204{
205 mutex_lock(&port->mutex);
206 if (port->console)
207 goto out;
208
209 if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) {
210
211
212
213
214 if (tty && C_HUPCL(tty))
215 tty_port_lower_dtr_rts(port);
216
217 if (port->ops->shutdown)
218 port->ops->shutdown(port);
219 }
220out:
221 mutex_unlock(&port->mutex);
222}
223
224
225
226
227
228
229
230
231
232void tty_port_hangup(struct tty_port *port)
233{
234 struct tty_struct *tty;
235 unsigned long flags;
236
237 spin_lock_irqsave(&port->lock, flags);
238 port->count = 0;
239 port->flags &= ~ASYNC_NORMAL_ACTIVE;
240 tty = port->tty;
241 if (tty)
242 set_bit(TTY_IO_ERROR, &tty->flags);
243 port->tty = NULL;
244 spin_unlock_irqrestore(&port->lock, flags);
245 tty_port_shutdown(port, tty);
246 tty_kref_put(tty);
247 wake_up_interruptible(&port->open_wait);
248 wake_up_interruptible(&port->delta_msr_wait);
249}
250EXPORT_SYMBOL(tty_port_hangup);
251
252
253
254
255
256
257
258void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
259{
260 struct tty_struct *tty = tty_port_tty_get(port);
261
262 if (tty && (!check_clocal || !C_CLOCAL(tty)))
263 tty_hangup(tty);
264 tty_kref_put(tty);
265}
266EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
267
268
269
270
271
272
273void tty_port_tty_wakeup(struct tty_port *port)
274{
275 struct tty_struct *tty = tty_port_tty_get(port);
276
277 if (tty) {
278 tty_wakeup(tty);
279 tty_kref_put(tty);
280 }
281}
282EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
283
284
285
286
287
288
289
290
291
292
293int tty_port_carrier_raised(struct tty_port *port)
294{
295 if (port->ops->carrier_raised == NULL)
296 return 1;
297 return port->ops->carrier_raised(port);
298}
299EXPORT_SYMBOL(tty_port_carrier_raised);
300
301
302
303
304
305
306
307
308
309
310void tty_port_raise_dtr_rts(struct tty_port *port)
311{
312 if (port->ops->dtr_rts)
313 port->ops->dtr_rts(port, 1);
314}
315EXPORT_SYMBOL(tty_port_raise_dtr_rts);
316
317
318
319
320
321
322
323
324
325
326void tty_port_lower_dtr_rts(struct tty_port *port)
327{
328 if (port->ops->dtr_rts)
329 port->ops->dtr_rts(port, 0);
330}
331EXPORT_SYMBOL(tty_port_lower_dtr_rts);
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353int 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 DEFINE_WAIT(wait);
359
360
361 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
362 wait_event_interruptible_tty(tty, port->close_wait,
363 !(port->flags & ASYNC_CLOSING));
364 if (port->flags & ASYNC_HUP_NOTIFY)
365 return -EAGAIN;
366 else
367 return -ERESTARTSYS;
368 }
369
370
371
372 if (tty->flags & (1 << TTY_IO_ERROR)) {
373 port->flags |= ASYNC_NORMAL_ACTIVE;
374 return 0;
375 }
376 if (filp->f_flags & O_NONBLOCK) {
377
378 if (tty->termios.c_cflag & CBAUD)
379 tty_port_raise_dtr_rts(port);
380 port->flags |= ASYNC_NORMAL_ACTIVE;
381 return 0;
382 }
383
384 if (C_CLOCAL(tty))
385 do_clocal = 1;
386
387
388
389
390
391 retval = 0;
392
393
394 spin_lock_irqsave(&port->lock, flags);
395 if (!tty_hung_up_p(filp))
396 port->count--;
397 port->blocked_open++;
398 spin_unlock_irqrestore(&port->lock, flags);
399
400 while (1) {
401
402 if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags))
403 tty_port_raise_dtr_rts(port);
404
405 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
406
407
408 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
409 if (port->flags & ASYNC_HUP_NOTIFY)
410 retval = -EAGAIN;
411 else
412 retval = -ERESTARTSYS;
413 break;
414 }
415
416
417
418
419
420
421 if (!(port->flags & ASYNC_CLOSING) &&
422 (do_clocal || tty_port_carrier_raised(port)))
423 break;
424 if (signal_pending(current)) {
425 retval = -ERESTARTSYS;
426 break;
427 }
428 tty_unlock(tty);
429 schedule();
430 tty_lock(tty);
431 }
432 finish_wait(&port->open_wait, &wait);
433
434
435
436 spin_lock_irqsave(&port->lock, flags);
437 if (!tty_hung_up_p(filp))
438 port->count++;
439 port->blocked_open--;
440 if (retval == 0)
441 port->flags |= ASYNC_NORMAL_ACTIVE;
442 spin_unlock_irqrestore(&port->lock, flags);
443 return retval;
444}
445EXPORT_SYMBOL(tty_port_block_til_ready);
446
447static 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 if (bps > 1200) {
453 timeout = (HZ * 10 * port->drain_delay) / bps;
454 timeout = max_t(long, timeout, HZ / 10);
455 } else {
456 timeout = 2 * HZ;
457 }
458 schedule_timeout_interruptible(timeout);
459}
460
461int tty_port_close_start(struct tty_port *port,
462 struct tty_struct *tty, struct file *filp)
463{
464 unsigned long flags;
465
466 spin_lock_irqsave(&port->lock, flags);
467 if (tty_hung_up_p(filp)) {
468 spin_unlock_irqrestore(&port->lock, flags);
469 return 0;
470 }
471
472 if (tty->count == 1 && port->count != 1) {
473 printk(KERN_WARNING
474 "tty_port_close_start: tty->count = 1 port count = %d.\n",
475 port->count);
476 port->count = 1;
477 }
478 if (--port->count < 0) {
479 printk(KERN_WARNING "tty_port_close_start: count = %d\n",
480 port->count);
481 port->count = 0;
482 }
483
484 if (port->count) {
485 spin_unlock_irqrestore(&port->lock, flags);
486 return 0;
487 }
488 set_bit(ASYNCB_CLOSING, &port->flags);
489 tty->closing = 1;
490 spin_unlock_irqrestore(&port->lock, flags);
491
492 if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
493
494 if (tty->flow_stopped)
495 tty_driver_flush_buffer(tty);
496 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
497 tty_wait_until_sent_from_close(tty, port->closing_wait);
498 if (port->drain_delay)
499 tty_port_drain_delay(port, tty);
500 }
501
502 tty_ldisc_flush(tty);
503
504
505 return 1;
506}
507EXPORT_SYMBOL(tty_port_close_start);
508
509void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
510{
511 unsigned long flags;
512
513 spin_lock_irqsave(&port->lock, flags);
514 tty->closing = 0;
515
516 if (port->blocked_open) {
517 spin_unlock_irqrestore(&port->lock, flags);
518 if (port->close_delay) {
519 msleep_interruptible(
520 jiffies_to_msecs(port->close_delay));
521 }
522 spin_lock_irqsave(&port->lock, flags);
523 wake_up_interruptible(&port->open_wait);
524 }
525 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
526 wake_up_interruptible(&port->close_wait);
527 spin_unlock_irqrestore(&port->lock, flags);
528}
529EXPORT_SYMBOL(tty_port_close_end);
530
531void tty_port_close(struct tty_port *port, struct tty_struct *tty,
532 struct file *filp)
533{
534 if (tty_port_close_start(port, tty, filp) == 0)
535 return;
536 tty_port_shutdown(port, tty);
537 set_bit(TTY_IO_ERROR, &tty->flags);
538 tty_port_close_end(port, tty);
539 tty_port_tty_set(port, NULL);
540}
541EXPORT_SYMBOL(tty_port_close);
542
543
544
545
546
547
548
549
550
551
552
553int tty_port_install(struct tty_port *port, struct tty_driver *driver,
554 struct tty_struct *tty)
555{
556 tty->port = port;
557 return tty_standard_install(driver, tty);
558}
559EXPORT_SYMBOL_GPL(tty_port_install);
560
561int tty_port_open(struct tty_port *port, struct tty_struct *tty,
562 struct file *filp)
563{
564 spin_lock_irq(&port->lock);
565 if (!tty_hung_up_p(filp))
566 ++port->count;
567 spin_unlock_irq(&port->lock);
568 tty_port_tty_set(port, tty);
569
570
571
572
573
574
575
576 mutex_lock(&port->mutex);
577
578 if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
579 clear_bit(TTY_IO_ERROR, &tty->flags);
580 if (port->ops->activate) {
581 int retval = port->ops->activate(port, tty);
582 if (retval) {
583 mutex_unlock(&port->mutex);
584 return retval;
585 }
586 }
587 set_bit(ASYNCB_INITIALIZED, &port->flags);
588 }
589 mutex_unlock(&port->mutex);
590 return tty_port_block_til_ready(port, tty, filp);
591}
592
593EXPORT_SYMBOL(tty_port_open);
594