]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/tty/tty_port.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[karo-tx-linux.git] / drivers / tty / 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         kref_init(&port->kref);
33 }
34 EXPORT_SYMBOL(tty_port_init);
35
36 /**
37  * tty_port_link_device - link tty and tty_port
38  * @port: tty_port of the device
39  * @driver: tty_driver for this device
40  * @index: index of the tty
41  *
42  * Provide the tty layer wit ha link from a tty (specified by @index) to a
43  * tty_port (@port). Use this only if neither tty_port_register_device nor
44  * tty_port_install is used in the driver. If used, this has to be called before
45  * tty_register_driver.
46  */
47 void tty_port_link_device(struct tty_port *port,
48                 struct tty_driver *driver, unsigned index)
49 {
50         if (WARN_ON(index >= driver->num))
51                 return;
52         driver->ports[index] = port;
53 }
54 EXPORT_SYMBOL_GPL(tty_port_link_device);
55
56 /**
57  * tty_port_register_device - register tty device
58  * @port: tty_port of the device
59  * @driver: tty_driver for this device
60  * @index: index of the tty
61  * @device: parent if exists, otherwise NULL
62  *
63  * It is the same as tty_register_device except the provided @port is linked to
64  * a concrete tty specified by @index. Use this or tty_port_install (or both).
65  * Call tty_port_link_device as a last resort.
66  */
67 struct device *tty_port_register_device(struct tty_port *port,
68                 struct tty_driver *driver, unsigned index,
69                 struct device *device)
70 {
71         tty_port_link_device(port, driver, index);
72         return tty_register_device(driver, index, device);
73 }
74 EXPORT_SYMBOL_GPL(tty_port_register_device);
75
76 /**
77  * tty_port_register_device_attr - register tty device
78  * @port: tty_port of the device
79  * @driver: tty_driver for this device
80  * @index: index of the tty
81  * @device: parent if exists, otherwise NULL
82  * @drvdata: Driver data to be set to device.
83  * @attr_grp: Attribute group to be set on device.
84  *
85  * It is the same as tty_register_device_attr except the provided @port is
86  * linked to a concrete tty specified by @index. Use this or tty_port_install
87  * (or both). Call tty_port_link_device as a last resort.
88  */
89 struct device *tty_port_register_device_attr(struct tty_port *port,
90                 struct tty_driver *driver, unsigned index,
91                 struct device *device, void *drvdata,
92                 const struct attribute_group **attr_grp)
93 {
94         tty_port_link_device(port, driver, index);
95         return tty_register_device_attr(driver, index, device, drvdata,
96                         attr_grp);
97 }
98 EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
99
100 int tty_port_alloc_xmit_buf(struct tty_port *port)
101 {
102         /* We may sleep in get_zeroed_page() */
103         mutex_lock(&port->buf_mutex);
104         if (port->xmit_buf == NULL)
105                 port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
106         mutex_unlock(&port->buf_mutex);
107         if (port->xmit_buf == NULL)
108                 return -ENOMEM;
109         return 0;
110 }
111 EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
112
113 void tty_port_free_xmit_buf(struct tty_port *port)
114 {
115         mutex_lock(&port->buf_mutex);
116         if (port->xmit_buf != NULL) {
117                 free_page((unsigned long)port->xmit_buf);
118                 port->xmit_buf = NULL;
119         }
120         mutex_unlock(&port->buf_mutex);
121 }
122 EXPORT_SYMBOL(tty_port_free_xmit_buf);
123
124 static void tty_port_destructor(struct kref *kref)
125 {
126         struct tty_port *port = container_of(kref, struct tty_port, kref);
127         if (port->xmit_buf)
128                 free_page((unsigned long)port->xmit_buf);
129         if (port->ops->destruct)
130                 port->ops->destruct(port);
131         else
132                 kfree(port);
133 }
134
135 void tty_port_put(struct tty_port *port)
136 {
137         if (port)
138                 kref_put(&port->kref, tty_port_destructor);
139 }
140 EXPORT_SYMBOL(tty_port_put);
141
142 /**
143  *      tty_port_tty_get        -       get a tty reference
144  *      @port: tty port
145  *
146  *      Return a refcount protected tty instance or NULL if the port is not
147  *      associated with a tty (eg due to close or hangup)
148  */
149
150 struct tty_struct *tty_port_tty_get(struct tty_port *port)
151 {
152         unsigned long flags;
153         struct tty_struct *tty;
154
155         spin_lock_irqsave(&port->lock, flags);
156         tty = tty_kref_get(port->tty);
157         spin_unlock_irqrestore(&port->lock, flags);
158         return tty;
159 }
160 EXPORT_SYMBOL(tty_port_tty_get);
161
162 /**
163  *      tty_port_tty_set        -       set the tty of a port
164  *      @port: tty port
165  *      @tty: the tty
166  *
167  *      Associate the port and tty pair. Manages any internal refcounts.
168  *      Pass NULL to deassociate a port
169  */
170
171 void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
172 {
173         unsigned long flags;
174
175         spin_lock_irqsave(&port->lock, flags);
176         if (port->tty)
177                 tty_kref_put(port->tty);
178         port->tty = tty_kref_get(tty);
179         spin_unlock_irqrestore(&port->lock, flags);
180 }
181 EXPORT_SYMBOL(tty_port_tty_set);
182
183 static void tty_port_shutdown(struct tty_port *port)
184 {
185         mutex_lock(&port->mutex);
186         if (port->ops->shutdown && !port->console &&
187                 test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
188                         port->ops->shutdown(port);
189         mutex_unlock(&port->mutex);
190 }
191
192 /**
193  *      tty_port_hangup         -       hangup helper
194  *      @port: tty port
195  *
196  *      Perform port level tty hangup flag and count changes. Drop the tty
197  *      reference.
198  */
199
200 void tty_port_hangup(struct tty_port *port)
201 {
202         unsigned long flags;
203
204         spin_lock_irqsave(&port->lock, flags);
205         port->count = 0;
206         port->flags &= ~ASYNC_NORMAL_ACTIVE;
207         if (port->tty) {
208                 set_bit(TTY_IO_ERROR, &port->tty->flags);
209                 tty_kref_put(port->tty);
210         }
211         port->tty = NULL;
212         spin_unlock_irqrestore(&port->lock, flags);
213         wake_up_interruptible(&port->open_wait);
214         wake_up_interruptible(&port->delta_msr_wait);
215         tty_port_shutdown(port);
216 }
217 EXPORT_SYMBOL(tty_port_hangup);
218
219 /**
220  *      tty_port_carrier_raised -       carrier raised check
221  *      @port: tty port
222  *
223  *      Wrapper for the carrier detect logic. For the moment this is used
224  *      to hide some internal details. This will eventually become entirely
225  *      internal to the tty port.
226  */
227
228 int tty_port_carrier_raised(struct tty_port *port)
229 {
230         if (port->ops->carrier_raised == NULL)
231                 return 1;
232         return port->ops->carrier_raised(port);
233 }
234 EXPORT_SYMBOL(tty_port_carrier_raised);
235
236 /**
237  *      tty_port_raise_dtr_rts  -       Raise DTR/RTS
238  *      @port: tty port
239  *
240  *      Wrapper for the DTR/RTS raise logic. For the moment this is used
241  *      to hide some internal details. This will eventually become entirely
242  *      internal to the tty port.
243  */
244
245 void tty_port_raise_dtr_rts(struct tty_port *port)
246 {
247         if (port->ops->dtr_rts)
248                 port->ops->dtr_rts(port, 1);
249 }
250 EXPORT_SYMBOL(tty_port_raise_dtr_rts);
251
252 /**
253  *      tty_port_lower_dtr_rts  -       Lower DTR/RTS
254  *      @port: tty port
255  *
256  *      Wrapper for the DTR/RTS raise logic. For the moment this is used
257  *      to hide some internal details. This will eventually become entirely
258  *      internal to the tty port.
259  */
260
261 void tty_port_lower_dtr_rts(struct tty_port *port)
262 {
263         if (port->ops->dtr_rts)
264                 port->ops->dtr_rts(port, 0);
265 }
266 EXPORT_SYMBOL(tty_port_lower_dtr_rts);
267
268 /**
269  *      tty_port_block_til_ready        -       Waiting logic for tty open
270  *      @port: the tty port being opened
271  *      @tty: the tty device being bound
272  *      @filp: the file pointer of the opener
273  *
274  *      Implement the core POSIX/SuS tty behaviour when opening a tty device.
275  *      Handles:
276  *              - hangup (both before and during)
277  *              - non blocking open
278  *              - rts/dtr/dcd
279  *              - signals
280  *              - port flags and counts
281  *
282  *      The passed tty_port must implement the carrier_raised method if it can
283  *      do carrier detect and the dtr_rts method if it supports software
284  *      management of these lines. Note that the dtr/rts raise is done each
285  *      iteration as a hangup may have previously dropped them while we wait.
286  */
287
288 int tty_port_block_til_ready(struct tty_port *port,
289                                 struct tty_struct *tty, struct file *filp)
290 {
291         int do_clocal = 0, retval;
292         unsigned long flags;
293         DEFINE_WAIT(wait);
294
295         /* block if port is in the process of being closed */
296         if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
297                 wait_event_interruptible_tty(tty, port->close_wait,
298                                 !(port->flags & ASYNC_CLOSING));
299                 if (port->flags & ASYNC_HUP_NOTIFY)
300                         return -EAGAIN;
301                 else
302                         return -ERESTARTSYS;
303         }
304
305         /* if non-blocking mode is set we can pass directly to open unless
306            the port has just hung up or is in another error state */
307         if (tty->flags & (1 << TTY_IO_ERROR)) {
308                 port->flags |= ASYNC_NORMAL_ACTIVE;
309                 return 0;
310         }
311         if (filp->f_flags & O_NONBLOCK) {
312                 /* Indicate we are open */
313                 if (tty->termios.c_cflag & CBAUD)
314                         tty_port_raise_dtr_rts(port);
315                 port->flags |= ASYNC_NORMAL_ACTIVE;
316                 return 0;
317         }
318
319         if (C_CLOCAL(tty))
320                 do_clocal = 1;
321
322         /* Block waiting until we can proceed. We may need to wait for the
323            carrier, but we must also wait for any close that is in progress
324            before the next open may complete */
325
326         retval = 0;
327
328         /* The port lock protects the port counts */
329         spin_lock_irqsave(&port->lock, flags);
330         if (!tty_hung_up_p(filp))
331                 port->count--;
332         port->blocked_open++;
333         spin_unlock_irqrestore(&port->lock, flags);
334
335         while (1) {
336                 /* Indicate we are open */
337                 if (tty->termios.c_cflag & CBAUD)
338                         tty_port_raise_dtr_rts(port);
339
340                 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
341                 /* Check for a hangup or uninitialised port.
342                                                         Return accordingly */
343                 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
344                         if (port->flags & ASYNC_HUP_NOTIFY)
345                                 retval = -EAGAIN;
346                         else
347                                 retval = -ERESTARTSYS;
348                         break;
349                 }
350                 /*
351                  * Probe the carrier. For devices with no carrier detect
352                  * tty_port_carrier_raised will always return true.
353                  * Never ask drivers if CLOCAL is set, this causes troubles
354                  * on some hardware.
355                  */
356                 if (!(port->flags & ASYNC_CLOSING) &&
357                                 (do_clocal || tty_port_carrier_raised(port)))
358                         break;
359                 if (signal_pending(current)) {
360                         retval = -ERESTARTSYS;
361                         break;
362                 }
363                 tty_unlock(tty);
364                 schedule();
365                 tty_lock(tty);
366         }
367         finish_wait(&port->open_wait, &wait);
368
369         /* Update counts. A parallel hangup will have set count to zero and
370            we must not mess that up further */
371         spin_lock_irqsave(&port->lock, flags);
372         if (!tty_hung_up_p(filp))
373                 port->count++;
374         port->blocked_open--;
375         if (retval == 0)
376                 port->flags |= ASYNC_NORMAL_ACTIVE;
377         spin_unlock_irqrestore(&port->lock, flags);
378         return retval;
379 }
380 EXPORT_SYMBOL(tty_port_block_til_ready);
381
382 int tty_port_close_start(struct tty_port *port,
383                                 struct tty_struct *tty, struct file *filp)
384 {
385         unsigned long flags;
386
387         spin_lock_irqsave(&port->lock, flags);
388         if (tty_hung_up_p(filp)) {
389                 spin_unlock_irqrestore(&port->lock, flags);
390                 return 0;
391         }
392
393         if (tty->count == 1 && port->count != 1) {
394                 printk(KERN_WARNING
395                     "tty_port_close_start: tty->count = 1 port count = %d.\n",
396                                                                 port->count);
397                 port->count = 1;
398         }
399         if (--port->count < 0) {
400                 printk(KERN_WARNING "tty_port_close_start: count = %d\n",
401                                                                 port->count);
402                 port->count = 0;
403         }
404
405         if (port->count) {
406                 spin_unlock_irqrestore(&port->lock, flags);
407                 if (port->ops->drop)
408                         port->ops->drop(port);
409                 return 0;
410         }
411         set_bit(ASYNCB_CLOSING, &port->flags);
412         tty->closing = 1;
413         spin_unlock_irqrestore(&port->lock, flags);
414         /* Don't block on a stalled port, just pull the chain */
415         if (tty->flow_stopped)
416                 tty_driver_flush_buffer(tty);
417         if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
418                         port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
419                 tty_wait_until_sent_from_close(tty, port->closing_wait);
420         if (port->drain_delay) {
421                 unsigned int bps = tty_get_baud_rate(tty);
422                 long timeout;
423
424                 if (bps > 1200)
425                         timeout = max_t(long,
426                                 (HZ * 10 * port->drain_delay) / bps, HZ / 10);
427                 else
428                         timeout = 2 * HZ;
429                 schedule_timeout_interruptible(timeout);
430         }
431         /* Flush the ldisc buffering */
432         tty_ldisc_flush(tty);
433
434         /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
435            hang up the line */
436         if (tty->termios.c_cflag & HUPCL)
437                 tty_port_lower_dtr_rts(port);
438
439         /* Don't call port->drop for the last reference. Callers will want
440            to drop the last active reference in ->shutdown() or the tty
441            shutdown path */
442         return 1;
443 }
444 EXPORT_SYMBOL(tty_port_close_start);
445
446 void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
447 {
448         unsigned long flags;
449
450         spin_lock_irqsave(&port->lock, flags);
451         tty->closing = 0;
452
453         if (port->blocked_open) {
454                 spin_unlock_irqrestore(&port->lock, flags);
455                 if (port->close_delay) {
456                         msleep_interruptible(
457                                 jiffies_to_msecs(port->close_delay));
458                 }
459                 spin_lock_irqsave(&port->lock, flags);
460                 wake_up_interruptible(&port->open_wait);
461         }
462         port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
463         wake_up_interruptible(&port->close_wait);
464         spin_unlock_irqrestore(&port->lock, flags);
465 }
466 EXPORT_SYMBOL(tty_port_close_end);
467
468 void tty_port_close(struct tty_port *port, struct tty_struct *tty,
469                                                         struct file *filp)
470 {
471         if (tty_port_close_start(port, tty, filp) == 0)
472                 return;
473         tty_port_shutdown(port);
474         set_bit(TTY_IO_ERROR, &tty->flags);
475         tty_port_close_end(port, tty);
476         tty_port_tty_set(port, NULL);
477 }
478 EXPORT_SYMBOL(tty_port_close);
479
480 /**
481  * tty_port_install - generic tty->ops->install handler
482  * @port: tty_port of the device
483  * @driver: tty_driver for this device
484  * @tty: tty to be installed
485  *
486  * It is the same as tty_standard_install except the provided @port is linked
487  * to a concrete tty specified by @tty. Use this or tty_port_register_device
488  * (or both). Call tty_port_link_device as a last resort.
489  */
490 int tty_port_install(struct tty_port *port, struct tty_driver *driver,
491                 struct tty_struct *tty)
492 {
493         tty->port = port;
494         return tty_standard_install(driver, tty);
495 }
496 EXPORT_SYMBOL_GPL(tty_port_install);
497
498 int tty_port_open(struct tty_port *port, struct tty_struct *tty,
499                                                         struct file *filp)
500 {
501         spin_lock_irq(&port->lock);
502         if (!tty_hung_up_p(filp))
503                 ++port->count;
504         spin_unlock_irq(&port->lock);
505         tty_port_tty_set(port, tty);
506
507         /*
508          * Do the device-specific open only if the hardware isn't
509          * already initialized. Serialize open and shutdown using the
510          * port mutex.
511          */
512
513         mutex_lock(&port->mutex);
514
515         if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
516                 clear_bit(TTY_IO_ERROR, &tty->flags);
517                 if (port->ops->activate) {
518                         int retval = port->ops->activate(port, tty);
519                         if (retval) {
520                                 mutex_unlock(&port->mutex);
521                                 return retval;
522                         }
523                 }
524                 set_bit(ASYNCB_INITIALIZED, &port->flags);
525         }
526         mutex_unlock(&port->mutex);
527         return tty_port_block_til_ready(port, tty, filp);
528 }
529
530 EXPORT_SYMBOL(tty_port_open);