119370Spst/* Serial interface for local (hardwired) serial ports on Un*x like systems 219370Spst 3130809Smarcel Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 4130809Smarcel 2003, 2004 Free Software Foundation, Inc. 5130809Smarcel 698948Sobrien This file is part of GDB. 719370Spst 898948Sobrien This program is free software; you can redistribute it and/or modify 998948Sobrien it under the terms of the GNU General Public License as published by 1098948Sobrien the Free Software Foundation; either version 2 of the License, or 1198948Sobrien (at your option) any later version. 1219370Spst 1398948Sobrien This program is distributed in the hope that it will be useful, 1498948Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1598948Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1698948Sobrien GNU General Public License for more details. 1719370Spst 1898948Sobrien You should have received a copy of the GNU General Public License 1998948Sobrien along with this program; if not, write to the Free Software 2098948Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2198948Sobrien Boston, MA 02111-1307, USA. */ 2219370Spst 2319370Spst#include "defs.h" 2419370Spst#include "serial.h" 2598948Sobrien#include "ser-unix.h" 2698948Sobrien 2719370Spst#include <fcntl.h> 2819370Spst#include <sys/types.h> 2919370Spst#include "terminal.h" 3098948Sobrien#include <sys/socket.h> 3198948Sobrien#include <sys/time.h> 3219370Spst 3398948Sobrien#include "gdb_string.h" 3498948Sobrien#include "event-loop.h" 3598948Sobrien 3619370Spst#ifdef HAVE_TERMIOS 3719370Spst 3819370Spststruct hardwire_ttystate 3998948Sobrien { 4098948Sobrien struct termios termios; 4198948Sobrien }; 4219370Spst#endif /* termios */ 4319370Spst 4419370Spst#ifdef HAVE_TERMIO 4519370Spst 4619370Spst/* It is believed that all systems which have added job control to SVR3 4719370Spst (e.g. sco) have also added termios. Even if not, trying to figure out 4819370Spst all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty 4919370Spst bewildering. So we don't attempt it. */ 5019370Spst 5119370Spststruct hardwire_ttystate 5298948Sobrien { 5398948Sobrien struct termio termio; 5498948Sobrien }; 5519370Spst#endif /* termio */ 5619370Spst 5719370Spst#ifdef HAVE_SGTTY 5819370Spststruct hardwire_ttystate 5998948Sobrien { 6098948Sobrien struct sgttyb sgttyb; 6198948Sobrien struct tchars tc; 6298948Sobrien struct ltchars ltc; 6398948Sobrien /* Line discipline flags. */ 6498948Sobrien int lmode; 6598948Sobrien }; 6619370Spst#endif /* sgtty */ 6719370Spst 6898948Sobrienstatic int hardwire_open (struct serial *scb, const char *name); 6998948Sobrienstatic void hardwire_raw (struct serial *scb); 7098948Sobrienstatic int wait_for (struct serial *scb, int timeout); 7198948Sobrienstatic int hardwire_readchar (struct serial *scb, int timeout); 7298948Sobrienstatic int do_hardwire_readchar (struct serial *scb, int timeout); 7398948Sobrienstatic int generic_readchar (struct serial *scb, int timeout, 7498948Sobrien int (*do_readchar) (struct serial *scb, 7598948Sobrien int timeout)); 7698948Sobrienstatic int rate_to_code (int rate); 7798948Sobrienstatic int hardwire_setbaudrate (struct serial *scb, int rate); 7898948Sobrienstatic void hardwire_close (struct serial *scb); 7998948Sobrienstatic int get_tty_state (struct serial *scb, 8098948Sobrien struct hardwire_ttystate * state); 8198948Sobrienstatic int set_tty_state (struct serial *scb, 8298948Sobrien struct hardwire_ttystate * state); 8398948Sobrienstatic serial_ttystate hardwire_get_tty_state (struct serial *scb); 8498948Sobrienstatic int hardwire_set_tty_state (struct serial *scb, serial_ttystate state); 8598948Sobrienstatic int hardwire_noflush_set_tty_state (struct serial *, serial_ttystate, 8698948Sobrien serial_ttystate); 8798948Sobrienstatic void hardwire_print_tty_state (struct serial *, serial_ttystate, 8898948Sobrien struct ui_file *); 8998948Sobrienstatic int hardwire_drain_output (struct serial *); 9098948Sobrienstatic int hardwire_flush_output (struct serial *); 9198948Sobrienstatic int hardwire_flush_input (struct serial *); 9298948Sobrienstatic int hardwire_send_break (struct serial *); 9398948Sobrienstatic int hardwire_setstopbits (struct serial *, int); 9419370Spst 9598948Sobrienstatic int do_unix_readchar (struct serial *scb, int timeout); 9698948Sobrienstatic timer_handler_func push_event; 9798948Sobrienstatic handler_func fd_event; 9898948Sobrienstatic void reschedule (struct serial *scb); 9946289Sdfr 10098948Sobrienvoid _initialize_ser_hardwire (void); 10146289Sdfr 10298948Sobrienextern int (*ui_loop_hook) (int); 10398948Sobrien 10419370Spst/* Open up a real live device for serial I/O */ 10519370Spst 10619370Spststatic int 10798948Sobrienhardwire_open (struct serial *scb, const char *name) 10819370Spst{ 10919370Spst scb->fd = open (name, O_RDWR); 11019370Spst if (scb->fd < 0) 11119370Spst return -1; 11219370Spst 11319370Spst return 0; 11419370Spst} 11519370Spst 11619370Spststatic int 11798948Sobrienget_tty_state (struct serial *scb, struct hardwire_ttystate *state) 11819370Spst{ 11919370Spst#ifdef HAVE_TERMIOS 12098948Sobrien if (tcgetattr (scb->fd, &state->termios) < 0) 12119370Spst return -1; 12219370Spst 12319370Spst return 0; 12419370Spst#endif 12519370Spst 12619370Spst#ifdef HAVE_TERMIO 12719370Spst if (ioctl (scb->fd, TCGETA, &state->termio) < 0) 12819370Spst return -1; 12919370Spst return 0; 13019370Spst#endif 13119370Spst 13219370Spst#ifdef HAVE_SGTTY 13319370Spst if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0) 13419370Spst return -1; 13519370Spst if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0) 13619370Spst return -1; 13719370Spst if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0) 13819370Spst return -1; 13919370Spst if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0) 14019370Spst return -1; 14119370Spst 14219370Spst return 0; 14319370Spst#endif 14419370Spst} 14519370Spst 14619370Spststatic int 14798948Sobrienset_tty_state (struct serial *scb, struct hardwire_ttystate *state) 14819370Spst{ 14919370Spst#ifdef HAVE_TERMIOS 15098948Sobrien if (tcsetattr (scb->fd, TCSANOW, &state->termios) < 0) 15119370Spst return -1; 15219370Spst 15319370Spst return 0; 15419370Spst#endif 15519370Spst 15619370Spst#ifdef HAVE_TERMIO 15719370Spst if (ioctl (scb->fd, TCSETA, &state->termio) < 0) 15819370Spst return -1; 15919370Spst return 0; 16019370Spst#endif 16119370Spst 16219370Spst#ifdef HAVE_SGTTY 16319370Spst if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0) 16419370Spst return -1; 16519370Spst if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0) 16619370Spst return -1; 16719370Spst if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0) 16819370Spst return -1; 16919370Spst if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0) 17019370Spst return -1; 17119370Spst 17219370Spst return 0; 17319370Spst#endif 17419370Spst} 17519370Spst 17619370Spststatic serial_ttystate 17798948Sobrienhardwire_get_tty_state (struct serial *scb) 17819370Spst{ 17919370Spst struct hardwire_ttystate *state; 18019370Spst 18198948Sobrien state = (struct hardwire_ttystate *) xmalloc (sizeof *state); 18219370Spst 18398948Sobrien if (get_tty_state (scb, state)) 18419370Spst return NULL; 18519370Spst 18698948Sobrien return (serial_ttystate) state; 18719370Spst} 18819370Spst 18919370Spststatic int 19098948Sobrienhardwire_set_tty_state (struct serial *scb, serial_ttystate ttystate) 19119370Spst{ 19219370Spst struct hardwire_ttystate *state; 19319370Spst 19498948Sobrien state = (struct hardwire_ttystate *) ttystate; 19519370Spst 19698948Sobrien return set_tty_state (scb, state); 19719370Spst} 19819370Spst 19919370Spststatic int 20098948Sobrienhardwire_noflush_set_tty_state (struct serial *scb, 20198948Sobrien serial_ttystate new_ttystate, 20298948Sobrien serial_ttystate old_ttystate) 20319370Spst{ 20419370Spst struct hardwire_ttystate new_state; 20519370Spst#ifdef HAVE_SGTTY 20619370Spst struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate; 20719370Spst#endif 20819370Spst 20998948Sobrien new_state = *(struct hardwire_ttystate *) new_ttystate; 21019370Spst 21119370Spst /* Don't change in or out of raw mode; we don't want to flush input. 21219370Spst termio and termios have no such restriction; for them flushing input 21319370Spst is separate from setting the attributes. */ 21419370Spst 21519370Spst#ifdef HAVE_SGTTY 21619370Spst if (state->sgttyb.sg_flags & RAW) 21719370Spst new_state.sgttyb.sg_flags |= RAW; 21819370Spst else 21919370Spst new_state.sgttyb.sg_flags &= ~RAW; 22019370Spst 22119370Spst /* I'm not sure whether this is necessary; the manpage just mentions 22219370Spst RAW not CBREAK. */ 22319370Spst if (state->sgttyb.sg_flags & CBREAK) 22419370Spst new_state.sgttyb.sg_flags |= CBREAK; 22519370Spst else 22619370Spst new_state.sgttyb.sg_flags &= ~CBREAK; 22719370Spst#endif 22819370Spst 22919370Spst return set_tty_state (scb, &new_state); 23019370Spst} 23119370Spst 23219370Spststatic void 23398948Sobrienhardwire_print_tty_state (struct serial *scb, 23498948Sobrien serial_ttystate ttystate, 23598948Sobrien struct ui_file *stream) 23619370Spst{ 23719370Spst struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate; 23819370Spst int i; 23919370Spst 24019370Spst#ifdef HAVE_TERMIOS 24198948Sobrien fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n", 24298948Sobrien (int) state->termios.c_iflag, 24398948Sobrien (int) state->termios.c_oflag); 24498948Sobrien fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x\n", 24598948Sobrien (int) state->termios.c_cflag, 24698948Sobrien (int) state->termios.c_lflag); 24719370Spst#if 0 24819370Spst /* This not in POSIX, and is not really documented by those systems 24919370Spst which have it (at least not Sun). */ 25098948Sobrien fprintf_filtered (stream, "c_line = 0x%x.\n", state->termios.c_line); 25119370Spst#endif 25298948Sobrien fprintf_filtered (stream, "c_cc: "); 25319370Spst for (i = 0; i < NCCS; i += 1) 25498948Sobrien fprintf_filtered (stream, "0x%x ", state->termios.c_cc[i]); 25598948Sobrien fprintf_filtered (stream, "\n"); 25619370Spst#endif 25719370Spst 25819370Spst#ifdef HAVE_TERMIO 25998948Sobrien fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n", 26098948Sobrien state->termio.c_iflag, state->termio.c_oflag); 26198948Sobrien fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n", 26298948Sobrien state->termio.c_cflag, state->termio.c_lflag, 26398948Sobrien state->termio.c_line); 26498948Sobrien fprintf_filtered (stream, "c_cc: "); 26519370Spst for (i = 0; i < NCC; i += 1) 26698948Sobrien fprintf_filtered (stream, "0x%x ", state->termio.c_cc[i]); 26798948Sobrien fprintf_filtered (stream, "\n"); 26819370Spst#endif 26919370Spst 27019370Spst#ifdef HAVE_SGTTY 27198948Sobrien fprintf_filtered (stream, "sgttyb.sg_flags = 0x%x.\n", 27298948Sobrien state->sgttyb.sg_flags); 27319370Spst 27498948Sobrien fprintf_filtered (stream, "tchars: "); 27598948Sobrien for (i = 0; i < (int) sizeof (struct tchars); i++) 27698948Sobrien fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->tc)[i]); 27798948Sobrien fprintf_filtered (stream, "\n"); 27819370Spst 27998948Sobrien fprintf_filtered (stream, "ltchars: "); 28098948Sobrien for (i = 0; i < (int) sizeof (struct ltchars); i++) 28198948Sobrien fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->ltc)[i]); 28298948Sobrien fprintf_filtered (stream, "\n"); 28319370Spst 28498948Sobrien fprintf_filtered (stream, "lmode: 0x%x\n", state->lmode); 28519370Spst#endif 28619370Spst} 28719370Spst 28846289Sdfr/* Wait for the output to drain away, as opposed to flushing (discarding) it */ 28946289Sdfr 29019370Spststatic int 29198948Sobrienhardwire_drain_output (struct serial *scb) 29246289Sdfr{ 29346289Sdfr#ifdef HAVE_TERMIOS 29446289Sdfr return tcdrain (scb->fd); 29546289Sdfr#endif 29646289Sdfr 29746289Sdfr#ifdef HAVE_TERMIO 29846289Sdfr return ioctl (scb->fd, TCSBRK, 1); 29946289Sdfr#endif 30046289Sdfr 30146289Sdfr#ifdef HAVE_SGTTY 30246289Sdfr /* Get the current state and then restore it using TIOCSETP, 30346289Sdfr which should cause the output to drain and pending input 30446289Sdfr to be discarded. */ 30546289Sdfr { 30646289Sdfr struct hardwire_ttystate state; 30746289Sdfr if (get_tty_state (scb, &state)) 30846289Sdfr { 30946289Sdfr return (-1); 31046289Sdfr } 31146289Sdfr else 31246289Sdfr { 31346289Sdfr return (ioctl (scb->fd, TIOCSETP, &state.sgttyb)); 31446289Sdfr } 31546289Sdfr } 31698948Sobrien#endif 31746289Sdfr} 31846289Sdfr 31946289Sdfrstatic int 32098948Sobrienhardwire_flush_output (struct serial *scb) 32119370Spst{ 32219370Spst#ifdef HAVE_TERMIOS 32319370Spst return tcflush (scb->fd, TCOFLUSH); 32419370Spst#endif 32519370Spst 32619370Spst#ifdef HAVE_TERMIO 32719370Spst return ioctl (scb->fd, TCFLSH, 1); 32819370Spst#endif 32919370Spst 33019370Spst#ifdef HAVE_SGTTY 33119370Spst /* This flushes both input and output, but we can't do better. */ 33219370Spst return ioctl (scb->fd, TIOCFLUSH, 0); 33398948Sobrien#endif 33419370Spst} 33519370Spst 33619370Spststatic int 33798948Sobrienhardwire_flush_input (struct serial *scb) 33819370Spst{ 33998948Sobrien ser_unix_flush_input (scb); 34019370Spst 34119370Spst#ifdef HAVE_TERMIOS 34219370Spst return tcflush (scb->fd, TCIFLUSH); 34319370Spst#endif 34419370Spst 34519370Spst#ifdef HAVE_TERMIO 34619370Spst return ioctl (scb->fd, TCFLSH, 0); 34719370Spst#endif 34819370Spst 34919370Spst#ifdef HAVE_SGTTY 35019370Spst /* This flushes both input and output, but we can't do better. */ 35119370Spst return ioctl (scb->fd, TIOCFLUSH, 0); 35298948Sobrien#endif 35319370Spst} 35419370Spst 35519370Spststatic int 35698948Sobrienhardwire_send_break (struct serial *scb) 35719370Spst{ 35819370Spst#ifdef HAVE_TERMIOS 35919370Spst return tcsendbreak (scb->fd, 0); 36019370Spst#endif 36119370Spst 36219370Spst#ifdef HAVE_TERMIO 36319370Spst return ioctl (scb->fd, TCSBRK, 0); 36419370Spst#endif 36519370Spst 36619370Spst#ifdef HAVE_SGTTY 36719370Spst { 36819370Spst int status; 36919370Spst struct timeval timeout; 37019370Spst 37119370Spst status = ioctl (scb->fd, TIOCSBRK, 0); 37219370Spst 37319370Spst /* Can't use usleep; it doesn't exist in BSD 4.2. */ 37419370Spst /* Note that if this select() is interrupted by a signal it will not wait 37519370Spst the full length of time. I think that is OK. */ 37619370Spst timeout.tv_sec = 0; 37719370Spst timeout.tv_usec = 250000; 37819370Spst select (0, 0, 0, 0, &timeout); 37919370Spst status = ioctl (scb->fd, TIOCCBRK, 0); 38019370Spst return status; 38119370Spst } 38298948Sobrien#endif 38319370Spst} 38419370Spst 38519370Spststatic void 38698948Sobrienhardwire_raw (struct serial *scb) 38719370Spst{ 38819370Spst struct hardwire_ttystate state; 38919370Spst 39098948Sobrien if (get_tty_state (scb, &state)) 39198948Sobrien fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n", safe_strerror (errno)); 39219370Spst 39319370Spst#ifdef HAVE_TERMIOS 39419370Spst state.termios.c_iflag = 0; 39519370Spst state.termios.c_oflag = 0; 39619370Spst state.termios.c_lflag = 0; 39798948Sobrien state.termios.c_cflag &= ~(CSIZE | PARENB); 39819370Spst state.termios.c_cflag |= CLOCAL | CS8; 39919370Spst state.termios.c_cc[VMIN] = 0; 40019370Spst state.termios.c_cc[VTIME] = 0; 40119370Spst#endif 40219370Spst 40319370Spst#ifdef HAVE_TERMIO 40419370Spst state.termio.c_iflag = 0; 40519370Spst state.termio.c_oflag = 0; 40619370Spst state.termio.c_lflag = 0; 40798948Sobrien state.termio.c_cflag &= ~(CSIZE | PARENB); 40819370Spst state.termio.c_cflag |= CLOCAL | CS8; 40919370Spst state.termio.c_cc[VMIN] = 0; 41019370Spst state.termio.c_cc[VTIME] = 0; 41119370Spst#endif 41219370Spst 41319370Spst#ifdef HAVE_SGTTY 41419370Spst state.sgttyb.sg_flags |= RAW | ANYP; 41519370Spst state.sgttyb.sg_flags &= ~(CBREAK | ECHO); 41619370Spst#endif 41719370Spst 41819370Spst scb->current_timeout = 0; 41919370Spst 42019370Spst if (set_tty_state (scb, &state)) 42198948Sobrien fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n", safe_strerror (errno)); 42219370Spst} 42319370Spst 42419370Spst/* Wait for input on scb, with timeout seconds. Returns 0 on success, 42519370Spst otherwise SERIAL_TIMEOUT or SERIAL_ERROR. 42619370Spst 42719370Spst For termio{s}, we actually just setup VTIME if necessary, and let the 42819370Spst timeout occur in the read() in hardwire_read(). 42919370Spst */ 43019370Spst 43198948Sobrien/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent 43298948Sobrien ser_unix*() until the old TERMIOS/SGTTY/... timer code has been 43398948Sobrien flushed. . */ 43498948Sobrien 43598948Sobrien/* NOTE: cagney/1999-09-30: Much of the code below is dead. The only 43698948Sobrien possible values of the TIMEOUT parameter are ONE and ZERO. 43798948Sobrien Consequently all the code that tries to handle the possability of 43898948Sobrien an overflowed timer is unnecessary. */ 43998948Sobrien 44019370Spststatic int 44198948Sobrienwait_for (struct serial *scb, int timeout) 44219370Spst{ 44319370Spst#ifdef HAVE_SGTTY 44498948Sobrien while (1) 44598948Sobrien { 44698948Sobrien struct timeval tv; 44798948Sobrien fd_set readfds; 44898948Sobrien int numfds; 44919370Spst 45098948Sobrien /* NOTE: Some OS's can scramble the READFDS when the select() 45198948Sobrien call fails (ex the kernel with Red Hat 5.2). Initialize all 45298948Sobrien arguments before each call. */ 45319370Spst 45498948Sobrien tv.tv_sec = timeout; 45598948Sobrien tv.tv_usec = 0; 45619370Spst 45798948Sobrien FD_ZERO (&readfds); 45898948Sobrien FD_SET (scb->fd, &readfds); 45919370Spst 46098948Sobrien if (timeout >= 0) 46198948Sobrien numfds = select (scb->fd + 1, &readfds, 0, 0, &tv); 46298948Sobrien else 46398948Sobrien numfds = select (scb->fd + 1, &readfds, 0, 0, 0); 46419370Spst 46598948Sobrien if (numfds <= 0) 46698948Sobrien if (numfds == 0) 46798948Sobrien return SERIAL_TIMEOUT; 46898948Sobrien else if (errno == EINTR) 46998948Sobrien continue; 47019370Spst else 47198948Sobrien return SERIAL_ERROR; /* Got an error from select or poll */ 47219370Spst 47398948Sobrien return 0; 47498948Sobrien } 47598948Sobrien#endif /* HAVE_SGTTY */ 47619370Spst 47719370Spst#if defined HAVE_TERMIO || defined HAVE_TERMIOS 47819370Spst if (timeout == scb->current_timeout) 47919370Spst return 0; 48019370Spst 48119370Spst scb->current_timeout = timeout; 48219370Spst 48319370Spst { 48419370Spst struct hardwire_ttystate state; 48519370Spst 48698948Sobrien if (get_tty_state (scb, &state)) 48798948Sobrien fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n", safe_strerror (errno)); 48819370Spst 48919370Spst#ifdef HAVE_TERMIOS 49019370Spst if (timeout < 0) 49119370Spst { 49219370Spst /* No timeout. */ 49319370Spst state.termios.c_cc[VTIME] = 0; 49419370Spst state.termios.c_cc[VMIN] = 1; 49519370Spst } 49619370Spst else 49719370Spst { 49819370Spst state.termios.c_cc[VMIN] = 0; 49919370Spst state.termios.c_cc[VTIME] = timeout * 10; 50019370Spst if (state.termios.c_cc[VTIME] != timeout * 10) 50119370Spst { 50219370Spst 50319370Spst /* If c_cc is an 8-bit signed character, we can't go 50419370Spst bigger than this. If it is always unsigned, we could use 50519370Spst 25. */ 50619370Spst 50719370Spst scb->current_timeout = 12; 50819370Spst state.termios.c_cc[VTIME] = scb->current_timeout * 10; 50919370Spst scb->timeout_remaining = timeout - scb->current_timeout; 51019370Spst } 51119370Spst } 51219370Spst#endif 51319370Spst 51419370Spst#ifdef HAVE_TERMIO 51519370Spst if (timeout < 0) 51619370Spst { 51719370Spst /* No timeout. */ 51819370Spst state.termio.c_cc[VTIME] = 0; 51919370Spst state.termio.c_cc[VMIN] = 1; 52019370Spst } 52119370Spst else 52219370Spst { 52319370Spst state.termio.c_cc[VMIN] = 0; 52419370Spst state.termio.c_cc[VTIME] = timeout * 10; 52519370Spst if (state.termio.c_cc[VTIME] != timeout * 10) 52619370Spst { 52719370Spst /* If c_cc is an 8-bit signed character, we can't go 52819370Spst bigger than this. If it is always unsigned, we could use 52919370Spst 25. */ 53019370Spst 53119370Spst scb->current_timeout = 12; 53219370Spst state.termio.c_cc[VTIME] = scb->current_timeout * 10; 53319370Spst scb->timeout_remaining = timeout - scb->current_timeout; 53419370Spst } 53519370Spst } 53619370Spst#endif 53719370Spst 53819370Spst if (set_tty_state (scb, &state)) 53998948Sobrien fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n", safe_strerror (errno)); 54019370Spst 54119370Spst return 0; 54219370Spst } 54398948Sobrien#endif /* HAVE_TERMIO || HAVE_TERMIOS */ 54419370Spst} 54519370Spst 54619370Spst/* Read a character with user-specified timeout. TIMEOUT is number of seconds 54719370Spst to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns 54819370Spst char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line 54919370Spst dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */ 55098948Sobrien 55198948Sobrien/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent 55298948Sobrien ser_unix*() until the old TERMIOS/SGTTY/... timer code has been 55398948Sobrien flushed. */ 55498948Sobrien 55598948Sobrien/* NOTE: cagney/1999-09-16: This function is not identical to 55698948Sobrien ser_unix_readchar() as part of replacing it with ser_unix*() 55798948Sobrien merging will be required - this code handles the case where read() 55898948Sobrien times out due to no data while ser_unix_readchar() doesn't expect 55998948Sobrien that. */ 56098948Sobrien 56119370Spststatic int 56298948Sobriendo_hardwire_readchar (struct serial *scb, int timeout) 56319370Spst{ 56498948Sobrien int status, delta; 56598948Sobrien int detach = 0; 56619370Spst 56746289Sdfr if (timeout > 0) 56846289Sdfr timeout++; 56946289Sdfr 57098948Sobrien /* We have to be able to keep the GUI alive here, so we break the original 57198948Sobrien timeout into steps of 1 second, running the "keep the GUI alive" hook 57298948Sobrien each time through the loop. 57398948Sobrien Also, timeout = 0 means to poll, so we just set the delta to 0, so we 57498948Sobrien will only go through the loop once. */ 57598948Sobrien 57698948Sobrien delta = (timeout == 0 ? 0 : 1); 57719370Spst while (1) 57819370Spst { 57946289Sdfr 58098948Sobrien /* N.B. The UI may destroy our world (for instance by calling 58198948Sobrien remote_stop,) in which case we want to get out of here as 58298948Sobrien quickly as possible. It is not safe to touch scb, since 58398948Sobrien someone else might have freed it. The ui_loop_hook signals that 58498948Sobrien we should exit by returning 1. */ 58598948Sobrien 58646289Sdfr if (ui_loop_hook) 58798948Sobrien detach = ui_loop_hook (0); 58898948Sobrien 58998948Sobrien if (detach) 59098948Sobrien return SERIAL_TIMEOUT; 59198948Sobrien 59298948Sobrien scb->timeout_remaining = (timeout < 0 ? timeout : timeout - delta); 59398948Sobrien status = wait_for (scb, delta); 59498948Sobrien 59519370Spst if (status < 0) 59619370Spst return status; 59719370Spst 59898948Sobrien status = read (scb->fd, scb->buf, BUFSIZ); 59919370Spst 60098948Sobrien if (status <= 0) 60119370Spst { 60298948Sobrien if (status == 0) 60319370Spst { 60419370Spst /* Zero characters means timeout (it could also be EOF, but 60598948Sobrien we don't (yet at least) distinguish). */ 60619370Spst if (scb->timeout_remaining > 0) 60719370Spst { 60819370Spst timeout = scb->timeout_remaining; 60919370Spst continue; 61019370Spst } 61198948Sobrien else if (scb->timeout_remaining < 0) 61298948Sobrien continue; 61319370Spst else 61419370Spst return SERIAL_TIMEOUT; 61519370Spst } 61619370Spst else if (errno == EINTR) 61719370Spst continue; 61819370Spst else 61919370Spst return SERIAL_ERROR; /* Got an error from read */ 62019370Spst } 62119370Spst 62298948Sobrien scb->bufcnt = status; 62319370Spst scb->bufcnt--; 62419370Spst scb->bufp = scb->buf; 62519370Spst return *scb->bufp++; 62619370Spst } 62719370Spst} 62819370Spst 62998948Sobrienstatic int 63098948Sobrienhardwire_readchar (struct serial *scb, int timeout) 63198948Sobrien{ 63298948Sobrien return generic_readchar (scb, timeout, do_hardwire_readchar); 63398948Sobrien} 63498948Sobrien 63598948Sobrien 63619370Spst#ifndef B19200 63719370Spst#define B19200 EXTA 63819370Spst#endif 63919370Spst 64019370Spst#ifndef B38400 64119370Spst#define B38400 EXTB 64219370Spst#endif 64319370Spst 64419370Spst/* Translate baud rates from integers to damn B_codes. Unix should 64519370Spst have outgrown this crap years ago, but even POSIX wouldn't buck it. */ 64619370Spst 64719370Spststatic struct 64819370Spst{ 64919370Spst int rate; 65019370Spst int code; 65119370Spst} 65219370Spstbaudtab[] = 65319370Spst{ 65498948Sobrien { 65598948Sobrien 50, B50 65698948Sobrien } 65798948Sobrien , 65898948Sobrien { 65998948Sobrien 75, B75 66098948Sobrien } 66198948Sobrien , 66298948Sobrien { 66398948Sobrien 110, B110 66498948Sobrien } 66598948Sobrien , 66698948Sobrien { 66798948Sobrien 134, B134 66898948Sobrien } 66998948Sobrien , 67098948Sobrien { 67198948Sobrien 150, B150 67298948Sobrien } 67398948Sobrien , 67498948Sobrien { 67598948Sobrien 200, B200 67698948Sobrien } 67798948Sobrien , 67898948Sobrien { 67998948Sobrien 300, B300 68098948Sobrien } 68198948Sobrien , 68298948Sobrien { 68398948Sobrien 600, B600 68498948Sobrien } 68598948Sobrien , 68698948Sobrien { 68798948Sobrien 1200, B1200 68898948Sobrien } 68998948Sobrien , 69098948Sobrien { 69198948Sobrien 1800, B1800 69298948Sobrien } 69398948Sobrien , 69498948Sobrien { 69598948Sobrien 2400, B2400 69698948Sobrien } 69798948Sobrien , 69898948Sobrien { 69998948Sobrien 4800, B4800 70098948Sobrien } 70198948Sobrien , 70298948Sobrien { 70398948Sobrien 9600, B9600 70498948Sobrien } 70598948Sobrien , 70698948Sobrien { 70798948Sobrien 19200, B19200 70898948Sobrien } 70998948Sobrien , 71098948Sobrien { 71198948Sobrien 38400, B38400 71298948Sobrien } 71398948Sobrien , 71436629Sdfr#ifdef B57600 71598948Sobrien { 71698948Sobrien 57600, B57600 71798948Sobrien } 71898948Sobrien , 71936629Sdfr#endif 72036629Sdfr#ifdef B115200 72198948Sobrien { 72298948Sobrien 115200, B115200 72398948Sobrien } 72498948Sobrien , 72536629Sdfr#endif 72636629Sdfr#ifdef B230400 72798948Sobrien { 72898948Sobrien 230400, B230400 72998948Sobrien } 73098948Sobrien , 73136629Sdfr#endif 73246289Sdfr#ifdef B460800 73398948Sobrien { 73498948Sobrien 460800, B460800 73598948Sobrien } 73698948Sobrien , 73746289Sdfr#endif 73898948Sobrien { 73998948Sobrien -1, -1 74098948Sobrien } 74198948Sobrien , 74219370Spst}; 74319370Spst 74498948Sobrienstatic int 74598948Sobrienrate_to_code (int rate) 74619370Spst{ 74719370Spst int i; 74819370Spst 74919370Spst for (i = 0; baudtab[i].rate != -1; i++) 75098948Sobrien { 75198948Sobrien /* test for perfect macth. */ 75298948Sobrien if (rate == baudtab[i].rate) 75398948Sobrien return baudtab[i].code; 75498948Sobrien else 75598948Sobrien { 75698948Sobrien /* check if it is in between valid values. */ 75798948Sobrien if (rate < baudtab[i].rate) 75898948Sobrien { 75998948Sobrien if (i) 76098948Sobrien { 76198948Sobrien warning ("Invalid baud rate %d. Closest values are %d and %d.", 76298948Sobrien rate, baudtab[i - 1].rate, baudtab[i].rate); 76398948Sobrien } 76498948Sobrien else 76598948Sobrien { 76698948Sobrien warning ("Invalid baud rate %d. Minimum value is %d.", 76798948Sobrien rate, baudtab[0].rate); 76898948Sobrien } 76998948Sobrien return -1; 77098948Sobrien } 77198948Sobrien } 77298948Sobrien } 77398948Sobrien 77498948Sobrien /* The requested speed was too large. */ 77598948Sobrien warning ("Invalid baud rate %d. Maximum value is %d.", 77698948Sobrien rate, baudtab[i - 1].rate); 77719370Spst return -1; 77819370Spst} 77919370Spst 78019370Spststatic int 78198948Sobrienhardwire_setbaudrate (struct serial *scb, int rate) 78219370Spst{ 78319370Spst struct hardwire_ttystate state; 78498948Sobrien int baud_code = rate_to_code (rate); 78598948Sobrien 78698948Sobrien if (baud_code < 0) 78798948Sobrien { 78898948Sobrien /* The baud rate was not valid. 78998948Sobrien A warning has already been issued. */ 79098948Sobrien errno = EINVAL; 79198948Sobrien return -1; 79298948Sobrien } 79319370Spst 79498948Sobrien if (get_tty_state (scb, &state)) 79519370Spst return -1; 79619370Spst 79719370Spst#ifdef HAVE_TERMIOS 79898948Sobrien cfsetospeed (&state.termios, baud_code); 79998948Sobrien cfsetispeed (&state.termios, baud_code); 80019370Spst#endif 80119370Spst 80219370Spst#ifdef HAVE_TERMIO 80319370Spst#ifndef CIBAUD 80419370Spst#define CIBAUD CBAUD 80519370Spst#endif 80619370Spst 80719370Spst state.termio.c_cflag &= ~(CBAUD | CIBAUD); 80898948Sobrien state.termio.c_cflag |= baud_code; 80919370Spst#endif 81019370Spst 81119370Spst#ifdef HAVE_SGTTY 81298948Sobrien state.sgttyb.sg_ispeed = baud_code; 81398948Sobrien state.sgttyb.sg_ospeed = baud_code; 81419370Spst#endif 81519370Spst 81619370Spst return set_tty_state (scb, &state); 81719370Spst} 81819370Spst 81919370Spststatic int 82098948Sobrienhardwire_setstopbits (struct serial *scb, int num) 82119370Spst{ 82219370Spst struct hardwire_ttystate state; 82319370Spst int newbit; 82419370Spst 82598948Sobrien if (get_tty_state (scb, &state)) 82619370Spst return -1; 82719370Spst 82819370Spst switch (num) 82919370Spst { 83019370Spst case SERIAL_1_STOPBITS: 83119370Spst newbit = 0; 83219370Spst break; 83319370Spst case SERIAL_1_AND_A_HALF_STOPBITS: 83419370Spst case SERIAL_2_STOPBITS: 83519370Spst newbit = 1; 83619370Spst break; 83719370Spst default: 83819370Spst return 1; 83919370Spst } 84019370Spst 84119370Spst#ifdef HAVE_TERMIOS 84219370Spst if (!newbit) 84319370Spst state.termios.c_cflag &= ~CSTOPB; 84419370Spst else 84598948Sobrien state.termios.c_cflag |= CSTOPB; /* two bits */ 84619370Spst#endif 84719370Spst 84819370Spst#ifdef HAVE_TERMIO 84919370Spst if (!newbit) 85019370Spst state.termio.c_cflag &= ~CSTOPB; 85119370Spst else 85298948Sobrien state.termio.c_cflag |= CSTOPB; /* two bits */ 85319370Spst#endif 85419370Spst 85519370Spst#ifdef HAVE_SGTTY 85619370Spst return 0; /* sgtty doesn't support this */ 85719370Spst#endif 85819370Spst 85919370Spst return set_tty_state (scb, &state); 86019370Spst} 86119370Spst 86298948Sobrienstatic void 86398948Sobrienhardwire_close (struct serial *scb) 86498948Sobrien{ 86598948Sobrien if (scb->fd < 0) 86698948Sobrien return; 86798948Sobrien 86898948Sobrien close (scb->fd); 86998948Sobrien scb->fd = -1; 87098948Sobrien} 87198948Sobrien 87298948Sobrien 87398948Sobrien/* Generic operations used by all UNIX/FD based serial interfaces. */ 87498948Sobrien 87598948Sobrienserial_ttystate 87698948Sobrienser_unix_nop_get_tty_state (struct serial *scb) 87798948Sobrien{ 87898948Sobrien /* allocate a dummy */ 87998948Sobrien return (serial_ttystate) XMALLOC (int); 88098948Sobrien} 88198948Sobrien 88298948Sobrienint 88398948Sobrienser_unix_nop_set_tty_state (struct serial *scb, serial_ttystate ttystate) 88498948Sobrien{ 88598948Sobrien return 0; 88698948Sobrien} 88798948Sobrien 88898948Sobrienvoid 88998948Sobrienser_unix_nop_raw (struct serial *scb) 89098948Sobrien{ 89198948Sobrien return; /* Always in raw mode */ 89298948Sobrien} 89398948Sobrien 89498948Sobrien/* Wait for input on scb, with timeout seconds. Returns 0 on success, 89598948Sobrien otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */ 89698948Sobrien 89798948Sobrienint 89898948Sobrienser_unix_wait_for (struct serial *scb, int timeout) 89998948Sobrien{ 90098948Sobrien while (1) 90198948Sobrien { 90298948Sobrien int numfds; 90398948Sobrien struct timeval tv; 90498948Sobrien fd_set readfds, exceptfds; 90598948Sobrien 90698948Sobrien /* NOTE: Some OS's can scramble the READFDS when the select() 90798948Sobrien call fails (ex the kernel with Red Hat 5.2). Initialize all 90898948Sobrien arguments before each call. */ 90998948Sobrien 91098948Sobrien tv.tv_sec = timeout; 91198948Sobrien tv.tv_usec = 0; 91298948Sobrien 91398948Sobrien FD_ZERO (&readfds); 91498948Sobrien FD_ZERO (&exceptfds); 91598948Sobrien FD_SET (scb->fd, &readfds); 91698948Sobrien FD_SET (scb->fd, &exceptfds); 91798948Sobrien 91898948Sobrien if (timeout >= 0) 91998948Sobrien numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv); 92098948Sobrien else 92198948Sobrien numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0); 92298948Sobrien 92398948Sobrien if (numfds <= 0) 92498948Sobrien { 92598948Sobrien if (numfds == 0) 92698948Sobrien return SERIAL_TIMEOUT; 92798948Sobrien else if (errno == EINTR) 92898948Sobrien continue; 92998948Sobrien else 93098948Sobrien return SERIAL_ERROR; /* Got an error from select or poll */ 93198948Sobrien } 93298948Sobrien 93398948Sobrien return 0; 93498948Sobrien } 93598948Sobrien} 93698948Sobrien 93798948Sobrien/* Read a character with user-specified timeout. TIMEOUT is number of seconds 93898948Sobrien to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns 93998948Sobrien char if successful. Returns -2 if timeout expired, EOF if line dropped 94098948Sobrien dead, or -3 for any other error (see errno in that case). */ 94198948Sobrien 94219370Spststatic int 94398948Sobriendo_unix_readchar (struct serial *scb, int timeout) 94419370Spst{ 94598948Sobrien int status; 94698948Sobrien int delta; 94798948Sobrien 94898948Sobrien /* We have to be able to keep the GUI alive here, so we break the original 94998948Sobrien timeout into steps of 1 second, running the "keep the GUI alive" hook 95098948Sobrien each time through the loop. 95198948Sobrien 95298948Sobrien Also, timeout = 0 means to poll, so we just set the delta to 0, so we 95398948Sobrien will only go through the loop once. */ 95498948Sobrien 95598948Sobrien delta = (timeout == 0 ? 0 : 1); 95698948Sobrien while (1) 95798948Sobrien { 95898948Sobrien 95998948Sobrien /* N.B. The UI may destroy our world (for instance by calling 96098948Sobrien remote_stop,) in which case we want to get out of here as 96198948Sobrien quickly as possible. It is not safe to touch scb, since 96298948Sobrien someone else might have freed it. The ui_loop_hook signals that 96398948Sobrien we should exit by returning 1. */ 96498948Sobrien 96598948Sobrien if (ui_loop_hook) 96698948Sobrien { 96798948Sobrien if (ui_loop_hook (0)) 96898948Sobrien return SERIAL_TIMEOUT; 96998948Sobrien } 97098948Sobrien 97198948Sobrien status = ser_unix_wait_for (scb, delta); 97298948Sobrien if (timeout > 0) 97398948Sobrien timeout -= delta; 97498948Sobrien 97598948Sobrien /* If we got a character or an error back from wait_for, then we can 97698948Sobrien break from the loop before the timeout is completed. */ 97798948Sobrien 97898948Sobrien if (status != SERIAL_TIMEOUT) 97998948Sobrien { 98098948Sobrien break; 98198948Sobrien } 98298948Sobrien 98398948Sobrien /* If we have exhausted the original timeout, then generate 98498948Sobrien a SERIAL_TIMEOUT, and pass it out of the loop. */ 98598948Sobrien 98698948Sobrien else if (timeout == 0) 98798948Sobrien { 98898948Sobrien status = SERIAL_TIMEOUT; 98998948Sobrien break; 99098948Sobrien } 99198948Sobrien } 99298948Sobrien 99398948Sobrien if (status < 0) 99498948Sobrien return status; 99598948Sobrien 99698948Sobrien while (1) 99798948Sobrien { 99898948Sobrien status = read (scb->fd, scb->buf, BUFSIZ); 99998948Sobrien if (status != -1 || errno != EINTR) 100098948Sobrien break; 100198948Sobrien } 100298948Sobrien 100398948Sobrien if (status <= 0) 100498948Sobrien { 100598948Sobrien if (status == 0) 100698948Sobrien return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to 100798948Sobrien distinguish between EOF & timeouts 100898948Sobrien someday] */ 100998948Sobrien else 101098948Sobrien return SERIAL_ERROR; /* Got an error from read */ 101198948Sobrien } 101298948Sobrien 101398948Sobrien scb->bufcnt = status; 101498948Sobrien scb->bufcnt--; 101598948Sobrien scb->bufp = scb->buf; 101698948Sobrien return *scb->bufp++; 101798948Sobrien} 101898948Sobrien 101998948Sobrien/* Perform operations common to both old and new readchar. */ 102098948Sobrien 102198948Sobrien/* Return the next character from the input FIFO. If the FIFO is 102298948Sobrien empty, call the SERIAL specific routine to try and read in more 102398948Sobrien characters. 102498948Sobrien 102598948Sobrien Initially data from the input FIFO is returned (fd_event() 102698948Sobrien pre-reads the input into that FIFO. Once that has been emptied, 102798948Sobrien further data is obtained by polling the input FD using the device 102898948Sobrien specific readchar() function. Note: reschedule() is called after 102998948Sobrien every read. This is because there is no guarentee that the lower 103098948Sobrien level fd_event() poll_event() code (which also calls reschedule()) 103198948Sobrien will be called. */ 103298948Sobrien 103398948Sobrienstatic int 103498948Sobriengeneric_readchar (struct serial *scb, int timeout, 103598948Sobrien int (do_readchar) (struct serial *scb, int timeout)) 103698948Sobrien{ 103798948Sobrien int ch; 103898948Sobrien if (scb->bufcnt > 0) 103998948Sobrien { 104098948Sobrien ch = *scb->bufp; 104198948Sobrien scb->bufcnt--; 104298948Sobrien scb->bufp++; 104398948Sobrien } 104498948Sobrien else if (scb->bufcnt < 0) 104598948Sobrien { 104698948Sobrien /* Some errors/eof are are sticky. */ 104798948Sobrien ch = scb->bufcnt; 104898948Sobrien } 104998948Sobrien else 105098948Sobrien { 105198948Sobrien ch = do_readchar (scb, timeout); 105298948Sobrien if (ch < 0) 105398948Sobrien { 105498948Sobrien switch ((enum serial_rc) ch) 105598948Sobrien { 105698948Sobrien case SERIAL_EOF: 105798948Sobrien case SERIAL_ERROR: 105898948Sobrien /* Make the error/eof stick. */ 105998948Sobrien scb->bufcnt = ch; 106098948Sobrien break; 106198948Sobrien case SERIAL_TIMEOUT: 106298948Sobrien scb->bufcnt = 0; 106398948Sobrien break; 106498948Sobrien } 106598948Sobrien } 106698948Sobrien } 106798948Sobrien reschedule (scb); 106898948Sobrien return ch; 106998948Sobrien} 107098948Sobrien 107198948Sobrienint 107298948Sobrienser_unix_readchar (struct serial *scb, int timeout) 107398948Sobrien{ 107498948Sobrien return generic_readchar (scb, timeout, do_unix_readchar); 107598948Sobrien} 107698948Sobrien 107798948Sobrienint 107898948Sobrienser_unix_nop_noflush_set_tty_state (struct serial *scb, 107998948Sobrien serial_ttystate new_ttystate, 108098948Sobrien serial_ttystate old_ttystate) 108198948Sobrien{ 108298948Sobrien return 0; 108398948Sobrien} 108498948Sobrien 108598948Sobrienvoid 108698948Sobrienser_unix_nop_print_tty_state (struct serial *scb, 108798948Sobrien serial_ttystate ttystate, 108898948Sobrien struct ui_file *stream) 108998948Sobrien{ 109098948Sobrien /* Nothing to print. */ 109198948Sobrien return; 109298948Sobrien} 109398948Sobrien 109498948Sobrienint 109598948Sobrienser_unix_nop_setbaudrate (struct serial *scb, int rate) 109698948Sobrien{ 109798948Sobrien return 0; /* Never fails! */ 109898948Sobrien} 109998948Sobrien 110098948Sobrienint 110198948Sobrienser_unix_nop_setstopbits (struct serial *scb, int num) 110298948Sobrien{ 110398948Sobrien return 0; /* Never fails! */ 110498948Sobrien} 110598948Sobrien 110698948Sobrienint 110798948Sobrienser_unix_write (struct serial *scb, const char *str, int len) 110898948Sobrien{ 110919370Spst int cc; 111019370Spst 111119370Spst while (len > 0) 111219370Spst { 111398948Sobrien cc = write (scb->fd, str, len); 111419370Spst 111519370Spst if (cc < 0) 111619370Spst return 1; 111719370Spst len -= cc; 111819370Spst str += cc; 111919370Spst } 112019370Spst return 0; 112119370Spst} 112219370Spst 112398948Sobrienint 112498948Sobrienser_unix_nop_flush_output (struct serial *scb) 112519370Spst{ 112698948Sobrien return 0; 112798948Sobrien} 112819370Spst 112998948Sobrienint 113098948Sobrienser_unix_flush_input (struct serial *scb) 113198948Sobrien{ 113298948Sobrien if (scb->bufcnt >= 0) 113398948Sobrien { 113498948Sobrien scb->bufcnt = 0; 113598948Sobrien scb->bufp = scb->buf; 113698948Sobrien return 0; 113798948Sobrien } 113898948Sobrien else 113998948Sobrien return SERIAL_ERROR; 114019370Spst} 114119370Spst 114298948Sobrienint 114398948Sobrienser_unix_nop_send_break (struct serial *scb) 114419370Spst{ 114598948Sobrien return 0; 114698948Sobrien} 114798948Sobrien 114898948Sobrienint 114998948Sobrienser_unix_nop_drain_output (struct serial *scb) 115098948Sobrien{ 115198948Sobrien return 0; 115298948Sobrien} 115398948Sobrien 115498948Sobrien 115598948Sobrien 115698948Sobrien/* Event handling for ASYNC serial code. 115798948Sobrien 115898948Sobrien At any time the SERIAL device either: has an empty FIFO and is 115998948Sobrien waiting on a FD event; or has a non-empty FIFO/error condition and 116098948Sobrien is constantly scheduling timer events. 116198948Sobrien 116298948Sobrien ASYNC only stops pestering its client when it is de-async'ed or it 116398948Sobrien is told to go away. */ 116498948Sobrien 116598948Sobrien/* Value of scb->async_state: */ 116698948Sobrienenum { 116798948Sobrien /* >= 0 (TIMER_SCHEDULED) */ 116898948Sobrien /* The ID of the currently scheduled timer event. This state is 116998948Sobrien rarely encountered. Timer events are one-off so as soon as the 117098948Sobrien event is delivered the state is shanged to NOTHING_SCHEDULED. */ 117198948Sobrien FD_SCHEDULED = -1, 117298948Sobrien /* The fd_event() handler is scheduled. It is called when ever the 117398948Sobrien file descriptor becomes ready. */ 117498948Sobrien NOTHING_SCHEDULED = -2 117598948Sobrien /* Either no task is scheduled (just going into ASYNC mode) or a 117698948Sobrien timer event has just gone off and the current state has been 117798948Sobrien forced into nothing scheduled. */ 117819370Spst}; 117919370Spst 118098948Sobrien/* Identify and schedule the next ASYNC task based on scb->async_state 118198948Sobrien and scb->buf* (the input FIFO). A state machine is used to avoid 118298948Sobrien the need to make redundant calls into the event-loop - the next 118398948Sobrien scheduled task is only changed when needed. */ 118498948Sobrien 118598948Sobrienstatic void 118698948Sobrienreschedule (struct serial *scb) 118798948Sobrien{ 118898948Sobrien if (serial_is_async_p (scb)) 118998948Sobrien { 119098948Sobrien int next_state; 119198948Sobrien switch (scb->async_state) 119298948Sobrien { 119398948Sobrien case FD_SCHEDULED: 119498948Sobrien if (scb->bufcnt == 0) 119598948Sobrien next_state = FD_SCHEDULED; 119698948Sobrien else 119798948Sobrien { 119898948Sobrien delete_file_handler (scb->fd); 119998948Sobrien next_state = create_timer (0, push_event, scb); 120098948Sobrien } 120198948Sobrien break; 120298948Sobrien case NOTHING_SCHEDULED: 120398948Sobrien if (scb->bufcnt == 0) 120498948Sobrien { 120598948Sobrien add_file_handler (scb->fd, fd_event, scb); 120698948Sobrien next_state = FD_SCHEDULED; 120798948Sobrien } 120898948Sobrien else 120998948Sobrien { 121098948Sobrien next_state = create_timer (0, push_event, scb); 121198948Sobrien } 121298948Sobrien break; 121398948Sobrien default: /* TIMER SCHEDULED */ 121498948Sobrien if (scb->bufcnt == 0) 121598948Sobrien { 121698948Sobrien delete_timer (scb->async_state); 121798948Sobrien add_file_handler (scb->fd, fd_event, scb); 121898948Sobrien next_state = FD_SCHEDULED; 121998948Sobrien } 122098948Sobrien else 122198948Sobrien next_state = scb->async_state; 122298948Sobrien break; 122398948Sobrien } 122498948Sobrien if (serial_debug_p (scb)) 122598948Sobrien { 122698948Sobrien switch (next_state) 122798948Sobrien { 122898948Sobrien case FD_SCHEDULED: 122998948Sobrien if (scb->async_state != FD_SCHEDULED) 123098948Sobrien fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n", 123198948Sobrien scb->fd); 123298948Sobrien break; 123398948Sobrien default: /* TIMER SCHEDULED */ 123498948Sobrien if (scb->async_state == FD_SCHEDULED) 123598948Sobrien fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n", 123698948Sobrien scb->fd); 123798948Sobrien break; 123898948Sobrien } 123998948Sobrien } 124098948Sobrien scb->async_state = next_state; 124198948Sobrien } 124298948Sobrien} 124398948Sobrien 124498948Sobrien/* FD_EVENT: This is scheduled when the input FIFO is empty (and there 124598948Sobrien is no pending error). As soon as data arrives, it is read into the 124698948Sobrien input FIFO and the client notified. The client should then drain 124798948Sobrien the FIFO using readchar(). If the FIFO isn't immediatly emptied, 124898948Sobrien push_event() is used to nag the client until it is. */ 124998948Sobrien 125098948Sobrienstatic void 125198948Sobrienfd_event (int error, void *context) 125298948Sobrien{ 125398948Sobrien struct serial *scb = context; 125498948Sobrien if (error != 0) 125598948Sobrien { 125698948Sobrien scb->bufcnt = SERIAL_ERROR; 125798948Sobrien } 125898948Sobrien else if (scb->bufcnt == 0) 125998948Sobrien { 126098948Sobrien /* Prime the input FIFO. The readchar() function is used to 126198948Sobrien pull characters out of the buffer. See also 126298948Sobrien generic_readchar(). */ 126398948Sobrien int nr; 126498948Sobrien do 126598948Sobrien { 126698948Sobrien nr = read (scb->fd, scb->buf, BUFSIZ); 126798948Sobrien } 126898948Sobrien while (nr == -1 && errno == EINTR); 126998948Sobrien if (nr == 0) 127098948Sobrien { 127198948Sobrien scb->bufcnt = SERIAL_EOF; 127298948Sobrien } 127398948Sobrien else if (nr > 0) 127498948Sobrien { 127598948Sobrien scb->bufcnt = nr; 127698948Sobrien scb->bufp = scb->buf; 127798948Sobrien } 127898948Sobrien else 127998948Sobrien { 128098948Sobrien scb->bufcnt = SERIAL_ERROR; 128198948Sobrien } 128298948Sobrien } 128398948Sobrien scb->async_handler (scb, scb->async_context); 128498948Sobrien reschedule (scb); 128598948Sobrien} 128698948Sobrien 128798948Sobrien/* PUSH_EVENT: The input FIFO is non-empty (or there is a pending 128898948Sobrien error). Nag the client until all the data has been read. In the 128998948Sobrien case of errors, the client will need to close or de-async the 129098948Sobrien device before naging stops. */ 129198948Sobrien 129298948Sobrienstatic void 129398948Sobrienpush_event (void *context) 129498948Sobrien{ 129598948Sobrien struct serial *scb = context; 129698948Sobrien scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */ 129798948Sobrien scb->async_handler (scb, scb->async_context); 129898948Sobrien /* re-schedule */ 129998948Sobrien reschedule (scb); 130098948Sobrien} 130198948Sobrien 130298948Sobrien/* Put the SERIAL device into/out-of ASYNC mode. */ 130398948Sobrien 130419370Spstvoid 130598948Sobrienser_unix_async (struct serial *scb, 130698948Sobrien int async_p) 130719370Spst{ 130898948Sobrien if (async_p) 130998948Sobrien { 131098948Sobrien /* Force a re-schedule. */ 131198948Sobrien scb->async_state = NOTHING_SCHEDULED; 131298948Sobrien if (serial_debug_p (scb)) 131398948Sobrien fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n", 131498948Sobrien scb->fd); 131598948Sobrien reschedule (scb); 131698948Sobrien } 131798948Sobrien else 131898948Sobrien { 131998948Sobrien if (serial_debug_p (scb)) 132098948Sobrien fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n", 132198948Sobrien scb->fd); 132298948Sobrien /* De-schedule whatever tasks are currently scheduled. */ 132398948Sobrien switch (scb->async_state) 132498948Sobrien { 132598948Sobrien case FD_SCHEDULED: 132698948Sobrien delete_file_handler (scb->fd); 132798948Sobrien break; 1328130809Smarcel case NOTHING_SCHEDULED: 132998948Sobrien break; 133098948Sobrien default: /* TIMER SCHEDULED */ 133198948Sobrien delete_timer (scb->async_state); 133298948Sobrien break; 133398948Sobrien } 133498948Sobrien } 133519370Spst} 133698948Sobrien 133798948Sobrienvoid 133898948Sobrien_initialize_ser_hardwire (void) 133998948Sobrien{ 134098948Sobrien struct serial_ops *ops = XMALLOC (struct serial_ops); 1341130809Smarcel memset (ops, 0, sizeof (struct serial_ops)); 134298948Sobrien ops->name = "hardwire"; 134398948Sobrien ops->next = 0; 134498948Sobrien ops->open = hardwire_open; 134598948Sobrien ops->close = hardwire_close; 134698948Sobrien /* FIXME: Don't replace this with the equivalent ser_unix*() until 134798948Sobrien the old TERMIOS/SGTTY/... timer code has been flushed. cagney 134898948Sobrien 1999-09-16. */ 134998948Sobrien ops->readchar = hardwire_readchar; 135098948Sobrien ops->write = ser_unix_write; 135198948Sobrien ops->flush_output = hardwire_flush_output; 135298948Sobrien ops->flush_input = hardwire_flush_input; 135398948Sobrien ops->send_break = hardwire_send_break; 135498948Sobrien ops->go_raw = hardwire_raw; 135598948Sobrien ops->get_tty_state = hardwire_get_tty_state; 135698948Sobrien ops->set_tty_state = hardwire_set_tty_state; 135798948Sobrien ops->print_tty_state = hardwire_print_tty_state; 135898948Sobrien ops->noflush_set_tty_state = hardwire_noflush_set_tty_state; 135998948Sobrien ops->setbaudrate = hardwire_setbaudrate; 136098948Sobrien ops->setstopbits = hardwire_setstopbits; 136198948Sobrien ops->drain_output = hardwire_drain_output; 136298948Sobrien ops->async = ser_unix_async; 136398948Sobrien serial_add_interface (ops); 136498948Sobrien} 1365