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/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 tty_buffer_init(port);
25 init_waitqueue_head(&port->open_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 if (port->xmit_buf)
143 free_page((unsigned long)port->xmit_buf);
144 tty_port_destroy(port);
145 if (port->ops && port->ops->destruct)
146 port->ops->destruct(port);
147 else
148 kfree(port);
149}
150
151void tty_port_put(struct tty_port *port)
152{
153 if (port)
154 kref_put(&port->kref, tty_port_destructor);
155}
156EXPORT_SYMBOL(tty_port_put);
157
158
159
160
161
162
163
164
165
166struct tty_struct *tty_port_tty_get(struct tty_port *port)
167{
168 unsigned long flags;
169 struct tty_struct *tty;
170
171 spin_lock_irqsave(&port->lock, flags);
172 tty = tty_kref_get(port->tty);
173 spin_unlock_irqrestore(&port->lock, flags);
174 return tty;
175}
176EXPORT_SYMBOL(tty_port_tty_get);
177
178
179
180
181
182
183
184
185
186
187void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
188{
189 unsigned long flags;
190
191 spin_lock_irqsave(&port->lock, flags);
192 if (port->tty)
193 tty_kref_put(port->tty);
194 port->tty = tty_kref_get(tty);
195 spin_unlock_irqrestore(&port->lock, flags);
196}
197EXPORT_SYMBOL(tty_port_tty_set);
198
199static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
200{
201 mutex_lock(&port->mutex);
202 if (port->console)
203 goto out;
204
205 if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) {
206
207
208
209
210 if (tty && C_HUPCL(tty))
211 tty_port_lower_dtr_rts(port);
212
213 if (port->ops->shutdown)
214 port->ops->shutdown(port);
215 }
216out:
217 mutex_unlock(&port->mutex);
218}
219
220
221
222
223
224
225
226
227
228void tty_port_hangup(struct tty_port *port)
229{
230 struct tty_struct *tty;
231 unsigned long flags;
232
233 spin_lock_irqsave(&port->lock, flags);
234 port->count = 0;
235 port->flags &= ~ASYNC_NORMAL_ACTIVE;
236 tty = port->tty;
237 if (tty)
238 set_bit(TTY_IO_ERROR, &tty->flags);
239 port->tty = NULL;
240 spin_unlock_irqrestore(&port->lock, flags);
241 tty_port_shutdown(port, tty);
242 tty_kref_put(tty);
243 wake_up_interruptible(&port->open_wait);
244 wake_up_interruptible(&port->delta_msr_wait);
245}
246EXPORT_SYMBOL(tty_port_hangup);
247
248
249
250
251
252
253
254void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
255{
256 struct tty_struct *tty = tty_port_tty_get(port);
257
258 if (tty && (!check_clocal || !C_CLOCAL(tty)))
259 tty_hangup(tty);
260 tty_kref_put(tty);
261}
262EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
263
264
265
266
267
268
269void tty_port_tty_wakeup(struct tty_port *port)
270{
271 struct tty_struct *tty = tty_port_tty_get(port);
272
273 if (tty) {
274 tty_wakeup(tty);
275 tty_kref_put(tty);
276 }
277}
278EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
279
280
281
282
283
284
285
286
287
288
289int tty_port_carrier_raised(struct tty_port *port)
290{
291 if (port->ops->carrier_raised == NULL)
292 return 1;
293 return port->ops->carrier_raised(port);
294}
295EXPORT_SYMBOL(tty_port_carrier_raised);
296
297
298
299
300
301
302
303
304
305
306void tty_port_raise_dtr_rts(struct tty_port *port)
307{
308 if (port->ops->dtr_rts)
309 port->ops->dtr_rts(port, 1);
310}
311EXPORT_SYMBOL(tty_port_raise_dtr_rts);
312
313
314
315
316
317
318
319
320
321
322void tty_port_lower_dtr_rts(struct tty_port *port)
323{
324 if (port->ops->dtr_rts)
325 port->ops->dtr_rts(port, 0);
326}
327EXPORT_SYMBOL(tty_port_lower_dtr_rts);
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349int tty_port_block_til_ready(struct tty_port *port,
350 struct tty_struct *tty, struct file *filp)
351{
352 int do_clocal = 0, retval;
353 unsigned long flags;
354 DEFINE_WAIT(wait);
355
356
357
358 if (tty->flags & (1 << TTY_IO_ERROR)) {
359 port->flags |= ASYNC_NORMAL_ACTIVE;
360 return 0;
361 }
362 if (filp->f_flags & O_NONBLOCK) {
363
364 if (tty->termios.c_cflag & CBAUD)
365 tty_port_raise_dtr_rts(port);
366 port->flags |= ASYNC_NORMAL_ACTIVE;
367 return 0;
368 }
369
370 if (C_CLOCAL(tty))
371 do_clocal = 1;
372
373
374
375
376
377 retval = 0;
378
379
380 spin_lock_irqsave(&port->lock, flags);
381 port->count--;
382 port->blocked_open++;
383 spin_unlock_irqrestore(&port->lock, flags);
384
385 while (1) {
386
387 if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags))
388 tty_port_raise_dtr_rts(port);
389
390 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
391
392
393 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
394 if (port->flags & ASYNC_HUP_NOTIFY)
395 retval = -EAGAIN;
396 else
397 retval = -ERESTARTSYS;
398 break;
399 }
400
401
402
403
404
405
406 if (do_clocal || tty_port_carrier_raised(port))
407 break;
408 if (signal_pending(current)) {
409 retval = -ERESTARTSYS;
410 break;
411 }
412 tty_unlock(tty);
413 schedule();
414 tty_lock(tty);
415 }
416 finish_wait(&port->open_wait, &wait);
417
418
419
420 spin_lock_irqsave(&port->lock, flags);
421 if (!tty_hung_up_p(filp))
422 port->count++;
423 port->blocked_open--;
424 if (retval == 0)
425 port->flags |= ASYNC_NORMAL_ACTIVE;
426 spin_unlock_irqrestore(&port->lock, flags);
427 return retval;
428}
429EXPORT_SYMBOL(tty_port_block_til_ready);
430
431static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty)
432{
433 unsigned int bps = tty_get_baud_rate(tty);
434 long timeout;
435
436 if (bps > 1200) {
437 timeout = (HZ * 10 * port->drain_delay) / bps;
438 timeout = max_t(long, timeout, HZ / 10);
439 } else {
440 timeout = 2 * HZ;
441 }
442 schedule_timeout_interruptible(timeout);
443}
444
445
446int tty_port_close_start(struct tty_port *port,
447 struct tty_struct *tty, struct file *filp)
448{
449 unsigned long flags;
450
451 spin_lock_irqsave(&port->lock, flags);
452 if (tty_hung_up_p(filp)) {
453 spin_unlock_irqrestore(&port->lock, flags);
454 return 0;
455 }
456
457 if (tty->count == 1 && port->count != 1) {
458 printk(KERN_WARNING
459 "tty_port_close_start: tty->count = 1 port count = %d.\n",
460 port->count);
461 port->count = 1;
462 }
463 if (--port->count < 0) {
464 printk(KERN_WARNING "tty_port_close_start: count = %d\n",
465 port->count);
466 port->count = 0;
467 }
468
469 if (port->count) {
470 spin_unlock_irqrestore(&port->lock, flags);
471 if (port->ops->drop)
472 port->ops->drop(port);
473 return 0;
474 }
475 set_bit(ASYNCB_CLOSING, &port->flags);
476 tty->closing = 1;
477 spin_unlock_irqrestore(&port->lock, flags);
478
479 if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
480
481 if (tty->flow_stopped)
482 tty_driver_flush_buffer(tty);
483 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
484 tty_wait_until_sent(tty, port->closing_wait);
485 if (port->drain_delay)
486 tty_port_drain_delay(port, tty);
487 }
488
489 tty_ldisc_flush(tty);
490
491
492
493
494 return 1;
495}
496EXPORT_SYMBOL(tty_port_close_start);
497
498
499void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
500{
501 unsigned long flags;
502
503 spin_lock_irqsave(&port->lock, flags);
504 tty->closing = 0;
505
506 if (port->blocked_open) {
507 spin_unlock_irqrestore(&port->lock, flags);
508 if (port->close_delay) {
509 msleep_interruptible(
510 jiffies_to_msecs(port->close_delay));
511 }
512 spin_lock_irqsave(&port->lock, flags);
513 wake_up_interruptible(&port->open_wait);
514 }
515 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
516 spin_unlock_irqrestore(&port->lock, flags);
517}
518EXPORT_SYMBOL(tty_port_close_end);
519
520
521
522
523
524
525void tty_port_close(struct tty_port *port, struct tty_struct *tty,
526 struct file *filp)
527{
528 if (tty_port_close_start(port, tty, filp) == 0)
529 return;
530 tty_port_shutdown(port, tty);
531 set_bit(TTY_IO_ERROR, &tty->flags);
532 tty_port_close_end(port, tty);
533 tty_port_tty_set(port, NULL);
534}
535EXPORT_SYMBOL(tty_port_close);
536
537
538
539
540
541
542
543
544
545
546
547int tty_port_install(struct tty_port *port, struct tty_driver *driver,
548 struct tty_struct *tty)
549{
550 tty->port = port;
551 return tty_standard_install(driver, tty);
552}
553EXPORT_SYMBOL_GPL(tty_port_install);
554
555int tty_port_open(struct tty_port *port, struct tty_struct *tty,
556 struct file *filp)
557{
558 spin_lock_irq(&port->lock);
559 ++port->count;
560 spin_unlock_irq(&port->lock);
561 tty_port_tty_set(port, tty);
562
563
564
565
566
567
568
569 mutex_lock(&port->mutex);
570
571 if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
572 clear_bit(TTY_IO_ERROR, &tty->flags);
573 if (port->ops->activate) {
574 int retval = port->ops->activate(port, tty);
575 if (retval) {
576 mutex_unlock(&port->mutex);
577 return retval;
578 }
579 }
580 set_bit(ASYNCB_INITIALIZED, &port->flags);
581 }
582 mutex_unlock(&port->mutex);
583 return tty_port_block_til_ready(port, tty, filp);
584}
585
586EXPORT_SYMBOL(tty_port_open);
587