forked from Imagelibrary/rtems
termios: SMP support
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user