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