diff options
-rw-r--r-- | c/src/lib/libbsp/arm/atsam/console/console.c | 14 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/tms570/console/tms570-sci.c | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/t32mppc/console/console.c | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/shared/console-termios-init.c | 41 | ||||
-rw-r--r-- | c/src/lib/libbsp/shared/console-termios.c | 20 | ||||
-rw-r--r-- | c/src/lib/libbsp/shared/include/console-termios.h | 19 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/console/console.c | 6 | ||||
-rw-r--r-- | cpukit/libcsupport/include/rtems/termiostypes.h | 56 | ||||
-rw-r--r-- | cpukit/libcsupport/src/termios.c | 460 | ||||
-rw-r--r-- | testsuites/libtests/termios01/init.c | 162 | ||||
-rw-r--r-- | testsuites/psxtests/psxfile01/test.c | 3 |
11 files changed, 350 insertions, 435 deletions
diff --git a/c/src/lib/libbsp/arm/atsam/console/console.c b/c/src/lib/libbsp/arm/atsam/console/console.c index ef75e8c7e8..ebf284b9ac 100644 --- a/c/src/lib/libbsp/arm/atsam/console/console.c +++ b/c/src/lib/libbsp/arm/atsam/console/console.c @@ -21,6 +21,8 @@ #include <chip.h> +#include <unistd.h> + typedef struct { rtems_termios_device_context base; Usart *regs; @@ -488,8 +490,6 @@ rtems_status_code console_initialize( usart[sizeof(usart) - 2] = (char) ('0' + i); rtems_termios_device_install( &usart[0], - major, - minor, &atsam_usart_handler, NULL, &atsam_usart_instances[i].base @@ -498,11 +498,9 @@ rtems_status_code console_initialize( #if ATSAM_CONSOLE_DEVICE_TYPE == 0 if (i == ATSAM_CONSOLE_DEVICE_INDEX) { atsam_usart_instances[i].console = true; - rtems_io_register_name(CONSOLE_DEVICE_NAME, major, minor); + link(&usart[0], CONSOLE_DEVICE_NAME); } #endif - - ++minor; } for (i = 0; i < RTEMS_ARRAY_SIZE(atsam_uart_instances); ++i) { @@ -511,8 +509,6 @@ rtems_status_code console_initialize( uart[sizeof(uart) - 2] = (char) ('0' + i); rtems_termios_device_install( &uart[0], - major, - minor, &atsam_uart_handler, NULL, &atsam_uart_instances[i].base @@ -521,11 +517,9 @@ rtems_status_code console_initialize( #if ATSAM_CONSOLE_DEVICE_TYPE == 1 if (i == ATSAM_CONSOLE_DEVICE_INDEX) { atsam_uart_instances[i].console = true; - rtems_io_register_name(CONSOLE_DEVICE_NAME, major, minor); + link(&usart[0], CONSOLE_DEVICE_NAME); } #endif - - ++minor; } return RTEMS_SUCCESSFUL; diff --git a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c index 6651cd83eb..1cd3fe1754 100644 --- a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c +++ b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c @@ -138,8 +138,6 @@ rtems_device_driver console_initialize( */ sc = rtems_termios_device_install( ctx->device_name, - major, - minor, handler, NULL, &ctx->base diff --git a/c/src/lib/libbsp/powerpc/t32mppc/console/console.c b/c/src/lib/libbsp/powerpc/t32mppc/console/console.c index 0c39bdd392..bc94f8537a 100644 --- a/c/src/lib/libbsp/powerpc/t32mppc/console/console.c +++ b/c/src/lib/libbsp/powerpc/t32mppc/console/console.c @@ -115,8 +115,6 @@ rtems_device_driver console_initialize( rtems_termios_device_context_initialize(&ctx->base, "T32 Console"); rtems_termios_device_install( CONSOLE_DEVICE_NAME, - major, - 0, &t32_console_handler, NULL, &ctx->base diff --git a/c/src/lib/libbsp/shared/console-termios-init.c b/c/src/lib/libbsp/shared/console-termios-init.c index 83d14d15fa..a01a75abf2 100644 --- a/c/src/lib/libbsp/shared/console-termios-init.c +++ b/c/src/lib/libbsp/shared/console-termios-init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -17,36 +17,7 @@ #include <rtems/console.h> -RTEMS_INTERRUPT_LOCK_DEFINE( static, console_lock, "console" ) - -static rtems_device_major_number console_major = UINT32_MAX; - -static rtems_device_minor_number console_minor; - -rtems_status_code console_device_install( - const char *device_file, - const rtems_termios_device_handler *handler, - const rtems_termios_device_flow *flow, - rtems_termios_device_context *context -) -{ - rtems_interrupt_lock_context lock_context; - rtems_device_minor_number minor; - - rtems_interrupt_lock_acquire( &console_lock, &lock_context ); - minor = console_minor; - ++console_minor; - rtems_interrupt_lock_release( &console_lock, &lock_context ); - - return rtems_termios_device_install( - device_file, - console_major, - minor, - handler, - flow, - context - ); -} +#include <unistd.h> bool console_device_probe_default(rtems_termios_device_context *context) { @@ -72,8 +43,6 @@ rtems_device_driver console_initialize( if ( ( *ctx->probe )( ctx->context ) ) { sc = rtems_termios_device_install( ctx->device_file, - major, - minor, ctx->handler, ctx->flow, ctx->context @@ -85,16 +54,12 @@ rtems_device_driver console_initialize( if ( !console_device_done ) { console_device_done = true; - sc = rtems_io_register_name( CONSOLE_DEVICE_NAME, major, minor ); - if ( sc != RTEMS_SUCCESSFUL ) { + if ( link( ctx->device_file, CONSOLE_DEVICE_NAME ) != 0 ) { bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_1 ); } } } } - console_major = major; - console_minor = minor; - return RTEMS_SUCCESSFUL; } diff --git a/c/src/lib/libbsp/shared/console-termios.c b/c/src/lib/libbsp/shared/console-termios.c index f57b06ce0c..1e755d91c9 100644 --- a/c/src/lib/libbsp/shared/console-termios.c +++ b/c/src/lib/libbsp/shared/console-termios.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -21,7 +21,11 @@ rtems_device_driver console_open( void *arg ) { - return rtems_termios_device_open( major, minor, arg ); + (void) major; + (void) minor; + (void) arg; + + return RTEMS_INTERNAL_ERROR; } rtems_device_driver console_close( @@ -32,8 +36,9 @@ rtems_device_driver console_close( { (void) major; (void) minor; + (void) arg; - return rtems_termios_device_close( arg ); + return RTEMS_INTERNAL_ERROR; } rtems_device_driver console_read( @@ -44,8 +49,9 @@ rtems_device_driver console_read( { (void) major; (void) minor; + (void) arg; - return rtems_termios_read( arg ); + return RTEMS_INTERNAL_ERROR; } rtems_device_driver console_write( @@ -56,8 +62,9 @@ rtems_device_driver console_write( { (void) major; (void) minor; + (void) arg; - return rtems_termios_write( arg ); + return RTEMS_INTERNAL_ERROR; } rtems_device_driver console_control( @@ -68,6 +75,7 @@ rtems_device_driver console_control( { (void) major; (void) minor; + (void) arg; - return rtems_termios_ioctl( arg ); + return RTEMS_INTERNAL_ERROR; } diff --git a/c/src/lib/libbsp/shared/include/console-termios.h b/c/src/lib/libbsp/shared/include/console-termios.h index bbb9f357df..413dde4663 100644 --- a/c/src/lib/libbsp/shared/include/console-termios.h +++ b/c/src/lib/libbsp/shared/include/console-termios.h @@ -87,25 +87,6 @@ typedef struct { } console_device; /** - * @brief Installs a console device after console driver initialization. - * - * @param[in] device_file The device file path. - * @param[in] handler The Termios device handler. It must be persistent - * throughout the installed time of the device. - * @param[in] flow The Termios device flow control handler. The device flow - * control handler are optional and may be @c NULL. If present must be - * persistent throughout the installed time of the device. - * @param[in] context The Termios device context. It must be persistent - * throughout the installed time of the device. - */ -rtems_status_code console_device_install( - const char *device_file, - const rtems_termios_device_handler *handler, - const rtems_termios_device_flow *flow, - rtems_termios_device_context *context -); - -/** * @brief Returns true and does nothing else. */ bool console_device_probe_default(rtems_termios_device_context *context); diff --git a/c/src/lib/libbsp/sparc/leon3/console/console.c b/c/src/lib/libbsp/sparc/leon3/console/console.c index eba0013ad4..666069efbb 100644 --- a/c/src/lib/libbsp/sparc/leon3/console/console.c +++ b/c/src/lib/libbsp/sparc/leon3/console/console.c @@ -131,11 +131,8 @@ rtems_device_driver console_initialize( * On a MP system one should not open UARTs that other OS instances use. */ if (syscon_uart_index < uarts) { - minor = 0; status = rtems_termios_device_install( CONSOLE_DEVICE_NAME, - major, - minor, handler, NULL, leon3_console_get_context(syscon_uart_index) @@ -148,11 +145,8 @@ rtems_device_driver console_initialize( if (i == syscon_uart_index) continue; /* skip UART that is registered as /dev/console */ console_name[13] = 'a' + i; - minor = i + 1; rtems_termios_device_install( console_name, - major, - minor, handler, NULL, leon3_console_get_context(i) diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h index 71be95fc06..80251a22d2 100644 --- a/cpukit/libcsupport/include/rtems/termiostypes.h +++ b/cpukit/libcsupport/include/rtems/termiostypes.h @@ -344,10 +344,9 @@ typedef struct rtems_termios_tty { /** * @brief Installs a Termios device. * - * @param[in] device_file If not @c NULL, then a device file for the specified - * major and minor number will be created. - * @param[in] major The device major number of the corresponding device driver. - * @param[in] minor The device minor number of the corresponding device driver. + * The installed Termios device may be removed via unlink(). + * + * @param[in] device_file The device file path. * @param[in] handler The device handler. It must be persistent throughout the * installed time of the device. * @param[in] flow The device flow control handler. The device flow control @@ -359,65 +358,18 @@ typedef struct rtems_termios_tty { * @retval RTEMS_SUCCESSFUL Successful operation. * @retval RTEMS_NO_MEMORY Not enough memory to create a device node. * @retval RTEMS_UNSATISFIED Creation of the device file failed. - * @retval RTEMS_RESOURCE_IN_USE There exists a device node for this major and - * minor number pair. * @retval RTEMS_INCORRECT_STATE Termios is not initialized. * - * @see rtems_termios_device_remove(), rtems_termios_device_open(), - * rtems_termios_device_close() and rtems_termios_get_device_context(). + * @see rtems_termios_get_device_context(). */ rtems_status_code rtems_termios_device_install( const char *device_file, - rtems_device_major_number major, - rtems_device_minor_number minor, const rtems_termios_device_handler *handler, const rtems_termios_device_flow *flow, rtems_termios_device_context *context ); /** - * @brief Removes a Termios device. - * - * @param[in] device_file If not @c NULL, then the device file to remove. - * @param[in] major The device major number of the corresponding device driver. - * @param[in] minor The device minor number of the corresponding device driver. - * - * @retval RTEMS_SUCCESSFUL Successful operation. - * @retval RTEMS_INVALID_ID There is no device installed with this major and - * minor number pair. - * @retval RTEMS_RESOURCE_IN_USE This device is currently in use. - * @retval RTEMS_UNSATISFIED Removal of the device file failed. - * @retval RTEMS_INCORRECT_STATE Termios is not initialized. - * - * @see rtems_termios_device_install(). - */ -rtems_status_code rtems_termios_device_remove( - const char *device_file, - rtems_device_major_number major, - rtems_device_minor_number minor -); - -/** - * @brief Opens an installed Termios device. - * - * @see rtems_termios_device_install(). - */ -rtems_status_code rtems_termios_device_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -); - -/** - * @brief Closes an installed Termios device. - * - * @retval RTEMS_SUCCESSFUL Successful operation. - * - * @see rtems_termios_device_install(). - */ -rtems_status_code rtems_termios_device_close(void *arg); - -/** * @brief Returns the device context of an installed Termios device. * * @param[in] tty The Termios control. diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c index d9886f4c01..3a6a3897f4 100644 --- a/cpukit/libcsupport/src/termios.c +++ b/cpukit/libcsupport/src/termios.c @@ -22,6 +22,8 @@ #include <rtems.h> #include <rtems/libio.h> +#include <rtems/imfs.h> +#include <rtems/score/assert.h> #include <ctype.h> #include <errno.h> #include <stdio.h> @@ -85,6 +87,8 @@ static size_t rtems_termios_cbufsize = 256; static size_t rtems_termios_raw_input_size = 128; static size_t rtems_termios_raw_output_size = 64; +static const IMFS_node_control rtems_termios_imfs_node_control; + static struct rtems_termios_tty *rtems_termios_ttyHead; static struct rtems_termios_tty *rtems_termios_ttyTail; @@ -108,126 +112,55 @@ static rtems_task rtems_termios_txdaemon(rtems_task_argument argument); #define TERMIOS_RX_PROC_EVENT RTEMS_EVENT_1 #define TERMIOS_RX_TERMINATE_EVENT RTEMS_EVENT_0 -static rtems_termios_device_node * -rtems_termios_find_device_node( - rtems_device_major_number major, - rtems_device_minor_number minor -) +static rtems_status_code +rtems_termios_obtain (void) { - rtems_chain_node *tail = rtems_chain_tail(&rtems_termios_devices); - rtems_chain_node *current = rtems_chain_first(&rtems_termios_devices); - - while (current != tail) { - rtems_termios_device_node *device_node = - (rtems_termios_device_node *) current; - - if (device_node->major == major && device_node->minor == minor) { - return device_node; - } + return rtems_semaphore_obtain (rtems_termios_ttyMutex, RTEMS_WAIT, + RTEMS_NO_TIMEOUT); +} - current = rtems_chain_next(current); - } +static void +rtems_termios_release (void) +{ + rtems_status_code sc; - return NULL; + sc = rtems_semaphore_release (rtems_termios_ttyMutex); + _Assert (sc == RTEMS_SUCCESSFUL); + (void) sc; } rtems_status_code rtems_termios_device_install( const char *device_file, - rtems_device_major_number major, - rtems_device_minor_number minor, const rtems_termios_device_handler *handler, const rtems_termios_device_flow *flow, rtems_termios_device_context *context ) { - rtems_status_code sc; rtems_termios_device_node *new_device_node; - rtems_termios_device_node *existing_device_node; + int rv; - new_device_node = malloc(sizeof(*new_device_node)); + new_device_node = calloc (1, sizeof(*new_device_node)); if (new_device_node == NULL) { return RTEMS_NO_MEMORY; } - rtems_chain_initialize_node(&new_device_node->node); - new_device_node->major = major; - new_device_node->minor = minor; + rtems_chain_initialize_node (&new_device_node->node); new_device_node->handler = handler; new_device_node->flow = flow; new_device_node->context = context; new_device_node->tty = NULL; - sc = rtems_semaphore_obtain( - rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) { - free(new_device_node); - return RTEMS_INCORRECT_STATE; - } - - existing_device_node = rtems_termios_find_device_node (major, minor); - if (existing_device_node != NULL) { - free(new_device_node); - rtems_semaphore_release (rtems_termios_ttyMutex); - return RTEMS_RESOURCE_IN_USE; - } - - if (device_file != NULL) { - sc = rtems_io_register_name (device_file, major, minor); - if (sc != RTEMS_SUCCESSFUL) { - free(new_device_node); - rtems_semaphore_release (rtems_termios_ttyMutex); - return RTEMS_UNSATISFIED; - } - } - - rtems_chain_append_unprotected( - &rtems_termios_devices, &new_device_node->node); - - rtems_semaphore_release (rtems_termios_ttyMutex); - - return RTEMS_SUCCESSFUL; -} - -rtems_status_code rtems_termios_device_remove( - const char *device_file, - rtems_device_major_number major, - rtems_device_minor_number minor -) -{ - rtems_status_code sc; - rtems_termios_device_node *device_node; - - sc = rtems_semaphore_obtain( - rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) { - return RTEMS_INCORRECT_STATE; - } - - device_node = rtems_termios_find_device_node (major, minor); - if (device_node == NULL) { - rtems_semaphore_release (rtems_termios_ttyMutex); - return RTEMS_INVALID_ID; - } - - if (device_node->tty != NULL) { - rtems_semaphore_release (rtems_termios_ttyMutex); - return RTEMS_RESOURCE_IN_USE; - } - - if (device_file != NULL) { - int rv = unlink (device_file); - - if (rv != 0) { - rtems_semaphore_release (rtems_termios_ttyMutex); - return RTEMS_UNSATISFIED; - } + rv = IMFS_make_generic_node( + device_file, + S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, + &rtems_termios_imfs_node_control, + new_device_node + ); + if (rv != 0) { + free (new_device_node); + return RTEMS_UNSATISFIED; } - rtems_chain_extract_unprotected (&device_node->node); - free (device_node); - - rtems_semaphore_release (rtems_termios_ttyMutex); - return RTEMS_SUCCESSFUL; } @@ -629,40 +562,6 @@ rtems_termios_open_tty( return tty; } -rtems_status_code -rtems_termios_device_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_status_code sc; - rtems_termios_device_node *device_node; - struct rtems_termios_tty *tty; - - sc = rtems_semaphore_obtain( - rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - return sc; - - device_node = rtems_termios_find_device_node (major, minor); - if (device_node == NULL) { - rtems_semaphore_release (rtems_termios_ttyMutex); - return RTEMS_INVALID_ID; - } - - tty = rtems_termios_open_tty( - major, minor, arg, device_node->tty, device_node, NULL); - if (tty == NULL) { - rtems_semaphore_release (rtems_termios_ttyMutex); - return RTEMS_NO_MEMORY; - } - - rtems_semaphore_release (rtems_termios_ttyMutex); - - return RTEMS_SUCCESSFUL; -} - /* * Open a termios device */ @@ -680,8 +579,7 @@ rtems_termios_open ( /* * See if the device has already been opened */ - sc = rtems_semaphore_obtain( - rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + sc = rtems_termios_obtain (); if (sc != RTEMS_SUCCESSFUL) return sc; @@ -693,7 +591,7 @@ rtems_termios_open ( tty = rtems_termios_open_tty( major, minor, arg, tty, NULL, callbacks); if (tty == NULL) { - rtems_semaphore_release (rtems_termios_ttyMutex); + rtems_termios_release (); return RTEMS_NO_MEMORY; } @@ -710,7 +608,7 @@ rtems_termios_open ( rtems_termios_ttyTail = tty; } - rtems_semaphore_release (rtems_termios_ttyMutex); + rtems_termios_release (); return RTEMS_SUCCESSFUL; } @@ -755,8 +653,7 @@ rtems_termios_close (void *arg) rtems_libio_open_close_args_t *args = arg; struct rtems_termios_tty *tty = args->iop->data1; - sc = rtems_semaphore_obtain( - rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + sc = rtems_termios_obtain (); if (sc != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (sc); @@ -782,26 +679,7 @@ rtems_termios_close (void *arg) rtems_termios_close_tty (tty, arg); - rtems_semaphore_release (rtems_termios_ttyMutex); - - return RTEMS_SUCCESSFUL; -} - -rtems_status_code -rtems_termios_device_close (void *arg) -{ - rtems_status_code sc; - rtems_libio_open_close_args_t *args = arg; - struct rtems_termios_tty *tty = args->iop->data1; - - sc = rtems_semaphore_obtain( - rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred (sc); - - rtems_termios_close_tty (tty, arg); - - rtems_semaphore_release (rtems_termios_ttyMutex); + rtems_termios_release (); return RTEMS_SUCCESSFUL; } @@ -1193,6 +1071,25 @@ oproc (unsigned char c, struct rtems_termios_tty *tty) rtems_termios_puts (&c, 1, tty); } +static uint32_t +rtems_termios_write_tty (struct rtems_termios_tty *tty, const char *buffer, + uint32_t initial_count) +{ + + if (tty->termios.c_oflag & OPOST) { + uint32_t count; + + count = initial_count; + + while (count--) + oproc (*buffer++, tty); + } else { + rtems_termios_puts (buffer, initial_count, tty); + } + + return initial_count; +} + rtems_status_code rtems_termios_write (void *arg) { @@ -1208,16 +1105,7 @@ rtems_termios_write (void *arg) rtems_semaphore_release (tty->osem); return sc; } - if (tty->termios.c_oflag & OPOST) { - uint32_t count = args->count; - char *buffer = args->buffer; - while (count--) - oproc (*buffer++, tty); - args->bytes_moved = args->count; - } else { - rtems_termios_puts (args->buffer, args->count, tty); - args->bytes_moved = args->count; - } + args->bytes_moved = rtems_termios_write_tty (tty, args->buffer, args->count); rtems_semaphore_release (tty->osem); return sc; } @@ -1521,27 +1409,17 @@ fillBufferQueue (struct rtems_termios_tty *tty) return RTEMS_SUCCESSFUL; } -rtems_status_code -rtems_termios_read (void *arg) +static uint32_t +rtems_termios_read_tty (struct rtems_termios_tty *tty, char *buffer, + uint32_t initial_count) { - rtems_libio_rw_args_t *args = arg; - struct rtems_termios_tty *tty = args->iop->data1; - uint32_t count = args->count; - char *buffer = args->buffer; - rtems_status_code sc; - - sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - return sc; + uint32_t count; - if (rtems_termios_linesw[tty->t_line].l_read != NULL) { - sc = rtems_termios_linesw[tty->t_line].l_read(tty,args); - tty->tty_rcvwakeup = 0; - rtems_semaphore_release (tty->isem); - return sc; - } + count = initial_count; if (tty->cindex == tty->ccount) { + rtems_status_code sc; + tty->cindex = tty->ccount = 0; tty->read_start_column = tty->column; if (tty->handler.poll_read != NULL && tty->handler.mode == TERMIOS_POLLED) @@ -1556,8 +1434,29 @@ rtems_termios_read (void *arg) *buffer++ = tty->cbuf[tty->cindex++]; count--; } - args->bytes_moved = args->count - count; tty->tty_rcvwakeup = 0; + return initial_count - count; +} + +rtems_status_code +rtems_termios_read (void *arg) +{ + rtems_libio_rw_args_t *args = arg; + struct rtems_termios_tty *tty = args->iop->data1; + rtems_status_code sc; + + sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) + return sc; + + if (rtems_termios_linesw[tty->t_line].l_read != NULL) { + sc = rtems_termios_linesw[tty->t_line].l_read(tty,args); + tty->tty_rcvwakeup = 0; + rtems_semaphore_release (tty->isem); + return sc; + } + + args->bytes_moved = rtems_termios_read_tty (tty, args->buffer, args->count); rtems_semaphore_release (tty->isem); return sc; } @@ -1928,3 +1827,198 @@ static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument) } } } + +static int +rtems_termios_imfs_open (rtems_libio_t *iop, + const char *path, int oflag, mode_t mode) +{ + rtems_termios_device_node *device_node; + rtems_status_code sc; + rtems_libio_open_close_args_t args; + struct rtems_termios_tty *tty; + + device_node = IMFS_generic_get_context_by_iop (iop); + + memset (&args, 0, sizeof (args)); + args.iop = iop; + args.flags = iop->flags; + args.mode = mode; + + sc = rtems_termios_obtain (); + if (sc != RTEMS_SUCCESSFUL) { + rtems_set_errno_and_return_minus_one (ENXIO); + } + + tty = rtems_termios_open_tty (device_node->major, device_node->minor, &args, + device_node->tty, device_node, NULL); + if (tty == NULL) { + rtems_termios_release (); + rtems_set_errno_and_return_minus_one (ENOMEM); + } + + rtems_termios_release (); + return 0; +} + +static int +rtems_termios_imfs_close (rtems_libio_t *iop) +{ + rtems_status_code sc; + rtems_libio_open_close_args_t args; + struct rtems_termios_tty *tty; + + memset (&args, 0, sizeof (args)); + args.iop = iop; + + tty = iop->data1; + + sc = rtems_termios_obtain (); + _Assert (sc == RTEMS_SUCCESSFUL); + (void) sc; + + rtems_termios_close_tty (tty, &args); + rtems_termios_release (); + return 0; +} + +static ssize_t +rtems_termios_imfs_read (rtems_libio_t *iop, void *buffer, size_t count) +{ + struct rtems_termios_tty *tty; + rtems_status_code sc; + uint32_t bytes_moved; + + tty = iop->data1; + + sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + _Assert (sc == RTEMS_SUCCESSFUL); + + if (rtems_termios_linesw[tty->t_line].l_read != NULL) { + rtems_libio_rw_args_t args; + + memset (&args, 0, sizeof (args)); + args.iop = iop; + args.buffer = buffer; + args.count = count; + args.flags = iop->flags; + + sc = rtems_termios_linesw[tty->t_line].l_read (tty, &args); + tty->tty_rcvwakeup = 0; + rtems_semaphore_release (tty->isem); + + if (sc != RTEMS_SUCCESSFUL) { + return rtems_status_code_to_errno (sc); + } + + return (ssize_t) args.bytes_moved; + } + + bytes_moved = rtems_termios_read_tty (tty, buffer, count); + rtems_semaphore_release (tty->isem); + return (ssize_t) bytes_moved; +} + +static ssize_t +rtems_termios_imfs_write (rtems_libio_t *iop, const void *buffer, size_t count) +{ + struct rtems_termios_tty *tty; + rtems_status_code sc; + uint32_t bytes_moved; + + tty = iop->data1; + + sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + _Assert (sc == RTEMS_SUCCESSFUL); + + if (rtems_termios_linesw[tty->t_line].l_write != NULL) { + rtems_libio_rw_args_t args; + + memset (&args, 0, sizeof (args)); + args.iop = iop; + args.buffer = RTEMS_DECONST (void *, buffer); + args.count = count; + args.flags = iop->flags; + + sc = rtems_termios_linesw[tty->t_line].l_write (tty, &args); + rtems_semaphore_release (tty->osem); + + if (sc != RTEMS_SUCCESSFUL) { + return rtems_status_code_to_errno (sc); + } + + return (ssize_t) args.bytes_moved; + } + + bytes_moved = rtems_termios_write_tty (tty, buffer, count); + rtems_semaphore_release (tty->osem); + return (ssize_t) bytes_moved; +} + +static int +rtems_termios_imfs_ioctl (rtems_libio_t *iop, uint32_t request, void *buffer) +{ + rtems_status_code sc; + rtems_libio_ioctl_args_t args; + + memset (&args, 0, sizeof (args)); + args.iop = iop; + args.command = request; + args.buffer = buffer; + + sc = rtems_termios_ioctl (&args); + if ( sc == RTEMS_SUCCESSFUL ) { + return args.ioctl_return; + } else { + return rtems_status_code_to_errno (sc); + } +} + +static const rtems_filesystem_file_handlers_r rtems_termios_imfs_handler = { + .open_h = rtems_termios_imfs_open, + .close_h = rtems_termios_imfs_close, + .read_h = rtems_termios_imfs_read, + .write_h = rtems_termios_imfs_write, + .ioctl_h = rtems_termios_imfs_ioctl, + .lseek_h = rtems_filesystem_default_lseek, + .fstat_h = IMFS_stat, + .ftruncate_h = rtems_filesystem_default_ftruncate, + .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, + .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, + .fcntl_h = rtems_filesystem_default_fcntl, + .kqfilter_h = rtems_filesystem_default_kqfilter, + .poll_h = rtems_filesystem_default_poll, + .readv_h = rtems_filesystem_default_readv, + .writev_h = rtems_filesystem_default_writev +}; + +static IMFS_jnode_t * +rtems_termios_imfs_node_initialize (IMFS_jnode_t *node, void *arg) +{ + rtems_termios_device_node *device_node; + dev_t dev; + + node = IMFS_node_initialize_generic (node, arg); + device_node = IMFS_generic_get_context_by_node (node); + dev = IMFS_generic_get_device_identifier_by_node (node); + device_node->major = rtems_filesystem_dev_major_t (dev); + device_node->minor = rtems_filesystem_dev_minor_t (dev); + + return node; +} + +static void +rtems_termios_imfs_node_destroy (IMFS_jnode_t *node) +{ + rtems_termios_device_node *device_node; + + device_node = IMFS_generic_get_context_by_node (node); + free (device_node); + IMFS_node_destroy_default (node); +} + +static const IMFS_node_control rtems_termios_imfs_node_control = + IMFS_GENERIC_INITIALIZER( + &rtems_termios_imfs_handler, + rtems_termios_imfs_node_initialize, + rtems_termios_imfs_node_destroy + ); diff --git a/testsuites/libtests/termios01/init.c b/testsuites/libtests/termios01/init.c index c836b3d79e..64c3bb286b 100644 --- a/testsuites/libtests/termios01/init.c +++ b/testsuites/libtests/termios01/init.c @@ -18,7 +18,9 @@ #include <rtems/termiostypes.h> #include <fcntl.h> #include <limits.h> +#include <unistd.h> #include <sys/errno.h> +#include <sys/stat.h> const char rtems_test_name[] = "TERMIOS 1"; @@ -522,22 +524,32 @@ typedef struct { bool done; } device_context; -static rtems_status_code test_early_device_install_remove( +static rtems_status_code test_early_device_install( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { + static const rtems_termios_device_handler handler; + static const char dev[] = "/foobar"; + rtems_resource_snapshot snapshot; rtems_status_code sc; + int fd; + int rv; rtems_resource_snapshot_take( &snapshot ); - sc = rtems_termios_device_install( "/", 0, 0, NULL, NULL, NULL ); - rtems_test_assert( sc == RTEMS_INCORRECT_STATE ); + sc = rtems_termios_device_install( &dev[0], &handler, NULL, NULL ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + errno = 0; + fd = open( &dev[0], O_RDWR ); + rtems_test_assert( fd == -1 ); + rtems_test_assert( errno == ENXIO ); - sc = rtems_termios_device_remove( "/", 0, 0 ); - rtems_test_assert( sc == RTEMS_INCORRECT_STATE ); + rv = unlink( &dev[0] ); + rtems_test_assert( rv == 0 ); rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) ); @@ -547,88 +559,34 @@ static rtems_status_code test_early_device_install_remove( static void test_device_install_remove(void) { static const rtems_termios_device_handler handler; - static const rtems_device_major_number major = 123456789; - static const rtems_device_minor_number minor = 0xdeadbeef; static const char dev[] = "/foobar"; rtems_resource_snapshot snapshot; rtems_status_code sc; void *greedy; - rtems_libio_t iop; - rtems_libio_open_close_args_t args; - - memset( &iop, 0, sizeof( iop ) ); - memset( &args, 0, sizeof( args ) ); - args.iop = &iop; + int rv; rtems_resource_snapshot_take( &snapshot ); greedy = rtems_heap_greedy_allocate( NULL, 0 ); - sc = rtems_termios_device_install( "/", major, minor, &handler, NULL, NULL ); + sc = rtems_termios_device_install( "/", &handler, NULL, NULL ); rtems_test_assert( sc == RTEMS_NO_MEMORY ); rtems_heap_greedy_free( greedy ); rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) ); - sc = rtems_termios_device_install( - NULL, - major, - minor, - &handler, - NULL, - NULL - ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); - - sc = rtems_termios_device_install( - NULL, - major, - minor, - &handler, - NULL, - NULL - ); - rtems_test_assert( sc == RTEMS_RESOURCE_IN_USE ); - - sc = rtems_termios_device_remove( NULL, major, minor ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); - - rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) ); - - sc = rtems_termios_device_install( "/", major, minor, &handler, NULL, NULL ); + sc = rtems_termios_device_install( "/", &handler, NULL, NULL ); rtems_test_assert( sc == RTEMS_UNSATISFIED ); rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) ); - sc = rtems_termios_device_remove( NULL, major, minor ); - rtems_test_assert( sc == RTEMS_INVALID_ID ); - - sc = rtems_termios_device_install( - &dev[0], - major, - minor, - &handler, - NULL, - NULL - ); + sc = rtems_termios_device_install( &dev[0], &handler, NULL, NULL ); rtems_test_assert( sc == RTEMS_SUCCESSFUL ); - sc = rtems_termios_device_remove( "/barfoo", major, minor ); - rtems_test_assert( sc == RTEMS_UNSATISFIED ); - - sc = rtems_termios_device_open( major, minor, &args ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); - - sc = rtems_termios_device_remove( &dev[0], major, minor ); - rtems_test_assert( sc == RTEMS_RESOURCE_IN_USE ); - - sc = rtems_termios_device_close( &args ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); - - sc = rtems_termios_device_remove( &dev[0], major, minor ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + rv = unlink( &dev[0] ); + rtems_test_assert( rv == 0 ); rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) ); } @@ -656,14 +614,12 @@ static void test_first_open_error(void) static const rtems_termios_device_handler handler = { .first_open = first_open_error }; - static const rtems_device_major_number major = 123456789; - static const rtems_device_minor_number minor = 0xdeadbeef; static const char dev[] = "/foobar"; rtems_resource_snapshot snapshot; rtems_status_code sc; - rtems_libio_t iop; - rtems_libio_open_close_args_t args; + int fd; + int rv; device_context ctx = { .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ), .done = false @@ -671,27 +627,18 @@ static void test_first_open_error(void) rtems_resource_snapshot_take( &snapshot ); - sc = rtems_termios_device_install( - &dev[0], - major, - minor, - &handler, - NULL, - &ctx.base - ); + sc = rtems_termios_device_install( &dev[0], &handler, NULL, &ctx.base ); rtems_test_assert( sc == RTEMS_SUCCESSFUL ); - memset( &iop, 0, sizeof( iop ) ); - memset( &args, 0, sizeof( args ) ); - args.iop = &iop; - rtems_test_assert( !ctx.done ); - sc = rtems_termios_device_open( major, minor, &args ); - rtems_test_assert( sc == RTEMS_NO_MEMORY ); + errno = 0; + fd = open( &dev[0], O_RDWR ); + rtems_test_assert( fd == -1 ); + rtems_test_assert( errno == ENOMEM ); rtems_test_assert( ctx.done ); - sc = rtems_termios_device_remove( &dev[0], major, minor ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + rv = unlink( &dev[0] ); + rtems_test_assert( rv == 0 ); rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) ); } @@ -715,55 +662,38 @@ static void test_set_attributes_error(void) static const rtems_termios_device_handler handler = { .set_attributes = set_attributes_error }; - static const rtems_device_major_number major = 123456789; - static const rtems_device_minor_number minor = 0xdeadbeef; static const char dev[] = "/foobar"; rtems_resource_snapshot snapshot; rtems_status_code sc; - rtems_libio_t iop; - rtems_libio_open_close_args_t oc_args; - rtems_libio_ioctl_args_t io_args; struct termios term; device_context ctx = { .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ), .done = false }; + int fd; + int rv; rtems_resource_snapshot_take( &snapshot ); - sc = rtems_termios_device_install( - &dev[0], - major, - minor, - &handler, - NULL, - &ctx.base - ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); - - memset( &iop, 0, sizeof( iop ) ); - memset( &oc_args, 0, sizeof( oc_args ) ); - oc_args.iop = &iop; - - sc = rtems_termios_device_open( major, minor, &oc_args ); + sc = rtems_termios_device_install( &dev[0], &handler, NULL, &ctx.base ); rtems_test_assert( sc == RTEMS_SUCCESSFUL ); - memset( &io_args, 0, sizeof( io_args ) ); - io_args.iop = &iop; - io_args.command = RTEMS_IO_SET_ATTRIBUTES; - io_args.buffer = &term; + fd = open( &dev[0], O_RDWR ); + rtems_test_assert( fd >= 0 ); rtems_test_assert( !ctx.done ); - sc = rtems_termios_ioctl( &io_args ); - rtems_test_assert( sc == RTEMS_IO_ERROR ); + errno = 0; + rv = ioctl( fd, RTEMS_IO_SET_ATTRIBUTES, &term ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EIO ); rtems_test_assert( ctx.done ); - sc = rtems_termios_device_close( &oc_args ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + rv = close( fd ); + rtems_test_assert( rv == 0 ); - sc = rtems_termios_device_remove( &dev[0], major, minor ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + rv = unlink( &dev[0] ); + rtems_test_assert( rv == 0 ); rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) ); } @@ -982,7 +912,7 @@ static rtems_task Init( /* configuration information */ #define CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS \ - { .initialization_entry = test_early_device_install_remove } + { .initialization_entry = test_early_device_install } #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER diff --git a/testsuites/psxtests/psxfile01/test.c b/testsuites/psxtests/psxfile01/test.c index abc9295053..8fcb281307 100644 --- a/testsuites/psxtests/psxfile01/test.c +++ b/testsuites/psxtests/psxfile01/test.c @@ -624,8 +624,9 @@ since new path is not valid"); rtems_test_assert( ctime1 != ctime2); /* try to truncate the console and see what happens */ + errno = 0; status = truncate( "/dev/console", 40 ); - rtems_test_assert( status == 0 ); + rtems_test_assert( status == 0 || ( status == -1 && errno == EINVAL ) ); puts( "truncate /tmp/j to length of 0" ); status = truncate( "/tmp/j", 0 ); |