TTY: fix typos
[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                 port->flags |= ASYNC_NORMAL_ACTIVE;
225                 return 0;
226         }
227
228         if (C_CLOCAL(tty))
229                 do_clocal = 1;
230
231         /* Block waiting until we can proceed. We may need to wait for the
232            carrier, but we must also wait for any close that is in progress
233            before the next open may complete */
234
235         retval = 0;
236
237         /* The port lock protects the port counts */
238         spin_lock_irqsave(&port->lock, flags);
239         if (!tty_hung_up_p(filp))
240                 port->count--;
241         port->blocked_open++;
242         spin_unlock_irqrestore(&port->lock, flags);
243
244         while (1) {
245                 /* Indicate we are open */
246                 if (tty->termios->c_cflag & CBAUD)
247                         tty_port_raise_dtr_rts(port);
248
249                 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
250                 /* Check for a hangup or uninitialised port. Return accordingly */
251                 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
252                         if (port->flags & ASYNC_HUP_NOTIFY)
253                                 retval = -EAGAIN;
254                         else
255                                 retval = -ERESTARTSYS;
256                         break;
257                 }
258                 /* Probe the carrier. For devices with no carrier detect this
259                    will always return true */
260                 cd = tty_port_carrier_raised(port);
261                 if (!(port->flags & ASYNC_CLOSING) &&
262                                 (do_clocal || cd))
263                         break;
264                 if (signal_pending(current)) {
265                         retval = -ERESTARTSYS;
266                         break;
267                 }
268                 schedule();
269         }
270         finish_wait(&port->open_wait, &wait);
271
272         /* Update counts. A parallel hangup will have set count to zero and
273            we must not mess that up further */
274         spin_lock_irqsave(&port->lock, flags);
275         if (!tty_hung_up_p(filp))
276                 port->count++;
277         port->blocked_open--;
278         if (retval == 0)
279                 port->flags |= ASYNC_NORMAL_ACTIVE;
280         spin_unlock_irqrestore(&port->lock, flags);
281         return retval;
282         
283 }
284 EXPORT_SYMBOL(tty_port_block_til_ready);
285
286 int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
287 {
288         unsigned long flags;
289
290         spin_lock_irqsave(&port->lock, flags);
291         if (tty_hung_up_p(filp)) {
292                 spin_unlock_irqrestore(&port->lock, flags);
293                 return 0;
294         }
295
296         if( tty->count == 1 && port->count != 1) {
297                 printk(KERN_WARNING
298                     "tty_port_close_start: tty->count = 1 port count = %d.\n",
299                                                                 port->count);
300                 port->count = 1;
301         }
302         if (--port->count < 0) {
303                 printk(KERN_WARNING "tty_port_close_start: count = %d\n",
304                                                                 port->count);
305                 port->count = 0;
306         }
307
308         if (port->count) {
309                 spin_unlock_irqrestore(&port->lock, flags);
310                 if (port->ops->drop)
311                         port->ops->drop(port);
312                 return 0;
313         }
314         set_bit(ASYNCB_CLOSING, &port->flags);
315         tty->closing = 1;
316         spin_unlock_irqrestore(&port->lock, flags);
317         /* Don't block on a stalled port, just pull the chain */
318         if (tty->flow_stopped)
319                 tty_driver_flush_buffer(tty);
320         if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
321                         port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
322                 tty_wait_until_sent(tty, port->closing_wait);
323         if (port->drain_delay) {
324                 unsigned int bps = tty_get_baud_rate(tty);
325                 long timeout;
326
327                 if (bps > 1200)
328                         timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps,
329                                                                 HZ / 10);
330                 else
331                         timeout = 2 * HZ;
332                 schedule_timeout_interruptible(timeout);
333         }
334         /* Don't call port->drop for the last reference. Callers will want
335            to drop the last active reference in ->shutdown() or the tty
336            shutdown path */
337         return 1;
338 }
339 EXPORT_SYMBOL(tty_port_close_start);
340
341 void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
342 {
343         unsigned long flags;
344
345         tty_ldisc_flush(tty);
346
347         if (tty->termios->c_cflag & HUPCL)
348                 tty_port_lower_dtr_rts(port);
349
350         spin_lock_irqsave(&port->lock, flags);
351         tty->closing = 0;
352
353         if (port->blocked_open) {
354                 spin_unlock_irqrestore(&port->lock, flags);
355                 if (port->close_delay) {
356                         msleep_interruptible(
357                                 jiffies_to_msecs(port->close_delay));
358                 }
359                 spin_lock_irqsave(&port->lock, flags);
360                 wake_up_interruptible(&port->open_wait);
361         }
362         port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
363         wake_up_interruptible(&port->close_wait);
364         spin_unlock_irqrestore(&port->lock, flags);
365 }
366 EXPORT_SYMBOL(tty_port_close_end);
367
368 void tty_port_close(struct tty_port *port, struct tty_struct *tty,
369                                                         struct file *filp)
370 {
371         if (tty_port_close_start(port, tty, filp) == 0)
372                 return;
373         tty_port_shutdown(port);
374         tty_port_close_end(port, tty);
375         tty_port_tty_set(port, NULL);
376 }
377 EXPORT_SYMBOL(tty_port_close);