summaryrefslogtreecommitdiff
path: root/gdb/rdi-share/unixcomm.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/rdi-share/unixcomm.c')
-rw-r--r--gdb/rdi-share/unixcomm.c552
1 files changed, 552 insertions, 0 deletions
diff --git a/gdb/rdi-share/unixcomm.c b/gdb/rdi-share/unixcomm.c
new file mode 100644
index 00000000000..7c2183de3e5
--- /dev/null
+++ b/gdb/rdi-share/unixcomm.c
@@ -0,0 +1,552 @@
+/*
+ * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
+ *
+ * This software may be freely used, copied, modified, and distributed
+ * provided that the above copyright notice is preserved in all copies of the
+ * software.
+ */
+
+/* -*-C-*-
+ *
+ * $Revision$
+ * $Date$
+ *
+ */
+
+#ifdef __hpux
+# define _POSIX_SOURCE 1
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#ifdef __hpux
+# define _TERMIOS_INCLUDED
+# include <sys/termio.h>
+# undef _TERMIOS_INCLUDED
+#else
+# include <termios.h>
+#endif
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef sun
+# include <sys/ioccom.h>
+# ifdef __svr4__
+# include <sys/bpp_io.h>
+# else
+# include <sbusdev/bpp_io.h>
+# endif
+#endif
+
+#ifdef BSD
+# ifdef sun
+# include <sys/ttydev.h>
+# endif
+# ifdef __alpha
+# include <sys/ioctl.h>
+# else
+# include <sys/filio.h>
+# endif
+#endif
+
+#ifdef __hpux
+# define _INCLUDE_HPUX_SOURCE
+# include <sys/ioctl.h>
+# undef _INCLUDE_HPUX_SOURCE
+#endif
+
+#include "host.h"
+#include "unixcomm.h"
+
+#define PP_TIMEOUT 1 /* seconds */
+
+#ifdef sun
+#define SERPORT1 "/dev/ttya"
+#define SERPORT2 "/dev/ttyb"
+#define PARPORT1 "/dev/bpp0"
+#define PARPORT2 "/dev/bpp1"
+#endif
+
+#ifdef __hpux
+#define SERPORT1 "/dev/tty00"
+#define SERPORT2 "/dev/tty01"
+#define PARPORT1 "/dev/ptr_parallel"
+#define PARPORT2 "/dev/ptr_parallel"
+#endif
+
+#ifdef __linux__
+#define SERPORT1 "/dev/cua0"
+#define SERPORT2 "/dev/cua1"
+#define PARPORT1 "/dev/par0"
+#define PARPORT2 "/dev/par1"
+#endif
+
+#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (bsdi)
+#define SERPORT1 "/dev/cuaa0"
+#define SERPORT2 "/dev/cuaa1"
+#define PARPORT1 "/dev/lpt0"
+#define PARPORT2 "/dev/lpt1"
+#endif
+
+
+#define SERIAL_PREFIX "/dev/tty"
+#if defined(_WIN32) || defined (__CYGWIN32__)
+#define SERPORT1 "com1"
+#define SERPORT2 "com2"
+#define PARPORT1 "lpt1"
+#define PARPORT2 "lpt2"
+#undef SERIAL_PREFIX
+#define SERIAL_PREFIX "com"
+#endif
+
+
+
+/*
+ * Parallel port output pins, used for signalling to target
+ */
+
+#ifdef sun
+struct bpp_pins bp;
+#endif
+
+static int serpfd = -1;
+static int parpfd = -1;
+
+extern const char *Unix_MatchValidSerialDevice(const char *name)
+{
+ int i=0;
+ char *sername=NULL;
+
+ /* Accept no name as the default serial port */
+ if (name == NULL) {
+ return SERPORT1;
+ }
+
+ /* Look for the simple cases - 1,2,s,S,/dev/... first, and
+ * afterwards look for S=... clauses, which need parsing properly.
+ */
+
+ /* Accept /dev/tty* where * is limited */
+ if (strlen(name) == strlen(SERPORT1)
+ && strncmp(name, SERIAL_PREFIX, strlen (SERIAL_PREFIX)) == 0)
+ {
+ return name;
+ }
+
+ /* Accept "1" or "2" or "S" - S is equivalent to "1" */
+ if (strcmp(name, "1") == 0 ||
+ strcmp(name, "S") == 0 || strcmp(name, "s") == 0) {
+ return SERPORT1;
+ }
+ if (strcmp(name, "2") == 0) return SERPORT2;
+
+ /* It wasn't one of the simple cases, so now we have to parse it
+ * properly
+ */
+
+ do {
+ switch (name[i]) {
+ case ',':
+ /* Skip over commas */
+ i++;
+ break;
+
+ default:
+ return 0;
+ /* Unexpected character => error - not matched */
+
+ case 0:
+ /* End of string means return whatever we have matched */
+ return sername;
+
+ case 's':
+ case 'S':
+ case 'h':
+ case 'H': {
+ char ch = tolower(name[i]);
+ int j, continue_from, len;
+
+ /* If the next character is a comma or a NULL then this is
+ * a request for the default Serial port
+ */
+ if (name[++i] == 0 || name[i] == ',') {
+ if (ch=='s')
+ sername=SERPORT1;
+ break;
+ }
+
+ /* Next character must be an = */
+ if (name[i] != '=') return 0;
+ /* Search for the end of the port spec. (ends in NULL or ,) */
+ for (j= ++i; name[j] != 0 && name[j] != ','; j++)
+ ; /* Do nothing */
+ /* Notice whether this is the last thing to parse or not
+ * and also calaculate the length of the string
+ */
+ if (name[j] == '0') continue_from = -1;
+ else continue_from = j;
+ len=(j-i);
+
+ /* And now try to match the serial / parallel port */
+ switch (ch) {
+ case 's': {
+ /* Match serial port */
+ if (len==1) {
+ if (name[i]=='1')
+ sername=SERPORT1;
+ else if (name[i]=='2')
+ sername=SERPORT2;
+ } else if (len==strlen(SERPORT1)) {
+ if (strncmp(name+i,SERPORT1,strlen(SERPORT1)) == 0)
+ sername=SERPORT1;
+ else if (strncmp(name+i,SERPORT2,strlen(SERPORT2)) == 0)
+ sername=SERPORT2;
+ }
+
+ break;
+ }
+
+ case 'h':
+ /* We don't actually deal with the H case here, we just
+ * match it and allow it through.
+ */
+ break;
+ }
+
+ if (continue_from == -1) return sername;
+ i = continue_from;
+ break;
+ }
+ }
+ } while (1);
+
+ return 0;
+}
+
+
+extern int Unix_IsSerialInUse(void)
+{
+ if (serpfd >= 0)
+ return -1;
+
+ return 0;
+}
+
+extern int Unix_OpenSerial(const char *name)
+{
+#if defined(BSD) || defined(__CYGWIN32__)
+ serpfd = open(name, O_RDWR);
+#else
+ serpfd = open(name, O_RDWR | O_NONBLOCK);
+#endif
+
+ if (serpfd < 0) {
+ perror("open");
+ return -1;
+ }
+
+ return 0;
+}
+
+extern void Unix_CloseSerial(void)
+{
+ if (serpfd >= 0)
+ {
+ (void)close(serpfd);
+ serpfd = -1;
+ }
+}
+
+extern int Unix_ReadSerial(unsigned char *buf, int n, bool block)
+{
+ fd_set fdset;
+ struct timeval tv;
+ int err;
+
+ FD_ZERO(&fdset);
+ FD_SET(serpfd, &fdset);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = (block ? 10000 : 0);
+
+ err = select(serpfd + 1, &fdset, NULL, NULL, &tv);
+
+ if (err < 0 && errno != EINTR)
+ {
+#ifdef DEBUG
+ perror("select");
+#endif
+ panic("select failure");
+ return -1;
+ }
+ else if (err > 0 && FD_ISSET(serpfd, &fdset))
+ return read(serpfd, buf, n);
+ else /* err == 0 || FD_CLR(serpfd, &fdset) */
+ {
+ errno = ERRNO_FOR_BLOCKED_IO;
+ return -1;
+ }
+}
+
+extern int Unix_WriteSerial(unsigned char *buf, int n)
+{
+ return write(serpfd, buf, n);
+}
+
+extern void Unix_ResetSerial(void)
+{
+ struct termios terminfo;
+
+ tcgetattr(serpfd, &terminfo);
+#ifdef __CYGWIN32__
+ /* Expedient, but it works. */
+ terminfo.c_iflag = 0;
+ terminfo.c_oflag = 0;
+ terminfo.c_cflag = 48;
+ terminfo.c_lflag = 0;
+ terminfo.c_cc[VMIN] = 0;
+ terminfo.c_cc[VTIME] = 1;
+#else
+ terminfo.c_lflag &= ~(ICANON | ISIG | ECHO | IEXTEN);
+ terminfo.c_iflag &= ~(IGNCR | INPCK | ISTRIP | ICRNL | BRKINT);
+ terminfo.c_iflag |= (IXON | IXOFF | IGNBRK);
+ terminfo.c_cflag = (terminfo.c_cflag & ~CSIZE) | CS8 | CREAD;
+ terminfo.c_cflag &= ~PARENB;
+ terminfo.c_cc[VMIN] = 1;
+ terminfo.c_cc[VTIME] = 0;
+ terminfo.c_oflag &= ~OPOST;
+#endif
+ tcsetattr(serpfd, TCSAFLUSH, &terminfo);
+}
+
+extern void Unix_SetSerialBaudRate(int baudrate)
+{
+ struct termios terminfo;
+
+ tcgetattr(serpfd, &terminfo);
+ cfsetospeed(&terminfo, baudrate);
+ cfsetispeed(&terminfo, baudrate);
+ tcsetattr(serpfd, TCSAFLUSH, &terminfo);
+}
+
+extern void Unix_ioctlNonBlocking(void)
+{
+#if defined(BSD)
+ int nonblockingIO = 1;
+ (void)ioctl(serpfd, FIONBIO, &nonblockingIO);
+
+ if (parpfd != -1)
+ (void)ioctl(parpfd, FIONBIO, &nonblockingIO);
+#endif
+}
+
+extern void Unix_IsValidParallelDevice(
+ const char *portstring, char **sername, char **parname)
+{
+ int i=0;
+ *sername=NULL;
+ *parname=NULL;
+
+ /* Do not recognise a NULL portstring */
+ if (portstring==NULL) return;
+
+ do {
+ switch (portstring[i]) {
+ case ',':
+ /* Skip over commas */
+ i++;
+ break;
+
+ default:
+ case 0:
+ /* End of string or bad characcter means we have finished */
+ return;
+
+ case 's':
+ case 'S':
+ case 'p':
+ case 'P':
+ case 'h':
+ case 'H': {
+ char ch = tolower(portstring[i]);
+ int j, continue_from, len;
+
+ /* If the next character is a comma or a NULL then this is
+ * a request for the default Serial or Parallel port
+ */
+ if (portstring[++i] == 0 || portstring[i] == ',') {
+ if (ch=='s') *sername=SERPORT1;
+ else if (ch=='p') *parname=PARPORT1;
+ break;
+ }
+
+ /* Next character must be an = */
+ if (portstring[i] != '=') return;
+ /* Search for the end of the port spec. (ends in NULL or ,) */
+ for (j= ++i; portstring[j] != 0 && portstring[j] != ','; j++)
+ ; /* Do nothing */
+ /* Notice whether this is the last thing to parse or not
+ * and also calaculate the length of the string
+ */
+ if (portstring[j] == '0') continue_from = -1;
+ else continue_from = j;
+ len=(j-i);
+
+ /* And now try to match the serial / parallel port */
+ switch (ch) {
+ case 's': {
+ /* Match serial port */
+ if (len==1) {
+ if (portstring[i]=='1') *sername=SERPORT1;
+ else if (portstring[i]=='2') *sername=SERPORT2;
+ } else if (len==strlen(SERPORT1)) {
+ if (strncmp(portstring+i,SERPORT1,strlen(SERPORT1)) == 0)
+ *sername=SERPORT1;
+ else if (strncmp(portstring+i,SERPORT2,strlen(SERPORT2)) == 0)
+ *sername=SERPORT2;
+ }
+ break;
+ }
+
+ case 'p': {
+ /* Match parallel port */
+ if (len==1) {
+ if (portstring[i]=='1') *parname=PARPORT1;
+ else if (portstring[i]=='2') *parname=PARPORT2;
+ } else if (len==strlen(PARPORT1)) {
+ if (strncmp(portstring+i,PARPORT1,strlen(PARPORT1)) == 0)
+ *parname=PARPORT1;
+ else if (strncmp(portstring+i,PARPORT2,strlen(PARPORT2)) == 0)
+ *parname=PARPORT2;
+ }
+ break;
+ }
+
+ case 'h':
+ /* We don't actually deal with the H case here, we just
+ * match it and allow it through.
+ */
+ break;
+ }
+
+ if (continue_from == -1) return;
+ i = continue_from;
+ break;
+ }
+ }
+ } while (1);
+ return; /* Will never get here */
+}
+
+extern int Unix_IsParallelInUse(void)
+{
+ if (parpfd >= 0)
+ return -1;
+
+ return 0;
+}
+
+extern int Unix_OpenParallel(const char *name)
+{
+#if defined(BSD)
+ parpfd = open(name, O_RDWR);
+#else
+ parpfd = open(name, O_RDWR | O_NONBLOCK);
+#endif
+
+ if (parpfd < 0)
+ {
+ char errbuf[256];
+
+ sprintf(errbuf, "open %s", name);
+ perror(errbuf);
+
+ return -1;
+ }
+
+ return 0;
+}
+
+extern void Unix_CloseParallel(void)
+{
+ if (parpfd >= 0)
+ {
+ (void)close(parpfd);
+ parpfd = -1;
+ }
+}
+
+
+extern unsigned int Unix_WriteParallel(unsigned char *buf, int n)
+{
+ int ngone;
+
+ if ((ngone = write(parpfd, buf, n)) < 0)
+ {
+ /*
+ * we ignore errors (except for debug purposes)
+ */
+#ifdef DEBUG
+ char errbuf[256];
+
+ sprintf(errbuf, "send_packet: write");
+ perror(errbuf);
+#endif
+ ngone = 0;
+ }
+
+ /* finished */
+ return (unsigned int)ngone;
+}
+
+
+#ifdef sun
+extern void Unix_ResetParallel(void)
+{
+ struct bpp_transfer_parms tp;
+
+#ifdef DEBUG
+ printf("serpar_reset\n");
+#endif
+
+ /*
+ * we need to set the parallel port up for BUSY handshaking,
+ * and select the timeout
+ */
+ if (ioctl(parpfd, BPPIOC_GETPARMS, &tp) < 0)
+ {
+#ifdef DEBUG
+ perror("ioctl(BPPIOCGETPARMS)");
+#endif
+ panic("serpar_reset: cannot get BPP parameters");
+ }
+
+ tp.write_handshake = BPP_BUSY_HS;
+ tp.write_timeout = PP_TIMEOUT;
+
+ if (ioctl(parpfd, BPPIOC_SETPARMS, &tp) < 0)
+ {
+#ifdef DEBUG
+ perror("ioctl(BPPIOC_SETPARMS)");
+#endif
+ panic("serpar_reset: cannot set BPP parameters");
+ }
+}
+
+#else
+
+/* Parallel not supported on HP */
+
+extern void Unix_ResetParallel(void)
+{
+}
+
+#endif
+