From 65483f807d166aba3d26420dcb75ca6f48f26199 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 10 Jun 2013 14:22:28 +0200 Subject: termios: SMP support --- cpukit/libcsupport/include/rtems/termiostypes.h | 8 +++++ cpukit/libcsupport/src/termios.c | 42 +++++++++++++------------ 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); -- cgit v1.2.3