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 
tty_port_init(struct tty_port * port)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 
tty_port_alloc_xmit_buf(struct tty_port * port)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 
tty_port_free_xmit_buf(struct tty_port * port)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 
tty_port_destructor(struct kref * kref)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 
tty_port_put(struct tty_port * port)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 
tty_port_tty_get(struct tty_port * port)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 
tty_port_tty_set(struct tty_port * port,struct tty_struct * tty)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 
tty_port_shutdown(struct tty_port * port)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 
tty_port_hangup(struct tty_port * port)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 
tty_port_carrier_raised(struct tty_port * port)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 
tty_port_raise_dtr_rts(struct tty_port * port)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 
tty_port_lower_dtr_rts(struct tty_port * port)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 
tty_port_block_til_ready(struct tty_port * port,struct tty_struct * tty,struct file * filp)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 
231 	/* block if port is in the process of being closed */
232 	if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
233 		wait_event_interruptible_tty(port->close_wait,
234 				!(port->flags & ASYNC_CLOSING));
235 		if (port->flags & ASYNC_HUP_NOTIFY)
236 			return -EAGAIN;
237 		else
238 			return -ERESTARTSYS;
239 	}
240 
241 	/* if non-blocking mode is set we can pass directly to open unless
242 	   the port has just hung up or is in another error state */
243 	if (tty->flags & (1 << TTY_IO_ERROR)) {
244 		port->flags |= ASYNC_NORMAL_ACTIVE;
245 		return 0;
246 	}
247 	if (filp->f_flags & O_NONBLOCK) {
248 		/* Indicate we are open */
249 		if (tty->termios->c_cflag & CBAUD)
250 			tty_port_raise_dtr_rts(port);
251 		port->flags |= ASYNC_NORMAL_ACTIVE;
252 		return 0;
253 	}
254 
255 	if (C_CLOCAL(tty))
256 		do_clocal = 1;
257 
258 	/* Block waiting until we can proceed. We may need to wait for the
259 	   carrier, but we must also wait for any close that is in progress
260 	   before the next open may complete */
261 
262 	retval = 0;
263 
264 	/* The port lock protects the port counts */
265 	spin_lock_irqsave(&port->lock, flags);
266 	if (!tty_hung_up_p(filp))
267 		port->count--;
268 	port->blocked_open++;
269 	spin_unlock_irqrestore(&port->lock, flags);
270 
271 	while (1) {
272 		/* Indicate we are open */
273 		if (tty->termios->c_cflag & CBAUD)
274 			tty_port_raise_dtr_rts(port);
275 
276 		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
277 		/* Check for a hangup or uninitialised port.
278 							Return accordingly */
279 		if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
280 			if (port->flags & ASYNC_HUP_NOTIFY)
281 				retval = -EAGAIN;
282 			else
283 				retval = -ERESTARTSYS;
284 			break;
285 		}
286 		/*
287 		 * Probe the carrier. For devices with no carrier detect
288 		 * tty_port_carrier_raised will always return true.
289 		 * Never ask drivers if CLOCAL is set, this causes troubles
290 		 * on some hardware.
291 		 */
292 		if (!(port->flags & ASYNC_CLOSING) &&
293 				(do_clocal || tty_port_carrier_raised(port)))
294 			break;
295 		if (signal_pending(current)) {
296 			retval = -ERESTARTSYS;
297 			break;
298 		}
299 		tty_unlock();
300 		schedule();
301 		tty_lock();
302 	}
303 	finish_wait(&port->open_wait, &wait);
304 
305 	/* Update counts. A parallel hangup will have set count to zero and
306 	   we must not mess that up further */
307 	spin_lock_irqsave(&port->lock, flags);
308 	if (!tty_hung_up_p(filp))
309 		port->count++;
310 	port->blocked_open--;
311 	if (retval == 0)
312 		port->flags |= ASYNC_NORMAL_ACTIVE;
313 	spin_unlock_irqrestore(&port->lock, flags);
314 	return retval;
315 }
316 EXPORT_SYMBOL(tty_port_block_til_ready);
317 
tty_port_close_start(struct tty_port * port,struct tty_struct * tty,struct file * filp)318 int tty_port_close_start(struct tty_port *port,
319 				struct tty_struct *tty, struct file *filp)
320 {
321 	unsigned long flags;
322 
323 	spin_lock_irqsave(&port->lock, flags);
324 	if (tty_hung_up_p(filp)) {
325 		spin_unlock_irqrestore(&port->lock, flags);
326 		return 0;
327 	}
328 
329 	if (tty->count == 1 && port->count != 1) {
330 		printk(KERN_WARNING
331 		    "tty_port_close_start: tty->count = 1 port count = %d.\n",
332 								port->count);
333 		port->count = 1;
334 	}
335 	if (--port->count < 0) {
336 		printk(KERN_WARNING "tty_port_close_start: count = %d\n",
337 								port->count);
338 		port->count = 0;
339 	}
340 
341 	if (port->count) {
342 		spin_unlock_irqrestore(&port->lock, flags);
343 		if (port->ops->drop)
344 			port->ops->drop(port);
345 		return 0;
346 	}
347 	set_bit(ASYNCB_CLOSING, &port->flags);
348 	tty->closing = 1;
349 	spin_unlock_irqrestore(&port->lock, flags);
350 	/* Don't block on a stalled port, just pull the chain */
351 	if (tty->flow_stopped)
352 		tty_driver_flush_buffer(tty);
353 	if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
354 			port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
355 		tty_wait_until_sent_from_close(tty, port->closing_wait);
356 	if (port->drain_delay) {
357 		unsigned int bps = tty_get_baud_rate(tty);
358 		long timeout;
359 
360 		if (bps > 1200)
361 			timeout = max_t(long,
362 				(HZ * 10 * port->drain_delay) / bps, HZ / 10);
363 		else
364 			timeout = 2 * HZ;
365 		schedule_timeout_interruptible(timeout);
366 	}
367 	/* Flush the ldisc buffering */
368 	tty_ldisc_flush(tty);
369 
370 	/* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
371 	   hang up the line */
372 	if (tty->termios->c_cflag & HUPCL)
373 		tty_port_lower_dtr_rts(port);
374 
375 	/* Don't call port->drop for the last reference. Callers will want
376 	   to drop the last active reference in ->shutdown() or the tty
377 	   shutdown path */
378 	return 1;
379 }
380 EXPORT_SYMBOL(tty_port_close_start);
381 
tty_port_close_end(struct tty_port * port,struct tty_struct * tty)382 void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
383 {
384 	unsigned long flags;
385 
386 	spin_lock_irqsave(&port->lock, flags);
387 	tty->closing = 0;
388 
389 	if (port->blocked_open) {
390 		spin_unlock_irqrestore(&port->lock, flags);
391 		if (port->close_delay) {
392 			msleep_interruptible(
393 				jiffies_to_msecs(port->close_delay));
394 		}
395 		spin_lock_irqsave(&port->lock, flags);
396 		wake_up_interruptible(&port->open_wait);
397 	}
398 	port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
399 	wake_up_interruptible(&port->close_wait);
400 	spin_unlock_irqrestore(&port->lock, flags);
401 }
402 EXPORT_SYMBOL(tty_port_close_end);
403 
tty_port_close(struct tty_port * port,struct tty_struct * tty,struct file * filp)404 void tty_port_close(struct tty_port *port, struct tty_struct *tty,
405 							struct file *filp)
406 {
407 	if (tty_port_close_start(port, tty, filp) == 0)
408 		return;
409 	tty_port_shutdown(port);
410 	set_bit(TTY_IO_ERROR, &tty->flags);
411 	tty_port_close_end(port, tty);
412 	tty_port_tty_set(port, NULL);
413 }
414 EXPORT_SYMBOL(tty_port_close);
415 
tty_port_open(struct tty_port * port,struct tty_struct * tty,struct file * filp)416 int tty_port_open(struct tty_port *port, struct tty_struct *tty,
417 							struct file *filp)
418 {
419 	spin_lock_irq(&port->lock);
420 	if (!tty_hung_up_p(filp))
421 		++port->count;
422 	spin_unlock_irq(&port->lock);
423 	tty_port_tty_set(port, tty);
424 
425 	/*
426 	 * Do the device-specific open only if the hardware isn't
427 	 * already initialized. Serialize open and shutdown using the
428 	 * port mutex.
429 	 */
430 
431 	mutex_lock(&port->mutex);
432 
433 	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
434 		clear_bit(TTY_IO_ERROR, &tty->flags);
435 		if (port->ops->activate) {
436 			int retval = port->ops->activate(port, tty);
437 			if (retval) {
438 				mutex_unlock(&port->mutex);
439 				return retval;
440 			}
441 		}
442 		set_bit(ASYNCB_INITIALIZED, &port->flags);
443 	}
444 	mutex_unlock(&port->mutex);
445 	return tty_port_block_til_ready(port, tty, filp);
446 }
447 
448 EXPORT_SYMBOL(tty_port_open);
449