compat-2.6.h: include generated config.h
[~tnikolova/compat/.git] / compat / compat-2.6.39.c
1 /*
2  * Copyright 2011    Hauke Mehrtens <hauke@hauke-m.de>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * Compatibility file for Linux wireless for kernels 2.6.39.
9  */
10
11 #include <linux/compat.h>
12 #include <linux/tty.h>
13 #include <linux/sched.h>
14
15 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
16 /*
17  *              Termios Helper Methods
18  */
19 static void unset_locked_termios(struct ktermios *termios,
20                                  struct ktermios *old,
21                                  struct ktermios *locked)
22 {
23         int     i;
24
25 #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
26
27         if (!locked) {
28                 printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
29                 return;
30         }
31
32         NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
33         NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
34         NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
35         NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
36         termios->c_line = locked->c_line ? old->c_line : termios->c_line;
37         for (i = 0; i < NCCS; i++)
38                 termios->c_cc[i] = locked->c_cc[i] ?
39                         old->c_cc[i] : termios->c_cc[i];
40         /* FIXME: What should we do for i/ospeed */
41 }
42
43 /**
44  *      tty_set_termios         -       update termios values
45  *      @tty: tty to update
46  *      @new_termios: desired new value
47  *
48  *      Perform updates to the termios values set on this terminal. There
49  *      is a bit of layering violation here with n_tty in terms of the
50  *      internal knowledge of this function.
51  *
52  *      Locking: termios_mutex
53  */
54 int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
55 {
56         struct ktermios old_termios;
57         struct tty_ldisc *ld;
58         unsigned long flags;
59
60         /*
61          *      Perform the actual termios internal changes under lock.
62          */
63
64
65         /* FIXME: we need to decide on some locking/ordering semantics
66            for the set_termios notification eventually */
67         mutex_lock(&tty->termios_mutex);
68         old_termios = *tty->termios;
69         *tty->termios = *new_termios;
70         unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
71
72         /* See if packet mode change of state. */
73         if (tty->link && tty->link->packet) {
74                 int extproc = (old_termios.c_lflag & EXTPROC) |
75                                 (tty->termios->c_lflag & EXTPROC);
76                 int old_flow = ((old_termios.c_iflag & IXON) &&
77                                 (old_termios.c_cc[VSTOP] == '\023') &&
78                                 (old_termios.c_cc[VSTART] == '\021'));
79                 int new_flow = (I_IXON(tty) &&
80                                 STOP_CHAR(tty) == '\023' &&
81                                 START_CHAR(tty) == '\021');
82                 if ((old_flow != new_flow) || extproc) {
83                         spin_lock_irqsave(&tty->ctrl_lock, flags);
84                         if (old_flow != new_flow) {
85                                 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
86                                 if (new_flow)
87                                         tty->ctrl_status |= TIOCPKT_DOSTOP;
88                                 else
89                                         tty->ctrl_status |= TIOCPKT_NOSTOP;
90                         }
91                         if (extproc)
92                                 tty->ctrl_status |= TIOCPKT_IOCTL;
93                         spin_unlock_irqrestore(&tty->ctrl_lock, flags);
94                         wake_up_interruptible(&tty->link->read_wait);
95                 }
96         }
97
98         if (tty->ops->set_termios)
99                 (*tty->ops->set_termios)(tty, &old_termios);
100         else
101                 tty_termios_copy_hw(tty->termios, &old_termios);
102
103         ld = tty_ldisc_ref(tty);
104         if (ld != NULL) {
105                 if (ld->ops->set_termios)
106                         (ld->ops->set_termios)(tty, &old_termios);
107                 tty_ldisc_deref(ld);
108         }
109         mutex_unlock(&tty->termios_mutex);
110         return 0;
111 }
112 EXPORT_SYMBOL_GPL(tty_set_termios);
113 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */
114