summaryrefslogtreecommitdiffstats
path: root/c/src
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2000-08-01 15:23:59 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2000-08-01 15:23:59 +0000
commite6890ba1f56fc6614b9494331a9f45d65db31649 (patch)
tree250d49da47520a8921e58d148c1f0f258a39a266 /c/src
parentEven more updates. (diff)
downloadrtems-e6890ba1f56fc6614b9494331a9f45d65db31649.tar.bz2
Patch from Eric Norum <eric@cls.usask.ca> to avoid lockup under
the correct circumstances of DMA buffer size, serial line interrupts, and ethernet interrupts the termios osend routine would lock up waiting for the raw output buffer semaphore.
Diffstat (limited to 'c/src')
-rw-r--r--c/src/exec/libcsupport/src/termios.c18
-rw-r--r--c/src/lib/libc/termios.c18
2 files changed, 18 insertions, 18 deletions
diff --git a/c/src/exec/libcsupport/src/termios.c b/c/src/exec/libcsupport/src/termios.c
index dea2608fa6..f70ed23c6a 100644
--- a/c/src/exec/libcsupport/src/termios.c
+++ b/c/src/exec/libcsupport/src/termios.c
@@ -126,7 +126,7 @@ struct rtems_termios_tty {
volatile unsigned int rawOutBufHead;
volatile unsigned int rawOutBufTail;
rtems_id rawOutBufSemaphore;
- enum {rob_idle, rob_busy, rob_wait } rawOutBufState;
+ volatile enum {rob_idle, rob_busy, rob_wait } rawOutBufState;
/*
* Callbacks to device-specific routines
@@ -219,7 +219,7 @@ rtems_termios_open (
sc = rtems_semaphore_create (
rtems_build_name ('T', 'R', 'x', c),
0,
- RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY,
+ RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_FIFO,
RTEMS_NO_PRIORITY,
&tty->rawOutBufSemaphore);
if (sc != RTEMS_SUCCESSFUL)
@@ -531,7 +531,7 @@ osend (const char *buf, int len, struct rtems_termios_tty *tty)
if (tty->rawOutBufState == rob_idle) {
/* check, whether XOFF has been received */
if (!(tty->flow_ctrl & FL_ORCVXOF)) {
- (*tty->device.write)(tty->minor,
+ (*tty->device.write)(tty->minor,
(char *)&tty->rawOutBuf[tty->rawOutBufTail],1);
}
else {
@@ -1101,8 +1101,10 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
else {
if (tty->rawOutBufState == rob_wait)
rtems_semaphore_release (tty->rawOutBufSemaphore);
- if ( tty->rawOutBufHead == tty->rawOutBufTail )
+ if ( tty->rawOutBufHead == tty->rawOutBufTail ) {
+ tty->rawOutBufState = rob_idle;
return 0;
+ }
newTail = (tty->rawOutBufTail + len) % RAW_OUTPUT_BUFFER_SIZE;
if (newTail == tty->rawOutBufHead) {
/*
@@ -1117,6 +1119,7 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
/* Buffer not empty, but output stops due to XOFF */
/* set flag, that output has been stopped */
tty->flow_ctrl |= FL_OSTOP;
+ tty->rawOutBufState = rob_busy;
nToSend = 0;
}
else {
@@ -1130,15 +1133,12 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
/* when flow control XON or XOF, don't send blocks of data */
/* to allow fast reaction on incoming flow ctrl and low latency*/
/* for outgoing flow control */
- if (tty->flow_ctrl & (FL_MDXON | FL_MDXOF)) {
+ if (tty->flow_ctrl & (FL_MDXON | FL_MDXOF))
nToSend = 1;
- }
- (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend);
tty->rawOutBufState = rob_busy;
+ (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend);
}
tty->rawOutBufTail = newTail;
}
return nToSend;
}
-
-
diff --git a/c/src/lib/libc/termios.c b/c/src/lib/libc/termios.c
index dea2608fa6..f70ed23c6a 100644
--- a/c/src/lib/libc/termios.c
+++ b/c/src/lib/libc/termios.c
@@ -126,7 +126,7 @@ struct rtems_termios_tty {
volatile unsigned int rawOutBufHead;
volatile unsigned int rawOutBufTail;
rtems_id rawOutBufSemaphore;
- enum {rob_idle, rob_busy, rob_wait } rawOutBufState;
+ volatile enum {rob_idle, rob_busy, rob_wait } rawOutBufState;
/*
* Callbacks to device-specific routines
@@ -219,7 +219,7 @@ rtems_termios_open (
sc = rtems_semaphore_create (
rtems_build_name ('T', 'R', 'x', c),
0,
- RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY,
+ RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_FIFO,
RTEMS_NO_PRIORITY,
&tty->rawOutBufSemaphore);
if (sc != RTEMS_SUCCESSFUL)
@@ -531,7 +531,7 @@ osend (const char *buf, int len, struct rtems_termios_tty *tty)
if (tty->rawOutBufState == rob_idle) {
/* check, whether XOFF has been received */
if (!(tty->flow_ctrl & FL_ORCVXOF)) {
- (*tty->device.write)(tty->minor,
+ (*tty->device.write)(tty->minor,
(char *)&tty->rawOutBuf[tty->rawOutBufTail],1);
}
else {
@@ -1101,8 +1101,10 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
else {
if (tty->rawOutBufState == rob_wait)
rtems_semaphore_release (tty->rawOutBufSemaphore);
- if ( tty->rawOutBufHead == tty->rawOutBufTail )
+ if ( tty->rawOutBufHead == tty->rawOutBufTail ) {
+ tty->rawOutBufState = rob_idle;
return 0;
+ }
newTail = (tty->rawOutBufTail + len) % RAW_OUTPUT_BUFFER_SIZE;
if (newTail == tty->rawOutBufHead) {
/*
@@ -1117,6 +1119,7 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
/* Buffer not empty, but output stops due to XOFF */
/* set flag, that output has been stopped */
tty->flow_ctrl |= FL_OSTOP;
+ tty->rawOutBufState = rob_busy;
nToSend = 0;
}
else {
@@ -1130,15 +1133,12 @@ rtems_termios_dequeue_characters (void *ttyp, int len)
/* when flow control XON or XOF, don't send blocks of data */
/* to allow fast reaction on incoming flow ctrl and low latency*/
/* for outgoing flow control */
- if (tty->flow_ctrl & (FL_MDXON | FL_MDXOF)) {
+ if (tty->flow_ctrl & (FL_MDXON | FL_MDXOF))
nToSend = 1;
- }
- (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend);
tty->rawOutBufState = rob_busy;
+ (*tty->device.write)(tty->minor, (char *)&tty->rawOutBuf[newTail], nToSend);
}
tty->rawOutBufTail = newTail;
}
return nToSend;
}
-
-