diff options
| -rw-r--r-- | arch/sandbox/cpu/os.c | 8 | ||||
| -rw-r--r-- | drivers/serial/sandbox.c | 44 | ||||
| -rw-r--r-- | include/os.h | 10 | 
3 files changed, 56 insertions, 6 deletions
| diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 36637af6c..3e37c930b 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -44,6 +44,14 @@ ssize_t os_read(int fd, void *buf, size_t count)  	return read(fd, buf, count);  } +ssize_t os_read_no_block(int fd, void *buf, size_t count) +{ +	const int flags = fcntl(fd, F_GETFL, 0); + +	fcntl(fd, F_SETFL, flags | O_NONBLOCK); +	return os_read(fd, buf, count); +} +  ssize_t os_write(int fd, const void *buf, size_t count)  {  	return write(fd, buf, count); diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index cb19401df..b73520ca9 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -30,6 +30,19 @@  #include <serial.h>  #include <linux/compiler.h> +/* + * + *   serial_buf: A buffer that holds keyboard characters for the + *		 Sandbox U-boot. + * + * invariants: + *   serial_buf_write		 == serial_buf_read -> empty buffer + *   (serial_buf_write + 1) % 16 == serial_buf_read -> full buffer + */ +static char serial_buf[16]; +static unsigned int serial_buf_write; +static unsigned int serial_buf_read; +  static int sandbox_serial_init(void)  {  	os_tty_raw(0); @@ -50,18 +63,37 @@ static void sandbox_serial_puts(const char *str)  	os_write(1, str, strlen(str));  } -static int sandbox_serial_getc(void) +static unsigned int increment_buffer_index(unsigned int index) +{ +	return (index + 1) % ARRAY_SIZE(serial_buf); +} + +static int sandbox_serial_tstc(void)  { -	char buf; +	const unsigned int next_index = +		increment_buffer_index(serial_buf_write);  	ssize_t count; -	count = os_read(0, &buf, 1); -	return count == 1 ? buf : 0; +	os_usleep(100); +	if (next_index == serial_buf_read) +		return 1;	/* buffer full */ + +	count = os_read_no_block(0, &serial_buf[serial_buf_write], 1); +	if (count == 1) +		serial_buf_write = next_index; +	return serial_buf_write != serial_buf_read;  } -static int sandbox_serial_tstc(void) +static int sandbox_serial_getc(void)  { -	return 0; +	int result; + +	while (!sandbox_serial_tstc()) +		;	/* buffer empty */ + +	result = serial_buf[serial_buf_read]; +	serial_buf_read = increment_buffer_index(serial_buf_read); +	return result;  }  static struct serial_device sandbox_serial_drv = { diff --git a/include/os.h b/include/os.h index 699682a40..c452d1b56 100644 --- a/include/os.h +++ b/include/os.h @@ -40,6 +40,16 @@ struct sandbox_state;  ssize_t os_read(int fd, void *buf, size_t count);  /** + * Access to the OS read() system call with non-blocking access + * + * \param fd	File descriptor as returned by os_open() + * \param buf	Buffer to place data + * \param count	Number of bytes to read + * \return number of bytes read, or -1 on error + */ +ssize_t os_read_no_block(int fd, void *buf, size_t count); + +/**   * Access to the OS write() system call   *   * \param fd	File descriptor as returned by os_open() |