116a28ef2SGary Jennejohn /* 216a28ef2SGary Jennejohn * (C) Copyright 2008 316a28ef2SGary Jennejohn * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. 416a28ef2SGary Jennejohn * 51a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 616a28ef2SGary Jennejohn */ 716a28ef2SGary Jennejohn 816a28ef2SGary Jennejohn #include <common.h> 924b852a7SSimon Glass #include <console.h> 1016a28ef2SGary Jennejohn #include <serial.h> 1116a28ef2SGary Jennejohn #include <malloc.h> 1216a28ef2SGary Jennejohn 13*b0265429SSimon Glass #if CONFIG_IS_ENABLED(CONSOLE_MUX) 1416a28ef2SGary Jennejohn void iomux_printdevs(const int console) 1516a28ef2SGary Jennejohn { 1616a28ef2SGary Jennejohn int i; 1752cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev; 1816a28ef2SGary Jennejohn 1916a28ef2SGary Jennejohn for (i = 0; i < cd_count[console]; i++) { 2016a28ef2SGary Jennejohn dev = console_devices[console][i]; 2116a28ef2SGary Jennejohn printf("%s ", dev->name); 2216a28ef2SGary Jennejohn } 2316a28ef2SGary Jennejohn printf("\n"); 2416a28ef2SGary Jennejohn } 2516a28ef2SGary Jennejohn 2616a28ef2SGary Jennejohn /* This tries to preserve the old list if an error occurs. */ 2716a28ef2SGary Jennejohn int iomux_doenv(const int console, const char *arg) 2816a28ef2SGary Jennejohn { 2916a28ef2SGary Jennejohn char *console_args, *temp, **start; 3016a28ef2SGary Jennejohn int i, j, k, io_flag, cs_idx, repeat; 3152cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev *dev; 3252cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev **cons_set; 3316a28ef2SGary Jennejohn 3416a28ef2SGary Jennejohn console_args = strdup(arg); 3516a28ef2SGary Jennejohn if (console_args == NULL) 3616a28ef2SGary Jennejohn return 1; 3716a28ef2SGary Jennejohn /* 3816a28ef2SGary Jennejohn * Check whether a comma separated list of devices was 3916a28ef2SGary Jennejohn * entered and count how many devices were entered. 4016a28ef2SGary Jennejohn * The array start[] has pointers to the beginning of 4116a28ef2SGary Jennejohn * each device name (up to MAX_CONSARGS devices). 4216a28ef2SGary Jennejohn * 4316a28ef2SGary Jennejohn * Have to do this twice - once to count the number of 4416a28ef2SGary Jennejohn * commas and then again to populate start. 4516a28ef2SGary Jennejohn */ 4616a28ef2SGary Jennejohn i = 0; 4716a28ef2SGary Jennejohn temp = console_args; 4816a28ef2SGary Jennejohn for (;;) { 4916a28ef2SGary Jennejohn temp = strchr(temp, ','); 5016a28ef2SGary Jennejohn if (temp != NULL) { 5116a28ef2SGary Jennejohn i++; 5216a28ef2SGary Jennejohn temp++; 5316a28ef2SGary Jennejohn continue; 5416a28ef2SGary Jennejohn } 5516a28ef2SGary Jennejohn /* There's always one entry more than the number of commas. */ 5616a28ef2SGary Jennejohn i++; 5716a28ef2SGary Jennejohn break; 5816a28ef2SGary Jennejohn } 5916a28ef2SGary Jennejohn start = (char **)malloc(i * sizeof(char *)); 6016a28ef2SGary Jennejohn if (start == NULL) { 6116a28ef2SGary Jennejohn free(console_args); 6216a28ef2SGary Jennejohn return 1; 6316a28ef2SGary Jennejohn } 6416a28ef2SGary Jennejohn i = 0; 6516a28ef2SGary Jennejohn start[0] = console_args; 6616a28ef2SGary Jennejohn for (;;) { 6716a28ef2SGary Jennejohn temp = strchr(start[i++], ','); 6816a28ef2SGary Jennejohn if (temp == NULL) 6916a28ef2SGary Jennejohn break; 7016a28ef2SGary Jennejohn *temp = '\0'; 7116a28ef2SGary Jennejohn start[i] = temp + 1; 7216a28ef2SGary Jennejohn } 7352cb4d4fSJean-Christophe PLAGNIOL-VILLARD cons_set = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *)); 7416a28ef2SGary Jennejohn if (cons_set == NULL) { 7516a28ef2SGary Jennejohn free(start); 7616a28ef2SGary Jennejohn free(console_args); 7716a28ef2SGary Jennejohn return 1; 7816a28ef2SGary Jennejohn } 7916a28ef2SGary Jennejohn 8016a28ef2SGary Jennejohn switch (console) { 8116a28ef2SGary Jennejohn case stdin: 8216a28ef2SGary Jennejohn io_flag = DEV_FLAGS_INPUT; 8316a28ef2SGary Jennejohn break; 8416a28ef2SGary Jennejohn case stdout: 8516a28ef2SGary Jennejohn case stderr: 8616a28ef2SGary Jennejohn io_flag = DEV_FLAGS_OUTPUT; 8716a28ef2SGary Jennejohn break; 8816a28ef2SGary Jennejohn default: 8916a28ef2SGary Jennejohn free(start); 9016a28ef2SGary Jennejohn free(console_args); 9116a28ef2SGary Jennejohn free(cons_set); 9216a28ef2SGary Jennejohn return 1; 9316a28ef2SGary Jennejohn } 9416a28ef2SGary Jennejohn 9516a28ef2SGary Jennejohn cs_idx = 0; 9616a28ef2SGary Jennejohn for (j = 0; j < i; j++) { 9716a28ef2SGary Jennejohn /* 9816a28ef2SGary Jennejohn * Check whether the device exists and is valid. 9916a28ef2SGary Jennejohn * console_assign() also calls search_device(), 10016a28ef2SGary Jennejohn * but I need the pointer to the device. 10116a28ef2SGary Jennejohn */ 10216a28ef2SGary Jennejohn dev = search_device(io_flag, start[j]); 10316a28ef2SGary Jennejohn if (dev == NULL) 10416a28ef2SGary Jennejohn continue; 10516a28ef2SGary Jennejohn /* 10616a28ef2SGary Jennejohn * Prevent multiple entries for a device. 10716a28ef2SGary Jennejohn */ 10816a28ef2SGary Jennejohn repeat = 0; 10916a28ef2SGary Jennejohn for (k = 0; k < cs_idx; k++) { 11016a28ef2SGary Jennejohn if (dev == cons_set[k]) { 11116a28ef2SGary Jennejohn repeat++; 11216a28ef2SGary Jennejohn break; 11316a28ef2SGary Jennejohn } 11416a28ef2SGary Jennejohn } 11516a28ef2SGary Jennejohn if (repeat) 11616a28ef2SGary Jennejohn continue; 11716a28ef2SGary Jennejohn /* 11816a28ef2SGary Jennejohn * Try assigning the specified device. 11916a28ef2SGary Jennejohn * This could screw up the console settings for apps. 12016a28ef2SGary Jennejohn */ 12116a28ef2SGary Jennejohn if (console_assign(console, start[j]) < 0) 12216a28ef2SGary Jennejohn continue; 12316a28ef2SGary Jennejohn cons_set[cs_idx++] = dev; 12416a28ef2SGary Jennejohn } 12516a28ef2SGary Jennejohn free(console_args); 12616a28ef2SGary Jennejohn free(start); 12716a28ef2SGary Jennejohn /* failed to set any console */ 12816a28ef2SGary Jennejohn if (cs_idx == 0) { 12916a28ef2SGary Jennejohn free(cons_set); 13016a28ef2SGary Jennejohn return 1; 13116a28ef2SGary Jennejohn } else { 13216a28ef2SGary Jennejohn /* Works even if console_devices[console] is NULL. */ 13316a28ef2SGary Jennejohn console_devices[console] = 13452cb4d4fSJean-Christophe PLAGNIOL-VILLARD (struct stdio_dev **)realloc(console_devices[console], 13552cb4d4fSJean-Christophe PLAGNIOL-VILLARD cs_idx * sizeof(struct stdio_dev *)); 13616a28ef2SGary Jennejohn if (console_devices[console] == NULL) { 13716a28ef2SGary Jennejohn free(cons_set); 13816a28ef2SGary Jennejohn return 1; 13916a28ef2SGary Jennejohn } 14016a28ef2SGary Jennejohn memcpy(console_devices[console], cons_set, cs_idx * 14152cb4d4fSJean-Christophe PLAGNIOL-VILLARD sizeof(struct stdio_dev *)); 14216a28ef2SGary Jennejohn 14316a28ef2SGary Jennejohn cd_count[console] = cs_idx; 14416a28ef2SGary Jennejohn } 14516a28ef2SGary Jennejohn free(cons_set); 14616a28ef2SGary Jennejohn return 0; 14716a28ef2SGary Jennejohn } 148*b0265429SSimon Glass #endif /* CONSOLE_MUX */ 149