1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
216a28ef2SGary Jennejohn /*
316a28ef2SGary Jennejohn * (C) Copyright 2008
416a28ef2SGary Jennejohn * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
516a28ef2SGary Jennejohn */
616a28ef2SGary Jennejohn
716a28ef2SGary Jennejohn #include <common.h>
824b852a7SSimon Glass #include <console.h>
916a28ef2SGary Jennejohn #include <serial.h>
1016a28ef2SGary Jennejohn #include <malloc.h>
1116a28ef2SGary Jennejohn
12b0265429SSimon Glass #if CONFIG_IS_ENABLED(CONSOLE_MUX)
iomux_printdevs(const int console)1316a28ef2SGary Jennejohn void iomux_printdevs(const int console)
1416a28ef2SGary Jennejohn {
1516a28ef2SGary Jennejohn int i;
1652cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev;
1716a28ef2SGary Jennejohn
1816a28ef2SGary Jennejohn for (i = 0; i < cd_count[console]; i++) {
1916a28ef2SGary Jennejohn dev = console_devices[console][i];
2016a28ef2SGary Jennejohn printf("%s ", dev->name);
2116a28ef2SGary Jennejohn }
2216a28ef2SGary Jennejohn printf("\n");
2316a28ef2SGary Jennejohn }
2416a28ef2SGary Jennejohn
2516a28ef2SGary Jennejohn /* This tries to preserve the old list if an error occurs. */
iomux_doenv(const int console,const char * arg)2616a28ef2SGary Jennejohn int iomux_doenv(const int console, const char *arg)
2716a28ef2SGary Jennejohn {
2816a28ef2SGary Jennejohn char *console_args, *temp, **start;
2916a28ef2SGary Jennejohn int i, j, k, io_flag, cs_idx, repeat;
3052cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev;
3152cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev **cons_set;
3216a28ef2SGary Jennejohn
3316a28ef2SGary Jennejohn console_args = strdup(arg);
3416a28ef2SGary Jennejohn if (console_args == NULL)
3516a28ef2SGary Jennejohn return 1;
3616a28ef2SGary Jennejohn /*
3716a28ef2SGary Jennejohn * Check whether a comma separated list of devices was
3816a28ef2SGary Jennejohn * entered and count how many devices were entered.
3916a28ef2SGary Jennejohn * The array start[] has pointers to the beginning of
4016a28ef2SGary Jennejohn * each device name (up to MAX_CONSARGS devices).
4116a28ef2SGary Jennejohn *
4216a28ef2SGary Jennejohn * Have to do this twice - once to count the number of
4316a28ef2SGary Jennejohn * commas and then again to populate start.
4416a28ef2SGary Jennejohn */
4516a28ef2SGary Jennejohn i = 0;
4616a28ef2SGary Jennejohn temp = console_args;
4716a28ef2SGary Jennejohn for (;;) {
4816a28ef2SGary Jennejohn temp = strchr(temp, ',');
4916a28ef2SGary Jennejohn if (temp != NULL) {
5016a28ef2SGary Jennejohn i++;
5116a28ef2SGary Jennejohn temp++;
5216a28ef2SGary Jennejohn continue;
5316a28ef2SGary Jennejohn }
5416a28ef2SGary Jennejohn /* There's always one entry more than the number of commas. */
5516a28ef2SGary Jennejohn i++;
5616a28ef2SGary Jennejohn break;
5716a28ef2SGary Jennejohn }
5816a28ef2SGary Jennejohn start = (char **)malloc(i * sizeof(char *));
5916a28ef2SGary Jennejohn if (start == NULL) {
6016a28ef2SGary Jennejohn free(console_args);
6116a28ef2SGary Jennejohn return 1;
6216a28ef2SGary Jennejohn }
6316a28ef2SGary Jennejohn i = 0;
6416a28ef2SGary Jennejohn start[0] = console_args;
6516a28ef2SGary Jennejohn for (;;) {
6616a28ef2SGary Jennejohn temp = strchr(start[i++], ',');
6716a28ef2SGary Jennejohn if (temp == NULL)
6816a28ef2SGary Jennejohn break;
6916a28ef2SGary Jennejohn *temp = '\0';
7016a28ef2SGary Jennejohn start[i] = temp + 1;
7116a28ef2SGary Jennejohn }
7252cb4d4fSJean-Christophe PLAGNIOL-VILLARD cons_set = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *));
7316a28ef2SGary Jennejohn if (cons_set == NULL) {
7416a28ef2SGary Jennejohn free(start);
7516a28ef2SGary Jennejohn free(console_args);
7616a28ef2SGary Jennejohn return 1;
7716a28ef2SGary Jennejohn }
7816a28ef2SGary Jennejohn
7916a28ef2SGary Jennejohn switch (console) {
8016a28ef2SGary Jennejohn case stdin:
8116a28ef2SGary Jennejohn io_flag = DEV_FLAGS_INPUT;
8216a28ef2SGary Jennejohn break;
8316a28ef2SGary Jennejohn case stdout:
8416a28ef2SGary Jennejohn case stderr:
8516a28ef2SGary Jennejohn io_flag = DEV_FLAGS_OUTPUT;
8616a28ef2SGary Jennejohn break;
8716a28ef2SGary Jennejohn default:
8816a28ef2SGary Jennejohn free(start);
8916a28ef2SGary Jennejohn free(console_args);
9016a28ef2SGary Jennejohn free(cons_set);
9116a28ef2SGary Jennejohn return 1;
9216a28ef2SGary Jennejohn }
9316a28ef2SGary Jennejohn
9416a28ef2SGary Jennejohn cs_idx = 0;
9516a28ef2SGary Jennejohn for (j = 0; j < i; j++) {
9616a28ef2SGary Jennejohn /*
9716a28ef2SGary Jennejohn * Check whether the device exists and is valid.
9816a28ef2SGary Jennejohn * console_assign() also calls search_device(),
9916a28ef2SGary Jennejohn * but I need the pointer to the device.
10016a28ef2SGary Jennejohn */
10116a28ef2SGary Jennejohn dev = search_device(io_flag, start[j]);
10216a28ef2SGary Jennejohn if (dev == NULL)
10316a28ef2SGary Jennejohn continue;
10416a28ef2SGary Jennejohn /*
10516a28ef2SGary Jennejohn * Prevent multiple entries for a device.
10616a28ef2SGary Jennejohn */
10716a28ef2SGary Jennejohn repeat = 0;
10816a28ef2SGary Jennejohn for (k = 0; k < cs_idx; k++) {
10916a28ef2SGary Jennejohn if (dev == cons_set[k]) {
11016a28ef2SGary Jennejohn repeat++;
11116a28ef2SGary Jennejohn break;
11216a28ef2SGary Jennejohn }
11316a28ef2SGary Jennejohn }
11416a28ef2SGary Jennejohn if (repeat)
11516a28ef2SGary Jennejohn continue;
11616a28ef2SGary Jennejohn /*
11716a28ef2SGary Jennejohn * Try assigning the specified device.
11816a28ef2SGary Jennejohn * This could screw up the console settings for apps.
11916a28ef2SGary Jennejohn */
12016a28ef2SGary Jennejohn if (console_assign(console, start[j]) < 0)
12116a28ef2SGary Jennejohn continue;
12216a28ef2SGary Jennejohn cons_set[cs_idx++] = dev;
12316a28ef2SGary Jennejohn }
12416a28ef2SGary Jennejohn free(console_args);
12516a28ef2SGary Jennejohn free(start);
12616a28ef2SGary Jennejohn /* failed to set any console */
12716a28ef2SGary Jennejohn if (cs_idx == 0) {
12816a28ef2SGary Jennejohn free(cons_set);
12916a28ef2SGary Jennejohn return 1;
13016a28ef2SGary Jennejohn } else {
13116a28ef2SGary Jennejohn /* Works even if console_devices[console] is NULL. */
13216a28ef2SGary Jennejohn console_devices[console] =
13352cb4d4fSJean-Christophe PLAGNIOL-VILLARD (struct stdio_dev **)realloc(console_devices[console],
13452cb4d4fSJean-Christophe PLAGNIOL-VILLARD cs_idx * sizeof(struct stdio_dev *));
13516a28ef2SGary Jennejohn if (console_devices[console] == NULL) {
13616a28ef2SGary Jennejohn free(cons_set);
13716a28ef2SGary Jennejohn return 1;
13816a28ef2SGary Jennejohn }
13916a28ef2SGary Jennejohn memcpy(console_devices[console], cons_set, cs_idx *
14052cb4d4fSJean-Christophe PLAGNIOL-VILLARD sizeof(struct stdio_dev *));
14116a28ef2SGary Jennejohn
14216a28ef2SGary Jennejohn cd_count[console] = cs_idx;
14316a28ef2SGary Jennejohn }
14416a28ef2SGary Jennejohn free(cons_set);
14516a28ef2SGary Jennejohn return 0;
14616a28ef2SGary Jennejohn }
147b0265429SSimon Glass #endif /* CONSOLE_MUX */
148