iomux.c 3.09 KB
Newer Older
1 2 3 4
/*
 * (C) Copyright 2008
 * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
 *
5
 * SPDX-License-Identifier:	GPL-2.0+
6 7 8
 */

#include <common.h>
9
#include <console.h>
10 11 12 13 14 15 16
#include <serial.h>
#include <malloc.h>

#ifdef CONFIG_CONSOLE_MUX
void iomux_printdevs(const int console)
{
	int i;
17
	struct stdio_dev *dev;
18 19 20 21 22 23 24 25 26 27 28 29 30

	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;
31 32
	struct stdio_dev *dev;
	struct stdio_dev **cons_set;
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

	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;
	}
73
	cons_set = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *));
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	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;
		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] =
134 135
			(struct stdio_dev **)realloc(console_devices[console],
			cs_idx * sizeof(struct stdio_dev *));
136 137 138 139 140
		if (console_devices[console] == NULL) {
			free(cons_set);
			return 1;
		}
		memcpy(console_devices[console], cons_set, cs_idx *
141
			sizeof(struct stdio_dev *));
142 143 144 145 146 147 148

		cd_count[console] = cs_idx;
	}
	free(cons_set);
	return 0;
}
#endif /* CONFIG_CONSOLE_MUX */