summaryrefslogtreecommitdiffstats
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.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 14a12d6b3df..5b58fad4529 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -19,18 +19,44 @@
#include "line.h"
#include "os.h"
-#ifdef CONFIG_NOCONFIG_CHAN
+/* XXX: could well be moved to somewhere else, if needed. */
+static int my_printf(const char * fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+static int my_printf(const char * fmt, ...)
+{
+ /* Yes, can be called on atomic context.*/
+ char *buf = kmalloc(4096, GFP_ATOMIC);
+ va_list args;
+ int r;
+
+ if (!buf) {
+ /* We print directly fmt.
+ * Yes, yes, yes, feel free to complain. */
+ r = strlen(fmt);
+ } else {
+ va_start(args, fmt);
+ r = vsprintf(buf, fmt, args);
+ va_end(args);
+ fmt = buf;
+ }
-/* The printk's here are wrong because we are complaining that there is no
- * output device, but printk is printing to that output device. The user will
- * never see the error. printf would be better, except it can't run on a
- * kernel stack because it will overflow it.
- * Use printk for now since that will avoid crashing.
- */
+ if (r)
+ r = os_write_file(1, fmt, r);
+ return r;
+
+}
+
+#ifdef CONFIG_NOCONFIG_CHAN
+/* Despite its name, there's no added trailing newline. */
+static int my_puts(const char * buf)
+{
+ return os_write_file(1, buf, strlen(buf));
+}
static void *not_configged_init(char *str, int device, struct chan_opts *opts)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(NULL);
}
@@ -38,35 +64,34 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
static int not_configged_open(int input, int output, int primary, void *data,
char **dev_out)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_close(int fd, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
}
static int not_configged_read(int fd, char *c_out, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
static int not_configged_write(int fd, const char *buf, int len, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
-static int not_configged_console_write(int fd, const char *buf, int len,
- void *data)
+static int not_configged_console_write(int fd, const char *buf, int len)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@@ -74,14 +99,14 @@ static int not_configged_console_write(int fd, const char *buf, int len,
static int not_configged_window_size(int fd, void *data, unsigned short *rows,
unsigned short *cols)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_free(void *data)
{
- printf(KERN_ERR "Using a channel type which is configured out of "
+ my_puts("Using a channel type which is configured out of "
"UML\n");
}
@@ -273,7 +298,7 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
chan = list_entry(ele, struct chan, list);
if(!chan->output || (chan->ops->console_write == NULL))
continue;
- n = chan->ops->console_write(chan->fd, buf, len, chan->data);
+ n = chan->ops->console_write(chan->fd, buf, len);
if(chan->primary) ret = n;
}
return(ret);
@@ -457,7 +482,7 @@ static struct chan *parse_chan(char *str, int pri, int device,
}
}
if(ops == NULL){
- printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n",
+ my_printf("parse_chan couldn't parse \"%s\"\n",
str);
return(NULL);
}
@@ -465,7 +490,7 @@ static struct chan *parse_chan(char *str, int pri, int device,
data = (*ops->init)(str, device, opts);
if(data == NULL) return(NULL);
- chan = kmalloc(sizeof(*chan), GFP_KERNEL);
+ chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
if(chan == NULL) return(NULL);
*chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list),
.primary = 1,