1 /* 2 * (C) Copyright 2008 3 * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. 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; 32 struct stdio_dev *dev; 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; 46 struct stdio_dev *dev; 47 struct stdio_dev **cons_set; 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 } 88 cons_set = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *)); 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] = 161 (struct stdio_dev **)realloc(console_devices[console], 162 cs_idx * sizeof(struct stdio_dev *)); 163 if (console_devices[console] == NULL) { 164 free(cons_set); 165 return 1; 166 } 167 memcpy(console_devices[console], cons_set, cs_idx * 168 sizeof(struct stdio_dev *)); 169 170 cd_count[console] = cs_idx; 171 } 172 free(cons_set); 173 return 0; 174 } 175 #endif /* CONFIG_CONSOLE_MUX */ 176