5 #include <linux/types.h>
6 #include <linux/errno.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>
21 void tty_port_init(struct tty_port *port)
23 memset(port, 0, sizeof(*port));
24 init_waitqueue_head(&port->open_wait);
25 init_waitqueue_head(&port->close_wait);
26 mutex_init(&port->mutex);
27 spin_lock_init(&port->lock);
28 port->close_delay = (50 * HZ) / 100;
29 port->closing_wait = (3000 * HZ) / 100;
31 EXPORT_SYMBOL(tty_port_init);
33 int tty_port_alloc_xmit_buf(struct tty_port *port)
35 /* We may sleep in get_zeroed_page() */
36 mutex_lock(&port->mutex);
37 if (port->xmit_buf == NULL)
38 port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
39 mutex_unlock(&port->mutex);
40 if (port->xmit_buf == NULL)
44 EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
46 void tty_port_free_xmit_buf(struct tty_port *port)
48 mutex_lock(&port->mutex);
49 if (port->xmit_buf != NULL) {
50 free_page((unsigned long)port->xmit_buf);
51 port->xmit_buf = NULL;
53 mutex_unlock(&port->mutex);
55 EXPORT_SYMBOL(tty_port_free_xmit_buf);
59 * tty_port_tty_get - get a tty reference
62 * Return a refcount protected tty instance or NULL if the port is not
63 * associated with a tty (eg due to close or hangup)
66 struct tty_struct *tty_port_tty_get(struct tty_port *port)
69 struct tty_struct *tty;
71 spin_lock_irqsave(&port->lock, flags);
72 tty = tty_kref_get(port->tty);
73 spin_unlock_irqrestore(&port->lock, flags);
76 EXPORT_SYMBOL(tty_port_tty_get);
79 * tty_port_tty_set - set the tty of a port
83 * Associate the port and tty pair. Manages any internal refcounts.
84 * Pass NULL to deassociate a port
87 void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
91 spin_lock_irqsave(&port->lock, flags);
93 tty_kref_put(port->tty);
94 port->tty = tty_kref_get(tty);
95 spin_unlock_irqrestore(&port->lock, flags);
97 EXPORT_SYMBOL(tty_port_tty_set);
99 static void tty_port_shutdown(struct tty_port *port)
101 if (port->ops->shutdown &&
102 test_and_clear_bit(ASYNC_INITIALIZED, &port->flags))
103 port->ops->shutdown(port);
108 * tty_port_hangup - hangup helper
111 * Perform port level tty hangup flag and count changes. Drop the tty
115 void tty_port_hangup(struct tty_port *port)
119 spin_lock_irqsave(&port->lock, flags);
121 port->flags &= ~ASYNC_NORMAL_ACTIVE;
123 tty_kref_put(port->tty);
125 spin_unlock_irqrestore(&port->lock, flags);
126 wake_up_interruptible(&port->open_wait);
127 tty_port_shutdown(port);
129 EXPORT_SYMBOL(tty_port_hangup);
132 * tty_port_carrier_raised - carrier raised check
135 * Wrapper for the carrier detect logic. For the moment this is used
136 * to hide some internal details. This will eventually become entirely
137 * internal to the tty port.
140 int tty_port_carrier_raised(struct tty_port *port)
142 if (port->ops->carrier_raised == NULL)
144 return port->ops->carrier_raised(port);
146 EXPORT_SYMBOL(tty_port_carrier_raised);
149 * tty_port_raise_dtr_rts - Raise DTR/RTS
152 * Wrapper for the DTR/RTS raise logic. For the moment this is used
153 * to hide some internal details. This will eventually become entirely
154 * internal to the tty port.
157 void tty_port_raise_dtr_rts(struct tty_port *port)
159 if (port->ops->dtr_rts)
160 port->ops->dtr_rts(port, 1);
162 EXPORT_SYMBOL(tty_port_raise_dtr_rts);
165 * tty_port_lower_dtr_rts - Lower DTR/RTS
168 * Wrapper for the DTR/RTS raise logic. For the moment this is used
169 * to hide some internal details. This will eventually become entirely
170 * internal to the tty port.
173 void tty_port_lower_dtr_rts(struct tty_port *port)
175 if (port->ops->dtr_rts)
176 port->ops->dtr_rts(port, 0);
178 EXPORT_SYMBOL(tty_port_lower_dtr_rts);
181 * tty_port_block_til_ready - Waiting logic for tty open
182 * @port: the tty port being opened
183 * @tty: the tty device being bound
184 * @filp: the file pointer of the opener
186 * Implement the core POSIX/SuS tty behaviour when opening a tty device.
188 * - hangup (both before and during)
189 * - non blocking open
192 * - port flags and counts
194 * The passed tty_port must implement the carrier_raised method if it can
195 * do carrier detect and the dtr_rts method if it supports software
196 * management of these lines. Note that the dtr/rts raise is done each
197 * iteration as a hangup may have previously dropped them while we wait.
200 int tty_port_block_til_ready(struct tty_port *port,
201 struct tty_struct *tty, struct file *filp)
203 int do_clocal = 0, retval;
208 /* block if port is in the process of being closed */
209 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
210 wait_event_interruptible(port->close_wait,
211 !(port->flags & ASYNC_CLOSING));
212 if (port->flags & ASYNC_HUP_NOTIFY)
218 /* if non-blocking mode is set we can pass directly to open unless
219 the port has just hung up or is in another error state */
220 if ((filp->f_flags & O_NONBLOCK) ||
221 (tty->flags & (1 << TTY_IO_ERROR))) {
222 port->flags |= ASYNC_NORMAL_ACTIVE;
229 /* Block waiting until we can proceed. We may need to wait for the
230 carrier, but we must also wait for any close that is in progress
231 before the next open may complete */
235 /* The port lock protects the port counts */
236 spin_lock_irqsave(&port->lock, flags);
237 if (!tty_hung_up_p(filp))
239 port->blocked_open++;
240 spin_unlock_irqrestore(&port->lock, flags);
243 /* Indicate we are open */
244 if (tty->termios->c_cflag & CBAUD)
245 tty_port_raise_dtr_rts(port);
247 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
248 /* Check for a hangup or uninitialised port. Return accordingly */
249 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
250 if (port->flags & ASYNC_HUP_NOTIFY)
253 retval = -ERESTARTSYS;
256 /* Probe the carrier. For devices with no carrier detect this
257 will always return true */
258 cd = tty_port_carrier_raised(port);
259 if (!(port->flags & ASYNC_CLOSING) &&
262 if (signal_pending(current)) {
263 retval = -ERESTARTSYS;
268 finish_wait(&port->open_wait, &wait);
270 /* Update counts. A parallel hangup will have set count to zero and
271 we must not mess that up further */
272 spin_lock_irqsave(&port->lock, flags);
273 if (!tty_hung_up_p(filp))
275 port->blocked_open--;
277 port->flags |= ASYNC_NORMAL_ACTIVE;
278 spin_unlock_irqrestore(&port->lock, flags);
282 EXPORT_SYMBOL(tty_port_block_til_ready);
284 int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
288 spin_lock_irqsave(&port->lock, flags);
289 if (tty_hung_up_p(filp)) {
290 spin_unlock_irqrestore(&port->lock, flags);
294 if( tty->count == 1 && port->count != 1) {
296 "tty_port_close_start: tty->count = 1 port count = %d.\n",
300 if (--port->count < 0) {
301 printk(KERN_WARNING "tty_port_close_start: count = %d\n",
307 spin_unlock_irqrestore(&port->lock, flags);
309 port->ops->drop(port);
312 set_bit(ASYNC_CLOSING, &port->flags);
314 spin_unlock_irqrestore(&port->lock, flags);
315 /* Don't block on a stalled port, just pull the chain */
316 if (tty->flow_stopped)
317 tty_driver_flush_buffer(tty);
318 if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
319 port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
320 tty_wait_until_sent(tty, port->closing_wait);
321 if (port->drain_delay) {
322 unsigned int bps = tty_get_baud_rate(tty);
326 timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps,
330 schedule_timeout_interruptible(timeout);
332 /* Don't call port->drop for the last reference. Callers will want
333 to drop the last active reference in ->shutdown() or the tty
337 EXPORT_SYMBOL(tty_port_close_start);
339 void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
343 tty_ldisc_flush(tty);
345 if (tty->termios->c_cflag & HUPCL)
346 tty_port_lower_dtr_rts(port);
348 spin_lock_irqsave(&port->lock, flags);
351 if (port->blocked_open) {
352 spin_unlock_irqrestore(&port->lock, flags);
353 if (port->close_delay) {
354 msleep_interruptible(
355 jiffies_to_msecs(port->close_delay));
357 spin_lock_irqsave(&port->lock, flags);
358 wake_up_interruptible(&port->open_wait);
360 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
361 wake_up_interruptible(&port->close_wait);
362 spin_unlock_irqrestore(&port->lock, flags);
364 EXPORT_SYMBOL(tty_port_close_end);
366 void tty_port_close(struct tty_port *port, struct tty_struct *tty,
369 if (tty_port_close_start(port, tty, filp) == 0)
371 tty_port_shutdown(port);
372 tty_port_close_end(port, tty);
373 tty_port_tty_set(port, NULL);
375 EXPORT_SYMBOL(tty_port_close);