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