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