summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/console.c59
-rw-r--r--common/iomux.c75
-rw-r--r--common/stdio.c57
-rw-r--r--common/usb_kbd.c16
4 files changed, 116 insertions, 91 deletions
diff --git a/common/console.c b/common/console.c
index 567273a0ce8..561cdf36a74 100644
--- a/common/console.c
+++ b/common/console.c
@@ -233,9 +233,10 @@ static struct stdio_dev *tstcdev;
struct stdio_dev **console_devices[MAX_FILES];
int cd_count[MAX_FILES];
-static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev)
+static void console_devices_set(int file, struct stdio_dev *dev)
{
console_devices[file][0] = dev;
+ cd_count[file] = 1;
}
/**
@@ -251,15 +252,14 @@ static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev)
*/
static bool console_needs_start_stop(int file, struct stdio_dev *sdev)
{
- int i, j;
+ int i;
for (i = 0; i < ARRAY_SIZE(cd_count); i++) {
if (i == file)
continue;
- for (j = 0; j < cd_count[i]; j++)
- if (console_devices[i][j] == sdev)
- return false;
+ if (iomux_match_device(console_devices[i], cd_count[i], sdev) >= 0)
+ return false;
}
return true;
}
@@ -293,8 +293,7 @@ static int console_tstc(int file)
int prev;
prev = disable_ctrlc(1);
- for (i = 0; i < cd_count[file]; i++) {
- dev = console_devices[file][i];
+ for_each_console_dev(i, file, dev) {
if (dev->tstc != NULL) {
ret = dev->tstc(dev);
if (ret > 0) {
@@ -314,8 +313,7 @@ static void console_putc(int file, const char c)
int i;
struct stdio_dev *dev;
- for (i = 0; i < cd_count[file]; i++) {
- dev = console_devices[file][i];
+ for_each_console_dev(i, file, dev) {
if (dev->putc != NULL)
dev->putc(dev, c);
}
@@ -334,11 +332,9 @@ static void console_puts_select(int file, bool serial_only, const char *s)
int i;
struct stdio_dev *dev;
- for (i = 0; i < cd_count[file]; i++) {
- bool is_serial;
+ for_each_console_dev(i, file, dev) {
+ bool is_serial = console_dev_is_serial(dev);
- dev = console_devices[file][i];
- is_serial = console_dev_is_serial(dev);
if (dev->puts && serial_only == is_serial)
dev->puts(dev, s);
}
@@ -354,8 +350,7 @@ static void console_puts(int file, const char *s)
int i;
struct stdio_dev *dev;
- for (i = 0; i < cd_count[file]; i++) {
- dev = console_devices[file][i];
+ for_each_console_dev(i, file, dev) {
if (dev->puts != NULL)
dev->puts(dev, s);
}
@@ -369,7 +364,7 @@ static inline void console_doenv(int file, struct stdio_dev *dev)
#endif
#else
-static void __maybe_unused console_devices_set(int file, struct stdio_dev *dev)
+static void console_devices_set(int file, struct stdio_dev *dev)
{
}
@@ -417,6 +412,12 @@ static inline void console_doenv(int file, struct stdio_dev *dev)
#endif
#endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
+static void __maybe_unused console_setfile_and_devices(int file, struct stdio_dev *dev)
+{
+ console_setfile(file, dev);
+ console_devices_set(file, dev);
+}
+
int console_start(int file, struct stdio_dev *sdev)
{
int error;
@@ -855,17 +856,9 @@ int console_assign(int file, const char *devname)
struct stdio_dev *dev;
/* Check for valid file */
- switch (file) {
- case stdin:
- flag = DEV_FLAGS_INPUT;
- break;
- case stdout:
- case stderr:
- flag = DEV_FLAGS_OUTPUT;
- break;
- default:
- return -1;
- }
+ flag = stdio_file_to_flags(file);
+ if (flag < 0)
+ return flag;
/* Check for valid device name */
@@ -1079,17 +1072,13 @@ int console_init_r(void)
/* Initializes output console first */
if (outputdev != NULL) {
- console_setfile(stdout, outputdev);
- console_setfile(stderr, outputdev);
- console_devices_set(stdout, outputdev);
- console_devices_set(stderr, outputdev);
+ console_setfile_and_devices(stdout, outputdev);
+ console_setfile_and_devices(stderr, outputdev);
}
/* Initializes input console */
- if (inputdev != NULL) {
- console_setfile(stdin, inputdev);
- console_devices_set(stdin, inputdev);
- }
+ if (inputdev != NULL)
+ console_setfile_and_devices(stdin, inputdev);
if (!IS_ENABLED(CONFIG_SYS_CONSOLE_INFO_QUIET))
stdio_print_current_devices();
diff --git a/common/iomux.c b/common/iomux.c
index 15bf5338855..b9088aa3b58 100644
--- a/common/iomux.c
+++ b/common/iomux.c
@@ -15,18 +15,26 @@ void iomux_printdevs(const int console)
int i;
struct stdio_dev *dev;
- for (i = 0; i < cd_count[console]; i++) {
- dev = console_devices[console][i];
+ for_each_console_dev(i, console, dev)
printf("%s ", dev->name);
- }
printf("\n");
}
+int iomux_match_device(struct stdio_dev **set, const int n, struct stdio_dev *sdev)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ if (sdev == set[i])
+ return i;
+ return -ENOENT;
+}
+
/* This tries to preserve the old list if an error occurs. */
int iomux_doenv(const int console, const char *arg)
{
char *console_args, *temp, **start;
- int i, j, k, io_flag, cs_idx, repeat;
+ int i, j, io_flag, cs_idx, repeat;
struct stdio_dev **cons_set, **old_set;
struct stdio_dev *dev;
@@ -75,15 +83,8 @@ int iomux_doenv(const int console, const char *arg)
return 1;
}
- switch (console) {
- case stdin:
- io_flag = DEV_FLAGS_INPUT;
- break;
- case stdout:
- case stderr:
- io_flag = DEV_FLAGS_OUTPUT;
- break;
- default:
+ io_flag = stdio_file_to_flags(console);
+ if (io_flag < 0) {
free(start);
free(console_args);
free(cons_set);
@@ -103,14 +104,8 @@ int iomux_doenv(const int console, const char *arg)
/*
* Prevent multiple entries for a device.
*/
- repeat = 0;
- for (k = 0; k < cs_idx; k++) {
- if (dev == cons_set[k]) {
- repeat++;
- break;
- }
- }
- if (repeat)
+ repeat = iomux_match_device(cons_set, cs_idx, dev);
+ if (repeat >= 0)
continue;
/*
* Try assigning the specified device.
@@ -136,10 +131,7 @@ int iomux_doenv(const int console, const char *arg)
/* Stop dropped consoles */
for (i = 0; i < repeat; i++) {
- for (j = 0; j < cs_idx; j++) {
- if (old_set[i] == cons_set[j])
- break;
- }
+ j = iomux_match_device(cons_set, cs_idx, old_set[i]);
if (j == cs_idx)
console_stop(console, old_set[i]);
}
@@ -147,4 +139,37 @@ int iomux_doenv(const int console, const char *arg)
free(old_set);
return 0;
}
+
+int iomux_replace_device(const int console, const char *old, const char *new)
+{
+ struct stdio_dev *dev;
+ char *arg = NULL; /* Initial empty list */
+ int size = 1; /* For NUL terminator */
+ int i, ret;
+
+ for_each_console_dev(i, console, dev) {
+ const char *name = strcmp(dev->name, old) ? dev->name : new;
+ char *tmp;
+
+ /* Append name with a ',' (comma) separator */
+ tmp = realloc(arg, size + strlen(name) + 1);
+ if (!tmp) {
+ free(arg);
+ return -ENOMEM;
+ }
+
+ strcat(tmp, ",");
+ strcat(tmp, name);
+
+ arg = tmp;
+ size = strlen(tmp) + 1;
+ }
+
+ ret = iomux_doenv(console, arg);
+ if (ret)
+ ret = -EINVAL;
+
+ free(arg);
+ return ret;
+}
#endif /* CONSOLE_MUX */
diff --git a/common/stdio.c b/common/stdio.c
index 2b883fddbea..d4acc5256c1 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -28,6 +28,20 @@ static struct stdio_dev devs;
struct stdio_dev *stdio_devices[] = { NULL, NULL, NULL };
char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
+int stdio_file_to_flags(const int file)
+{
+ switch (file) {
+ case stdin:
+ return DEV_FLAGS_INPUT;
+ case stdout:
+ case stderr:
+ return DEV_FLAGS_OUTPUT;
+ default:
+ return -EINVAL;
+ }
+}
+
+#if CONFIG_IS_ENABLED(SYS_DEVICE_NULLDEV)
static void nulldev_putc(struct stdio_dev *dev, const char c)
{
/* nulldev is empty! */
@@ -44,6 +58,25 @@ static int nulldev_input(struct stdio_dev *dev)
return 0;
}
+static void nulldev_register(void)
+{
+ struct stdio_dev dev;
+
+ memset(&dev, '\0', sizeof(dev));
+
+ strcpy(dev.name, "nulldev");
+ dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
+ dev.putc = nulldev_putc;
+ dev.puts = nulldev_puts;
+ dev.getc = nulldev_input;
+ dev.tstc = nulldev_input;
+
+ stdio_register(&dev);
+}
+#else
+static inline void nulldev_register(void) {}
+#endif /* SYS_DEVICE_NULLDEV */
+
static void stdio_serial_putc(struct stdio_dev *dev, const char c)
{
serial_putc(c);
@@ -83,18 +116,7 @@ static void drv_system_init (void)
dev.tstc = stdio_serial_tstc;
stdio_register (&dev);
- if (CONFIG_IS_ENABLED(SYS_DEVICE_NULLDEV)) {
- memset(&dev, '\0', sizeof(dev));
-
- strcpy(dev.name, "nulldev");
- dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
- dev.putc = nulldev_putc;
- dev.puts = nulldev_puts;
- dev.getc = nulldev_input;
- dev.tstc = nulldev_input;
-
- stdio_register(&dev);
- }
+ nulldev_register();
}
/**************************************************************************
@@ -261,17 +283,6 @@ int stdio_deregister_dev(struct stdio_dev *dev, int force)
return 0;
}
-int stdio_deregister(const char *devname, int force)
-{
- struct stdio_dev *dev;
-
- dev = stdio_get_by_name(devname);
- if (!dev) /* device not found */
- return -ENODEV;
-
- return stdio_deregister_dev(dev, force);
-}
-
int stdio_init_tables(void)
{
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index b316807844b..60c6027e048 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -617,12 +617,12 @@ int usb_kbd_deregister(int force)
if (dev) {
usb_kbd_dev = (struct usb_device *)dev->priv;
data = usb_kbd_dev->privptr;
- if (stdio_deregister_dev(dev, force) != 0)
- return 1;
#if CONFIG_IS_ENABLED(CONSOLE_MUX)
- if (iomux_doenv(stdin, env_get("stdin")) != 0)
+ if (iomux_replace_device(stdin, DEVNAME, force ? "nulldev" : ""))
return 1;
#endif
+ if (stdio_deregister_dev(dev, force) != 0)
+ return 1;
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
destroy_int_queue(usb_kbd_dev, data->intq);
#endif
@@ -660,16 +660,16 @@ static int usb_kbd_remove(struct udevice *dev)
goto err;
}
data = udev->privptr;
- if (stdio_deregister_dev(sdev, true)) {
- ret = -EPERM;
- goto err;
- }
#if CONFIG_IS_ENABLED(CONSOLE_MUX)
- if (iomux_doenv(stdin, env_get("stdin"))) {
+ if (iomux_replace_device(stdin, DEVNAME, "nulldev")) {
ret = -ENOLINK;
goto err;
}
#endif
+ if (stdio_deregister_dev(sdev, true)) {
+ ret = -EPERM;
+ goto err;
+ }
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
destroy_int_queue(udev, data->intq);
#endif