mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-11-09 08:37:58 +08:00
termios: Partially hide rtems_termios_tty
Move interrupt lock to device context and expose only this structure to the read, write and set attributes device handler. This makes these device handler independent of the general Termios infrastructure suitable for direct use in printk() support.
This commit is contained in:
1 parent
a830cb864d
commit
7fd5e89c96
12 files changed
+325
-197
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+21
-17
@@ -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
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user