diff options
Diffstat (limited to 'arch/um/drivers/chan_kern.c')
-rw-r--r-- | arch/um/drivers/chan_kern.c | 77 |
1 files changed, 23 insertions, 54 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 7d4190e55654..4e7e3cfa21f9 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -19,44 +19,11 @@ | |||
19 | #include "line.h" | 19 | #include "line.h" |
20 | #include "os.h" | 20 | #include "os.h" |
21 | 21 | ||
22 | /* XXX: could well be moved to somewhere else, if needed. */ | ||
23 | static int my_printf(const char * fmt, ...) | ||
24 | __attribute__ ((format (printf, 1, 2))); | ||
25 | |||
26 | static int my_printf(const char * fmt, ...) | ||
27 | { | ||
28 | /* Yes, can be called on atomic context.*/ | ||
29 | char *buf = kmalloc(4096, GFP_ATOMIC); | ||
30 | va_list args; | ||
31 | int r; | ||
32 | |||
33 | if (!buf) { | ||
34 | /* We print directly fmt. | ||
35 | * Yes, yes, yes, feel free to complain. */ | ||
36 | r = strlen(fmt); | ||
37 | } else { | ||
38 | va_start(args, fmt); | ||
39 | r = vsprintf(buf, fmt, args); | ||
40 | va_end(args); | ||
41 | fmt = buf; | ||
42 | } | ||
43 | |||
44 | if (r) | ||
45 | r = os_write_file(1, fmt, r); | ||
46 | return r; | ||
47 | |||
48 | } | ||
49 | |||
50 | #ifdef CONFIG_NOCONFIG_CHAN | 22 | #ifdef CONFIG_NOCONFIG_CHAN |
51 | /* Despite its name, there's no added trailing newline. */ | 23 | static void *not_configged_init(char *str, int device, |
52 | static int my_puts(const char * buf) | 24 | const struct chan_opts *opts) |
53 | { | 25 | { |
54 | return os_write_file(1, buf, strlen(buf)); | 26 | printk("Using a channel type which is configured out of " |
55 | } | ||
56 | |||
57 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) | ||
58 | { | ||
59 | my_puts("Using a channel type which is configured out of " | ||
60 | "UML\n"); | 27 | "UML\n"); |
61 | return NULL; | 28 | return NULL; |
62 | } | 29 | } |
@@ -64,34 +31,34 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts) | |||
64 | static int not_configged_open(int input, int output, int primary, void *data, | 31 | static int not_configged_open(int input, int output, int primary, void *data, |
65 | char **dev_out) | 32 | char **dev_out) |
66 | { | 33 | { |
67 | my_puts("Using a channel type which is configured out of " | 34 | printk("Using a channel type which is configured out of " |
68 | "UML\n"); | 35 | "UML\n"); |
69 | return -ENODEV; | 36 | return -ENODEV; |
70 | } | 37 | } |
71 | 38 | ||
72 | static void not_configged_close(int fd, void *data) | 39 | static void not_configged_close(int fd, void *data) |
73 | { | 40 | { |
74 | my_puts("Using a channel type which is configured out of " | 41 | printk("Using a channel type which is configured out of " |
75 | "UML\n"); | 42 | "UML\n"); |
76 | } | 43 | } |
77 | 44 | ||
78 | static int not_configged_read(int fd, char *c_out, void *data) | 45 | static int not_configged_read(int fd, char *c_out, void *data) |
79 | { | 46 | { |
80 | my_puts("Using a channel type which is configured out of " | 47 | printk("Using a channel type which is configured out of " |
81 | "UML\n"); | 48 | "UML\n"); |
82 | return -EIO; | 49 | return -EIO; |
83 | } | 50 | } |
84 | 51 | ||
85 | static int not_configged_write(int fd, const char *buf, int len, void *data) | 52 | static int not_configged_write(int fd, const char *buf, int len, void *data) |
86 | { | 53 | { |
87 | my_puts("Using a channel type which is configured out of " | 54 | printk("Using a channel type which is configured out of " |
88 | "UML\n"); | 55 | "UML\n"); |
89 | return -EIO; | 56 | return -EIO; |
90 | } | 57 | } |
91 | 58 | ||
92 | static int not_configged_console_write(int fd, const char *buf, int len) | 59 | static int not_configged_console_write(int fd, const char *buf, int len) |
93 | { | 60 | { |
94 | my_puts("Using a channel type which is configured out of " | 61 | printk("Using a channel type which is configured out of " |
95 | "UML\n"); | 62 | "UML\n"); |
96 | return -EIO; | 63 | return -EIO; |
97 | } | 64 | } |
@@ -99,14 +66,14 @@ static int not_configged_console_write(int fd, const char *buf, int len) | |||
99 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, | 66 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, |
100 | unsigned short *cols) | 67 | unsigned short *cols) |
101 | { | 68 | { |
102 | my_puts("Using a channel type which is configured out of " | 69 | printk("Using a channel type which is configured out of " |
103 | "UML\n"); | 70 | "UML\n"); |
104 | return -ENODEV; | 71 | return -ENODEV; |
105 | } | 72 | } |
106 | 73 | ||
107 | static void not_configged_free(void *data) | 74 | static void not_configged_free(void *data) |
108 | { | 75 | { |
109 | my_puts("Using a channel type which is configured out of " | 76 | printk("Using a channel type which is configured out of " |
110 | "UML\n"); | 77 | "UML\n"); |
111 | } | 78 | } |
112 | 79 | ||
@@ -534,7 +501,7 @@ static const struct chan_type chan_table[] = { | |||
534 | }; | 501 | }; |
535 | 502 | ||
536 | static struct chan *parse_chan(struct line *line, char *str, int device, | 503 | static struct chan *parse_chan(struct line *line, char *str, int device, |
537 | const struct chan_opts *opts) | 504 | const struct chan_opts *opts, char **error_out) |
538 | { | 505 | { |
539 | const struct chan_type *entry; | 506 | const struct chan_type *entry; |
540 | const struct chan_ops *ops; | 507 | const struct chan_ops *ops; |
@@ -553,19 +520,21 @@ static struct chan *parse_chan(struct line *line, char *str, int device, | |||
553 | } | 520 | } |
554 | } | 521 | } |
555 | if(ops == NULL){ | 522 | if(ops == NULL){ |
556 | my_printf("parse_chan couldn't parse \"%s\"\n", | 523 | *error_out = "No match for configured backends"; |
557 | str); | ||
558 | return NULL; | 524 | return NULL; |
559 | } | 525 | } |
560 | if(ops->init == NULL) | 526 | |
561 | return NULL; | ||
562 | data = (*ops->init)(str, device, opts); | 527 | data = (*ops->init)(str, device, opts); |
563 | if(data == NULL) | 528 | if(data == NULL){ |
529 | *error_out = "Configuration failed"; | ||
564 | return NULL; | 530 | return NULL; |
531 | } | ||
565 | 532 | ||
566 | chan = kmalloc(sizeof(*chan), GFP_ATOMIC); | 533 | chan = kmalloc(sizeof(*chan), GFP_ATOMIC); |
567 | if(chan == NULL) | 534 | if(chan == NULL){ |
535 | *error_out = "Memory allocation failed"; | ||
568 | return NULL; | 536 | return NULL; |
537 | } | ||
569 | *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), | 538 | *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), |
570 | .free_list = | 539 | .free_list = |
571 | LIST_HEAD_INIT(chan->free_list), | 540 | LIST_HEAD_INIT(chan->free_list), |
@@ -582,7 +551,7 @@ static struct chan *parse_chan(struct line *line, char *str, int device, | |||
582 | } | 551 | } |
583 | 552 | ||
584 | int parse_chan_pair(char *str, struct line *line, int device, | 553 | int parse_chan_pair(char *str, struct line *line, int device, |
585 | const struct chan_opts *opts) | 554 | const struct chan_opts *opts, char **error_out) |
586 | { | 555 | { |
587 | struct list_head *chans = &line->chan_list; | 556 | struct list_head *chans = &line->chan_list; |
588 | struct chan *new, *chan; | 557 | struct chan *new, *chan; |
@@ -599,14 +568,14 @@ int parse_chan_pair(char *str, struct line *line, int device, | |||
599 | in = str; | 568 | in = str; |
600 | *out = '\0'; | 569 | *out = '\0'; |
601 | out++; | 570 | out++; |
602 | new = parse_chan(line, in, device, opts); | 571 | new = parse_chan(line, in, device, opts, error_out); |
603 | if(new == NULL) | 572 | if(new == NULL) |
604 | return -1; | 573 | return -1; |
605 | 574 | ||
606 | new->input = 1; | 575 | new->input = 1; |
607 | list_add(&new->list, chans); | 576 | list_add(&new->list, chans); |
608 | 577 | ||
609 | new = parse_chan(line, out, device, opts); | 578 | new = parse_chan(line, out, device, opts, error_out); |
610 | if(new == NULL) | 579 | if(new == NULL) |
611 | return -1; | 580 | return -1; |
612 | 581 | ||
@@ -614,7 +583,7 @@ int parse_chan_pair(char *str, struct line *line, int device, | |||
614 | new->output = 1; | 583 | new->output = 1; |
615 | } | 584 | } |
616 | else { | 585 | else { |
617 | new = parse_chan(line, str, device, opts); | 586 | new = parse_chan(line, str, device, opts, error_out); |
618 | if(new == NULL) | 587 | if(new == NULL) |
619 | return -1; | 588 | return -1; |
620 | 589 | ||