Changeset 6cc69f1 in rtems


Ignore:
Timestamp:
Jun 28, 2010, 6:48:32 PM (9 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.11, master
Children:
ef87186
Parents:
43efb633
Message:

2010-06-28 Joel Sherrill <joel.sherrilL@…>

  • libcsupport/src/termios.c: Formatting.
Location:
cpukit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/ChangeLog

    r43efb633 r6cc69f1  
     12010-06-28      Joel Sherrill <joel.sherrilL@OARcorp.com>
     2
     3        * libcsupport/src/termios.c: Formatting.
     4
    152010-06-28      Joel Sherrill <joel.sherrill@oarcorp.com>
    26
  • cpukit/libcsupport/src/termios.c

    r43efb633 r6cc69f1  
    3535 * The size of the cooked buffer
    3636 */
    37 #define CBUFSIZE        (rtems_termios_cbufsize)
     37#define CBUFSIZE  (rtems_termios_cbufsize)
    3838
    3939/*
     
    4242 * efficient if these are powers of two.
    4343 */
    44 #define RAW_INPUT_BUFFER_SIZE   (rtems_termios_raw_input_size)
    45 #define RAW_OUTPUT_BUFFER_SIZE  (rtems_termios_raw_output_size)
     44#define RAW_INPUT_BUFFER_SIZE  (rtems_termios_raw_input_size)
     45#define RAW_OUTPUT_BUFFER_SIZE  (rtems_termios_raw_output_size)
    4646
    4747/* fields for "flow_ctrl" status */
     
    5858
    5959#define NODISC(n) \
    60         { NULL, NULL,   NULL,   NULL, \
    61           NULL, NULL,   NULL,   NULL }
     60  { NULL,  NULL,  NULL,  NULL, \
     61    NULL,  NULL,  NULL,  NULL }
    6262/*
    6363 * FIXME: change rtems_termios_linesw entries consistant with rtems_termios_linesw entry usage...
    6464 */
    65 struct  rtems_termios_linesw rtems_termios_linesw[MAXLDISC] =
    66 {
    67         NODISC(0),              /* 0- termios-built-in */
    68         NODISC(1),              /* 1- defunct */
    69         NODISC(2),              /* 2- NTTYDISC */
    70         NODISC(3),              /* TABLDISC */
    71         NODISC(4),              /* SLIPDISC */
    72         NODISC(5),              /* PPPDISC */
    73         NODISC(6),              /* loadable */
    74         NODISC(7),              /* loadable */
     65struct  rtems_termios_linesw rtems_termios_linesw[MAXLDISC] =
     66{
     67  NODISC(0),    /* 0- termios-built-in */
     68  NODISC(1),    /* 1- defunct */
     69  NODISC(2),              /* 2- NTTYDISC */
     70  NODISC(3),    /* TABLDISC */
     71  NODISC(4),    /* SLIPDISC */
     72  NODISC(5),    /* PPPDISC */
     73  NODISC(6),    /* loadable */
     74  NODISC(7),    /* loadable */
    7575};
    7676
    77 int     rtems_termios_nlinesw = sizeof (rtems_termios_linesw) / sizeof (rtems_termios_linesw[0]);
     77int  rtems_termios_nlinesw = sizeof (rtems_termios_linesw) / sizeof (rtems_termios_linesw[0]);
    7878
    7979extern struct rtems_termios_tty *rtems_termios_ttyHead;
     
    114114  )
    115115{
    116         rtems_status_code sc;
    117         rtems_libio_open_close_args_t *args = arg;
    118         struct rtems_termios_tty *tty;
    119 
    120         /*
    121         * See if the device has already been opened
    122         */
    123         sc = rtems_semaphore_obtain (rtems_termios_ttyMutex,
    124                                      RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    125         if (sc != RTEMS_SUCCESSFUL)
    126                 return sc;
    127         for (tty = rtems_termios_ttyHead ; tty != NULL ; tty = tty->forw) {
    128                 if ((tty->major == major) && (tty->minor == minor))
    129                         break;
    130         }
    131         if (tty == NULL) {
    132                 static char c = 'a';
    133 
    134                 /*
    135                 * Create a new device
    136                 */
    137                 tty = calloc (1, sizeof (struct rtems_termios_tty));
    138                 if (tty == NULL) {
    139                         rtems_semaphore_release (rtems_termios_ttyMutex);
    140                         return RTEMS_NO_MEMORY;
    141                 }
    142                 /*
    143                 * allocate raw input buffer
    144                 */
    145                 tty->rawInBuf.Size = RAW_INPUT_BUFFER_SIZE;
    146                 tty->rawInBuf.theBuf = malloc (tty->rawInBuf.Size);
    147                 if (tty->rawInBuf.theBuf == NULL) {
    148                         free(tty);
    149                         rtems_semaphore_release (rtems_termios_ttyMutex);
    150                         return RTEMS_NO_MEMORY;
    151                 }
    152                 /*
    153                 * allocate raw output buffer
    154                 */
    155                 tty->rawOutBuf.Size = RAW_OUTPUT_BUFFER_SIZE;
    156                 tty->rawOutBuf.theBuf = malloc (tty->rawOutBuf.Size);
    157                 if (tty->rawOutBuf.theBuf == NULL) {
    158                         free((void *)(tty->rawInBuf.theBuf));
    159                         free(tty);
    160                         rtems_semaphore_release (rtems_termios_ttyMutex);
    161                         return RTEMS_NO_MEMORY;
    162                 }
    163                 /*
    164                 * allocate cooked buffer
    165                 */
    166                 tty->cbuf  = malloc (CBUFSIZE);
    167                 if (tty->cbuf == NULL) {
    168                         free((void *)(tty->rawOutBuf.theBuf));
    169                         free((void *)(tty->rawInBuf.theBuf));
    170                         free(tty);
    171                         rtems_semaphore_release (rtems_termios_ttyMutex);
    172                         return RTEMS_NO_MEMORY;
    173                 }
    174                 /*
    175                 * Initialize wakeup callbacks
    176                 */
    177                 tty->tty_snd.sw_pfn = NULL;
    178                 tty->tty_snd.sw_arg = NULL;
    179                 tty->tty_rcv.sw_pfn = NULL;
    180                 tty->tty_rcv.sw_arg = NULL;
    181                 tty->tty_rcvwakeup  = 0;
    182 
    183                 /*
    184                 * link tty
    185                 */
    186                 tty->forw = rtems_termios_ttyHead;
    187                 tty->back = NULL;
    188                 if (rtems_termios_ttyHead != NULL)
    189                         rtems_termios_ttyHead->back = tty;
    190                 rtems_termios_ttyHead = tty;
    191                 if (rtems_termios_ttyTail == NULL)
    192                         rtems_termios_ttyTail = tty;
    193 
    194                 tty->minor = minor;
    195                 tty->major = major;
    196 
    197                 /*
    198                 * Set up mutex semaphores
    199                 */
    200                 sc = rtems_semaphore_create (
    201                         rtems_build_name ('T', 'R', 'i', c),
    202                         1,
    203                         RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
    204                         RTEMS_NO_PRIORITY,
    205                         &tty->isem);
    206                 if (sc != RTEMS_SUCCESSFUL)
    207                         rtems_fatal_error_occurred (sc);
    208                 sc = rtems_semaphore_create (
    209                         rtems_build_name ('T', 'R', 'o', c),
    210                         1,
    211                         RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
    212                         RTEMS_NO_PRIORITY,
    213                         &tty->osem);
    214                 if (sc != RTEMS_SUCCESSFUL)
    215                         rtems_fatal_error_occurred (sc);
    216                 sc = rtems_semaphore_create (
    217                         rtems_build_name ('T', 'R', 'x', c),
    218                         0,
    219                         RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_FIFO,
    220                         RTEMS_NO_PRIORITY,
    221                         &tty->rawOutBuf.Semaphore);
    222                 if (sc != RTEMS_SUCCESSFUL)
    223                         rtems_fatal_error_occurred (sc);
    224                 tty->rawOutBufState = rob_idle;
    225 
    226                 /*
    227                 * Set callbacks
    228                 */
    229                 tty->device = *callbacks;
    230 
    231                 /*
    232                 * Create I/O tasks
    233                 */
    234                 if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) {
    235                         sc = rtems_task_create (
     116  rtems_status_code sc;
     117  rtems_libio_open_close_args_t *args = arg;
     118  struct rtems_termios_tty *tty;
     119
     120  /*
     121  * See if the device has already been opened
     122  */
     123  sc = rtems_semaphore_obtain (rtems_termios_ttyMutex,
     124             RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     125  if (sc != RTEMS_SUCCESSFUL)
     126    return sc;
     127  for (tty = rtems_termios_ttyHead ; tty != NULL ; tty = tty->forw) {
     128    if ((tty->major == major) && (tty->minor == minor))
     129      break;
     130  }
     131  if (tty == NULL) {
     132    static char c = 'a';
     133
     134    /*
     135    * Create a new device
     136    */
     137    tty = calloc (1, sizeof (struct rtems_termios_tty));
     138    if (tty == NULL) {
     139      rtems_semaphore_release (rtems_termios_ttyMutex);
     140      return RTEMS_NO_MEMORY;
     141    }
     142    /*
     143    * allocate raw input buffer
     144    */
     145    tty->rawInBuf.Size = RAW_INPUT_BUFFER_SIZE;
     146    tty->rawInBuf.theBuf = malloc (tty->rawInBuf.Size);
     147    if (tty->rawInBuf.theBuf == NULL) {
     148            free(tty);
     149      rtems_semaphore_release (rtems_termios_ttyMutex);
     150      return RTEMS_NO_MEMORY;
     151    }
     152    /*
     153    * allocate raw output buffer
     154    */
     155    tty->rawOutBuf.Size = RAW_OUTPUT_BUFFER_SIZE;
     156    tty->rawOutBuf.theBuf = malloc (tty->rawOutBuf.Size);
     157    if (tty->rawOutBuf.theBuf == NULL) {
     158            free((void *)(tty->rawInBuf.theBuf));
     159            free(tty);
     160      rtems_semaphore_release (rtems_termios_ttyMutex);
     161      return RTEMS_NO_MEMORY;
     162    }
     163    /*
     164    * allocate cooked buffer
     165    */
     166    tty->cbuf  = malloc (CBUFSIZE);
     167    if (tty->cbuf == NULL) {
     168            free((void *)(tty->rawOutBuf.theBuf));
     169            free((void *)(tty->rawInBuf.theBuf));
     170            free(tty);
     171      rtems_semaphore_release (rtems_termios_ttyMutex);
     172      return RTEMS_NO_MEMORY;
     173    }
     174    /*
     175    * Initialize wakeup callbacks
     176    */
     177    tty->tty_snd.sw_pfn = NULL;
     178    tty->tty_snd.sw_arg = NULL;
     179    tty->tty_rcv.sw_pfn = NULL;
     180    tty->tty_rcv.sw_arg = NULL;
     181    tty->tty_rcvwakeup  = 0;
     182
     183    /*
     184    * link tty
     185    */
     186    tty->forw = rtems_termios_ttyHead;
     187    tty->back = NULL;
     188    if (rtems_termios_ttyHead != NULL)
     189      rtems_termios_ttyHead->back = tty;
     190    rtems_termios_ttyHead = tty;
     191    if (rtems_termios_ttyTail == NULL)
     192      rtems_termios_ttyTail = tty;
     193
     194    tty->minor = minor;
     195    tty->major = major;
     196
     197    /*
     198    * Set up mutex semaphores
     199    */
     200    sc = rtems_semaphore_create (
     201      rtems_build_name ('T', 'R', 'i', c),
     202      1,
     203      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
     204      RTEMS_NO_PRIORITY,
     205      &tty->isem);
     206    if (sc != RTEMS_SUCCESSFUL)
     207      rtems_fatal_error_occurred (sc);
     208    sc = rtems_semaphore_create (
     209      rtems_build_name ('T', 'R', 'o', c),
     210      1,
     211      RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
     212      RTEMS_NO_PRIORITY,
     213      &tty->osem);
     214    if (sc != RTEMS_SUCCESSFUL)
     215      rtems_fatal_error_occurred (sc);
     216    sc = rtems_semaphore_create (
     217      rtems_build_name ('T', 'R', 'x', c),
     218      0,
     219      RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_FIFO,
     220      RTEMS_NO_PRIORITY,
     221      &tty->rawOutBuf.Semaphore);
     222    if (sc != RTEMS_SUCCESSFUL)
     223      rtems_fatal_error_occurred (sc);
     224    tty->rawOutBufState = rob_idle;
     225
     226    /*
     227    * Set callbacks
     228    */
     229    tty->device = *callbacks;
     230
     231    /*
     232    * Create I/O tasks
     233    */
     234    if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) {
     235      sc = rtems_task_create (
    236236                                   rtems_build_name ('T', 'x', 'T', c),
    237                                    TERMIOS_TXTASK_PRIO,
    238                                    TERMIOS_TXTASK_STACKSIZE,
    239                                    RTEMS_NO_PREEMPT | RTEMS_NO_TIMESLICE |
    240                                    RTEMS_NO_ASR,
    241                                    RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
    242                                    &tty->txTaskId);
    243                         if (sc != RTEMS_SUCCESSFUL)
    244                                 rtems_fatal_error_occurred (sc);
    245                         sc = rtems_task_create (
     237           TERMIOS_TXTASK_PRIO,
     238           TERMIOS_TXTASK_STACKSIZE,
     239           RTEMS_NO_PREEMPT | RTEMS_NO_TIMESLICE |
     240           RTEMS_NO_ASR,
     241           RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
     242           &tty->txTaskId);
     243      if (sc != RTEMS_SUCCESSFUL)
     244        rtems_fatal_error_occurred (sc);
     245      sc = rtems_task_create (
    246246                                   rtems_build_name ('R', 'x', 'T', c),
    247                                    TERMIOS_RXTASK_PRIO,
    248                                    TERMIOS_RXTASK_STACKSIZE,
    249                                    RTEMS_NO_PREEMPT | RTEMS_NO_TIMESLICE |
    250                                    RTEMS_NO_ASR,
    251                                    RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
    252                                    &tty->rxTaskId);
    253                         if (sc != RTEMS_SUCCESSFUL)
    254                                 rtems_fatal_error_occurred (sc);
    255 
    256                 }
    257                 if ((tty->device.pollRead == NULL) ||
    258                     (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN)){
    259                         sc = rtems_semaphore_create (
    260                                 rtems_build_name ('T', 'R', 'r', c),
    261                                 0,
    262                                 RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY,
    263                                 RTEMS_NO_PRIORITY,
    264                                 &tty->rawInBuf.Semaphore);
    265                         if (sc != RTEMS_SUCCESSFUL)
    266                                 rtems_fatal_error_occurred (sc);
    267                 }
    268 
    269                 /*
    270                  * Set default parameters
    271                  */
    272                 tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
    273                 tty->termios.c_oflag = OPOST | ONLCR | XTABS;
    274                 tty->termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
    275                 tty->termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL;
    276 
    277                 tty->termios.c_cc[VINTR] = '\003';
    278                 tty->termios.c_cc[VQUIT] = '\034';
    279                 tty->termios.c_cc[VERASE] = '\177';
    280                 tty->termios.c_cc[VKILL] = '\025';
    281                 tty->termios.c_cc[VEOF] = '\004';
    282                 tty->termios.c_cc[VEOL] = '\000';
    283                 tty->termios.c_cc[VEOL2] = '\000';
    284                 tty->termios.c_cc[VSTART] = '\021';
    285                 tty->termios.c_cc[VSTOP] = '\023';
    286                 tty->termios.c_cc[VSUSP] = '\032';
    287                 tty->termios.c_cc[VREPRINT] = '\022';
    288                 tty->termios.c_cc[VDISCARD] = '\017';
    289                 tty->termios.c_cc[VWERASE] = '\027';
    290                 tty->termios.c_cc[VLNEXT] = '\026';
    291 
    292                 /* start with no flow control, clear flow control flags */
    293                 tty->flow_ctrl = 0;
    294                 /*
    295                  * set low/highwater mark for XON/XOFF support
    296                  */
    297                 tty->lowwater  = tty->rawInBuf.Size * 1/2;
    298                 tty->highwater = tty->rawInBuf.Size * 3/4;
    299                 /*
    300                  * Bump name characer
    301                  */
    302                 if (c++ == 'z')
    303                         c = 'a';
    304 
    305         }
    306         args->iop->data1 = tty;
    307         if (!tty->refcount++) {
    308           if (tty->device.firstOpen)
    309                 (*tty->device.firstOpen)(major, minor, arg);
    310           /*
    311            * start I/O tasks, if needed
    312            */
    313           if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) {
    314             sc = rtems_task_start(tty->rxTaskId,
    315                                   rtems_termios_rxdaemon,
    316                                   (rtems_task_argument)tty);
    317             if (sc != RTEMS_SUCCESSFUL)
    318               rtems_fatal_error_occurred (sc);
    319 
    320             sc = rtems_task_start(tty->txTaskId,
    321                                   rtems_termios_txdaemon,
    322                                   (rtems_task_argument)tty);
    323             if (sc != RTEMS_SUCCESSFUL)
    324               rtems_fatal_error_occurred (sc);
    325           }
    326         }
    327         rtems_semaphore_release (rtems_termios_ttyMutex);
    328         return RTEMS_SUCCESSFUL;
     247           TERMIOS_RXTASK_PRIO,
     248           TERMIOS_RXTASK_STACKSIZE,
     249           RTEMS_NO_PREEMPT | RTEMS_NO_TIMESLICE |
     250           RTEMS_NO_ASR,
     251           RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
     252           &tty->rxTaskId);
     253      if (sc != RTEMS_SUCCESSFUL)
     254        rtems_fatal_error_occurred (sc);
     255
     256    }
     257    if ((tty->device.pollRead == NULL) ||
     258        (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN)){
     259      sc = rtems_semaphore_create (
     260        rtems_build_name ('T', 'R', 'r', c),
     261        0,
     262        RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY,
     263        RTEMS_NO_PRIORITY,
     264        &tty->rawInBuf.Semaphore);
     265      if (sc != RTEMS_SUCCESSFUL)
     266        rtems_fatal_error_occurred (sc);
     267    }
     268
     269    /*
     270     * Set default parameters
     271     */
     272    tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
     273    tty->termios.c_oflag = OPOST | ONLCR | XTABS;
     274    tty->termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
     275    tty->termios.c_lflag =
     276       ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL;
     277
     278    tty->termios.c_cc[VINTR] = '\003';
     279    tty->termios.c_cc[VQUIT] = '\034';
     280    tty->termios.c_cc[VERASE] = '\177';
     281    tty->termios.c_cc[VKILL] = '\025';
     282    tty->termios.c_cc[VEOF] = '\004';
     283    tty->termios.c_cc[VEOL] = '\000';
     284    tty->termios.c_cc[VEOL2] = '\000';
     285    tty->termios.c_cc[VSTART] = '\021';
     286    tty->termios.c_cc[VSTOP] = '\023';
     287    tty->termios.c_cc[VSUSP] = '\032';
     288    tty->termios.c_cc[VREPRINT] = '\022';
     289    tty->termios.c_cc[VDISCARD] = '\017';
     290    tty->termios.c_cc[VWERASE] = '\027';
     291    tty->termios.c_cc[VLNEXT] = '\026';
     292
     293    /* start with no flow control, clear flow control flags */
     294    tty->flow_ctrl = 0;
     295    /*
     296     * set low/highwater mark for XON/XOFF support
     297     */
     298    tty->lowwater  = tty->rawInBuf.Size * 1/2;
     299    tty->highwater = tty->rawInBuf.Size * 3/4;
     300    /*
     301     * Bump name characer
     302     */
     303    if (c++ == 'z')
     304      c = 'a';
     305
     306  }
     307  args->iop->data1 = tty;
     308  if (!tty->refcount++) {
     309    if (tty->device.firstOpen)
     310    (*tty->device.firstOpen)(major, minor, arg);
     311    /*
     312     * start I/O tasks, if needed
     313     */
     314    if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) {
     315      sc = rtems_task_start(tty->rxTaskId,
     316          rtems_termios_rxdaemon,
     317          (rtems_task_argument)tty);
     318      if (sc != RTEMS_SUCCESSFUL)
     319        rtems_fatal_error_occurred (sc);
     320
     321      sc = rtems_task_start(tty->txTaskId,
     322          rtems_termios_txdaemon,
     323          (rtems_task_argument)tty);
     324      if (sc != RTEMS_SUCCESSFUL)
     325        rtems_fatal_error_occurred (sc);
     326    }
     327  }
     328  rtems_semaphore_release (rtems_termios_ttyMutex);
     329  return RTEMS_SUCCESSFUL;
    329330}
    330331
     
    335336drainOutput (struct rtems_termios_tty *tty)
    336337{
    337         rtems_interrupt_level level;
    338         rtems_status_code sc;
    339 
    340         if (tty->device.outputUsesInterrupts != TERMIOS_POLLED) {
    341                 rtems_interrupt_disable (level);
    342                 while (tty->rawOutBuf.Tail != tty->rawOutBuf.Head) {
    343                         tty->rawOutBufState = rob_wait;
    344                         rtems_interrupt_enable (level);
    345                         sc = rtems_semaphore_obtain (tty->rawOutBuf.Semaphore,
    346                                                         RTEMS_WAIT,
    347                                                         RTEMS_NO_TIMEOUT);
    348                         if (sc != RTEMS_SUCCESSFUL)
    349                                 rtems_fatal_error_occurred (sc);
    350                         rtems_interrupt_disable (level);
    351                 }
    352                 rtems_interrupt_enable (level);
    353         }
     338  rtems_interrupt_level level;
     339  rtems_status_code sc;
     340
     341  if (tty->device.outputUsesInterrupts != TERMIOS_POLLED) {
     342    rtems_interrupt_disable (level);
     343    while (tty->rawOutBuf.Tail != tty->rawOutBuf.Head) {
     344      tty->rawOutBufState = rob_wait;
     345      rtems_interrupt_enable (level);
     346      sc = rtems_semaphore_obtain (tty->rawOutBuf.Semaphore,
     347              RTEMS_WAIT,
     348              RTEMS_NO_TIMEOUT);
     349      if (sc != RTEMS_SUCCESSFUL)
     350        rtems_fatal_error_occurred (sc);
     351      rtems_interrupt_disable (level);
     352    }
     353    rtems_interrupt_enable (level);
     354  }
    354355}
    355356
     
    357358rtems_termios_close (void *arg)
    358359{
    359         rtems_libio_open_close_args_t *args = arg;
    360         struct rtems_termios_tty *tty = args->iop->data1;
    361         rtems_status_code sc;
    362 
    363         sc = rtems_semaphore_obtain (rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    364         if (sc != RTEMS_SUCCESSFUL)
    365                 rtems_fatal_error_occurred (sc);
    366         if (--tty->refcount == 0) {
    367                 if (rtems_termios_linesw[tty->t_line].l_close != NULL) {
    368                         /*
    369                          * call discipline-specific close
    370                          */
    371                         sc = rtems_termios_linesw[tty->t_line].l_close(tty);
    372                 }
    373                 else {
    374                         /*
    375                          * default: just flush output buffer
    376                          */
    377                         sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    378                         if (sc != RTEMS_SUCCESSFUL) {
    379                                 rtems_fatal_error_occurred (sc);
    380                         }
    381                         drainOutput (tty);
    382                 }
    383 
    384                 if (tty->device.outputUsesInterrupts
    385                     == TERMIOS_TASK_DRIVEN) {
    386                         /*
    387                          * send "terminate" to I/O tasks
    388                          */
    389                         sc = rtems_event_send(
     360  rtems_libio_open_close_args_t *args = arg;
     361  struct rtems_termios_tty *tty = args->iop->data1;
     362  rtems_status_code sc;
     363
     364  sc = rtems_semaphore_obtain(
     365    rtems_termios_ttyMutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     366  if (sc != RTEMS_SUCCESSFUL)
     367    rtems_fatal_error_occurred (sc);
     368  if (--tty->refcount == 0) {
     369    if (rtems_termios_linesw[tty->t_line].l_close != NULL) {
     370      /*
     371       * call discipline-specific close
     372       */
     373      sc = rtems_termios_linesw[tty->t_line].l_close(tty);
     374    }
     375    else {
     376      /*
     377       * default: just flush output buffer
     378       */
     379      sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     380      if (sc != RTEMS_SUCCESSFUL) {
     381        rtems_fatal_error_occurred (sc);
     382      }
     383            drainOutput (tty);
     384    }
     385
     386    if (tty->device.outputUsesInterrupts
     387        == TERMIOS_TASK_DRIVEN) {
     388      /*
     389       * send "terminate" to I/O tasks
     390       */
     391      sc = rtems_event_send(
    390392                                  tty->rxTaskId,
    391                                   TERMIOS_RX_TERMINATE_EVENT);
    392                         if (sc != RTEMS_SUCCESSFUL)
    393                                 rtems_fatal_error_occurred (sc);
    394                         sc = rtems_event_send(
     393          TERMIOS_RX_TERMINATE_EVENT);
     394      if (sc != RTEMS_SUCCESSFUL)
     395        rtems_fatal_error_occurred (sc);
     396      sc = rtems_event_send(
    395397                                  tty->txTaskId,
    396                                   TERMIOS_TX_TERMINATE_EVENT);
    397                         if (sc != RTEMS_SUCCESSFUL)
    398                                 rtems_fatal_error_occurred (sc);
    399                 }
    400                 if (tty->device.lastClose)
    401                         (*tty->device.lastClose)(tty->major, tty->minor, arg);
    402                 if (tty->forw == NULL) {
    403                         rtems_termios_ttyTail = tty->back;
    404                         if ( rtems_termios_ttyTail != NULL ) {
    405                                 rtems_termios_ttyTail->forw = NULL;
    406                         }
    407                 }
    408                 else {
    409                         tty->forw->back = tty->back;
    410                 }
    411                 if (tty->back == NULL) {
    412                         rtems_termios_ttyHead = tty->forw;
    413                         if ( rtems_termios_ttyHead != NULL ) {
    414                                 rtems_termios_ttyHead->back = NULL;
    415                         }
    416                 }
    417                 else {
    418                         tty->back->forw = tty->forw;
    419                 }
    420                 rtems_semaphore_delete (tty->isem);
    421                 rtems_semaphore_delete (tty->osem);
    422                 rtems_semaphore_delete (tty->rawOutBuf.Semaphore);
    423                 if ((tty->device.pollRead == NULL) ||
    424                     (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN))
    425                         rtems_semaphore_delete (tty->rawInBuf.Semaphore);
    426                 free (tty->rawInBuf.theBuf);
    427                 free (tty->rawOutBuf.theBuf);
    428                 free (tty->cbuf);
    429                 free (tty);
    430         }
    431         rtems_semaphore_release (rtems_termios_ttyMutex);
    432         return RTEMS_SUCCESSFUL;
     398          TERMIOS_TX_TERMINATE_EVENT);
     399      if (sc != RTEMS_SUCCESSFUL)
     400        rtems_fatal_error_occurred (sc);
     401    }
     402    if (tty->device.lastClose)
     403      (*tty->device.lastClose)(tty->major, tty->minor, arg);
     404    if (tty->forw == NULL) {
     405      rtems_termios_ttyTail = tty->back;
     406      if ( rtems_termios_ttyTail != NULL ) {
     407        rtems_termios_ttyTail->forw = NULL;
     408      }
     409    }
     410    else {
     411      tty->forw->back = tty->back;
     412    }
     413    if (tty->back == NULL) {
     414      rtems_termios_ttyHead = tty->forw;
     415      if ( rtems_termios_ttyHead != NULL ) {
     416        rtems_termios_ttyHead->back = NULL;
     417      }
     418    }
     419    else {
     420      tty->back->forw = tty->forw;
     421    }
     422    rtems_semaphore_delete (tty->isem);
     423    rtems_semaphore_delete (tty->osem);
     424    rtems_semaphore_delete (tty->rawOutBuf.Semaphore);
     425    if ((tty->device.pollRead == NULL) ||
     426        (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN))
     427      rtems_semaphore_delete (tty->rawInBuf.Semaphore);
     428    free (tty->rawInBuf.theBuf);
     429    free (tty->rawOutBuf.theBuf);
     430    free (tty->cbuf);
     431    free (tty);
     432  }
     433  rtems_semaphore_release (rtems_termios_ttyMutex);
     434  return RTEMS_SUCCESSFUL;
    433435}
    434436
     
    466468      /* check for chars in output buffer (or rob_state?) */
    467469      if (tty->rawOutBufState != rob_idle) {
    468         /* if chars available, call write function... */
    469         (*tty->device.write)(tty->minor,
    470                      &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
     470  /* if chars available, call write function... */
     471  (*tty->device.write)(tty->minor,
     472         &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
    471473      }
    472474      /* reenable interrupts */
     
    484486
    485487  /* check for incoming RTS/CTS flow control switched off */
    486   if (( tty->flow_ctrl & FL_MDRTS) &&
    487       !(tty->termios.c_cflag & CRTSCTS)) {
     488  if (( tty->flow_ctrl & FL_MDRTS) && !(tty->termios.c_cflag & CRTSCTS)) {
    488489    /* clear related flags in flow_ctrl */
    489490    tty->flow_ctrl &= ~(FL_MDRTS);
    490491
    491492    /* restart remote Tx, if it was stopped */
    492     if ((tty->flow_ctrl & FL_IRTSOFF) &&
    493         (tty->device.startRemoteTx != NULL)) {
     493    if ((tty->flow_ctrl & FL_IRTSOFF) && (tty->device.startRemoteTx != NULL)) {
    494494      tty->device.startRemoteTx(tty->minor);
    495495    }
     
    517517rtems_termios_ioctl (void *arg)
    518518{
    519         rtems_libio_ioctl_args_t *args = arg;
    520         struct rtems_termios_tty *tty = args->iop->data1;
    521         struct ttywakeup         *wakeup = (struct ttywakeup *)args->buffer;
    522         rtems_status_code sc;
    523 
    524         args->ioctl_return = 0;
    525         sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    526         if (sc != RTEMS_SUCCESSFUL) {
    527                 args->ioctl_return = sc;
    528                 return sc;
    529         }
    530         switch (args->command) {
    531         default:
    532                 if (rtems_termios_linesw[tty->t_line].l_ioctl != NULL) {
    533                         sc = rtems_termios_linesw[tty->t_line].l_ioctl(tty,args);
    534                 }
    535                 else {
    536                         sc = RTEMS_INVALID_NUMBER;
    537                 }
    538                 break;
    539 
    540         case RTEMS_IO_GET_ATTRIBUTES:
    541                 *(struct termios *)args->buffer = tty->termios;
    542                 break;
    543 
    544         case RTEMS_IO_SET_ATTRIBUTES:
    545                 tty->termios = *(struct termios *)args->buffer;
    546 
    547                 /* check for and process change in flow control options */
    548                 termios_set_flowctrl(tty);
    549 
    550                 if (tty->termios.c_lflag & ICANON) {
    551                         tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
    552                         tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
    553                         tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
    554                 }
    555                 else {
    556                         tty->vtimeTicks = tty->termios.c_cc[VTIME] *
    557                                       rtems_clock_get_ticks_per_second() / 10;
    558                         if (tty->termios.c_cc[VTIME]) {
    559                                 tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
    560                                 tty->rawInBufSemaphoreTimeout = tty->vtimeTicks;
    561                                 if (tty->termios.c_cc[VMIN])
    562                                         tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
    563                                 else
    564                                         tty->rawInBufSemaphoreFirstTimeout = tty->vtimeTicks;
    565                         }
    566                         else {
    567                                 if (tty->termios.c_cc[VMIN]) {
    568                                         tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
    569                                         tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
    570                                         tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
    571                                 }
    572                                 else {
    573                                         tty->rawInBufSemaphoreOptions = RTEMS_NO_WAIT;
    574                                 }
    575                         }
    576                 }
    577                 if (tty->device.setAttributes)
    578                         (*tty->device.setAttributes)(tty->minor, &tty->termios);
    579                 break;
    580 
    581         case RTEMS_IO_TCDRAIN:
    582                 drainOutput (tty);
    583                 break;
    584 
    585         case RTEMS_IO_SNDWAKEUP:
    586                 tty->tty_snd = *wakeup;
    587                 break;
    588 
    589         case RTEMS_IO_RCVWAKEUP:
    590                 tty->tty_rcv = *wakeup;
    591                 break;
    592 
    593                 /*
    594                 * FIXME: add various ioctl code handlers
    595                 */
     519  rtems_libio_ioctl_args_t *args = arg;
     520  struct rtems_termios_tty *tty = args->iop->data1;
     521  struct ttywakeup         *wakeup = (struct ttywakeup *)args->buffer;
     522  rtems_status_code sc;
     523
     524   args->ioctl_return = 0;
     525  sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     526  if (sc != RTEMS_SUCCESSFUL) {
     527    args->ioctl_return = sc;
     528    return sc;
     529  }
     530  switch (args->command) {
     531  default:
     532    if (rtems_termios_linesw[tty->t_line].l_ioctl != NULL) {
     533      sc = rtems_termios_linesw[tty->t_line].l_ioctl(tty,args);
     534    }
     535    else {
     536      sc = RTEMS_INVALID_NUMBER;
     537    }
     538    break;
     539
     540  case RTEMS_IO_GET_ATTRIBUTES:
     541    *(struct termios *)args->buffer = tty->termios;
     542    break;
     543
     544  case RTEMS_IO_SET_ATTRIBUTES:
     545    tty->termios = *(struct termios *)args->buffer;
     546
     547    /* check for and process change in flow control options */
     548    termios_set_flowctrl(tty);
     549
     550    if (tty->termios.c_lflag & ICANON) {
     551      tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
     552      tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
     553      tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
     554    }
     555    else {
     556      tty->vtimeTicks = tty->termios.c_cc[VTIME] *
     557                    rtems_clock_get_ticks_per_second() / 10;
     558      if (tty->termios.c_cc[VTIME]) {
     559        tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
     560        tty->rawInBufSemaphoreTimeout = tty->vtimeTicks;
     561        if (tty->termios.c_cc[VMIN])
     562          tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
     563        else
     564          tty->rawInBufSemaphoreFirstTimeout = tty->vtimeTicks;
     565      }
     566      else {
     567        if (tty->termios.c_cc[VMIN]) {
     568          tty->rawInBufSemaphoreOptions = RTEMS_WAIT;
     569          tty->rawInBufSemaphoreTimeout = RTEMS_NO_TIMEOUT;
     570          tty->rawInBufSemaphoreFirstTimeout = RTEMS_NO_TIMEOUT;
     571        }
     572        else {
     573          tty->rawInBufSemaphoreOptions = RTEMS_NO_WAIT;
     574        }
     575      }
     576    }
     577    if (tty->device.setAttributes)
     578      (*tty->device.setAttributes)(tty->minor, &tty->termios);
     579    break;
     580
     581  case RTEMS_IO_TCDRAIN:
     582    drainOutput (tty);
     583    break;
     584
     585  case RTEMS_IO_SNDWAKEUP:
     586    tty->tty_snd = *wakeup;
     587    break;
     588
     589  case RTEMS_IO_RCVWAKEUP:
     590    tty->tty_rcv = *wakeup;
     591    break;
     592
     593    /*
     594    * FIXME: add various ioctl code handlers
     595    */
    596596
    597597#if 1 /* FIXME */
    598         case TIOCSETD:
    599                 /*
    600                 * close old line discipline
    601                 */
    602                 if (rtems_termios_linesw[tty->t_line].l_close != NULL) {
    603                         sc = rtems_termios_linesw[tty->t_line].l_close(tty);
    604                 }
    605                 tty->t_line=*(int*)(args->buffer);
    606                 tty->t_sc = NULL; /* ensure that no more valid data */
    607                 /*
    608                 * open new line discipline
    609                 */
    610                 if (rtems_termios_linesw[tty->t_line].l_open != NULL) {
    611                         sc = rtems_termios_linesw[tty->t_line].l_open(tty);
    612                 }
    613                 break;
    614         case TIOCGETD:
    615                 *(int*)(args->buffer)=tty->t_line;
    616                 break;
     598  case TIOCSETD:
     599    /*
     600    * close old line discipline
     601    */
     602    if (rtems_termios_linesw[tty->t_line].l_close != NULL) {
     603      sc = rtems_termios_linesw[tty->t_line].l_close(tty);
     604    }
     605    tty->t_line=*(int*)(args->buffer);
     606    tty->t_sc = NULL; /* ensure that no more valid data */
     607    /*
     608    * open new line discipline
     609    */
     610    if (rtems_termios_linesw[tty->t_line].l_open != NULL) {
     611      sc = rtems_termios_linesw[tty->t_line].l_open(tty);
     612    }
     613    break;
     614  case TIOCGETD:
     615    *(int*)(args->buffer)=tty->t_line;
     616    break;
    617617#endif
    618         case FIONREAD:
    619                 {
    620                 int rawnc = tty->rawInBuf.Tail - tty->rawInBuf.Head;
    621                 if ( rawnc < 0 )
    622                         rawnc += tty->rawInBuf.Size;
    623                 /* Half guess that this is the right operation */
    624                 *(int *)args->buffer = tty->ccount - tty->cindex + rawnc;
    625                 }
    626                 break;
    627         }
    628         rtems_semaphore_release (tty->osem);
    629         args->ioctl_return = sc;
    630         return sc;
     618   case FIONREAD:
     619    {
     620    int rawnc = tty->rawInBuf.Tail - tty->rawInBuf.Head;
     621    if ( rawnc < 0 )
     622      rawnc += tty->rawInBuf.Size;
     623    /* Half guess that this is the right operation */
     624    *(int *)args->buffer = tty->ccount - tty->cindex + rawnc;
     625    }
     626    break;
     627  }
     628  rtems_semaphore_release (tty->osem);
     629  args->ioctl_return = sc;
     630  return sc;
    631631}
    632632
     
    638638  const void *_buf, int len, struct rtems_termios_tty *tty)
    639639{
    640         const unsigned char *buf = _buf;
    641         unsigned int newHead;
    642         rtems_interrupt_level level;
    643         rtems_status_code sc;
    644 
    645         if (tty->device.outputUsesInterrupts == TERMIOS_POLLED) {
    646                 (*tty->device.write)(tty->minor, (void *)buf, len);
    647                 return;
    648         }
    649         newHead = tty->rawOutBuf.Head;
    650         while (len) {
    651                 /*
    652                 * Performance improvement could be made here.
    653                 * Copy multiple bytes to raw buffer:
    654                 * if (len > 1) && (space to buffer end, or tail > 1)
    655                  *      ncopy = MIN (len, space to buffer end or tail)
    656                  *      memcpy (raw buffer, buf, ncopy)
    657                  *      buf += ncopy
    658                  *      len -= ncopy
    659                 *
    660                 * To minimize latency, the memcpy should be done
    661                 * with interrupts enabled.
    662                 */
    663                 newHead = (newHead + 1) % tty->rawOutBuf.Size;
    664                 rtems_interrupt_disable (level);
    665                 while (newHead == tty->rawOutBuf.Tail) {
    666                         tty->rawOutBufState = rob_wait;
    667                         rtems_interrupt_enable (level);
    668                         sc = rtems_semaphore_obtain (tty->rawOutBuf.Semaphore,
    669                                                         RTEMS_WAIT,
    670                                                         RTEMS_NO_TIMEOUT);
    671                         if (sc != RTEMS_SUCCESSFUL)
    672                                 rtems_fatal_error_occurred (sc);
    673                         rtems_interrupt_disable (level);
    674                 }
    675                 tty->rawOutBuf.theBuf[tty->rawOutBuf.Head] = *buf++;
    676                 tty->rawOutBuf.Head = newHead;
    677                 if (tty->rawOutBufState == rob_idle) {
    678                   /* check, whether XOFF has been received */
    679                   if (!(tty->flow_ctrl & FL_ORCVXOF)) {
    680                     (*tty->device.write)(tty->minor,
    681                         (char *)&tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
    682                   }
    683                   else {
    684                     /* remember that output has been stopped due to flow ctrl*/
    685                     tty->flow_ctrl |= FL_OSTOP;
    686                   }
    687                   tty->rawOutBufState = rob_busy;
    688                 }
    689                 rtems_interrupt_enable (level);
    690                 len--;
    691         }
     640  const unsigned char *buf = _buf;
     641  unsigned int newHead;
     642  rtems_interrupt_level level;
     643  rtems_status_code sc;
     644
     645  if (tty->device.outputUsesInterrupts == TERMIOS_POLLED) {
     646    (*tty->device.write)(tty->minor, (void *)buf, len);
     647    return;
     648  }
     649  newHead = tty->rawOutBuf.Head;
     650  while (len) {
     651    /*
     652    * Performance improvement could be made here.
     653    * Copy multiple bytes to raw buffer:
     654    * if (len > 1) && (space to buffer end, or tail > 1)
     655     *  ncopy = MIN (len, space to buffer end or tail)
     656     *  memcpy (raw buffer, buf, ncopy)
     657     *  buf += ncopy
     658     *  len -= ncopy
     659    *
     660    * To minimize latency, the memcpy should be done
     661    * with interrupts enabled.
     662    */
     663    newHead = (newHead + 1) % tty->rawOutBuf.Size;
     664    rtems_interrupt_disable (level);
     665    while (newHead == tty->rawOutBuf.Tail) {
     666      tty->rawOutBufState = rob_wait;
     667      rtems_interrupt_enable (level);
     668      sc = rtems_semaphore_obtain (tty->rawOutBuf.Semaphore,
     669              RTEMS_WAIT,
     670              RTEMS_NO_TIMEOUT);
     671      if (sc != RTEMS_SUCCESSFUL)
     672        rtems_fatal_error_occurred (sc);
     673      rtems_interrupt_disable (level);
     674    }
     675    tty->rawOutBuf.theBuf[tty->rawOutBuf.Head] = *buf++;
     676    tty->rawOutBuf.Head = newHead;
     677    if (tty->rawOutBufState == rob_idle) {
     678      /* check, whether XOFF has been received */
     679      if (!(tty->flow_ctrl & FL_ORCVXOF)) {
     680        (*tty->device.write)(tty->minor,
     681      (char *)&tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
     682      }
     683      else {
     684        /* remember that output has been stopped due to flow ctrl*/
     685        tty->flow_ctrl |= FL_OSTOP;
     686      }
     687      tty->rawOutBufState = rob_busy;
     688    }
     689    rtems_interrupt_enable (level);
     690    len--;
     691  }
    692692}
    693693
     
    698698oproc (unsigned char c, struct rtems_termios_tty *tty)
    699699{
    700         int     i;
    701 
    702         if (tty->termios.c_oflag & OPOST) {
    703                 switch (c) {
    704                 case '\n':
    705                         if (tty->termios.c_oflag & ONLRET)
    706                                 tty->column = 0;
    707                         if (tty->termios.c_oflag & ONLCR) {
    708                                 rtems_termios_puts ("\r", 1, tty);
    709                                 tty->column = 0;
    710                         }
    711                         break;
    712 
    713                 case '\r':
    714                         if ((tty->termios.c_oflag & ONOCR) && (tty->column == 0))
    715                                 return;
    716                         if (tty->termios.c_oflag & OCRNL) {
    717                                 c = '\n';
    718                                 if (tty->termios.c_oflag & ONLRET)
    719                                         tty->column = 0;
    720                                 break;
    721                         }
    722                         tty->column = 0;
    723                         break;
    724 
    725                 case '\t':
    726                         i = 8 - (tty->column & 7);
    727                         if ((tty->termios.c_oflag & TABDLY) == XTABS) {
    728                                 tty->column += i;
    729                                 rtems_termios_puts ( "        ",  i, tty);
    730                                 return;
    731                         }
    732                         tty->column += i;
    733                         break;
    734 
    735                 case '\b':
    736                         if (tty->column > 0)
    737                                 tty->column--;
    738                         break;
    739 
    740                 default:
    741                         if (tty->termios.c_oflag & OLCUC)
    742                                 c = toupper(c);
    743                         if (!iscntrl(c))
    744                                 tty->column++;
    745                         break;
    746                 }
    747         }
    748         rtems_termios_puts (&c, 1, tty);
     700  int  i;
     701
     702  if (tty->termios.c_oflag & OPOST) {
     703    switch (c) {
     704    case '\n':
     705      if (tty->termios.c_oflag & ONLRET)
     706        tty->column = 0;
     707      if (tty->termios.c_oflag & ONLCR) {
     708        rtems_termios_puts ("\r", 1, tty);
     709        tty->column = 0;
     710      }
     711      break;
     712
     713    case '\r':
     714      if ((tty->termios.c_oflag & ONOCR) && (tty->column == 0))
     715        return;
     716      if (tty->termios.c_oflag & OCRNL) {
     717        c = '\n';
     718        if (tty->termios.c_oflag & ONLRET)
     719          tty->column = 0;
     720        break;
     721      }
     722      tty->column = 0;
     723      break;
     724
     725    case '\t':
     726      i = 8 - (tty->column & 7);
     727      if ((tty->termios.c_oflag & TABDLY) == XTABS) {
     728        tty->column += i;
     729        rtems_termios_puts ( "        ",  i, tty);
     730        return;
     731      }
     732      tty->column += i;
     733      break;
     734
     735    case '\b':
     736      if (tty->column > 0)
     737        tty->column--;
     738      break;
     739
     740    default:
     741      if (tty->termios.c_oflag & OLCUC)
     742        c = toupper(c);
     743      if (!iscntrl(c))
     744        tty->column++;
     745      break;
     746    }
     747  }
     748  rtems_termios_puts (&c, 1, tty);
    749749}
    750750
     
    752752rtems_termios_write (void *arg)
    753753{
    754         rtems_libio_rw_args_t *args = arg;
    755         struct rtems_termios_tty *tty = args->iop->data1;
    756         rtems_status_code sc;
    757 
    758         sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    759         if (sc != RTEMS_SUCCESSFUL)
    760                 return sc;
    761         if (rtems_termios_linesw[tty->t_line].l_write != NULL) {
    762                 sc = rtems_termios_linesw[tty->t_line].l_write(tty,args);
    763                 rtems_semaphore_release (tty->osem);
    764                 return sc;
    765         }
    766         if (tty->termios.c_oflag & OPOST) {
    767                 uint32_t   count = args->count;
    768                 char      *buffer = args->buffer;
    769                 while (count--)
    770                         oproc (*buffer++, tty);
    771                 args->bytes_moved = args->count;
    772         }
    773         else {
    774                 rtems_termios_puts (args->buffer, args->count, tty);
    775                 args->bytes_moved = args->count;
    776         }
    777         rtems_semaphore_release (tty->osem);
    778         return sc;
     754  rtems_libio_rw_args_t *args = arg;
     755  struct rtems_termios_tty *tty = args->iop->data1;
     756  rtems_status_code sc;
     757
     758  sc = rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     759  if (sc != RTEMS_SUCCESSFUL)
     760    return sc;
     761  if (rtems_termios_linesw[tty->t_line].l_write != NULL) {
     762    sc = rtems_termios_linesw[tty->t_line].l_write(tty,args);
     763    rtems_semaphore_release (tty->osem);
     764    return sc;
     765  }
     766  if (tty->termios.c_oflag & OPOST) {
     767    uint32_t   count = args->count;
     768    char      *buffer = args->buffer;
     769    while (count--)
     770      oproc (*buffer++, tty);
     771    args->bytes_moved = args->count;
     772  }
     773  else {
     774    rtems_termios_puts (args->buffer, args->count, tty);
     775    args->bytes_moved = args->count;
     776  }
     777  rtems_semaphore_release (tty->osem);
     778  return sc;
    779779}
    780780
     
    785785echo (unsigned char c, struct rtems_termios_tty *tty)
    786786{
    787         if ((tty->termios.c_lflag & ECHOCTL) && iscntrl(c) && (c != '\t') && (c != '\n')) {
    788                 char echobuf[2];
    789 
    790                 echobuf[0] = '^';
    791                 echobuf[1] = c ^ 0x40;
    792                 rtems_termios_puts (echobuf, 2, tty);
    793                 tty->column += 2;
    794         }
    795         else {
    796                 oproc (c, tty);
    797         }
     787  if ((tty->termios.c_lflag & ECHOCTL) && iscntrl(c) && (c != '\t') && (c != '\n')) {
     788    char echobuf[2];
     789
     790    echobuf[0] = '^';
     791    echobuf[1] = c ^ 0x40;
     792    rtems_termios_puts (echobuf, 2, tty);
     793    tty->column += 2;
     794  }
     795  else {
     796    oproc (c, tty);
     797  }
    798798}
    799799
     
    806806erase (struct rtems_termios_tty *tty, int lineFlag)
    807807{
    808         if (tty->ccount == 0)
    809                 return;
    810         if (lineFlag) {
    811                 if (!(tty->termios.c_lflag & ECHO)) {
    812                         tty->ccount = 0;
    813                         return;
    814                 }
    815                 if (!(tty->termios.c_lflag & ECHOE)) {
    816                         tty->ccount = 0;
    817                         echo (tty->termios.c_cc[VKILL], tty);
    818                         if (tty->termios.c_lflag & ECHOK)
    819                                 echo ('\n', tty);
    820                         return;
    821                 }
    822         }
    823         while (tty->ccount) {
    824                 unsigned char c = tty->cbuf[--tty->ccount];
    825 
    826                 if (tty->termios.c_lflag & ECHO) {
    827                         if (!lineFlag && !(tty->termios.c_lflag & ECHOE)) {
    828                                 echo (tty->termios.c_cc[VERASE], tty);
    829                         }
    830                         else if (c == '\t') {
    831                                 int col = tty->read_start_column;
    832                                 int i = 0;
    833 
    834                                 /*
    835                                 * Find the character before the tab
    836                                 */
    837                                 while (i != tty->ccount) {
    838                                         c = tty->cbuf[i++];
    839                                         if (c == '\t') {
    840                                                 col = (col | 7) + 1;
    841                                         }
    842                                         else if (iscntrl (c)) {
    843                                                 if (tty->termios.c_lflag & ECHOCTL)
    844                                                         col += 2;
    845                                         }
    846                                         else {
    847                                                 col++;
    848                                         }
    849                                 }
    850 
    851                                 /*
    852                                 * Back up over the tab
    853                                 */
    854                                 while (tty->column > col) {
    855                                         rtems_termios_puts ("\b", 1, tty);
    856                                         tty->column--;
    857                                 }
    858                         }
    859                         else {
    860                                 if (iscntrl (c) && (tty->termios.c_lflag & ECHOCTL)) {
    861                                         rtems_termios_puts ("\b \b", 3, tty);
    862                                         if (tty->column)
    863                                                 tty->column--;
    864                                 }
    865                                 if (!iscntrl (c) || (tty->termios.c_lflag & ECHOCTL)) {
    866                                         rtems_termios_puts ("\b \b", 3, tty);
    867                                         if (tty->column)
    868                                                 tty->column--;
    869                                 }
    870                         }
    871                 }
    872                 if (!lineFlag)
    873                         break;
    874         }
     808  if (tty->ccount == 0)
     809    return;
     810  if (lineFlag) {
     811    if (!(tty->termios.c_lflag & ECHO)) {
     812      tty->ccount = 0;
     813      return;
     814    }
     815    if (!(tty->termios.c_lflag & ECHOE)) {
     816      tty->ccount = 0;
     817      echo (tty->termios.c_cc[VKILL], tty);
     818      if (tty->termios.c_lflag & ECHOK)
     819        echo ('\n', tty);
     820      return;
     821    }
     822  }
     823  while (tty->ccount) {
     824    unsigned char c = tty->cbuf[--tty->ccount];
     825
     826    if (tty->termios.c_lflag & ECHO) {
     827      if (!lineFlag && !(tty->termios.c_lflag & ECHOE)) {
     828        echo (tty->termios.c_cc[VERASE], tty);
     829      }
     830      else if (c == '\t') {
     831        int col = tty->read_start_column;
     832        int i = 0;
     833
     834        /*
     835        * Find the character before the tab
     836        */
     837        while (i != tty->ccount) {
     838          c = tty->cbuf[i++];
     839          if (c == '\t') {
     840            col = (col | 7) + 1;
     841          }
     842          else if (iscntrl (c)) {
     843            if (tty->termios.c_lflag & ECHOCTL)
     844              col += 2;
     845          }
     846          else {
     847            col++;
     848          }
     849        }
     850
     851        /*
     852        * Back up over the tab
     853        */
     854        while (tty->column > col) {
     855          rtems_termios_puts ("\b", 1, tty);
     856          tty->column--;
     857        }
     858      }
     859      else {
     860        if (iscntrl (c) && (tty->termios.c_lflag & ECHOCTL)) {
     861          rtems_termios_puts ("\b \b", 3, tty);
     862          if (tty->column)
     863            tty->column--;
     864        }
     865        if (!iscntrl (c) || (tty->termios.c_lflag & ECHOCTL)) {
     866          rtems_termios_puts ("\b \b", 3, tty);
     867          if (tty->column)
     868            tty->column--;
     869        }
     870      }
     871    }
     872    if (!lineFlag)
     873      break;
     874  }
    875875}
    876876
     
    881881iproc (unsigned char c, struct rtems_termios_tty *tty)
    882882{
    883         if (tty->termios.c_iflag & ISTRIP)
    884                 c &= 0x7f;
    885         if (tty->termios.c_iflag & IUCLC)
    886                 c = tolower (c);
    887         if (c == '\r') {
    888                 if (tty->termios.c_iflag & IGNCR)
    889                         return 0;
    890                 if (tty->termios.c_iflag & ICRNL)
    891                         c = '\n';
    892         }
    893         else if ((c == '\n') && (tty->termios.c_iflag & INLCR)) {
    894                 c = '\r';
    895         }
    896         if ((c != '\0') && (tty->termios.c_lflag & ICANON)) {
    897                 if (c == tty->termios.c_cc[VERASE]) {
    898                         erase (tty, 0);
    899                         return 0;
    900                 }
    901                 else if (c == tty->termios.c_cc[VKILL]) {
    902                         erase (tty, 1);
    903                         return 0;
    904                 }
    905                 else if (c == tty->termios.c_cc[VEOF]) {
    906                         return 1;
    907                 }
    908                 else if (c == '\n') {
    909                         if (tty->termios.c_lflag & (ECHO | ECHONL))
    910                                 echo (c, tty);
    911                         tty->cbuf[tty->ccount++] = c;
    912                         return 1;
    913                 }
    914                 else if ((c == tty->termios.c_cc[VEOL])
    915                       || (c == tty->termios.c_cc[VEOL2])) {
    916                         if (tty->termios.c_lflag & ECHO)
    917                                 echo (c, tty);
    918                         tty->cbuf[tty->ccount++] = c;
    919                         return 1;
    920                 }
    921         }
    922 
    923         /*
    924         * FIXME: Should do IMAXBEL handling somehow
    925         */
    926         if (tty->ccount < (CBUFSIZE-1)) {
    927                 if (tty->termios.c_lflag & ECHO)
    928                         echo (c, tty);
    929                 tty->cbuf[tty->ccount++] = c;
    930         }
    931         return 0;
     883  if (tty->termios.c_iflag & ISTRIP)
     884    c &= 0x7f;
     885  if (tty->termios.c_iflag & IUCLC)
     886    c = tolower (c);
     887  if (c == '\r') {
     888    if (tty->termios.c_iflag & IGNCR)
     889      return 0;
     890    if (tty->termios.c_iflag & ICRNL)
     891      c = '\n';
     892  }
     893  else if ((c == '\n') && (tty->termios.c_iflag & INLCR)) {
     894    c = '\r';
     895  }
     896  if ((c != '\0') && (tty->termios.c_lflag & ICANON)) {
     897    if (c == tty->termios.c_cc[VERASE]) {
     898      erase (tty, 0);
     899      return 0;
     900    }
     901    else if (c == tty->termios.c_cc[VKILL]) {
     902      erase (tty, 1);
     903      return 0;
     904    }
     905    else if (c == tty->termios.c_cc[VEOF]) {
     906      return 1;
     907    }
     908    else if (c == '\n') {
     909      if (tty->termios.c_lflag & (ECHO | ECHONL))
     910        echo (c, tty);
     911      tty->cbuf[tty->ccount++] = c;
     912      return 1;
     913    }
     914    else if ((c == tty->termios.c_cc[VEOL])
     915          || (c == tty->termios.c_cc[VEOL2])) {
     916      if (tty->termios.c_lflag & ECHO)
     917        echo (c, tty);
     918      tty->cbuf[tty->ccount++] = c;
     919      return 1;
     920    }
     921  }
     922
     923  /*
     924  * FIXME: Should do IMAXBEL handling somehow
     925  */
     926  if (tty->ccount < (CBUFSIZE-1)) {
     927    if (tty->termios.c_lflag & ECHO)
     928      echo (c, tty);
     929    tty->cbuf[tty->ccount++] = c;
     930  }
     931  return 0;
    932932}
    933933
     
    938938siproc (unsigned char c, struct rtems_termios_tty *tty)
    939939{
    940         int i;
    941 
    942         /*
    943         * Obtain output semaphore if character will be echoed
    944         */
    945         if (tty->termios.c_lflag & (ECHO|ECHOE|ECHOK|ECHONL|ECHOPRT|ECHOCTL|ECHOKE)) {
    946                 rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    947                 i = iproc (c, tty);
    948                 rtems_semaphore_release (tty->osem);
    949         }
    950         else {
    951                 i = iproc (c, tty);
    952         }
    953         return i;
     940  int i;
     941
     942  /*
     943  * Obtain output semaphore if character will be echoed
     944  */
     945  if (tty->termios.c_lflag & (ECHO|ECHOE|ECHOK|ECHONL|ECHOPRT|ECHOCTL|ECHOKE)) {
     946    rtems_semaphore_obtain (tty->osem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     947    i = iproc (c, tty);
     948    rtems_semaphore_release (tty->osem);
     949  }
     950  else {
     951    i = iproc (c, tty);
     952  }
     953  return i;
    954954}
    955955
     
    960960fillBufferPoll (struct rtems_termios_tty *tty)
    961961{
    962         int n;
    963 
    964         if (tty->termios.c_lflag & ICANON) {
    965                 for (;;) {
    966                         n = (*tty->device.pollRead)(tty->minor);
    967                         if (n < 0) {
    968                                 rtems_task_wake_after (1);
    969                         }
    970                         else {
    971                                 if  (siproc (n, tty))
    972                                         break;
    973                         }
    974                 }
    975         }
    976         else {
    977                 rtems_interval then, now;
    978                 then = rtems_clock_get_ticks_since_boot();
    979                 for (;;) {
    980                         n = (*tty->device.pollRead)(tty->minor);
    981                         if (n < 0) {
    982                                 if (tty->termios.c_cc[VMIN]) {
    983                                         if (tty->termios.c_cc[VTIME] && tty->ccount) {
    984                                                 now = rtems_clock_get_ticks_since_boot();
    985                                                 if ((now - then) > tty->vtimeTicks) {
    986                                                         break;
    987                                                 }
    988                                         }
    989                                 }
    990                                 else {
    991                                         if (!tty->termios.c_cc[VTIME])
    992                                                 break;
    993                                         now = rtems_clock_get_ticks_since_boot();
    994                                         if ((now - then) > tty->vtimeTicks) {
    995                                                 break;
    996                                         }
    997                                 }
    998                                 rtems_task_wake_after (1);
    999                         }
    1000                         else {
    1001                                 siproc (n, tty);
    1002                                 if (tty->ccount >= tty->termios.c_cc[VMIN])
    1003                                         break;
    1004                                 if (tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
    1005                                         then = rtems_clock_get_ticks_since_boot();
    1006                         }
    1007                 }
    1008         }
    1009         return RTEMS_SUCCESSFUL;
     962  int n;
     963
     964  if (tty->termios.c_lflag & ICANON) {
     965    for (;;) {
     966      n = (*tty->device.pollRead)(tty->minor);
     967      if (n < 0) {
     968        rtems_task_wake_after (1);
     969      }
     970      else {
     971        if  (siproc (n, tty))
     972          break;
     973      }
     974    }
     975  }
     976  else {
     977    rtems_interval then, now;
     978    then = rtems_clock_get_ticks_since_boot();
     979    for (;;) {
     980      n = (*tty->device.pollRead)(tty->minor);
     981      if (n < 0) {
     982        if (tty->termios.c_cc[VMIN]) {
     983          if (tty->termios.c_cc[VTIME] && tty->ccount) {
     984            now = rtems_clock_get_ticks_since_boot();
     985            if ((now - then) > tty->vtimeTicks) {
     986              break;
     987            }
     988          }
     989        }
     990        else {
     991          if (!tty->termios.c_cc[VTIME])
     992            break;
     993          now = rtems_clock_get_ticks_since_boot();
     994          if ((now - then) > tty->vtimeTicks) {
     995            break;
     996          }
     997        }
     998        rtems_task_wake_after (1);
     999      }
     1000      else {
     1001        siproc (n, tty);
     1002        if (tty->ccount >= tty->termios.c_cc[VMIN])
     1003          break;
     1004        if (tty->termios.c_cc[VMIN] && tty->termios.c_cc[VTIME])
     1005          then = rtems_clock_get_ticks_since_boot();
     1006      }
     1007    }
     1008  }
     1009  return RTEMS_SUCCESSFUL;
    10101010}
    10111011
     
    10161016fillBufferQueue (struct rtems_termios_tty *tty)
    10171017{
    1018         rtems_interval timeout = tty->rawInBufSemaphoreFirstTimeout;
    1019         rtems_status_code sc;
    1020         int               wait = (int)1;
    1021 
    1022         while ( wait ) {
    1023                 /*
    1024                 * Process characters read from raw queue
    1025                 */
    1026                 while ((tty->rawInBuf.Head != tty->rawInBuf.Tail) &&
     1018  rtems_interval timeout = tty->rawInBufSemaphoreFirstTimeout;
     1019  rtems_status_code sc;
     1020  int               wait = (int)1;
     1021
     1022  while ( wait ) {
     1023    /*
     1024    * Process characters read from raw queue
     1025    */
     1026    while ((tty->rawInBuf.Head != tty->rawInBuf.Tail) &&
    10271027                       (tty->ccount < (CBUFSIZE-1))) {
    1028                         unsigned char c;
    1029                         unsigned int newHead;
    1030 
    1031                         newHead = (tty->rawInBuf.Head + 1) % tty->rawInBuf.Size;
    1032                         c = tty->rawInBuf.theBuf[newHead];
    1033                         tty->rawInBuf.Head = newHead;
    1034                         if(((tty->rawInBuf.Tail-newHead+tty->rawInBuf.Size)
    1035                             % tty->rawInBuf.Size)
    1036                            < tty->lowwater) {
    1037                           tty->flow_ctrl &= ~FL_IREQXOF;
    1038                           /* if tx stopped and XON should be sent... */
    1039                           if (((tty->flow_ctrl & (FL_MDXON | FL_ISNTXOF))
    1040                                ==                (FL_MDXON | FL_ISNTXOF))
    1041                               && ((tty->rawOutBufState == rob_idle)
    1042                                   || (tty->flow_ctrl & FL_OSTOP))) {
    1043                             /* XON should be sent now... */
    1044                             (*tty->device.write)(tty->minor,
    1045                                 (void *)&(tty->termios.c_cc[VSTART]),
    1046                                 1);
    1047                           }
    1048                           else if (tty->flow_ctrl & FL_MDRTS) {
    1049                             tty->flow_ctrl &= ~FL_IRTSOFF;
    1050                             /* activate RTS line */
    1051                             if (tty->device.startRemoteTx != NULL) {
    1052                               tty->device.startRemoteTx(tty->minor);
    1053                             }
    1054                           }
    1055                         }
    1056 
    1057                         /* continue processing new character */
    1058                         if (tty->termios.c_lflag & ICANON) {
    1059                                 if  (siproc (c, tty))
    1060                                         wait = 0;
    1061                         }
    1062                         else {
    1063                                 siproc (c, tty);
    1064                                 if (tty->ccount >= tty->termios.c_cc[VMIN])
    1065                                         wait = 0;
    1066                         }
    1067                         timeout = tty->rawInBufSemaphoreTimeout;
    1068                 }
    1069 
    1070                 /*
    1071                 * Wait for characters
    1072                 */
    1073                 if ( wait ) {
    1074                         sc = rtems_semaphore_obtain (tty->rawInBuf.Semaphore,
    1075                                 tty->rawInBufSemaphoreOptions,
    1076                                 timeout);
    1077                         if (sc != RTEMS_SUCCESSFUL)
    1078                                 break;
    1079                 }
    1080         }
    1081         return RTEMS_SUCCESSFUL;
     1028      unsigned char c;
     1029      unsigned int newHead;
     1030
     1031      newHead = (tty->rawInBuf.Head + 1) % tty->rawInBuf.Size;
     1032      c = tty->rawInBuf.theBuf[newHead];
     1033      tty->rawInBuf.Head = newHead;
     1034      if(((tty->rawInBuf.Tail-newHead+tty->rawInBuf.Size)
     1035          % tty->rawInBuf.Size)
     1036         < tty->lowwater) {
     1037        tty->flow_ctrl &= ~FL_IREQXOF;
     1038        /* if tx stopped and XON should be sent... */
     1039        if (((tty->flow_ctrl & (FL_MDXON | FL_ISNTXOF))
     1040             ==                (FL_MDXON | FL_ISNTXOF))
     1041            && ((tty->rawOutBufState == rob_idle)
     1042          || (tty->flow_ctrl & FL_OSTOP))) {
     1043          /* XON should be sent now... */
     1044          (*tty->device.write)(tty->minor,
     1045        (void *)&(tty->termios.c_cc[VSTART]),
     1046        1);
     1047        }
     1048        else if (tty->flow_ctrl & FL_MDRTS) {
     1049          tty->flow_ctrl &= ~FL_IRTSOFF;
     1050          /* activate RTS line */
     1051          if (tty->device.startRemoteTx != NULL) {
     1052            tty->device.startRemoteTx(tty->minor);
     1053          }
     1054        }
     1055      }
     1056
     1057      /* continue processing new character */
     1058      if (tty->termios.c_lflag & ICANON) {
     1059        if  (siproc (c, tty))
     1060          wait = 0;
     1061      }
     1062      else {
     1063        siproc (c, tty);
     1064        if (tty->ccount >= tty->termios.c_cc[VMIN])
     1065          wait = 0;
     1066      }
     1067      timeout = tty->rawInBufSemaphoreTimeout;
     1068    }
     1069
     1070    /*
     1071    * Wait for characters
     1072    */
     1073    if ( wait ) {
     1074      sc = rtems_semaphore_obtain (tty->rawInBuf.Semaphore,
     1075        tty->rawInBufSemaphoreOptions,
     1076        timeout);
     1077      if (sc != RTEMS_SUCCESSFUL)
     1078        break;
     1079    }
     1080  }
     1081  return RTEMS_SUCCESSFUL;
    10821082}
    10831083
     
    10851085rtems_termios_read (void *arg)
    10861086{
    1087         rtems_libio_rw_args_t *args = arg;
    1088         struct rtems_termios_tty *tty = args->iop->data1;
    1089         uint32_t   count = args->count;
    1090         char      *buffer = args->buffer;
    1091         rtems_status_code sc;
    1092 
    1093         sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    1094         if (sc != RTEMS_SUCCESSFUL)
    1095                 return sc;
    1096         if (rtems_termios_linesw[tty->t_line].l_read != NULL) {
    1097                 sc = rtems_termios_linesw[tty->t_line].l_read(tty,args);
    1098                 tty->tty_rcvwakeup = 0;
    1099                 rtems_semaphore_release (tty->isem);
    1100                 return sc;
    1101         }
    1102         if (tty->cindex == tty->ccount) {
    1103                 tty->cindex = tty->ccount = 0;
    1104                 tty->read_start_column = tty->column;
    1105                 if (tty->device.pollRead != NULL
    1106                     && tty->device.outputUsesInterrupts == TERMIOS_POLLED)
    1107                         sc = fillBufferPoll (tty);
    1108                 else
    1109                         sc = fillBufferQueue (tty);
    1110                 if (sc != RTEMS_SUCCESSFUL)
    1111                         tty->cindex = tty->ccount = 0;
    1112         }
    1113         while (count && (tty->cindex < tty->ccount)) {
    1114                 *buffer++ = tty->cbuf[tty->cindex++];
    1115                 count--;
    1116         }
    1117         args->bytes_moved = args->count - count;
    1118         tty->tty_rcvwakeup = 0;
    1119         rtems_semaphore_release (tty->isem);
    1120         return sc;
     1087  rtems_libio_rw_args_t *args = arg;
     1088  struct rtems_termios_tty *tty = args->iop->data1;
     1089  uint32_t   count = args->count;
     1090  char      *buffer = args->buffer;
     1091  rtems_status_code sc;
     1092
     1093  sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     1094  if (sc != RTEMS_SUCCESSFUL)
     1095    return sc;
     1096  if (rtems_termios_linesw[tty->t_line].l_read != NULL) {
     1097    sc = rtems_termios_linesw[tty->t_line].l_read(tty,args);
     1098    tty->tty_rcvwakeup = 0;
     1099    rtems_semaphore_release (tty->isem);
     1100    return sc;
     1101  }
     1102  if (tty->cindex == tty->ccount) {
     1103    tty->cindex = tty->ccount = 0;
     1104    tty->read_start_column = tty->column;
     1105    if (tty->device.pollRead != NULL
     1106        && tty->device.outputUsesInterrupts == TERMIOS_POLLED)
     1107      sc = fillBufferPoll (tty);
     1108    else
     1109      sc = fillBufferQueue (tty);
     1110    if (sc != RTEMS_SUCCESSFUL)
     1111      tty->cindex = tty->ccount = 0;
     1112  }
     1113  while (count && (tty->cindex < tty->ccount)) {
     1114    *buffer++ = tty->cbuf[tty->cindex++];
     1115    count--;
     1116  }
     1117  args->bytes_moved = args->count - count;
     1118  tty->tty_rcvwakeup = 0;
     1119  rtems_semaphore_release (tty->isem);
     1120  return sc;
    11211121}
    11221122
     
    11281128void rtems_termios_rxirq_occured(struct rtems_termios_tty *tty)
    11291129{
    1130         /*
    1131         * send event to rx daemon task
    1132         */
    1133         rtems_event_send(tty->rxTaskId,TERMIOS_RX_PROC_EVENT);
     1130  /*
     1131  * send event to rx daemon task
     1132  */
     1133  rtems_event_send(tty->rxTaskId,TERMIOS_RX_PROC_EVENT);
    11341134}
    11351135
     
    11431143rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
    11441144{
    1145         struct rtems_termios_tty *tty = ttyp;
    1146         unsigned int newTail;
    1147         char c;
    1148         int dropped = 0;
    1149         bool flow_rcv = false; /* true, if flow control char received */
    1150         rtems_interrupt_level level;
    1151 
    1152         if (rtems_termios_linesw[tty->t_line].l_rint != NULL) {
    1153           while (len--) {
    1154             c = *buf++;
    1155             rtems_termios_linesw[tty->t_line].l_rint(c,tty);
    1156           }
    1157 
    1158           /*
    1159            * check to see if rcv wakeup callback was set
    1160            */
    1161           if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
    1162             (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
    1163             tty->tty_rcvwakeup = 1;
    1164           }
    1165           return 0;
    1166         }
    1167 
    1168         while (len--) {
    1169           c = *buf++;
    1170           /* FIXME: implement IXANY: any character restarts output */
    1171           /* if incoming XON/XOFF controls outgoing stream: */
    1172           if (tty->flow_ctrl & FL_MDXON) {
    1173             /* if received char is V_STOP and V_START (both are equal value) */
    1174             if (c == tty->termios.c_cc[VSTOP]) {
    1175               if (c == tty->termios.c_cc[VSTART]) {
    1176                 /* received VSTOP and VSTART==VSTOP? */
    1177                 /* then toggle "stop output" status  */
    1178                 tty->flow_ctrl = tty->flow_ctrl ^ FL_ORCVXOF;
    1179               }
    1180               else {
    1181                 /* VSTOP received (other code than VSTART) */
    1182                 /* stop output                             */
    1183                 tty->flow_ctrl |= FL_ORCVXOF;
    1184               }
    1185               flow_rcv = true;
    1186             }
    1187             else if (c == tty->termios.c_cc[VSTART]) {
    1188               /* VSTART received */
    1189               /* restart output  */
    1190               tty->flow_ctrl &= ~FL_ORCVXOF;
    1191               flow_rcv = true;
    1192             }
    1193           }
    1194           if (flow_rcv) {
    1195             /* restart output according to FL_ORCVXOF flag */
    1196             if ((tty->flow_ctrl & (FL_ORCVXOF | FL_OSTOP)) == FL_OSTOP) {
    1197               /* disable interrupts    */
    1198               rtems_interrupt_disable(level);
    1199               tty->flow_ctrl &= ~FL_OSTOP;
    1200               /* check for chars in output buffer (or rob_state?) */
    1201               if (tty->rawOutBufState != rob_idle) {
    1202               /* if chars available, call write function... */
    1203                 (*tty->device.write)(tty->minor,
    1204                      &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1);
    1205               }
    1206               /* reenable interrupts */
    1207               rtems_interrupt_enable(level);
    1208             }
    1209           }
    1210           else {
    1211                 newTail = (tty->rawInBuf.Tail + 1) % tty->rawInBuf.Size;
    1212                 /* if chars_in_buffer > highwater                */
    1213                 rtems_interrupt_disable(level);
    1214                 if ((((newTail - tty->rawInBuf.Head + tty->rawInBuf.Size)
    1215                       % tty->rawInBuf.Size)
    1216                      > tty->highwater) &&
    1217                     !(tty->flow_ctrl & FL_IREQXOF)) {
    1218                   /* incoming data stream should be stopped */
    1219                   tty->flow_ctrl |= FL_IREQXOF;
    1220                   if ((tty->flow_ctrl & (FL_MDXOF | FL_ISNTXOF))
    1221                       ==                (FL_MDXOF             ) ){
    1222                     if ((tty->flow_ctrl & FL_OSTOP) ||
    1223                         (tty->rawOutBufState == rob_idle)) {
    1224                       /* if tx is stopped due to XOFF or out of data */
    1225                       /*    call write function here                 */
    1226                       tty->flow_ctrl |= FL_ISNTXOF;
    1227                       (*tty->device.write)(tty->minor,
    1228                          (void *)&(tty->termios.c_cc[VSTOP]),
    1229                          1);
    1230                     }
    1231                   }
    1232                   else if ((tty->flow_ctrl & (FL_MDRTS | FL_IRTSOFF))
    1233                            ==                (FL_MDRTS             ) ) {
    1234                     tty->flow_ctrl |= FL_IRTSOFF;
    1235                     /* deactivate RTS line */
    1236                     if (tty->device.stopRemoteTx != NULL) {
    1237                       tty->device.stopRemoteTx(tty->minor);
    1238                     }
    1239                   }
    1240                 }
    1241                 /* reenable interrupts */
    1242                 rtems_interrupt_enable(level);
    1243 
    1244                 if (newTail == tty->rawInBuf.Head) {
    1245                         dropped++;
    1246                 }
    1247                 else {
    1248                         tty->rawInBuf.theBuf[newTail] = c;
    1249                         tty->rawInBuf.Tail = newTail;
    1250 
    1251                         /*
    1252                          * check to see if rcv wakeup callback was set
    1253                          */
    1254                         if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
    1255                           (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
    1256                           tty->tty_rcvwakeup = 1;
    1257                         }
    1258                 }
    1259           }
    1260         }
    1261         tty->rawInBufDropped += dropped;
    1262         rtems_semaphore_release (tty->rawInBuf.Semaphore);
    1263         return dropped;
     1145  struct rtems_termios_tty *tty = ttyp;
     1146  unsigned int newTail;
     1147  char c;
     1148  int dropped = 0;
     1149  bool flow_rcv = false; /* true, if flow control char received */
     1150  rtems_interrupt_level level;
     1151
     1152  if (rtems_termios_linesw[tty->t_line].l_rint != NULL) {
     1153    while (len--) {
     1154      c = *buf++;
     1155      rtems_termios_linesw[tty->t_line].l_rint(c,tty);
     1156    }
     1157
     1158    /*
     1159     * check to see if rcv wakeup callback was set
     1160     */
     1161    if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
     1162      (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
     1163      tty->tty_rcvwakeup = 1;
     1164        }
     1165    return 0;
     1166  }
     1167
     1168  while (len--) {
     1169    c = *buf++;
     1170    /* FIXME: implement IXANY: any character restarts output */
     1171    /* if incoming XON/XOFF controls outgoing stream: */
     1172    if (tty->flow_ctrl & FL_MDXON) {
     1173      /* if received char is V_STOP and V_START (both are equal value) */
     1174      if (c == tty->termios.c_cc[VSTOP]) {
     1175        if (c == tty->termios.c_cc[VSTART]) {
     1176          /* received VSTOP and VSTART==VSTOP? */
     1177          /* then toggle "stop output" status  */
     1178          tty->flow_ctrl = tty->flow_ctrl ^ FL_ORCVXOF;
     1179        }
     1180        else {
     1181          /* VSTOP received (other code than VSTART) */
     1182          /* stop output                             */
     1183          tty->flow_ctrl |= FL_ORCVXOF;
     1184        }
     1185        flow_rcv = true;
     1186      }
     1187      else if (c == tty->termios.c_cc[VSTART]) {
     1188        /* VSTART received */
     1189        /* restart output  */
     1190        tty->flow_ctrl &= ~FL_ORCVXOF;
     1191        flow_rcv = true;
     1192      }
     1193    }
     1194    if (flow_rcv) {
     1195      /* restart output according to FL_ORCVXOF flag */
     1196      if ((tty->flow_ctrl & (FL_ORCVXOF | FL_OSTOP)) == FL_OSTOP) {
     1197        /* disable interrupts    */
     1198        rtems_interrupt_disable(level);
     1199        tty->flow_ctrl &= ~FL_OSTOP;
     1200        /* check for chars in output buffer (or rob_state?) */
     1201        if (tty->rawOutBufState != rob_idle) {
     1202        /* if chars available, call write function... */
     1203        (*tty->device.write)(tty->minor,
     1204         &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1);
     1205        }
     1206        /* reenable interrupts */
     1207        rtems_interrupt_enable(level);
     1208      }
     1209    }
     1210    else {
     1211      newTail = (tty->rawInBuf.Tail + 1) % tty->rawInBuf.Size;
     1212      /* if chars_in_buffer > highwater                */
     1213      rtems_interrupt_disable(level);
     1214      if ((((newTail - tty->rawInBuf.Head + tty->rawInBuf.Size)
     1215            % tty->rawInBuf.Size) > tty->highwater) &&
     1216          !(tty->flow_ctrl & FL_IREQXOF)) {
     1217        /* incoming data stream should be stopped */
     1218        tty->flow_ctrl |= FL_IREQXOF;
     1219        if ((tty->flow_ctrl & (FL_MDXOF | FL_ISNTXOF))
     1220            ==                (FL_MDXOF             ) ) {
     1221          if ((tty->flow_ctrl & FL_OSTOP) ||
     1222              (tty->rawOutBufState == rob_idle)) {
     1223            /* if tx is stopped due to XOFF or out of data */
     1224            /*    call write function here                 */
     1225            tty->flow_ctrl |= FL_ISNTXOF;
     1226            (*tty->device.write)(tty->minor,
     1227                (void *)&(tty->termios.c_cc[VSTOP]), 1);
     1228          }
     1229        }
     1230        else if ((tty->flow_ctrl & (FL_MDRTS | FL_IRTSOFF)) == (FL_MDRTS) ) {
     1231          tty->flow_ctrl |= FL_IRTSOFF;
     1232          /* deactivate RTS line */
     1233          if (tty->device.stopRemoteTx != NULL) {
     1234            tty->device.stopRemoteTx(tty->minor);
     1235          }
     1236        }
     1237      }
     1238
     1239      /* reenable interrupts */
     1240      rtems_interrupt_enable(level);
     1241
     1242      if (newTail == tty->rawInBuf.Head) {
     1243        dropped++;
     1244      }
     1245      else {
     1246        tty->rawInBuf.theBuf[newTail] = c;
     1247        tty->rawInBuf.Tail = newTail;
     1248
     1249        /*
     1250         * check to see if rcv wakeup callback was set
     1251         */
     1252        if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
     1253          (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
     1254          tty->tty_rcvwakeup = 1;
     1255        }
     1256      }
     1257    }
     1258  }
     1259  tty->rawInBufDropped += dropped;
     1260  rtems_semaphore_release (tty->rawInBuf.Semaphore);
     1261  return dropped;
    12641262}
    12651263
     
    12711269rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
    12721270{
    1273         unsigned int newTail;
    1274         int nToSend;
    1275         rtems_interrupt_level level;
    1276         int len;
    1277 
    1278         /* check for XOF/XON to send */
    1279         if ((tty->flow_ctrl & (FL_MDXOF | FL_IREQXOF | FL_ISNTXOF))
    1280             == (FL_MDXOF | FL_IREQXOF)) {
    1281           /* XOFF should be sent now... */
    1282           (*tty->device.write)(tty->minor,
    1283                                (void *)&(tty->termios.c_cc[VSTOP]), 1);
    1284 
    1285           rtems_interrupt_disable(level);
    1286           tty->t_dqlen--;
    1287           tty->flow_ctrl |= FL_ISNTXOF;
    1288           rtems_interrupt_enable(level);
    1289 
    1290           nToSend = 1;
    1291         }
    1292         else if ((tty->flow_ctrl & (FL_IREQXOF | FL_ISNTXOF))
    1293                  == FL_ISNTXOF) {
    1294           /* NOTE: send XON even, if no longer in XON/XOFF mode... */
    1295           /* XON should be sent now... */
    1296                 /*
    1297                  * FIXME: this .write call will generate another
    1298                  * dequeue callback. This will advance the "Tail" in the data
    1299                  * buffer, although the corresponding data is not yet out!
    1300                  * Therefore the dequeue "length" should be reduced by 1
    1301                  */
    1302           (*tty->device.write)(tty->minor,
    1303                                (void *)&(tty->termios.c_cc[VSTART]), 1);
    1304 
    1305           rtems_interrupt_disable(level);
    1306           tty->t_dqlen--;
    1307           tty->flow_ctrl &= ~FL_ISNTXOF;
    1308           rtems_interrupt_enable(level);
    1309 
    1310           nToSend = 1;
    1311         }
    1312         else {
    1313           if ( tty->rawOutBuf.Head == tty->rawOutBuf.Tail ) {
    1314             /*
    1315              * buffer was empty
    1316              */
    1317             if (tty->rawOutBufState == rob_wait) {
    1318               /*
    1319                * this should never happen...
    1320                */
    1321               rtems_semaphore_release (tty->rawOutBuf.Semaphore);
    1322             }
    1323             return 0;
    1324           }
    1325 
    1326           rtems_interrupt_disable(level);
    1327           len = tty->t_dqlen;
    1328           tty->t_dqlen = 0;
    1329           rtems_interrupt_enable(level);
    1330 
    1331           newTail = (tty->rawOutBuf.Tail + len) % tty->rawOutBuf.Size;
    1332           tty->rawOutBuf.Tail = newTail;
    1333           if (tty->rawOutBufState == rob_wait) {
    1334             /*
    1335              * wake up any pending writer task
    1336              */
    1337             rtems_semaphore_release (tty->rawOutBuf.Semaphore);
    1338           }
    1339           if (newTail == tty->rawOutBuf.Head) {
    1340             /*
    1341              * Buffer has become empty
    1342              */
    1343             tty->rawOutBufState = rob_idle;
    1344             nToSend = 0;
    1345 
    1346             /*
    1347              * check to see if snd wakeup callback was set
    1348              */
    1349             if ( tty->tty_snd.sw_pfn != NULL) {
    1350               (*tty->tty_snd.sw_pfn)(&tty->termios, tty->tty_snd.sw_arg);
    1351             }
    1352           }
    1353           /* check, whether output should stop due to received XOFF */
    1354           else if ((tty->flow_ctrl & (FL_MDXON | FL_ORCVXOF))
    1355                    ==                (FL_MDXON | FL_ORCVXOF)) {
    1356                   /* Buffer not empty, but output stops due to XOFF */
    1357                   /* set flag, that output has been stopped */
    1358                   rtems_interrupt_disable(level);
    1359                   tty->flow_ctrl |= FL_OSTOP;
    1360                   tty->rawOutBufState = rob_busy; /*apm*/
    1361                   rtems_interrupt_enable(level);
    1362                   nToSend = 0;
    1363           }
    1364           else {
    1365             /*
    1366              * Buffer not empty, start tranmitter
    1367              */
    1368             if (newTail > tty->rawOutBuf.Head)
    1369                     nToSend = tty->rawOutBuf.Size - newTail;
    1370             else
    1371                     nToSend = tty->rawOutBuf.Head - newTail;
    1372             /* when flow control XON or XOF, don't send blocks of data     */
    1373             /* to allow fast reaction on incoming flow ctrl and low latency*/
    1374             /* for outgoing flow control                                   */
    1375             if (tty->flow_ctrl & (FL_MDXON | FL_MDXOF)) {
    1376                     nToSend = 1;
    1377             }
    1378             tty->rawOutBufState = rob_busy; /*apm*/
    1379             (*tty->device.write)(tty->minor,
    1380                                  &tty->rawOutBuf.theBuf[newTail],
    1381                                  nToSend);
    1382           }
    1383           tty->rawOutBuf.Tail = newTail; /*apm*/
    1384         }
    1385         return nToSend;
     1271  unsigned int newTail;
     1272  int nToSend;
     1273  rtems_interrupt_level level;
     1274  int len;
     1275
     1276  /* check for XOF/XON to send */
     1277  if ((tty->flow_ctrl & (FL_MDXOF | FL_IREQXOF | FL_ISNTXOF))
     1278      == (FL_MDXOF | FL_IREQXOF)) {
     1279    /* XOFF should be sent now... */
     1280    (*tty->device.write)(tty->minor,
     1281        (void *)&(tty->termios.c_cc[VSTOP]), 1);
     1282
     1283    rtems_interrupt_disable(level);
     1284    tty->t_dqlen--;
     1285    tty->flow_ctrl |= FL_ISNTXOF;
     1286    rtems_interrupt_enable(level);
     1287
     1288    nToSend = 1;
     1289  }
     1290  else if ((tty->flow_ctrl & (FL_IREQXOF | FL_ISNTXOF)) == FL_ISNTXOF) {
     1291    /* NOTE: send XON even, if no longer in XON/XOFF mode... */
     1292    /* XON should be sent now... */
     1293    /*
     1294     * FIXME: this .write call will generate another
     1295     * dequeue callback. This will advance the "Tail" in the data
     1296     * buffer, although the corresponding data is not yet out!
     1297     * Therefore the dequeue "length" should be reduced by 1
     1298     */
     1299    (*tty->device.write)(tty->minor,
     1300             (void *)&(tty->termios.c_cc[VSTART]), 1);
     1301
     1302    rtems_interrupt_disable(level);
     1303    tty->t_dqlen--;
     1304    tty->flow_ctrl &= ~FL_ISNTXOF;
     1305    rtems_interrupt_enable(level);
     1306
     1307    nToSend = 1;
     1308  }
     1309  else {
     1310    if ( tty->rawOutBuf.Head == tty->rawOutBuf.Tail ) {
     1311      /*
     1312       * buffer was empty
     1313       */
     1314      if (tty->rawOutBufState == rob_wait) {
     1315        /*
     1316         * this should never happen...
     1317         */
     1318        rtems_semaphore_release (tty->rawOutBuf.Semaphore);
     1319      }
     1320      return 0;
     1321    }
     1322
     1323    rtems_interrupt_disable(level);
     1324    len = tty->t_dqlen;
     1325    tty->t_dqlen = 0;
     1326    rtems_interrupt_enable(level);
     1327
     1328    newTail = (tty->rawOutBuf.Tail + len) % tty->rawOutBuf.Size;
     1329    tty->rawOutBuf.Tail = newTail;
     1330    if (tty->rawOutBufState == rob_wait) {
     1331      /*
     1332       * wake up any pending writer task
     1333       */
     1334      rtems_semaphore_release (tty->rawOutBuf.Semaphore);
     1335    }
     1336    if (newTail == tty->rawOutBuf.Head) {
     1337      /*
     1338       * Buffer has become empty
     1339       */
     1340      tty->rawOutBufState = rob_idle;
     1341      nToSend = 0;
     1342
     1343      /*
     1344       * check to see if snd wakeup callback was set
     1345       */
     1346      if ( tty->tty_snd.sw_pfn != NULL) {
     1347        (*tty->tty_snd.sw_pfn)(&tty->termios, tty->tty_snd.sw_arg);
     1348      }
     1349    }
     1350    /* check, whether output should stop due to received XOFF */
     1351    else if ((tty->flow_ctrl & (FL_MDXON | FL_ORCVXOF))
     1352       ==                (FL_MDXON | FL_ORCVXOF)) {
     1353      /* Buffer not empty, but output stops due to XOFF */
     1354      /* set flag, that output has been stopped */
     1355      rtems_interrupt_disable(level);
     1356      tty->flow_ctrl |= FL_OSTOP;
     1357      tty->rawOutBufState = rob_busy; /*apm*/
     1358      rtems_interrupt_enable(level);
     1359      nToSend = 0;
     1360    }
     1361    else {
     1362      /*
     1363       * Buffer not empty, start tranmitter
     1364       */
     1365      if (newTail > tty->rawOutBuf.Head)
     1366        nToSend = tty->rawOutBuf.Size - newTail;
     1367      else
     1368        nToSend = tty->rawOutBuf.Head - newTail;
     1369      /* when flow control XON or XOF, don't send blocks of data     */
     1370      /* to allow fast reaction on incoming flow ctrl and low latency*/
     1371      /* for outgoing flow control                                   */
     1372      if (tty->flow_ctrl & (FL_MDXON | FL_MDXOF)) {
     1373        nToSend = 1;
     1374      }
     1375      tty->rawOutBufState = rob_busy; /*apm*/
     1376      (*tty->device.write)(tty->minor,
     1377         &tty->rawOutBuf.theBuf[newTail],
     1378         nToSend);
     1379    }
     1380    tty->rawOutBuf.Tail = newTail; /*apm*/
     1381  }
     1382  return nToSend;
    13861383}
    13871384
     
    13981395rtems_termios_dequeue_characters (void *ttyp, int len)
    13991396{
    1400         struct rtems_termios_tty *tty = ttyp;
    1401         rtems_status_code sc;
    1402 
    1403         /*
    1404         * sum up character count already sent
    1405         */
    1406         tty->t_dqlen += len;
    1407 
    1408         if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) {
    1409                 /*
    1410                 * send wake up to transmitter task
    1411                 */
    1412                 sc = rtems_event_send(tty->txTaskId,
    1413                                       TERMIOS_TX_START_EVENT);
    1414                 if (sc != RTEMS_SUCCESSFUL)
    1415                         rtems_fatal_error_occurred (sc);
    1416                 return 0; /* nothing to output in IRQ... */
    1417         }
    1418         else if (tty->t_line == PPPDISC ) {
    1419                 /*
    1420                  * call any line discipline start function
    1421                  */
    1422                 if (rtems_termios_linesw[tty->t_line].l_start != NULL) {
    1423                         rtems_termios_linesw[tty->t_line].l_start(tty);
    1424                 }
    1425                 return 0; /* nothing to output in IRQ... */
    1426         }
    1427         else {
    1428                 return rtems_termios_refill_transmitter(tty);
    1429         }
     1397  struct rtems_termios_tty *tty = ttyp;
     1398  rtems_status_code sc;
     1399
     1400  /*
     1401  * sum up character count already sent
     1402  */
     1403  tty->t_dqlen += len;
     1404
     1405  if (tty->device.outputUsesInterrupts == TERMIOS_TASK_DRIVEN) {
     1406    /*
     1407    * send wake up to transmitter task
     1408    */
     1409    sc = rtems_event_send(tty->txTaskId,
     1410              TERMIOS_TX_START_EVENT);
     1411    if (sc != RTEMS_SUCCESSFUL)
     1412      rtems_fatal_error_occurred (sc);
     1413    return 0; /* nothing to output in IRQ... */
     1414  }
     1415
     1416  if (tty->t_line == PPPDISC ) {
     1417    /*
     1418     * call any line discipline start function
     1419     */
     1420    if (rtems_termios_linesw[tty->t_line].l_start != NULL) {
     1421      rtems_termios_linesw[tty->t_line].l_start(tty);
     1422    }
     1423    return 0; /* nothing to output in IRQ... */
     1424  }
     1425
     1426  return rtems_termios_refill_transmitter(tty);
    14301427}
    14311428
     
    14351432static rtems_task rtems_termios_txdaemon(rtems_task_argument argument)
    14361433{
    1437         struct rtems_termios_tty *tty = (struct rtems_termios_tty *)argument;
    1438         rtems_event_set the_event;
    1439 
    1440         while (1) {
    1441                 /*
    1442                 * wait for rtems event
    1443                 */
    1444                 rtems_event_receive((TERMIOS_TX_START_EVENT |
    1445                                      TERMIOS_TX_TERMINATE_EVENT),
    1446                                     RTEMS_EVENT_ANY | RTEMS_WAIT,
    1447                                     RTEMS_NO_TIMEOUT,
    1448                                     &the_event);
    1449                 if ((the_event & TERMIOS_TX_TERMINATE_EVENT) != 0) {
    1450                         tty->txTaskId = 0;
    1451                         rtems_task_delete(RTEMS_SELF);
    1452                 }
    1453                 else {
    1454                         /*
    1455                         * call any line discipline start function
    1456                         */
    1457                         if (rtems_termios_linesw[tty->t_line].l_start != NULL) {
    1458                                 rtems_termios_linesw[tty->t_line].l_start(tty);
    1459                         }
    1460                         /*
    1461                         * try to push further characters to device
    1462                         */
    1463                         rtems_termios_refill_transmitter(tty);
    1464                 }
    1465         }
     1434  struct rtems_termios_tty *tty = (struct rtems_termios_tty *)argument;
     1435  rtems_event_set the_event;
     1436
     1437  while (1) {
     1438    /*
     1439    * wait for rtems event
     1440    */
     1441    rtems_event_receive((TERMIOS_TX_START_EVENT |
     1442             TERMIOS_TX_TERMINATE_EVENT),
     1443            RTEMS_EVENT_ANY | RTEMS_WAIT,
     1444            RTEMS_NO_TIMEOUT,
     1445            &the_event);
     1446    if ((the_event & TERMIOS_TX_TERMINATE_EVENT) != 0) {
     1447      tty->txTaskId = 0;
     1448      rtems_task_delete(RTEMS_SELF);
     1449    }
     1450    else {
     1451      /*
     1452      * call any line discipline start function
     1453      */
     1454      if (rtems_termios_linesw[tty->t_line].l_start != NULL) {
     1455        rtems_termios_linesw[tty->t_line].l_start(tty);
     1456      }
     1457      /*
     1458      * try to push further characters to device
     1459      */
     1460      rtems_termios_refill_transmitter(tty);
     1461    }
     1462  }
    14661463}
    14671464
     
    14711468static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument)
    14721469{
    1473         struct rtems_termios_tty *tty = (struct rtems_termios_tty *)argument;
    1474         rtems_event_set the_event;
    1475         int c;
    1476         char c_buf;
    1477         while (1) {
    1478                 /*
    1479                 * wait for rtems event
    1480                 */
    1481                 rtems_event_receive((TERMIOS_RX_PROC_EVENT |
    1482                                      TERMIOS_RX_TERMINATE_EVENT),
    1483                                     RTEMS_EVENT_ANY | RTEMS_WAIT,
    1484                                     RTEMS_NO_TIMEOUT,
    1485                                     &the_event);
    1486                 if ((the_event & TERMIOS_RX_TERMINATE_EVENT) != 0) {
    1487                         tty->rxTaskId = 0;
    1488                         rtems_task_delete(RTEMS_SELF);
    1489                 }
    1490                 else {
    1491                         /*
    1492                         * do something
    1493                         */
    1494                         c = tty->device.pollRead(tty->minor);
    1495                         if (c != EOF) {
    1496                                 /*
    1497                                 * pollRead did call enqueue on its own
    1498                                 */
    1499                                 c_buf = c;
    1500                                 rtems_termios_enqueue_raw_characters (
    1501                                       tty,&c_buf,1);
    1502                         }
    1503                 }
    1504         }
    1505 }
     1470  struct rtems_termios_tty *tty = (struct rtems_termios_tty *)argument;
     1471  rtems_event_set the_event;
     1472  int c;
     1473  char c_buf;
     1474  while (1) {
     1475    /*
     1476    * wait for rtems event
     1477    */
     1478    rtems_event_receive((TERMIOS_RX_PROC_EVENT |
     1479             TERMIOS_RX_TERMINATE_EVENT),
     1480            RTEMS_EVENT_ANY | RTEMS_WAIT,
     1481            RTEMS_NO_TIMEOUT,
     1482            &the_event);
     1483    if ((the_event & TERMIOS_RX_TERMINATE_EVENT) != 0) {
     1484      tty->rxTaskId = 0;
     1485      rtems_task_delete(RTEMS_SELF);
     1486    }
     1487    else {
     1488      /*
     1489      * do something
     1490      */
     1491      c = tty->device.pollRead(tty->minor);
     1492      if (c != EOF) {
     1493        /*
     1494        * pollRead did call enqueue on its own
     1495        */
     1496        c_buf = c;
     1497        rtems_termios_enqueue_raw_characters (
     1498              tty,&c_buf,1);
     1499      }
     1500    }
     1501  }
     1502}
Note: See TracChangeset for help on using the changeset viewer.