OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [ser-base.c] - Blame information for rev 227

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Generic serial interface functions.
2
 
3
   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2003,
4
   2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "defs.h"
22
#include "serial.h"
23
#include "ser-base.h"
24
#include "event-loop.h"
25
 
26
#include "gdb_select.h"
27
#include "gdb_string.h"
28
#include <sys/time.h>
29
#ifdef USE_WIN32API
30
#include <winsock2.h>
31
#endif
32
 
33
 
34
static timer_handler_func push_event;
35
static handler_func fd_event;
36
 
37
/* Event handling for ASYNC serial code.
38
 
39
   At any time the SERIAL device either: has an empty FIFO and is
40
   waiting on a FD event; or has a non-empty FIFO/error condition and
41
   is constantly scheduling timer events.
42
 
43
   ASYNC only stops pestering its client when it is de-async'ed or it
44
   is told to go away. */
45
 
46
/* Value of scb->async_state: */
47
enum {
48
  /* >= 0 (TIMER_SCHEDULED) */
49
  /* The ID of the currently scheduled timer event. This state is
50
     rarely encountered.  Timer events are one-off so as soon as the
51
     event is delivered the state is shanged to NOTHING_SCHEDULED. */
52
  FD_SCHEDULED = -1,
53
  /* The fd_event() handler is scheduled.  It is called when ever the
54
     file descriptor becomes ready. */
55
  NOTHING_SCHEDULED = -2
56
  /* Either no task is scheduled (just going into ASYNC mode) or a
57
     timer event has just gone off and the current state has been
58
     forced into nothing scheduled. */
59
};
60
 
61
/* Identify and schedule the next ASYNC task based on scb->async_state
62
   and scb->buf* (the input FIFO).  A state machine is used to avoid
63
   the need to make redundant calls into the event-loop - the next
64
   scheduled task is only changed when needed. */
65
 
66
void
67
reschedule (struct serial *scb)
68
{
69
  if (serial_is_async_p (scb))
70
    {
71
      int next_state;
72
      switch (scb->async_state)
73
        {
74
        case FD_SCHEDULED:
75
          if (scb->bufcnt == 0)
76
            next_state = FD_SCHEDULED;
77
          else
78
            {
79
              delete_file_handler (scb->fd);
80
              next_state = create_timer (0, push_event, scb);
81
            }
82
          break;
83
        case NOTHING_SCHEDULED:
84
          if (scb->bufcnt == 0)
85
            {
86
              add_file_handler (scb->fd, fd_event, scb);
87
              next_state = FD_SCHEDULED;
88
            }
89
          else
90
            {
91
              next_state = create_timer (0, push_event, scb);
92
            }
93
          break;
94
        default: /* TIMER SCHEDULED */
95
          if (scb->bufcnt == 0)
96
            {
97
              delete_timer (scb->async_state);
98
              add_file_handler (scb->fd, fd_event, scb);
99
              next_state = FD_SCHEDULED;
100
            }
101
          else
102
            next_state = scb->async_state;
103
          break;
104
        }
105
      if (serial_debug_p (scb))
106
        {
107
          switch (next_state)
108
            {
109
            case FD_SCHEDULED:
110
              if (scb->async_state != FD_SCHEDULED)
111
                fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n",
112
                                    scb->fd);
113
              break;
114
            default: /* TIMER SCHEDULED */
115
              if (scb->async_state == FD_SCHEDULED)
116
                fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n",
117
                                    scb->fd);
118
              break;
119
            }
120
        }
121
      scb->async_state = next_state;
122
    }
123
}
124
 
125
/* FD_EVENT: This is scheduled when the input FIFO is empty (and there
126
   is no pending error).  As soon as data arrives, it is read into the
127
   input FIFO and the client notified.  The client should then drain
128
   the FIFO using readchar().  If the FIFO isn't immediatly emptied,
129
   push_event() is used to nag the client until it is. */
130
 
131
static void
132
fd_event (int error, void *context)
133
{
134
  struct serial *scb = context;
135
  if (error != 0)
136
    {
137
      scb->bufcnt = SERIAL_ERROR;
138
    }
139
  else if (scb->bufcnt == 0)
140
    {
141
      /* Prime the input FIFO.  The readchar() function is used to
142
         pull characters out of the buffer.  See also
143
         generic_readchar(). */
144
      int nr;
145
      nr = scb->ops->read_prim (scb, BUFSIZ);
146
      if (nr == 0)
147
        {
148
          scb->bufcnt = SERIAL_EOF;
149
        }
150
      else if (nr > 0)
151
        {
152
          scb->bufcnt = nr;
153
          scb->bufp = scb->buf;
154
        }
155
      else
156
        {
157
          scb->bufcnt = SERIAL_ERROR;
158
        }
159
    }
160
  scb->async_handler (scb, scb->async_context);
161
  reschedule (scb);
162
}
163
 
164
/* PUSH_EVENT: The input FIFO is non-empty (or there is a pending
165
   error).  Nag the client until all the data has been read.  In the
166
   case of errors, the client will need to close or de-async the
167
   device before naging stops. */
168
 
169
static void
170
push_event (void *context)
171
{
172
  struct serial *scb = context;
173
  scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */
174
  scb->async_handler (scb, scb->async_context);
175
  /* re-schedule */
176
  reschedule (scb);
177
}
178
 
179
/* Wait for input on scb, with timeout seconds.  Returns 0 on success,
180
   otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
181
 
182
static int
183
ser_base_wait_for (struct serial *scb, int timeout)
184
{
185
  while (1)
186
    {
187
      int numfds;
188
      struct timeval tv;
189
      fd_set readfds, exceptfds;
190
 
191
      /* NOTE: Some OS's can scramble the READFDS when the select()
192
         call fails (ex the kernel with Red Hat 5.2).  Initialize all
193
         arguments before each call. */
194
 
195
      tv.tv_sec = timeout;
196
      tv.tv_usec = 0;
197
 
198
      FD_ZERO (&readfds);
199
      FD_ZERO (&exceptfds);
200
      FD_SET (scb->fd, &readfds);
201
      FD_SET (scb->fd, &exceptfds);
202
 
203
      if (timeout >= 0)
204
        numfds = gdb_select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
205
      else
206
        numfds = gdb_select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
207
 
208
      if (numfds <= 0)
209
        {
210
          if (numfds == 0)
211
            return SERIAL_TIMEOUT;
212
          else if (errno == EINTR)
213
            continue;
214
          else
215
            return SERIAL_ERROR;        /* Got an error from select or poll */
216
        }
217
 
218
      return 0;
219
    }
220
}
221
 
222
/* Read a character with user-specified timeout.  TIMEOUT is number of seconds
223
   to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
224
   char if successful.  Returns -2 if timeout expired, EOF if line dropped
225
   dead, or -3 for any other error (see errno in that case). */
226
 
227
static int
228
do_ser_base_readchar (struct serial *scb, int timeout)
229
{
230
  int status;
231
  int delta;
232
 
233
  /* We have to be able to keep the GUI alive here, so we break the
234
     original timeout into steps of 1 second, running the "keep the
235
     GUI alive" hook each time through the loop.
236
 
237
     Also, timeout = 0 means to poll, so we just set the delta to 0,
238
     so we will only go through the loop once.  */
239
 
240
  delta = (timeout == 0 ? 0 : 1);
241
  while (1)
242
    {
243
      /* N.B. The UI may destroy our world (for instance by calling
244
         remote_stop,) in which case we want to get out of here as
245
         quickly as possible.  It is not safe to touch scb, since
246
         someone else might have freed it.  The
247
         deprecated_ui_loop_hook signals that we should exit by
248
         returning 1.  */
249
 
250
      if (deprecated_ui_loop_hook)
251
        {
252
          if (deprecated_ui_loop_hook (0))
253
            return SERIAL_TIMEOUT;
254
        }
255
 
256
      status = ser_base_wait_for (scb, delta);
257
      if (timeout > 0)
258
        timeout -= delta;
259
 
260
      /* If we got a character or an error back from wait_for, then we can
261
         break from the loop before the timeout is completed. */
262
      if (status != SERIAL_TIMEOUT)
263
        break;
264
 
265
      /* If we have exhausted the original timeout, then generate
266
         a SERIAL_TIMEOUT, and pass it out of the loop. */
267
      else if (timeout == 0)
268
        {
269
          status = SERIAL_TIMEOUT;
270
          break;
271
        }
272
    }
273
 
274
  if (status < 0)
275
    return status;
276
 
277
  status = scb->ops->read_prim (scb, BUFSIZ);
278
 
279
  if (status <= 0)
280
    {
281
      if (status == 0)
282
        return SERIAL_EOF;
283
      else
284
        /* Got an error from read.  */
285
        return SERIAL_ERROR;
286
    }
287
 
288
  scb->bufcnt = status;
289
  scb->bufcnt--;
290
  scb->bufp = scb->buf;
291
  return *scb->bufp++;
292
}
293
 
294
/* Perform operations common to both old and new readchar. */
295
 
296
/* Return the next character from the input FIFO.  If the FIFO is
297
   empty, call the SERIAL specific routine to try and read in more
298
   characters.
299
 
300
   Initially data from the input FIFO is returned (fd_event()
301
   pre-reads the input into that FIFO.  Once that has been emptied,
302
   further data is obtained by polling the input FD using the device
303
   specific readchar() function.  Note: reschedule() is called after
304
   every read.  This is because there is no guarentee that the lower
305
   level fd_event() poll_event() code (which also calls reschedule())
306
   will be called. */
307
 
308
int
309
generic_readchar (struct serial *scb, int timeout,
310
                  int (do_readchar) (struct serial *scb, int timeout))
311
{
312
  int ch;
313
  if (scb->bufcnt > 0)
314
    {
315
      ch = *scb->bufp;
316
      scb->bufcnt--;
317
      scb->bufp++;
318
    }
319
  else if (scb->bufcnt < 0)
320
    {
321
      /* Some errors/eof are are sticky. */
322
      ch = scb->bufcnt;
323
    }
324
  else
325
    {
326
      ch = do_readchar (scb, timeout);
327
      if (ch < 0)
328
        {
329
          switch ((enum serial_rc) ch)
330
            {
331
            case SERIAL_EOF:
332
            case SERIAL_ERROR:
333
              /* Make the error/eof stick. */
334
              scb->bufcnt = ch;
335
              break;
336
            case SERIAL_TIMEOUT:
337
              scb->bufcnt = 0;
338
              break;
339
            }
340
        }
341
    }
342
  /* Read any error output we might have.  */
343
  if (scb->error_fd != -1)
344
    {
345
      ssize_t s;
346
      char buf[81];
347
 
348
      for (;;)
349
        {
350
          char *current;
351
          char *newline;
352
          int to_read = 80;
353
 
354
          int num_bytes = -1;
355
          if (scb->ops->avail)
356
            num_bytes = (scb->ops->avail)(scb, scb->error_fd);
357
          if (num_bytes != -1)
358
            to_read = (num_bytes < to_read) ? num_bytes : to_read;
359
 
360
          if (to_read == 0)
361
            break;
362
 
363
          s = read (scb->error_fd, &buf, to_read);
364
          if (s == -1)
365
            break;
366
 
367
          /* In theory, embedded newlines are not a problem.
368
             But for MI, we want each output line to have just
369
             one newline for legibility.  So output things
370
             in newline chunks.  */
371
          buf[s] = '\0';
372
          current = buf;
373
          while ((newline = strstr (current, "\n")) != NULL)
374
            {
375
              *newline = '\0';
376
              fputs_unfiltered (current, gdb_stderr);
377
              fputs_unfiltered ("\n", gdb_stderr);
378
              current = newline + 1;
379
            }
380
          fputs_unfiltered (current, gdb_stderr);
381
        }
382
    }
383
 
384
  reschedule (scb);
385
  return ch;
386
}
387
 
388
int
389
ser_base_readchar (struct serial *scb, int timeout)
390
{
391
  return generic_readchar (scb, timeout, do_ser_base_readchar);
392
}
393
 
394
int
395
ser_base_write (struct serial *scb, const char *str, int len)
396
{
397
  int cc;
398
 
399
  while (len > 0)
400
    {
401
      cc = scb->ops->write_prim (scb, str, len);
402
 
403
      if (cc < 0)
404
        return 1;
405
      len -= cc;
406
      str += cc;
407
    }
408
  return 0;
409
}
410
 
411
int
412
ser_base_flush_output (struct serial *scb)
413
{
414
  return 0;
415
}
416
 
417
int
418
ser_base_flush_input (struct serial *scb)
419
{
420
  if (scb->bufcnt >= 0)
421
    {
422
      scb->bufcnt = 0;
423
      scb->bufp = scb->buf;
424
      return 0;
425
    }
426
  else
427
    return SERIAL_ERROR;
428
}
429
 
430
int
431
ser_base_send_break (struct serial *scb)
432
{
433
  return 0;
434
}
435
 
436
int
437
ser_base_drain_output (struct serial *scb)
438
{
439
  return 0;
440
}
441
 
442
void
443
ser_base_raw (struct serial *scb)
444
{
445
  return;                       /* Always in raw mode */
446
}
447
 
448
serial_ttystate
449
ser_base_get_tty_state (struct serial *scb)
450
{
451
  /* allocate a dummy */
452
  return (serial_ttystate) XMALLOC (int);
453
}
454
 
455
int
456
ser_base_set_tty_state (struct serial *scb, serial_ttystate ttystate)
457
{
458
  return 0;
459
}
460
 
461
int
462
ser_base_noflush_set_tty_state (struct serial *scb,
463
                                serial_ttystate new_ttystate,
464
                                serial_ttystate old_ttystate)
465
{
466
  return 0;
467
}
468
 
469
void
470
ser_base_print_tty_state (struct serial *scb,
471
                          serial_ttystate ttystate,
472
                          struct ui_file *stream)
473
{
474
  /* Nothing to print.  */
475
  return;
476
}
477
 
478
int
479
ser_base_setbaudrate (struct serial *scb, int rate)
480
{
481
  return 0;                      /* Never fails! */
482
}
483
 
484
int
485
ser_base_setstopbits (struct serial *scb, int num)
486
{
487
  return 0;                      /* Never fails! */
488
}
489
 
490
/* Put the SERIAL device into/out-of ASYNC mode.  */
491
 
492
void
493
ser_base_async (struct serial *scb,
494
                int async_p)
495
{
496
  if (async_p)
497
    {
498
      /* Force a re-schedule. */
499
      scb->async_state = NOTHING_SCHEDULED;
500
      if (serial_debug_p (scb))
501
        fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n",
502
                            scb->fd);
503
      reschedule (scb);
504
    }
505
  else
506
    {
507
      if (serial_debug_p (scb))
508
        fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
509
                            scb->fd);
510
      /* De-schedule whatever tasks are currently scheduled. */
511
      switch (scb->async_state)
512
        {
513
        case FD_SCHEDULED:
514
          delete_file_handler (scb->fd);
515
          break;
516
        case NOTHING_SCHEDULED:
517
          break;
518
        default: /* TIMER SCHEDULED */
519
          delete_timer (scb->async_state);
520
          break;
521
        }
522
    }
523
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.