xref: /openbmc/linux/drivers/tty/tty_port.c (revision 05bcf503)
1 /*
2  * Tty port functions
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 
21 void tty_port_init(struct tty_port *port)
22 {
23 	memset(port, 0, sizeof(*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 }
34 EXPORT_SYMBOL(tty_port_init);
35 
36 /**
37  * tty_port_link_device - link tty and tty_port
38  * @port: tty_port of the device
39  * @driver: tty_driver for this device
40  * @index: index of the tty
41  *
42  * Provide the tty layer wit ha link from a tty (specified by @index) to a
43  * tty_port (@port). Use this only if neither tty_port_register_device nor
44  * tty_port_install is used in the driver. If used, this has to be called before
45  * tty_register_driver.
46  */
47 void 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 }
54 EXPORT_SYMBOL_GPL(tty_port_link_device);
55 
56 /**
57  * tty_port_register_device - register tty device
58  * @port: tty_port of the device
59  * @driver: tty_driver for this device
60  * @index: index of the tty
61  * @device: parent if exists, otherwise NULL
62  *
63  * It is the same as tty_register_device except the provided @port is linked to
64  * a concrete tty specified by @index. Use this or tty_port_install (or both).
65  * Call tty_port_link_device as a last resort.
66  */
67 struct 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 }
74 EXPORT_SYMBOL_GPL(tty_port_register_device);
75 
76 /**
77  * tty_port_register_device_attr - register tty device
78  * @port: tty_port of the device
79  * @driver: tty_driver for this device
80  * @index: index of the tty
81  * @device: parent if exists, otherwise NULL
82  * @drvdata: Driver data to be set to device.
83  * @attr_grp: Attribute group to be set on device.
84  *
85  * It is the same as tty_register_device_attr except the provided @port is
86  * linked to a concrete tty specified by @index. Use this or tty_port_install
87  * (or both). Call tty_port_link_device as a last resort.
88  */
89 struct 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 }
98 EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
99 
100 int tty_port_alloc_xmit_buf(struct tty_port *port)
101 {
102 	/* We may sleep in get_zeroed_page() */
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 }
111 EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
112 
113 void 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 }
122 EXPORT_SYMBOL(tty_port_free_xmit_buf);
123 
124 static void tty_port_destructor(struct kref *kref)
125 {
126 	struct tty_port *port = container_of(kref, struct tty_port, kref);
127 	if (port->xmit_buf)
128 		free_page((unsigned long)port->xmit_buf);
129 	if (port->ops->destruct)
130 		port->ops->destruct(port);
131 	else
132 		kfree(port);
133 }
134 
135 void tty_port_put(struct tty_port *port)
136 {
137 	if (port)
138 		kref_put(&port->kref, tty_port_destructor);
139 }
140 EXPORT_SYMBOL(tty_port_put);
141 
142 /**
143  *	tty_port_tty_get	-	get a tty reference
144  *	@port: tty port
145  *
146  *	Return a refcount protected tty instance or NULL if the port is not
147  *	associated with a tty (eg due to close or hangup)
148  */
149 
150 struct tty_struct *tty_port_tty_get(struct tty_port *port)
151 {
152 	unsigned long flags;
153 	struct tty_struct *tty;
154 
155 	spin_lock_irqsave(&port->lock, flags);
156 	tty = tty_kref_get(port->tty);
157 	spin_unlock_irqrestore(&port->lock, flags);
158 	return tty;
159 }
160 EXPORT_SYMBOL(tty_port_tty_get);
161 
162 /**
163  *	tty_port_tty_set	-	set the tty of a port
164  *	@port: tty port
165  *	@tty: the tty
166  *
167  *	Associate the port and tty pair. Manages any internal refcounts.
168  *	Pass NULL to deassociate a port
169  */
170 
171 void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
172 {
173 	unsigned long flags;
174 
175 	spin_lock_irqsave(&port->lock, flags);
176 	if (port->tty)
177 		tty_kref_put(port->tty);
178 	port->tty = tty_kref_get(tty);
179 	spin_unlock_irqrestore(&port->lock, flags);
180 }
181 EXPORT_SYMBOL(tty_port_tty_set);
182 
183 static void tty_port_shutdown(struct tty_port *port)
184 {
185 	mutex_lock(&port->mutex);
186 	if (port->ops->shutdown && !port->console &&
187 		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
188 			port->ops->shutdown(port);
189 	mutex_unlock(&port->mutex);
190 }
191 
192 /**
193  *	tty_port_hangup		-	hangup helper
194  *	@port: tty port
195  *
196  *	Perform port level tty hangup flag and count changes. Drop the tty
197  *	reference.
198  */
199 
200 void tty_port_hangup(struct tty_port *port)
201 {
202 	unsigned long flags;
203 
204 	spin_lock_irqsave(&port->lock, flags);
205 	port->count = 0;
206 	port->flags &= ~ASYNC_NORMAL_ACTIVE;
207 	if (port->tty) {
208 		set_bit(TTY_IO_ERROR, &port->tty->flags);
209 		tty_kref_put(port->tty);
210 	}
211 	port->tty = NULL;
212 	spin_unlock_irqrestore(&port->lock, flags);
213 	wake_up_interruptible(&port->open_wait);
214 	wake_up_interruptible(&port->delta_msr_wait);
215 	tty_port_shutdown(port);
216 }
217 EXPORT_SYMBOL(tty_port_hangup);
218 
219 /**
220  *	tty_port_carrier_raised	-	carrier raised check
221  *	@port: tty port
222  *
223  *	Wrapper for the carrier detect logic. For the moment this is used
224  *	to hide some internal details. This will eventually become entirely
225  *	internal to the tty port.
226  */
227 
228 int tty_port_carrier_raised(struct tty_port *port)
229 {
230 	if (port->ops->carrier_raised == NULL)
231 		return 1;
232 	return port->ops->carrier_raised(port);
233 }
234 EXPORT_SYMBOL(tty_port_carrier_raised);
235 
236 /**
237  *	tty_port_raise_dtr_rts	-	Raise DTR/RTS
238  *	@port: tty port
239  *
240  *	Wrapper for the DTR/RTS raise logic. For the moment this is used
241  *	to hide some internal details. This will eventually become entirely
242  *	internal to the tty port.
243  */
244 
245 void tty_port_raise_dtr_rts(struct tty_port *port)
246 {
247 	if (port->ops->dtr_rts)
248 		port->ops->dtr_rts(port, 1);
249 }
250 EXPORT_SYMBOL(tty_port_raise_dtr_rts);
251 
252 /**
253  *	tty_port_lower_dtr_rts	-	Lower DTR/RTS
254  *	@port: tty port
255  *
256  *	Wrapper for the DTR/RTS raise logic. For the moment this is used
257  *	to hide some internal details. This will eventually become entirely
258  *	internal to the tty port.
259  */
260 
261 void tty_port_lower_dtr_rts(struct tty_port *port)
262 {
263 	if (port->ops->dtr_rts)
264 		port->ops->dtr_rts(port, 0);
265 }
266 EXPORT_SYMBOL(tty_port_lower_dtr_rts);
267 
268 /**
269  *	tty_port_block_til_ready	-	Waiting logic for tty open
270  *	@port: the tty port being opened
271  *	@tty: the tty device being bound
272  *	@filp: the file pointer of the opener
273  *
274  *	Implement the core POSIX/SuS tty behaviour when opening a tty device.
275  *	Handles:
276  *		- hangup (both before and during)
277  *		- non blocking open
278  *		- rts/dtr/dcd
279  *		- signals
280  *		- port flags and counts
281  *
282  *	The passed tty_port must implement the carrier_raised method if it can
283  *	do carrier detect and the dtr_rts method if it supports software
284  *	management of these lines. Note that the dtr/rts raise is done each
285  *	iteration as a hangup may have previously dropped them while we wait.
286  */
287 
288 int tty_port_block_til_ready(struct tty_port *port,
289 				struct tty_struct *tty, struct file *filp)
290 {
291 	int do_clocal = 0, retval;
292 	unsigned long flags;
293 	DEFINE_WAIT(wait);
294 
295 	/* block if port is in the process of being closed */
296 	if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
297 		wait_event_interruptible_tty(tty, port->close_wait,
298 				!(port->flags & ASYNC_CLOSING));
299 		if (port->flags & ASYNC_HUP_NOTIFY)
300 			return -EAGAIN;
301 		else
302 			return -ERESTARTSYS;
303 	}
304 
305 	/* if non-blocking mode is set we can pass directly to open unless
306 	   the port has just hung up or is in another error state */
307 	if (tty->flags & (1 << TTY_IO_ERROR)) {
308 		port->flags |= ASYNC_NORMAL_ACTIVE;
309 		return 0;
310 	}
311 	if (filp->f_flags & O_NONBLOCK) {
312 		/* Indicate we are open */
313 		if (tty->termios.c_cflag & CBAUD)
314 			tty_port_raise_dtr_rts(port);
315 		port->flags |= ASYNC_NORMAL_ACTIVE;
316 		return 0;
317 	}
318 
319 	if (C_CLOCAL(tty))
320 		do_clocal = 1;
321 
322 	/* Block waiting until we can proceed. We may need to wait for the
323 	   carrier, but we must also wait for any close that is in progress
324 	   before the next open may complete */
325 
326 	retval = 0;
327 
328 	/* The port lock protects the port counts */
329 	spin_lock_irqsave(&port->lock, flags);
330 	if (!tty_hung_up_p(filp))
331 		port->count--;
332 	port->blocked_open++;
333 	spin_unlock_irqrestore(&port->lock, flags);
334 
335 	while (1) {
336 		/* Indicate we are open */
337 		if (tty->termios.c_cflag & CBAUD)
338 			tty_port_raise_dtr_rts(port);
339 
340 		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
341 		/* Check for a hangup or uninitialised port.
342 							Return accordingly */
343 		if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
344 			if (port->flags & ASYNC_HUP_NOTIFY)
345 				retval = -EAGAIN;
346 			else
347 				retval = -ERESTARTSYS;
348 			break;
349 		}
350 		/*
351 		 * Probe the carrier. For devices with no carrier detect
352 		 * tty_port_carrier_raised will always return true.
353 		 * Never ask drivers if CLOCAL is set, this causes troubles
354 		 * on some hardware.
355 		 */
356 		if (!(port->flags & ASYNC_CLOSING) &&
357 				(do_clocal || tty_port_carrier_raised(port)))
358 			break;
359 		if (signal_pending(current)) {
360 			retval = -ERESTARTSYS;
361 			break;
362 		}
363 		tty_unlock(tty);
364 		schedule();
365 		tty_lock(tty);
366 	}
367 	finish_wait(&port->open_wait, &wait);
368 
369 	/* Update counts. A parallel hangup will have set count to zero and
370 	   we must not mess that up further */
371 	spin_lock_irqsave(&port->lock, flags);
372 	if (!tty_hung_up_p(filp))
373 		port->count++;
374 	port->blocked_open--;
375 	if (retval == 0)
376 		port->flags |= ASYNC_NORMAL_ACTIVE;
377 	spin_unlock_irqrestore(&port->lock, flags);
378 	return retval;
379 }
380 EXPORT_SYMBOL(tty_port_block_til_ready);
381 
382 int tty_port_close_start(struct tty_port *port,
383 				struct tty_struct *tty, struct file *filp)
384 {
385 	unsigned long flags;
386 
387 	spin_lock_irqsave(&port->lock, flags);
388 	if (tty_hung_up_p(filp)) {
389 		spin_unlock_irqrestore(&port->lock, flags);
390 		return 0;
391 	}
392 
393 	if (tty->count == 1 && port->count != 1) {
394 		printk(KERN_WARNING
395 		    "tty_port_close_start: tty->count = 1 port count = %d.\n",
396 								port->count);
397 		port->count = 1;
398 	}
399 	if (--port->count < 0) {
400 		printk(KERN_WARNING "tty_port_close_start: count = %d\n",
401 								port->count);
402 		port->count = 0;
403 	}
404 
405 	if (port->count) {
406 		spin_unlock_irqrestore(&port->lock, flags);
407 		if (port->ops->drop)
408 			port->ops->drop(port);
409 		return 0;
410 	}
411 	set_bit(ASYNCB_CLOSING, &port->flags);
412 	tty->closing = 1;
413 	spin_unlock_irqrestore(&port->lock, flags);
414 	/* Don't block on a stalled port, just pull the chain */
415 	if (tty->flow_stopped)
416 		tty_driver_flush_buffer(tty);
417 	if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
418 			port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
419 		tty_wait_until_sent_from_close(tty, port->closing_wait);
420 	if (port->drain_delay) {
421 		unsigned int bps = tty_get_baud_rate(tty);
422 		long timeout;
423 
424 		if (bps > 1200)
425 			timeout = max_t(long,
426 				(HZ * 10 * port->drain_delay) / bps, HZ / 10);
427 		else
428 			timeout = 2 * HZ;
429 		schedule_timeout_interruptible(timeout);
430 	}
431 	/* Flush the ldisc buffering */
432 	tty_ldisc_flush(tty);
433 
434 	/* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
435 	   hang up the line */
436 	if (tty->termios.c_cflag & HUPCL)
437 		tty_port_lower_dtr_rts(port);
438 
439 	/* Don't call port->drop for the last reference. Callers will want
440 	   to drop the last active reference in ->shutdown() or the tty
441 	   shutdown path */
442 	return 1;
443 }
444 EXPORT_SYMBOL(tty_port_close_start);
445 
446 void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
447 {
448 	unsigned long flags;
449 
450 	spin_lock_irqsave(&port->lock, flags);
451 	tty->closing = 0;
452 
453 	if (port->blocked_open) {
454 		spin_unlock_irqrestore(&port->lock, flags);
455 		if (port->close_delay) {
456 			msleep_interruptible(
457 				jiffies_to_msecs(port->close_delay));
458 		}
459 		spin_lock_irqsave(&port->lock, flags);
460 		wake_up_interruptible(&port->open_wait);
461 	}
462 	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
463 	wake_up_interruptible(&port->close_wait);
464 	spin_unlock_irqrestore(&port->lock, flags);
465 }
466 EXPORT_SYMBOL(tty_port_close_end);
467 
468 void tty_port_close(struct tty_port *port, struct tty_struct *tty,
469 							struct file *filp)
470 {
471 	if (tty_port_close_start(port, tty, filp) == 0)
472 		return;
473 	tty_port_shutdown(port);
474 	set_bit(TTY_IO_ERROR, &tty->flags);
475 	tty_port_close_end(port, tty);
476 	tty_port_tty_set(port, NULL);
477 }
478 EXPORT_SYMBOL(tty_port_close);
479 
480 /**
481  * tty_port_install - generic tty->ops->install handler
482  * @port: tty_port of the device
483  * @driver: tty_driver for this device
484  * @tty: tty to be installed
485  *
486  * It is the same as tty_standard_install except the provided @port is linked
487  * to a concrete tty specified by @tty. Use this or tty_port_register_device
488  * (or both). Call tty_port_link_device as a last resort.
489  */
490 int tty_port_install(struct tty_port *port, struct tty_driver *driver,
491 		struct tty_struct *tty)
492 {
493 	tty->port = port;
494 	return tty_standard_install(driver, tty);
495 }
496 EXPORT_SYMBOL_GPL(tty_port_install);
497 
498 int tty_port_open(struct tty_port *port, struct tty_struct *tty,
499 							struct file *filp)
500 {
501 	spin_lock_irq(&port->lock);
502 	if (!tty_hung_up_p(filp))
503 		++port->count;
504 	spin_unlock_irq(&port->lock);
505 	tty_port_tty_set(port, tty);
506 
507 	/*
508 	 * Do the device-specific open only if the hardware isn't
509 	 * already initialized. Serialize open and shutdown using the
510 	 * port mutex.
511 	 */
512 
513 	mutex_lock(&port->mutex);
514 
515 	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
516 		clear_bit(TTY_IO_ERROR, &tty->flags);
517 		if (port->ops->activate) {
518 			int retval = port->ops->activate(port, tty);
519 			if (retval) {
520 				mutex_unlock(&port->mutex);
521 				return retval;
522 			}
523 		}
524 		set_bit(ASYNCB_INITIALIZED, &port->flags);
525 	}
526 	mutex_unlock(&port->mutex);
527 	return tty_port_block_til_ready(port, tty, filp);
528 }
529 
530 EXPORT_SYMBOL(tty_port_open);
531