| /* |
| * (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; |
| struct stdio_dev *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; |
| struct stdio_dev *dev; |
| struct stdio_dev **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 = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *)); |
| 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; |
| /* |
| * 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; |
| 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] = |
| (struct stdio_dev **)realloc(console_devices[console], |
| cs_idx * sizeof(struct stdio_dev *)); |
| if (console_devices[console] == NULL) { |
| free(cons_set); |
| return 1; |
| } |
| memcpy(console_devices[console], cons_set, cs_idx * |
| sizeof(struct stdio_dev *)); |
| |
| cd_count[console] = cs_idx; |
| } |
| free(cons_set); |
| return 0; |
| } |
| #endif /* CONFIG_CONSOLE_MUX */ |