aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers/chan_kern.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers/chan_kern.c')
-rw-r--r--arch/um/drivers/chan_kern.c160
1 files changed, 80 insertions, 80 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}