blob: 7709ce655f44affa9980fe6f959ef4c31505e047 [file] [log] [blame]
Greg Kroah-Hartmane3b3d0f2017-11-06 18:11:51 +01001// SPDX-License-Identifier: GPL-2.0
Alan Cox9e485652008-10-13 10:37:07 +01002/*
3 * Tty port functions
4 */
5
6#include <linux/types.h>
7#include <linux/errno.h>
8#include <linux/tty.h>
9#include <linux/tty_driver.h>
10#include <linux/tty_flip.h>
Alan Cox3e616962009-01-02 13:45:26 +000011#include <linux/serial.h>
Alan Cox9e485652008-10-13 10:37:07 +010012#include <linux/timer.h>
13#include <linux/string.h>
14#include <linux/slab.h>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010015#include <linux/sched/signal.h>
Alan Cox9e485652008-10-13 10:37:07 +010016#include <linux/wait.h>
17#include <linux/bitops.h>
18#include <linux/delay.h>
19#include <linux/module.h>
Johan Hovold8cde11b2017-05-18 17:33:00 +020020#include <linux/serdev.h>
Greg Kroah-Hartman98602c02021-04-08 14:51:22 +020021#include "tty.h"
Alan Cox9e485652008-10-13 10:37:07 +010022
Rob Herringc3485ee2017-02-02 13:48:05 -060023static int tty_port_default_receive_buf(struct tty_port *port,
24 const unsigned char *p,
25 const unsigned char *f, size_t count)
26{
27 int ret;
28 struct tty_struct *tty;
29 struct tty_ldisc *disc;
30
31 tty = READ_ONCE(port->itty);
32 if (!tty)
33 return 0;
34
35 disc = tty_ldisc_ref(tty);
36 if (!disc)
37 return 0;
38
39 ret = tty_ldisc_receive_buf(disc, p, (char *)f, count);
40
41 tty_ldisc_deref(disc);
42
43 return ret;
44}
45
46static void tty_port_default_wakeup(struct tty_port *port)
47{
48 struct tty_struct *tty = tty_port_tty_get(port);
49
50 if (tty) {
51 tty_wakeup(tty);
52 tty_kref_put(tty);
53 }
54}
55
Johan Hovold0c5aae52020-02-10 15:57:30 +010056const struct tty_port_client_operations tty_port_default_client_ops = {
Rob Herringc3485ee2017-02-02 13:48:05 -060057 .receive_buf = tty_port_default_receive_buf,
58 .write_wakeup = tty_port_default_wakeup,
59};
Johan Hovold0c5aae52020-02-10 15:57:30 +010060EXPORT_SYMBOL_GPL(tty_port_default_client_ops);
Rob Herringc3485ee2017-02-02 13:48:05 -060061
Jiri Slaby3be491d2021-11-26 09:16:06 +010062/**
63 * tty_port_init -- initialize tty_port
64 * @port: tty_port to initialize
65 *
66 * Initializes the state of struct tty_port. When a port was initialized using
67 * this function, one has to destroy the port by tty_port_destroy(). Either
68 * indirectly by using &tty_port refcounting (tty_port_put()) or directly if
69 * refcounting is not used.
70 */
Alan Cox9e485652008-10-13 10:37:07 +010071void tty_port_init(struct tty_port *port)
72{
73 memset(port, 0, sizeof(*port));
Jiri Slabyecbbfd42012-10-18 22:26:47 +020074 tty_buffer_init(port);
Alan Cox9e485652008-10-13 10:37:07 +010075 init_waitqueue_head(&port->open_wait);
Alan Coxbdc04e32009-09-19 13:13:31 -070076 init_waitqueue_head(&port->delta_msr_wait);
Alan Cox9e485652008-10-13 10:37:07 +010077 mutex_init(&port->mutex);
Alan Cox44e49092009-11-30 13:16:41 +000078 mutex_init(&port->buf_mutex);
Alan Cox4a90f092008-10-13 10:39:46 +010079 spin_lock_init(&port->lock);
Alan Cox9e485652008-10-13 10:37:07 +010080 port->close_delay = (50 * HZ) / 100;
81 port->closing_wait = (3000 * HZ) / 100;
Johan Hovold0c5aae52020-02-10 15:57:30 +010082 port->client_ops = &tty_port_default_client_ops;
Alan Cox568aafc2009-11-30 13:17:14 +000083 kref_init(&port->kref);
Alan Cox9e485652008-10-13 10:37:07 +010084}
85EXPORT_SYMBOL(tty_port_init);
86
Jiri Slaby72a33bf2012-08-07 21:47:49 +020087/**
Jiri Slaby2cb4ca02012-08-07 21:47:50 +020088 * tty_port_link_device - link tty and tty_port
89 * @port: tty_port of the device
90 * @driver: tty_driver for this device
91 * @index: index of the tty
92 *
Antonio Borneo1926e5d2017-09-08 08:59:42 +020093 * Provide the tty layer with a link from a tty (specified by @index) to a
Jiri Slabycb6f6f92021-11-26 09:15:59 +010094 * tty_port (@port). Use this only if neither tty_port_register_device() nor
95 * tty_port_install() is used in the driver. If used, this has to be called
96 * before tty_register_driver().
Jiri Slaby2cb4ca02012-08-07 21:47:50 +020097 */
98void tty_port_link_device(struct tty_port *port,
99 struct tty_driver *driver, unsigned index)
100{
101 if (WARN_ON(index >= driver->num))
102 return;
Sudip Mukherjee273f63292019-12-27 17:44:34 +0000103 driver->ports[index] = port;
Jiri Slaby2cb4ca02012-08-07 21:47:50 +0200104}
105EXPORT_SYMBOL_GPL(tty_port_link_device);
106
107/**
Jiri Slaby72a33bf2012-08-07 21:47:49 +0200108 * tty_port_register_device - register tty device
109 * @port: tty_port of the device
110 * @driver: tty_driver for this device
111 * @index: index of the tty
112 * @device: parent if exists, otherwise NULL
113 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100114 * It is the same as tty_register_device() except the provided @port is linked
115 * to a concrete tty specified by @index. Use this or tty_port_install() (or
116 * both). Call tty_port_link_device() as a last resort.
Jiri Slaby72a33bf2012-08-07 21:47:49 +0200117 */
Jiri Slaby057eb852012-06-04 13:35:37 +0200118struct device *tty_port_register_device(struct tty_port *port,
119 struct tty_driver *driver, unsigned index,
120 struct device *device)
121{
Rob Herring30863652017-01-16 16:54:30 -0600122 return tty_port_register_device_attr(port, driver, index, device, NULL, NULL);
Jiri Slaby057eb852012-06-04 13:35:37 +0200123}
124EXPORT_SYMBOL_GPL(tty_port_register_device);
125
Tomas Hlavacekb1b79912012-09-06 23:17:47 +0200126/**
127 * tty_port_register_device_attr - register tty device
128 * @port: tty_port of the device
129 * @driver: tty_driver for this device
130 * @index: index of the tty
131 * @device: parent if exists, otherwise NULL
132 * @drvdata: Driver data to be set to device.
133 * @attr_grp: Attribute group to be set on device.
134 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100135 * It is the same as tty_register_device_attr() except the provided @port is
136 * linked to a concrete tty specified by @index. Use this or tty_port_install()
137 * (or both). Call tty_port_link_device() as a last resort.
Tomas Hlavacekb1b79912012-09-06 23:17:47 +0200138 */
139struct device *tty_port_register_device_attr(struct tty_port *port,
140 struct tty_driver *driver, unsigned index,
141 struct device *device, void *drvdata,
142 const struct attribute_group **attr_grp)
143{
144 tty_port_link_device(port, driver, index);
145 return tty_register_device_attr(driver, index, device, drvdata,
146 attr_grp);
147}
148EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
149
Johan Hovold8cde11b2017-05-18 17:33:00 +0200150/**
151 * tty_port_register_device_attr_serdev - register tty or serdev device
152 * @port: tty_port of the device
153 * @driver: tty_driver for this device
154 * @index: index of the tty
155 * @device: parent if exists, otherwise NULL
156 * @drvdata: driver data for the device
157 * @attr_grp: attribute group for the device
158 *
159 * Register a serdev or tty device depending on if the parent device has any
160 * defined serdev clients or not.
161 */
162struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
163 struct tty_driver *driver, unsigned index,
164 struct device *device, void *drvdata,
165 const struct attribute_group **attr_grp)
166{
167 struct device *dev;
168
169 tty_port_link_device(port, driver, index);
170
171 dev = serdev_tty_port_register(port, device, driver, index);
172 if (PTR_ERR(dev) != -ENODEV) {
173 /* Skip creating cdev if we registered a serdev device */
174 return dev;
175 }
176
177 return tty_register_device_attr(driver, index, device, drvdata,
178 attr_grp);
179}
180EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
181
182/**
183 * tty_port_register_device_serdev - register tty or serdev device
184 * @port: tty_port of the device
185 * @driver: tty_driver for this device
186 * @index: index of the tty
187 * @device: parent if exists, otherwise NULL
188 *
189 * Register a serdev or tty device depending on if the parent device has any
190 * defined serdev clients or not.
191 */
192struct device *tty_port_register_device_serdev(struct tty_port *port,
193 struct tty_driver *driver, unsigned index,
194 struct device *device)
195{
196 return tty_port_register_device_attr_serdev(port, driver, index,
197 device, NULL, NULL);
198}
199EXPORT_SYMBOL_GPL(tty_port_register_device_serdev);
200
201/**
202 * tty_port_unregister_device - deregister a tty or serdev device
203 * @port: tty_port of the device
204 * @driver: tty_driver for this device
205 * @index: index of the tty
206 *
207 * If a tty or serdev device is registered with a call to
208 * tty_port_register_device_serdev() then this function must be called when
209 * the device is gone.
210 */
211void tty_port_unregister_device(struct tty_port *port,
212 struct tty_driver *driver, unsigned index)
213{
214 int ret;
215
216 ret = serdev_tty_port_unregister(port);
217 if (ret == 0)
218 return;
219
220 tty_unregister_device(driver, index);
221}
222EXPORT_SYMBOL_GPL(tty_port_unregister_device);
223
Alan Cox9e485652008-10-13 10:37:07 +0100224int tty_port_alloc_xmit_buf(struct tty_port *port)
225{
226 /* We may sleep in get_zeroed_page() */
Alan Cox44e49092009-11-30 13:16:41 +0000227 mutex_lock(&port->buf_mutex);
Alan Cox9e485652008-10-13 10:37:07 +0100228 if (port->xmit_buf == NULL)
229 port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
Alan Cox44e49092009-11-30 13:16:41 +0000230 mutex_unlock(&port->buf_mutex);
Alan Cox9e485652008-10-13 10:37:07 +0100231 if (port->xmit_buf == NULL)
232 return -ENOMEM;
233 return 0;
234}
235EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
236
237void tty_port_free_xmit_buf(struct tty_port *port)
238{
Alan Cox44e49092009-11-30 13:16:41 +0000239 mutex_lock(&port->buf_mutex);
Alan Cox9e485652008-10-13 10:37:07 +0100240 if (port->xmit_buf != NULL) {
241 free_page((unsigned long)port->xmit_buf);
242 port->xmit_buf = NULL;
243 }
Alan Cox44e49092009-11-30 13:16:41 +0000244 mutex_unlock(&port->buf_mutex);
Alan Cox9e485652008-10-13 10:37:07 +0100245}
246EXPORT_SYMBOL(tty_port_free_xmit_buf);
247
Jiri Slabyde274bf2012-11-15 09:49:54 +0100248/**
249 * tty_port_destroy -- destroy inited port
Antonio Borneo1926e5d2017-09-08 08:59:42 +0200250 * @port: tty port to be destroyed
Jiri Slabyde274bf2012-11-15 09:49:54 +0100251 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100252 * When a port was initialized using tty_port_init(), one has to destroy the
253 * port by this function. Either indirectly by using &tty_port refcounting
254 * (tty_port_put()) or directly if refcounting is not used.
Jiri Slabyde274bf2012-11-15 09:49:54 +0100255 */
256void tty_port_destroy(struct tty_port *port)
257{
Peter Hurleye1760582015-10-17 16:36:23 -0400258 tty_buffer_cancel_work(port);
Jiri Slabyde274bf2012-11-15 09:49:54 +0100259 tty_buffer_free_all(port);
260}
261EXPORT_SYMBOL(tty_port_destroy);
262
Alan Cox568aafc2009-11-30 13:17:14 +0000263static void tty_port_destructor(struct kref *kref)
264{
265 struct tty_port *port = container_of(kref, struct tty_port, kref);
Peter Hurleye3bfea22013-09-18 20:42:39 -0400266
267 /* check if last port ref was dropped before tty release */
268 if (WARN_ON(port->itty))
269 return;
Alan Cox568aafc2009-11-30 13:17:14 +0000270 if (port->xmit_buf)
271 free_page((unsigned long)port->xmit_buf);
Jiri Slabyde274bf2012-11-15 09:49:54 +0100272 tty_port_destroy(port);
Jiri Slaby81c79832012-11-15 09:49:49 +0100273 if (port->ops && port->ops->destruct)
Alan Cox568aafc2009-11-30 13:17:14 +0000274 port->ops->destruct(port);
275 else
276 kfree(port);
277}
278
Jiri Slaby3be491d2021-11-26 09:16:06 +0100279/**
280 * tty_port_put -- drop a reference to tty_port
281 * @port: port to drop a reference of (can be NULL)
282 *
283 * The final put will destroy and free up the @port using
284 * @port->ops->destruct() hook, or using kfree() if not provided.
285 */
Alan Cox568aafc2009-11-30 13:17:14 +0000286void tty_port_put(struct tty_port *port)
287{
288 if (port)
289 kref_put(&port->kref, tty_port_destructor);
290}
291EXPORT_SYMBOL(tty_port_put);
Alan Cox9e485652008-10-13 10:37:07 +0100292
Alan Cox4a90f092008-10-13 10:39:46 +0100293/**
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100294 * tty_port_tty_get - get a tty reference
295 * @port: tty port
Alan Cox4a90f092008-10-13 10:39:46 +0100296 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100297 * Return a refcount protected tty instance or %NULL if the port is not
298 * associated with a tty (eg due to close or hangup).
Alan Cox4a90f092008-10-13 10:39:46 +0100299 */
Alan Cox4a90f092008-10-13 10:39:46 +0100300struct tty_struct *tty_port_tty_get(struct tty_port *port)
301{
302 unsigned long flags;
303 struct tty_struct *tty;
304
305 spin_lock_irqsave(&port->lock, flags);
306 tty = tty_kref_get(port->tty);
307 spin_unlock_irqrestore(&port->lock, flags);
308 return tty;
309}
310EXPORT_SYMBOL(tty_port_tty_get);
311
312/**
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100313 * tty_port_tty_set - set the tty of a port
314 * @port: tty port
315 * @tty: the tty
Alan Cox4a90f092008-10-13 10:39:46 +0100316 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100317 * Associate the port and tty pair. Manages any internal refcounts. Pass %NULL
318 * to deassociate a port.
Alan Cox4a90f092008-10-13 10:39:46 +0100319 */
Alan Cox4a90f092008-10-13 10:39:46 +0100320void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
321{
322 unsigned long flags;
323
324 spin_lock_irqsave(&port->lock, flags);
Markus Elfringa211b1a2014-11-21 13:42:29 +0100325 tty_kref_put(port->tty);
Alan Coxcb4bca32008-10-21 13:47:44 +0100326 port->tty = tty_kref_get(tty);
Alan Cox4a90f092008-10-13 10:39:46 +0100327 spin_unlock_irqrestore(&port->lock, flags);
328}
329EXPORT_SYMBOL(tty_port_tty_set);
Alan Cox31f35932009-01-02 13:45:05 +0000330
Jiri Slaby3be491d2021-11-26 09:16:06 +0100331/**
332 * tty_port_shutdown - internal helper to shutdown the device
333 * @port: tty port to be shut down
334 * @tty: the associated tty
335 *
336 * It is used by tty_port_hangup() and tty_port_close(). Its task is to
337 * shutdown the device if it was initialized (note consoles remain
338 * functioning). It lowers DTR/RTS (if @tty has HUPCL set) and invokes
339 * @port->ops->shutdown().
340 */
Johan Hovold957daca2013-03-07 15:55:51 +0100341static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
Alan Cox7ca0ff92009-09-19 13:13:20 -0700342{
Alan Cox64bc3972009-10-06 16:06:11 +0100343 mutex_lock(&port->mutex);
Johan Hovold8bde9652013-03-07 15:55:48 +0100344 if (port->console)
345 goto out;
346
Peter Hurleyd41861c2016-04-09 17:53:25 -0700347 if (tty_port_initialized(port)) {
348 tty_port_set_initialized(port, 0);
Johan Hovold957daca2013-03-07 15:55:51 +0100349 /*
350 * Drop DTR/RTS if HUPCL is set. This causes any attached
351 * modem to hang up the line.
352 */
353 if (tty && C_HUPCL(tty))
354 tty_port_lower_dtr_rts(port);
355
Johan Hovold0d3cb6f2019-04-03 09:40:53 +0200356 if (port->ops->shutdown)
Alan Cox7ca0ff92009-09-19 13:13:20 -0700357 port->ops->shutdown(port);
Johan Hovold8bde9652013-03-07 15:55:48 +0100358 }
359out:
Alan Cox64bc3972009-10-06 16:06:11 +0100360 mutex_unlock(&port->mutex);
Alan Cox7ca0ff92009-09-19 13:13:20 -0700361}
362
Alan Cox31f35932009-01-02 13:45:05 +0000363/**
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100364 * tty_port_hangup - hangup helper
365 * @port: tty port
Alan Cox3e616962009-01-02 13:45:26 +0000366 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100367 * Perform port level tty hangup flag and count changes. Drop the tty
368 * reference.
Peter Hurley9c9928b2014-06-16 09:17:02 -0400369 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100370 * Caller holds tty lock.
Alan Cox3e616962009-01-02 13:45:26 +0000371 */
Alan Cox3e616962009-01-02 13:45:26 +0000372void tty_port_hangup(struct tty_port *port)
373{
Johan Hovold957daca2013-03-07 15:55:51 +0100374 struct tty_struct *tty;
Alan Cox3e616962009-01-02 13:45:26 +0000375 unsigned long flags;
376
377 spin_lock_irqsave(&port->lock, flags);
378 port->count = 0;
Johan Hovold957daca2013-03-07 15:55:51 +0100379 tty = port->tty;
380 if (tty)
381 set_bit(TTY_IO_ERROR, &tty->flags);
Alan Cox3e616962009-01-02 13:45:26 +0000382 port->tty = NULL;
383 spin_unlock_irqrestore(&port->lock, flags);
Peter Hurley807c8d812016-04-09 17:53:22 -0700384 tty_port_set_active(port, 0);
Johan Hovold957daca2013-03-07 15:55:51 +0100385 tty_port_shutdown(port, tty);
386 tty_kref_put(tty);
Alan Cox3e616962009-01-02 13:45:26 +0000387 wake_up_interruptible(&port->open_wait);
Alan Coxbdc04e32009-09-19 13:13:31 -0700388 wake_up_interruptible(&port->delta_msr_wait);
Alan Cox3e616962009-01-02 13:45:26 +0000389}
390EXPORT_SYMBOL(tty_port_hangup);
391
392/**
Jiri Slabyaa27a092013-03-07 13:12:30 +0100393 * tty_port_tty_hangup - helper to hang up a tty
Jiri Slabyaa27a092013-03-07 13:12:30 +0100394 * @port: tty port
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100395 * @check_clocal: hang only ttys with %CLOCAL unset?
Jiri Slabyaa27a092013-03-07 13:12:30 +0100396 */
397void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
398{
399 struct tty_struct *tty = tty_port_tty_get(port);
400
Gianluca Anzolin1d9e6892013-07-25 07:26:16 +0200401 if (tty && (!check_clocal || !C_CLOCAL(tty)))
Jiri Slabyaa27a092013-03-07 13:12:30 +0100402 tty_hangup(tty);
Gianluca Anzolin1d9e6892013-07-25 07:26:16 +0200403 tty_kref_put(tty);
Jiri Slabyaa27a092013-03-07 13:12:30 +0100404}
405EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
406
407/**
Jiri Slaby6aad04f2013-03-07 13:12:29 +0100408 * tty_port_tty_wakeup - helper to wake up a tty
Jiri Slaby6aad04f2013-03-07 13:12:29 +0100409 * @port: tty port
410 */
411void tty_port_tty_wakeup(struct tty_port *port)
412{
Rob Herringc3485ee2017-02-02 13:48:05 -0600413 port->client_ops->write_wakeup(port);
Jiri Slaby6aad04f2013-03-07 13:12:29 +0100414}
415EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
416
417/**
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100418 * tty_port_carrier_raised - carrier raised check
419 * @port: tty port
Alan Cox31f35932009-01-02 13:45:05 +0000420 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100421 * Wrapper for the carrier detect logic. For the moment this is used
422 * to hide some internal details. This will eventually become entirely
423 * internal to the tty port.
Alan Cox31f35932009-01-02 13:45:05 +0000424 */
Alan Cox31f35932009-01-02 13:45:05 +0000425int tty_port_carrier_raised(struct tty_port *port)
426{
Johan Hovold0d3cb6f2019-04-03 09:40:53 +0200427 if (port->ops->carrier_raised == NULL)
Alan Cox31f35932009-01-02 13:45:05 +0000428 return 1;
429 return port->ops->carrier_raised(port);
430}
431EXPORT_SYMBOL(tty_port_carrier_raised);
Alan Cox5d951fb2009-01-02 13:45:19 +0000432
433/**
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100434 * tty_port_raise_dtr_rts - Raise DTR/RTS
435 * @port: tty port
Alan Cox5d951fb2009-01-02 13:45:19 +0000436 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100437 * Wrapper for the DTR/RTS raise logic. For the moment this is used to hide
438 * some internal details. This will eventually become entirely internal to the
439 * tty port.
Alan Cox5d951fb2009-01-02 13:45:19 +0000440 */
Alan Cox5d951fb2009-01-02 13:45:19 +0000441void tty_port_raise_dtr_rts(struct tty_port *port)
442{
Johan Hovold0d3cb6f2019-04-03 09:40:53 +0200443 if (port->ops->dtr_rts)
Alan Coxfcc8ac12009-06-11 12:24:17 +0100444 port->ops->dtr_rts(port, 1);
Alan Cox5d951fb2009-01-02 13:45:19 +0000445}
446EXPORT_SYMBOL(tty_port_raise_dtr_rts);
Alan Cox36c621d2009-01-02 13:46:10 +0000447
448/**
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100449 * tty_port_lower_dtr_rts - Lower DTR/RTS
450 * @port: tty port
Alan Coxfcc8ac12009-06-11 12:24:17 +0100451 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100452 * Wrapper for the DTR/RTS raise logic. For the moment this is used to hide
453 * some internal details. This will eventually become entirely internal to the
454 * tty port.
Alan Coxfcc8ac12009-06-11 12:24:17 +0100455 */
Alan Coxfcc8ac12009-06-11 12:24:17 +0100456void tty_port_lower_dtr_rts(struct tty_port *port)
457{
Johan Hovold0d3cb6f2019-04-03 09:40:53 +0200458 if (port->ops->dtr_rts)
Alan Coxfcc8ac12009-06-11 12:24:17 +0100459 port->ops->dtr_rts(port, 0);
460}
461EXPORT_SYMBOL(tty_port_lower_dtr_rts);
462
463/**
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100464 * tty_port_block_til_ready - Waiting logic for tty open
465 * @port: the tty port being opened
466 * @tty: the tty device being bound
467 * @filp: the file pointer of the opener or %NULL
Alan Cox36c621d2009-01-02 13:46:10 +0000468 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100469 * Implement the core POSIX/SuS tty behaviour when opening a tty device.
470 * Handles:
Alan Cox36c621d2009-01-02 13:46:10 +0000471 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100472 * - hangup (both before and during)
473 * - non blocking open
474 * - rts/dtr/dcd
475 * - signals
476 * - port flags and counts
Peter Hurleyc590f6b2014-06-16 09:17:01 -0400477 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100478 * The passed @port must implement the @port->ops->carrier_raised method if it
479 * can do carrier detect and the @port->ops->dtr_rts method if it supports
480 * software management of these lines. Note that the dtr/rts raise is done each
481 * iteration as a hangup may have previously dropped them while we wait.
Peter Hurleyc590f6b2014-06-16 09:17:01 -0400482 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100483 * Caller holds tty lock.
484 *
485 * Note: May drop and reacquire tty lock when blocking, so @tty and @port may
486 * have changed state (eg., may have been hung up).
Alan Cox36c621d2009-01-02 13:46:10 +0000487 */
Alan Cox36c621d2009-01-02 13:46:10 +0000488int tty_port_block_til_ready(struct tty_port *port,
489 struct tty_struct *tty, struct file *filp)
490{
491 int do_clocal = 0, retval;
492 unsigned long flags;
Jiri Slaby6af9a432009-06-24 18:35:05 +0100493 DEFINE_WAIT(wait);
Alan Cox36c621d2009-01-02 13:46:10 +0000494
Alan Cox36c621d2009-01-02 13:46:10 +0000495 /* if non-blocking mode is set we can pass directly to open unless
Xiaofei Tan1df92642021-05-12 17:26:25 +0800496 * the port has just hung up or is in another error state.
497 */
Peter Hurley18900ca2016-04-09 17:06:48 -0700498 if (tty_io_error(tty)) {
Peter Hurley807c8d812016-04-09 17:53:22 -0700499 tty_port_set_active(port, 1);
Alan Cox8627b962009-11-18 14:12:58 +0000500 return 0;
501 }
Alan Coxed3f0af2017-01-16 16:54:29 -0600502 if (filp == NULL || (filp->f_flags & O_NONBLOCK)) {
Alan Cox4175f3e2009-10-28 21:12:32 +0100503 /* Indicate we are open */
Peter Hurley9db276f2016-01-10 20:36:15 -0800504 if (C_BAUD(tty))
Alan Cox4175f3e2009-10-28 21:12:32 +0100505 tty_port_raise_dtr_rts(port);
Peter Hurley807c8d812016-04-09 17:53:22 -0700506 tty_port_set_active(port, 1);
Alan Cox36c621d2009-01-02 13:46:10 +0000507 return 0;
508 }
509
510 if (C_CLOCAL(tty))
511 do_clocal = 1;
512
513 /* Block waiting until we can proceed. We may need to wait for the
Xiaofei Tan1df92642021-05-12 17:26:25 +0800514 * carrier, but we must also wait for any close that is in progress
515 * before the next open may complete.
516 */
Alan Cox36c621d2009-01-02 13:46:10 +0000517
518 retval = 0;
Alan Cox36c621d2009-01-02 13:46:10 +0000519
520 /* The port lock protects the port counts */
521 spin_lock_irqsave(&port->lock, flags);
Peter Hurleye359a4e2014-06-16 09:17:06 -0400522 port->count--;
Alan Cox36c621d2009-01-02 13:46:10 +0000523 port->blocked_open++;
524 spin_unlock_irqrestore(&port->lock, flags);
525
526 while (1) {
527 /* Indicate we are open */
Peter Hurleyd41861c2016-04-09 17:53:25 -0700528 if (C_BAUD(tty) && tty_port_initialized(port))
Alan Cox78349092009-01-02 13:46:43 +0000529 tty_port_raise_dtr_rts(port);
Alan Cox36c621d2009-01-02 13:46:10 +0000530
Jiri Slaby3e3b5c02009-06-11 14:33:37 +0100531 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
Alan Coxd774a562009-10-06 16:06:21 +0100532 /* Check for a hangup or uninitialised port.
Xiaofei Tan1df92642021-05-12 17:26:25 +0800533 * Return accordingly.
534 */
Peter Hurleyd41861c2016-04-09 17:53:25 -0700535 if (tty_hung_up_p(filp) || !tty_port_initialized(port)) {
Alan Cox36c621d2009-01-02 13:46:10 +0000536 if (port->flags & ASYNC_HUP_NOTIFY)
537 retval = -EAGAIN;
538 else
539 retval = -ERESTARTSYS;
540 break;
541 }
Jiri Slaby0eee50a2012-01-12 22:55:15 +0100542 /*
543 * Probe the carrier. For devices with no carrier detect
544 * tty_port_carrier_raised will always return true.
545 * Never ask drivers if CLOCAL is set, this causes troubles
546 * on some hardware.
547 */
Peter Hurleyfef062c2015-10-10 16:00:52 -0400548 if (do_clocal || tty_port_carrier_raised(port))
Alan Cox36c621d2009-01-02 13:46:10 +0000549 break;
550 if (signal_pending(current)) {
551 retval = -ERESTARTSYS;
552 break;
553 }
Alan Cox89c8d912012-08-08 16:30:13 +0100554 tty_unlock(tty);
Alan Cox36c621d2009-01-02 13:46:10 +0000555 schedule();
Alan Cox89c8d912012-08-08 16:30:13 +0100556 tty_lock(tty);
Alan Cox36c621d2009-01-02 13:46:10 +0000557 }
Jiri Slaby3e3b5c02009-06-11 14:33:37 +0100558 finish_wait(&port->open_wait, &wait);
Alan Cox36c621d2009-01-02 13:46:10 +0000559
560 /* Update counts. A parallel hangup will have set count to zero and
Xiaofei Tan1df92642021-05-12 17:26:25 +0800561 * we must not mess that up further.
562 */
Alan Cox36c621d2009-01-02 13:46:10 +0000563 spin_lock_irqsave(&port->lock, flags);
564 if (!tty_hung_up_p(filp))
565 port->count++;
566 port->blocked_open--;
Alan Cox36c621d2009-01-02 13:46:10 +0000567 spin_unlock_irqrestore(&port->lock, flags);
Peter Hurley807c8d812016-04-09 17:53:22 -0700568 if (retval == 0)
569 tty_port_set_active(port, 1);
Alan Coxecc2e052009-07-17 16:17:26 +0100570 return retval;
Alan Cox36c621d2009-01-02 13:46:10 +0000571}
572EXPORT_SYMBOL(tty_port_block_til_ready);
573
Johan Hovoldb74414f2013-03-07 15:55:52 +0100574static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty)
575{
576 unsigned int bps = tty_get_baud_rate(tty);
577 long timeout;
578
579 if (bps > 1200) {
580 timeout = (HZ * 10 * port->drain_delay) / bps;
581 timeout = max_t(long, timeout, HZ / 10);
582 } else {
583 timeout = 2 * HZ;
584 }
585 schedule_timeout_interruptible(timeout);
586}
587
Jiri Slaby3be491d2021-11-26 09:16:06 +0100588/**
589 * tty_port_close_start - helper for tty->ops->close, part 1/2
590 * @port: tty_port of the device
591 * @tty: tty being closed
592 * @filp: passed file pointer
593 *
594 * Decrements and checks open count. Flushes the port if this is the last
595 * close. That means, dropping the data from the outpu buffer on the device and
596 * waiting for sending logic to finish. The rest of close handling is performed
597 * in tty_port_close_end().
598 *
599 * Locking: Caller holds tty lock.
600 *
601 * Return: 1 if this is the last close, otherwise 0
602 */
Alan Coxd774a562009-10-06 16:06:21 +0100603int tty_port_close_start(struct tty_port *port,
604 struct tty_struct *tty, struct file *filp)
Alan Coxa6614992009-01-02 13:46:50 +0000605{
606 unsigned long flags;
607
Peter Hurley633caba2014-11-05 12:40:03 -0500608 if (tty_hung_up_p(filp))
Alan Coxa6614992009-01-02 13:46:50 +0000609 return 0;
Alan Coxa6614992009-01-02 13:46:50 +0000610
Peter Hurley633caba2014-11-05 12:40:03 -0500611 spin_lock_irqsave(&port->lock, flags);
Alan Coxd774a562009-10-06 16:06:21 +0100612 if (tty->count == 1 && port->count != 1) {
Peter Hurley339f36b2015-11-08 13:01:13 -0500613 tty_warn(tty, "%s: tty->count = 1 port count = %d\n", __func__,
614 port->count);
Alan Coxa6614992009-01-02 13:46:50 +0000615 port->count = 1;
616 }
617 if (--port->count < 0) {
Peter Hurley339f36b2015-11-08 13:01:13 -0500618 tty_warn(tty, "%s: bad port count (%d)\n", __func__,
619 port->count);
Alan Coxa6614992009-01-02 13:46:50 +0000620 port->count = 0;
621 }
622
623 if (port->count) {
624 spin_unlock_irqrestore(&port->lock, flags);
625 return 0;
626 }
Alan Coxa6614992009-01-02 13:46:50 +0000627 spin_unlock_irqrestore(&port->lock, flags);
Johan Hovold0b2588c2013-03-07 15:55:53 +0100628
Peter Hurleyddc7b752014-06-16 09:17:03 -0400629 tty->closing = 1;
630
Peter Hurleyd41861c2016-04-09 17:53:25 -0700631 if (tty_port_initialized(port)) {
Johan Hovold0b2588c2013-03-07 15:55:53 +0100632 /* Don't block on a stalled port, just pull the chain */
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200633 if (tty->flow.tco_stopped)
Johan Hovold0b2588c2013-03-07 15:55:53 +0100634 tty_driver_flush_buffer(tty);
635 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
Peter Hurley79c1faa2015-10-10 16:00:51 -0400636 tty_wait_until_sent(tty, port->closing_wait);
Johan Hovold0b2588c2013-03-07 15:55:53 +0100637 if (port->drain_delay)
638 tty_port_drain_delay(port, tty);
639 }
Alan Coxe707c352009-11-05 13:27:57 +0000640 /* Flush the ldisc buffering */
641 tty_ldisc_flush(tty);
642
Peter Hurley469d6d02013-09-18 20:47:06 -0400643 /* Report to caller this is the last port reference */
Alan Coxa6614992009-01-02 13:46:50 +0000644 return 1;
645}
646EXPORT_SYMBOL(tty_port_close_start);
647
Jiri Slaby3be491d2021-11-26 09:16:06 +0100648/**
649 * tty_port_close_end - helper for tty->ops->close, part 2/2
650 * @port: tty_port of the device
651 * @tty: tty being closed
652 *
653 * This is a continuation of the first part: tty_port_close_start(). This
654 * should be called after turning off the device. It flushes the data from the
655 * line discipline and delays the close by @port->close_delay.
656 *
657 * Locking: Caller holds tty lock.
658 */
Alan Coxa6614992009-01-02 13:46:50 +0000659void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
660{
661 unsigned long flags;
662
Peter Hurley3f40f5b2014-11-05 12:40:05 -0500663 tty_ldisc_flush(tty);
Alan Coxa6614992009-01-02 13:46:50 +0000664 tty->closing = 0;
665
Peter Hurleyddc7b752014-06-16 09:17:03 -0400666 spin_lock_irqsave(&port->lock, flags);
667
Alan Coxa6614992009-01-02 13:46:50 +0000668 if (port->blocked_open) {
669 spin_unlock_irqrestore(&port->lock, flags);
Peter Hurley5823323e2016-01-10 20:36:14 -0800670 if (port->close_delay)
671 msleep_interruptible(jiffies_to_msecs(port->close_delay));
Alan Coxa6614992009-01-02 13:46:50 +0000672 spin_lock_irqsave(&port->lock, flags);
673 wake_up_interruptible(&port->open_wait);
674 }
Alan Coxa6614992009-01-02 13:46:50 +0000675 spin_unlock_irqrestore(&port->lock, flags);
Peter Hurley807c8d812016-04-09 17:53:22 -0700676 tty_port_set_active(port, 0);
Alan Coxa6614992009-01-02 13:46:50 +0000677}
678EXPORT_SYMBOL(tty_port_close_end);
Alan Cox7ca0ff92009-09-19 13:13:20 -0700679
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100680/**
681 * tty_port_close - generic tty->ops->close handler
682 * @port: tty_port of the device
683 * @tty: tty being closed
684 * @filp: passed file pointer
Peter Hurley0733db912014-06-16 09:16:59 -0400685 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100686 * It is a generic helper to be used in driver's @tty->ops->close. It wraps a
687 * sequence of tty_port_close_start(), tty_port_shutdown(), and
688 * tty_port_close_end(). The latter two are called only if this is the last
689 * close. See the respective functions for the details.
690 *
691 * Locking: Caller holds tty lock
Peter Hurley0733db912014-06-16 09:16:59 -0400692 */
Alan Cox7ca0ff92009-09-19 13:13:20 -0700693void tty_port_close(struct tty_port *port, struct tty_struct *tty,
694 struct file *filp)
695{
696 if (tty_port_close_start(port, tty, filp) == 0)
697 return;
Johan Hovold957daca2013-03-07 15:55:51 +0100698 tty_port_shutdown(port, tty);
Chanho Park2a486022018-11-22 18:23:47 +0900699 if (!port->console)
700 set_bit(TTY_IO_ERROR, &tty->flags);
Alan Cox7ca0ff92009-09-19 13:13:20 -0700701 tty_port_close_end(port, tty);
702 tty_port_tty_set(port, NULL);
703}
704EXPORT_SYMBOL(tty_port_close);
Alan Cox64bc3972009-10-06 16:06:11 +0100705
Jiri Slaby72a33bf2012-08-07 21:47:49 +0200706/**
707 * tty_port_install - generic tty->ops->install handler
708 * @port: tty_port of the device
709 * @driver: tty_driver for this device
710 * @tty: tty to be installed
711 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100712 * It is the same as tty_standard_install() except the provided @port is linked
713 * to a concrete tty specified by @tty. Use this or tty_port_register_device()
714 * (or both). Call tty_port_link_device() as a last resort.
Jiri Slaby72a33bf2012-08-07 21:47:49 +0200715 */
Jiri Slaby695586c2012-06-04 13:35:32 +0200716int tty_port_install(struct tty_port *port, struct tty_driver *driver,
717 struct tty_struct *tty)
718{
719 tty->port = port;
720 return tty_standard_install(driver, tty);
721}
722EXPORT_SYMBOL_GPL(tty_port_install);
723
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100724/**
725 * tty_port_open - generic tty->ops->open handler
726 * @port: tty_port of the device
727 * @tty: tty to be opened
728 * @filp: passed file pointer
Peter Hurleyaddd4672014-06-16 09:17:00 -0400729 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100730 * It is a generic helper to be used in driver's @tty->ops->open. It activates
731 * the devices using @port->ops->activate if not active already. And waits for
732 * the device to be ready using tty_port_block_til_ready() (e.g. raises
733 * DTR/CTS and waits for carrier).
Peter Hurleyaddd4672014-06-16 09:17:00 -0400734 *
Jiri Slabycb6f6f92021-11-26 09:15:59 +0100735 * Locking: Caller holds tty lock.
736 *
737 * Note: may drop and reacquire tty lock (in tty_port_block_til_ready()) so
738 * @tty and @port may have changed state (eg., may be hung up now).
Peter Hurleyaddd4672014-06-16 09:17:00 -0400739 */
Alan Cox64bc3972009-10-06 16:06:11 +0100740int tty_port_open(struct tty_port *port, struct tty_struct *tty,
Alan Coxd774a562009-10-06 16:06:21 +0100741 struct file *filp)
Alan Cox64bc3972009-10-06 16:06:11 +0100742{
743 spin_lock_irq(&port->lock);
Peter Hurleye359a4e2014-06-16 09:17:06 -0400744 ++port->count;
Alan Cox64bc3972009-10-06 16:06:11 +0100745 spin_unlock_irq(&port->lock);
746 tty_port_tty_set(port, tty);
747
748 /*
749 * Do the device-specific open only if the hardware isn't
750 * already initialized. Serialize open and shutdown using the
751 * port mutex.
752 */
753
754 mutex_lock(&port->mutex);
755
Peter Hurleyd41861c2016-04-09 17:53:25 -0700756 if (!tty_port_initialized(port)) {
Alan Coxa9a37ec2009-11-30 13:16:57 +0000757 clear_bit(TTY_IO_ERROR, &tty->flags);
Johan Hovold0d3cb6f2019-04-03 09:40:53 +0200758 if (port->ops->activate) {
Alan Cox64bc3972009-10-06 16:06:11 +0100759 int retval = port->ops->activate(port, tty);
Xiaofei Tan54ad59a2021-05-12 17:26:24 +0800760
Alan Cox64bc3972009-10-06 16:06:11 +0100761 if (retval) {
Alan Coxd774a562009-10-06 16:06:21 +0100762 mutex_unlock(&port->mutex);
763 return retval;
764 }
765 }
Peter Hurleyd41861c2016-04-09 17:53:25 -0700766 tty_port_set_initialized(port, 1);
Alan Cox64bc3972009-10-06 16:06:11 +0100767 }
768 mutex_unlock(&port->mutex);
769 return tty_port_block_til_ready(port, tty, filp);
770}
Alan Cox64bc3972009-10-06 16:06:11 +0100771EXPORT_SYMBOL(tty_port_open);