diff options
-rw-r--r-- | c/src/lib/libbsp/arm/tms570/console/tms570-sci.c | 74 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/tms570/include/tms570-sci-driver.h | 1 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/console/console.c | 10 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/include/apbuart_termios.h | 1 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/uart/apbuart_termios.c | 45 | ||||
-rw-r--r-- | cpukit/libcsupport/include/rtems/termiostypes.h | 146 | ||||
-rw-r--r-- | cpukit/libcsupport/src/termios.c | 142 | ||||
-rw-r--r-- | cpukit/libcsupport/src/termios_setbestbaud.c | 6 | ||||
-rw-r--r-- | cpukit/libnetworking/net/if_ppp.c | 2 | ||||
-rw-r--r-- | cpukit/libnetworking/net/ppp_tty.c | 5 | ||||
-rw-r--r-- | doc/bsp_howto/console.t | 38 | ||||
-rw-r--r-- | testsuites/libtests/termios01/init.c | 52 |
12 files changed, 325 insertions, 197 deletions
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 961754ece6..3f103004b8 100644 --- a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c +++ b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c @@ -26,7 +26,6 @@ #include <bspopts.h> #include <termios.h> #include <rtems/termiostypes.h> -#include <libchip/sersupp.h> #include <bsp/tms570-sci.h> #include <bsp/tms570-sci-driver.h> #include <rtems/console.h> @@ -43,11 +42,13 @@ */ const tms570_sci_context driver_context_table[] = { { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI1"), .device_name = "/dev/console", .regs = &TMS570_SCI, .irq = TMS570_IRQ_SCI_LEVEL_0, }, { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("TMS570 SCI2"), .device_name = "/dev/ttyS1", .regs = &TMS570_SCI2, .irq = TMS570_IRQ_SCI2_LEVEL_0, @@ -104,7 +105,7 @@ rtems_device_driver console_initialize( minor, handler, NULL, - (void *) ctx + RTEMS_DECONST(rtems_termios_device_context *, &ctx->base) ); if ( sc != RTEMS_SUCCESSFUL ) { bsp_fatal(BSP_FATAL_CONSOLE_NO_DEV); @@ -196,21 +197,21 @@ static int tms570_sci_transmitted_chars(tms570_sci_context * ctx) * * Sets attributes of the HW peripheral (parity, baud rate, etc.) * - * @param[in] tty rtems_termios_tty + * @param[in] base context of the driver * @param[in] t termios driver * @retval true peripheral setting is changed */ static bool tms570_sci_set_attributes( - rtems_termios_tty *tty, + rtems_termios_device_context *base, const struct termios *t ) { - tms570_sci_context *ctx = rtems_termios_get_device_context(tty); + tms570_sci_context *ctx = (tms570_sci_context *) base; rtems_interrupt_lock_context lock_context; int32_t bauddiv; int32_t baudrate; - rtems_termios_interrupt_lock_acquire(tty, &lock_context); + rtems_termios_device_lock_acquire(base, &lock_context); ctx->regs->SCIGCR1 &= ~( (1<<7) | (1<<25) | (1<<24) ); @@ -245,7 +246,7 @@ static bool tms570_sci_set_attributes( ctx->regs->SCIGCR1 |= (1<<7) | (1<<25) | (1<<24); - rtems_termios_interrupt_lock_release(tty, &lock_context); + rtems_termios_device_lock_release(base, &lock_context); return true; } @@ -300,18 +301,18 @@ static void tms570_sci_interrupt_handler(void * arg) * TMS570 does not have write data buffer asociated with SCI * so only one character can be written. * - * @param[in] tty rtems_termios_tty + * @param[in] base context of the driver * @param[in] buf buffer of characters pending to send * @param[in] len size of the buffer * @retval Void */ static void tms570_sci_interrupt_write( - rtems_termios_tty *tty, + rtems_termios_device_context *base, const char *buf, size_t len ) { - tms570_sci_context *ctx = rtems_termios_get_device_context(tty); + tms570_sci_context *ctx = (tms570_sci_context *) base; if ( len > 0 ) { /* start UART TX, this will result in an interrupt when done */ @@ -334,18 +335,18 @@ static void tms570_sci_interrupt_write( * Blocking write function. Waits until HW peripheral is ready and then writes * character to HW peripheral. Writes all characters in the buffer. * - * @param[in] tty rtems_termios_tty + * @param[in] base context of the driver * @param[in] buf buffer of characters pending to send * @param[in] len size of the buffer * @retval Void */ static void tms570_sci_poll_write( - rtems_termios_tty *tty, - const char *buf, - size_t n + rtems_termios_device_context *base, + const char *buf, + size_t n ) { - tms570_sci_context *ctx = rtems_termios_get_device_context(tty); + tms570_sci_context *ctx = (tms570_sci_context *) base; size_t i; /* Write */ @@ -394,13 +395,13 @@ static char TMS570_sci_read_char( * * check if there is recieved character to be read and reads it. * - * @param[in] tty rtems_termios_tty (context of the driver) + * @param[in] base context of the driver * @retval -1 No character to be read * @retval x Read character */ -static int tms570_sci_poll_read(rtems_termios_tty *tty) +static int tms570_sci_poll_read(rtems_termios_device_context *base) { - tms570_sci_context *ctx = rtems_termios_get_device_context(tty); + tms570_sci_context *ctx = (tms570_sci_context *) base; /* Check if a character is available */ if ( TMS570_sci_can_read_char(ctx) ) { @@ -416,20 +417,24 @@ static int tms570_sci_poll_read(rtems_termios_tty *tty) * initialization of the HW peripheral specified in contex of the driver. * This function is called only once when opening the driver. * - * @param[in] tty context of the driver + * @param[in] tty Termios control + * @param[in] ctx context of the driver + * @param[in] term Termios attributes * @param[in] args * @retval false Error occured during initialization * @retval true Driver is open and ready */ static bool tms570_sci_poll_first_open( rtems_termios_tty *tty, + rtems_termios_device_context *ctx, + struct termios *term, rtems_libio_open_close_args_t *args ) { bool ok; - rtems_termios_set_best_baud(tty, TMS570_SCI_BAUD_RATE); - ok = tms570_sci_set_attributes(tty, rtems_termios_get_termios(tty)); + rtems_termios_set_best_baud(term, TMS570_SCI_BAUD_RATE); + ok = tms570_sci_set_attributes(ctx, term); if ( !ok ) { return false; } @@ -442,21 +447,24 @@ static bool tms570_sci_poll_first_open( * calls tms570_sci_poll_first_open function. * install and enables interrupts. * - * @param[in] tty context of the driver + * @param[in] tty Termios control + * @param[in] base context of the driver * @param[in] args * @retval false Error occured during initialization * @retval true Driver is open and ready */ static bool tms570_sci_interrupt_first_open( rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, rtems_libio_open_close_args_t *args ) { - tms570_sci_context *ctx = rtems_termios_get_device_context(tty); + tms570_sci_context *ctx = (tms570_sci_context *) base; rtems_status_code sc; bool ret; - ret = tms570_sci_poll_first_open(tty,args); + ret = tms570_sci_poll_first_open(tty, base, term, args); if ( ret == false ) { return false; } @@ -471,20 +479,22 @@ static bool tms570_sci_interrupt_first_open( if ( sc != RTEMS_SUCCESSFUL ) { return false; } - tms570_sci_enable_interrupts(rtems_termios_get_device_context(tty)); + tms570_sci_enable_interrupts(ctx); return true; } /** * @brief closes sci peripheral * - * @param[in] tty context of the driver + * @param[in] tty Termios control + * @param[in] base context of the driver * @param[in] args * @retval false Error occured during initialization * @retval true Driver is open and ready */ static void tms570_sci_poll_last_close( rtems_termios_tty *tty, + rtems_termios_device_context *base, rtems_libio_open_close_args_t *args ) { @@ -496,23 +506,25 @@ static void tms570_sci_poll_last_close( * * calls tms570_sci_poll_last_close and disables interrupts * - * @param[in] tty context of the driver + * @param[in] tty Termios control + * @param[in] base context of the driver * @param[in] args * @retval false Error occured during initialization * @retval true Driver is open and ready */ static void tms570_sci_interrupt_last_close( rtems_termios_tty *tty, + rtems_termios_device_context *base, rtems_libio_open_close_args_t *args ) { - tms570_sci_context *ctx = rtems_termios_get_device_context(tty); + tms570_sci_context *ctx = (tms570_sci_context *) base; rtems_interrupt_lock_context lock_context; /* Turn off RX interrupts */ - rtems_termios_interrupt_lock_acquire(tty, &lock_context); + rtems_termios_device_lock_acquire(base, &lock_context); tms570_sci_disable_interrupts(ctx); - rtems_termios_interrupt_lock_release(tty, &lock_context); + rtems_termios_device_lock_release(base, &lock_context); /* Flush device */ while ( ( ctx->regs->SCIFLR & (1<<11) ) > 0 ) { @@ -522,7 +534,7 @@ static void tms570_sci_interrupt_last_close( /* uninstall ISR */ rtems_interrupt_handler_remove(ctx->irq, tms570_sci_interrupt_handler, tty); - tms570_sci_poll_last_close(tty,args); + tms570_sci_poll_last_close(tty, base, args); } /** diff --git a/c/src/lib/libbsp/arm/tms570/include/tms570-sci-driver.h b/c/src/lib/libbsp/arm/tms570/include/tms570-sci-driver.h index 5f38908499..f32eaea875 100644 --- a/c/src/lib/libbsp/arm/tms570/include/tms570-sci-driver.h +++ b/c/src/lib/libbsp/arm/tms570/include/tms570-sci-driver.h @@ -36,6 +36,7 @@ extern "C" { /* Low-level driver specific data structure */ typedef struct { + rtems_termios_device_context base; const char *device_name; volatile tms570_sci_t *regs; int tx_chars_in_hw; diff --git a/c/src/lib/libbsp/sparc/leon3/console/console.c b/c/src/lib/libbsp/sparc/leon3/console/console.c index 513d45d256..35767ce786 100644 --- a/c/src/lib/libbsp/sparc/leon3/console/console.c +++ b/c/src/lib/libbsp/sparc/leon3/console/console.c @@ -36,7 +36,7 @@ int syscon_uart_index __attribute__((weak)) = 0; static struct apbuart_context apbuarts[BSP_NUMBER_OF_TERMIOS_PORTS]; static int uarts = 0; -static struct apbuart_context *leon3_console_get_uart(int minor) +static rtems_termios_device_context *leon3_console_get_context(int minor) { struct apbuart_context *uart; @@ -45,7 +45,9 @@ static struct apbuart_context *leon3_console_get_uart(int minor) else uart = &apbuarts[minor - 1]; - return uart; + rtems_termios_device_context_initialize(&uart->base, "APBUART"); + + return &uart->base; } /* AMBA PP find routine. Extract AMBA PnP information into data structure. */ @@ -132,7 +134,7 @@ rtems_device_driver console_initialize( minor, handler, NULL, - leon3_console_get_uart(syscon_uart_index) + leon3_console_get_context(syscon_uart_index) ); if (status != RTEMS_SUCCESSFUL) bsp_fatal(LEON3_FATAL_CONSOLE_REGISTER_DEV); @@ -149,7 +151,7 @@ rtems_device_driver console_initialize( minor, handler, NULL, - leon3_console_get_uart(syscon_uart_index) + leon3_console_get_context(syscon_uart_index) ); } diff --git a/c/src/lib/libbsp/sparc/shared/include/apbuart_termios.h b/c/src/lib/libbsp/sparc/shared/include/apbuart_termios.h index ba5f049e09..40377c1023 100644 --- a/c/src/lib/libbsp/sparc/shared/include/apbuart_termios.h +++ b/c/src/lib/libbsp/sparc/shared/include/apbuart_termios.h @@ -22,6 +22,7 @@ extern "C" { #endif /* __cplusplus */ struct apbuart_context { + rtems_termios_device_context base; struct apbuart_regs *regs; unsigned int freq_hz; rtems_vector_number irq; diff --git a/c/src/lib/libbsp/sparc/shared/uart/apbuart_termios.c b/c/src/lib/libbsp/sparc/shared/uart/apbuart_termios.c index dd3ca5db3d..05bd608711 100644 --- a/c/src/lib/libbsp/sparc/shared/uart/apbuart_termios.c +++ b/c/src/lib/libbsp/sparc/shared/uart/apbuart_termios.c @@ -41,12 +41,12 @@ static void apbuart_isr(void *arg) } static void apbuart_write_support( - rtems_termios_tty *tty, + rtems_termios_device_context *base, const char *buf, size_t len ) { - struct apbuart_context *uart = rtems_termios_get_device_context(tty); + struct apbuart_context *uart = (struct apbuart_context *) base; int sending; if (len > 0) { @@ -69,12 +69,12 @@ static void apbuart_write_support( } static void apbuart_write_polled( - rtems_termios_tty *tty, + rtems_termios_device_context *base, const char *buf, size_t len ) { - struct apbuart_context *uart = rtems_termios_get_device_context(tty); + struct apbuart_context *uart = (struct apbuart_context *) base; size_t nwrite = 0; while (nwrite < len) { @@ -83,19 +83,19 @@ static void apbuart_write_polled( } } -static int apbuart_poll_read(rtems_termios_tty *tty) +static int apbuart_poll_read(rtems_termios_device_context *base) { - struct apbuart_context *uart = rtems_termios_get_device_context(tty); + struct apbuart_context *uart = (struct apbuart_context *) base; return apbuart_inbyte_nonblocking(uart->regs); } static bool apbuart_set_attributes( - rtems_termios_tty *tty, + rtems_termios_device_context *base, const struct termios *t ) { - struct apbuart_context *uart = rtems_termios_get_device_context(tty); + struct apbuart_context *uart = (struct apbuart_context *) base; rtems_interrupt_lock_context lock_context; unsigned int scaler; unsigned int ctrl; @@ -112,7 +112,7 @@ static bool apbuart_set_attributes( break; } - rtems_termios_interrupt_lock_acquire(tty, &lock_context); + rtems_termios_device_lock_acquire(base, &lock_context); /* Read out current value */ ctrl = uart->regs->ctrl; @@ -145,7 +145,7 @@ static bool apbuart_set_attributes( /* Update new settings */ uart->regs->ctrl = ctrl; - rtems_termios_interrupt_lock_release(tty, &lock_context); + rtems_termios_device_lock_release(base, &lock_context); /* Baud rate */ baud = rtems_termios_baud_to_number(t->c_cflag); @@ -161,23 +161,25 @@ static bool apbuart_set_attributes( } static void apbuart_set_best_baud( - rtems_termios_tty *tty, - const struct apbuart_context *uart + const struct apbuart_context *uart, + struct termios *term ) { uint32_t baud = (uart->freq_hz * 10) / ((uart->regs->scaler * 10 + 5) * 8); - rtems_termios_set_best_baud(tty, baud); + rtems_termios_set_best_baud(term, baud); } static bool apbuart_first_open_polled( rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, rtems_libio_open_close_args_t *args ) { - struct apbuart_context *uart = rtems_termios_get_device_context(tty); + struct apbuart_context *uart = (struct apbuart_context *) base; - apbuart_set_best_baud(tty, uart); + apbuart_set_best_baud(uart, term); /* Initialize UART on opening */ uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; @@ -188,13 +190,15 @@ static bool apbuart_first_open_polled( static bool apbuart_first_open_interrupt( rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, rtems_libio_open_close_args_t *args ) { - struct apbuart_context *uart = rtems_termios_get_device_context(tty); + struct apbuart_context *uart = (struct apbuart_context *) base; rtems_status_code sc; - apbuart_set_best_baud(tty, uart); + apbuart_set_best_baud(uart, term); /* Register Interrupt handler */ sc = rtems_interrupt_handler_install(uart->irq, "console", @@ -217,16 +221,17 @@ static bool apbuart_first_open_interrupt( static void apbuart_last_close_interrupt( rtems_termios_tty *tty, + rtems_termios_device_context *base, rtems_libio_open_close_args_t *args ) { - struct apbuart_context *uart = rtems_termios_get_device_context(tty); + struct apbuart_context *uart = (struct apbuart_context *) base; rtems_interrupt_lock_context lock_context; /* Turn off RX interrupts */ - rtems_termios_interrupt_lock_acquire(tty, &lock_context); + rtems_termios_device_lock_acquire(base, &lock_context); uart->regs->ctrl &= ~(APBUART_CTRL_RI); - rtems_termios_interrupt_lock_release(tty, &lock_context); + rtems_termios_device_lock_release(base, &lock_context); /**** Flush device ****/ while (uart->sending) { diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h index 045a91f4c2..71be95fc06 100644 --- a/cpukit/libcsupport/include/rtems/termiostypes.h +++ b/cpukit/libcsupport/include/rtems/termiostypes.h @@ -63,6 +63,42 @@ typedef enum { struct rtems_termios_tty; /** + * @brief Termios device context. + * + * @see RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER(), + * rtems_termios_device_context_initialize() and + * rtems_termios_device_install(). + */ +typedef struct rtems_termios_device_context { + rtems_interrupt_lock interrupt_lock; +} rtems_termios_device_context; + +/** + * @brief Initializes a device context. + * + * @param[in] context The Termios device context. + * @param[in] name The name for the interrupt lock. This name must be a + * string persistent throughout the life time of this lock. The name is only + * used if profiling is enabled. + */ +RTEMS_INLINE_ROUTINE void rtems_termios_device_context_initialize( + rtems_termios_device_context *context, + const char *name +) +{ + rtems_interrupt_lock_initialize( &context->interrupt_lock, name ); +} + +/** + * @brief Initializer for static initialization of Termios device contexts. + * + * @param name The name for the interrupt lock. It must be a string. The name + * is only used if profiling is enabled. + */ +#define RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( name ) \ + { RTEMS_INTERRUPT_LOCK_INITIALIZER( name ) } + +/** * @brief Termios device handler. * * @see rtems_termios_device_install(). @@ -71,18 +107,24 @@ typedef struct { /** * @brief First open of this device. * - * @param[in] tty The Termios control. + * @param[in] tty The Termios control. This parameter may be passed to + * interrupt service routines since it must be provided for the + * rtems_termios_enqueue_raw_characters() and + * rtems_termios_dequeue_characters() functions. + * @param[in] context The Termios device context. + * @param[in] term The current Termios attributes. * @param[in] args The open/close arguments. This is parameter provided to * support legacy drivers. It must not be used by new drivers. * * @retval true Successful operation. * @retval false Cannot open device. * - * @see rtems_termios_get_device_context(), rtems_termios_set_best_baud() and - * rtems_termios_get_termios(). + * @see rtems_termios_get_device_context() and rtems_termios_set_best_baud(). */ bool (*first_open)( struct rtems_termios_tty *tty, + rtems_termios_device_context *context, + struct termios *term, rtems_libio_open_close_args_t *args ); @@ -90,13 +132,13 @@ typedef struct { * @brief Last close of this device. * * @param[in] tty The Termios control. + * @param[in] context The Termios device context. * @param[in] args The open/close arguments. This is parameter provided to * support legacy drivers. It must not be used by new drivers. - * - * @see rtems_termios_get_device_context(). */ void (*last_close)( struct rtems_termios_tty *tty, + rtems_termios_device_context *context, rtems_libio_open_close_args_t *args ); @@ -106,41 +148,39 @@ typedef struct { * In case mode is TERMIOS_IRQ_DRIVEN or TERMIOS_TASK_DRIVEN, then data is * received via rtems_termios_enqueue_raw_characters(). * - * @param[in] tty The Termios control. + * @param[in] context The Termios device context. * * @retval char The received data encoded as unsigned char. * @retval -1 No data currently available. - * - * @see rtems_termios_get_device_context(). */ - int (*poll_read)(struct rtems_termios_tty *tty); + int (*poll_read)(rtems_termios_device_context *context); /** * @brief Polled write in case mode is TERMIOS_POLLED or write support * otherwise. * - * @param[in] tty The Termios control. + * @param[in] context The Termios device context. * @param[in] buf The output buffer. * @param[in] len The output buffer length in characters. - * - * @see rtems_termios_get_device_context(). */ - void (*write)(struct rtems_termios_tty *tty, const char *buf, size_t len); + void (*write)( + rtems_termios_device_context *context, + const char *buf, + size_t len + ); /** * @brief Set attributes after a Termios settings change. * - * @param[in] tty The Termios control. + * @param[in] context The Termios device context. * @param[in] term The new Termios attributes. * * @retval true Successful operation. * @retval false Invalid attributes. - * - * @see rtems_termios_get_device_context(). */ bool (*set_attributes)( - struct rtems_termios_tty *tty, - const struct termios *term + rtems_termios_device_context *context, + const struct termios *term ); /** @@ -158,20 +198,16 @@ typedef struct { /** * @brief Indicate to stop remote transmitter. * - * @param[in] tty The Termios control. - * - * @see rtems_termios_get_device_context(). + * @param[in] context The Termios device context. */ - void (*stop_remote_tx)(struct rtems_termios_tty *tty); + void (*stop_remote_tx)(rtems_termios_device_context *context); /** * @brief Indicate to start remote transmitter. * - * @param[in] tty The Termios control. - * - * @see rtems_termios_get_device_context(). + * @param[in] context The Termios device context. */ - void (*start_remote_tx)(struct rtems_termios_tty *tty); + void (*start_remote_tx)(rtems_termios_device_context *context); } rtems_termios_device_flow; /** @@ -185,7 +221,7 @@ typedef struct rtems_termios_device_node { rtems_device_minor_number minor; const rtems_termios_device_handler *handler; const rtems_termios_device_flow *flow; - void *context; + rtems_termios_device_context *context; struct rtems_termios_tty *tty; } rtems_termios_device_node; @@ -258,6 +294,11 @@ typedef struct rtems_termios_tty { rtems_termios_callbacks device; /** + * @brief Context for legacy devices using the callbacks. + */ + rtems_termios_device_context legacy_device_context; + + /** * @brief The device handler. */ rtems_termios_device_handler handler; @@ -289,8 +330,6 @@ typedef struct rtems_termios_tty { struct ttywakeup tty_rcv; int tty_rcvwakeup; - rtems_interrupt_lock interrupt_lock; - /** * @brief Corresponding device node. */ @@ -298,10 +337,8 @@ typedef struct rtems_termios_tty { /** * @brief Context for device driver. - * - * @see rtems_termios_get_device_context(). */ - void *device_context; + rtems_termios_device_context *device_context; } rtems_termios_tty; /** @@ -335,7 +372,7 @@ rtems_status_code rtems_termios_device_install( rtems_device_minor_number minor, const rtems_termios_device_handler *handler, const rtems_termios_device_flow *flow, - void *context + rtems_termios_device_context *context ); /** @@ -382,6 +419,8 @@ 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. */ RTEMS_INLINE_ROUTINE void *rtems_termios_get_device_context( const rtems_termios_tty *tty @@ -391,16 +430,33 @@ RTEMS_INLINE_ROUTINE void *rtems_termios_get_device_context( } /** - * @brief Returns the Termios structure. + * @brief Acquires the device lock. * - * It can be used for example in the first open handler to adjust or obtain the - * initial attributes. + * @param[in] context The device context. + * @param[in] lock_context The local interrupt lock context for an acquire and + * release pair. */ -RTEMS_INLINE_ROUTINE struct termios *rtems_termios_get_termios( - rtems_termios_tty *tty +RTEMS_INLINE_ROUTINE void rtems_termios_device_lock_acquire( + rtems_termios_device_context *context, + rtems_interrupt_lock_context *lock_context ) { - return &tty->termios; + rtems_interrupt_lock_acquire( &context->interrupt_lock, lock_context ); +} + +/** + * @brief Releases the device lock. + * + * @param[in] context The device context. + * @param[in] lock_context The local interrupt lock context for an acquire and + * release pair. + */ +RTEMS_INLINE_ROUTINE void rtems_termios_device_lock_release( + rtems_termios_device_context *context, + rtems_interrupt_lock_context *lock_context +) +{ + rtems_interrupt_lock_release( &context->interrupt_lock, lock_context ); } /** @@ -409,12 +465,12 @@ RTEMS_INLINE_ROUTINE struct termios *rtems_termios_get_termios( * The valid Termios baud values are between 0 and 460800. The Termios baud * value is chosen which minimizes the difference to the value specified. * - * @param[in] tty The Termios control. + * @param[in] term The Termios attributes. * @param[in] baud The current baud setting of the device. */ void rtems_termios_set_best_baud( - rtems_termios_tty *tty, - uint32_t baud + struct termios *term, + uint32_t baud ); struct rtems_termios_linesw { @@ -498,12 +554,6 @@ int rtems_termios_set_initial_baud( rtems_termios_baud_t baud ); -#define rtems_termios_interrupt_lock_acquire(tty, level) \ - rtems_interrupt_lock_acquire(&tty->interrupt_lock, level) - -#define rtems_termios_interrupt_lock_release(tty, level) \ - rtems_interrupt_lock_release(&tty->interrupt_lock, level) - #ifdef __cplusplus } #endif diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c index 6119b22a55..f0ecad0130 100644 --- a/cpukit/libcsupport/src/termios.c +++ b/cpukit/libcsupport/src/termios.c @@ -134,7 +134,7 @@ rtems_status_code rtems_termios_device_install( rtems_device_minor_number minor, const rtems_termios_device_handler *handler, const rtems_termios_device_flow *flow, - void *context + rtems_termios_device_context *context ) { rtems_status_code sc; @@ -227,12 +227,23 @@ rtems_status_code rtems_termios_device_remove( return RTEMS_SUCCESSFUL; } +static rtems_termios_tty * +legacyContextToTTY (rtems_termios_device_context *ctx) +{ + return RTEMS_CONTAINER_OF (ctx, rtems_termios_tty, legacy_device_context); +} + static bool rtems_termios_callback_firstOpen( rtems_termios_tty *tty, + rtems_termios_device_context *ctx, + struct termios *term, rtems_libio_open_close_args_t *args ) { + (void) ctx; + (void) term; + (*tty->device.firstOpen) (tty->major, tty->minor, args); return true; @@ -241,48 +252,61 @@ rtems_termios_callback_firstOpen( static void rtems_termios_callback_lastClose( rtems_termios_tty *tty, + rtems_termios_device_context *ctx, rtems_libio_open_close_args_t *args ) { + (void) ctx; + (*tty->device.lastClose) (tty->major, tty->minor, args); } static int -rtems_termios_callback_pollRead (struct rtems_termios_tty *tty) +rtems_termios_callback_pollRead (rtems_termios_device_context *ctx) { + rtems_termios_tty *tty = legacyContextToTTY (ctx); + return (*tty->device.pollRead) (tty->minor); } static void rtems_termios_callback_write( - rtems_termios_tty *tty, - const char *buf, - size_t len + rtems_termios_device_context *ctx, + const char *buf, + size_t len ) { + rtems_termios_tty *tty = legacyContextToTTY (ctx); + (*tty->device.write) (tty->minor, buf, len); } static bool rtems_termios_callback_setAttributes( - rtems_termios_tty *tty, - const struct termios *term + rtems_termios_device_context *ctx, + const struct termios *term ) { + rtems_termios_tty *tty = legacyContextToTTY (ctx); + (*tty->device.setAttributes) (tty->minor, term); return true; } static void -rtems_termios_callback_stopRemoteTx (rtems_termios_tty *tty) +rtems_termios_callback_stopRemoteTx (rtems_termios_device_context *ctx) { + rtems_termios_tty *tty = legacyContextToTTY (ctx); + (*tty->device.stopRemoteTx) (tty->minor); } static void -rtems_termios_callback_startRemoteTx (rtems_termios_tty *tty) +rtems_termios_callback_startRemoteTx (rtems_termios_device_context *ctx) { + rtems_termios_tty *tty = legacyContextToTTY (ctx); + (*tty->device.startRemoteTx) (tty->minor); } @@ -292,21 +316,22 @@ rtems_termios_callback_startRemoteTx (rtems_termios_tty *tty) static void drainOutput (struct rtems_termios_tty *tty) { + rtems_termios_device_context *ctx = tty->device_context; rtems_interrupt_lock_context lock_context; rtems_status_code sc; if (tty->handler.mode != TERMIOS_POLLED) { - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); while (tty->rawOutBuf.Tail != tty->rawOutBuf.Head) { tty->rawOutBufState = rob_wait; - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); sc = rtems_semaphore_obtain( tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT); if (sc != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (sc); - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); } - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); } } @@ -344,7 +369,7 @@ rtems_termios_destroy_tty (rtems_termios_tty *tty, void *arg, bool last_close) rtems_fatal_error_occurred (sc); } if (last_close && tty->handler.last_close) - (*tty->handler.last_close)(tty, arg); + (*tty->handler.last_close)(tty, tty->device_context, arg); if (tty->device_node != NULL) tty->device_node->tty = NULL; @@ -355,7 +380,10 @@ rtems_termios_destroy_tty (rtems_termios_tty *tty, void *arg, bool last_close) if ((tty->handler.poll_read == NULL) || (tty->handler.mode == TERMIOS_TASK_DRIVEN)) rtems_semaphore_delete (tty->rawInBuf.Semaphore); - rtems_interrupt_lock_destroy (&tty->interrupt_lock); + + if (tty->device_context == &tty->legacy_device_context) + rtems_interrupt_lock_destroy (&tty->legacy_device_context.interrupt_lock); + free (tty->rawInBuf.theBuf); free (tty->rawOutBuf.theBuf); free (tty->cbuf); @@ -489,7 +517,10 @@ rtems_termios_open_tty( tty->device = *callbacks; } - rtems_interrupt_lock_initialize (&tty->interrupt_lock, "Termios"); + if (tty->device_context == NULL) { + tty->device_context = &tty->legacy_device_context; + rtems_termios_device_context_initialize (tty->device_context, "Termios"); + } /* * Create I/O tasks @@ -569,8 +600,8 @@ rtems_termios_open_tty( } args->iop->data1 = tty; if (!tty->refcount++) { - if (tty->handler.first_open && - !(*tty->handler.first_open)(tty, args)) { + if (tty->handler.first_open && !(*tty->handler.first_open)( + tty, tty->device_context, &tty->termios, args)) { rtems_termios_destroy_tty(tty, args, false); return NULL; } @@ -683,24 +714,26 @@ rtems_termios_open ( static void flushOutput (struct rtems_termios_tty *tty) { + rtems_termios_device_context *ctx = tty->device_context; rtems_interrupt_lock_context lock_context; - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); tty->rawOutBuf.Tail = 0; tty->rawOutBuf.Head = 0; tty->rawOutBufState = rob_idle; - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); } static void flushInput (struct rtems_termios_tty *tty) { + rtems_termios_device_context *ctx = tty->device_context; rtems_interrupt_lock_context lock_context; - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); tty->rawInBuf.Tail = 0; tty->rawInBuf.Head = 0; - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); } static void @@ -784,6 +817,7 @@ rtems_status_code rtems_termios_bufsize ( static void termios_set_flowctrl(struct rtems_termios_tty *tty) { + rtems_termios_device_context *ctx = tty->device_context; rtems_interrupt_lock_context lock_context; /* * check for flow control options to be switched off @@ -798,16 +832,16 @@ termios_set_flowctrl(struct rtems_termios_tty *tty) /* has output been stopped due to received XOFF? */ if (tty->flow_ctrl & FL_OSTOP) { /* disable interrupts */ - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); tty->flow_ctrl &= ~FL_OSTOP; /* check for chars in output buffer (or rob_state?) */ if (tty->rawOutBufState != rob_idle) { /* if chars available, call write function... */ (*tty->handler.write)( - tty, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1); + ctx, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1); } /* reenable interrupts */ - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); } } /* check for incoming XON/XOFF flow control switched off */ @@ -826,7 +860,7 @@ termios_set_flowctrl(struct rtems_termios_tty *tty) /* restart remote Tx, if it was stopped */ if ((tty->flow_ctrl & FL_IRTSOFF) && (tty->flow.start_remote_tx != NULL)) { - tty->flow.start_remote_tx(tty); + tty->flow.start_remote_tx(ctx); } tty->flow_ctrl &= ~(FL_IRTSOFF); } @@ -906,7 +940,7 @@ rtems_termios_ioctl (void *arg) } } if (tty->handler.set_attributes) { - sc = (*tty->handler.set_attributes)(tty, &tty->termios) ? + sc = (*tty->handler.set_attributes)(tty->device_context, &tty->termios) ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR; } break; @@ -1003,7 +1037,7 @@ startXmit ( nToSend = 0; /* stop transmitter */ if (transmitting) { - (*tty->handler.write) (tty, NULL, 0); + (*tty->handler.write) (tty->device_context, NULL, 0); } } else { /* when flow control XON or XOF, don't send blocks of data */ @@ -1017,7 +1051,7 @@ startXmit ( nToSend = tty->rawOutBuf.Head - newTail; (*tty->handler.write)( - tty, &tty->rawOutBuf.theBuf[newTail], nToSend); + tty->device_context, &tty->rawOutBuf.theBuf[newTail], nToSend); } return nToSend; @@ -1032,11 +1066,12 @@ rtems_termios_puts ( { const char *buf = _buf; unsigned int newHead; + rtems_termios_device_context *ctx = tty->device_context; rtems_interrupt_lock_context lock_context; rtems_status_code sc; if (tty->handler.mode == TERMIOS_POLLED) { - (*tty->handler.write)(tty, buf, len); + (*tty->handler.write)(ctx, buf, len); return; } @@ -1049,15 +1084,15 @@ rtems_termios_puts ( if (newHead >= tty->rawOutBuf.Size) newHead -= tty->rawOutBuf.Size; - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); while (newHead == tty->rawOutBuf.Tail) { tty->rawOutBufState = rob_wait; - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); sc = rtems_semaphore_obtain( tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT); if (sc != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred (sc); - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); } /* Determine free space up to current tail or end of ring buffer */ @@ -1090,7 +1125,7 @@ rtems_termios_puts ( startXmit (tty, tty->rawOutBuf.Tail, false); } - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); buf += nToCopy; len -= nToCopy; @@ -1371,7 +1406,7 @@ fillBufferPoll (struct rtems_termios_tty *tty) if (tty->termios.c_lflag & ICANON) { for (;;) { - n = (*tty->handler.poll_read)(tty); + n = (*tty->handler.poll_read)(tty->device_context); if (n < 0) { rtems_task_wake_after (1); } else { @@ -1384,7 +1419,7 @@ fillBufferPoll (struct rtems_termios_tty *tty) then = rtems_clock_get_ticks_since_boot(); for (;;) { - n = (*tty->handler.poll_read)(tty); + n = (*tty->handler.poll_read)(tty->device_context); if (n < 0) { if (tty->termios.c_cc[VMIN]) { if (tty->termios.c_cc[VTIME] && tty->ccount) { @@ -1447,12 +1482,12 @@ fillBufferQueue (struct rtems_termios_tty *tty) || (tty->flow_ctrl & FL_OSTOP))) { /* XON should be sent now... */ (*tty->handler.write)( - tty, (void *)&(tty->termios.c_cc[VSTART]), 1); + tty->device_context, (void *)&(tty->termios.c_cc[VSTART]), 1); } else if (tty->flow_ctrl & FL_MDRTS) { tty->flow_ctrl &= ~FL_IRTSOFF; /* activate RTS line */ if (tty->flow.start_remote_tx != NULL) { - tty->flow.start_remote_tx(tty); + tty->flow.start_remote_tx(tty->device_context); } } } @@ -1550,6 +1585,7 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len) char c; int dropped = 0; bool flow_rcv = false; /* true, if flow control char received */ + rtems_termios_device_context *ctx = tty->device_context; rtems_interrupt_lock_context lock_context; if (rtems_termios_linesw[tty->t_line].l_rint != NULL) { @@ -1598,21 +1634,21 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len) /* restart output according to FL_ORCVXOF flag */ if ((tty->flow_ctrl & (FL_ORCVXOF | FL_OSTOP)) == FL_OSTOP) { /* disable interrupts */ - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); tty->flow_ctrl &= ~FL_OSTOP; /* check for chars in output buffer (or rob_state?) */ if (tty->rawOutBufState != rob_idle) { /* if chars available, call write function... */ (*tty->handler.write)( - tty, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1); + ctx, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1); } /* reenable interrupts */ - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); } } else { newTail = (tty->rawInBuf.Tail + 1) % tty->rawInBuf.Size; /* if chars_in_buffer > highwater */ - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); if ((((newTail - tty->rawInBuf.Head + tty->rawInBuf.Size) % tty->rawInBuf.Size) > tty->highwater) && !(tty->flow_ctrl & FL_IREQXOF)) { @@ -1625,20 +1661,20 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len) /* if tx is stopped due to XOFF or out of data */ /* call write function here */ tty->flow_ctrl |= FL_ISNTXOF; - (*tty->handler.write)(tty, + (*tty->handler.write)(ctx, (void *)&(tty->termios.c_cc[VSTOP]), 1); } } else if ((tty->flow_ctrl & (FL_MDRTS | FL_IRTSOFF)) == (FL_MDRTS) ) { tty->flow_ctrl |= FL_IRTSOFF; /* deactivate RTS line */ if (tty->flow.stop_remote_tx != NULL) { - tty->flow.stop_remote_tx(tty); + tty->flow.stop_remote_tx(ctx); } } } /* reenable interrupts */ - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); if (newTail == tty->rawInBuf.Head) { dropped++; @@ -1672,16 +1708,17 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) bool wakeUpWriterTask = false; unsigned int newTail; int nToSend; + rtems_termios_device_context *ctx = tty->device_context; rtems_interrupt_lock_context lock_context; int len; - rtems_termios_interrupt_lock_acquire (tty, &lock_context); + rtems_termios_device_lock_acquire (ctx, &lock_context); /* check for XOF/XON to send */ if ((tty->flow_ctrl & (FL_MDXOF | FL_IREQXOF | FL_ISNTXOF)) == (FL_MDXOF | FL_IREQXOF)) { /* XOFF should be sent now... */ - (*tty->handler.write)(tty, (void *)&(tty->termios.c_cc[VSTOP]), 1); + (*tty->handler.write)(ctx, (void *)&(tty->termios.c_cc[VSTOP]), 1); tty->t_dqlen--; tty->flow_ctrl |= FL_ISNTXOF; @@ -1697,7 +1734,7 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) * buffer, although the corresponding data is not yet out! * Therefore the dequeue "length" should be reduced by 1 */ - (*tty->handler.write)(tty, (void *)&(tty->termios.c_cc[VSTART]), 1); + (*tty->handler.write)(ctx, (void *)&(tty->termios.c_cc[VSTART]), 1); tty->t_dqlen--; tty->flow_ctrl &= ~FL_ISNTXOF; @@ -1714,7 +1751,7 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) wakeUpWriterTask = true; } - (*tty->handler.write) (tty, NULL, 0); + (*tty->handler.write) (ctx, NULL, 0); nToSend = 0; } else { len = tty->t_dqlen; @@ -1734,7 +1771,7 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) * Buffer has become empty */ tty->rawOutBufState = rob_idle; - (*tty->handler.write) (tty, NULL, 0); + (*tty->handler.write) (ctx, NULL, 0); nToSend = 0; /* @@ -1751,7 +1788,7 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) } } - rtems_termios_interrupt_lock_release (tty, &lock_context); + rtems_termios_device_lock_release (ctx, &lock_context); if (wakeUpWriterTask) { rtems_semaphore_release (tty->rawOutBuf.Semaphore); @@ -1854,6 +1891,7 @@ static rtems_task rtems_termios_txdaemon(rtems_task_argument argument) static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument) { struct rtems_termios_tty *tty = (struct rtems_termios_tty *)argument; + rtems_termios_device_context *ctx = tty->device_context; rtems_event_set the_event; int c; char c_buf; @@ -1876,7 +1914,7 @@ static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument) /* * do something */ - c = tty->handler.poll_read(tty); + c = tty->handler.poll_read(ctx); if (c != EOF) { /* * poll_read did call enqueue on its own diff --git a/cpukit/libcsupport/src/termios_setbestbaud.c b/cpukit/libcsupport/src/termios_setbestbaud.c index 3d7a3a80f0..768011892e 100644 --- a/cpukit/libcsupport/src/termios_setbestbaud.c +++ b/cpukit/libcsupport/src/termios_setbestbaud.c @@ -19,8 +19,8 @@ #include <rtems/termiostypes.h> void rtems_termios_set_best_baud( - rtems_termios_tty *tty, - uint32_t baud + struct termios *term, + uint32_t baud ) { const rtems_assoc_t *current = &rtems_termios_baud_table[ 0 ]; @@ -41,5 +41,5 @@ void rtems_termios_set_best_baud( cbaud = B460800; } - tty->termios.c_cflag = (tty->termios.c_cflag & ~cbaud_mask) | cbaud; + term->c_cflag = (term->c_cflag & ~cbaud_mask) | cbaud; } diff --git a/cpukit/libnetworking/net/if_ppp.c b/cpukit/libnetworking/net/if_ppp.c index a1d7a62568..95fa556f25 100644 --- a/cpukit/libnetworking/net/if_ppp.c +++ b/cpukit/libnetworking/net/if_ppp.c @@ -387,7 +387,7 @@ static rtems_task ppp_txdaemon(rtems_task_argument arg) /* write out frame byte to start the transmission */ sc->sc_outchar = (u_char)PPP_FLAG; - (*tp->handler.write)(tp, (char *)&sc->sc_outchar, 1); + (*tp->handler.write)(tp->device_context, (char *)&sc->sc_outchar, 1); } /* check to see if we need to free some empty mbufs */ diff --git a/cpukit/libnetworking/net/ppp_tty.c b/cpukit/libnetworking/net/ppp_tty.c index 613d9c5f82..85a336cbf4 100644 --- a/cpukit/libnetworking/net/ppp_tty.c +++ b/cpukit/libnetworking/net/ppp_tty.c @@ -568,6 +568,7 @@ pppstart(struct rtems_termios_tty *tp) u_long ioffset = (u_long )0; struct mbuf *m = (struct mbuf *)0; struct ppp_softc *sc = tp->t_sc; + rtems_termios_device_context *ctx = rtems_termios_get_device_context(tp); /* ensure input is valid and we are busy */ if (( sc != NULL ) && ( sc->sc_outflag & SC_TX_BUSY )) { @@ -606,7 +607,7 @@ pppstart(struct rtems_termios_tty *tp) sc->sc_outflag |= SC_TX_LASTCHAR; sc->sc_outflag &=~(SC_TX_FCS); sc->sc_outchar = (u_char)PPP_FLAG; - (*tp->handler.write)(tp, (char *)&sc->sc_outchar, 1); + (*tp->handler.write)(ctx, (char *)&sc->sc_outchar, 1); return(0); } } @@ -643,7 +644,7 @@ pppstart(struct rtems_termios_tty *tp) } /* write out the character(s) and update the stats */ - (*tp->handler.write)(tp, (char *)sendBegin, (ioffset > 0) ? ioffset : 1); + (*tp->handler.write)(ctx, (char *)sendBegin, (ioffset > 0) ? ioffset : 1); sc->sc_stats.ppp_obytes += (ioffset > 0) ? ioffset : 1; sc->sc_outoff += ioffset; } diff --git a/doc/bsp_howto/console.t b/doc/bsp_howto/console.t index a165f72016..687ecda1a7 100644 --- a/doc/bsp_howto/console.t +++ b/doc/bsp_howto/console.t @@ -274,6 +274,7 @@ initialization example the device name is also present. Her is an example heade /* Low-level driver specific data structure */ typedef struct @{ + rtems_termios_device_context base; const char *device_name; volatile module_register_block *regs; /* More stuff */ @@ -298,12 +299,12 @@ characters from @code{buf} to the serial device specified by @code{tty}. @example @group static void my_driver_poll_write( - rtems_termios_tty *tty, - const char *buf, - size_t n + rtems_termios_device_context *base, + const char *buf, + size_t n ) @{ - my_driver_context *ctx = rtems_termios_get_device_context(tty); + my_driver_context *ctx = (my_driver_context *) base; size_t i; /* Write */ @@ -320,9 +321,9 @@ available, then the routine should return minus one. @example @group -static int my_driver_poll_read(rtems_termios_tty *tty) +static int my_driver_poll_read(rtems_termios_device_context *base) @{ - my_driver_context *ctx = rtems_termios_get_device_context(tty); + my_driver_context *ctx = (my_driver_context *) base; /* Check if a character is available */ if (my_driver_can_read_char(ctx)) @{ @@ -409,12 +410,12 @@ character. @example @group static void my_driver_interrupt_write( - rtems_termios_tty *tty, - const char *buf, - size_t n + rtems_termios_device_context *base, + const char *buf, + size_t n ) @{ - my_driver_context *ctx = rtems_termios_get_device_context(tty); + my_driver_context *ctx = (my_driver_context *) base; /* * Tell the device to transmit some characters from buf (less than @@ -518,10 +519,12 @@ During the first open of the device Termios will call the @group static bool my_driver_first_open( rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, rtems_libio_open_close_args_t *args ) @{ - my_driver_context *ctx = rtems_termios_get_device_context(tty); + my_driver_context *ctx = (my_driver_context *) base; rtems_status_code sc; bool ok; @@ -542,13 +545,13 @@ static bool my_driver_first_open( /* * Alternatively you can set the best baud. */ - rtems_termios_set_best_baud(tty, MY_DRIVER_BAUD_RATE); + rtems_termios_set_best_baud(term, MY_DRIVER_BAUD_RATE); /* * To propagate the initial Termios attributes to the device use * this. */ - ok = my_driver_set_attributes(tty, rtems_termios_get_termios(tty)); + ok = my_driver_set_attributes(base, term); if (!ok) @{ /* This is bad */ @} @@ -574,10 +577,11 @@ happens on the device. @group static void my_driver_last_close( rtems_termios_tty *tty, + rtems_termios_device_context *base, rtems_libio_open_close_args_t *args ) @{ - my_driver_context *ctx = rtems_termios_get_device_context(tty); + my_driver_context *ctx = (my_driver_context *) base; /* * The driver may do some cleanup here. @@ -618,11 +622,11 @@ handler. @example @group static bool my_driver_set_attributes( - rtems_termios_tty *tty, - const struct termios *term + rtems_termios_device_context *base, + const struct termios *term ) @{ - my_driver_context *ctx = rtems_termios_get_device_context(tty); + my_driver_context *ctx = (my_driver_context *) base; /* * Inspect the termios data structure and configure the device diff --git a/testsuites/libtests/termios01/init.c b/testsuites/libtests/termios01/init.c index 080363f07c..c836b3d79e 100644 --- a/testsuites/libtests/termios01/init.c +++ b/testsuites/libtests/termios01/init.c @@ -517,6 +517,11 @@ static void test_termios_cfmakeraw(void) rtems_test_assert( term.c_cflag & CS8 ); } +typedef struct { + rtems_termios_device_context base; + bool done; +} device_context; + static rtems_status_code test_early_device_install_remove( rtems_device_major_number major, rtems_device_minor_number minor, @@ -528,7 +533,7 @@ static rtems_status_code test_early_device_install_remove( rtems_resource_snapshot_take( &snapshot ); - sc = rtems_termios_device_install( "/", 0, 0, NULL, NULL ); + sc = rtems_termios_device_install( "/", 0, 0, NULL, NULL, NULL ); rtems_test_assert( sc == RTEMS_INCORRECT_STATE ); sc = rtems_termios_device_remove( "/", 0, 0 ); @@ -630,14 +635,18 @@ static void test_device_install_remove(void) static bool first_open_error( rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, rtems_libio_open_close_args_t *args ) { - bool *done = rtems_termios_get_device_context( tty ); + device_context *ctx = (device_context *) base; + (void) tty; + (void) term; (void) args; - *done = true; + ctx->done = true; return false; } @@ -655,7 +664,10 @@ static void test_first_open_error(void) rtems_status_code sc; rtems_libio_t iop; rtems_libio_open_close_args_t args; - bool done = false; + device_context ctx = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ), + .done = false + }; rtems_resource_snapshot_take( &snapshot ); @@ -665,7 +677,7 @@ static void test_first_open_error(void) minor, &handler, NULL, - &done + &ctx.base ); rtems_test_assert( sc == RTEMS_SUCCESSFUL ); @@ -673,10 +685,10 @@ static void test_first_open_error(void) memset( &args, 0, sizeof( args ) ); args.iop = &iop; - rtems_test_assert( !done ); + rtems_test_assert( !ctx.done ); sc = rtems_termios_device_open( major, minor, &args ); rtems_test_assert( sc == RTEMS_NO_MEMORY ); - rtems_test_assert( done ); + rtems_test_assert( ctx.done ); sc = rtems_termios_device_remove( &dev[0], major, minor ); rtems_test_assert( sc == RTEMS_SUCCESSFUL ); @@ -685,15 +697,15 @@ static void test_first_open_error(void) } static bool set_attributes_error( - rtems_termios_tty *tty, + rtems_termios_device_context *base, const struct termios *term ) { - bool *done = rtems_termios_get_device_context( tty ); + device_context *ctx = (device_context *) base; (void) term; - *done = true; + ctx->done = true; return false; } @@ -713,7 +725,10 @@ static void test_set_attributes_error(void) rtems_libio_open_close_args_t oc_args; rtems_libio_ioctl_args_t io_args; struct termios term; - bool done = false; + device_context ctx = { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ), + .done = false + }; rtems_resource_snapshot_take( &snapshot ); @@ -723,7 +738,7 @@ static void test_set_attributes_error(void) minor, &handler, NULL, - &done + &ctx.base ); rtems_test_assert( sc == RTEMS_SUCCESSFUL ); @@ -739,10 +754,10 @@ static void test_set_attributes_error(void) io_args.command = RTEMS_IO_SET_ATTRIBUTES; io_args.buffer = &term; - rtems_test_assert( !done ); + rtems_test_assert( !ctx.done ); sc = rtems_termios_ioctl( &io_args ); rtems_test_assert( sc == RTEMS_IO_ERROR ); - rtems_test_assert( done ); + rtems_test_assert( ctx.done ); sc = rtems_termios_device_close( &oc_args ); rtems_test_assert( sc == RTEMS_SUCCESSFUL ); @@ -790,15 +805,14 @@ static void test_set_best_baud(void) size_t i; for ( i = 0; i < n; ++i ) { - rtems_termios_tty tty; - struct termios *term = rtems_termios_get_termios( &tty ); + struct termios term; tcflag_t cbaud_mask = CBAUD; - memset( &tty, 0xff, sizeof( tty ) ); - rtems_termios_set_best_baud( &tty, baud_to_cflag_table[ i ].baud ); + memset( &term, 0xff, sizeof( term ) ); + rtems_termios_set_best_baud( &term, baud_to_cflag_table[ i ].baud ); rtems_test_assert( - (term->c_cflag & cbaud_mask) == baud_to_cflag_table[ i ].cflag + (term.c_cflag & cbaud_mask) == baud_to_cflag_table[ i ].cflag ); } } |