forked from Imagelibrary/rtems
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:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user