tty_port.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Tty port functions
  3. */
  4. #include <linux/types.h>
  5. #include <linux/errno.h>
  6. #include <linux/tty.h>
  7. #include <linux/tty_driver.h>
  8. #include <linux/tty_flip.h>
  9. #include <linux/serial.h>
  10. #include <linux/timer.h>
  11. #include <linux/string.h>
  12. #include <linux/slab.h>
  13. #include <linux/sched.h>
  14. #include <linux/init.h>
  15. #include <linux/wait.h>
  16. #include <linux/bitops.h>
  17. #include <linux/delay.h>
  18. #include <linux/module.h>
  19. void tty_port_init(struct tty_port *port)
  20. {
  21. memset(port, 0, sizeof(*port));
  22. init_waitqueue_head(&port->open_wait);
  23. init_waitqueue_head(&port->close_wait);
  24. mutex_init(&port->mutex);
  25. spin_lock_init(&port->lock);
  26. port->close_delay = (50 * HZ) / 100;
  27. port->closing_wait = (3000 * HZ) / 100;
  28. }
  29. EXPORT_SYMBOL(tty_port_init);
  30. int tty_port_alloc_xmit_buf(struct tty_port *port)
  31. {
  32. /* We may sleep in get_zeroed_page() */
  33. mutex_lock(&port->mutex);
  34. if (port->xmit_buf == NULL)
  35. port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
  36. mutex_unlock(&port->mutex);
  37. if (port->xmit_buf == NULL)
  38. return -ENOMEM;
  39. return 0;
  40. }
  41. EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
  42. void tty_port_free_xmit_buf(struct tty_port *port)
  43. {
  44. mutex_lock(&port->mutex);
  45. if (port->xmit_buf != NULL) {
  46. free_page((unsigned long)port->xmit_buf);
  47. port->xmit_buf = NULL;
  48. }
  49. mutex_unlock(&port->mutex);
  50. }
  51. EXPORT_SYMBOL(tty_port_free_xmit_buf);
  52. /**
  53. * tty_port_tty_get - get a tty reference
  54. * @port: tty port
  55. *
  56. * Return a refcount protected tty instance or NULL if the port is not
  57. * associated with a tty (eg due to close or hangup)
  58. */
  59. struct tty_struct *tty_port_tty_get(struct tty_port *port)
  60. {
  61. unsigned long flags;
  62. struct tty_struct *tty;
  63. spin_lock_irqsave(&port->lock, flags);
  64. tty = tty_kref_get(port->tty);
  65. spin_unlock_irqrestore(&port->lock, flags);
  66. return tty;
  67. }
  68. EXPORT_SYMBOL(tty_port_tty_get);
  69. /**
  70. * tty_port_tty_set - set the tty of a port
  71. * @port: tty port
  72. * @tty: the tty
  73. *
  74. * Associate the port and tty pair. Manages any internal refcounts.
  75. * Pass NULL to deassociate a port
  76. */
  77. void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
  78. {
  79. unsigned long flags;
  80. spin_lock_irqsave(&port->lock, flags);
  81. if (port->tty)
  82. tty_kref_put(port->tty);
  83. port->tty = tty_kref_get(tty);
  84. spin_unlock_irqrestore(&port->lock, flags);
  85. }
  86. EXPORT_SYMBOL(tty_port_tty_set);
  87. /**
  88. * tty_port_hangup - hangup helper
  89. * @port: tty port
  90. *
  91. * Perform port level tty hangup flag and count changes. Drop the tty
  92. * reference.
  93. */
  94. void tty_port_hangup(struct tty_port *port)
  95. {
  96. unsigned long flags;
  97. spin_lock_irqsave(&port->lock, flags);
  98. port->count = 0;
  99. port->flags &= ~ASYNC_NORMAL_ACTIVE;
  100. if (port->tty)
  101. tty_kref_put(port->tty);
  102. port->tty = NULL;
  103. spin_unlock_irqrestore(&port->lock, flags);
  104. wake_up_interruptible(&port->open_wait);
  105. }
  106. EXPORT_SYMBOL(tty_port_hangup);
  107. /**
  108. * tty_port_carrier_raised - carrier raised check
  109. * @port: tty port
  110. *
  111. * Wrapper for the carrier detect logic. For the moment this is used
  112. * to hide some internal details. This will eventually become entirely
  113. * internal to the tty port.
  114. */
  115. int tty_port_carrier_raised(struct tty_port *port)
  116. {
  117. if (port->ops->carrier_raised == NULL)
  118. return 1;
  119. return port->ops->carrier_raised(port);
  120. }
  121. EXPORT_SYMBOL(tty_port_carrier_raised);
  122. /**
  123. * tty_port_raise_dtr_rts - Riase DTR/RTS
  124. * @port: tty port
  125. *
  126. * Wrapper for the DTR/RTS raise logic. For the moment this is used
  127. * to hide some internal details. This will eventually become entirely
  128. * internal to the tty port.
  129. */
  130. void tty_port_raise_dtr_rts(struct tty_port *port)
  131. {
  132. if (port->ops->raise_dtr_rts)
  133. port->ops->raise_dtr_rts(port);
  134. }
  135. EXPORT_SYMBOL(tty_port_raise_dtr_rts);