diff options
| author | Gary Jennejohn <garyj@denx.de> | 2008-11-06 15:04:23 +0100 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2008-12-07 01:23:35 +0100 | 
| commit | 16a28ef219c27423a1ef502f19070c4d375079b8 (patch) | |
| tree | 2241bdb2293824bdb7b82e1ff8d54e9246c81bcc /common/console.c | |
| parent | 774ce72026f74ac9641bcbbc588b20f2e13f7ab8 (diff) | |
| download | olio-uboot-2014.01-16a28ef219c27423a1ef502f19070c4d375079b8.tar.xz olio-uboot-2014.01-16a28ef219c27423a1ef502f19070c4d375079b8.zip | |
IOMUX: Add console multiplexing support.
Modifications to support console multiplexing.  This is controlled using
CONFIG_SYS_CONSOLE_MUX in the board configuration file.
This allows a user to specify multiple console devices in the environment
with a command like this: setenv stdin serial,nc.  As a result, the user can
enter text on both the serial and netconsole interfaces.
All devices - stdin, stdout and stderr - can be set in this manner.
1) common/iomux.c and include/iomux.h contain the environment setting
implementation.
2) doc/README.iomux contains a somewhat more detailed description.
3) The implementation in (1) is called from common/cmd_nvedit.c to
handle setenv and from common/console.c to handle initialization of
input/output devices at boot time.
4) common/console.c also contains the code needed to poll multiple console
devices for input and send output to all devices registered for output.
5) include/common.h includes iomux.h and common/Makefile generates iomux.o
when CONFIG_SYS_CONSOLE_MUX is set.
Signed-off-by: Gary Jennejohn <garyj@denx.de>
Diffstat (limited to 'common/console.c')
| -rw-r--r-- | common/console.c | 156 | 
1 files changed, 155 insertions, 1 deletions
| diff --git a/common/console.c b/common/console.c index 6f0846f5e..89aeab69e 100644 --- a/common/console.c +++ b/common/console.c @@ -93,6 +93,76 @@ static int console_setfile (int file, device_t * dev)  	return error;  } +#if defined(CONFIG_CONSOLE_MUX) +/** Console I/O multiplexing *******************************************/ + +static device_t *tstcdev; +device_t **console_devices[MAX_FILES]; +int cd_count[MAX_FILES]; + +/* + * This depends on tstc() always being called before getc(). + * This is guaranteed to be true because this routine is called + * only from fgetc() which assures it. + * No attempt is made to demultiplex multiple input sources. + */ +static int iomux_getc(void) +{ +	unsigned char ret; + +	/* This is never called with testcdev == NULL */ +	ret = tstcdev->getc(); +	tstcdev = NULL; +	return ret; +} + +static int iomux_tstc(int file) +{ +	int i, ret; +	device_t *dev; + +	disable_ctrlc(1); +	for (i = 0; i < cd_count[file]; i++) { +		dev = console_devices[file][i]; +		if (dev->tstc != NULL) { +			ret = dev->tstc(); +			if (ret > 0) { +				tstcdev = dev; +				disable_ctrlc(0); +				return ret; +			} +		} +	} +	disable_ctrlc(0); + +	return 0; +} + +static void iomux_putc(int file, const char c) +{ +	int i; +	device_t *dev; + +	for (i = 0; i < cd_count[file]; i++) { +		dev = console_devices[file][i]; +		if (dev->putc != NULL) +			dev->putc(c); +	} +} + +static void iomux_puts(int file, const char *s) +{ +	int i; +	device_t *dev; + +	for (i = 0; i < cd_count[file]; i++) { +		dev = console_devices[file][i]; +		if (dev->puts != NULL) +			dev->puts(s); +	} +} +#endif /* defined(CONFIG_CONSOLE_MUX) */ +  /** U-Boot INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/  void serial_printf (const char *fmt, ...) @@ -114,8 +184,31 @@ void serial_printf (const char *fmt, ...)  int fgetc (int file)  { -	if (file < MAX_FILES) +	if (file < MAX_FILES) { +#if defined(CONFIG_CONSOLE_MUX) +		/* +		 * Effectively poll for input wherever it may be available. +		 */ +		for (;;) { +			/* +			 * Upper layer may have already called tstc() so +			 * check for that first. +			 */ +			if (tstcdev != NULL) +				return iomux_getc(); +			iomux_tstc(file); +#ifdef CONFIG_WATCHDOG +			/* +			 * If the watchdog must be rate-limited then it should +			 * already be handled in board-specific code. +			 */ +			 udelay(1); +#endif +		} +#else  		return stdio_devices[file]->getc (); +#endif +	}  	return -1;  } @@ -123,7 +216,11 @@ int fgetc (int file)  int ftstc (int file)  {  	if (file < MAX_FILES) +#if defined(CONFIG_CONSOLE_MUX) +		return iomux_tstc(file); +#else  		return stdio_devices[file]->tstc (); +#endif  	return -1;  } @@ -131,13 +228,21 @@ int ftstc (int file)  void fputc (int file, const char c)  {  	if (file < MAX_FILES) +#if defined(CONFIG_CONSOLE_MUX) +		iomux_putc(file, c); +#else  		stdio_devices[file]->putc (c); +#endif  }  void fputs (int file, const char *s)  {  	if (file < MAX_FILES) +#if defined(CONFIG_CONSOLE_MUX) +		iomux_puts(file, s); +#else  		stdio_devices[file]->puts (s); +#endif  }  void fprintf (int file, const char *fmt, ...) @@ -407,6 +512,9 @@ int console_init_r (void)  #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE  	int i;  #endif /* CONFIG_SYS_CONSOLE_ENV_OVERWRITE */ +#ifdef CONFIG_CONSOLE_MUX +	int iomux_err = 0; +#endif  	/* set default handlers at first */  	gd->jt[XF_getc] = serial_getc; @@ -425,6 +533,14 @@ int console_init_r (void)  		inputdev  = search_device (DEV_FLAGS_INPUT,  stdinname);  		outputdev = search_device (DEV_FLAGS_OUTPUT, stdoutname);  		errdev    = search_device (DEV_FLAGS_OUTPUT, stderrname); +#ifdef CONFIG_CONSOLE_MUX +		iomux_err = iomux_doenv(stdin, stdinname); +		iomux_err += iomux_doenv(stdout, stdoutname); +		iomux_err += iomux_doenv(stderr, stderrname); +		if (!iomux_err) +			/* Successful, so skip all the code below. */ +			goto done; +#endif  	}  	/* if the devices are overwritten or not found, use default device */  	if (inputdev == NULL) { @@ -438,15 +554,34 @@ int console_init_r (void)  	}  	/* Initializes output console first */  	if (outputdev != NULL) { +#ifdef CONFIG_CONSOLE_MUX +		/* need to set a console if not done above. */ +		iomux_doenv(stdout, outputdev->name); +#else  		console_setfile (stdout, outputdev); +#endif  	}  	if (errdev != NULL) { +#ifdef CONFIG_CONSOLE_MUX +		/* need to set a console if not done above. */ +		iomux_doenv(stderr, errdev->name); +#else  		console_setfile (stderr, errdev); +#endif  	}  	if (inputdev != NULL) { +#ifdef CONFIG_CONSOLE_MUX +		/* need to set a console if not done above. */ +		iomux_doenv(stdin, inputdev->name); +#else  		console_setfile (stdin, inputdev); +#endif  	} +#ifdef CONFIG_CONSOLE_MUX +done: +#endif +  	gd->flags |= GD_FLG_DEVINIT;	/* device initialization completed */  #ifndef CONFIG_SYS_CONSOLE_INFO_QUIET @@ -455,21 +590,33 @@ int console_init_r (void)  	if (stdio_devices[stdin] == NULL) {  		puts ("No input devices available!\n");  	} else { +#ifdef CONFIG_CONSOLE_MUX +		iomux_printdevs(stdin); +#else  		printf ("%s\n", stdio_devices[stdin]->name); +#endif  	}  	puts ("Out:   ");  	if (stdio_devices[stdout] == NULL) {  		puts ("No output devices available!\n");  	} else { +#ifdef CONFIG_CONSOLE_MUX +		iomux_printdevs(stdout); +#else  		printf ("%s\n", stdio_devices[stdout]->name); +#endif  	}  	puts ("Err:   ");  	if (stdio_devices[stderr] == NULL) {  		puts ("No error devices available!\n");  	} else { +#ifdef CONFIG_CONSOLE_MUX +		iomux_printdevs(stderr); +#else  		printf ("%s\n", stdio_devices[stderr]->name); +#endif  	}  #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ @@ -524,11 +671,18 @@ int console_init_r (void)  	if (outputdev != NULL) {  		console_setfile (stdout, outputdev);  		console_setfile (stderr, outputdev); +#ifdef CONFIG_CONSOLE_MUX +		console_devices[stdout][0] = outputdev; +		console_devices[stderr][0] = outputdev; +#endif  	}  	/* Initializes input console */  	if (inputdev != NULL) {  		console_setfile (stdin, inputdev); +#ifdef CONFIG_CONSOLE_MUX +		console_devices[stdin][0] = inputdev; +#endif  	}  	gd->flags |= GD_FLG_DEVINIT;	/* device initialization completed */ |