/* * (C) Copyright 2008 * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include <common.h> #include <serial.h> #include <malloc.h> #ifdef CONFIG_CONSOLE_MUX void iomux_printdevs(const int console) { int i; device_t *dev; for (i = 0; i < cd_count[console]; i++) { dev = console_devices[console][i]; printf("%s ", dev->name); } printf("\n"); } /* This tries to preserve the old list if an error occurs. */ int iomux_doenv(const int console, const char *arg) { char *console_args, *temp, **start; int i, j, k, io_flag, cs_idx, repeat; device_t *dev; device_t **cons_set; console_args = strdup(arg); if (console_args == NULL) return 1; /* * Check whether a comma separated list of devices was * entered and count how many devices were entered. * The array start[] has pointers to the beginning of * each device name (up to MAX_CONSARGS devices). * * Have to do this twice - once to count the number of * commas and then again to populate start. */ i = 0; temp = console_args; for (;;) { temp = strchr(temp, ','); if (temp != NULL) { i++; temp++; continue; } /* There's always one entry more than the number of commas. */ i++; break; } start = (char **)malloc(i * sizeof(char *)); if (start == NULL) { free(console_args); return 1; } i = 0; start[0] = console_args; for (;;) { temp = strchr(start[i++], ','); if (temp == NULL) break; *temp = '\0'; start[i] = temp + 1; } cons_set = (device_t **)calloc(i, sizeof(device_t *)); if (cons_set == NULL) { free(start); free(console_args); return 1; } switch (console) { case stdin: io_flag = DEV_FLAGS_INPUT; break; case stdout: case stderr: io_flag = DEV_FLAGS_OUTPUT; break; default: free(start); free(console_args); free(cons_set); return 1; } cs_idx = 0; for (j = 0; j < i; j++) { /* * Check whether the device exists and is valid. * console_assign() also calls search_device(), * but I need the pointer to the device. */ dev = search_device(io_flag, start[j]); if (dev == NULL) continue; /* * Prevent multiple entries for a device. */ repeat = 0; for (k = 0; k < cs_idx; k++) { if (dev == cons_set[k]) { repeat++; break; } } if (repeat) continue; /* * Try assigning the specified device. * This could screw up the console settings for apps. */ if (console_assign(console, start[j]) < 0) continue; #ifdef CONFIG_SERIAL_MULTI /* * This was taken from common/cmd_nvedit.c. * This will never work because serial_assign() returns * 1 upon error, not -1. * This would almost always return an error anyway because * serial_assign() expects the name of a serial device, like * serial_smc, but the user generally only wants to set serial. */ if (serial_assign(start[j]) < 0) continue; #endif cons_set[cs_idx++] = dev; } free(console_args); free(start); /* failed to set any console */ if (cs_idx == 0) { free(cons_set); return 1; } else { /* Works even if console_devices[console] is NULL. */ console_devices[console] = (device_t **)realloc(console_devices[console], cs_idx * sizeof(device_t *)); if (console_devices[console] == NULL) { free(cons_set); return 1; } memcpy(console_devices[console], cons_set, cs_idx * sizeof(device_t *)); cd_count[console] = cs_idx; } free(cons_set); return 0; } #endif /* CONFIG_CONSOLE_MUX */