tty_port.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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. init_waitqueue_head(&port->delta_msr_wait);
  25. mutex_init(&port->mutex);
  26. spin_lock_init(&port->lock);
  27. port->close_delay = (50 * HZ) / 100;
  28. port->closing_wait = (3000 * HZ) / 100;
  29. }
  30. EXPORT_SYMBOL(tty_port_init);
  31. int tty_port_alloc_xmit_buf(struct tty_port *port)
  32. {
  33. /* We may sleep in get_zeroed_page() */
  34. mutex_lock(&port->mutex);
  35. if (port->xmit_buf == NULL)
  36. port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
  37. mutex_unlock(&port->mutex);
  38. if (port->xmit_buf == NULL)
  39. return -ENOMEM;
  40. return 0;
  41. }
  42. EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
  43. void tty_port_free_xmit_buf(struct tty_port *port)
  44. {
  45. mutex_lock(&port->mutex);
  46. if (port->xmit_buf != NULL) {
  47. free_page((unsigned long)port->xmit_buf);
  48. port->xmit_buf = NULL;
  49. }
  50. mutex_unlock(&port->mutex);
  51. }
  52. EXPORT_SYMBOL(tty_port_free_xmit_buf);
  53. /**
  54. * tty_port_tty_get - get a tty reference
  55. * @port: tty port
  56. *
  57. * Return a refcount protected tty instance or NULL if the port is not
  58. * associated with a tty (eg due to close or hangup)
  59. */
  60. struct tty_struct *tty_port_tty_get(struct tty_port *port)
  61. {
  62. unsigned long flags;
  63. struct tty_struct *tty;
  64. spin_lock_irqsave(&port->lock, flags);
  65. tty = tty_kref_get(port->tty);
  66. spin_unlock_irqrestore(&port->lock, flags);
  67. return tty;
  68. }
  69. EXPORT_SYMBOL(tty_port_tty_get);
  70. /**
  71. * tty_port_tty_set - set the tty of a port
  72. * @port: tty port
  73. * @tty: the tty
  74. *
  75. * Associate the port and tty pair. Manages any internal refcounts.
  76. * Pass NULL to deassociate a port
  77. */
  78. void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
  79. {
  80. unsigned long flags;
  81. spin_lock_irqsave(&port->lock, flags);
  82. if (port->tty)
  83. tty_kref_put(port->tty);
  84. port->tty = tty_kref_get(tty);
  85. spin_unlock_irqrestore(&port->lock, flags);
  86. }
  87. EXPORT_SYMBOL(tty_port_tty_set);
  88. static void tty_port_shutdown(struct tty_port *port)
  89. {
  90. if (port->ops->shutdown &&
  91. test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
  92. port->ops->shutdown(port);
  93. }
  94. /**
  95. * tty_port_hangup - hangup helper
  96. * @port: tty port
  97. *
  98. * Perform port level tty hangup flag and count changes. Drop the tty
  99. * reference.
  100. */
  101. void tty_port_hangup(struct tty_port *port)
  102. {
  103. unsigned long flags;
  104. spin_lock_irqsave(&port->lock, flags);
  105. port->count = 0;
  106. port->flags &= ~ASYNC_NORMAL_ACTIVE;
  107. if (port->tty)
  108. tty_kref_put(port->tty);
  109. port->tty = NULL;
  110. spin_unlock_irqrestore(&port->lock, flags);
  111. wake_up_interruptible(&port->open_wait);
  112. wake_up_interruptible(&port->delta_msr_wait);
  113. tty_port_shutdown(port);
  114. }
  115. EXPORT_SYMBOL(tty_port_hangup);
  116. /**
  117. * tty_port_carrier_raised - carrier raised check
  118. * @port: tty port
  119. *
  120. * Wrapper for the carrier detect logic. For the moment this is used
  121. * to hide some internal details. This will eventually become entirely
  122. * internal to the tty port.
  123. */
  124. int tty_port_carrier_raised(struct tty_port *port)
  125. {
  126. if (port->ops->carrier_raised == NULL)
  127. return 1;
  128. return port->ops->carrier_raised(port);
  129. }
  130. EXPORT_SYMBOL(tty_port_carrier_raised);
  131. /**
  132. * tty_port_raise_dtr_rts - Raise DTR/RTS
  133. * @port: tty port
  134. *
  135. * Wrapper for the DTR/RTS raise logic. For the moment this is used
  136. * to hide some internal details. This will eventually become entirely
  137. * internal to the tty port.
  138. */
  139. void tty_port_raise_dtr_rts(struct tty_port *port)
  140. {
  141. if (port->ops->dtr_rts)
  142. port->ops->dtr_rts(port, 1);
  143. }
  144. EXPORT_SYMBOL(tty_port_raise_dtr_rts);
  145. /**
  146. * tty_port_lower_dtr_rts - Lower DTR/RTS
  147. * @port: tty port
  148. *
  149. * Wrapper for the DTR/RTS raise logic. For the moment this is used
  150. * to hide some internal details. This will eventually become entirely
  151. * internal to the tty port.
  152. */
  153. void tty_port_lower_dtr_rts(struct tty_port *port)
  154. {
  155. if (port->ops->dtr_rts)
  156. port->ops->dtr_rts(port, 0);
  157. }
  158. EXPORT_SYMBOL(tty_port_lower_dtr_rts);
  159. /**
  160. * tty_port_block_til_ready - Waiting logic for tty open
  161. * @port: the tty port being opened
  162. * @tty: the tty device being bound
  163. * @filp: the file pointer of the opener
  164. *
  165. * Implement the core POSIX/SuS tty behaviour when opening a tty device.
  166. * Handles:
  167. * - hangup (both before and during)
  168. * - non blocking open
  169. * - rts/dtr/dcd
  170. * - signals
  171. * - port flags and counts
  172. *
  173. * The passed tty_port must implement the carrier_raised method if it can
  174. * do carrier detect and the dtr_rts method if it supports software
  175. * management of these lines. Note that the dtr/rts raise is done each
  176. * iteration as a hangup may have previously dropped them while we wait.
  177. */
  178. int tty_port_block_til_ready(struct tty_port *port,
  179. struct tty_struct *tty, struct file *filp)
  180. {
  181. int do_clocal = 0, retval;
  182. unsigned long flags;
  183. DEFINE_WAIT(wait);
  184. int cd;
  185. /* block if port is in the process of being closed */
  186. if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
  187. wait_event_interruptible(port->close_wait,
  188. !(port->flags & ASYNC_CLOSING));
  189. if (port->flags & ASYNC_HUP_NOTIFY)
  190. return -EAGAIN;
  191. else
  192. return -ERESTARTSYS;
  193. }
  194. /* if non-blocking mode is set we can pass directly to open unless
  195. the port has just hung up or is in another error state */
  196. if ((filp->f_flags & O_NONBLOCK) ||
  197. (tty->flags & (1 << TTY_IO_ERROR))) {
  198. port->flags |= ASYNC_NORMAL_ACTIVE;
  199. return 0;
  200. }
  201. if (C_CLOCAL(tty))
  202. do_clocal = 1;
  203. /* Block waiting until we can proceed. We may need to wait for the
  204. carrier, but we must also wait for any close that is in progress
  205. before the next open may complete */
  206. retval = 0;
  207. /* The port lock protects the port counts */
  208. spin_lock_irqsave(&port->lock, flags);
  209. if (!tty_hung_up_p(filp))
  210. port->count--;
  211. port->blocked_open++;
  212. spin_unlock_irqrestore(&port->lock, flags);
  213. while (1) {
  214. /* Indicate we are open */
  215. if (tty->termios->c_cflag & CBAUD)
  216. tty_port_raise_dtr_rts(port);
  217. prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
  218. /* Check for a hangup or uninitialised port. Return accordingly */
  219. if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
  220. if (port->flags & ASYNC_HUP_NOTIFY)
  221. retval = -EAGAIN;
  222. else
  223. retval = -ERESTARTSYS;
  224. break;
  225. }
  226. /* Probe the carrier. For devices with no carrier detect this
  227. will always return true */
  228. cd = tty_port_carrier_raised(port);
  229. if (!(port->flags & ASYNC_CLOSING) &&
  230. (do_clocal || cd))
  231. break;
  232. if (signal_pending(current)) {
  233. retval = -ERESTARTSYS;
  234. break;
  235. }
  236. schedule();
  237. }
  238. finish_wait(&port->open_wait, &wait);
  239. /* Update counts. A parallel hangup will have set count to zero and
  240. we must not mess that up further */
  241. spin_lock_irqsave(&port->lock, flags);
  242. if (!tty_hung_up_p(filp))
  243. port->count++;
  244. port->blocked_open--;
  245. if (retval == 0)
  246. port->flags |= ASYNC_NORMAL_ACTIVE;
  247. spin_unlock_irqrestore(&port->lock, flags);
  248. return retval;
  249. }
  250. EXPORT_SYMBOL(tty_port_block_til_ready);
  251. int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
  252. {
  253. unsigned long flags;
  254. spin_lock_irqsave(&port->lock, flags);
  255. if (tty_hung_up_p(filp)) {
  256. spin_unlock_irqrestore(&port->lock, flags);
  257. return 0;
  258. }
  259. if( tty->count == 1 && port->count != 1) {
  260. printk(KERN_WARNING
  261. "tty_port_close_start: tty->count = 1 port count = %d.\n",
  262. port->count);
  263. port->count = 1;
  264. }
  265. if (--port->count < 0) {
  266. printk(KERN_WARNING "tty_port_close_start: count = %d\n",
  267. port->count);
  268. port->count = 0;
  269. }
  270. if (port->count) {
  271. spin_unlock_irqrestore(&port->lock, flags);
  272. if (port->ops->drop)
  273. port->ops->drop(port);
  274. return 0;
  275. }
  276. set_bit(ASYNCB_CLOSING, &port->flags);
  277. tty->closing = 1;
  278. spin_unlock_irqrestore(&port->lock, flags);
  279. /* Don't block on a stalled port, just pull the chain */
  280. if (tty->flow_stopped)
  281. tty_driver_flush_buffer(tty);
  282. if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
  283. port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
  284. tty_wait_until_sent(tty, port->closing_wait);
  285. if (port->drain_delay) {
  286. unsigned int bps = tty_get_baud_rate(tty);
  287. long timeout;
  288. if (bps > 1200)
  289. timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps,
  290. HZ / 10);
  291. else
  292. timeout = 2 * HZ;
  293. schedule_timeout_interruptible(timeout);
  294. }
  295. /* Don't call port->drop for the last reference. Callers will want
  296. to drop the last active reference in ->shutdown() or the tty
  297. shutdown path */
  298. return 1;
  299. }
  300. EXPORT_SYMBOL(tty_port_close_start);
  301. void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
  302. {
  303. unsigned long flags;
  304. tty_ldisc_flush(tty);
  305. if (tty->termios->c_cflag & HUPCL)
  306. tty_port_lower_dtr_rts(port);
  307. spin_lock_irqsave(&port->lock, flags);
  308. tty->closing = 0;
  309. if (port->blocked_open) {
  310. spin_unlock_irqrestore(&port->lock, flags);
  311. if (port->close_delay) {
  312. msleep_interruptible(
  313. jiffies_to_msecs(port->close_delay));
  314. }
  315. spin_lock_irqsave(&port->lock, flags);
  316. wake_up_interruptible(&port->open_wait);
  317. }
  318. port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
  319. wake_up_interruptible(&port->close_wait);
  320. spin_unlock_irqrestore(&port->lock, flags);
  321. }
  322. EXPORT_SYMBOL(tty_port_close_end);
  323. void tty_port_close(struct tty_port *port, struct tty_struct *tty,
  324. struct file *filp)
  325. {
  326. if (tty_port_close_start(port, tty, filp) == 0)
  327. return;
  328. tty_port_shutdown(port);
  329. tty_port_close_end(port, tty);
  330. tty_port_tty_set(port, NULL);
  331. }
  332. EXPORT_SYMBOL(tty_port_close);