xref: /openbmc/linux/drivers/tty/tty_port.c (revision 22fd411a)
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 int tty_port_alloc_xmit_buf(struct tty_port *port)
37 {
38 	/* We may sleep in get_zeroed_page() */
39 	mutex_lock(&port->buf_mutex);
40 	if (port->xmit_buf == NULL)
41 		port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
42 	mutex_unlock(&port->buf_mutex);
43 	if (port->xmit_buf == NULL)
44 		return -ENOMEM;
45 	return 0;
46 }
47 EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
48 
49 void tty_port_free_xmit_buf(struct tty_port *port)
50 {
51 	mutex_lock(&port->buf_mutex);
52 	if (port->xmit_buf != NULL) {
53 		free_page((unsigned long)port->xmit_buf);
54 		port->xmit_buf = NULL;
55 	}
56 	mutex_unlock(&port->buf_mutex);
57 }
58 EXPORT_SYMBOL(tty_port_free_xmit_buf);
59 
60 static void tty_port_destructor(struct kref *kref)
61 {
62 	struct tty_port *port = container_of(kref, struct tty_port, kref);
63 	if (port->xmit_buf)
64 		free_page((unsigned long)port->xmit_buf);
65 	if (port->ops->destruct)
66 		port->ops->destruct(port);
67 	else
68 		kfree(port);
69 }
70 
71 void tty_port_put(struct tty_port *port)
72 {
73 	if (port)
74 		kref_put(&port->kref, tty_port_destructor);
75 }
76 EXPORT_SYMBOL(tty_port_put);
77 
78 /**
79  *	tty_port_tty_get	-	get a tty reference
80  *	@port: tty port
81  *
82  *	Return a refcount protected tty instance or NULL if the port is not
83  *	associated with a tty (eg due to close or hangup)
84  */
85 
86 struct tty_struct *tty_port_tty_get(struct tty_port *port)
87 {
88 	unsigned long flags;
89 	struct tty_struct *tty;
90 
91 	spin_lock_irqsave(&port->lock, flags);
92 	tty = tty_kref_get(port->tty);
93 	spin_unlock_irqrestore(&port->lock, flags);
94 	return tty;
95 }
96 EXPORT_SYMBOL(tty_port_tty_get);
97 
98 /**
99  *	tty_port_tty_set	-	set the tty of a port
100  *	@port: tty port
101  *	@tty: the tty
102  *
103  *	Associate the port and tty pair. Manages any internal refcounts.
104  *	Pass NULL to deassociate a port
105  */
106 
107 void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
108 {
109 	unsigned long flags;
110 
111 	spin_lock_irqsave(&port->lock, flags);
112 	if (port->tty)
113 		tty_kref_put(port->tty);
114 	port->tty = tty_kref_get(tty);
115 	spin_unlock_irqrestore(&port->lock, flags);
116 }
117 EXPORT_SYMBOL(tty_port_tty_set);
118 
119 static void tty_port_shutdown(struct tty_port *port)
120 {
121 	mutex_lock(&port->mutex);
122 	if (port->ops->shutdown && !port->console &&
123 		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
124 			port->ops->shutdown(port);
125 	mutex_unlock(&port->mutex);
126 }
127 
128 /**
129  *	tty_port_hangup		-	hangup helper
130  *	@port: tty port
131  *
132  *	Perform port level tty hangup flag and count changes. Drop the tty
133  *	reference.
134  */
135 
136 void tty_port_hangup(struct tty_port *port)
137 {
138 	unsigned long flags;
139 
140 	spin_lock_irqsave(&port->lock, flags);
141 	port->count = 0;
142 	port->flags &= ~ASYNC_NORMAL_ACTIVE;
143 	if (port->tty) {
144 		set_bit(TTY_IO_ERROR, &port->tty->flags);
145 		tty_kref_put(port->tty);
146 	}
147 	port->tty = NULL;
148 	spin_unlock_irqrestore(&port->lock, flags);
149 	wake_up_interruptible(&port->open_wait);
150 	wake_up_interruptible(&port->delta_msr_wait);
151 	tty_port_shutdown(port);
152 }
153 EXPORT_SYMBOL(tty_port_hangup);
154 
155 /**
156  *	tty_port_carrier_raised	-	carrier raised check
157  *	@port: tty port
158  *
159  *	Wrapper for the carrier detect logic. For the moment this is used
160  *	to hide some internal details. This will eventually become entirely
161  *	internal to the tty port.
162  */
163 
164 int tty_port_carrier_raised(struct tty_port *port)
165 {
166 	if (port->ops->carrier_raised == NULL)
167 		return 1;
168 	return port->ops->carrier_raised(port);
169 }
170 EXPORT_SYMBOL(tty_port_carrier_raised);
171 
172 /**
173  *	tty_port_raise_dtr_rts	-	Raise DTR/RTS
174  *	@port: tty port
175  *
176  *	Wrapper for the DTR/RTS raise logic. For the moment this is used
177  *	to hide some internal details. This will eventually become entirely
178  *	internal to the tty port.
179  */
180 
181 void tty_port_raise_dtr_rts(struct tty_port *port)
182 {
183 	if (port->ops->dtr_rts)
184 		port->ops->dtr_rts(port, 1);
185 }
186 EXPORT_SYMBOL(tty_port_raise_dtr_rts);
187 
188 /**
189  *	tty_port_lower_dtr_rts	-	Lower DTR/RTS
190  *	@port: tty port
191  *
192  *	Wrapper for the DTR/RTS raise logic. For the moment this is used
193  *	to hide some internal details. This will eventually become entirely
194  *	internal to the tty port.
195  */
196 
197 void tty_port_lower_dtr_rts(struct tty_port *port)
198 {
199 	if (port->ops->dtr_rts)
200 		port->ops->dtr_rts(port, 0);
201 }
202 EXPORT_SYMBOL(tty_port_lower_dtr_rts);
203 
204 /**
205  *	tty_port_block_til_ready	-	Waiting logic for tty open
206  *	@port: the tty port being opened
207  *	@tty: the tty device being bound
208  *	@filp: the file pointer of the opener
209  *
210  *	Implement the core POSIX/SuS tty behaviour when opening a tty device.
211  *	Handles:
212  *		- hangup (both before and during)
213  *		- non blocking open
214  *		- rts/dtr/dcd
215  *		- signals
216  *		- port flags and counts
217  *
218  *	The passed tty_port must implement the carrier_raised method if it can
219  *	do carrier detect and the dtr_rts method if it supports software
220  *	management of these lines. Note that the dtr/rts raise is done each
221  *	iteration as a hangup may have previously dropped them while we wait.
222  */
223 
224 int tty_port_block_til_ready(struct tty_port *port,
225 				struct tty_struct *tty, struct file *filp)
226 {
227 	int do_clocal = 0, retval;
228 	unsigned long flags;
229 	DEFINE_WAIT(wait);
230 	int cd;
231 
232 	/* block if port is in the process of being closed */
233 	if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
234 		wait_event_interruptible_tty(port->close_wait,
235 				!(port->flags & ASYNC_CLOSING));
236 		if (port->flags & ASYNC_HUP_NOTIFY)
237 			return -EAGAIN;
238 		else
239 			return -ERESTARTSYS;
240 	}
241 
242 	/* if non-blocking mode is set we can pass directly to open unless
243 	   the port has just hung up or is in another error state */
244 	if (tty->flags & (1 << TTY_IO_ERROR)) {
245 		port->flags |= ASYNC_NORMAL_ACTIVE;
246 		return 0;
247 	}
248 	if (filp->f_flags & O_NONBLOCK) {
249 		/* Indicate we are open */
250 		if (tty->termios->c_cflag & CBAUD)
251 			tty_port_raise_dtr_rts(port);
252 		port->flags |= ASYNC_NORMAL_ACTIVE;
253 		return 0;
254 	}
255 
256 	if (C_CLOCAL(tty))
257 		do_clocal = 1;
258 
259 	/* Block waiting until we can proceed. We may need to wait for the
260 	   carrier, but we must also wait for any close that is in progress
261 	   before the next open may complete */
262 
263 	retval = 0;
264 
265 	/* The port lock protects the port counts */
266 	spin_lock_irqsave(&port->lock, flags);
267 	if (!tty_hung_up_p(filp))
268 		port->count--;
269 	port->blocked_open++;
270 	spin_unlock_irqrestore(&port->lock, flags);
271 
272 	while (1) {
273 		/* Indicate we are open */
274 		if (tty->termios->c_cflag & CBAUD)
275 			tty_port_raise_dtr_rts(port);
276 
277 		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
278 		/* Check for a hangup or uninitialised port.
279 							Return accordingly */
280 		if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
281 			if (port->flags & ASYNC_HUP_NOTIFY)
282 				retval = -EAGAIN;
283 			else
284 				retval = -ERESTARTSYS;
285 			break;
286 		}
287 		/* Probe the carrier. For devices with no carrier detect this
288 		   will always return true */
289 		cd = tty_port_carrier_raised(port);
290 		if (!(port->flags & ASYNC_CLOSING) &&
291 				(do_clocal || cd))
292 			break;
293 		if (signal_pending(current)) {
294 			retval = -ERESTARTSYS;
295 			break;
296 		}
297 		tty_unlock();
298 		schedule();
299 		tty_lock();
300 	}
301 	finish_wait(&port->open_wait, &wait);
302 
303 	/* Update counts. A parallel hangup will have set count to zero and
304 	   we must not mess that up further */
305 	spin_lock_irqsave(&port->lock, flags);
306 	if (!tty_hung_up_p(filp))
307 		port->count++;
308 	port->blocked_open--;
309 	if (retval == 0)
310 		port->flags |= ASYNC_NORMAL_ACTIVE;
311 	spin_unlock_irqrestore(&port->lock, flags);
312 	return retval;
313 }
314 EXPORT_SYMBOL(tty_port_block_til_ready);
315 
316 int tty_port_close_start(struct tty_port *port,
317 				struct tty_struct *tty, struct file *filp)
318 {
319 	unsigned long flags;
320 
321 	spin_lock_irqsave(&port->lock, flags);
322 	if (tty_hung_up_p(filp)) {
323 		spin_unlock_irqrestore(&port->lock, flags);
324 		return 0;
325 	}
326 
327 	if (tty->count == 1 && port->count != 1) {
328 		printk(KERN_WARNING
329 		    "tty_port_close_start: tty->count = 1 port count = %d.\n",
330 								port->count);
331 		port->count = 1;
332 	}
333 	if (--port->count < 0) {
334 		printk(KERN_WARNING "tty_port_close_start: count = %d\n",
335 								port->count);
336 		port->count = 0;
337 	}
338 
339 	if (port->count) {
340 		spin_unlock_irqrestore(&port->lock, flags);
341 		if (port->ops->drop)
342 			port->ops->drop(port);
343 		return 0;
344 	}
345 	set_bit(ASYNCB_CLOSING, &port->flags);
346 	tty->closing = 1;
347 	spin_unlock_irqrestore(&port->lock, flags);
348 	/* Don't block on a stalled port, just pull the chain */
349 	if (tty->flow_stopped)
350 		tty_driver_flush_buffer(tty);
351 	if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
352 			port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
353 		tty_wait_until_sent(tty, port->closing_wait);
354 	if (port->drain_delay) {
355 		unsigned int bps = tty_get_baud_rate(tty);
356 		long timeout;
357 
358 		if (bps > 1200)
359 			timeout = max_t(long,
360 				(HZ * 10 * port->drain_delay) / bps, HZ / 10);
361 		else
362 			timeout = 2 * HZ;
363 		schedule_timeout_interruptible(timeout);
364 	}
365 	/* Flush the ldisc buffering */
366 	tty_ldisc_flush(tty);
367 
368 	/* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
369 	   hang up the line */
370 	if (tty->termios->c_cflag & HUPCL)
371 		tty_port_lower_dtr_rts(port);
372 
373 	/* Don't call port->drop for the last reference. Callers will want
374 	   to drop the last active reference in ->shutdown() or the tty
375 	   shutdown path */
376 	return 1;
377 }
378 EXPORT_SYMBOL(tty_port_close_start);
379 
380 void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
381 {
382 	unsigned long flags;
383 
384 	spin_lock_irqsave(&port->lock, flags);
385 	tty->closing = 0;
386 
387 	if (port->blocked_open) {
388 		spin_unlock_irqrestore(&port->lock, flags);
389 		if (port->close_delay) {
390 			msleep_interruptible(
391 				jiffies_to_msecs(port->close_delay));
392 		}
393 		spin_lock_irqsave(&port->lock, flags);
394 		wake_up_interruptible(&port->open_wait);
395 	}
396 	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
397 	wake_up_interruptible(&port->close_wait);
398 	spin_unlock_irqrestore(&port->lock, flags);
399 }
400 EXPORT_SYMBOL(tty_port_close_end);
401 
402 void tty_port_close(struct tty_port *port, struct tty_struct *tty,
403 							struct file *filp)
404 {
405 	if (tty_port_close_start(port, tty, filp) == 0)
406 		return;
407 	tty_port_shutdown(port);
408 	set_bit(TTY_IO_ERROR, &tty->flags);
409 	tty_port_close_end(port, tty);
410 	tty_port_tty_set(port, NULL);
411 }
412 EXPORT_SYMBOL(tty_port_close);
413 
414 int tty_port_open(struct tty_port *port, struct tty_struct *tty,
415 							struct file *filp)
416 {
417 	spin_lock_irq(&port->lock);
418 	if (!tty_hung_up_p(filp))
419 		++port->count;
420 	spin_unlock_irq(&port->lock);
421 	tty_port_tty_set(port, tty);
422 
423 	/*
424 	 * Do the device-specific open only if the hardware isn't
425 	 * already initialized. Serialize open and shutdown using the
426 	 * port mutex.
427 	 */
428 
429 	mutex_lock(&port->mutex);
430 
431 	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
432 		clear_bit(TTY_IO_ERROR, &tty->flags);
433 		if (port->ops->activate) {
434 			int retval = port->ops->activate(port, tty);
435 			if (retval) {
436 				mutex_unlock(&port->mutex);
437 				return retval;
438 			}
439 		}
440 		set_bit(ASYNCB_INITIALIZED, &port->flags);
441 	}
442 	mutex_unlock(&port->mutex);
443 	return tty_port_block_til_ready(port, tty, filp);
444 }
445 
446 EXPORT_SYMBOL(tty_port_open);
447