]>
Commit | Line | Data |
---|---|---|
16a28ef2 GJ |
1 | /* |
2 | * (C) Copyright 2008 | |
3 | * Gary Jennejohn, DENX Software Engineering GmbH, [email protected]. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | #include <common.h> | |
25 | #include <serial.h> | |
26 | #include <malloc.h> | |
27 | ||
28 | #ifdef CONFIG_CONSOLE_MUX | |
29 | void iomux_printdevs(const int console) | |
30 | { | |
31 | int i; | |
52cb4d4f | 32 | struct stdio_dev *dev; |
16a28ef2 GJ |
33 | |
34 | for (i = 0; i < cd_count[console]; i++) { | |
35 | dev = console_devices[console][i]; | |
36 | printf("%s ", dev->name); | |
37 | } | |
38 | printf("\n"); | |
39 | } | |
40 | ||
41 | /* This tries to preserve the old list if an error occurs. */ | |
42 | int iomux_doenv(const int console, const char *arg) | |
43 | { | |
44 | char *console_args, *temp, **start; | |
45 | int i, j, k, io_flag, cs_idx, repeat; | |
52cb4d4f JCPV |
46 | struct stdio_dev *dev; |
47 | struct stdio_dev **cons_set; | |
16a28ef2 GJ |
48 | |
49 | console_args = strdup(arg); | |
50 | if (console_args == NULL) | |
51 | return 1; | |
52 | /* | |
53 | * Check whether a comma separated list of devices was | |
54 | * entered and count how many devices were entered. | |
55 | * The array start[] has pointers to the beginning of | |
56 | * each device name (up to MAX_CONSARGS devices). | |
57 | * | |
58 | * Have to do this twice - once to count the number of | |
59 | * commas and then again to populate start. | |
60 | */ | |
61 | i = 0; | |
62 | temp = console_args; | |
63 | for (;;) { | |
64 | temp = strchr(temp, ','); | |
65 | if (temp != NULL) { | |
66 | i++; | |
67 | temp++; | |
68 | continue; | |
69 | } | |
70 | /* There's always one entry more than the number of commas. */ | |
71 | i++; | |
72 | break; | |
73 | } | |
74 | start = (char **)malloc(i * sizeof(char *)); | |
75 | if (start == NULL) { | |
76 | free(console_args); | |
77 | return 1; | |
78 | } | |
79 | i = 0; | |
80 | start[0] = console_args; | |
81 | for (;;) { | |
82 | temp = strchr(start[i++], ','); | |
83 | if (temp == NULL) | |
84 | break; | |
85 | *temp = '\0'; | |
86 | start[i] = temp + 1; | |
87 | } | |
52cb4d4f | 88 | cons_set = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *)); |
16a28ef2 GJ |
89 | if (cons_set == NULL) { |
90 | free(start); | |
91 | free(console_args); | |
92 | return 1; | |
93 | } | |
94 | ||
95 | switch (console) { | |
96 | case stdin: | |
97 | io_flag = DEV_FLAGS_INPUT; | |
98 | break; | |
99 | case stdout: | |
100 | case stderr: | |
101 | io_flag = DEV_FLAGS_OUTPUT; | |
102 | break; | |
103 | default: | |
104 | free(start); | |
105 | free(console_args); | |
106 | free(cons_set); | |
107 | return 1; | |
108 | } | |
109 | ||
110 | cs_idx = 0; | |
111 | for (j = 0; j < i; j++) { | |
112 | /* | |
113 | * Check whether the device exists and is valid. | |
114 | * console_assign() also calls search_device(), | |
115 | * but I need the pointer to the device. | |
116 | */ | |
117 | dev = search_device(io_flag, start[j]); | |
118 | if (dev == NULL) | |
119 | continue; | |
120 | /* | |
121 | * Prevent multiple entries for a device. | |
122 | */ | |
123 | repeat = 0; | |
124 | for (k = 0; k < cs_idx; k++) { | |
125 | if (dev == cons_set[k]) { | |
126 | repeat++; | |
127 | break; | |
128 | } | |
129 | } | |
130 | if (repeat) | |
131 | continue; | |
132 | /* | |
133 | * Try assigning the specified device. | |
134 | * This could screw up the console settings for apps. | |
135 | */ | |
136 | if (console_assign(console, start[j]) < 0) | |
137 | continue; | |
138 | #ifdef CONFIG_SERIAL_MULTI | |
139 | /* | |
140 | * This was taken from common/cmd_nvedit.c. | |
141 | * This will never work because serial_assign() returns | |
142 | * 1 upon error, not -1. | |
143 | * This would almost always return an error anyway because | |
144 | * serial_assign() expects the name of a serial device, like | |
145 | * serial_smc, but the user generally only wants to set serial. | |
146 | */ | |
147 | if (serial_assign(start[j]) < 0) | |
148 | continue; | |
149 | #endif | |
150 | cons_set[cs_idx++] = dev; | |
151 | } | |
152 | free(console_args); | |
153 | free(start); | |
154 | /* failed to set any console */ | |
155 | if (cs_idx == 0) { | |
156 | free(cons_set); | |
157 | return 1; | |
158 | } else { | |
159 | /* Works even if console_devices[console] is NULL. */ | |
160 | console_devices[console] = | |
52cb4d4f JCPV |
161 | (struct stdio_dev **)realloc(console_devices[console], |
162 | cs_idx * sizeof(struct stdio_dev *)); | |
16a28ef2 GJ |
163 | if (console_devices[console] == NULL) { |
164 | free(cons_set); | |
165 | return 1; | |
166 | } | |
167 | memcpy(console_devices[console], cons_set, cs_idx * | |
52cb4d4f | 168 | sizeof(struct stdio_dev *)); |
16a28ef2 GJ |
169 | |
170 | cd_count[console] = cs_idx; | |
171 | } | |
172 | free(cons_set); | |
173 | return 0; | |
174 | } | |
175 | #endif /* CONFIG_CONSOLE_MUX */ |