Commit | Line | Data |
---|---|---|
16a28ef2 GJ |
1 | /* |
2 | * (C) Copyright 2008 | |
3 | * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. | |
4 | * | |
3765b3e7 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
16a28ef2 GJ |
6 | */ |
7 | ||
8 | #include <common.h> | |
24b852a7 | 9 | #include <console.h> |
16a28ef2 GJ |
10 | #include <serial.h> |
11 | #include <malloc.h> | |
12 | ||
13 | #ifdef CONFIG_CONSOLE_MUX | |
14 | void iomux_printdevs(const int console) | |
15 | { | |
16 | int i; | |
52cb4d4f | 17 | struct stdio_dev *dev; |
16a28ef2 GJ |
18 | |
19 | for (i = 0; i < cd_count[console]; i++) { | |
20 | dev = console_devices[console][i]; | |
21 | printf("%s ", dev->name); | |
22 | } | |
23 | printf("\n"); | |
24 | } | |
25 | ||
26 | /* This tries to preserve the old list if an error occurs. */ | |
27 | int iomux_doenv(const int console, const char *arg) | |
28 | { | |
29 | char *console_args, *temp, **start; | |
30 | int i, j, k, io_flag, cs_idx, repeat; | |
52cb4d4f JCPV |
31 | struct stdio_dev *dev; |
32 | struct stdio_dev **cons_set; | |
16a28ef2 GJ |
33 | |
34 | console_args = strdup(arg); | |
35 | if (console_args == NULL) | |
36 | return 1; | |
37 | /* | |
38 | * Check whether a comma separated list of devices was | |
39 | * entered and count how many devices were entered. | |
40 | * The array start[] has pointers to the beginning of | |
41 | * each device name (up to MAX_CONSARGS devices). | |
42 | * | |
43 | * Have to do this twice - once to count the number of | |
44 | * commas and then again to populate start. | |
45 | */ | |
46 | i = 0; | |
47 | temp = console_args; | |
48 | for (;;) { | |
49 | temp = strchr(temp, ','); | |
50 | if (temp != NULL) { | |
51 | i++; | |
52 | temp++; | |
53 | continue; | |
54 | } | |
55 | /* There's always one entry more than the number of commas. */ | |
56 | i++; | |
57 | break; | |
58 | } | |
59 | start = (char **)malloc(i * sizeof(char *)); | |
60 | if (start == NULL) { | |
61 | free(console_args); | |
62 | return 1; | |
63 | } | |
64 | i = 0; | |
65 | start[0] = console_args; | |
66 | for (;;) { | |
67 | temp = strchr(start[i++], ','); | |
68 | if (temp == NULL) | |
69 | break; | |
70 | *temp = '\0'; | |
71 | start[i] = temp + 1; | |
72 | } | |
52cb4d4f | 73 | cons_set = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *)); |
16a28ef2 GJ |
74 | if (cons_set == NULL) { |
75 | free(start); | |
76 | free(console_args); | |
77 | return 1; | |
78 | } | |
79 | ||
80 | switch (console) { | |
81 | case stdin: | |
82 | io_flag = DEV_FLAGS_INPUT; | |
83 | break; | |
84 | case stdout: | |
85 | case stderr: | |
86 | io_flag = DEV_FLAGS_OUTPUT; | |
87 | break; | |
88 | default: | |
89 | free(start); | |
90 | free(console_args); | |
91 | free(cons_set); | |
92 | return 1; | |
93 | } | |
94 | ||
95 | cs_idx = 0; | |
96 | for (j = 0; j < i; j++) { | |
97 | /* | |
98 | * Check whether the device exists and is valid. | |
99 | * console_assign() also calls search_device(), | |
100 | * but I need the pointer to the device. | |
101 | */ | |
102 | dev = search_device(io_flag, start[j]); | |
103 | if (dev == NULL) | |
104 | continue; | |
105 | /* | |
106 | * Prevent multiple entries for a device. | |
107 | */ | |
108 | repeat = 0; | |
109 | for (k = 0; k < cs_idx; k++) { | |
110 | if (dev == cons_set[k]) { | |
111 | repeat++; | |
112 | break; | |
113 | } | |
114 | } | |
115 | if (repeat) | |
116 | continue; | |
117 | /* | |
118 | * Try assigning the specified device. | |
119 | * This could screw up the console settings for apps. | |
120 | */ | |
121 | if (console_assign(console, start[j]) < 0) | |
122 | continue; | |
16a28ef2 GJ |
123 | cons_set[cs_idx++] = dev; |
124 | } | |
125 | free(console_args); | |
126 | free(start); | |
127 | /* failed to set any console */ | |
128 | if (cs_idx == 0) { | |
129 | free(cons_set); | |
130 | return 1; | |
131 | } else { | |
132 | /* Works even if console_devices[console] is NULL. */ | |
133 | console_devices[console] = | |
52cb4d4f JCPV |
134 | (struct stdio_dev **)realloc(console_devices[console], |
135 | cs_idx * sizeof(struct stdio_dev *)); | |
16a28ef2 GJ |
136 | if (console_devices[console] == NULL) { |
137 | free(cons_set); | |
138 | return 1; | |
139 | } | |
140 | memcpy(console_devices[console], cons_set, cs_idx * | |
52cb4d4f | 141 | sizeof(struct stdio_dev *)); |
16a28ef2 GJ |
142 | |
143 | cd_count[console] = cs_idx; | |
144 | } | |
145 | free(cons_set); | |
146 | return 0; | |
147 | } | |
148 | #endif /* CONFIG_CONSOLE_MUX */ |