Changeset 2fd3e65f in rtems


Ignore:
Timestamp:
10/07/14 13:42:47 (9 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5, master
Children:
8a9bdc5
Parents:
6ec438e
git-author:
Sebastian Huber <sebastian.huber@…> (10/07/14 13:42:47)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/07/14 14:35:20)
Message:

libchip/serial: Fix NS16550 for pppstart()

Call rtems_termios_dequeue_characters() only in case all characters of
the last write handler invocation have been transmitted. This avoids
problems with pppstart() since the start line discipline does not know
how many characters have been dequeued and assumes the maximum.

Location:
c/src/libchip/serial
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/libchip/serial/ns16550-context.c

    r6ec438e r2fd3e65f  
    163163}
    164164
     165static size_t ns16550_write_to_fifo(
     166  const ns16550_context *ctx,
     167  const char *buf,
     168  size_t len
     169)
     170{
     171  uint32_t port = ctx->port;
     172  ns16550_set_reg set = ctx->set_reg;
     173  size_t out = len > SP_FIFO_SIZE ? SP_FIFO_SIZE : len;
     174  size_t i;
     175
     176  for (i = 0; i < out; ++i) {
     177    (*set)(port, NS16550_TRANSMIT_BUFFER, buf[i]);
     178  }
     179
     180  return out;
     181}
     182
    165183#if defined(BSP_FEATURE_IRQ_EXTENSION) || defined(BSP_FEATURE_IRQ_LEGACY)
    166184
     
    191209    rtems_termios_enqueue_raw_characters(tty, buf, i);
    192210
    193     /* Check if we can dequeue transmitted characters */
    194     if (ctx->transmit_fifo_chars > 0
    195         && (get( port, NS16550_LINE_STATUS) & SP_LSR_THOLD) != 0) {
    196 
    197       /* Dequeue transmitted characters */
    198       rtems_termios_dequeue_characters(
    199         tty,
    200         ctx->transmit_fifo_chars
    201       );
     211    /* Do transmit */
     212    if (ctx->out_total > 0
     213        && (get(port, NS16550_LINE_STATUS) & SP_LSR_THOLD) != 0) {
     214      size_t current = ctx->out_current;
     215
     216      ctx->out_buf += current;
     217      ctx->out_remaining -= current;
     218
     219      if (ctx->out_remaining > 0) {
     220        ctx->out_current =
     221          ns16550_write_to_fifo(ctx, ctx->out_buf, ctx->out_remaining);
     222      } else {
     223        rtems_termios_dequeue_characters(tty, ctx->out_total);
     224      }
    202225    }
    203226  } while ((get( port, NS16550_INTERRUPT_ID) & SP_IID_0) == 0);
     
    578601{
    579602  ns16550_context *ctx = (ns16550_context *) base;
    580   uint32_t port = ctx->port;
    581   ns16550_set_reg set = ctx->set_reg;
    582   int i = 0;
    583   int out = len > SP_FIFO_SIZE ? SP_FIFO_SIZE : len;
    584 
    585   for (i = 0; i < out; ++i) {
    586     set( port, NS16550_TRANSMIT_BUFFER, buf [i]);
    587   }
    588 
    589   ctx->transmit_fifo_chars = out;
    590 
    591   if (out > 0) {
     603
     604  ctx->out_total = len;
     605
     606  if (len > 0) {
     607    ctx->out_remaining = len;
     608    ctx->out_buf = buf;
     609    ctx->out_current = ns16550_write_to_fifo(ctx, buf, len);
     610
    592611    ns16550_enable_interrupts(ctx, NS16550_ENABLE_ALL_INTR);
    593612  } else {
  • c/src/libchip/serial/ns16550.h

    r6ec438e r2fd3e65f  
    7171  bool has_fractional_divider_register;
    7272  uint8_t modem_control;
    73   size_t transmit_fifo_chars;
     73  size_t out_total;
     74  size_t out_remaining;
     75  size_t out_current;
     76  const char *out_buf;
    7477} ns16550_context;
    7578
Note: See TracChangeset for help on using the changeset viewer.