diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/hvsi.c | 8 | ||||
-rw-r--r-- | drivers/char/hw_random/geode-rng.c | 6 | ||||
-rw-r--r-- | drivers/char/hw_random/intel-rng.c | 2 | ||||
-rw-r--r-- | drivers/char/hw_random/omap-rng.c | 51 | ||||
-rw-r--r-- | drivers/char/keyboard.c | 139 | ||||
-rw-r--r-- | drivers/char/moxa.c | 8 | ||||
-rw-r--r-- | drivers/char/pc8736x_gpio.c | 1 | ||||
-rw-r--r-- | drivers/char/snsc.c | 7 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 808 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 59 | ||||
-rw-r--r-- | drivers/char/vt_ioctl.c | 2 | ||||
-rw-r--r-- | drivers/char/watchdog/Kconfig | 8 |
12 files changed, 923 insertions, 176 deletions
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 41db8060e8f7..017f755632a3 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -311,7 +311,8 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet, | |||
311 | /* CD went away; no more connection */ | 311 | /* CD went away; no more connection */ |
312 | pr_debug("hvsi%i: CD dropped\n", hp->index); | 312 | pr_debug("hvsi%i: CD dropped\n", hp->index); |
313 | hp->mctrl &= TIOCM_CD; | 313 | hp->mctrl &= TIOCM_CD; |
314 | if (!(hp->tty->flags & CLOCAL)) | 314 | /* If userland hasn't done an open(2) yet, hp->tty is NULL. */ |
315 | if (hp->tty && !(hp->tty->flags & CLOCAL)) | ||
315 | *to_hangup = hp->tty; | 316 | *to_hangup = hp->tty; |
316 | } | 317 | } |
317 | break; | 318 | break; |
@@ -986,10 +987,7 @@ static void hvsi_write_worker(void *arg) | |||
986 | start_j = 0; | 987 | start_j = 0; |
987 | #endif /* DEBUG */ | 988 | #endif /* DEBUG */ |
988 | wake_up_all(&hp->emptyq); | 989 | wake_up_all(&hp->emptyq); |
989 | if (test_bit(TTY_DO_WRITE_WAKEUP, &hp->tty->flags) | 990 | tty_wakeup(hp->tty); |
990 | && hp->tty->ldisc.write_wakeup) | ||
991 | hp->tty->ldisc.write_wakeup(hp->tty); | ||
992 | wake_up_interruptible(&hp->tty->write_wait); | ||
993 | } | 991 | } |
994 | 992 | ||
995 | out: | 993 | out: |
diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c index be61f22ee7bb..d37ced0d132b 100644 --- a/drivers/char/hw_random/geode-rng.c +++ b/drivers/char/hw_random/geode-rng.c | |||
@@ -107,10 +107,14 @@ found: | |||
107 | if (err) { | 107 | if (err) { |
108 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", | 108 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", |
109 | err); | 109 | err); |
110 | goto out; | 110 | goto err_unmap; |
111 | } | 111 | } |
112 | out: | 112 | out: |
113 | return err; | 113 | return err; |
114 | |||
115 | err_unmap: | ||
116 | iounmap(mem); | ||
117 | goto out; | ||
114 | } | 118 | } |
115 | 119 | ||
116 | static void __exit mod_exit(void) | 120 | static void __exit mod_exit(void) |
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 6594bd5645f4..ccd7e7102234 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c | |||
@@ -164,7 +164,7 @@ static int __init mod_init(void) | |||
164 | if (err) { | 164 | if (err) { |
165 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", | 165 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", |
166 | err); | 166 | err); |
167 | goto out; | 167 | goto err_unmap; |
168 | } | 168 | } |
169 | out: | 169 | out: |
170 | return err; | 170 | return err; |
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 819516b35a79..a01d796d1eeb 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c | |||
@@ -25,12 +25,12 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/random.h> | 27 | #include <linux/random.h> |
28 | #include <linux/clk.h> | ||
28 | #include <linux/err.h> | 29 | #include <linux/err.h> |
29 | #include <linux/device.h> | 30 | #include <linux/platform_device.h> |
30 | #include <linux/hw_random.h> | 31 | #include <linux/hw_random.h> |
31 | 32 | ||
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
33 | #include <asm/hardware/clock.h> | ||
34 | 34 | ||
35 | #define RNG_OUT_REG 0x00 /* Output register */ | 35 | #define RNG_OUT_REG 0x00 /* Output register */ |
36 | #define RNG_STAT_REG 0x04 /* Status register | 36 | #define RNG_STAT_REG 0x04 /* Status register |
@@ -52,7 +52,7 @@ | |||
52 | 52 | ||
53 | static void __iomem *rng_base; | 53 | static void __iomem *rng_base; |
54 | static struct clk *rng_ick; | 54 | static struct clk *rng_ick; |
55 | static struct device *rng_dev; | 55 | static struct platform_device *rng_dev; |
56 | 56 | ||
57 | static u32 omap_rng_read_reg(int reg) | 57 | static u32 omap_rng_read_reg(int reg) |
58 | { | 58 | { |
@@ -83,9 +83,8 @@ static struct hwrng omap_rng_ops = { | |||
83 | .data_read = omap_rng_data_read, | 83 | .data_read = omap_rng_data_read, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static int __init omap_rng_probe(struct device *dev) | 86 | static int __init omap_rng_probe(struct platform_device *pdev) |
87 | { | 87 | { |
88 | struct platform_device *pdev = to_platform_device(dev); | ||
89 | struct resource *res, *mem; | 88 | struct resource *res, *mem; |
90 | int ret; | 89 | int ret; |
91 | 90 | ||
@@ -95,16 +94,14 @@ static int __init omap_rng_probe(struct device *dev) | |||
95 | */ | 94 | */ |
96 | BUG_ON(rng_dev); | 95 | BUG_ON(rng_dev); |
97 | 96 | ||
98 | if (cpu_is_omap24xx()) { | 97 | if (cpu_is_omap24xx()) { |
99 | rng_ick = clk_get(NULL, "rng_ick"); | 98 | rng_ick = clk_get(NULL, "rng_ick"); |
100 | if (IS_ERR(rng_ick)) { | 99 | if (IS_ERR(rng_ick)) { |
101 | dev_err(dev, "Could not get rng_ick\n"); | 100 | dev_err(&pdev->dev, "Could not get rng_ick\n"); |
102 | ret = PTR_ERR(rng_ick); | 101 | ret = PTR_ERR(rng_ick); |
103 | return ret; | 102 | return ret; |
104 | } | 103 | } else |
105 | else { | 104 | clk_enable(rng_ick); |
106 | clk_use(rng_ick); | ||
107 | } | ||
108 | } | 105 | } |
109 | 106 | ||
110 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 107 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -117,7 +114,7 @@ static int __init omap_rng_probe(struct device *dev) | |||
117 | if (mem == NULL) | 114 | if (mem == NULL) |
118 | return -EBUSY; | 115 | return -EBUSY; |
119 | 116 | ||
120 | dev_set_drvdata(dev, mem); | 117 | dev_set_drvdata(&pdev->dev, mem); |
121 | rng_base = (u32 __iomem *)io_p2v(res->start); | 118 | rng_base = (u32 __iomem *)io_p2v(res->start); |
122 | 119 | ||
123 | ret = hwrng_register(&omap_rng_ops); | 120 | ret = hwrng_register(&omap_rng_ops); |
@@ -127,25 +124,25 @@ static int __init omap_rng_probe(struct device *dev) | |||
127 | return ret; | 124 | return ret; |
128 | } | 125 | } |
129 | 126 | ||
130 | dev_info(dev, "OMAP Random Number Generator ver. %02x\n", | 127 | dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", |
131 | omap_rng_read_reg(RNG_REV_REG)); | 128 | omap_rng_read_reg(RNG_REV_REG)); |
132 | omap_rng_write_reg(RNG_MASK_REG, 0x1); | 129 | omap_rng_write_reg(RNG_MASK_REG, 0x1); |
133 | 130 | ||
134 | rng_dev = dev; | 131 | rng_dev = pdev; |
135 | 132 | ||
136 | return 0; | 133 | return 0; |
137 | } | 134 | } |
138 | 135 | ||
139 | static int __exit omap_rng_remove(struct device *dev) | 136 | static int __exit omap_rng_remove(struct platform_device *pdev) |
140 | { | 137 | { |
141 | struct resource *mem = dev_get_drvdata(dev); | 138 | struct resource *mem = dev_get_drvdata(&pdev->dev); |
142 | 139 | ||
143 | hwrng_unregister(&omap_rng_ops); | 140 | hwrng_unregister(&omap_rng_ops); |
144 | 141 | ||
145 | omap_rng_write_reg(RNG_MASK_REG, 0x0); | 142 | omap_rng_write_reg(RNG_MASK_REG, 0x0); |
146 | 143 | ||
147 | if (cpu_is_omap24xx()) { | 144 | if (cpu_is_omap24xx()) { |
148 | clk_unuse(rng_ick); | 145 | clk_disable(rng_ick); |
149 | clk_put(rng_ick); | 146 | clk_put(rng_ick); |
150 | } | 147 | } |
151 | 148 | ||
@@ -157,18 +154,16 @@ static int __exit omap_rng_remove(struct device *dev) | |||
157 | 154 | ||
158 | #ifdef CONFIG_PM | 155 | #ifdef CONFIG_PM |
159 | 156 | ||
160 | static int omap_rng_suspend(struct device *dev, pm_message_t message, u32 level) | 157 | static int omap_rng_suspend(struct platform_device *pdev, pm_message_t message) |
161 | { | 158 | { |
162 | omap_rng_write_reg(RNG_MASK_REG, 0x0); | 159 | omap_rng_write_reg(RNG_MASK_REG, 0x0); |
163 | |||
164 | return 0; | 160 | return 0; |
165 | } | 161 | } |
166 | 162 | ||
167 | static int omap_rng_resume(struct device *dev, pm_message_t message, u32 level) | 163 | static int omap_rng_resume(struct platform_device *pdev) |
168 | { | 164 | { |
169 | omap_rng_write_reg(RNG_MASK_REG, 0x1); | 165 | omap_rng_write_reg(RNG_MASK_REG, 0x1); |
170 | 166 | return 0; | |
171 | return 1; | ||
172 | } | 167 | } |
173 | 168 | ||
174 | #else | 169 | #else |
@@ -179,9 +174,11 @@ static int omap_rng_resume(struct device *dev, pm_message_t message, u32 level) | |||
179 | #endif | 174 | #endif |
180 | 175 | ||
181 | 176 | ||
182 | static struct device_driver omap_rng_driver = { | 177 | static struct platform_driver omap_rng_driver = { |
183 | .name = "omap_rng", | 178 | .driver = { |
184 | .bus = &platform_bus_type, | 179 | .name = "omap_rng", |
180 | .owner = THIS_MODULE, | ||
181 | }, | ||
185 | .probe = omap_rng_probe, | 182 | .probe = omap_rng_probe, |
186 | .remove = __exit_p(omap_rng_remove), | 183 | .remove = __exit_p(omap_rng_remove), |
187 | .suspend = omap_rng_suspend, | 184 | .suspend = omap_rng_suspend, |
@@ -193,12 +190,12 @@ static int __init omap_rng_init(void) | |||
193 | if (!cpu_is_omap16xx() && !cpu_is_omap24xx()) | 190 | if (!cpu_is_omap16xx() && !cpu_is_omap24xx()) |
194 | return -ENODEV; | 191 | return -ENODEV; |
195 | 192 | ||
196 | return driver_register(&omap_rng_driver); | 193 | return platform_driver_register(&omap_rng_driver); |
197 | } | 194 | } |
198 | 195 | ||
199 | static void __exit omap_rng_exit(void) | 196 | static void __exit omap_rng_exit(void) |
200 | { | 197 | { |
201 | driver_unregister(&omap_rng_driver); | 198 | platform_driver_unregister(&omap_rng_driver); |
202 | } | 199 | } |
203 | 200 | ||
204 | module_init(omap_rng_init); | 201 | module_init(omap_rng_init); |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 056ebe84b81d..3e90aac37510 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -107,7 +107,6 @@ const int NR_TYPES = ARRAY_SIZE(max_vals); | |||
107 | 107 | ||
108 | struct kbd_struct kbd_table[MAX_NR_CONSOLES]; | 108 | struct kbd_struct kbd_table[MAX_NR_CONSOLES]; |
109 | static struct kbd_struct *kbd = kbd_table; | 109 | static struct kbd_struct *kbd = kbd_table; |
110 | static struct kbd_struct kbd0; | ||
111 | 110 | ||
112 | int spawnpid, spawnsig; | 111 | int spawnpid, spawnsig; |
113 | 112 | ||
@@ -223,13 +222,13 @@ static void kd_nosound(unsigned long ignored) | |||
223 | { | 222 | { |
224 | struct list_head *node; | 223 | struct list_head *node; |
225 | 224 | ||
226 | list_for_each(node,&kbd_handler.h_list) { | 225 | list_for_each(node, &kbd_handler.h_list) { |
227 | struct input_handle *handle = to_handle_h(node); | 226 | struct input_handle *handle = to_handle_h(node); |
228 | if (test_bit(EV_SND, handle->dev->evbit)) { | 227 | if (test_bit(EV_SND, handle->dev->evbit)) { |
229 | if (test_bit(SND_TONE, handle->dev->sndbit)) | 228 | if (test_bit(SND_TONE, handle->dev->sndbit)) |
230 | input_event(handle->dev, EV_SND, SND_TONE, 0); | 229 | input_inject_event(handle, EV_SND, SND_TONE, 0); |
231 | if (test_bit(SND_BELL, handle->dev->sndbit)) | 230 | if (test_bit(SND_BELL, handle->dev->sndbit)) |
232 | input_event(handle->dev, EV_SND, SND_BELL, 0); | 231 | input_inject_event(handle, EV_SND, SND_BELL, 0); |
233 | } | 232 | } |
234 | } | 233 | } |
235 | } | 234 | } |
@@ -247,11 +246,11 @@ void kd_mksound(unsigned int hz, unsigned int ticks) | |||
247 | struct input_handle *handle = to_handle_h(node); | 246 | struct input_handle *handle = to_handle_h(node); |
248 | if (test_bit(EV_SND, handle->dev->evbit)) { | 247 | if (test_bit(EV_SND, handle->dev->evbit)) { |
249 | if (test_bit(SND_TONE, handle->dev->sndbit)) { | 248 | if (test_bit(SND_TONE, handle->dev->sndbit)) { |
250 | input_event(handle->dev, EV_SND, SND_TONE, hz); | 249 | input_inject_event(handle, EV_SND, SND_TONE, hz); |
251 | break; | 250 | break; |
252 | } | 251 | } |
253 | if (test_bit(SND_BELL, handle->dev->sndbit)) { | 252 | if (test_bit(SND_BELL, handle->dev->sndbit)) { |
254 | input_event(handle->dev, EV_SND, SND_BELL, 1); | 253 | input_inject_event(handle, EV_SND, SND_BELL, 1); |
255 | break; | 254 | break; |
256 | } | 255 | } |
257 | } | 256 | } |
@@ -272,15 +271,15 @@ int kbd_rate(struct kbd_repeat *rep) | |||
272 | unsigned int d = 0; | 271 | unsigned int d = 0; |
273 | unsigned int p = 0; | 272 | unsigned int p = 0; |
274 | 273 | ||
275 | list_for_each(node,&kbd_handler.h_list) { | 274 | list_for_each(node, &kbd_handler.h_list) { |
276 | struct input_handle *handle = to_handle_h(node); | 275 | struct input_handle *handle = to_handle_h(node); |
277 | struct input_dev *dev = handle->dev; | 276 | struct input_dev *dev = handle->dev; |
278 | 277 | ||
279 | if (test_bit(EV_REP, dev->evbit)) { | 278 | if (test_bit(EV_REP, dev->evbit)) { |
280 | if (rep->delay > 0) | 279 | if (rep->delay > 0) |
281 | input_event(dev, EV_REP, REP_DELAY, rep->delay); | 280 | input_inject_event(handle, EV_REP, REP_DELAY, rep->delay); |
282 | if (rep->period > 0) | 281 | if (rep->period > 0) |
283 | input_event(dev, EV_REP, REP_PERIOD, rep->period); | 282 | input_inject_event(handle, EV_REP, REP_PERIOD, rep->period); |
284 | d = dev->rep[REP_DELAY]; | 283 | d = dev->rep[REP_DELAY]; |
285 | p = dev->rep[REP_PERIOD]; | 284 | p = dev->rep[REP_PERIOD]; |
286 | } | 285 | } |
@@ -988,7 +987,7 @@ static inline unsigned char getleds(void) | |||
988 | * interrupt routines for this thing allows us to easily mask | 987 | * interrupt routines for this thing allows us to easily mask |
989 | * this when we don't want any of the above to happen. | 988 | * this when we don't want any of the above to happen. |
990 | * This allows for easy and efficient race-condition prevention | 989 | * This allows for easy and efficient race-condition prevention |
991 | * for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ... | 990 | * for kbd_start => input_inject_event(dev, EV_LED, ...) => ... |
992 | */ | 991 | */ |
993 | 992 | ||
994 | static void kbd_bh(unsigned long dummy) | 993 | static void kbd_bh(unsigned long dummy) |
@@ -998,11 +997,11 @@ static void kbd_bh(unsigned long dummy) | |||
998 | 997 | ||
999 | if (leds != ledstate) { | 998 | if (leds != ledstate) { |
1000 | list_for_each(node, &kbd_handler.h_list) { | 999 | list_for_each(node, &kbd_handler.h_list) { |
1001 | struct input_handle * handle = to_handle_h(node); | 1000 | struct input_handle *handle = to_handle_h(node); |
1002 | input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | 1001 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); |
1003 | input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); | 1002 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); |
1004 | input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); | 1003 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); |
1005 | input_sync(handle->dev); | 1004 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); |
1006 | } | 1005 | } |
1007 | } | 1006 | } |
1008 | 1007 | ||
@@ -1011,23 +1010,6 @@ static void kbd_bh(unsigned long dummy) | |||
1011 | 1010 | ||
1012 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); | 1011 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); |
1013 | 1012 | ||
1014 | /* | ||
1015 | * This allows a newly plugged keyboard to pick the LED state. | ||
1016 | */ | ||
1017 | static void kbd_refresh_leds(struct input_handle *handle) | ||
1018 | { | ||
1019 | unsigned char leds = ledstate; | ||
1020 | |||
1021 | tasklet_disable(&keyboard_tasklet); | ||
1022 | if (leds != 0xff) { | ||
1023 | input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | ||
1024 | input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1025 | input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1026 | input_sync(handle->dev); | ||
1027 | } | ||
1028 | tasklet_enable(&keyboard_tasklet); | ||
1029 | } | ||
1030 | |||
1031 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ | 1013 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ |
1032 | defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ | 1014 | defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ |
1033 | defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ | 1015 | defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ |
@@ -1043,7 +1025,7 @@ static const unsigned short x86_keycodes[256] = | |||
1043 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, | 1025 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, |
1044 | 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, | 1026 | 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, |
1045 | 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92, | 1027 | 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92, |
1046 | 284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339, | 1028 | 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339, |
1047 | 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, | 1029 | 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, |
1048 | 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, | 1030 | 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, |
1049 | 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, | 1031 | 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, |
@@ -1065,38 +1047,55 @@ extern void sun_do_break(void); | |||
1065 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, | 1047 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, |
1066 | unsigned char up_flag) | 1048 | unsigned char up_flag) |
1067 | { | 1049 | { |
1068 | if (keycode > 255 || !x86_keycodes[keycode]) | 1050 | int code; |
1069 | return -1; | ||
1070 | 1051 | ||
1071 | switch (keycode) { | 1052 | switch (keycode) { |
1072 | case KEY_PAUSE: | 1053 | case KEY_PAUSE: |
1073 | put_queue(vc, 0xe1); | 1054 | put_queue(vc, 0xe1); |
1074 | put_queue(vc, 0x1d | up_flag); | 1055 | put_queue(vc, 0x1d | up_flag); |
1075 | put_queue(vc, 0x45 | up_flag); | 1056 | put_queue(vc, 0x45 | up_flag); |
1076 | return 0; | 1057 | break; |
1058 | |||
1077 | case KEY_HANGEUL: | 1059 | case KEY_HANGEUL: |
1078 | if (!up_flag) | 1060 | if (!up_flag) |
1079 | put_queue(vc, 0xf2); | 1061 | put_queue(vc, 0xf2); |
1080 | return 0; | 1062 | break; |
1063 | |||
1081 | case KEY_HANJA: | 1064 | case KEY_HANJA: |
1082 | if (!up_flag) | 1065 | if (!up_flag) |
1083 | put_queue(vc, 0xf1); | 1066 | put_queue(vc, 0xf1); |
1084 | return 0; | 1067 | break; |
1085 | } | ||
1086 | 1068 | ||
1087 | if (keycode == KEY_SYSRQ && sysrq_alt) { | 1069 | case KEY_SYSRQ: |
1088 | put_queue(vc, 0x54 | up_flag); | 1070 | /* |
1089 | return 0; | 1071 | * Real AT keyboards (that's what we're trying |
1090 | } | 1072 | * to emulate here emit 0xe0 0x2a 0xe0 0x37 when |
1073 | * pressing PrtSc/SysRq alone, but simply 0x54 | ||
1074 | * when pressing Alt+PrtSc/SysRq. | ||
1075 | */ | ||
1076 | if (sysrq_alt) { | ||
1077 | put_queue(vc, 0x54 | up_flag); | ||
1078 | } else { | ||
1079 | put_queue(vc, 0xe0); | ||
1080 | put_queue(vc, 0x2a | up_flag); | ||
1081 | put_queue(vc, 0xe0); | ||
1082 | put_queue(vc, 0x37 | up_flag); | ||
1083 | } | ||
1084 | break; | ||
1085 | |||
1086 | default: | ||
1087 | if (keycode > 255) | ||
1088 | return -1; | ||
1091 | 1089 | ||
1092 | if (x86_keycodes[keycode] & 0x100) | 1090 | code = x86_keycodes[keycode]; |
1093 | put_queue(vc, 0xe0); | 1091 | if (!code) |
1092 | return -1; | ||
1094 | 1093 | ||
1095 | put_queue(vc, (x86_keycodes[keycode] & 0x7f) | up_flag); | 1094 | if (code & 0x100) |
1095 | put_queue(vc, 0xe0); | ||
1096 | put_queue(vc, (code & 0x7f) | up_flag); | ||
1096 | 1097 | ||
1097 | if (keycode == KEY_SYSRQ) { | 1098 | break; |
1098 | put_queue(vc, 0xe0); | ||
1099 | put_queue(vc, 0x37 | up_flag); | ||
1100 | } | 1099 | } |
1101 | 1100 | ||
1102 | return 0; | 1101 | return 0; |
@@ -1298,16 +1297,15 @@ static struct input_handle *kbd_connect(struct input_handler *handler, | |||
1298 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) | 1297 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) |
1299 | return NULL; | 1298 | return NULL; |
1300 | 1299 | ||
1301 | if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) | 1300 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); |
1301 | if (!handle) | ||
1302 | return NULL; | 1302 | return NULL; |
1303 | memset(handle, 0, sizeof(struct input_handle)); | ||
1304 | 1303 | ||
1305 | handle->dev = dev; | 1304 | handle->dev = dev; |
1306 | handle->handler = handler; | 1305 | handle->handler = handler; |
1307 | handle->name = "kbd"; | 1306 | handle->name = "kbd"; |
1308 | 1307 | ||
1309 | input_open_device(handle); | 1308 | input_open_device(handle); |
1310 | kbd_refresh_leds(handle); | ||
1311 | 1309 | ||
1312 | return handle; | 1310 | return handle; |
1313 | } | 1311 | } |
@@ -1318,6 +1316,24 @@ static void kbd_disconnect(struct input_handle *handle) | |||
1318 | kfree(handle); | 1316 | kfree(handle); |
1319 | } | 1317 | } |
1320 | 1318 | ||
1319 | /* | ||
1320 | * Start keyboard handler on the new keyboard by refreshing LED state to | ||
1321 | * match the rest of the system. | ||
1322 | */ | ||
1323 | static void kbd_start(struct input_handle *handle) | ||
1324 | { | ||
1325 | unsigned char leds = ledstate; | ||
1326 | |||
1327 | tasklet_disable(&keyboard_tasklet); | ||
1328 | if (leds != 0xff) { | ||
1329 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | ||
1330 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1331 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1332 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); | ||
1333 | } | ||
1334 | tasklet_enable(&keyboard_tasklet); | ||
1335 | } | ||
1336 | |||
1321 | static struct input_device_id kbd_ids[] = { | 1337 | static struct input_device_id kbd_ids[] = { |
1322 | { | 1338 | { |
1323 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | 1339 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, |
@@ -1338,6 +1354,7 @@ static struct input_handler kbd_handler = { | |||
1338 | .event = kbd_event, | 1354 | .event = kbd_event, |
1339 | .connect = kbd_connect, | 1355 | .connect = kbd_connect, |
1340 | .disconnect = kbd_disconnect, | 1356 | .disconnect = kbd_disconnect, |
1357 | .start = kbd_start, | ||
1341 | .name = "kbd", | 1358 | .name = "kbd", |
1342 | .id_table = kbd_ids, | 1359 | .id_table = kbd_ids, |
1343 | }; | 1360 | }; |
@@ -1346,15 +1363,15 @@ int __init kbd_init(void) | |||
1346 | { | 1363 | { |
1347 | int i; | 1364 | int i; |
1348 | 1365 | ||
1349 | kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS; | 1366 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
1350 | kbd0.ledmode = LED_SHOW_FLAGS; | 1367 | kbd_table[i].ledflagstate = KBD_DEFLEDS; |
1351 | kbd0.lockstate = KBD_DEFLOCK; | 1368 | kbd_table[i].default_ledflagstate = KBD_DEFLEDS; |
1352 | kbd0.slockstate = 0; | 1369 | kbd_table[i].ledmode = LED_SHOW_FLAGS; |
1353 | kbd0.modeflags = KBD_DEFMODE; | 1370 | kbd_table[i].lockstate = KBD_DEFLOCK; |
1354 | kbd0.kbdmode = VC_XLATE; | 1371 | kbd_table[i].slockstate = 0; |
1355 | 1372 | kbd_table[i].modeflags = KBD_DEFMODE; | |
1356 | for (i = 0 ; i < MAX_NR_CONSOLES ; i++) | 1373 | kbd_table[i].kbdmode = VC_XLATE; |
1357 | kbd_table[i] = kbd0; | 1374 | } |
1358 | 1375 | ||
1359 | input_register_handler(&kbd_handler); | 1376 | input_register_handler(&kbd_handler); |
1360 | 1377 | ||
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 4ea7bd5f4f56..a369dd6877d8 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -142,6 +142,7 @@ typedef struct _moxa_board_conf { | |||
142 | 142 | ||
143 | static moxa_board_conf moxa_boards[MAX_BOARDS]; | 143 | static moxa_board_conf moxa_boards[MAX_BOARDS]; |
144 | static void __iomem *moxaBaseAddr[MAX_BOARDS]; | 144 | static void __iomem *moxaBaseAddr[MAX_BOARDS]; |
145 | static int loadstat[MAX_BOARDS]; | ||
145 | 146 | ||
146 | struct moxa_str { | 147 | struct moxa_str { |
147 | int type; | 148 | int type; |
@@ -1688,6 +1689,8 @@ int MoxaDriverPoll(void) | |||
1688 | if (moxaCard == 0) | 1689 | if (moxaCard == 0) |
1689 | return (-1); | 1690 | return (-1); |
1690 | for (card = 0; card < MAX_BOARDS; card++) { | 1691 | for (card = 0; card < MAX_BOARDS; card++) { |
1692 | if (loadstat[card] == 0) | ||
1693 | continue; | ||
1691 | if ((ports = moxa_boards[card].numPorts) == 0) | 1694 | if ((ports = moxa_boards[card].numPorts) == 0) |
1692 | continue; | 1695 | continue; |
1693 | if (readb(moxaIntPend[card]) == 0xff) { | 1696 | if (readb(moxaIntPend[card]) == 0xff) { |
@@ -2903,6 +2906,7 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) | |||
2903 | } | 2906 | } |
2904 | break; | 2907 | break; |
2905 | } | 2908 | } |
2909 | loadstat[cardno] = 1; | ||
2906 | return (0); | 2910 | return (0); |
2907 | } | 2911 | } |
2908 | 2912 | ||
@@ -2920,7 +2924,7 @@ static int moxaloadc218(int cardno, void __iomem *baseAddr, int len) | |||
2920 | len1 = len >> 1; | 2924 | len1 = len >> 1; |
2921 | ptr = (ushort *) moxaBuff; | 2925 | ptr = (ushort *) moxaBuff; |
2922 | for (i = 0; i < len1; i++) | 2926 | for (i = 0; i < len1; i++) |
2923 | usum += *(ptr + i); | 2927 | usum += le16_to_cpu(*(ptr + i)); |
2924 | retry = 0; | 2928 | retry = 0; |
2925 | do { | 2929 | do { |
2926 | len1 = len >> 1; | 2930 | len1 = len >> 1; |
@@ -2992,7 +2996,7 @@ static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPor | |||
2992 | wlen = len >> 1; | 2996 | wlen = len >> 1; |
2993 | uptr = (ushort *) moxaBuff; | 2997 | uptr = (ushort *) moxaBuff; |
2994 | for (i = 0; i < wlen; i++) | 2998 | for (i = 0; i < wlen; i++) |
2995 | usum += uptr[i]; | 2999 | usum += le16_to_cpu(uptr[i]); |
2996 | retry = 0; | 3000 | retry = 0; |
2997 | j = 0; | 3001 | j = 0; |
2998 | do { | 3002 | do { |
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index 645eb81cb5a9..84e5a68635f1 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c | |||
@@ -221,7 +221,6 @@ static struct nsc_gpio_ops pc8736x_gpio_ops = { | |||
221 | .gpio_change = pc8736x_gpio_change, | 221 | .gpio_change = pc8736x_gpio_change, |
222 | .gpio_current = pc8736x_gpio_current | 222 | .gpio_current = pc8736x_gpio_current |
223 | }; | 223 | }; |
224 | EXPORT_SYMBOL(pc8736x_gpio_ops); | ||
225 | 224 | ||
226 | static int pc8736x_gpio_open(struct inode *inode, struct file *file) | 225 | static int pc8736x_gpio_open(struct inode *inode, struct file *file) |
227 | { | 226 | { |
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index afc6eda602f7..07e0b75f2338 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c | |||
@@ -374,7 +374,12 @@ scdrv_init(void) | |||
374 | struct sysctl_data_s *scd; | 374 | struct sysctl_data_s *scd; |
375 | void *salbuf; | 375 | void *salbuf; |
376 | dev_t first_dev, dev; | 376 | dev_t first_dev, dev; |
377 | nasid_t event_nasid = ia64_sn_get_console_nasid(); | 377 | nasid_t event_nasid; |
378 | |||
379 | if (!ia64_platform_is("sn2")) | ||
380 | return -ENODEV; | ||
381 | |||
382 | event_nasid = ia64_sn_get_console_nasid(); | ||
378 | 383 | ||
379 | if (alloc_chrdev_region(&first_dev, 0, num_cnodes, | 384 | if (alloc_chrdev_region(&first_dev, 0, num_cnodes, |
380 | SYSCTL_BASENAME) < 0) { | 385 | SYSCTL_BASENAME) < 0) { |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index bfdb90242a90..bb0d9199e994 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -153,6 +153,15 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
153 | static int tty_fasync(int fd, struct file * filp, int on); | 153 | static int tty_fasync(int fd, struct file * filp, int on); |
154 | static void release_mem(struct tty_struct *tty, int idx); | 154 | static void release_mem(struct tty_struct *tty, int idx); |
155 | 155 | ||
156 | /** | ||
157 | * alloc_tty_struct - allocate a tty object | ||
158 | * | ||
159 | * Return a new empty tty structure. The data fields have not | ||
160 | * been initialized in any way but has been zeroed | ||
161 | * | ||
162 | * Locking: none | ||
163 | * FIXME: use kzalloc | ||
164 | */ | ||
156 | 165 | ||
157 | static struct tty_struct *alloc_tty_struct(void) | 166 | static struct tty_struct *alloc_tty_struct(void) |
158 | { | 167 | { |
@@ -166,6 +175,15 @@ static struct tty_struct *alloc_tty_struct(void) | |||
166 | 175 | ||
167 | static void tty_buffer_free_all(struct tty_struct *); | 176 | static void tty_buffer_free_all(struct tty_struct *); |
168 | 177 | ||
178 | /** | ||
179 | * free_tty_struct - free a disused tty | ||
180 | * @tty: tty struct to free | ||
181 | * | ||
182 | * Free the write buffers, tty queue and tty memory itself. | ||
183 | * | ||
184 | * Locking: none. Must be called after tty is definitely unused | ||
185 | */ | ||
186 | |||
169 | static inline void free_tty_struct(struct tty_struct *tty) | 187 | static inline void free_tty_struct(struct tty_struct *tty) |
170 | { | 188 | { |
171 | kfree(tty->write_buf); | 189 | kfree(tty->write_buf); |
@@ -175,6 +193,17 @@ static inline void free_tty_struct(struct tty_struct *tty) | |||
175 | 193 | ||
176 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) | 194 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) |
177 | 195 | ||
196 | /** | ||
197 | * tty_name - return tty naming | ||
198 | * @tty: tty structure | ||
199 | * @buf: buffer for output | ||
200 | * | ||
201 | * Convert a tty structure into a name. The name reflects the kernel | ||
202 | * naming policy and if udev is in use may not reflect user space | ||
203 | * | ||
204 | * Locking: none | ||
205 | */ | ||
206 | |||
178 | char *tty_name(struct tty_struct *tty, char *buf) | 207 | char *tty_name(struct tty_struct *tty, char *buf) |
179 | { | 208 | { |
180 | if (!tty) /* Hmm. NULL pointer. That's fun. */ | 209 | if (!tty) /* Hmm. NULL pointer. That's fun. */ |
@@ -235,6 +264,28 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
235 | * Tty buffer allocation management | 264 | * Tty buffer allocation management |
236 | */ | 265 | */ |
237 | 266 | ||
267 | |||
268 | /** | ||
269 | * tty_buffer_free_all - free buffers used by a tty | ||
270 | * @tty: tty to free from | ||
271 | * | ||
272 | * Remove all the buffers pending on a tty whether queued with data | ||
273 | * or in the free ring. Must be called when the tty is no longer in use | ||
274 | * | ||
275 | * Locking: none | ||
276 | */ | ||
277 | |||
278 | |||
279 | /** | ||
280 | * tty_buffer_free_all - free buffers used by a tty | ||
281 | * @tty: tty to free from | ||
282 | * | ||
283 | * Remove all the buffers pending on a tty whether queued with data | ||
284 | * or in the free ring. Must be called when the tty is no longer in use | ||
285 | * | ||
286 | * Locking: none | ||
287 | */ | ||
288 | |||
238 | static void tty_buffer_free_all(struct tty_struct *tty) | 289 | static void tty_buffer_free_all(struct tty_struct *tty) |
239 | { | 290 | { |
240 | struct tty_buffer *thead; | 291 | struct tty_buffer *thead; |
@@ -247,19 +298,47 @@ static void tty_buffer_free_all(struct tty_struct *tty) | |||
247 | kfree(thead); | 298 | kfree(thead); |
248 | } | 299 | } |
249 | tty->buf.tail = NULL; | 300 | tty->buf.tail = NULL; |
301 | tty->buf.memory_used = 0; | ||
250 | } | 302 | } |
251 | 303 | ||
304 | /** | ||
305 | * tty_buffer_init - prepare a tty buffer structure | ||
306 | * @tty: tty to initialise | ||
307 | * | ||
308 | * Set up the initial state of the buffer management for a tty device. | ||
309 | * Must be called before the other tty buffer functions are used. | ||
310 | * | ||
311 | * Locking: none | ||
312 | */ | ||
313 | |||
252 | static void tty_buffer_init(struct tty_struct *tty) | 314 | static void tty_buffer_init(struct tty_struct *tty) |
253 | { | 315 | { |
254 | spin_lock_init(&tty->buf.lock); | 316 | spin_lock_init(&tty->buf.lock); |
255 | tty->buf.head = NULL; | 317 | tty->buf.head = NULL; |
256 | tty->buf.tail = NULL; | 318 | tty->buf.tail = NULL; |
257 | tty->buf.free = NULL; | 319 | tty->buf.free = NULL; |
320 | tty->buf.memory_used = 0; | ||
258 | } | 321 | } |
259 | 322 | ||
260 | static struct tty_buffer *tty_buffer_alloc(size_t size) | 323 | /** |
324 | * tty_buffer_alloc - allocate a tty buffer | ||
325 | * @tty: tty device | ||
326 | * @size: desired size (characters) | ||
327 | * | ||
328 | * Allocate a new tty buffer to hold the desired number of characters. | ||
329 | * Return NULL if out of memory or the allocation would exceed the | ||
330 | * per device queue | ||
331 | * | ||
332 | * Locking: Caller must hold tty->buf.lock | ||
333 | */ | ||
334 | |||
335 | static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) | ||
261 | { | 336 | { |
262 | struct tty_buffer *p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | 337 | struct tty_buffer *p; |
338 | |||
339 | if (tty->buf.memory_used + size > 65536) | ||
340 | return NULL; | ||
341 | p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | ||
263 | if(p == NULL) | 342 | if(p == NULL) |
264 | return NULL; | 343 | return NULL; |
265 | p->used = 0; | 344 | p->used = 0; |
@@ -269,17 +348,27 @@ static struct tty_buffer *tty_buffer_alloc(size_t size) | |||
269 | p->read = 0; | 348 | p->read = 0; |
270 | p->char_buf_ptr = (char *)(p->data); | 349 | p->char_buf_ptr = (char *)(p->data); |
271 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | 350 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; |
272 | /* printk("Flip create %p\n", p); */ | 351 | tty->buf.memory_used += size; |
273 | return p; | 352 | return p; |
274 | } | 353 | } |
275 | 354 | ||
276 | /* Must be called with the tty_read lock held. This needs to acquire strategy | 355 | /** |
277 | code to decide if we should kfree or relink a given expired buffer */ | 356 | * tty_buffer_free - free a tty buffer |
357 | * @tty: tty owning the buffer | ||
358 | * @b: the buffer to free | ||
359 | * | ||
360 | * Free a tty buffer, or add it to the free list according to our | ||
361 | * internal strategy | ||
362 | * | ||
363 | * Locking: Caller must hold tty->buf.lock | ||
364 | */ | ||
278 | 365 | ||
279 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | 366 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) |
280 | { | 367 | { |
281 | /* Dumb strategy for now - should keep some stats */ | 368 | /* Dumb strategy for now - should keep some stats */ |
282 | /* printk("Flip dispose %p\n", b); */ | 369 | tty->buf.memory_used -= b->size; |
370 | WARN_ON(tty->buf.memory_used < 0); | ||
371 | |||
283 | if(b->size >= 512) | 372 | if(b->size >= 512) |
284 | kfree(b); | 373 | kfree(b); |
285 | else { | 374 | else { |
@@ -288,6 +377,18 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) | |||
288 | } | 377 | } |
289 | } | 378 | } |
290 | 379 | ||
380 | /** | ||
381 | * tty_buffer_find - find a free tty buffer | ||
382 | * @tty: tty owning the buffer | ||
383 | * @size: characters wanted | ||
384 | * | ||
385 | * Locate an existing suitable tty buffer or if we are lacking one then | ||
386 | * allocate a new one. We round our buffers off in 256 character chunks | ||
387 | * to get better allocation behaviour. | ||
388 | * | ||
389 | * Locking: Caller must hold tty->buf.lock | ||
390 | */ | ||
391 | |||
291 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | 392 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) |
292 | { | 393 | { |
293 | struct tty_buffer **tbh = &tty->buf.free; | 394 | struct tty_buffer **tbh = &tty->buf.free; |
@@ -299,20 +400,28 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | |||
299 | t->used = 0; | 400 | t->used = 0; |
300 | t->commit = 0; | 401 | t->commit = 0; |
301 | t->read = 0; | 402 | t->read = 0; |
302 | /* DEBUG ONLY */ | 403 | tty->buf.memory_used += t->size; |
303 | /* memset(t->data, '*', size); */ | ||
304 | /* printk("Flip recycle %p\n", t); */ | ||
305 | return t; | 404 | return t; |
306 | } | 405 | } |
307 | tbh = &((*tbh)->next); | 406 | tbh = &((*tbh)->next); |
308 | } | 407 | } |
309 | /* Round the buffer size out */ | 408 | /* Round the buffer size out */ |
310 | size = (size + 0xFF) & ~ 0xFF; | 409 | size = (size + 0xFF) & ~ 0xFF; |
311 | return tty_buffer_alloc(size); | 410 | return tty_buffer_alloc(tty, size); |
312 | /* Should possibly check if this fails for the largest buffer we | 411 | /* Should possibly check if this fails for the largest buffer we |
313 | have queued and recycle that ? */ | 412 | have queued and recycle that ? */ |
314 | } | 413 | } |
315 | 414 | ||
415 | /** | ||
416 | * tty_buffer_request_room - grow tty buffer if needed | ||
417 | * @tty: tty structure | ||
418 | * @size: size desired | ||
419 | * | ||
420 | * Make at least size bytes of linear space available for the tty | ||
421 | * buffer. If we fail return the size we managed to find. | ||
422 | * | ||
423 | * Locking: Takes tty->buf.lock | ||
424 | */ | ||
316 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | 425 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) |
317 | { | 426 | { |
318 | struct tty_buffer *b, *n; | 427 | struct tty_buffer *b, *n; |
@@ -347,6 +456,18 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
347 | } | 456 | } |
348 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | 457 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); |
349 | 458 | ||
459 | /** | ||
460 | * tty_insert_flip_string - Add characters to the tty buffer | ||
461 | * @tty: tty structure | ||
462 | * @chars: characters | ||
463 | * @size: size | ||
464 | * | ||
465 | * Queue a series of bytes to the tty buffering. All the characters | ||
466 | * passed are marked as without error. Returns the number added. | ||
467 | * | ||
468 | * Locking: Called functions may take tty->buf.lock | ||
469 | */ | ||
470 | |||
350 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | 471 | int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, |
351 | size_t size) | 472 | size_t size) |
352 | { | 473 | { |
@@ -370,6 +491,20 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, | |||
370 | } | 491 | } |
371 | EXPORT_SYMBOL(tty_insert_flip_string); | 492 | EXPORT_SYMBOL(tty_insert_flip_string); |
372 | 493 | ||
494 | /** | ||
495 | * tty_insert_flip_string_flags - Add characters to the tty buffer | ||
496 | * @tty: tty structure | ||
497 | * @chars: characters | ||
498 | * @flags: flag bytes | ||
499 | * @size: size | ||
500 | * | ||
501 | * Queue a series of bytes to the tty buffering. For each character | ||
502 | * the flags array indicates the status of the character. Returns the | ||
503 | * number added. | ||
504 | * | ||
505 | * Locking: Called functions may take tty->buf.lock | ||
506 | */ | ||
507 | |||
373 | int tty_insert_flip_string_flags(struct tty_struct *tty, | 508 | int tty_insert_flip_string_flags(struct tty_struct *tty, |
374 | const unsigned char *chars, const char *flags, size_t size) | 509 | const unsigned char *chars, const char *flags, size_t size) |
375 | { | 510 | { |
@@ -394,6 +529,17 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, | |||
394 | } | 529 | } |
395 | EXPORT_SYMBOL(tty_insert_flip_string_flags); | 530 | EXPORT_SYMBOL(tty_insert_flip_string_flags); |
396 | 531 | ||
532 | /** | ||
533 | * tty_schedule_flip - push characters to ldisc | ||
534 | * @tty: tty to push from | ||
535 | * | ||
536 | * Takes any pending buffers and transfers their ownership to the | ||
537 | * ldisc side of the queue. It then schedules those characters for | ||
538 | * processing by the line discipline. | ||
539 | * | ||
540 | * Locking: Takes tty->buf.lock | ||
541 | */ | ||
542 | |||
397 | void tty_schedule_flip(struct tty_struct *tty) | 543 | void tty_schedule_flip(struct tty_struct *tty) |
398 | { | 544 | { |
399 | unsigned long flags; | 545 | unsigned long flags; |
@@ -405,12 +551,19 @@ void tty_schedule_flip(struct tty_struct *tty) | |||
405 | } | 551 | } |
406 | EXPORT_SYMBOL(tty_schedule_flip); | 552 | EXPORT_SYMBOL(tty_schedule_flip); |
407 | 553 | ||
408 | /* | 554 | /** |
555 | * tty_prepare_flip_string - make room for characters | ||
556 | * @tty: tty | ||
557 | * @chars: return pointer for character write area | ||
558 | * @size: desired size | ||
559 | * | ||
409 | * Prepare a block of space in the buffer for data. Returns the length | 560 | * Prepare a block of space in the buffer for data. Returns the length |
410 | * available and buffer pointer to the space which is now allocated and | 561 | * available and buffer pointer to the space which is now allocated and |
411 | * accounted for as ready for normal characters. This is used for drivers | 562 | * accounted for as ready for normal characters. This is used for drivers |
412 | * that need their own block copy routines into the buffer. There is no | 563 | * that need their own block copy routines into the buffer. There is no |
413 | * guarantee the buffer is a DMA target! | 564 | * guarantee the buffer is a DMA target! |
565 | * | ||
566 | * Locking: May call functions taking tty->buf.lock | ||
414 | */ | 567 | */ |
415 | 568 | ||
416 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) | 569 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) |
@@ -427,12 +580,20 @@ int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_ | |||
427 | 580 | ||
428 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | 581 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); |
429 | 582 | ||
430 | /* | 583 | /** |
584 | * tty_prepare_flip_string_flags - make room for characters | ||
585 | * @tty: tty | ||
586 | * @chars: return pointer for character write area | ||
587 | * @flags: return pointer for status flag write area | ||
588 | * @size: desired size | ||
589 | * | ||
431 | * Prepare a block of space in the buffer for data. Returns the length | 590 | * Prepare a block of space in the buffer for data. Returns the length |
432 | * available and buffer pointer to the space which is now allocated and | 591 | * available and buffer pointer to the space which is now allocated and |
433 | * accounted for as ready for characters. This is used for drivers | 592 | * accounted for as ready for characters. This is used for drivers |
434 | * that need their own block copy routines into the buffer. There is no | 593 | * that need their own block copy routines into the buffer. There is no |
435 | * guarantee the buffer is a DMA target! | 594 | * guarantee the buffer is a DMA target! |
595 | * | ||
596 | * Locking: May call functions taking tty->buf.lock | ||
436 | */ | 597 | */ |
437 | 598 | ||
438 | int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) | 599 | int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) |
@@ -451,10 +612,16 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | |||
451 | 612 | ||
452 | 613 | ||
453 | 614 | ||
454 | /* | 615 | /** |
616 | * tty_set_termios_ldisc - set ldisc field | ||
617 | * @tty: tty structure | ||
618 | * @num: line discipline number | ||
619 | * | ||
455 | * This is probably overkill for real world processors but | 620 | * This is probably overkill for real world processors but |
456 | * they are not on hot paths so a little discipline won't do | 621 | * they are not on hot paths so a little discipline won't do |
457 | * any harm. | 622 | * any harm. |
623 | * | ||
624 | * Locking: takes termios_sem | ||
458 | */ | 625 | */ |
459 | 626 | ||
460 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | 627 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) |
@@ -474,6 +641,19 @@ static DEFINE_SPINLOCK(tty_ldisc_lock); | |||
474 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); | 641 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); |
475 | static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ | 642 | static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ |
476 | 643 | ||
644 | /** | ||
645 | * tty_register_ldisc - install a line discipline | ||
646 | * @disc: ldisc number | ||
647 | * @new_ldisc: pointer to the ldisc object | ||
648 | * | ||
649 | * Installs a new line discipline into the kernel. The discipline | ||
650 | * is set up as unreferenced and then made available to the kernel | ||
651 | * from this point onwards. | ||
652 | * | ||
653 | * Locking: | ||
654 | * takes tty_ldisc_lock to guard against ldisc races | ||
655 | */ | ||
656 | |||
477 | int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | 657 | int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) |
478 | { | 658 | { |
479 | unsigned long flags; | 659 | unsigned long flags; |
@@ -493,6 +673,18 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | |||
493 | } | 673 | } |
494 | EXPORT_SYMBOL(tty_register_ldisc); | 674 | EXPORT_SYMBOL(tty_register_ldisc); |
495 | 675 | ||
676 | /** | ||
677 | * tty_unregister_ldisc - unload a line discipline | ||
678 | * @disc: ldisc number | ||
679 | * @new_ldisc: pointer to the ldisc object | ||
680 | * | ||
681 | * Remove a line discipline from the kernel providing it is not | ||
682 | * currently in use. | ||
683 | * | ||
684 | * Locking: | ||
685 | * takes tty_ldisc_lock to guard against ldisc races | ||
686 | */ | ||
687 | |||
496 | int tty_unregister_ldisc(int disc) | 688 | int tty_unregister_ldisc(int disc) |
497 | { | 689 | { |
498 | unsigned long flags; | 690 | unsigned long flags; |
@@ -512,6 +704,19 @@ int tty_unregister_ldisc(int disc) | |||
512 | } | 704 | } |
513 | EXPORT_SYMBOL(tty_unregister_ldisc); | 705 | EXPORT_SYMBOL(tty_unregister_ldisc); |
514 | 706 | ||
707 | /** | ||
708 | * tty_ldisc_get - take a reference to an ldisc | ||
709 | * @disc: ldisc number | ||
710 | * | ||
711 | * Takes a reference to a line discipline. Deals with refcounts and | ||
712 | * module locking counts. Returns NULL if the discipline is not available. | ||
713 | * Returns a pointer to the discipline and bumps the ref count if it is | ||
714 | * available | ||
715 | * | ||
716 | * Locking: | ||
717 | * takes tty_ldisc_lock to guard against ldisc races | ||
718 | */ | ||
719 | |||
515 | struct tty_ldisc *tty_ldisc_get(int disc) | 720 | struct tty_ldisc *tty_ldisc_get(int disc) |
516 | { | 721 | { |
517 | unsigned long flags; | 722 | unsigned long flags; |
@@ -540,6 +745,17 @@ struct tty_ldisc *tty_ldisc_get(int disc) | |||
540 | 745 | ||
541 | EXPORT_SYMBOL_GPL(tty_ldisc_get); | 746 | EXPORT_SYMBOL_GPL(tty_ldisc_get); |
542 | 747 | ||
748 | /** | ||
749 | * tty_ldisc_put - drop ldisc reference | ||
750 | * @disc: ldisc number | ||
751 | * | ||
752 | * Drop a reference to a line discipline. Manage refcounts and | ||
753 | * module usage counts | ||
754 | * | ||
755 | * Locking: | ||
756 | * takes tty_ldisc_lock to guard against ldisc races | ||
757 | */ | ||
758 | |||
543 | void tty_ldisc_put(int disc) | 759 | void tty_ldisc_put(int disc) |
544 | { | 760 | { |
545 | struct tty_ldisc *ld; | 761 | struct tty_ldisc *ld; |
@@ -557,6 +773,19 @@ void tty_ldisc_put(int disc) | |||
557 | 773 | ||
558 | EXPORT_SYMBOL_GPL(tty_ldisc_put); | 774 | EXPORT_SYMBOL_GPL(tty_ldisc_put); |
559 | 775 | ||
776 | /** | ||
777 | * tty_ldisc_assign - set ldisc on a tty | ||
778 | * @tty: tty to assign | ||
779 | * @ld: line discipline | ||
780 | * | ||
781 | * Install an instance of a line discipline into a tty structure. The | ||
782 | * ldisc must have a reference count above zero to ensure it remains/ | ||
783 | * The tty instance refcount starts at zero. | ||
784 | * | ||
785 | * Locking: | ||
786 | * Caller must hold references | ||
787 | */ | ||
788 | |||
560 | static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) | 789 | static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) |
561 | { | 790 | { |
562 | tty->ldisc = *ld; | 791 | tty->ldisc = *ld; |
@@ -571,6 +800,8 @@ static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) | |||
571 | * the tty ldisc. Return 0 on failure or 1 on success. This is | 800 | * the tty ldisc. Return 0 on failure or 1 on success. This is |
572 | * used to implement both the waiting and non waiting versions | 801 | * used to implement both the waiting and non waiting versions |
573 | * of tty_ldisc_ref | 802 | * of tty_ldisc_ref |
803 | * | ||
804 | * Locking: takes tty_ldisc_lock | ||
574 | */ | 805 | */ |
575 | 806 | ||
576 | static int tty_ldisc_try(struct tty_struct *tty) | 807 | static int tty_ldisc_try(struct tty_struct *tty) |
@@ -602,6 +833,8 @@ static int tty_ldisc_try(struct tty_struct *tty) | |||
602 | * must also be careful not to hold other locks that will deadlock | 833 | * must also be careful not to hold other locks that will deadlock |
603 | * against a discipline change, such as an existing ldisc reference | 834 | * against a discipline change, such as an existing ldisc reference |
604 | * (which we check for) | 835 | * (which we check for) |
836 | * | ||
837 | * Locking: call functions take tty_ldisc_lock | ||
605 | */ | 838 | */ |
606 | 839 | ||
607 | struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) | 840 | struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) |
@@ -622,6 +855,8 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); | |||
622 | * Dereference the line discipline for the terminal and take a | 855 | * Dereference the line discipline for the terminal and take a |
623 | * reference to it. If the line discipline is in flux then | 856 | * reference to it. If the line discipline is in flux then |
624 | * return NULL. Can be called from IRQ and timer functions. | 857 | * return NULL. Can be called from IRQ and timer functions. |
858 | * | ||
859 | * Locking: called functions take tty_ldisc_lock | ||
625 | */ | 860 | */ |
626 | 861 | ||
627 | struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) | 862 | struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) |
@@ -639,6 +874,8 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref); | |||
639 | * | 874 | * |
640 | * Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May | 875 | * Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May |
641 | * be called in IRQ context. | 876 | * be called in IRQ context. |
877 | * | ||
878 | * Locking: takes tty_ldisc_lock | ||
642 | */ | 879 | */ |
643 | 880 | ||
644 | void tty_ldisc_deref(struct tty_ldisc *ld) | 881 | void tty_ldisc_deref(struct tty_ldisc *ld) |
@@ -683,6 +920,9 @@ static void tty_ldisc_enable(struct tty_struct *tty) | |||
683 | * | 920 | * |
684 | * Set the discipline of a tty line. Must be called from a process | 921 | * Set the discipline of a tty line. Must be called from a process |
685 | * context. | 922 | * context. |
923 | * | ||
924 | * Locking: takes tty_ldisc_lock. | ||
925 | * called functions take termios_sem | ||
686 | */ | 926 | */ |
687 | 927 | ||
688 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) | 928 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) |
@@ -846,9 +1086,17 @@ restart: | |||
846 | return retval; | 1086 | return retval; |
847 | } | 1087 | } |
848 | 1088 | ||
849 | /* | 1089 | /** |
850 | * This routine returns a tty driver structure, given a device number | 1090 | * get_tty_driver - find device of a tty |
1091 | * @dev_t: device identifier | ||
1092 | * @index: returns the index of the tty | ||
1093 | * | ||
1094 | * This routine returns a tty driver structure, given a device number | ||
1095 | * and also passes back the index number. | ||
1096 | * | ||
1097 | * Locking: caller must hold tty_mutex | ||
851 | */ | 1098 | */ |
1099 | |||
852 | static struct tty_driver *get_tty_driver(dev_t device, int *index) | 1100 | static struct tty_driver *get_tty_driver(dev_t device, int *index) |
853 | { | 1101 | { |
854 | struct tty_driver *p; | 1102 | struct tty_driver *p; |
@@ -863,11 +1111,17 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index) | |||
863 | return NULL; | 1111 | return NULL; |
864 | } | 1112 | } |
865 | 1113 | ||
866 | /* | 1114 | /** |
867 | * If we try to write to, or set the state of, a terminal and we're | 1115 | * tty_check_change - check for POSIX terminal changes |
868 | * not in the foreground, send a SIGTTOU. If the signal is blocked or | 1116 | * @tty: tty to check |
869 | * ignored, go ahead and perform the operation. (POSIX 7.2) | 1117 | * |
1118 | * If we try to write to, or set the state of, a terminal and we're | ||
1119 | * not in the foreground, send a SIGTTOU. If the signal is blocked or | ||
1120 | * ignored, go ahead and perform the operation. (POSIX 7.2) | ||
1121 | * | ||
1122 | * Locking: none | ||
870 | */ | 1123 | */ |
1124 | |||
871 | int tty_check_change(struct tty_struct * tty) | 1125 | int tty_check_change(struct tty_struct * tty) |
872 | { | 1126 | { |
873 | if (current->signal->tty != tty) | 1127 | if (current->signal->tty != tty) |
@@ -1005,10 +1259,27 @@ void tty_ldisc_flush(struct tty_struct *tty) | |||
1005 | 1259 | ||
1006 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); | 1260 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); |
1007 | 1261 | ||
1008 | /* | 1262 | /** |
1009 | * This can be called by the "eventd" kernel thread. That is process synchronous, | 1263 | * do_tty_hangup - actual handler for hangup events |
1010 | * but doesn't hold any locks, so we need to make sure we have the appropriate | 1264 | * @data: tty device |
1011 | * locks for what we're doing.. | 1265 | * |
1266 | * This can be called by the "eventd" kernel thread. That is process | ||
1267 | * synchronous but doesn't hold any locks, so we need to make sure we | ||
1268 | * have the appropriate locks for what we're doing. | ||
1269 | * | ||
1270 | * The hangup event clears any pending redirections onto the hung up | ||
1271 | * device. It ensures future writes will error and it does the needed | ||
1272 | * line discipline hangup and signal delivery. The tty object itself | ||
1273 | * remains intact. | ||
1274 | * | ||
1275 | * Locking: | ||
1276 | * BKL | ||
1277 | * redirect lock for undoing redirection | ||
1278 | * file list lock for manipulating list of ttys | ||
1279 | * tty_ldisc_lock from called functions | ||
1280 | * termios_sem resetting termios data | ||
1281 | * tasklist_lock to walk task list for hangup event | ||
1282 | * | ||
1012 | */ | 1283 | */ |
1013 | static void do_tty_hangup(void *data) | 1284 | static void do_tty_hangup(void *data) |
1014 | { | 1285 | { |
@@ -1133,6 +1404,14 @@ static void do_tty_hangup(void *data) | |||
1133 | fput(f); | 1404 | fput(f); |
1134 | } | 1405 | } |
1135 | 1406 | ||
1407 | /** | ||
1408 | * tty_hangup - trigger a hangup event | ||
1409 | * @tty: tty to hangup | ||
1410 | * | ||
1411 | * A carrier loss (virtual or otherwise) has occurred on this like | ||
1412 | * schedule a hangup sequence to run after this event. | ||
1413 | */ | ||
1414 | |||
1136 | void tty_hangup(struct tty_struct * tty) | 1415 | void tty_hangup(struct tty_struct * tty) |
1137 | { | 1416 | { |
1138 | #ifdef TTY_DEBUG_HANGUP | 1417 | #ifdef TTY_DEBUG_HANGUP |
@@ -1145,6 +1424,15 @@ void tty_hangup(struct tty_struct * tty) | |||
1145 | 1424 | ||
1146 | EXPORT_SYMBOL(tty_hangup); | 1425 | EXPORT_SYMBOL(tty_hangup); |
1147 | 1426 | ||
1427 | /** | ||
1428 | * tty_vhangup - process vhangup | ||
1429 | * @tty: tty to hangup | ||
1430 | * | ||
1431 | * The user has asked via system call for the terminal to be hung up. | ||
1432 | * We do this synchronously so that when the syscall returns the process | ||
1433 | * is complete. That guarantee is neccessary for security reasons. | ||
1434 | */ | ||
1435 | |||
1148 | void tty_vhangup(struct tty_struct * tty) | 1436 | void tty_vhangup(struct tty_struct * tty) |
1149 | { | 1437 | { |
1150 | #ifdef TTY_DEBUG_HANGUP | 1438 | #ifdef TTY_DEBUG_HANGUP |
@@ -1156,6 +1444,14 @@ void tty_vhangup(struct tty_struct * tty) | |||
1156 | } | 1444 | } |
1157 | EXPORT_SYMBOL(tty_vhangup); | 1445 | EXPORT_SYMBOL(tty_vhangup); |
1158 | 1446 | ||
1447 | /** | ||
1448 | * tty_hung_up_p - was tty hung up | ||
1449 | * @filp: file pointer of tty | ||
1450 | * | ||
1451 | * Return true if the tty has been subject to a vhangup or a carrier | ||
1452 | * loss | ||
1453 | */ | ||
1454 | |||
1159 | int tty_hung_up_p(struct file * filp) | 1455 | int tty_hung_up_p(struct file * filp) |
1160 | { | 1456 | { |
1161 | return (filp->f_op == &hung_up_tty_fops); | 1457 | return (filp->f_op == &hung_up_tty_fops); |
@@ -1163,19 +1459,28 @@ int tty_hung_up_p(struct file * filp) | |||
1163 | 1459 | ||
1164 | EXPORT_SYMBOL(tty_hung_up_p); | 1460 | EXPORT_SYMBOL(tty_hung_up_p); |
1165 | 1461 | ||
1166 | /* | 1462 | /** |
1167 | * This function is typically called only by the session leader, when | 1463 | * disassociate_ctty - disconnect controlling tty |
1168 | * it wants to disassociate itself from its controlling tty. | 1464 | * @on_exit: true if exiting so need to "hang up" the session |
1465 | * | ||
1466 | * This function is typically called only by the session leader, when | ||
1467 | * it wants to disassociate itself from its controlling tty. | ||
1169 | * | 1468 | * |
1170 | * It performs the following functions: | 1469 | * It performs the following functions: |
1171 | * (1) Sends a SIGHUP and SIGCONT to the foreground process group | 1470 | * (1) Sends a SIGHUP and SIGCONT to the foreground process group |
1172 | * (2) Clears the tty from being controlling the session | 1471 | * (2) Clears the tty from being controlling the session |
1173 | * (3) Clears the controlling tty for all processes in the | 1472 | * (3) Clears the controlling tty for all processes in the |
1174 | * session group. | 1473 | * session group. |
1175 | * | 1474 | * |
1176 | * The argument on_exit is set to 1 if called when a process is | 1475 | * The argument on_exit is set to 1 if called when a process is |
1177 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. | 1476 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. |
1477 | * | ||
1478 | * Locking: tty_mutex is taken to protect current->signal->tty | ||
1479 | * BKL is taken for hysterical raisins | ||
1480 | * Tasklist lock is taken (under tty_mutex) to walk process | ||
1481 | * lists for the session. | ||
1178 | */ | 1482 | */ |
1483 | |||
1179 | void disassociate_ctty(int on_exit) | 1484 | void disassociate_ctty(int on_exit) |
1180 | { | 1485 | { |
1181 | struct tty_struct *tty; | 1486 | struct tty_struct *tty; |
@@ -1222,6 +1527,25 @@ void disassociate_ctty(int on_exit) | |||
1222 | unlock_kernel(); | 1527 | unlock_kernel(); |
1223 | } | 1528 | } |
1224 | 1529 | ||
1530 | |||
1531 | /** | ||
1532 | * stop_tty - propogate flow control | ||
1533 | * @tty: tty to stop | ||
1534 | * | ||
1535 | * Perform flow control to the driver. For PTY/TTY pairs we | ||
1536 | * must also propogate the TIOCKPKT status. May be called | ||
1537 | * on an already stopped device and will not re-call the driver | ||
1538 | * method. | ||
1539 | * | ||
1540 | * This functionality is used by both the line disciplines for | ||
1541 | * halting incoming flow and by the driver. It may therefore be | ||
1542 | * called from any context, may be under the tty atomic_write_lock | ||
1543 | * but not always. | ||
1544 | * | ||
1545 | * Locking: | ||
1546 | * Broken. Relies on BKL which is unsafe here. | ||
1547 | */ | ||
1548 | |||
1225 | void stop_tty(struct tty_struct *tty) | 1549 | void stop_tty(struct tty_struct *tty) |
1226 | { | 1550 | { |
1227 | if (tty->stopped) | 1551 | if (tty->stopped) |
@@ -1238,6 +1562,19 @@ void stop_tty(struct tty_struct *tty) | |||
1238 | 1562 | ||
1239 | EXPORT_SYMBOL(stop_tty); | 1563 | EXPORT_SYMBOL(stop_tty); |
1240 | 1564 | ||
1565 | /** | ||
1566 | * start_tty - propogate flow control | ||
1567 | * @tty: tty to start | ||
1568 | * | ||
1569 | * Start a tty that has been stopped if at all possible. Perform | ||
1570 | * any neccessary wakeups and propogate the TIOCPKT status. If this | ||
1571 | * is the tty was previous stopped and is being started then the | ||
1572 | * driver start method is invoked and the line discipline woken. | ||
1573 | * | ||
1574 | * Locking: | ||
1575 | * Broken. Relies on BKL which is unsafe here. | ||
1576 | */ | ||
1577 | |||
1241 | void start_tty(struct tty_struct *tty) | 1578 | void start_tty(struct tty_struct *tty) |
1242 | { | 1579 | { |
1243 | if (!tty->stopped || tty->flow_stopped) | 1580 | if (!tty->stopped || tty->flow_stopped) |
@@ -1258,6 +1595,23 @@ void start_tty(struct tty_struct *tty) | |||
1258 | 1595 | ||
1259 | EXPORT_SYMBOL(start_tty); | 1596 | EXPORT_SYMBOL(start_tty); |
1260 | 1597 | ||
1598 | /** | ||
1599 | * tty_read - read method for tty device files | ||
1600 | * @file: pointer to tty file | ||
1601 | * @buf: user buffer | ||
1602 | * @count: size of user buffer | ||
1603 | * @ppos: unused | ||
1604 | * | ||
1605 | * Perform the read system call function on this terminal device. Checks | ||
1606 | * for hung up devices before calling the line discipline method. | ||
1607 | * | ||
1608 | * Locking: | ||
1609 | * Locks the line discipline internally while needed | ||
1610 | * For historical reasons the line discipline read method is | ||
1611 | * invoked under the BKL. This will go away in time so do not rely on it | ||
1612 | * in new code. Multiple read calls may be outstanding in parallel. | ||
1613 | */ | ||
1614 | |||
1261 | static ssize_t tty_read(struct file * file, char __user * buf, size_t count, | 1615 | static ssize_t tty_read(struct file * file, char __user * buf, size_t count, |
1262 | loff_t *ppos) | 1616 | loff_t *ppos) |
1263 | { | 1617 | { |
@@ -1302,6 +1656,7 @@ static inline ssize_t do_tty_write( | |||
1302 | ssize_t ret = 0, written = 0; | 1656 | ssize_t ret = 0, written = 0; |
1303 | unsigned int chunk; | 1657 | unsigned int chunk; |
1304 | 1658 | ||
1659 | /* FIXME: O_NDELAY ... */ | ||
1305 | if (mutex_lock_interruptible(&tty->atomic_write_lock)) { | 1660 | if (mutex_lock_interruptible(&tty->atomic_write_lock)) { |
1306 | return -ERESTARTSYS; | 1661 | return -ERESTARTSYS; |
1307 | } | 1662 | } |
@@ -1318,6 +1673,9 @@ static inline ssize_t do_tty_write( | |||
1318 | * layer has problems with bigger chunks. It will | 1673 | * layer has problems with bigger chunks. It will |
1319 | * claim to be able to handle more characters than | 1674 | * claim to be able to handle more characters than |
1320 | * it actually does. | 1675 | * it actually does. |
1676 | * | ||
1677 | * FIXME: This can probably go away now except that 64K chunks | ||
1678 | * are too likely to fail unless switched to vmalloc... | ||
1321 | */ | 1679 | */ |
1322 | chunk = 2048; | 1680 | chunk = 2048; |
1323 | if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) | 1681 | if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) |
@@ -1375,6 +1733,24 @@ static inline ssize_t do_tty_write( | |||
1375 | } | 1733 | } |
1376 | 1734 | ||
1377 | 1735 | ||
1736 | /** | ||
1737 | * tty_write - write method for tty device file | ||
1738 | * @file: tty file pointer | ||
1739 | * @buf: user data to write | ||
1740 | * @count: bytes to write | ||
1741 | * @ppos: unused | ||
1742 | * | ||
1743 | * Write data to a tty device via the line discipline. | ||
1744 | * | ||
1745 | * Locking: | ||
1746 | * Locks the line discipline as required | ||
1747 | * Writes to the tty driver are serialized by the atomic_write_lock | ||
1748 | * and are then processed in chunks to the device. The line discipline | ||
1749 | * write method will not be involked in parallel for each device | ||
1750 | * The line discipline write method is called under the big | ||
1751 | * kernel lock for historical reasons. New code should not rely on this. | ||
1752 | */ | ||
1753 | |||
1378 | static ssize_t tty_write(struct file * file, const char __user * buf, size_t count, | 1754 | static ssize_t tty_write(struct file * file, const char __user * buf, size_t count, |
1379 | loff_t *ppos) | 1755 | loff_t *ppos) |
1380 | { | 1756 | { |
@@ -1422,7 +1798,18 @@ ssize_t redirected_tty_write(struct file * file, const char __user * buf, size_t | |||
1422 | 1798 | ||
1423 | static char ptychar[] = "pqrstuvwxyzabcde"; | 1799 | static char ptychar[] = "pqrstuvwxyzabcde"; |
1424 | 1800 | ||
1425 | static inline void pty_line_name(struct tty_driver *driver, int index, char *p) | 1801 | /** |
1802 | * pty_line_name - generate name for a pty | ||
1803 | * @driver: the tty driver in use | ||
1804 | * @index: the minor number | ||
1805 | * @p: output buffer of at least 6 bytes | ||
1806 | * | ||
1807 | * Generate a name from a driver reference and write it to the output | ||
1808 | * buffer. | ||
1809 | * | ||
1810 | * Locking: None | ||
1811 | */ | ||
1812 | static void pty_line_name(struct tty_driver *driver, int index, char *p) | ||
1426 | { | 1813 | { |
1427 | int i = index + driver->name_base; | 1814 | int i = index + driver->name_base; |
1428 | /* ->name is initialized to "ttyp", but "tty" is expected */ | 1815 | /* ->name is initialized to "ttyp", but "tty" is expected */ |
@@ -1431,24 +1818,53 @@ static inline void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
1431 | ptychar[i >> 4 & 0xf], i & 0xf); | 1818 | ptychar[i >> 4 & 0xf], i & 0xf); |
1432 | } | 1819 | } |
1433 | 1820 | ||
1434 | static inline void tty_line_name(struct tty_driver *driver, int index, char *p) | 1821 | /** |
1822 | * pty_line_name - generate name for a tty | ||
1823 | * @driver: the tty driver in use | ||
1824 | * @index: the minor number | ||
1825 | * @p: output buffer of at least 7 bytes | ||
1826 | * | ||
1827 | * Generate a name from a driver reference and write it to the output | ||
1828 | * buffer. | ||
1829 | * | ||
1830 | * Locking: None | ||
1831 | */ | ||
1832 | static void tty_line_name(struct tty_driver *driver, int index, char *p) | ||
1435 | { | 1833 | { |
1436 | sprintf(p, "%s%d", driver->name, index + driver->name_base); | 1834 | sprintf(p, "%s%d", driver->name, index + driver->name_base); |
1437 | } | 1835 | } |
1438 | 1836 | ||
1439 | /* | 1837 | /** |
1838 | * init_dev - initialise a tty device | ||
1839 | * @driver: tty driver we are opening a device on | ||
1840 | * @idx: device index | ||
1841 | * @tty: returned tty structure | ||
1842 | * | ||
1843 | * Prepare a tty device. This may not be a "new" clean device but | ||
1844 | * could also be an active device. The pty drivers require special | ||
1845 | * handling because of this. | ||
1846 | * | ||
1847 | * Locking: | ||
1848 | * The function is called under the tty_mutex, which | ||
1849 | * protects us from the tty struct or driver itself going away. | ||
1850 | * | ||
1851 | * On exit the tty device has the line discipline attached and | ||
1852 | * a reference count of 1. If a pair was created for pty/tty use | ||
1853 | * and the other was a pty master then it too has a reference count of 1. | ||
1854 | * | ||
1440 | * WSH 06/09/97: Rewritten to remove races and properly clean up after a | 1855 | * WSH 06/09/97: Rewritten to remove races and properly clean up after a |
1441 | * failed open. The new code protects the open with a mutex, so it's | 1856 | * failed open. The new code protects the open with a mutex, so it's |
1442 | * really quite straightforward. The mutex locking can probably be | 1857 | * really quite straightforward. The mutex locking can probably be |
1443 | * relaxed for the (most common) case of reopening a tty. | 1858 | * relaxed for the (most common) case of reopening a tty. |
1444 | */ | 1859 | */ |
1860 | |||
1445 | static int init_dev(struct tty_driver *driver, int idx, | 1861 | static int init_dev(struct tty_driver *driver, int idx, |
1446 | struct tty_struct **ret_tty) | 1862 | struct tty_struct **ret_tty) |
1447 | { | 1863 | { |
1448 | struct tty_struct *tty, *o_tty; | 1864 | struct tty_struct *tty, *o_tty; |
1449 | struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; | 1865 | struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; |
1450 | struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | 1866 | struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; |
1451 | int retval=0; | 1867 | int retval = 0; |
1452 | 1868 | ||
1453 | /* check whether we're reopening an existing tty */ | 1869 | /* check whether we're reopening an existing tty */ |
1454 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | 1870 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { |
@@ -1662,10 +2078,20 @@ release_mem_out: | |||
1662 | goto end_init; | 2078 | goto end_init; |
1663 | } | 2079 | } |
1664 | 2080 | ||
1665 | /* | 2081 | /** |
1666 | * Releases memory associated with a tty structure, and clears out the | 2082 | * release_mem - release tty structure memory |
1667 | * driver table slots. | 2083 | * |
2084 | * Releases memory associated with a tty structure, and clears out the | ||
2085 | * driver table slots. This function is called when a device is no longer | ||
2086 | * in use. It also gets called when setup of a device fails. | ||
2087 | * | ||
2088 | * Locking: | ||
2089 | * tty_mutex - sometimes only | ||
2090 | * takes the file list lock internally when working on the list | ||
2091 | * of ttys that the driver keeps. | ||
2092 | * FIXME: should we require tty_mutex is held here ?? | ||
1668 | */ | 2093 | */ |
2094 | |||
1669 | static void release_mem(struct tty_struct *tty, int idx) | 2095 | static void release_mem(struct tty_struct *tty, int idx) |
1670 | { | 2096 | { |
1671 | struct tty_struct *o_tty; | 2097 | struct tty_struct *o_tty; |
@@ -2006,18 +2432,27 @@ static void release_dev(struct file * filp) | |||
2006 | 2432 | ||
2007 | } | 2433 | } |
2008 | 2434 | ||
2009 | /* | 2435 | /** |
2010 | * tty_open and tty_release keep up the tty count that contains the | 2436 | * tty_open - open a tty device |
2011 | * number of opens done on a tty. We cannot use the inode-count, as | 2437 | * @inode: inode of device file |
2012 | * different inodes might point to the same tty. | 2438 | * @filp: file pointer to tty |
2439 | * | ||
2440 | * tty_open and tty_release keep up the tty count that contains the | ||
2441 | * number of opens done on a tty. We cannot use the inode-count, as | ||
2442 | * different inodes might point to the same tty. | ||
2013 | * | 2443 | * |
2014 | * Open-counting is needed for pty masters, as well as for keeping | 2444 | * Open-counting is needed for pty masters, as well as for keeping |
2015 | * track of serial lines: DTR is dropped when the last close happens. | 2445 | * track of serial lines: DTR is dropped when the last close happens. |
2016 | * (This is not done solely through tty->count, now. - Ted 1/27/92) | 2446 | * (This is not done solely through tty->count, now. - Ted 1/27/92) |
2017 | * | 2447 | * |
2018 | * The termios state of a pty is reset on first open so that | 2448 | * The termios state of a pty is reset on first open so that |
2019 | * settings don't persist across reuse. | 2449 | * settings don't persist across reuse. |
2450 | * | ||
2451 | * Locking: tty_mutex protects current->signal->tty, get_tty_driver and | ||
2452 | * init_dev work. tty->count should protect the rest. | ||
2453 | * task_lock is held to update task details for sessions | ||
2020 | */ | 2454 | */ |
2455 | |||
2021 | static int tty_open(struct inode * inode, struct file * filp) | 2456 | static int tty_open(struct inode * inode, struct file * filp) |
2022 | { | 2457 | { |
2023 | struct tty_struct *tty; | 2458 | struct tty_struct *tty; |
@@ -2132,6 +2567,18 @@ got_driver: | |||
2132 | } | 2567 | } |
2133 | 2568 | ||
2134 | #ifdef CONFIG_UNIX98_PTYS | 2569 | #ifdef CONFIG_UNIX98_PTYS |
2570 | /** | ||
2571 | * ptmx_open - open a unix 98 pty master | ||
2572 | * @inode: inode of device file | ||
2573 | * @filp: file pointer to tty | ||
2574 | * | ||
2575 | * Allocate a unix98 pty master device from the ptmx driver. | ||
2576 | * | ||
2577 | * Locking: tty_mutex protects theinit_dev work. tty->count should | ||
2578 | protect the rest. | ||
2579 | * allocated_ptys_lock handles the list of free pty numbers | ||
2580 | */ | ||
2581 | |||
2135 | static int ptmx_open(struct inode * inode, struct file * filp) | 2582 | static int ptmx_open(struct inode * inode, struct file * filp) |
2136 | { | 2583 | { |
2137 | struct tty_struct *tty; | 2584 | struct tty_struct *tty; |
@@ -2191,6 +2638,18 @@ out: | |||
2191 | } | 2638 | } |
2192 | #endif | 2639 | #endif |
2193 | 2640 | ||
2641 | /** | ||
2642 | * tty_release - vfs callback for close | ||
2643 | * @inode: inode of tty | ||
2644 | * @filp: file pointer for handle to tty | ||
2645 | * | ||
2646 | * Called the last time each file handle is closed that references | ||
2647 | * this tty. There may however be several such references. | ||
2648 | * | ||
2649 | * Locking: | ||
2650 | * Takes bkl. See release_dev | ||
2651 | */ | ||
2652 | |||
2194 | static int tty_release(struct inode * inode, struct file * filp) | 2653 | static int tty_release(struct inode * inode, struct file * filp) |
2195 | { | 2654 | { |
2196 | lock_kernel(); | 2655 | lock_kernel(); |
@@ -2199,7 +2658,18 @@ static int tty_release(struct inode * inode, struct file * filp) | |||
2199 | return 0; | 2658 | return 0; |
2200 | } | 2659 | } |
2201 | 2660 | ||
2202 | /* No kernel lock held - fine */ | 2661 | /** |
2662 | * tty_poll - check tty status | ||
2663 | * @filp: file being polled | ||
2664 | * @wait: poll wait structures to update | ||
2665 | * | ||
2666 | * Call the line discipline polling method to obtain the poll | ||
2667 | * status of the device. | ||
2668 | * | ||
2669 | * Locking: locks called line discipline but ldisc poll method | ||
2670 | * may be re-entered freely by other callers. | ||
2671 | */ | ||
2672 | |||
2203 | static unsigned int tty_poll(struct file * filp, poll_table * wait) | 2673 | static unsigned int tty_poll(struct file * filp, poll_table * wait) |
2204 | { | 2674 | { |
2205 | struct tty_struct * tty; | 2675 | struct tty_struct * tty; |
@@ -2243,6 +2713,21 @@ static int tty_fasync(int fd, struct file * filp, int on) | |||
2243 | return 0; | 2713 | return 0; |
2244 | } | 2714 | } |
2245 | 2715 | ||
2716 | /** | ||
2717 | * tiocsti - fake input character | ||
2718 | * @tty: tty to fake input into | ||
2719 | * @p: pointer to character | ||
2720 | * | ||
2721 | * Fake input to a tty device. Does the neccessary locking and | ||
2722 | * input management. | ||
2723 | * | ||
2724 | * FIXME: does not honour flow control ?? | ||
2725 | * | ||
2726 | * Locking: | ||
2727 | * Called functions take tty_ldisc_lock | ||
2728 | * current->signal->tty check is safe without locks | ||
2729 | */ | ||
2730 | |||
2246 | static int tiocsti(struct tty_struct *tty, char __user *p) | 2731 | static int tiocsti(struct tty_struct *tty, char __user *p) |
2247 | { | 2732 | { |
2248 | char ch, mbz = 0; | 2733 | char ch, mbz = 0; |
@@ -2258,6 +2743,18 @@ static int tiocsti(struct tty_struct *tty, char __user *p) | |||
2258 | return 0; | 2743 | return 0; |
2259 | } | 2744 | } |
2260 | 2745 | ||
2746 | /** | ||
2747 | * tiocgwinsz - implement window query ioctl | ||
2748 | * @tty; tty | ||
2749 | * @arg: user buffer for result | ||
2750 | * | ||
2751 | * Copies the kernel idea of the window size into the user buffer. No | ||
2752 | * locking is done. | ||
2753 | * | ||
2754 | * FIXME: Returning random values racing a window size set is wrong | ||
2755 | * should lock here against that | ||
2756 | */ | ||
2757 | |||
2261 | static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) | 2758 | static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) |
2262 | { | 2759 | { |
2263 | if (copy_to_user(arg, &tty->winsize, sizeof(*arg))) | 2760 | if (copy_to_user(arg, &tty->winsize, sizeof(*arg))) |
@@ -2265,6 +2762,24 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) | |||
2265 | return 0; | 2762 | return 0; |
2266 | } | 2763 | } |
2267 | 2764 | ||
2765 | /** | ||
2766 | * tiocswinsz - implement window size set ioctl | ||
2767 | * @tty; tty | ||
2768 | * @arg: user buffer for result | ||
2769 | * | ||
2770 | * Copies the user idea of the window size to the kernel. Traditionally | ||
2771 | * this is just advisory information but for the Linux console it | ||
2772 | * actually has driver level meaning and triggers a VC resize. | ||
2773 | * | ||
2774 | * Locking: | ||
2775 | * The console_sem is used to ensure we do not try and resize | ||
2776 | * the console twice at once. | ||
2777 | * FIXME: Two racing size sets may leave the console and kernel | ||
2778 | * parameters disagreeing. Is this exploitable ? | ||
2779 | * FIXME: Random values racing a window size get is wrong | ||
2780 | * should lock here against that | ||
2781 | */ | ||
2782 | |||
2268 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | 2783 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, |
2269 | struct winsize __user * arg) | 2784 | struct winsize __user * arg) |
2270 | { | 2785 | { |
@@ -2294,6 +2809,15 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | |||
2294 | return 0; | 2809 | return 0; |
2295 | } | 2810 | } |
2296 | 2811 | ||
2812 | /** | ||
2813 | * tioccons - allow admin to move logical console | ||
2814 | * @file: the file to become console | ||
2815 | * | ||
2816 | * Allow the adminstrator to move the redirected console device | ||
2817 | * | ||
2818 | * Locking: uses redirect_lock to guard the redirect information | ||
2819 | */ | ||
2820 | |||
2297 | static int tioccons(struct file *file) | 2821 | static int tioccons(struct file *file) |
2298 | { | 2822 | { |
2299 | if (!capable(CAP_SYS_ADMIN)) | 2823 | if (!capable(CAP_SYS_ADMIN)) |
@@ -2319,6 +2843,17 @@ static int tioccons(struct file *file) | |||
2319 | return 0; | 2843 | return 0; |
2320 | } | 2844 | } |
2321 | 2845 | ||
2846 | /** | ||
2847 | * fionbio - non blocking ioctl | ||
2848 | * @file: file to set blocking value | ||
2849 | * @p: user parameter | ||
2850 | * | ||
2851 | * Historical tty interfaces had a blocking control ioctl before | ||
2852 | * the generic functionality existed. This piece of history is preserved | ||
2853 | * in the expected tty API of posix OS's. | ||
2854 | * | ||
2855 | * Locking: none, the open fle handle ensures it won't go away. | ||
2856 | */ | ||
2322 | 2857 | ||
2323 | static int fionbio(struct file *file, int __user *p) | 2858 | static int fionbio(struct file *file, int __user *p) |
2324 | { | 2859 | { |
@@ -2334,6 +2869,23 @@ static int fionbio(struct file *file, int __user *p) | |||
2334 | return 0; | 2869 | return 0; |
2335 | } | 2870 | } |
2336 | 2871 | ||
2872 | /** | ||
2873 | * tiocsctty - set controlling tty | ||
2874 | * @tty: tty structure | ||
2875 | * @arg: user argument | ||
2876 | * | ||
2877 | * This ioctl is used to manage job control. It permits a session | ||
2878 | * leader to set this tty as the controlling tty for the session. | ||
2879 | * | ||
2880 | * Locking: | ||
2881 | * Takes tasklist lock internally to walk sessions | ||
2882 | * Takes task_lock() when updating signal->tty | ||
2883 | * | ||
2884 | * FIXME: tty_mutex is needed to protect signal->tty references. | ||
2885 | * FIXME: why task_lock on the signal->tty reference ?? | ||
2886 | * | ||
2887 | */ | ||
2888 | |||
2337 | static int tiocsctty(struct tty_struct *tty, int arg) | 2889 | static int tiocsctty(struct tty_struct *tty, int arg) |
2338 | { | 2890 | { |
2339 | struct task_struct *p; | 2891 | struct task_struct *p; |
@@ -2374,6 +2926,18 @@ static int tiocsctty(struct tty_struct *tty, int arg) | |||
2374 | return 0; | 2926 | return 0; |
2375 | } | 2927 | } |
2376 | 2928 | ||
2929 | /** | ||
2930 | * tiocgpgrp - get process group | ||
2931 | * @tty: tty passed by user | ||
2932 | * @real_tty: tty side of the tty pased by the user if a pty else the tty | ||
2933 | * @p: returned pid | ||
2934 | * | ||
2935 | * Obtain the process group of the tty. If there is no process group | ||
2936 | * return an error. | ||
2937 | * | ||
2938 | * Locking: none. Reference to ->signal->tty is safe. | ||
2939 | */ | ||
2940 | |||
2377 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2941 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2378 | { | 2942 | { |
2379 | /* | 2943 | /* |
@@ -2385,6 +2949,20 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2385 | return put_user(real_tty->pgrp, p); | 2949 | return put_user(real_tty->pgrp, p); |
2386 | } | 2950 | } |
2387 | 2951 | ||
2952 | /** | ||
2953 | * tiocspgrp - attempt to set process group | ||
2954 | * @tty: tty passed by user | ||
2955 | * @real_tty: tty side device matching tty passed by user | ||
2956 | * @p: pid pointer | ||
2957 | * | ||
2958 | * Set the process group of the tty to the session passed. Only | ||
2959 | * permitted where the tty session is our session. | ||
2960 | * | ||
2961 | * Locking: None | ||
2962 | * | ||
2963 | * FIXME: current->signal->tty referencing is unsafe. | ||
2964 | */ | ||
2965 | |||
2388 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2966 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2389 | { | 2967 | { |
2390 | pid_t pgrp; | 2968 | pid_t pgrp; |
@@ -2408,6 +2986,18 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2408 | return 0; | 2986 | return 0; |
2409 | } | 2987 | } |
2410 | 2988 | ||
2989 | /** | ||
2990 | * tiocgsid - get session id | ||
2991 | * @tty: tty passed by user | ||
2992 | * @real_tty: tty side of the tty pased by the user if a pty else the tty | ||
2993 | * @p: pointer to returned session id | ||
2994 | * | ||
2995 | * Obtain the session id of the tty. If there is no session | ||
2996 | * return an error. | ||
2997 | * | ||
2998 | * Locking: none. Reference to ->signal->tty is safe. | ||
2999 | */ | ||
3000 | |||
2411 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 3001 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2412 | { | 3002 | { |
2413 | /* | 3003 | /* |
@@ -2421,6 +3011,16 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ | |||
2421 | return put_user(real_tty->session, p); | 3011 | return put_user(real_tty->session, p); |
2422 | } | 3012 | } |
2423 | 3013 | ||
3014 | /** | ||
3015 | * tiocsetd - set line discipline | ||
3016 | * @tty: tty device | ||
3017 | * @p: pointer to user data | ||
3018 | * | ||
3019 | * Set the line discipline according to user request. | ||
3020 | * | ||
3021 | * Locking: see tty_set_ldisc, this function is just a helper | ||
3022 | */ | ||
3023 | |||
2424 | static int tiocsetd(struct tty_struct *tty, int __user *p) | 3024 | static int tiocsetd(struct tty_struct *tty, int __user *p) |
2425 | { | 3025 | { |
2426 | int ldisc; | 3026 | int ldisc; |
@@ -2430,6 +3030,21 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) | |||
2430 | return tty_set_ldisc(tty, ldisc); | 3030 | return tty_set_ldisc(tty, ldisc); |
2431 | } | 3031 | } |
2432 | 3032 | ||
3033 | /** | ||
3034 | * send_break - performed time break | ||
3035 | * @tty: device to break on | ||
3036 | * @duration: timeout in mS | ||
3037 | * | ||
3038 | * Perform a timed break on hardware that lacks its own driver level | ||
3039 | * timed break functionality. | ||
3040 | * | ||
3041 | * Locking: | ||
3042 | * None | ||
3043 | * | ||
3044 | * FIXME: | ||
3045 | * What if two overlap | ||
3046 | */ | ||
3047 | |||
2433 | static int send_break(struct tty_struct *tty, unsigned int duration) | 3048 | static int send_break(struct tty_struct *tty, unsigned int duration) |
2434 | { | 3049 | { |
2435 | tty->driver->break_ctl(tty, -1); | 3050 | tty->driver->break_ctl(tty, -1); |
@@ -2442,8 +3057,19 @@ static int send_break(struct tty_struct *tty, unsigned int duration) | |||
2442 | return 0; | 3057 | return 0; |
2443 | } | 3058 | } |
2444 | 3059 | ||
2445 | static int | 3060 | /** |
2446 | tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p) | 3061 | * tiocmget - get modem status |
3062 | * @tty: tty device | ||
3063 | * @file: user file pointer | ||
3064 | * @p: pointer to result | ||
3065 | * | ||
3066 | * Obtain the modem status bits from the tty driver if the feature | ||
3067 | * is supported. Return -EINVAL if it is not available. | ||
3068 | * | ||
3069 | * Locking: none (up to the driver) | ||
3070 | */ | ||
3071 | |||
3072 | static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p) | ||
2447 | { | 3073 | { |
2448 | int retval = -EINVAL; | 3074 | int retval = -EINVAL; |
2449 | 3075 | ||
@@ -2456,8 +3082,20 @@ tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p) | |||
2456 | return retval; | 3082 | return retval; |
2457 | } | 3083 | } |
2458 | 3084 | ||
2459 | static int | 3085 | /** |
2460 | tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, | 3086 | * tiocmset - set modem status |
3087 | * @tty: tty device | ||
3088 | * @file: user file pointer | ||
3089 | * @cmd: command - clear bits, set bits or set all | ||
3090 | * @p: pointer to desired bits | ||
3091 | * | ||
3092 | * Set the modem status bits from the tty driver if the feature | ||
3093 | * is supported. Return -EINVAL if it is not available. | ||
3094 | * | ||
3095 | * Locking: none (up to the driver) | ||
3096 | */ | ||
3097 | |||
3098 | static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, | ||
2461 | unsigned __user *p) | 3099 | unsigned __user *p) |
2462 | { | 3100 | { |
2463 | int retval = -EINVAL; | 3101 | int retval = -EINVAL; |
@@ -2573,6 +3211,7 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
2573 | clear_bit(TTY_EXCLUSIVE, &tty->flags); | 3211 | clear_bit(TTY_EXCLUSIVE, &tty->flags); |
2574 | return 0; | 3212 | return 0; |
2575 | case TIOCNOTTY: | 3213 | case TIOCNOTTY: |
3214 | /* FIXME: taks lock or tty_mutex ? */ | ||
2576 | if (current->signal->tty != tty) | 3215 | if (current->signal->tty != tty) |
2577 | return -ENOTTY; | 3216 | return -ENOTTY; |
2578 | if (current->signal->leader) | 3217 | if (current->signal->leader) |
@@ -2753,9 +3392,16 @@ void do_SAK(struct tty_struct *tty) | |||
2753 | 3392 | ||
2754 | EXPORT_SYMBOL(do_SAK); | 3393 | EXPORT_SYMBOL(do_SAK); |
2755 | 3394 | ||
2756 | /* | 3395 | /** |
2757 | * This routine is called out of the software interrupt to flush data | 3396 | * flush_to_ldisc |
2758 | * from the buffer chain to the line discipline. | 3397 | * @private_: tty structure passed from work queue. |
3398 | * | ||
3399 | * This routine is called out of the software interrupt to flush data | ||
3400 | * from the buffer chain to the line discipline. | ||
3401 | * | ||
3402 | * Locking: holds tty->buf.lock to guard buffer list. Drops the lock | ||
3403 | * while invoking the line discipline receive_buf method. The | ||
3404 | * receive_buf method is single threaded for each tty instance. | ||
2759 | */ | 3405 | */ |
2760 | 3406 | ||
2761 | static void flush_to_ldisc(void *private_) | 3407 | static void flush_to_ldisc(void *private_) |
@@ -2831,6 +3477,8 @@ static int n_baud_table = ARRAY_SIZE(baud_table); | |||
2831 | * Convert termios baud rate data into a speed. This should be called | 3477 | * Convert termios baud rate data into a speed. This should be called |
2832 | * with the termios lock held if this termios is a terminal termios | 3478 | * with the termios lock held if this termios is a terminal termios |
2833 | * structure. May change the termios data. | 3479 | * structure. May change the termios data. |
3480 | * | ||
3481 | * Locking: none | ||
2834 | */ | 3482 | */ |
2835 | 3483 | ||
2836 | int tty_termios_baud_rate(struct termios *termios) | 3484 | int tty_termios_baud_rate(struct termios *termios) |
@@ -2859,6 +3507,8 @@ EXPORT_SYMBOL(tty_termios_baud_rate); | |||
2859 | * Returns the baud rate as an integer for this terminal. The | 3507 | * Returns the baud rate as an integer for this terminal. The |
2860 | * termios lock must be held by the caller and the terminal bit | 3508 | * termios lock must be held by the caller and the terminal bit |
2861 | * flags may be updated. | 3509 | * flags may be updated. |
3510 | * | ||
3511 | * Locking: none | ||
2862 | */ | 3512 | */ |
2863 | 3513 | ||
2864 | int tty_get_baud_rate(struct tty_struct *tty) | 3514 | int tty_get_baud_rate(struct tty_struct *tty) |
@@ -2888,6 +3538,8 @@ EXPORT_SYMBOL(tty_get_baud_rate); | |||
2888 | * | 3538 | * |
2889 | * In the event of the queue being busy for flipping the work will be | 3539 | * In the event of the queue being busy for flipping the work will be |
2890 | * held off and retried later. | 3540 | * held off and retried later. |
3541 | * | ||
3542 | * Locking: tty buffer lock. Driver locks in low latency mode. | ||
2891 | */ | 3543 | */ |
2892 | 3544 | ||
2893 | void tty_flip_buffer_push(struct tty_struct *tty) | 3545 | void tty_flip_buffer_push(struct tty_struct *tty) |
@@ -2907,9 +3559,16 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
2907 | EXPORT_SYMBOL(tty_flip_buffer_push); | 3559 | EXPORT_SYMBOL(tty_flip_buffer_push); |
2908 | 3560 | ||
2909 | 3561 | ||
2910 | /* | 3562 | /** |
2911 | * This subroutine initializes a tty structure. | 3563 | * initialize_tty_struct |
3564 | * @tty: tty to initialize | ||
3565 | * | ||
3566 | * This subroutine initializes a tty structure that has been newly | ||
3567 | * allocated. | ||
3568 | * | ||
3569 | * Locking: none - tty in question must not be exposed at this point | ||
2912 | */ | 3570 | */ |
3571 | |||
2913 | static void initialize_tty_struct(struct tty_struct *tty) | 3572 | static void initialize_tty_struct(struct tty_struct *tty) |
2914 | { | 3573 | { |
2915 | memset(tty, 0, sizeof(struct tty_struct)); | 3574 | memset(tty, 0, sizeof(struct tty_struct)); |
@@ -2935,6 +3594,7 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
2935 | /* | 3594 | /* |
2936 | * The default put_char routine if the driver did not define one. | 3595 | * The default put_char routine if the driver did not define one. |
2937 | */ | 3596 | */ |
3597 | |||
2938 | static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) | 3598 | static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) |
2939 | { | 3599 | { |
2940 | tty->driver->write(tty, &ch, 1); | 3600 | tty->driver->write(tty, &ch, 1); |
@@ -2943,19 +3603,23 @@ static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) | |||
2943 | static struct class *tty_class; | 3603 | static struct class *tty_class; |
2944 | 3604 | ||
2945 | /** | 3605 | /** |
2946 | * tty_register_device - register a tty device | 3606 | * tty_register_device - register a tty device |
2947 | * @driver: the tty driver that describes the tty device | 3607 | * @driver: the tty driver that describes the tty device |
2948 | * @index: the index in the tty driver for this tty device | 3608 | * @index: the index in the tty driver for this tty device |
2949 | * @device: a struct device that is associated with this tty device. | 3609 | * @device: a struct device that is associated with this tty device. |
2950 | * This field is optional, if there is no known struct device for this | 3610 | * This field is optional, if there is no known struct device |
2951 | * tty device it can be set to NULL safely. | 3611 | * for this tty device it can be set to NULL safely. |
2952 | * | 3612 | * |
2953 | * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). | 3613 | * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). |
2954 | * | 3614 | * |
2955 | * This call is required to be made to register an individual tty device if | 3615 | * This call is required to be made to register an individual tty device |
2956 | * the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If that | 3616 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If |
2957 | * bit is not set, this function should not be called by a tty driver. | 3617 | * that bit is not set, this function should not be called by a tty |
3618 | * driver. | ||
3619 | * | ||
3620 | * Locking: ?? | ||
2958 | */ | 3621 | */ |
3622 | |||
2959 | struct class_device *tty_register_device(struct tty_driver *driver, | 3623 | struct class_device *tty_register_device(struct tty_driver *driver, |
2960 | unsigned index, struct device *device) | 3624 | unsigned index, struct device *device) |
2961 | { | 3625 | { |
@@ -2977,13 +3641,16 @@ struct class_device *tty_register_device(struct tty_driver *driver, | |||
2977 | } | 3641 | } |
2978 | 3642 | ||
2979 | /** | 3643 | /** |
2980 | * tty_unregister_device - unregister a tty device | 3644 | * tty_unregister_device - unregister a tty device |
2981 | * @driver: the tty driver that describes the tty device | 3645 | * @driver: the tty driver that describes the tty device |
2982 | * @index: the index in the tty driver for this tty device | 3646 | * @index: the index in the tty driver for this tty device |
2983 | * | 3647 | * |
2984 | * If a tty device is registered with a call to tty_register_device() then | 3648 | * If a tty device is registered with a call to tty_register_device() then |
2985 | * this function must be made when the tty device is gone. | 3649 | * this function must be called when the tty device is gone. |
3650 | * | ||
3651 | * Locking: ?? | ||
2986 | */ | 3652 | */ |
3653 | |||
2987 | void tty_unregister_device(struct tty_driver *driver, unsigned index) | 3654 | void tty_unregister_device(struct tty_driver *driver, unsigned index) |
2988 | { | 3655 | { |
2989 | class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); | 3656 | class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); |
@@ -3094,7 +3761,6 @@ int tty_register_driver(struct tty_driver *driver) | |||
3094 | driver->cdev.owner = driver->owner; | 3761 | driver->cdev.owner = driver->owner; |
3095 | error = cdev_add(&driver->cdev, dev, driver->num); | 3762 | error = cdev_add(&driver->cdev, dev, driver->num); |
3096 | if (error) { | 3763 | if (error) { |
3097 | cdev_del(&driver->cdev); | ||
3098 | unregister_chrdev_region(dev, driver->num); | 3764 | unregister_chrdev_region(dev, driver->num); |
3099 | driver->ttys = NULL; | 3765 | driver->ttys = NULL; |
3100 | driver->termios = driver->termios_locked = NULL; | 3766 | driver->termios = driver->termios_locked = NULL; |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index f19cf9d7792d..4ad47d321bd4 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -36,6 +36,18 @@ | |||
36 | #define TERMIOS_WAIT 2 | 36 | #define TERMIOS_WAIT 2 |
37 | #define TERMIOS_TERMIO 4 | 37 | #define TERMIOS_TERMIO 4 |
38 | 38 | ||
39 | |||
40 | /** | ||
41 | * tty_wait_until_sent - wait for I/O to finish | ||
42 | * @tty: tty we are waiting for | ||
43 | * @timeout: how long we will wait | ||
44 | * | ||
45 | * Wait for characters pending in a tty driver to hit the wire, or | ||
46 | * for a timeout to occur (eg due to flow control) | ||
47 | * | ||
48 | * Locking: none | ||
49 | */ | ||
50 | |||
39 | void tty_wait_until_sent(struct tty_struct * tty, long timeout) | 51 | void tty_wait_until_sent(struct tty_struct * tty, long timeout) |
40 | { | 52 | { |
41 | DECLARE_WAITQUEUE(wait, current); | 53 | DECLARE_WAITQUEUE(wait, current); |
@@ -94,6 +106,18 @@ static void unset_locked_termios(struct termios *termios, | |||
94 | old->c_cc[i] : termios->c_cc[i]; | 106 | old->c_cc[i] : termios->c_cc[i]; |
95 | } | 107 | } |
96 | 108 | ||
109 | /** | ||
110 | * change_termios - update termios values | ||
111 | * @tty: tty to update | ||
112 | * @new_termios: desired new value | ||
113 | * | ||
114 | * Perform updates to the termios values set on this terminal. There | ||
115 | * is a bit of layering violation here with n_tty in terms of the | ||
116 | * internal knowledge of this function. | ||
117 | * | ||
118 | * Locking: termios_sem | ||
119 | */ | ||
120 | |||
97 | static void change_termios(struct tty_struct * tty, struct termios * new_termios) | 121 | static void change_termios(struct tty_struct * tty, struct termios * new_termios) |
98 | { | 122 | { |
99 | int canon_change; | 123 | int canon_change; |
@@ -155,6 +179,19 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios | |||
155 | up(&tty->termios_sem); | 179 | up(&tty->termios_sem); |
156 | } | 180 | } |
157 | 181 | ||
182 | /** | ||
183 | * set_termios - set termios values for a tty | ||
184 | * @tty: terminal device | ||
185 | * @arg: user data | ||
186 | * @opt: option information | ||
187 | * | ||
188 | * Helper function to prepare termios data and run neccessary other | ||
189 | * functions before using change_termios to do the actual changes. | ||
190 | * | ||
191 | * Locking: | ||
192 | * Called functions take ldisc and termios_sem locks | ||
193 | */ | ||
194 | |||
158 | static int set_termios(struct tty_struct * tty, void __user *arg, int opt) | 195 | static int set_termios(struct tty_struct * tty, void __user *arg, int opt) |
159 | { | 196 | { |
160 | struct termios tmp_termios; | 197 | struct termios tmp_termios; |
@@ -284,6 +321,17 @@ static void set_sgflags(struct termios * termios, int flags) | |||
284 | } | 321 | } |
285 | } | 322 | } |
286 | 323 | ||
324 | /** | ||
325 | * set_sgttyb - set legacy terminal values | ||
326 | * @tty: tty structure | ||
327 | * @sgttyb: pointer to old style terminal structure | ||
328 | * | ||
329 | * Updates a terminal from the legacy BSD style terminal information | ||
330 | * structure. | ||
331 | * | ||
332 | * Locking: termios_sem | ||
333 | */ | ||
334 | |||
287 | static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) | 335 | static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) |
288 | { | 336 | { |
289 | int retval; | 337 | int retval; |
@@ -369,9 +417,16 @@ static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars) | |||
369 | } | 417 | } |
370 | #endif | 418 | #endif |
371 | 419 | ||
372 | /* | 420 | /** |
373 | * Send a high priority character to the tty. | 421 | * send_prio_char - send priority character |
422 | * | ||
423 | * Send a high priority character to the tty even if stopped | ||
424 | * | ||
425 | * Locking: none | ||
426 | * | ||
427 | * FIXME: overlapping calls with start/stop tty lose state of tty | ||
374 | */ | 428 | */ |
429 | |||
375 | static void send_prio_char(struct tty_struct *tty, char ch) | 430 | static void send_prio_char(struct tty_struct *tty, char ch) |
376 | { | 431 | { |
377 | int was_stopped = tty->stopped; | 432 | int was_stopped = tty->stopped; |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index eccffaf26faa..a5628a8b6620 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -1011,6 +1011,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
1011 | return -EPERM; | 1011 | return -EPERM; |
1012 | vt_dont_switch = 0; | 1012 | vt_dont_switch = 0; |
1013 | return 0; | 1013 | return 0; |
1014 | case VT_GETHIFONTMASK: | ||
1015 | return put_user(vc->vc_hi_font_mask, (unsigned short __user *)arg); | ||
1014 | default: | 1016 | default: |
1015 | return -ENOIOCTLCMD; | 1017 | return -ENOIOCTLCMD; |
1016 | } | 1018 | } |
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index d53f664a4dd8..fff89c2d88fd 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig | |||
@@ -45,7 +45,7 @@ config WATCHDOG_NOWAYOUT | |||
45 | comment "Watchdog Device Drivers" | 45 | comment "Watchdog Device Drivers" |
46 | depends on WATCHDOG | 46 | depends on WATCHDOG |
47 | 47 | ||
48 | # Architecture Independant | 48 | # Architecture Independent |
49 | 49 | ||
50 | config SOFT_WATCHDOG | 50 | config SOFT_WATCHDOG |
51 | tristate "Software watchdog" | 51 | tristate "Software watchdog" |
@@ -127,7 +127,7 @@ config S3C2410_WATCHDOG | |||
127 | enabled. | 127 | enabled. |
128 | 128 | ||
129 | The driver is limited by the speed of the system's PCLK | 129 | The driver is limited by the speed of the system's PCLK |
130 | signal, so with reasonbaly fast systems (PCLK around 50-66MHz) | 130 | signal, so with reasonably fast systems (PCLK around 50-66MHz) |
131 | then watchdog intervals of over approximately 20seconds are | 131 | then watchdog intervals of over approximately 20seconds are |
132 | unavailable. | 132 | unavailable. |
133 | 133 | ||
@@ -423,7 +423,7 @@ config SBC_EPX_C3_WATCHDOG | |||
423 | is no way to know if writing to its IO address will corrupt | 423 | is no way to know if writing to its IO address will corrupt |
424 | your system or have any real effect. The only way to be sure | 424 | your system or have any real effect. The only way to be sure |
425 | that this driver does what you want is to make sure you | 425 | that this driver does what you want is to make sure you |
426 | are runnning it on an EPX-C3 from Winsystems with the watchdog | 426 | are running it on an EPX-C3 from Winsystems with the watchdog |
427 | timer at IO address 0x1ee and 0x1ef. It will write to both those | 427 | timer at IO address 0x1ee and 0x1ef. It will write to both those |
428 | IO ports. Basically, the assumption is made that if you compile | 428 | IO ports. Basically, the assumption is made that if you compile |
429 | this driver into your kernel and/or load it as a module, that you | 429 | this driver into your kernel and/or load it as a module, that you |
@@ -472,7 +472,7 @@ config INDYDOG | |||
472 | tristate "Indy/I2 Hardware Watchdog" | 472 | tristate "Indy/I2 Hardware Watchdog" |
473 | depends on WATCHDOG && SGI_IP22 | 473 | depends on WATCHDOG && SGI_IP22 |
474 | help | 474 | help |
475 | Hardwaredriver for the Indy's/I2's watchdog. This is a | 475 | Hardware driver for the Indy's/I2's watchdog. This is a |
476 | watchdog timer that will reboot the machine after a 60 second | 476 | watchdog timer that will reboot the machine after a 60 second |
477 | timer expired and no process has written to /dev/watchdog during | 477 | timer expired and no process has written to /dev/watchdog during |
478 | that time. | 478 | that time. |