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:
Sebastian Huber committed 2014-10-07 16:35:13 +02:00
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
+3 -3
View File
@@ -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;
}
+1 -1
View File
@@ -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 */
+3 -2
View File
@@ -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
View File
@@ -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
+33 -19
View File
@@ -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
);
}
}