summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libc
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-05-04 12:41:07 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-05-04 12:41:07 +0000
commit161e1b3f6a1a5b0b3a13c48579a3c3e74faff4a1 (patch)
treec48b7a933aa793c98aecef2dec6f113ca6ee112f /c/src/lib/libc
parentSwitched to termios callback structure. (diff)
downloadrtems-161e1b3f6a1a5b0b3a13c48579a3c3e74faff4a1.tar.bz2
Patch from Eric Norum to switch to termios callback structure, add
support for device driver support on tcsetattr(), and hardware flow control callbacks.
Diffstat (limited to 'c/src/lib/libc')
-rw-r--r--c/src/lib/libc/libio.h30
-rw-r--r--c/src/lib/libc/termios.c49
2 files changed, 41 insertions, 38 deletions
diff --git a/c/src/lib/libc/libio.h b/c/src/lib/libc/libio.h
index 2f4dedddf0..ec30cf0d08 100644
--- a/c/src/lib/libc/libio.h
+++ b/c/src/lib/libc/libio.h
@@ -128,20 +128,30 @@ void rtems_register_libio_handler(int handler_flag,
#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);
rtems_status_code rtems_termios_open (
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg,
- int (*deviceFirstOpen)(int major, int minor, void *arg),
- int (*deviceLastClose)(int major, int minor, void *arg),
- int (*deviceRead)(int minor),
- int (*deviceWrite)(int minor, const char *buf, int len),
- int deviceOutputUsesInterrupts
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg,
+ const rtems_termios_callbacks *callbacks
);
-
rtems_status_code rtems_termios_close (void *arg);
rtems_status_code rtems_termios_read (void *arg);
rtems_status_code rtems_termios_write (void *arg);
diff --git a/c/src/lib/libc/termios.c b/c/src/lib/libc/termios.c
index 85e171bd16..a41817b28a 100644
--- a/c/src/lib/libc/termios.c
+++ b/c/src/lib/libc/termios.c
@@ -99,7 +99,6 @@ struct rtems_termios_tty {
/*
* Raw output character buffer
*/
- char outputUsesInterrupts;
volatile char rawOutBuf[RAW_OUTPUT_BUFFER_SIZE];
volatile unsigned int rawOutBufHead;
volatile unsigned int rawOutBufTail;
@@ -109,9 +108,7 @@ struct rtems_termios_tty {
/*
* Callbacks to device-specific routines
*/
- int (*lastClose)(int major, int minor, void *arg);
- int (*read)(int minor);
- int (*write)(int minor, const char *buf, int len);
+ rtems_termios_callbacks device;
};
static struct rtems_termios_tty *ttyHead, *ttyTail;
@@ -167,14 +164,10 @@ rtems_termios_initialize (void)
*/
rtems_status_code
rtems_termios_open (
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg,
- int (*deviceFirstOpen)(int major, int minor, void *arg),
- int (*deviceLastClose)(int major, int minor, void *arg),
- int (*deviceRead)(int minor),
- int (*deviceWrite)(int minor, const char *buf, int len),
- int deviceOutputUsesInterrupts
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg,
+ const rtems_termios_callbacks *callbacks
)
{
rtems_status_code sc;
@@ -244,9 +237,8 @@ rtems_termios_open (
/*
* Set callbacks
*/
- tty->write = deviceWrite;
- tty->lastClose = deviceLastClose;
- if ((tty->read = deviceRead) == NULL) {
+ tty->device = *callbacks;
+ if (!tty->device.pollRead) {
sc = rtems_semaphore_create (
rtems_build_name ('T', 'R', 'r', c),
0,
@@ -264,7 +256,6 @@ rtems_termios_open (
*/
tty->column = 0;
tty->cindex = tty->ccount = 0;
- tty->outputUsesInterrupts = deviceOutputUsesInterrupts;
/*
* Set default parameters
@@ -291,8 +282,8 @@ rtems_termios_open (
/*
* Device-specific open
*/
- if (deviceFirstOpen)
- (*deviceFirstOpen) (major, minor, arg);
+ if (tty->device.firstOpen)
+ (*tty->device.firstOpen)(major, minor, arg);
/*
* Bump name characer
@@ -317,8 +308,8 @@ rtems_termios_close (void *arg)
if (sc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (sc);
if (--tty->refcount == 0) {
- if (tty->lastClose)
- (*tty->lastClose) (tty->major, tty->minor, arg);
+ if (tty->device.lastClose)
+ (*tty->device.lastClose)(tty->major, tty->minor, arg);
if (tty->forw == NULL)
ttyTail = tty->back;
else
@@ -330,7 +321,7 @@ rtems_termios_close (void *arg)
rtems_semaphore_delete (tty->isem);
rtems_semaphore_delete (tty->osem);
rtems_semaphore_delete (tty->rawOutBufSemaphore);
- if (tty->read == NULL)
+ if (!tty->device.pollRead)
rtems_semaphore_delete (tty->rawInBufSemaphore);
free (tty);
}
@@ -390,6 +381,8 @@ rtems_termios_ioctl (void *arg)
}
}
}
+ if (tty->device.setAttributes)
+ (*tty->device.setAttributes)(tty->minor, &tty->termios);
break;
}
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_status_code sc;
- if (!tty->outputUsesInterrupts) {
- (*tty->write)(tty->minor, buf, len);
+ if (!tty->device.outputUsesInterrupts) {
+ (*tty->device.write)(tty->minor, buf, len);
return;
}
newHead = tty->rawOutBufHead;
@@ -442,7 +435,7 @@ osend (const char *buf, int len, struct rtems_termios_tty *tty)
if (tty->rawOutBufState == rob_idle) {
rtems_interrupt_enable (level);
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 {
rtems_interrupt_enable (level);
@@ -718,7 +711,7 @@ fillBufferPoll (struct rtems_termios_tty *tty)
if (tty->termios.c_lflag & ICANON) {
for (;;) {
- n = (*tty->read)(tty->minor);
+ n = (*tty->device.pollRead)(tty->minor);
if (n < 0) {
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])
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then);
for (;;) {
- n = (*tty->read)(tty->minor);
+ n = (*tty->device.pollRead)(tty->minor);
if (n < 0) {
if (tty->termios.c_cc[VMIN]) {
if (tty->termios.c_cc[VTIME] && tty->ccount) {
@@ -824,7 +817,7 @@ rtems_termios_read (void *arg)
if (tty->cindex == tty->ccount) {
tty->cindex = tty->ccount = 0;
tty->read_start_column = tty->column;
- if (tty->read)
+ if (tty->device.pollRead)
sc = fillBufferPoll (tty);
else
sc = fillBufferQueue (tty);
@@ -897,7 +890,7 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
nToSend = RAW_OUTPUT_BUFFER_SIZE - newTail;
else
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;
}