aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/drivers/chan_kern.c160
-rw-r--r--arch/um/drivers/chan_user.c111
-rw-r--r--arch/um/drivers/fd.c74
-rw-r--r--arch/um/drivers/null.c28
-rw-r--r--arch/um/drivers/port_kern.c82
-rw-r--r--arch/um/drivers/port_user.c73
-rw-r--r--arch/um/drivers/pty.c14
-rw-r--r--arch/um/drivers/tty.c37
-rw-r--r--arch/um/drivers/xterm.c16
9 files changed, 296 insertions, 299 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 9a6222f1a51b..c09dbdfa298a 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -1,28 +1,19 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <linux/stddef.h>
7#include <linux/kernel.h>
8#include <linux/list.h>
9#include <linux/slab.h> 6#include <linux/slab.h>
10#include <linux/tty.h> 7#include <linux/tty.h>
11#include <linux/string.h>
12#include <linux/tty_flip.h> 8#include <linux/tty_flip.h>
13#include <asm/irq.h>
14#include "chan_kern.h" 9#include "chan_kern.h"
15#include "kern.h"
16#include "irq_user.h"
17#include "sigio.h"
18#include "line.h"
19#include "os.h" 10#include "os.h"
20 11
21#ifdef CONFIG_NOCONFIG_CHAN 12#ifdef CONFIG_NOCONFIG_CHAN
22static void *not_configged_init(char *str, int device, 13static void *not_configged_init(char *str, int device,
23 const struct chan_opts *opts) 14 const struct chan_opts *opts)
24{ 15{
25 printk("Using a channel type which is configured out of " 16 printk(KERN_ERR "Using a channel type which is configured out of "
26 "UML\n"); 17 "UML\n");
27 return NULL; 18 return NULL;
28} 19}
@@ -30,34 +21,34 @@ static void *not_configged_init(char *str, int device,
30static int not_configged_open(int input, int output, int primary, void *data, 21static int not_configged_open(int input, int output, int primary, void *data,
31 char **dev_out) 22 char **dev_out)
32{ 23{
33 printk("Using a channel type which is configured out of " 24 printk(KERN_ERR "Using a channel type which is configured out of "
34 "UML\n"); 25 "UML\n");
35 return -ENODEV; 26 return -ENODEV;
36} 27}
37 28
38static void not_configged_close(int fd, void *data) 29static void not_configged_close(int fd, void *data)
39{ 30{
40 printk("Using a channel type which is configured out of " 31 printk(KERN_ERR "Using a channel type which is configured out of "
41 "UML\n"); 32 "UML\n");
42} 33}
43 34
44static int not_configged_read(int fd, char *c_out, void *data) 35static int not_configged_read(int fd, char *c_out, void *data)
45{ 36{
46 printk("Using a channel type which is configured out of " 37 printk(KERN_ERR "Using a channel type which is configured out of "
47 "UML\n"); 38 "UML\n");
48 return -EIO; 39 return -EIO;
49} 40}
50 41
51static int not_configged_write(int fd, const char *buf, int len, void *data) 42static int not_configged_write(int fd, const char *buf, int len, void *data)
52{ 43{
53 printk("Using a channel type which is configured out of " 44 printk(KERN_ERR "Using a channel type which is configured out of "
54 "UML\n"); 45 "UML\n");
55 return -EIO; 46 return -EIO;
56} 47}
57 48
58static int not_configged_console_write(int fd, const char *buf, int len) 49static int not_configged_console_write(int fd, const char *buf, int len)
59{ 50{
60 printk("Using a channel type which is configured out of " 51 printk(KERN_ERR "Using a channel type which is configured out of "
61 "UML\n"); 52 "UML\n");
62 return -EIO; 53 return -EIO;
63} 54}
@@ -65,14 +56,14 @@ static int not_configged_console_write(int fd, const char *buf, int len)
65static int not_configged_window_size(int fd, void *data, unsigned short *rows, 56static int not_configged_window_size(int fd, void *data, unsigned short *rows,
66 unsigned short *cols) 57 unsigned short *cols)
67{ 58{
68 printk("Using a channel type which is configured out of " 59 printk(KERN_ERR "Using a channel type which is configured out of "
69 "UML\n"); 60 "UML\n");
70 return -ENODEV; 61 return -ENODEV;
71} 62}
72 63
73static void not_configged_free(void *data) 64static void not_configged_free(void *data)
74{ 65{
75 printk("Using a channel type which is configured out of " 66 printk(KERN_ERR "Using a channel type which is configured out of "
76 "UML\n"); 67 "UML\n");
77} 68}
78 69
@@ -91,14 +82,15 @@ static const struct chan_ops not_configged_ops = {
91 82
92static void tty_receive_char(struct tty_struct *tty, char ch) 83static void tty_receive_char(struct tty_struct *tty, char ch)
93{ 84{
94 if(tty == NULL) return; 85 if (tty == NULL)
86 return;
95 87
96 if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) { 88 if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
97 if(ch == STOP_CHAR(tty)){ 89 if (ch == STOP_CHAR(tty)) {
98 stop_tty(tty); 90 stop_tty(tty);
99 return; 91 return;
100 } 92 }
101 else if(ch == START_CHAR(tty)){ 93 else if (ch == START_CHAR(tty)) {
102 start_tty(tty); 94 start_tty(tty);
103 return; 95 return;
104 } 96 }
@@ -111,14 +103,14 @@ static int open_one_chan(struct chan *chan)
111{ 103{
112 int fd, err; 104 int fd, err;
113 105
114 if(chan->opened) 106 if (chan->opened)
115 return 0; 107 return 0;
116 108
117 if(chan->ops->open == NULL) 109 if (chan->ops->open == NULL)
118 fd = 0; 110 fd = 0;
119 else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary, 111 else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary,
120 chan->data, &chan->dev); 112 chan->data, &chan->dev);
121 if(fd < 0) 113 if (fd < 0)
122 return fd; 114 return fd;
123 115
124 err = os_set_fd_block(fd, 0); 116 err = os_set_fd_block(fd, 0);
@@ -139,10 +131,10 @@ int open_chan(struct list_head *chans)
139 struct chan *chan; 131 struct chan *chan;
140 int ret, err = 0; 132 int ret, err = 0;
141 133
142 list_for_each(ele, chans){ 134 list_for_each(ele, chans) {
143 chan = list_entry(ele, struct chan, list); 135 chan = list_entry(ele, struct chan, list);
144 ret = open_one_chan(chan); 136 ret = open_one_chan(chan);
145 if(chan->primary) 137 if (chan->primary)
146 err = ret; 138 err = ret;
147 } 139 }
148 return err; 140 return err;
@@ -153,9 +145,9 @@ void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
153 struct list_head *ele; 145 struct list_head *ele;
154 struct chan *chan; 146 struct chan *chan;
155 147
156 list_for_each(ele, chans){ 148 list_for_each(ele, chans) {
157 chan = list_entry(ele, struct chan, list); 149 chan = list_entry(ele, struct chan, list);
158 if(chan->primary && chan->output && chan->ops->winch){ 150 if (chan->primary && chan->output && chan->ops->winch) {
159 register_winch(chan->fd, tty); 151 register_winch(chan->fd, tty);
160 return; 152 return;
161 } 153 }
@@ -168,7 +160,7 @@ int enable_chan(struct line *line)
168 struct chan *chan; 160 struct chan *chan;
169 int err; 161 int err;
170 162
171 list_for_each(ele, &line->chan_list){ 163 list_for_each(ele, &line->chan_list) {
172 chan = list_entry(ele, struct chan, list); 164 chan = list_entry(ele, struct chan, list);
173 err = open_one_chan(chan); 165 err = open_one_chan(chan);
174 if (err) { 166 if (err) {
@@ -178,7 +170,7 @@ int enable_chan(struct line *line)
178 continue; 170 continue;
179 } 171 }
180 172
181 if(chan->enabled) 173 if (chan->enabled)
182 continue; 174 continue;
183 err = line_setup_irq(chan->fd, chan->input, chan->output, line, 175 err = line_setup_irq(chan->fd, chan->input, chan->output, line,
184 chan); 176 chan);
@@ -215,12 +207,12 @@ void free_irqs(void)
215 list_splice_init(&irqs_to_free, &list); 207 list_splice_init(&irqs_to_free, &list);
216 spin_unlock_irqrestore(&irqs_to_free_lock, flags); 208 spin_unlock_irqrestore(&irqs_to_free_lock, flags);
217 209
218 list_for_each(ele, &list){ 210 list_for_each(ele, &list) {
219 chan = list_entry(ele, struct chan, free_list); 211 chan = list_entry(ele, struct chan, free_list);
220 212
221 if(chan->input) 213 if (chan->input)
222 free_irq(chan->line->driver->read_irq, chan); 214 free_irq(chan->line->driver->read_irq, chan);
223 if(chan->output) 215 if (chan->output)
224 free_irq(chan->line->driver->write_irq, chan); 216 free_irq(chan->line->driver->write_irq, chan);
225 chan->enabled = 0; 217 chan->enabled = 0;
226 } 218 }
@@ -230,22 +222,22 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)
230{ 222{
231 unsigned long flags; 223 unsigned long flags;
232 224
233 if(!chan->opened) 225 if (!chan->opened)
234 return; 226 return;
235 227
236 if(delay_free_irq){ 228 if (delay_free_irq) {
237 spin_lock_irqsave(&irqs_to_free_lock, flags); 229 spin_lock_irqsave(&irqs_to_free_lock, flags);
238 list_add(&chan->free_list, &irqs_to_free); 230 list_add(&chan->free_list, &irqs_to_free);
239 spin_unlock_irqrestore(&irqs_to_free_lock, flags); 231 spin_unlock_irqrestore(&irqs_to_free_lock, flags);
240 } 232 }
241 else { 233 else {
242 if(chan->input) 234 if (chan->input)
243 free_irq(chan->line->driver->read_irq, chan); 235 free_irq(chan->line->driver->read_irq, chan);
244 if(chan->output) 236 if (chan->output)
245 free_irq(chan->line->driver->write_irq, chan); 237 free_irq(chan->line->driver->write_irq, chan);
246 chan->enabled = 0; 238 chan->enabled = 0;
247 } 239 }
248 if(chan->ops->close != NULL) 240 if (chan->ops->close != NULL)
249 (*chan->ops->close)(chan->fd, chan->data); 241 (*chan->ops->close)(chan->fd, chan->data);
250 242
251 chan->opened = 0; 243 chan->opened = 0;
@@ -274,7 +266,7 @@ void deactivate_chan(struct list_head *chans, int irq)
274 list_for_each(ele, chans) { 266 list_for_each(ele, chans) {
275 chan = list_entry(ele, struct chan, list); 267 chan = list_entry(ele, struct chan, list);
276 268
277 if(chan->enabled && chan->input) 269 if (chan->enabled && chan->input)
278 deactivate_fd(chan->fd, irq); 270 deactivate_fd(chan->fd, irq);
279 } 271 }
280} 272}
@@ -287,7 +279,7 @@ void reactivate_chan(struct list_head *chans, int irq)
287 list_for_each(ele, chans) { 279 list_for_each(ele, chans) {
288 chan = list_entry(ele, struct chan, list); 280 chan = list_entry(ele, struct chan, list);
289 281
290 if(chan->enabled && chan->input) 282 if (chan->enabled && chan->input)
291 reactivate_fd(chan->fd, irq); 283 reactivate_fd(chan->fd, irq);
292 } 284 }
293} 285}
@@ -303,6 +295,7 @@ int write_chan(struct list_head *chans, const char *buf, int len,
303 chan = list_entry(ele, struct chan, list); 295 chan = list_entry(ele, struct chan, list);
304 if (!chan->output || (chan->ops->write == NULL)) 296 if (!chan->output || (chan->ops->write == NULL))
305 continue; 297 continue;
298
306 n = chan->ops->write(chan->fd, buf, len, chan->data); 299 n = chan->ops->write(chan->fd, buf, len, chan->data);
307 if (chan->primary) { 300 if (chan->primary) {
308 ret = n; 301 ret = n;
@@ -319,12 +312,14 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
319 struct chan *chan; 312 struct chan *chan;
320 int n, ret = 0; 313 int n, ret = 0;
321 314
322 list_for_each(ele, chans){ 315 list_for_each(ele, chans) {
323 chan = list_entry(ele, struct chan, list); 316 chan = list_entry(ele, struct chan, list);
324 if(!chan->output || (chan->ops->console_write == NULL)) 317 if (!chan->output || (chan->ops->console_write == NULL))
325 continue; 318 continue;
319
326 n = chan->ops->console_write(chan->fd, buf, len); 320 n = chan->ops->console_write(chan->fd, buf, len);
327 if(chan->primary) ret = n; 321 if (chan->primary)
322 ret = n;
328 } 323 }
329 return ret; 324 return ret;
330} 325}
@@ -334,10 +329,11 @@ int console_open_chan(struct line *line, struct console *co)
334 int err; 329 int err;
335 330
336 err = open_chan(&line->chan_list); 331 err = open_chan(&line->chan_list);
337 if(err) 332 if (err)
338 return err; 333 return err;
339 334
340 printk("Console initialized on /dev/%s%d\n", co->name, co->index); 335 printk(KERN_INFO "Console initialized on /dev/%s%d\n", co->name,
336 co->index);
341 return 0; 337 return 0;
342} 338}
343 339
@@ -347,10 +343,10 @@ int chan_window_size(struct list_head *chans, unsigned short *rows_out,
347 struct list_head *ele; 343 struct list_head *ele;
348 struct chan *chan; 344 struct chan *chan;
349 345
350 list_for_each(ele, chans){ 346 list_for_each(ele, chans) {
351 chan = list_entry(ele, struct chan, list); 347 chan = list_entry(ele, struct chan, list);
352 if(chan->primary){ 348 if (chan->primary) {
353 if(chan->ops->window_size == NULL) 349 if (chan->ops->window_size == NULL)
354 return 0; 350 return 0;
355 return chan->ops->window_size(chan->fd, chan->data, 351 return chan->ops->window_size(chan->fd, chan->data,
356 rows_out, cols_out); 352 rows_out, cols_out);
@@ -365,10 +361,11 @@ static void free_one_chan(struct chan *chan, int delay_free_irq)
365 361
366 close_one_chan(chan, delay_free_irq); 362 close_one_chan(chan, delay_free_irq);
367 363
368 if(chan->ops->free != NULL) 364 if (chan->ops->free != NULL)
369 (*chan->ops->free)(chan->data); 365 (*chan->ops->free)(chan->data);
370 366
371 if(chan->primary && chan->output) ignore_sigio_fd(chan->fd); 367 if (chan->primary && chan->output)
368 ignore_sigio_fd(chan->fd);
372 kfree(chan); 369 kfree(chan);
373} 370}
374 371
@@ -377,7 +374,7 @@ static void free_chan(struct list_head *chans, int delay_free_irq)
377 struct list_head *ele, *next; 374 struct list_head *ele, *next;
378 struct chan *chan; 375 struct chan *chan;
379 376
380 list_for_each_safe(ele, next, chans){ 377 list_for_each_safe(ele, next, chans) {
381 chan = list_entry(ele, struct chan, list); 378 chan = list_entry(ele, struct chan, list);
382 free_one_chan(chan, delay_free_irq); 379 free_one_chan(chan, delay_free_irq);
383 } 380 }
@@ -388,14 +385,14 @@ static int one_chan_config_string(struct chan *chan, char *str, int size,
388{ 385{
389 int n = 0; 386 int n = 0;
390 387
391 if(chan == NULL){ 388 if (chan == NULL) {
392 CONFIG_CHUNK(str, size, n, "none", 1); 389 CONFIG_CHUNK(str, size, n, "none", 1);
393 return n; 390 return n;
394 } 391 }
395 392
396 CONFIG_CHUNK(str, size, n, chan->ops->type, 0); 393 CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
397 394
398 if(chan->dev == NULL){ 395 if (chan->dev == NULL) {
399 CONFIG_CHUNK(str, size, n, "", 1); 396 CONFIG_CHUNK(str, size, n, "", 1);
400 return n; 397 return n;
401 } 398 }
@@ -415,7 +412,7 @@ static int chan_pair_config_string(struct chan *in, struct chan *out,
415 str += n; 412 str += n;
416 size -= n; 413 size -= n;
417 414
418 if(in == out){ 415 if (in == out) {
419 CONFIG_CHUNK(str, size, n, "", 1); 416 CONFIG_CHUNK(str, size, n, "", 1);
420 return n; 417 return n;
421 } 418 }
@@ -435,13 +432,13 @@ int chan_config_string(struct list_head *chans, char *str, int size,
435 struct list_head *ele; 432 struct list_head *ele;
436 struct chan *chan, *in = NULL, *out = NULL; 433 struct chan *chan, *in = NULL, *out = NULL;
437 434
438 list_for_each(ele, chans){ 435 list_for_each(ele, chans) {
439 chan = list_entry(ele, struct chan, list); 436 chan = list_entry(ele, struct chan, list);
440 if(!chan->primary) 437 if (!chan->primary)
441 continue; 438 continue;
442 if(chan->input) 439 if (chan->input)
443 in = chan; 440 in = chan;
444 if(chan->output) 441 if (chan->output)
445 out = chan; 442 out = chan;
446 } 443 }
447 444
@@ -500,27 +497,27 @@ static struct chan *parse_chan(struct line *line, char *str, int device,
500 497
501 ops = NULL; 498 ops = NULL;
502 data = NULL; 499 data = NULL;
503 for(i = 0; i < ARRAY_SIZE(chan_table); i++){ 500 for(i = 0; i < ARRAY_SIZE(chan_table); i++) {
504 entry = &chan_table[i]; 501 entry = &chan_table[i];
505 if(!strncmp(str, entry->key, strlen(entry->key))){ 502 if (!strncmp(str, entry->key, strlen(entry->key))) {
506 ops = entry->ops; 503 ops = entry->ops;
507 str += strlen(entry->key); 504 str += strlen(entry->key);
508 break; 505 break;
509 } 506 }
510 } 507 }
511 if(ops == NULL){ 508 if (ops == NULL) {
512 *error_out = "No match for configured backends"; 509 *error_out = "No match for configured backends";
513 return NULL; 510 return NULL;
514 } 511 }
515 512
516 data = (*ops->init)(str, device, opts); 513 data = (*ops->init)(str, device, opts);
517 if(data == NULL){ 514 if (data == NULL) {
518 *error_out = "Configuration failed"; 515 *error_out = "Configuration failed";
519 return NULL; 516 return NULL;
520 } 517 }
521 518
522 chan = kmalloc(sizeof(*chan), GFP_ATOMIC); 519 chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
523 if(chan == NULL){ 520 if (chan == NULL) {
524 *error_out = "Memory allocation failed"; 521 *error_out = "Memory allocation failed";
525 return NULL; 522 return NULL;
526 } 523 }
@@ -546,26 +543,26 @@ int parse_chan_pair(char *str, struct line *line, int device,
546 struct chan *new, *chan; 543 struct chan *new, *chan;
547 char *in, *out; 544 char *in, *out;
548 545
549 if(!list_empty(chans)){ 546 if (!list_empty(chans)) {
550 chan = list_entry(chans->next, struct chan, list); 547 chan = list_entry(chans->next, struct chan, list);
551 free_chan(chans, 0); 548 free_chan(chans, 0);
552 INIT_LIST_HEAD(chans); 549 INIT_LIST_HEAD(chans);
553 } 550 }
554 551
555 out = strchr(str, ','); 552 out = strchr(str, ',');
556 if(out != NULL){ 553 if (out != NULL) {
557 in = str; 554 in = str;
558 *out = '\0'; 555 *out = '\0';
559 out++; 556 out++;
560 new = parse_chan(line, in, device, opts, error_out); 557 new = parse_chan(line, in, device, opts, error_out);
561 if(new == NULL) 558 if (new == NULL)
562 return -1; 559 return -1;
563 560
564 new->input = 1; 561 new->input = 1;
565 list_add(&new->list, chans); 562 list_add(&new->list, chans);
566 563
567 new = parse_chan(line, out, device, opts, error_out); 564 new = parse_chan(line, out, device, opts, error_out);
568 if(new == NULL) 565 if (new == NULL)
569 return -1; 566 return -1;
570 567
571 list_add(&new->list, chans); 568 list_add(&new->list, chans);
@@ -573,7 +570,7 @@ int parse_chan_pair(char *str, struct line *line, int device,
573 } 570 }
574 else { 571 else {
575 new = parse_chan(line, str, device, opts, error_out); 572 new = parse_chan(line, str, device, opts, error_out);
576 if(new == NULL) 573 if (new == NULL)
577 return -1; 574 return -1;
578 575
579 list_add(&new->list, chans); 576 list_add(&new->list, chans);
@@ -588,9 +585,9 @@ int chan_out_fd(struct list_head *chans)
588 struct list_head *ele; 585 struct list_head *ele;
589 struct chan *chan; 586 struct chan *chan;
590 587
591 list_for_each(ele, chans){ 588 list_for_each(ele, chans) {
592 chan = list_entry(ele, struct chan, list); 589 chan = list_entry(ele, struct chan, list);
593 if(chan->primary && chan->output) 590 if (chan->primary && chan->output)
594 return chan->fd; 591 return chan->fd;
595 } 592 }
596 return -1; 593 return -1;
@@ -604,23 +601,25 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task,
604 int err; 601 int err;
605 char c; 602 char c;
606 603
607 list_for_each_safe(ele, next, chans){ 604 list_for_each_safe(ele, next, chans) {
608 chan = list_entry(ele, struct chan, list); 605 chan = list_entry(ele, struct chan, list);
609 if(!chan->input || (chan->ops->read == NULL)) continue; 606 if (!chan->input || (chan->ops->read == NULL))
607 continue;
610 do { 608 do {
611 if (tty && !tty_buffer_request_room(tty, 1)) { 609 if (tty && !tty_buffer_request_room(tty, 1)) {
612 schedule_delayed_work(task, 1); 610 schedule_delayed_work(task, 1);
613 goto out; 611 goto out;
614 } 612 }
615 err = chan->ops->read(chan->fd, &c, chan->data); 613 err = chan->ops->read(chan->fd, &c, chan->data);
616 if(err > 0) 614 if (err > 0)
617 tty_receive_char(tty, c); 615 tty_receive_char(tty, c);
618 } while(err > 0); 616 } while (err > 0);
619 617
620 if(err == 0) reactivate_fd(chan->fd, irq); 618 if (err == 0)
621 if(err == -EIO){ 619 reactivate_fd(chan->fd, irq);
622 if(chan->primary){ 620 if (err == -EIO) {
623 if(tty != NULL) 621 if (chan->primary) {
622 if (tty != NULL)
624 tty_hangup(tty); 623 tty_hangup(tty);
625 close_chan(chans, 1); 624 close_chan(chans, 1);
626 return; 625 return;
@@ -629,5 +628,6 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task,
629 } 628 }
630 } 629 }
631 out: 630 out:
632 if(tty) tty_flip_buffer_push(tty); 631 if (tty)
632 tty_flip_buffer_push(tty);
633} 633}
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 40271afa3ee2..77557e233f58 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -1,25 +1,19 @@
1/* 1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h>
7#include <stdlib.h> 6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h> 8#include <errno.h>
9#include <termios.h>
10#include <string.h>
11#include <signal.h>
12#include <sched.h> 9#include <sched.h>
13#include <sys/stat.h> 10#include <signal.h>
11#include <termios.h>
14#include <sys/ioctl.h> 12#include <sys/ioctl.h>
15#include <sys/socket.h>
16#include "kern_util.h"
17#include "chan_user.h" 13#include "chan_user.h"
18#include "user.h"
19#include "os.h" 14#include "os.h"
20#include "choose-mode.h"
21#include "mode.h"
22#include "um_malloc.h" 15#include "um_malloc.h"
16#include "user.h"
23 17
24void generic_close(int fd, void *unused) 18void generic_close(int fd, void *unused)
25{ 19{
@@ -53,7 +47,7 @@ int generic_window_size(int fd, void *unused, unsigned short *rows_out,
53 struct winsize size; 47 struct winsize size;
54 int ret; 48 int ret;
55 49
56 if(ioctl(fd, TIOCGWINSZ, &size) < 0) 50 if (ioctl(fd, TIOCGWINSZ, &size) < 0)
57 return -errno; 51 return -errno;
58 52
59 ret = ((*rows_out != size.ws_row) || (*cols_out != size.ws_col)); 53 ret = ((*rows_out != size.ws_row) || (*cols_out != size.ws_col));
@@ -74,7 +68,7 @@ int generic_console_write(int fd, const char *buf, int n)
74 struct termios save, new; 68 struct termios save, new;
75 int err; 69 int err;
76 70
77 if(isatty(fd)){ 71 if (isatty(fd)) {
78 CATCH_EINTR(err = tcgetattr(fd, &save)); 72 CATCH_EINTR(err = tcgetattr(fd, &save));
79 if (err) 73 if (err)
80 goto error; 74 goto error;
@@ -90,11 +84,11 @@ int generic_console_write(int fd, const char *buf, int n)
90 err = generic_write(fd, buf, n, NULL); 84 err = generic_write(fd, buf, n, NULL);
91 /* Restore raw mode, in any case; we *must* ignore any error apart 85 /* Restore raw mode, in any case; we *must* ignore any error apart
92 * EINTR, except for debug.*/ 86 * EINTR, except for debug.*/
93 if(isatty(fd)) 87 if (isatty(fd))
94 CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save)); 88 CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save));
95 return(err); 89 return err;
96error: 90error:
97 return(-errno); 91 return -errno;
98} 92}
99 93
100/* 94/*
@@ -137,56 +131,62 @@ static int winch_thread(void *arg)
137 pty_fd = data->pty_fd; 131 pty_fd = data->pty_fd;
138 pipe_fd = data->pipe_fd; 132 pipe_fd = data->pipe_fd;
139 count = os_write_file(pipe_fd, &c, sizeof(c)); 133 count = os_write_file(pipe_fd, &c, sizeof(c));
140 if(count != sizeof(c)) 134 if (count != sizeof(c))
141 printk("winch_thread : failed to write synchronization " 135 printk(UM_KERN_ERR "winch_thread : failed to write "
142 "byte, err = %d\n", -count); 136 "synchronization byte, err = %d\n", -count);
143 137
144 /* We are not using SIG_IGN on purpose, so don't fix it as I thought to 138 /*
139 * We are not using SIG_IGN on purpose, so don't fix it as I thought to
145 * do! If using SIG_IGN, the sigsuspend() call below would not stop on 140 * do! If using SIG_IGN, the sigsuspend() call below would not stop on
146 * SIGWINCH. */ 141 * SIGWINCH.
142 */
147 143
148 signal(SIGWINCH, winch_handler); 144 signal(SIGWINCH, winch_handler);
149 sigfillset(&sigs); 145 sigfillset(&sigs);
150 /* Block all signals possible. */ 146 /* Block all signals possible. */
151 if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){ 147 if (sigprocmask(SIG_SETMASK, &sigs, NULL) < 0) {
152 printk("winch_thread : sigprocmask failed, errno = %d\n", 148 printk(UM_KERN_ERR "winch_thread : sigprocmask failed, "
153 errno); 149 "errno = %d\n", errno);
154 exit(1); 150 exit(1);
155 } 151 }
156 /* In sigsuspend(), block anything else than SIGWINCH. */ 152 /* In sigsuspend(), block anything else than SIGWINCH. */
157 sigdelset(&sigs, SIGWINCH); 153 sigdelset(&sigs, SIGWINCH);
158 154
159 if(setsid() < 0){ 155 if (setsid() < 0) {
160 printk("winch_thread : setsid failed, errno = %d\n", errno); 156 printk(UM_KERN_ERR "winch_thread : setsid failed, errno = %d\n",
157 errno);
161 exit(1); 158 exit(1);
162 } 159 }
163 160
164 err = os_new_tty_pgrp(pty_fd, os_getpid()); 161 err = os_new_tty_pgrp(pty_fd, os_getpid());
165 if(err < 0){ 162 if (err < 0) {
166 printk("winch_thread : new_tty_pgrp failed on fd %d, " 163 printk(UM_KERN_ERR "winch_thread : new_tty_pgrp failed on "
167 "err = %d\n", pty_fd, -err); 164 "fd %d err = %d\n", pty_fd, -err);
168 exit(1); 165 exit(1);
169 } 166 }
170 167
171 /* These are synchronization calls between various UML threads on the 168 /*
169 * These are synchronization calls between various UML threads on the
172 * host - since they are not different kernel threads, we cannot use 170 * host - since they are not different kernel threads, we cannot use
173 * kernel semaphores. We don't use SysV semaphores because they are 171 * kernel semaphores. We don't use SysV semaphores because they are
174 * persistent. */ 172 * persistent.
173 */
175 count = os_read_file(pipe_fd, &c, sizeof(c)); 174 count = os_read_file(pipe_fd, &c, sizeof(c));
176 if(count != sizeof(c)) 175 if (count != sizeof(c))
177 printk("winch_thread : failed to read synchronization byte, " 176 printk(UM_KERN_ERR "winch_thread : failed to read "
178 "err = %d\n", -count); 177 "synchronization byte, err = %d\n", -count);
179 178
180 while(1){ 179 while(1) {
181 /* This will be interrupted by SIGWINCH only, since 180 /*
181 * This will be interrupted by SIGWINCH only, since
182 * other signals are blocked. 182 * other signals are blocked.
183 */ 183 */
184 sigsuspend(&sigs); 184 sigsuspend(&sigs);
185 185
186 count = os_write_file(pipe_fd, &c, sizeof(c)); 186 count = os_write_file(pipe_fd, &c, sizeof(c));
187 if(count != sizeof(c)) 187 if (count != sizeof(c))
188 printk("winch_thread : write failed, err = %d\n", 188 printk(UM_KERN_ERR "winch_thread : write failed, "
189 -count); 189 "err = %d\n", -count);
190 } 190 }
191} 191}
192 192
@@ -198,36 +198,41 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
198 char c; 198 char c;
199 199
200 err = os_pipe(fds, 1, 1); 200 err = os_pipe(fds, 1, 1);
201 if(err < 0){ 201 if (err < 0) {
202 printk("winch_tramp : os_pipe failed, err = %d\n", -err); 202 printk(UM_KERN_ERR "winch_tramp : os_pipe failed, err = %d\n",
203 -err);
203 goto out; 204 goto out;
204 } 205 }
205 206
206 data = ((struct winch_data) { .pty_fd = fd, 207 data = ((struct winch_data) { .pty_fd = fd,
207 .pipe_fd = fds[1] } ); 208 .pipe_fd = fds[1] } );
208 /* CLONE_FILES so this thread doesn't hold open files which are open 209 /*
210 * CLONE_FILES so this thread doesn't hold open files which are open
209 * now, but later closed in a different thread. This is a 211 * now, but later closed in a different thread. This is a
210 * problem with /dev/net/tun, which if held open by this 212 * problem with /dev/net/tun, which if held open by this
211 * thread, prevents the TUN/TAP device from being reused. 213 * thread, prevents the TUN/TAP device from being reused.
212 */ 214 */
213 err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); 215 err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out);
214 if(err < 0){ 216 if (err < 0) {
215 printk("fork of winch_thread failed - errno = %d\n", -err); 217 printk(UM_KERN_ERR "fork of winch_thread failed - errno = %d\n",
218 -err);
216 goto out_close; 219 goto out_close;
217 } 220 }
218 221
219 *fd_out = fds[0]; 222 *fd_out = fds[0];
220 n = os_read_file(fds[0], &c, sizeof(c)); 223 n = os_read_file(fds[0], &c, sizeof(c));
221 if(n != sizeof(c)){ 224 if (n != sizeof(c)) {
222 printk("winch_tramp : failed to read synchronization byte\n"); 225 printk(UM_KERN_ERR "winch_tramp : failed to read "
223 printk("read failed, err = %d\n", -n); 226 "synchronization byte\n");
224 printk("fd %d will not support SIGWINCH\n", fd); 227 printk(UM_KERN_ERR "read failed, err = %d\n", -n);
225 err = -EINVAL; 228 printk(UM_KERN_ERR "fd %d will not support SIGWINCH\n", fd);
229 err = -EINVAL;
226 goto out_close; 230 goto out_close;
227 } 231 }
228 232
229 if (os_set_fd_block(*fd_out, 0)) { 233 if (os_set_fd_block(*fd_out, 0)) {
230 printk("winch_tramp: failed to set thread_fd non-blocking.\n"); 234 printk(UM_KERN_ERR "winch_tramp: failed to set thread_fd "
235 "non-blocking.\n");
231 goto out_close; 236 goto out_close;
232 } 237 }
233 238
@@ -246,7 +251,7 @@ void register_winch(int fd, struct tty_struct *tty)
246 int pid, thread, count, thread_fd = -1; 251 int pid, thread, count, thread_fd = -1;
247 char c = 1; 252 char c = 1;
248 253
249 if(!isatty(fd)) 254 if (!isatty(fd))
250 return; 255 return;
251 256
252 pid = tcgetpgrp(fd); 257 pid = tcgetpgrp(fd);
@@ -259,8 +264,8 @@ void register_winch(int fd, struct tty_struct *tty)
259 register_winch_irq(thread_fd, fd, thread, tty, stack); 264 register_winch_irq(thread_fd, fd, thread, tty, stack);
260 265
261 count = os_write_file(thread_fd, &c, sizeof(c)); 266 count = os_write_file(thread_fd, &c, sizeof(c));
262 if(count != sizeof(c)) 267 if (count != sizeof(c))
263 printk("register_winch : failed to write " 268 printk(UM_KERN_ERR "register_winch : failed to write "
264 "synchronization byte, err = %d\n", -count); 269 "synchronization byte, err = %d\n", -count);
265 } 270 }
266} 271}
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 39c01ffd45c9..207b0444c9d9 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -1,17 +1,19 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stddef.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <unistd.h> 8#include <stdio.h>
9#include <termios.h>
10#include <errno.h> 9#include <errno.h>
11#include "user.h" 10#include <termios.h>
11#include <unistd.h>
12#include "chan_user.h" 12#include "chan_user.h"
13#include "os.h"
14#include "um_malloc.h" 13#include "um_malloc.h"
14#include "user.h"
15#include "os.h"
16#include "kern_constants.h"
15 17
16struct fd_chan { 18struct fd_chan {
17 int fd; 19 int fd;
@@ -26,22 +28,26 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts)
26 char *end; 28 char *end;
27 int n; 29 int n;
28 30
29 if(*str != ':'){ 31 if (*str != ':') {
30 printk("fd_init : channel type 'fd' must specify a file " 32 printk(UM_KERN_ERR "fd_init : channel type 'fd' must specify a "
31 "descriptor\n"); 33 "file descriptor\n");
32 return(NULL); 34 return NULL;
33 } 35 }
34 str++; 36 str++;
35 n = strtoul(str, &end, 0); 37 n = strtoul(str, &end, 0);
36 if((*end != '\0') || (end == str)){ 38 if ((*end != '\0') || (end == str)) {
37 printk("fd_init : couldn't parse file descriptor '%s'\n", str); 39 printk(UM_KERN_ERR "fd_init : couldn't parse file descriptor "
38 return(NULL); 40 "'%s'\n", str);
41 return NULL;
39 } 42 }
43
40 data = kmalloc(sizeof(*data), UM_GFP_KERNEL); 44 data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
41 if(data == NULL) return(NULL); 45 if(data == NULL)
46 return NULL;
47
42 *data = ((struct fd_chan) { .fd = n, 48 *data = ((struct fd_chan) { .fd = n,
43 .raw = opts->raw }); 49 .raw = opts->raw });
44 return(data); 50 return data;
45} 51}
46 52
47static int fd_open(int input, int output, int primary, void *d, char **dev_out) 53static int fd_open(int input, int output, int primary, void *d, char **dev_out)
@@ -49,18 +55,18 @@ static int fd_open(int input, int output, int primary, void *d, char **dev_out)
49 struct fd_chan *data = d; 55 struct fd_chan *data = d;
50 int err; 56 int err;
51 57
52 if(data->raw && isatty(data->fd)){ 58 if (data->raw && isatty(data->fd)) {
53 CATCH_EINTR(err = tcgetattr(data->fd, &data->tt)); 59 CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
54 if(err) 60 if (err)
55 return(err); 61 return err;
56 62
57 err = raw(data->fd); 63 err = raw(data->fd);
58 if(err) 64 if (err)
59 return(err); 65 return err;
60 } 66 }
61 sprintf(data->str, "%d", data->fd); 67 sprintf(data->str, "%d", data->fd);
62 *dev_out = data->str; 68 *dev_out = data->str;
63 return(data->fd); 69 return data->fd;
64} 70}
65 71
66static void fd_close(int fd, void *d) 72static void fd_close(int fd, void *d)
@@ -68,13 +74,14 @@ static void fd_close(int fd, void *d)
68 struct fd_chan *data = d; 74 struct fd_chan *data = d;
69 int err; 75 int err;
70 76
71 if(data->raw && isatty(fd)){ 77 if (!data->raw || !isatty(fd))
72 CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt)); 78 return;
73 if(err) 79
74 printk("Failed to restore terminal state - " 80 CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
75 "errno = %d\n", -err); 81 if (err)
76 data->raw = 0; 82 printk(UM_KERN_ERR "Failed to restore terminal state - "
77 } 83 "errno = %d\n", -err);
84 data->raw = 0;
78} 85}
79 86
80const struct chan_ops fd_ops = { 87const struct chan_ops fd_ops = {
@@ -89,14 +96,3 @@ const struct chan_ops fd_ops = {
89 .free = generic_free, 96 .free = generic_free,
90 .winch = 1, 97 .winch = 1,
91}; 98};
92
93/*
94 * Overrides for Emacs so that we follow Linus's tabbing style.
95 * Emacs will notice this stuff at the end of the file and automatically
96 * adjust the settings for this buffer only. This must remain at the end
97 * of the file.
98 * ---------------------------------------------------------------------------
99 * Local variables:
100 * c-file-style: "linux"
101 * End:
102 */
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 9016c68beee8..b808641ee679 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -1,31 +1,36 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stddef.h>
7#include <errno.h> 7#include <errno.h>
8#include "chan_user.h" 8#include <fcntl.h>
9#include "os.h" 9#include "os.h"
10#include "chan_user.h"
10 11
11/* This address is used only as a unique identifer */ 12/* This address is used only as a unique identifer */
12static int null_chan; 13static int null_chan;
13 14
14static void *null_init(char *str, int device, const struct chan_opts *opts) 15static void *null_init(char *str, int device, const struct chan_opts *opts)
15{ 16{
16 return(&null_chan); 17 return &null_chan;
17} 18}
18 19
19static int null_open(int input, int output, int primary, void *d, 20static int null_open(int input, int output, int primary, void *d,
20 char **dev_out) 21 char **dev_out)
21{ 22{
23 int fd;
24
22 *dev_out = NULL; 25 *dev_out = NULL;
23 return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0)); 26
27 fd = open(DEV_NULL, O_RDWR);
28 return (fd < 0) ? -errno : fd;
24} 29}
25 30
26static int null_read(int fd, char *c_out, void *unused) 31static int null_read(int fd, char *c_out, void *unused)
27{ 32{
28 return(-ENODEV); 33 return -ENODEV;
29} 34}
30 35
31static void null_free(void *data) 36static void null_free(void *data)
@@ -44,14 +49,3 @@ const struct chan_ops null_ops = {
44 .free = null_free, 49 .free = null_free,
45 .winch = 0, 50 .winch = 0,
46}; 51};
47
48/*
49 * Overrides for Emacs so that we follow Linus's tabbing style.
50 * Emacs will notice this stuff at the end of the file and automatically
51 * adjust the settings for this buffer only. This must remain at the end
52 * of the file.
53 * ---------------------------------------------------------------------------
54 * Local variables:
55 * c-file-style: "linux"
56 * End:
57 */
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index d8acf7470e70..330543b3129b 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -1,24 +1,16 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/list.h" 6#include "linux/completion.h"
7#include "linux/sched.h"
8#include "linux/slab.h"
9#include "linux/interrupt.h" 7#include "linux/interrupt.h"
10#include "linux/spinlock.h" 8#include "linux/list.h"
11#include "linux/errno.h"
12#include "asm/atomic.h" 9#include "asm/atomic.h"
13#include "asm/semaphore.h"
14#include "asm/errno.h"
15#include "kern_util.h"
16#include "kern.h"
17#include "irq_user.h"
18#include "irq_kern.h"
19#include "port.h"
20#include "init.h" 10#include "init.h"
11#include "irq_kern.h"
21#include "os.h" 12#include "os.h"
13#include "port.h"
22 14
23struct port_list { 15struct port_list {
24 struct list_head list; 16 struct list_head list;
@@ -53,8 +45,8 @@ static irqreturn_t pipe_interrupt(int irq, void *data)
53 int fd; 45 int fd;
54 46
55 fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); 47 fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
56 if(fd < 0){ 48 if (fd < 0) {
57 if(fd == -EAGAIN) 49 if (fd == -EAGAIN)
58 return IRQ_NONE; 50 return IRQ_NONE;
59 51
60 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 52 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
@@ -81,18 +73,18 @@ static irqreturn_t pipe_interrupt(int irq, void *data)
81static int port_accept(struct port_list *port) 73static int port_accept(struct port_list *port)
82{ 74{
83 struct connection *conn; 75 struct connection *conn;
84 int fd, socket[2], pid, ret = 0; 76 int fd, socket[2], pid;
85 77
86 fd = port_connection(port->fd, socket, &pid); 78 fd = port_connection(port->fd, socket, &pid);
87 if(fd < 0){ 79 if (fd < 0) {
88 if(fd != -EAGAIN) 80 if (fd != -EAGAIN)
89 printk(KERN_ERR "port_accept : port_connection " 81 printk(KERN_ERR "port_accept : port_connection "
90 "returned %d\n", -fd); 82 "returned %d\n", -fd);
91 goto out; 83 goto out;
92 } 84 }
93 85
94 conn = kmalloc(sizeof(*conn), GFP_ATOMIC); 86 conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
95 if(conn == NULL){ 87 if (conn == NULL) {
96 printk(KERN_ERR "port_accept : failed to allocate " 88 printk(KERN_ERR "port_accept : failed to allocate "
97 "connection\n"); 89 "connection\n");
98 goto out_close; 90 goto out_close;
@@ -104,17 +96,17 @@ static int port_accept(struct port_list *port)
104 .telnetd_pid = pid, 96 .telnetd_pid = pid,
105 .port = port }); 97 .port = port });
106 98
107 if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, 99 if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
108 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, 100 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
109 "telnetd", conn)){ 101 "telnetd", conn)) {
110 printk(KERN_ERR "port_accept : failed to get IRQ for " 102 printk(KERN_ERR "port_accept : failed to get IRQ for "
111 "telnetd\n"); 103 "telnetd\n");
112 goto out_free; 104 goto out_free;
113 } 105 }
114 106
115 if(atomic_read(&port->wait_count) == 0){ 107 if (atomic_read(&port->wait_count) == 0) {
116 os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); 108 os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG));
117 printk("No one waiting for port\n"); 109 printk(KERN_ERR "No one waiting for port\n");
118 } 110 }
119 list_add(&conn->list, &port->pending); 111 list_add(&conn->list, &port->pending);
120 return 1; 112 return 1;
@@ -123,28 +115,29 @@ static int port_accept(struct port_list *port)
123 kfree(conn); 115 kfree(conn);
124 out_close: 116 out_close:
125 os_close_file(fd); 117 os_close_file(fd);
126 if(pid != -1) 118 os_kill_process(pid, 1);
127 os_kill_process(pid, 1);
128 out: 119 out:
129 return ret; 120 return 0;
130} 121}
131 122
132static DECLARE_MUTEX(ports_sem); 123static DECLARE_MUTEX(ports_sem);
133static LIST_HEAD(ports); 124static LIST_HEAD(ports);
134 125
135void port_work_proc(struct work_struct *unused) 126static void port_work_proc(struct work_struct *unused)
136{ 127{
137 struct port_list *port; 128 struct port_list *port;
138 struct list_head *ele; 129 struct list_head *ele;
139 unsigned long flags; 130 unsigned long flags;
140 131
141 local_irq_save(flags); 132 local_irq_save(flags);
142 list_for_each(ele, &ports){ 133 list_for_each(ele, &ports) {
143 port = list_entry(ele, struct port_list, list); 134 port = list_entry(ele, struct port_list, list);
144 if(!port->has_connection) 135 if (!port->has_connection)
145 continue; 136 continue;
137
146 reactivate_fd(port->fd, ACCEPT_IRQ); 138 reactivate_fd(port->fd, ACCEPT_IRQ);
147 while(port_accept(port)) ; 139 while (port_accept(port))
140 ;
148 port->has_connection = 0; 141 port->has_connection = 0;
149 } 142 }
150 local_irq_restore(flags); 143 local_irq_restore(flags);
@@ -169,25 +162,27 @@ void *port_data(int port_num)
169 int fd; 162 int fd;
170 163
171 down(&ports_sem); 164 down(&ports_sem);
172 list_for_each(ele, &ports){ 165 list_for_each(ele, &ports) {
173 port = list_entry(ele, struct port_list, list); 166 port = list_entry(ele, struct port_list, list);
174 if(port->port == port_num) goto found; 167 if (port->port == port_num)
168 goto found;
175 } 169 }
176 port = kmalloc(sizeof(struct port_list), GFP_KERNEL); 170 port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
177 if(port == NULL){ 171 if (port == NULL) {
178 printk(KERN_ERR "Allocation of port list failed\n"); 172 printk(KERN_ERR "Allocation of port list failed\n");
179 goto out; 173 goto out;
180 } 174 }
181 175
182 fd = port_listen_fd(port_num); 176 fd = port_listen_fd(port_num);
183 if(fd < 0){ 177 if (fd < 0) {
184 printk(KERN_ERR "binding to port %d failed, errno = %d\n", 178 printk(KERN_ERR "binding to port %d failed, errno = %d\n",
185 port_num, -fd); 179 port_num, -fd);
186 goto out_free; 180 goto out_free;
187 } 181 }
188 if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, 182
183 if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
189 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, 184 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
190 "port", port)){ 185 "port", port)) {
191 printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); 186 printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
192 goto out_close; 187 goto out_close;
193 } 188 }
@@ -206,7 +201,7 @@ void *port_data(int port_num)
206 201
207 found: 202 found:
208 dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL); 203 dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
209 if(dev == NULL){ 204 if (dev == NULL) {
210 printk(KERN_ERR "Allocation of port device entry failed\n"); 205 printk(KERN_ERR "Allocation of port device entry failed\n");
211 goto out; 206 goto out;
212 } 207 }
@@ -233,9 +228,9 @@ int port_wait(void *data)
233 int fd; 228 int fd;
234 229
235 atomic_inc(&port->wait_count); 230 atomic_inc(&port->wait_count);
236 while(1){ 231 while (1) {
237 fd = -ERESTARTSYS; 232 fd = -ERESTARTSYS;
238 if(wait_for_completion_interruptible(&port->done)) 233 if (wait_for_completion_interruptible(&port->done))
239 goto out; 234 goto out;
240 235
241 spin_lock(&port->lock); 236 spin_lock(&port->lock);
@@ -258,7 +253,8 @@ int port_wait(void *data)
258 */ 253 */
259 free_irq(TELNETD_IRQ, conn); 254 free_irq(TELNETD_IRQ, conn);
260 255
261 if(conn->fd >= 0) break; 256 if (conn->fd >= 0)
257 break;
262 os_close_file(conn->fd); 258 os_close_file(conn->fd);
263 kfree(conn); 259 kfree(conn);
264 } 260 }
@@ -276,9 +272,9 @@ void port_remove_dev(void *d)
276{ 272{
277 struct port_dev *dev = d; 273 struct port_dev *dev = d;
278 274
279 if(dev->helper_pid != -1) 275 if (dev->helper_pid != -1)
280 os_kill_process(dev->helper_pid, 0); 276 os_kill_process(dev->helper_pid, 0);
281 if(dev->telnetd_pid != -1) 277 if (dev->telnetd_pid != -1)
282 os_kill_process(dev->telnetd_pid, 1); 278 os_kill_process(dev->telnetd_pid, 1);
283 dev->helper_pid = -1; 279 dev->helper_pid = -1;
284 dev->telnetd_pid = -1; 280 dev->telnetd_pid = -1;
@@ -297,7 +293,7 @@ static void free_port(void)
297 struct list_head *ele; 293 struct list_head *ele;
298 struct port_list *port; 294 struct port_list *port;
299 295
300 list_for_each(ele, &ports){ 296 list_for_each(ele, &ports) {
301 port = list_entry(ele, struct port_list, list); 297 port = list_entry(ele, struct port_list, list);
302 free_irq_by_fd(port->fd); 298 free_irq_by_fd(port->fd);
303 os_close_file(port->fd); 299 os_close_file(port->fd);
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index c799b00012c7..addd75902656 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -1,24 +1,20 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stdio.h>
7#include <stddef.h>
8#include <stdlib.h> 7#include <stdlib.h>
9#include <string.h>
10#include <errno.h> 8#include <errno.h>
11#include <unistd.h>
12#include <termios.h> 9#include <termios.h>
13#include <sys/socket.h> 10#include <unistd.h>
14#include <sys/un.h>
15#include <netinet/in.h> 11#include <netinet/in.h>
16#include "kern_util.h"
17#include "user.h"
18#include "chan_user.h" 12#include "chan_user.h"
19#include "port.h" 13#include "kern_constants.h"
20#include "os.h" 14#include "os.h"
15#include "port.h"
21#include "um_malloc.h" 16#include "um_malloc.h"
17#include "user.h"
22 18
23struct port_chan { 19struct port_chan {
24 int raw; 20 int raw;
@@ -34,24 +30,25 @@ static void *port_init(char *str, int device, const struct chan_opts *opts)
34 char *end; 30 char *end;
35 int port; 31 int port;
36 32
37 if(*str != ':'){ 33 if (*str != ':') {
38 printk("port_init : channel type 'port' must specify a " 34 printk(UM_KERN_ERR "port_init : channel type 'port' must "
39 "port number\n"); 35 "specify a port number\n");
40 return NULL; 36 return NULL;
41 } 37 }
42 str++; 38 str++;
43 port = strtoul(str, &end, 0); 39 port = strtoul(str, &end, 0);
44 if((*end != '\0') || (end == str)){ 40 if ((*end != '\0') || (end == str)) {
45 printk("port_init : couldn't parse port '%s'\n", str); 41 printk(UM_KERN_ERR "port_init : couldn't parse port '%s'\n",
42 str);
46 return NULL; 43 return NULL;
47 } 44 }
48 45
49 kern_data = port_data(port); 46 kern_data = port_data(port);
50 if(kern_data == NULL) 47 if (kern_data == NULL)
51 return NULL; 48 return NULL;
52 49
53 data = kmalloc(sizeof(*data), UM_GFP_KERNEL); 50 data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
54 if(data == NULL) 51 if (data == NULL)
55 goto err; 52 goto err;
56 53
57 *data = ((struct port_chan) { .raw = opts->raw, 54 *data = ((struct port_chan) { .raw = opts->raw,
@@ -79,13 +76,13 @@ static int port_open(int input, int output, int primary, void *d,
79 int fd, err; 76 int fd, err;
80 77
81 fd = port_wait(data->kernel_data); 78 fd = port_wait(data->kernel_data);
82 if((fd >= 0) && data->raw){ 79 if ((fd >= 0) && data->raw) {
83 CATCH_EINTR(err = tcgetattr(fd, &data->tt)); 80 CATCH_EINTR(err = tcgetattr(fd, &data->tt));
84 if(err) 81 if (err)
85 return err; 82 return err;
86 83
87 err = raw(fd); 84 err = raw(fd);
88 if(err) 85 if (err)
89 return err; 86 return err;
90 } 87 }
91 *dev_out = data->dev; 88 *dev_out = data->dev;
@@ -119,11 +116,11 @@ int port_listen_fd(int port)
119 int fd, err, arg; 116 int fd, err, arg;
120 117
121 fd = socket(PF_INET, SOCK_STREAM, 0); 118 fd = socket(PF_INET, SOCK_STREAM, 0);
122 if(fd == -1) 119 if (fd == -1)
123 return -errno; 120 return -errno;
124 121
125 arg = 1; 122 arg = 1;
126 if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){ 123 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0) {
127 err = -errno; 124 err = -errno;
128 goto out; 125 goto out;
129 } 126 }
@@ -131,23 +128,23 @@ int port_listen_fd(int port)
131 addr.sin_family = AF_INET; 128 addr.sin_family = AF_INET;
132 addr.sin_port = htons(port); 129 addr.sin_port = htons(port);
133 addr.sin_addr.s_addr = htonl(INADDR_ANY); 130 addr.sin_addr.s_addr = htonl(INADDR_ANY);
134 if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){ 131 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
135 err = -errno; 132 err = -errno;
136 goto out; 133 goto out;
137 } 134 }
138 135
139 if(listen(fd, 1) < 0){ 136 if (listen(fd, 1) < 0) {
140 err = -errno; 137 err = -errno;
141 goto out; 138 goto out;
142 } 139 }
143 140
144 err = os_set_fd_block(fd, 0); 141 err = os_set_fd_block(fd, 0);
145 if(err < 0) 142 if (err < 0)
146 goto out; 143 goto out;
147 144
148 return fd; 145 return fd;
149 out: 146 out:
150 os_close_file(fd); 147 close(fd);
151 return err; 148 return err;
152} 149}
153 150
@@ -163,10 +160,10 @@ void port_pre_exec(void *arg)
163 dup2(data->sock_fd, 0); 160 dup2(data->sock_fd, 0);
164 dup2(data->sock_fd, 1); 161 dup2(data->sock_fd, 1);
165 dup2(data->sock_fd, 2); 162 dup2(data->sock_fd, 2);
166 os_close_file(data->sock_fd); 163 close(data->sock_fd);
167 dup2(data->pipe_fd, 3); 164 dup2(data->pipe_fd, 3);
168 os_shutdown_socket(3, 1, 0); 165 shutdown(3, SHUT_RD);
169 os_close_file(data->pipe_fd); 166 close(data->pipe_fd);
170} 167}
171 168
172int port_connection(int fd, int *socket, int *pid_out) 169int port_connection(int fd, int *socket, int *pid_out)
@@ -176,12 +173,12 @@ int port_connection(int fd, int *socket, int *pid_out)
176 "/usr/lib/uml/port-helper", NULL }; 173 "/usr/lib/uml/port-helper", NULL };
177 struct port_pre_exec_data data; 174 struct port_pre_exec_data data;
178 175
179 new = os_accept_connection(fd); 176 new = accept(fd, NULL, 0);
180 if(new < 0) 177 if (new < 0)
181 return new; 178 return -errno;
182 179
183 err = os_pipe(socket, 0, 0); 180 err = os_pipe(socket, 0, 0);
184 if(err < 0) 181 if (err < 0)
185 goto out_close; 182 goto out_close;
186 183
187 data = ((struct port_pre_exec_data) 184 data = ((struct port_pre_exec_data)
@@ -189,18 +186,18 @@ int port_connection(int fd, int *socket, int *pid_out)
189 .pipe_fd = socket[1] }); 186 .pipe_fd = socket[1] });
190 187
191 err = run_helper(port_pre_exec, &data, argv); 188 err = run_helper(port_pre_exec, &data, argv);
192 if(err < 0) 189 if (err < 0)
193 goto out_shutdown; 190 goto out_shutdown;
194 191
195 *pid_out = err; 192 *pid_out = err;
196 return new; 193 return new;
197 194
198 out_shutdown: 195 out_shutdown:
199 os_shutdown_socket(socket[0], 1, 1); 196 shutdown(socket[0], SHUT_RDWR);
200 os_close_file(socket[0]); 197 close(socket[0]);
201 os_shutdown_socket(socket[1], 1, 1); 198 shutdown(socket[1], SHUT_RDWR);
202 os_close_file(socket[1]); 199 close(socket[1]);
203 out_close: 200 out_close:
204 os_close_file(new); 201 close(new);
205 return err; 202 return err;
206} 203}
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 1e3fd619a837..4123fe1fca98 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -56,11 +56,11 @@ static int pts_open(int input, int output, int primary, void *d,
56 if (data->raw) { 56 if (data->raw) {
57 CATCH_EINTR(err = tcgetattr(fd, &data->tt)); 57 CATCH_EINTR(err = tcgetattr(fd, &data->tt));
58 if (err) 58 if (err)
59 return err; 59 goto out_close;
60 60
61 err = raw(fd); 61 err = raw(fd);
62 if (err) 62 if (err)
63 return err; 63 goto out_close;
64 } 64 }
65 65
66 dev = ptsname(fd); 66 dev = ptsname(fd);
@@ -71,6 +71,10 @@ static int pts_open(int input, int output, int primary, void *d,
71 (*data->announce)(dev, data->dev); 71 (*data->announce)(dev, data->dev);
72 72
73 return fd; 73 return fd;
74
75out_close:
76 close(fd);
77 return err;
74} 78}
75 79
76static int getmaster(char *line) 80static int getmaster(char *line)
@@ -119,10 +123,12 @@ static int pty_open(int input, int output, int primary, void *d,
119 if (fd < 0) 123 if (fd < 0)
120 return fd; 124 return fd;
121 125
122 if(data->raw){ 126 if (data->raw) {
123 err = raw(fd); 127 err = raw(fd);
124 if (err) 128 if (err) {
129 close(fd);
125 return err; 130 return err;
131 }
126 } 132 }
127 133
128 if (data->announce) 134 if (data->announce)
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index a9f87e19c5bf..c930fedc5172 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -1,16 +1,16 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h>
7#include <termios.h>
8#include <errno.h> 6#include <errno.h>
9#include <unistd.h> 7#include <fcntl.h>
8#include <termios.h>
10#include "chan_user.h" 9#include "chan_user.h"
11#include "user.h" 10#include "kern_constants.h"
12#include "os.h" 11#include "os.h"
13#include "um_malloc.h" 12#include "um_malloc.h"
13#include "user.h"
14 14
15struct tty_chan { 15struct tty_chan {
16 char *dev; 16 char *dev;
@@ -22,15 +22,15 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
22{ 22{
23 struct tty_chan *data; 23 struct tty_chan *data;
24 24
25 if(*str != ':'){ 25 if (*str != ':') {
26 printk("tty_init : channel type 'tty' must specify " 26 printk(UM_KERN_ERR "tty_init : channel type 'tty' must specify "
27 "a device\n"); 27 "a device\n");
28 return NULL; 28 return NULL;
29 } 29 }
30 str++; 30 str++;
31 31
32 data = kmalloc(sizeof(*data), UM_GFP_KERNEL); 32 data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
33 if(data == NULL) 33 if (data == NULL)
34 return NULL; 34 return NULL;
35 *data = ((struct tty_chan) { .dev = str, 35 *data = ((struct tty_chan) { .dev = str,
36 .raw = opts->raw }); 36 .raw = opts->raw });
@@ -42,19 +42,26 @@ static int tty_open(int input, int output, int primary, void *d,
42 char **dev_out) 42 char **dev_out)
43{ 43{
44 struct tty_chan *data = d; 44 struct tty_chan *data = d;
45 int fd, err; 45 int fd, err, mode = 0;
46
47 if (input && output)
48 mode = O_RDWR;
49 else if (input)
50 mode = O_RDONLY;
51 else if (output)
52 mode = O_WRONLY;
46 53
47 fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0); 54 fd = open(data->dev, mode);
48 if(fd < 0) 55 if (fd < 0)
49 return fd; 56 return -errno;
50 57
51 if(data->raw){ 58 if (data->raw) {
52 CATCH_EINTR(err = tcgetattr(fd, &data->tt)); 59 CATCH_EINTR(err = tcgetattr(fd, &data->tt));
53 if(err) 60 if (err)
54 return err; 61 return err;
55 62
56 err = raw(fd); 63 err = raw(fd);
57 if(err) 64 if (err)
58 return err; 65 return err;
59 } 66 }
60 67
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index fd817e541543..87e18bf2c667 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -3,18 +3,19 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stddef.h>
6#include <stdlib.h> 7#include <stdlib.h>
7#include <stdio.h> 8#include <stdio.h>
8#include <unistd.h> 9#include <unistd.h>
9#include <string.h>
10#include <errno.h> 10#include <errno.h>
11#include <string.h>
11#include <termios.h> 12#include <termios.h>
12#include "chan_user.h" 13#include "chan_user.h"
14#include "kern_constants.h"
13#include "os.h" 15#include "os.h"
14#include "init.h" 16#include "um_malloc.h"
15#include "user.h" 17#include "user.h"
16#include "xterm.h" 18#include "xterm.h"
17#include "kern_constants.h"
18 19
19struct xterm_chan { 20struct xterm_chan {
20 int pid; 21 int pid;
@@ -29,7 +30,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts)
29{ 30{
30 struct xterm_chan *data; 31 struct xterm_chan *data;
31 32
32 data = malloc(sizeof(*data)); 33 data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
33 if (data == NULL) 34 if (data == NULL)
34 return NULL; 35 return NULL;
35 *data = ((struct xterm_chan) { .pid = -1, 36 *data = ((struct xterm_chan) { .pid = -1,
@@ -207,11 +208,6 @@ static void xterm_close(int fd, void *d)
207 os_close_file(fd); 208 os_close_file(fd);
208} 209}
209 210
210static void xterm_free(void *d)
211{
212 free(d);
213}
214
215const struct chan_ops xterm_ops = { 211const struct chan_ops xterm_ops = {
216 .type = "xterm", 212 .type = "xterm",
217 .init = xterm_init, 213 .init = xterm_init,
@@ -221,6 +217,6 @@ const struct chan_ops xterm_ops = {
221 .write = generic_write, 217 .write = generic_write,
222 .console_write = generic_console_write, 218 .console_write = generic_console_write,
223 .window_size = generic_window_size, 219 .window_size = generic_window_size,
224 .free = xterm_free, 220 .free = generic_free,
225 .winch = 1, 221 .winch = 1,
226}; 222};