xref: /OK3568_Linux_fs/u-boot/tools/gdb/serial.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2000
3*4882a593Smuzhiyun  * Murray Jensen <Murray.Jensen@csiro.au>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <unistd.h>
9*4882a593Smuzhiyun #include <string.h>
10*4882a593Smuzhiyun #include <fcntl.h>
11*4882a593Smuzhiyun #include <sys/time.h>
12*4882a593Smuzhiyun #include "serial.h"
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #if defined(__sun__)	 || \
15*4882a593Smuzhiyun     defined(__OpenBSD__) || \
16*4882a593Smuzhiyun     defined(__FreeBSD__) || \
17*4882a593Smuzhiyun     defined(__NetBSD__)	 || \
18*4882a593Smuzhiyun     defined(__APPLE__)
19*4882a593Smuzhiyun static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, { 0 } };
20*4882a593Smuzhiyun #else
21*4882a593Smuzhiyun static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0,   0   };
22*4882a593Smuzhiyun #endif
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun static struct speedmap {
25*4882a593Smuzhiyun     char *str;
26*4882a593Smuzhiyun     speed_t val;
27*4882a593Smuzhiyun } speedmap[] = {
28*4882a593Smuzhiyun     { "50", B50 },		{ "75", B75 },		{ "110", B110 },
29*4882a593Smuzhiyun     { "134", B134 },		{ "150", B150 },	{ "200", B200 },
30*4882a593Smuzhiyun     { "300", B300 },		{ "600", B600 },	{ "1200", B1200 },
31*4882a593Smuzhiyun     { "1800", B1800 },		{ "2400", B2400 },	{ "4800", B4800 },
32*4882a593Smuzhiyun     { "9600", B9600 },		{ "19200", B19200 },	{ "38400", B38400 },
33*4882a593Smuzhiyun     { "57600", B57600 },
34*4882a593Smuzhiyun #ifdef	B76800
35*4882a593Smuzhiyun     { "76800", B76800 },
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun     { "115200", B115200 },
38*4882a593Smuzhiyun #ifdef	B153600
39*4882a593Smuzhiyun     { "153600", B153600 },
40*4882a593Smuzhiyun #endif
41*4882a593Smuzhiyun     { "230400", B230400 },
42*4882a593Smuzhiyun #ifdef	B307200
43*4882a593Smuzhiyun     { "307200", B307200 },
44*4882a593Smuzhiyun #endif
45*4882a593Smuzhiyun #ifdef B460800
46*4882a593Smuzhiyun     { "460800", B460800 }
47*4882a593Smuzhiyun #endif
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun static int nspeeds = sizeof speedmap / sizeof speedmap[0];
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun speed_t
cvtspeed(char * str)52*4882a593Smuzhiyun cvtspeed(char *str)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun     struct speedmap *smp = speedmap, *esmp = &speedmap[nspeeds];
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun     while (smp < esmp) {
57*4882a593Smuzhiyun 	if (strcmp(str, smp->str) == 0)
58*4882a593Smuzhiyun 	    return (smp->val);
59*4882a593Smuzhiyun 	smp++;
60*4882a593Smuzhiyun     }
61*4882a593Smuzhiyun     return B0;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun int
serialopen(char * device,speed_t speed)65*4882a593Smuzhiyun serialopen(char *device, speed_t speed)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun     int fd;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun     if (cfsetospeed(&tios, speed) < 0)
70*4882a593Smuzhiyun 	return -1;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun     if ((fd = open(device, O_RDWR)) < 0)
73*4882a593Smuzhiyun 	return -1;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun     if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
76*4882a593Smuzhiyun 	(void)close(fd);
77*4882a593Smuzhiyun 	return -1;
78*4882a593Smuzhiyun     }
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun     return fd;
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun int
serialreadchar(int fd,int timeout)84*4882a593Smuzhiyun serialreadchar(int fd, int timeout)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun     fd_set fds;
87*4882a593Smuzhiyun     struct timeval tv;
88*4882a593Smuzhiyun     int n;
89*4882a593Smuzhiyun     char ch;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun     tv.tv_sec = timeout;
92*4882a593Smuzhiyun     tv.tv_usec = 0;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun     FD_ZERO(&fds);
95*4882a593Smuzhiyun     FD_SET(fd, &fds);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun     /* this is a fucking horrible quick hack - fix this */
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun     if ((n = select(fd + 1, &fds, 0, 0, &tv)) < 0)
100*4882a593Smuzhiyun 	return SERIAL_ERROR;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun     if (n == 0)
103*4882a593Smuzhiyun 	return SERIAL_TIMEOUT;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun     if ((n = read(fd, &ch, 1)) < 0)
106*4882a593Smuzhiyun 	return SERIAL_ERROR;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun     if (n == 0)
109*4882a593Smuzhiyun 	return SERIAL_EOF;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun     return ch;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun int
serialwrite(int fd,char * buf,int len)115*4882a593Smuzhiyun serialwrite(int fd, char *buf, int len)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun     int n;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun     do {
120*4882a593Smuzhiyun 	n = write(fd, buf, len);
121*4882a593Smuzhiyun 	if (n < 0)
122*4882a593Smuzhiyun 	    return 1;
123*4882a593Smuzhiyun 	len -= n;
124*4882a593Smuzhiyun 	buf += n;
125*4882a593Smuzhiyun     } while (len > 0);
126*4882a593Smuzhiyun     return 0;
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun int
serialclose(int fd)130*4882a593Smuzhiyun serialclose(int fd)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun     return close(fd);
133*4882a593Smuzhiyun }
134