Patch from Eric Norum to switch to termios callback structure, add

support for device driver support on tcsetattr(), and hardware
flow control callbacks.
This commit is contained in:
Joel Sherrill
1998-05-04 12:41:07 +00:00
parent 55951bc1e6
commit 161e1b3f6a
7 changed files with 143 additions and 124 deletions

View File

@@ -128,20 +128,30 @@ void rtems_register_libio_handler(int handler_flag,
#define RTEMS_IO_SET_ATTRIBUTES 2 #define RTEMS_IO_SET_ATTRIBUTES 2
/* /*
* Termios prototypes * Callbacks from TERMIOS routines to device-dependent code
*/
#include <termios.h>
typedef struct rtems_termios_callbacks {
int (*firstOpen)(int major, int minor, void *arg);
int (*lastClose)(int major, int minor, void *arg);
int (*pollRead)(int minor);
int (*write)(int minor, const char *buf, int len);
int (*setAttributes)(int minor, const struct termios *t);
int (*stopRemoteTx)(int minor);
int (*startRemoteTx)(int minor);
int outputUsesInterrupts;
} rtems_termios_callbacks;
/*
* Device-independent TERMIOS routines
*/ */
void rtems_termios_initialize (void); void rtems_termios_initialize (void);
rtems_status_code rtems_termios_open ( rtems_status_code rtems_termios_open (
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg, void *arg,
int (*deviceFirstOpen)(int major, int minor, void *arg), const rtems_termios_callbacks *callbacks
int (*deviceLastClose)(int major, int minor, void *arg),
int (*deviceRead)(int minor),
int (*deviceWrite)(int minor, const char *buf, int len),
int deviceOutputUsesInterrupts
); );
rtems_status_code rtems_termios_close (void *arg); rtems_status_code rtems_termios_close (void *arg);
rtems_status_code rtems_termios_read (void *arg); rtems_status_code rtems_termios_read (void *arg);
rtems_status_code rtems_termios_write (void *arg); rtems_status_code rtems_termios_write (void *arg);

View File

@@ -99,7 +99,6 @@ struct rtems_termios_tty {
/* /*
* Raw output character buffer * Raw output character buffer
*/ */
char outputUsesInterrupts;
volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE]; volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE];
volatile unsigned int rawOutBufHead; volatile unsigned int rawOutBufHead;
volatile unsigned int rawOutBufTail; volatile unsigned int rawOutBufTail;
@@ -109,9 +108,7 @@ struct rtems_termios_tty {
/* /*
* Callbacks to device-specific routines * Callbacks to device-specific routines
*/ */
int (*lastClose)(int major, int minor, void *arg); rtems_termios_callbacks device;
int (*read)(int minor);
int (*write)(int minor, const char *buf, int len);
}; };
static struct rtems_termios_tty *ttyHead, *ttyTail; static struct rtems_termios_tty *ttyHead, *ttyTail;
@@ -167,14 +164,10 @@ rtems_termios_initialize (void)
*/ */
rtems_status_code rtems_status_code
rtems_termios_open ( rtems_termios_open (
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg, void *arg,
int (*deviceFirstOpen)(int major, int minor, void *arg), const rtems_termios_callbacks *callbacks
int (*deviceLastClose)(int major, int minor, void *arg),
int (*deviceRead)(int minor),
int (*deviceWrite)(int minor, const char *buf, int len),
int deviceOutputUsesInterrupts
) )
{ {
rtems_status_code sc; rtems_status_code sc;
@@ -244,9 +237,8 @@ rtems_termios_open (
/* /*
* Set callbacks * Set callbacks
*/ */
tty->write = deviceWrite; tty->device = *callbacks;
tty->lastClose = deviceLastClose; if (!tty->device.pollRead) {
if ((tty->read = deviceRead) == NULL) {
sc = rtems_semaphore_create ( sc = rtems_semaphore_create (
rtems_build_name ('T', 'R', 'r', c), rtems_build_name ('T', 'R', 'r', c),
0, 0,
@@ -264,7 +256,6 @@ rtems_termios_open (
*/ */
tty->column = 0; tty->column = 0;
tty->cindex = tty->ccount = 0; tty->cindex = tty->ccount = 0;
tty->outputUsesInterrupts = deviceOutputUsesInterrupts;
/* /*
* Set default parameters * Set default parameters
@@ -291,8 +282,8 @@ rtems_termios_open (
/* /*
* Device-specific open * Device-specific open
*/ */
if (deviceFirstOpen) if (tty->device.firstOpen)
(*deviceFirstOpen) (major, minor, arg); (*tty->device.firstOpen)(major, minor, arg);
/* /*
* Bump name characer * Bump name characer
@@ -317,8 +308,8 @@ rtems_termios_close (void *arg)
if (sc != RTEMS_SUCCESSFUL) if (sc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (sc); rtems_fatal_error_occurred (sc);
if (--tty->refcount == 0) { if (--tty->refcount == 0) {
if (tty->lastClose) if (tty->device.lastClose)
(*tty->lastClose) (tty->major, tty->minor, arg); (*tty->device.lastClose)(tty->major, tty->minor, arg);
if (tty->forw == NULL) if (tty->forw == NULL)
ttyTail = tty->back; ttyTail = tty->back;
else else
@@ -330,7 +321,7 @@ rtems_termios_close (void *arg)
rtems_semaphore_delete (tty->isem); rtems_semaphore_delete (tty->isem);
rtems_semaphore_delete (tty->osem); rtems_semaphore_delete (tty->osem);
rtems_semaphore_delete (tty->rawOutBufSemaphore); rtems_semaphore_delete (tty->rawOutBufSemaphore);
if (tty->read == NULL) if (!tty->device.pollRead)
rtems_semaphore_delete (tty->rawInBufSemaphore); rtems_semaphore_delete (tty->rawInBufSemaphore);
free (tty); free (tty);
} }
@@ -390,6 +381,8 @@ rtems_termios_ioctl (void *arg)
} }
} }
} }
if (tty->device.setAttributes)
(*tty->device.setAttributes)(tty->minor, &tty->termios);
break; break;
} }
rtems_semaphore_release (tty->osem); rtems_semaphore_release (tty->osem);
@@ -407,8 +400,8 @@ osend (const char *buf, int len, struct rtems_termios_tty *tty)
rtems_interrupt_level level; rtems_interrupt_level level;
rtems_status_code sc; rtems_status_code sc;
if (!tty->outputUsesInterrupts) { if (!tty->device.outputUsesInterrupts) {
(*tty->write)(tty->minor, buf, len); (*tty->device.write)(tty->minor, buf, len);
return; return;
} }
newHead = tty->rawOutBufHead; newHead = tty->rawOutBufHead;
@@ -442,7 +435,7 @@ osend (const char *buf, int len, struct rtems_termios_tty *tty)
if (tty->rawOutBufState == rob_idle) { if (tty->rawOutBufState == rob_idle) {
rtems_interrupt_enable (level); rtems_interrupt_enable (level);
tty->rawOutBufState = rob_busy; tty->rawOutBufState = rob_busy;
(*tty->write)(tty->minor, (char *)&tty->rawOutBuf[tty->rawOutBufTail], 1); (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[tty->rawOutBufTail], 1);
} }
else { else {
rtems_interrupt_enable (level); rtems_interrupt_enable (level);
@@ -718,7 +711,7 @@ fillBufferPoll (struct rtems_termios_tty *tty)
if (tty->termios.c_lflag & ICANON) { if (tty->termios.c_lflag & ICANON) {
for (;;) { for (;;) {
n = (*tty->read)(tty->minor); n = (*tty->device.pollRead)(tty->minor);
if (n < 0) { if (n < 0) {
rtems_task_wake_after (1); rtems_task_wake_after (1);
} }
@@ -733,7 +726,7 @@ fillBufferPoll (struct rtems_termios_tty *tty)
if (!tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME]) if (!tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then); rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
for (;;) { for (;;) {
n = (*tty->read)(tty->minor); n = (*tty->device.pollRead)(tty->minor);
if (n < 0) { if (n < 0) {
if (tty->termios.c_cc[VMIN]) { if (tty->termios.c_cc[VMIN]) {
if (tty->termios.c_cc[VTIME] && tty->ccount) { if (tty->termios.c_cc[VTIME] && tty->ccount) {
@@ -824,7 +817,7 @@ rtems_termios_read (void *arg)
if (tty->cindex == tty->ccount) { if (tty->cindex == tty->ccount) {
tty->cindex = tty->ccount = 0; tty->cindex = tty->ccount = 0;
tty->read_start_column = tty->column; tty->read_start_column = tty->column;
if (tty->read) if (tty->device.pollRead)
sc = fillBufferPoll (tty); sc = fillBufferPoll (tty);
else else
sc = fillBufferQueue (tty); sc = fillBufferQueue (tty);
@@ -897,7 +890,7 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail; nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail;
else else
nToSend = tty->rawOutBufHead - newTail; nToSend = tty->rawOutBufHead - newTail;
(*tty->write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend); (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend);
} }
tty->rawOutBufTail = newTail; tty->rawOutBufTail = newTail;
} }

View File

@@ -128,20 +128,30 @@ void rtems_register_libio_handler(int handler_flag,
#define RTEMS_IO_SET_ATTRIBUTES 2 #define RTEMS_IO_SET_ATTRIBUTES 2
/* /*
* Termios prototypes * Callbacks from TERMIOS routines to device-dependent code
*/
#include <termios.h>
typedef struct rtems_termios_callbacks {
int (*firstOpen)(int major, int minor, void *arg);
int (*lastClose)(int major, int minor, void *arg);
int (*pollRead)(int minor);
int (*write)(int minor, const char *buf, int len);
int (*setAttributes)(int minor, const struct termios *t);
int (*stopRemoteTx)(int minor);
int (*startRemoteTx)(int minor);
int outputUsesInterrupts;
} rtems_termios_callbacks;
/*
* Device-independent TERMIOS routines
*/ */
void rtems_termios_initialize (void); void rtems_termios_initialize (void);
rtems_status_code rtems_termios_open ( rtems_status_code rtems_termios_open (
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg, void *arg,
int (*deviceFirstOpen)(int major, int minor, void *arg), const rtems_termios_callbacks *callbacks
int (*deviceLastClose)(int major, int minor, void *arg),
int (*deviceRead)(int minor),
int (*deviceWrite)(int minor, const char *buf, int len),
int deviceOutputUsesInterrupts
); );
rtems_status_code rtems_termios_close (void *arg); rtems_status_code rtems_termios_close (void *arg);
rtems_status_code rtems_termios_read (void *arg); rtems_status_code rtems_termios_read (void *arg);
rtems_status_code rtems_termios_write (void *arg); rtems_status_code rtems_termios_write (void *arg);

View File

@@ -128,20 +128,30 @@ void rtems_register_libio_handler(int handler_flag,
#define RTEMS_IO_SET_ATTRIBUTES 2 #define RTEMS_IO_SET_ATTRIBUTES 2
/* /*
* Termios prototypes * Callbacks from TERMIOS routines to device-dependent code
*/
#include <termios.h>
typedef struct rtems_termios_callbacks {
int (*firstOpen)(int major, int minor, void *arg);
int (*lastClose)(int major, int minor, void *arg);
int (*pollRead)(int minor);
int (*write)(int minor, const char *buf, int len);
int (*setAttributes)(int minor, const struct termios *t);
int (*stopRemoteTx)(int minor);
int (*startRemoteTx)(int minor);
int outputUsesInterrupts;
} rtems_termios_callbacks;
/*
* Device-independent TERMIOS routines
*/ */
void rtems_termios_initialize (void); void rtems_termios_initialize (void);
rtems_status_code rtems_termios_open ( rtems_status_code rtems_termios_open (
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg, void *arg,
int (*deviceFirstOpen)(int major, int minor, void *arg), const rtems_termios_callbacks *callbacks
int (*deviceLastClose)(int major, int minor, void *arg),
int (*deviceRead)(int minor),
int (*deviceWrite)(int minor, const char *buf, int len),
int deviceOutputUsesInterrupts
); );
rtems_status_code rtems_termios_close (void *arg); rtems_status_code rtems_termios_close (void *arg);
rtems_status_code rtems_termios_read (void *arg); rtems_status_code rtems_termios_read (void *arg);
rtems_status_code rtems_termios_write (void *arg); rtems_status_code rtems_termios_write (void *arg);

View File

@@ -99,7 +99,6 @@ struct rtems_termios_tty {
/* /*
* Raw output character buffer * Raw output character buffer
*/ */
char outputUsesInterrupts;
volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE]; volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE];
volatile unsigned int rawOutBufHead; volatile unsigned int rawOutBufHead;
volatile unsigned int rawOutBufTail; volatile unsigned int rawOutBufTail;
@@ -109,9 +108,7 @@ struct rtems_termios_tty {
/* /*
* Callbacks to device-specific routines * Callbacks to device-specific routines
*/ */
int (*lastClose)(int major, int minor, void *arg); rtems_termios_callbacks device;
int (*read)(int minor);
int (*write)(int minor, const char *buf, int len);
}; };
static struct rtems_termios_tty *ttyHead, *ttyTail; static struct rtems_termios_tty *ttyHead, *ttyTail;
@@ -167,14 +164,10 @@ rtems_termios_initialize (void)
*/ */
rtems_status_code rtems_status_code
rtems_termios_open ( rtems_termios_open (
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg, void *arg,
int (*deviceFirstOpen)(int major, int minor, void *arg), const rtems_termios_callbacks *callbacks
int (*deviceLastClose)(int major, int minor, void *arg),
int (*deviceRead)(int minor),
int (*deviceWrite)(int minor, const char *buf, int len),
int deviceOutputUsesInterrupts
) )
{ {
rtems_status_code sc; rtems_status_code sc;
@@ -244,9 +237,8 @@ rtems_termios_open (
/* /*
* Set callbacks * Set callbacks
*/ */
tty->write = deviceWrite; tty->device = *callbacks;
tty->lastClose = deviceLastClose; if (!tty->device.pollRead) {
if ((tty->read = deviceRead) == NULL) {
sc = rtems_semaphore_create ( sc = rtems_semaphore_create (
rtems_build_name ('T', 'R', 'r', c), rtems_build_name ('T', 'R', 'r', c),
0, 0,
@@ -264,7 +256,6 @@ rtems_termios_open (
*/ */
tty->column = 0; tty->column = 0;
tty->cindex = tty->ccount = 0; tty->cindex = tty->ccount = 0;
tty->outputUsesInterrupts = deviceOutputUsesInterrupts;
/* /*
* Set default parameters * Set default parameters
@@ -291,8 +282,8 @@ rtems_termios_open (
/* /*
* Device-specific open * Device-specific open
*/ */
if (deviceFirstOpen) if (tty->device.firstOpen)
(*deviceFirstOpen) (major, minor, arg); (*tty->device.firstOpen)(major, minor, arg);
/* /*
* Bump name characer * Bump name characer
@@ -317,8 +308,8 @@ rtems_termios_close (void *arg)
if (sc != RTEMS_SUCCESSFUL) if (sc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (sc); rtems_fatal_error_occurred (sc);
if (--tty->refcount == 0) { if (--tty->refcount == 0) {
if (tty->lastClose) if (tty->device.lastClose)
(*tty->lastClose) (tty->major, tty->minor, arg); (*tty->device.lastClose)(tty->major, tty->minor, arg);
if (tty->forw == NULL) if (tty->forw == NULL)
ttyTail = tty->back; ttyTail = tty->back;
else else
@@ -330,7 +321,7 @@ rtems_termios_close (void *arg)
rtems_semaphore_delete (tty->isem); rtems_semaphore_delete (tty->isem);
rtems_semaphore_delete (tty->osem); rtems_semaphore_delete (tty->osem);
rtems_semaphore_delete (tty->rawOutBufSemaphore); rtems_semaphore_delete (tty->rawOutBufSemaphore);
if (tty->read == NULL) if (!tty->device.pollRead)
rtems_semaphore_delete (tty->rawInBufSemaphore); rtems_semaphore_delete (tty->rawInBufSemaphore);
free (tty); free (tty);
} }
@@ -390,6 +381,8 @@ rtems_termios_ioctl (void *arg)
} }
} }
} }
if (tty->device.setAttributes)
(*tty->device.setAttributes)(tty->minor, &tty->termios);
break; break;
} }
rtems_semaphore_release (tty->osem); rtems_semaphore_release (tty->osem);
@@ -407,8 +400,8 @@ osend (const char *buf, int len, struct rtems_termios_tty *tty)
rtems_interrupt_level level; rtems_interrupt_level level;
rtems_status_code sc; rtems_status_code sc;
if (!tty->outputUsesInterrupts) { if (!tty->device.outputUsesInterrupts) {
(*tty->write)(tty->minor, buf, len); (*tty->device.write)(tty->minor, buf, len);
return; return;
} }
newHead = tty->rawOutBufHead; newHead = tty->rawOutBufHead;
@@ -442,7 +435,7 @@ osend (const char *buf, int len, struct rtems_termios_tty *tty)
if (tty->rawOutBufState == rob_idle) { if (tty->rawOutBufState == rob_idle) {
rtems_interrupt_enable (level); rtems_interrupt_enable (level);
tty->rawOutBufState = rob_busy; tty->rawOutBufState = rob_busy;
(*tty->write)(tty->minor, (char *)&tty->rawOutBuf[tty->rawOutBufTail], 1); (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[tty->rawOutBufTail], 1);
} }
else { else {
rtems_interrupt_enable (level); rtems_interrupt_enable (level);
@@ -718,7 +711,7 @@ fillBufferPoll (struct rtems_termios_tty *tty)
if (tty->termios.c_lflag & ICANON) { if (tty->termios.c_lflag & ICANON) {
for (;;) { for (;;) {
n = (*tty->read)(tty->minor); n = (*tty->device.pollRead)(tty->minor);
if (n < 0) { if (n < 0) {
rtems_task_wake_after (1); rtems_task_wake_after (1);
} }
@@ -733,7 +726,7 @@ fillBufferPoll (struct rtems_termios_tty *tty)
if (!tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME]) if (!tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then); rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
for (;;) { for (;;) {
n = (*tty->read)(tty->minor); n = (*tty->device.pollRead)(tty->minor);
if (n < 0) { if (n < 0) {
if (tty->termios.c_cc[VMIN]) { if (tty->termios.c_cc[VMIN]) {
if (tty->termios.c_cc[VTIME] && tty->ccount) { if (tty->termios.c_cc[VTIME] && tty->ccount) {
@@ -824,7 +817,7 @@ rtems_termios_read (void *arg)
if (tty->cindex == tty->ccount) { if (tty->cindex == tty->ccount) {
tty->cindex = tty->ccount = 0; tty->cindex = tty->ccount = 0;
tty->read_start_column = tty->column; tty->read_start_column = tty->column;
if (tty->read) if (tty->device.pollRead)
sc = fillBufferPoll (tty); sc = fillBufferPoll (tty);
else else
sc = fillBufferQueue (tty); sc = fillBufferQueue (tty);
@@ -897,7 +890,7 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail; nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail;
else else
nToSend = tty->rawOutBufHead - newTail; nToSend = tty->rawOutBufHead - newTail;
(*tty->write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend); (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend);
} }
tty->rawOutBufTail = newTail; tty->rawOutBufTail = newTail;
} }

View File

@@ -128,20 +128,30 @@ void rtems_register_libio_handler(int handler_flag,
#define RTEMS_IO_SET_ATTRIBUTES 2 #define RTEMS_IO_SET_ATTRIBUTES 2
/* /*
* Termios prototypes * Callbacks from TERMIOS routines to device-dependent code
*/
#include <termios.h>
typedef struct rtems_termios_callbacks {
int (*firstOpen)(int major, int minor, void *arg);
int (*lastClose)(int major, int minor, void *arg);
int (*pollRead)(int minor);
int (*write)(int minor, const char *buf, int len);
int (*setAttributes)(int minor, const struct termios *t);
int (*stopRemoteTx)(int minor);
int (*startRemoteTx)(int minor);
int outputUsesInterrupts;
} rtems_termios_callbacks;
/*
* Device-independent TERMIOS routines
*/ */
void rtems_termios_initialize (void); void rtems_termios_initialize (void);
rtems_status_code rtems_termios_open ( rtems_status_code rtems_termios_open (
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg, void *arg,
int (*deviceFirstOpen)(int major, int minor, void *arg), const rtems_termios_callbacks *callbacks
int (*deviceLastClose)(int major, int minor, void *arg),
int (*deviceRead)(int minor),
int (*deviceWrite)(int minor, const char *buf, int len),
int deviceOutputUsesInterrupts
); );
rtems_status_code rtems_termios_close (void *arg); rtems_status_code rtems_termios_close (void *arg);
rtems_status_code rtems_termios_read (void *arg); rtems_status_code rtems_termios_read (void *arg);
rtems_status_code rtems_termios_write (void *arg); rtems_status_code rtems_termios_write (void *arg);

View File

@@ -99,7 +99,6 @@ struct rtems_termios_tty {
/* /*
* Raw output character buffer * Raw output character buffer
*/ */
char outputUsesInterrupts;
volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE]; volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE];
volatile unsigned int rawOutBufHead; volatile unsigned int rawOutBufHead;
volatile unsigned int rawOutBufTail; volatile unsigned int rawOutBufTail;
@@ -109,9 +108,7 @@ struct rtems_termios_tty {
/* /*
* Callbacks to device-specific routines * Callbacks to device-specific routines
*/ */
int (*lastClose)(int major, int minor, void *arg); rtems_termios_callbacks device;
int (*read)(int minor);
int (*write)(int minor, const char *buf, int len);
}; };
static struct rtems_termios_tty *ttyHead, *ttyTail; static struct rtems_termios_tty *ttyHead, *ttyTail;
@@ -167,14 +164,10 @@ rtems_termios_initialize (void)
*/ */
rtems_status_code rtems_status_code
rtems_termios_open ( rtems_termios_open (
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *arg, void *arg,
int (*deviceFirstOpen)(int major, int minor, void *arg), const rtems_termios_callbacks *callbacks
int (*deviceLastClose)(int major, int minor, void *arg),
int (*deviceRead)(int minor),
int (*deviceWrite)(int minor, const char *buf, int len),
int deviceOutputUsesInterrupts
) )
{ {
rtems_status_code sc; rtems_status_code sc;
@@ -244,9 +237,8 @@ rtems_termios_open (
/* /*
* Set callbacks * Set callbacks
*/ */
tty->write = deviceWrite; tty->device = *callbacks;
tty->lastClose = deviceLastClose; if (!tty->device.pollRead) {
if ((tty->read = deviceRead) == NULL) {
sc = rtems_semaphore_create ( sc = rtems_semaphore_create (
rtems_build_name ('T', 'R', 'r', c), rtems_build_name ('T', 'R', 'r', c),
0, 0,
@@ -264,7 +256,6 @@ rtems_termios_open (
*/ */
tty->column = 0; tty->column = 0;
tty->cindex = tty->ccount = 0; tty->cindex = tty->ccount = 0;
tty->outputUsesInterrupts = deviceOutputUsesInterrupts;
/* /*
* Set default parameters * Set default parameters
@@ -291,8 +282,8 @@ rtems_termios_open (
/* /*
* Device-specific open * Device-specific open
*/ */
if (deviceFirstOpen) if (tty->device.firstOpen)
(*deviceFirstOpen) (major, minor, arg); (*tty->device.firstOpen)(major, minor, arg);
/* /*
* Bump name characer * Bump name characer
@@ -317,8 +308,8 @@ rtems_termios_close (void *arg)
if (sc != RTEMS_SUCCESSFUL) if (sc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (sc); rtems_fatal_error_occurred (sc);
if (--tty->refcount == 0) { if (--tty->refcount == 0) {
if (tty->lastClose) if (tty->device.lastClose)
(*tty->lastClose) (tty->major, tty->minor, arg); (*tty->device.lastClose)(tty->major, tty->minor, arg);
if (tty->forw == NULL) if (tty->forw == NULL)
ttyTail = tty->back; ttyTail = tty->back;
else else
@@ -330,7 +321,7 @@ rtems_termios_close (void *arg)
rtems_semaphore_delete (tty->isem); rtems_semaphore_delete (tty->isem);
rtems_semaphore_delete (tty->osem); rtems_semaphore_delete (tty->osem);
rtems_semaphore_delete (tty->rawOutBufSemaphore); rtems_semaphore_delete (tty->rawOutBufSemaphore);
if (tty->read == NULL) if (!tty->device.pollRead)
rtems_semaphore_delete (tty->rawInBufSemaphore); rtems_semaphore_delete (tty->rawInBufSemaphore);
free (tty); free (tty);
} }
@@ -390,6 +381,8 @@ rtems_termios_ioctl (void *arg)
} }
} }
} }
if (tty->device.setAttributes)
(*tty->device.setAttributes)(tty->minor, &tty->termios);
break; break;
} }
rtems_semaphore_release (tty->osem); rtems_semaphore_release (tty->osem);
@@ -407,8 +400,8 @@ osend (const char *buf, int len, struct rtems_termios_tty *tty)
rtems_interrupt_level level; rtems_interrupt_level level;
rtems_status_code sc; rtems_status_code sc;
if (!tty->outputUsesInterrupts) { if (!tty->device.outputUsesInterrupts) {
(*tty->write)(tty->minor, buf, len); (*tty->device.write)(tty->minor, buf, len);
return; return;
} }
newHead = tty->rawOutBufHead; newHead = tty->rawOutBufHead;
@@ -442,7 +435,7 @@ osend (const char *buf, int len, struct rtems_termios_tty *tty)
if (tty->rawOutBufState == rob_idle) { if (tty->rawOutBufState == rob_idle) {
rtems_interrupt_enable (level); rtems_interrupt_enable (level);
tty->rawOutBufState = rob_busy; tty->rawOutBufState = rob_busy;
(*tty->write)(tty->minor, (char *)&tty->rawOutBuf[tty->rawOutBufTail], 1); (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[tty->rawOutBufTail], 1);
} }
else { else {
rtems_interrupt_enable (level); rtems_interrupt_enable (level);
@@ -718,7 +711,7 @@ fillBufferPoll (struct rtems_termios_tty *tty)
if (tty->termios.c_lflag & ICANON) { if (tty->termios.c_lflag & ICANON) {
for (;;) { for (;;) {
n = (*tty->read)(tty->minor); n = (*tty->device.pollRead)(tty->minor);
if (n < 0) { if (n < 0) {
rtems_task_wake_after (1); rtems_task_wake_after (1);
} }
@@ -733,7 +726,7 @@ fillBufferPoll (struct rtems_termios_tty *tty)
if (!tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME]) if (!tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then); rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
for (;;) { for (;;) {
n = (*tty->read)(tty->minor); n = (*tty->device.pollRead)(tty->minor);
if (n < 0) { if (n < 0) {
if (tty->termios.c_cc[VMIN]) { if (tty->termios.c_cc[VMIN]) {
if (tty->termios.c_cc[VTIME] && tty->ccount) { if (tty->termios.c_cc[VTIME] && tty->ccount) {
@@ -824,7 +817,7 @@ rtems_termios_read (void *arg)
if (tty->cindex == tty->ccount) { if (tty->cindex == tty->ccount) {
tty->cindex = tty->ccount = 0; tty->cindex = tty->ccount = 0;
tty->read_start_column = tty->column; tty->read_start_column = tty->column;
if (tty->read) if (tty->device.pollRead)
sc = fillBufferPoll (tty); sc = fillBufferPoll (tty);
else else
sc = fillBufferQueue (tty); sc = fillBufferQueue (tty);
@@ -897,7 +890,7 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail; nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail;
else else
nToSend = tty->rawOutBufHead - newTail; nToSend = tty->rawOutBufHead - newTail;
(*tty->write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend); (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend);
} }
tty->rawOutBufTail = newTail; tty->rawOutBufTail = newTail;
} }