blob: 15bf53388559a0035f857f8ca614864be4925dee [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Gary Jennejohn16a28ef2008-11-06 15:04:23 +01002/*
3 * (C) Copyright 2008
4 * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
Gary Jennejohn16a28ef2008-11-06 15:04:23 +01005 */
6
7#include <common.h>
Simon Glass24b852a2015-11-08 23:47:45 -07008#include <console.h>
Gary Jennejohn16a28ef2008-11-06 15:04:23 +01009#include <serial.h>
10#include <malloc.h>
11
Simon Glassb0265422017-01-16 07:03:26 -070012#if CONFIG_IS_ENABLED(CONSOLE_MUX)
Gary Jennejohn16a28ef2008-11-06 15:04:23 +010013void iomux_printdevs(const int console)
14{
15 int i;
Jean-Christophe PLAGNIOL-VILLARD52cb4d42009-05-16 12:14:54 +020016 struct stdio_dev *dev;
Gary Jennejohn16a28ef2008-11-06 15:04:23 +010017
18 for (i = 0; i < cd_count[console]; i++) {
19 dev = console_devices[console][i];
20 printf("%s ", dev->name);
21 }
22 printf("\n");
23}
24
25/* This tries to preserve the old list if an error occurs. */
26int iomux_doenv(const int console, const char *arg)
27{
28 char *console_args, *temp, **start;
29 int i, j, k, io_flag, cs_idx, repeat;
Andy Shevchenko70c25252020-12-21 14:30:08 +020030 struct stdio_dev **cons_set, **old_set;
Jean-Christophe PLAGNIOL-VILLARD52cb4d42009-05-16 12:14:54 +020031 struct stdio_dev *dev;
Gary Jennejohn16a28ef2008-11-06 15:04:23 +010032
33 console_args = strdup(arg);
34 if (console_args == NULL)
35 return 1;
36 /*
37 * Check whether a comma separated list of devices was
38 * entered and count how many devices were entered.
39 * The array start[] has pointers to the beginning of
40 * each device name (up to MAX_CONSARGS devices).
41 *
42 * Have to do this twice - once to count the number of
43 * commas and then again to populate start.
44 */
45 i = 0;
46 temp = console_args;
47 for (;;) {
Gary Jennejohn16a28ef2008-11-06 15:04:23 +010048 /* There's always one entry more than the number of commas. */
49 i++;
Andy Shevchenkoc939e1c2020-12-21 14:30:06 +020050
51 temp = strchr(temp, ',');
52 if (temp == NULL)
53 break;
54
55 temp++;
Gary Jennejohn16a28ef2008-11-06 15:04:23 +010056 }
57 start = (char **)malloc(i * sizeof(char *));
58 if (start == NULL) {
59 free(console_args);
60 return 1;
61 }
62 i = 0;
63 start[0] = console_args;
64 for (;;) {
65 temp = strchr(start[i++], ',');
66 if (temp == NULL)
67 break;
68 *temp = '\0';
69 start[i] = temp + 1;
70 }
Jean-Christophe PLAGNIOL-VILLARD52cb4d42009-05-16 12:14:54 +020071 cons_set = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *));
Gary Jennejohn16a28ef2008-11-06 15:04:23 +010072 if (cons_set == NULL) {
73 free(start);
74 free(console_args);
75 return 1;
76 }
77
78 switch (console) {
79 case stdin:
80 io_flag = DEV_FLAGS_INPUT;
81 break;
82 case stdout:
83 case stderr:
84 io_flag = DEV_FLAGS_OUTPUT;
85 break;
86 default:
87 free(start);
88 free(console_args);
89 free(cons_set);
90 return 1;
91 }
92
93 cs_idx = 0;
94 for (j = 0; j < i; j++) {
95 /*
96 * Check whether the device exists and is valid.
Andy Shevchenko32324872020-12-21 14:30:03 +020097 * console_assign() also calls console_search_dev(),
Gary Jennejohn16a28ef2008-11-06 15:04:23 +010098 * but I need the pointer to the device.
99 */
Andy Shevchenko32324872020-12-21 14:30:03 +0200100 dev = console_search_dev(io_flag, start[j]);
Gary Jennejohn16a28ef2008-11-06 15:04:23 +0100101 if (dev == NULL)
102 continue;
103 /*
104 * Prevent multiple entries for a device.
105 */
106 repeat = 0;
107 for (k = 0; k < cs_idx; k++) {
108 if (dev == cons_set[k]) {
109 repeat++;
110 break;
111 }
112 }
113 if (repeat)
114 continue;
115 /*
116 * Try assigning the specified device.
117 * This could screw up the console settings for apps.
118 */
119 if (console_assign(console, start[j]) < 0)
120 continue;
Gary Jennejohn16a28ef2008-11-06 15:04:23 +0100121 cons_set[cs_idx++] = dev;
122 }
123 free(console_args);
124 free(start);
125 /* failed to set any console */
126 if (cs_idx == 0) {
127 free(cons_set);
128 return 1;
Gary Jennejohn16a28ef2008-11-06 15:04:23 +0100129 }
Andy Shevchenko420782c2020-12-21 14:30:07 +0200130
Andy Shevchenko70c25252020-12-21 14:30:08 +0200131 old_set = console_devices[console];
132 repeat = cd_count[console];
133
Andy Shevchenko420782c2020-12-21 14:30:07 +0200134 console_devices[console] = cons_set;
135 cd_count[console] = cs_idx;
Andy Shevchenko70c25252020-12-21 14:30:08 +0200136
137 /* Stop dropped consoles */
138 for (i = 0; i < repeat; i++) {
139 for (j = 0; j < cs_idx; j++) {
140 if (old_set[i] == cons_set[j])
141 break;
142 }
143 if (j == cs_idx)
144 console_stop(console, old_set[i]);
145 }
146
147 free(old_set);
Gary Jennejohn16a28ef2008-11-06 15:04:23 +0100148 return 0;
149}
Simon Glassb0265422017-01-16 07:03:26 -0700150#endif /* CONSOLE_MUX */