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