diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/console.c | 59 | ||||
| -rw-r--r-- | common/iomux.c | 75 | ||||
| -rw-r--r-- | common/stdio.c | 57 | ||||
| -rw-r--r-- | common/usb_kbd.c | 16 |
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 |
