summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-06-10 14:22:28 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-06-12 16:12:50 +0200
commit65483f807d166aba3d26420dcb75ca6f48f26199 (patch)
treea19ffa0a323688f4998a8b095d887337d6edbd7e
parenttermios: Notify driver about inactive transmit (diff)
downloadrtems-65483f807d166aba3d26420dcb75ca6f48f26199.tar.bz2
termios: SMP support
-rw-r--r--cpukit/libcsupport/include/rtems/termiostypes.h8
-rw-r--r--cpukit/libcsupport/src/termios.c42
2 files changed, 30 insertions, 20 deletions
diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h
index 89a997a09e..4f691919bf 100644
--- a/cpukit/libcsupport/include/rtems/termiostypes.h
+++ b/cpukit/libcsupport/include/rtems/termiostypes.h
@@ -140,6 +140,8 @@ struct rtems_termios_tty {
struct ttywakeup tty_snd;
struct ttywakeup tty_rcv;
int tty_rcvwakeup;
+
+ rtems_interrupt_lock interrupt_lock;
};
struct rtems_termios_linesw {
@@ -231,6 +233,12 @@ int rtems_termios_set_initial_baud(
rtems_termios_baud_t baud
);
+#define rtems_termios_interrupt_lock_acquire(tty, level) \
+ rtems_interrupt_lock_acquire(&tty->interrupt_lock, level)
+
+#define rtems_termios_interrupt_lock_release(tty, level) \
+ rtems_interrupt_lock_release(&tty->interrupt_lock, level)
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index 1c87e6b2c6..976c376281 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -230,6 +230,8 @@ rtems_termios_open (
*/
tty->device = *callbacks;
+ rtems_interrupt_lock_initialize (&tty->interrupt_lock);
+
/*
* Create I/O tasks
*/
@@ -340,17 +342,17 @@ drainOutput (struct rtems_termios_tty *tty)
rtems_status_code sc;
if (tty->device.outputUsesInterrupts != TERMIOS_POLLED) {
- rtems_interrupt_disable (level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
while (tty->rawOutBuf.Tail != tty->rawOutBuf.Head) {
tty->rawOutBufState = rob_wait;
- rtems_interrupt_enable (level);
+ rtems_termios_interrupt_lock_release (tty, level);
sc = rtems_semaphore_obtain(
tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (sc);
- rtems_interrupt_disable (level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
}
- rtems_interrupt_enable (level);
+ rtems_termios_interrupt_lock_release (tty, level);
}
}
@@ -359,11 +361,11 @@ flushOutput (struct rtems_termios_tty *tty)
{
rtems_interrupt_level level;
- rtems_interrupt_disable (level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
tty->rawOutBuf.Tail = 0;
tty->rawOutBuf.Head = 0;
tty->rawOutBufState = rob_idle;
- rtems_interrupt_enable (level);
+ rtems_termios_interrupt_lock_release (tty, level);
}
static void
@@ -371,10 +373,10 @@ flushInput (struct rtems_termios_tty *tty)
{
rtems_interrupt_level level;
- rtems_interrupt_disable (level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
tty->rawInBuf.Tail = 0;
tty->rawInBuf.Head = 0;
- rtems_interrupt_enable (level);
+ rtems_termios_interrupt_lock_release (tty, level);
}
rtems_status_code
@@ -481,7 +483,7 @@ termios_set_flowctrl(struct rtems_termios_tty *tty)
/* has output been stopped due to received XOFF? */
if (tty->flow_ctrl & FL_OSTOP) {
/* disable interrupts */
- rtems_interrupt_disable(level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
tty->flow_ctrl &= ~FL_OSTOP;
/* check for chars in output buffer (or rob_state?) */
if (tty->rawOutBufState != rob_idle) {
@@ -490,7 +492,7 @@ termios_set_flowctrl(struct rtems_termios_tty *tty)
tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
}
/* reenable interrupts */
- rtems_interrupt_enable(level);
+ rtems_termios_interrupt_lock_release (tty, level);
}
}
/* check for incoming XON/XOFF flow control switched off */
@@ -691,15 +693,15 @@ rtems_termios_puts (
* with interrupts enabled.
*/
newHead = (newHead + 1) % tty->rawOutBuf.Size;
- rtems_interrupt_disable (level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
while (newHead == tty->rawOutBuf.Tail) {
tty->rawOutBufState = rob_wait;
- rtems_interrupt_enable (level);
+ rtems_termios_interrupt_lock_release (tty, level);
sc = rtems_semaphore_obtain(
tty->rawOutBuf.Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (sc);
- rtems_interrupt_disable (level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
}
tty->rawOutBuf.theBuf[tty->rawOutBuf.Head] = *buf++;
tty->rawOutBuf.Head = newHead;
@@ -714,7 +716,7 @@ rtems_termios_puts (
}
tty->rawOutBufState = rob_busy;
}
- rtems_interrupt_enable (level);
+ rtems_termios_interrupt_lock_release (tty, level);
len--;
}
}
@@ -1216,7 +1218,7 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
/* restart output according to FL_ORCVXOF flag */
if ((tty->flow_ctrl & (FL_ORCVXOF | FL_OSTOP)) == FL_OSTOP) {
/* disable interrupts */
- rtems_interrupt_disable(level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
tty->flow_ctrl &= ~FL_OSTOP;
/* check for chars in output buffer (or rob_state?) */
if (tty->rawOutBufState != rob_idle) {
@@ -1225,12 +1227,12 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1);
}
/* reenable interrupts */
- rtems_interrupt_enable(level);
+ rtems_termios_interrupt_lock_release (tty, level);
}
} else {
newTail = (tty->rawInBuf.Tail + 1) % tty->rawInBuf.Size;
/* if chars_in_buffer > highwater */
- rtems_interrupt_disable(level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
if ((((newTail - tty->rawInBuf.Head + tty->rawInBuf.Size)
% tty->rawInBuf.Size) > tty->highwater) &&
!(tty->flow_ctrl & FL_IREQXOF)) {
@@ -1256,7 +1258,7 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
}
/* reenable interrupts */
- rtems_interrupt_enable(level);
+ rtems_termios_interrupt_lock_release (tty, level);
if (newTail == tty->rawInBuf.Head) {
dropped++;
@@ -1293,7 +1295,7 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
rtems_interrupt_level level;
int len;
- rtems_interrupt_disable(level);
+ rtems_termios_interrupt_lock_acquire (tty, level);
/* check for XOF/XON to send */
if ((tty->flow_ctrl & (FL_MDXOF | FL_IREQXOF | FL_ISNTXOF))
@@ -1392,7 +1394,7 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
tty->rawOutBuf.Tail = newTail; /*apm*/
}
- rtems_interrupt_enable(level);
+ rtems_termios_interrupt_lock_release (tty, level);
if (wakeUpWriterTask) {
rtems_semaphore_release (tty->rawOutBuf.Semaphore);