uboot/common/iomux.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2008
   3 * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <console.h>
  10#include <serial.h>
  11#include <malloc.h>
  12
  13#ifdef CONFIG_CONSOLE_MUX
  14void iomux_printdevs(const int console)
  15{
  16        int i;
  17        struct stdio_dev *dev;
  18
  19        for (i = 0; i < cd_count[console]; i++) {
  20                dev = console_devices[console][i];
  21                printf("%s ", dev->name);
  22        }
  23        printf("\n");
  24}
  25
  26/* This tries to preserve the old list if an error occurs. */
  27int iomux_doenv(const int console, const char *arg)
  28{
  29        char *console_args, *temp, **start;
  30        int i, j, k, io_flag, cs_idx, repeat;
  31        struct stdio_dev *dev;
  32        struct stdio_dev **cons_set;
  33
  34        console_args = strdup(arg);
  35        if (console_args == NULL)
  36                return 1;
  37        /*
  38         * Check whether a comma separated list of devices was
  39         * entered and count how many devices were entered.
  40         * The array start[] has pointers to the beginning of
  41         * each device name (up to MAX_CONSARGS devices).
  42         *
  43         * Have to do this twice - once to count the number of
  44         * commas and then again to populate start.
  45         */
  46        i = 0;
  47        temp = console_args;
  48        for (;;) {
  49                temp = strchr(temp, ',');
  50                if (temp != NULL) {
  51                        i++;
  52                        temp++;
  53                        continue;
  54                }
  55                /* There's always one entry more than the number of commas. */
  56                i++;
  57                break;
  58        }
  59        start = (char **)malloc(i * sizeof(char *));
  60        if (start == NULL) {
  61                free(console_args);
  62                return 1;
  63        }
  64        i = 0;
  65        start[0] = console_args;
  66        for (;;) {
  67                temp = strchr(start[i++], ',');
  68                if (temp == NULL)
  69                        break;
  70                *temp = '\0';
  71                start[i] = temp + 1;
  72        }
  73        cons_set = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *));
  74        if (cons_set == NULL) {
  75                free(start);
  76                free(console_args);
  77                return 1;
  78        }
  79
  80        switch (console) {
  81        case stdin:
  82                io_flag = DEV_FLAGS_INPUT;
  83                break;
  84        case stdout:
  85        case stderr:
  86                io_flag = DEV_FLAGS_OUTPUT;
  87                break;
  88        default:
  89                free(start);
  90                free(console_args);
  91                free(cons_set);
  92                return 1;
  93        }
  94
  95        cs_idx = 0;
  96        for (j = 0; j < i; j++) {
  97                /*
  98                 * Check whether the device exists and is valid.
  99                 * console_assign() also calls search_device(),
 100                 * but I need the pointer to the device.
 101                 */
 102                dev = search_device(io_flag, start[j]);
 103                if (dev == NULL)
 104                        continue;
 105                /*
 106                 * Prevent multiple entries for a device.
 107                 */
 108                 repeat = 0;
 109                 for (k = 0; k < cs_idx; k++) {
 110                        if (dev == cons_set[k]) {
 111                                repeat++;
 112                                break;
 113                        }
 114                 }
 115                 if (repeat)
 116                        continue;
 117                /*
 118                 * Try assigning the specified device.
 119                 * This could screw up the console settings for apps.
 120                 */
 121                if (console_assign(console, start[j]) < 0)
 122                        continue;
 123                cons_set[cs_idx++] = dev;
 124        }
 125        free(console_args);
 126        free(start);
 127        /* failed to set any console */
 128        if (cs_idx == 0) {
 129                free(cons_set);
 130                return 1;
 131        } else {
 132                /* Works even if console_devices[console] is NULL. */
 133                console_devices[console] =
 134                        (struct stdio_dev **)realloc(console_devices[console],
 135                        cs_idx * sizeof(struct stdio_dev *));
 136                if (console_devices[console] == NULL) {
 137                        free(cons_set);
 138                        return 1;
 139                }
 140                memcpy(console_devices[console], cons_set, cs_idx *
 141                        sizeof(struct stdio_dev *));
 142
 143                cd_count[console] = cs_idx;
 144        }
 145        free(cons_set);
 146        return 0;
 147}
 148#endif /* CONFIG_CONSOLE_MUX */
 149