Applied patches from Tony.Thompson@arm.com to implement the Angel remote
[deliverable/binutils-gdb.git] / gdb / rdi-share / unixcomm.c
1 /*
2 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3 *
4 * This software may be freely used, copied, modified, and distributed
5 * provided that the above copyright notice is preserved in all copies of the
6 * software.
7 */
8
9 /* -*-C-*-
10 *
11 * $Revision$
12 * $Date$
13 *
14 */
15
16 #ifdef __hpux
17 # define _POSIX_SOURCE 1
18 #endif
19
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <ctype.h>
23
24 #ifdef __hpux
25 # define _TERMIOS_INCLUDED
26 # include <sys/termio.h>
27 # undef _TERMIOS_INCLUDED
28 #else
29 # include <termios.h>
30 #endif
31
32 #include <string.h>
33 #include <fcntl.h>
34 #include <errno.h>
35 #include <stdarg.h>
36 #include <sys/types.h>
37 #include <sys/time.h>
38
39 #ifdef sun
40 # include <sys/ioccom.h>
41 # ifdef __svr4__
42 # include <sys/bpp_io.h>
43 # else
44 # include <sbusdev/bpp_io.h>
45 # endif
46 #endif
47
48 #ifdef BSD
49 # ifdef sun
50 # include <sys/ttydev.h>
51 # endif
52 # ifdef __alpha
53 # include <sys/ioctl.h>
54 # else
55 # include <sys/filio.h>
56 # endif
57 #endif
58
59 #ifdef __hpux
60 # define _INCLUDE_HPUX_SOURCE
61 # include <sys/ioctl.h>
62 # undef _INCLUDE_HPUX_SOURCE
63 #endif
64
65 #include "host.h"
66 #include "unixcomm.h"
67
68 #define PP_TIMEOUT 1 /* seconds */
69
70 #ifdef sun
71 #define SERPORT1 "/dev/ttya"
72 #define SERPORT2 "/dev/ttyb"
73 #define PARPORT1 "/dev/bpp0"
74 #define PARPORT2 "/dev/bpp1"
75 #endif
76
77 #ifdef __hpux
78 #define SERPORT1 "/dev/tty00"
79 #define SERPORT2 "/dev/tty01"
80 #define PARPORT1 "/dev/ptr_parallel"
81 #define PARPORT2 "/dev/ptr_parallel"
82 #endif
83
84 #ifdef __linux__
85 #define SERPORT1 "/dev/cua0"
86 #define SERPORT2 "/dev/cua1"
87 #define PARPORT1 "/dev/par0"
88 #define PARPORT2 "/dev/par1"
89 #endif
90
91 #ifdef _WIN32
92 #define SERPORT1 "com1"
93 #define SERPORT2 "com2"
94 #define PARPORT1 "lpt1"
95 #define PARPORT2 "lpt2"
96 #endif
97
98 /*
99 * Parallel port output pins, used for signalling to target
100 */
101
102 #ifdef sun
103 struct bpp_pins bp;
104 #endif
105
106 static int serpfd = -1;
107 static int parpfd = -1;
108
109 extern const char *Unix_MatchValidSerialDevice(const char *name)
110 {
111 int i=0;
112 char *sername=NULL;
113
114 /* Accept no name as the default serial port */
115 if (name == NULL) {
116 return SERPORT1;
117 }
118
119 /* Look for the simple cases - 1,2,s,S,/dev/... first, and
120 * afterwards look for S=... clauses, which need parsing properly.
121 */
122
123 /* Accept /dev/tty* where * is limited */
124 if (strlen(name) == strlen(SERPORT1) && strncmp(name, "/dev/tty", 8) == 0) return name;
125
126 /* Accept "1" or "2" or "S" - S is equivalent to "1" */
127 if (strcmp(name, "1") == 0 ||
128 strcmp(name, "S") == 0 || strcmp(name, "s") == 0) {
129 return SERPORT1;
130 }
131 if (strcmp(name, "2") == 0) return SERPORT2;
132
133 /* It wasn't one of the simple cases, so now we have to parse it
134 * properly
135 */
136
137 do {
138 switch (name[i]) {
139 case ',':
140 /* Skip over commas */
141 i++;
142 break;
143
144 default:
145 return 0;
146 /* Unexpected character => error - not matched */
147
148 case 0:
149 /* End of string means return whatever we have matched */
150 return sername;
151
152 case 's':
153 case 'S':
154 case 'h':
155 case 'H': {
156 char ch = tolower(name[i]);
157 int j, continue_from, len;
158
159 /* If the next character is a comma or a NULL then this is
160 * a request for the default Serial port
161 */
162 if (name[++i] == 0 || name[i] == ',') {
163 if (ch=='s')
164 sername=SERPORT1;
165 break;
166 }
167
168 /* Next character must be an = */
169 if (name[i] != '=') return 0;
170 /* Search for the end of the port spec. (ends in NULL or ,) */
171 for (j= ++i; name[j] != 0 && name[j] != ','; j++)
172 ; /* Do nothing */
173 /* Notice whether this is the last thing to parse or not
174 * and also calaculate the length of the string
175 */
176 if (name[j] == '0') continue_from = -1;
177 else continue_from = j;
178 len=(j-i);
179
180 /* And now try to match the serial / parallel port */
181 switch (ch) {
182 case 's': {
183 /* Match serial port */
184 if (len==1) {
185 if (name[i]=='1')
186 sername=SERPORT1;
187 else if (name[i]=='2')
188 sername=SERPORT2;
189 } else if (len==strlen(SERPORT1)) {
190 if (strncmp(name+i,SERPORT1,strlen(SERPORT1)) == 0)
191 sername=SERPORT1;
192 else if (strncmp(name+i,SERPORT2,strlen(SERPORT2)) == 0)
193 sername=SERPORT2;
194 }
195
196 break;
197 }
198
199 case 'h':
200 /* We don't actually deal with the H case here, we just
201 * match it and allow it through.
202 */
203 break;
204 }
205
206 if (continue_from == -1) return sername;
207 i = continue_from;
208 break;
209 }
210 }
211 } while (1);
212
213 return 0;
214 }
215
216
217 extern int Unix_IsSerialInUse(void)
218 {
219 if (serpfd >= 0)
220 return -1;
221
222 return 0;
223 }
224
225 extern int Unix_OpenSerial(const char *name)
226 {
227 #if defined(BSD)
228 serpfd = open(name, O_RDWR);
229 #else
230 serpfd = open(name, O_RDWR | O_NONBLOCK);
231 #endif
232
233 if (serpfd < 0) {
234 perror("open");
235 return -1;
236 }
237
238 return 0;
239 }
240
241 extern void Unix_CloseSerial(void)
242 {
243 if (serpfd >= 0)
244 {
245 (void)close(serpfd);
246 serpfd = -1;
247 }
248 }
249
250 extern int Unix_ReadSerial(unsigned char *buf, int n, bool block)
251 {
252 fd_set fdset;
253 struct timeval tv;
254 int err;
255
256 FD_ZERO(&fdset);
257 FD_SET(serpfd, &fdset);
258
259 tv.tv_sec = 0;
260 tv.tv_usec = (block ? 10000 : 0);
261
262 err = select(serpfd + 1, &fdset, NULL, NULL, &tv);
263
264 if (err < 0 && errno != EINTR)
265 {
266 #ifdef DEBUG
267 perror("select");
268 #endif
269 panic("select failure");
270 return -1;
271 }
272 else if (err > 0 && FD_ISSET(serpfd, &fdset))
273 return read(serpfd, buf, n);
274 else /* err == 0 || FD_CLR(serpfd, &fdset) */
275 {
276 errno = ERRNO_FOR_BLOCKED_IO;
277 return -1;
278 }
279 }
280
281 extern int Unix_WriteSerial(unsigned char *buf, int n)
282 {
283 return write(serpfd, buf, n);
284 }
285
286 extern void Unix_ResetSerial(void)
287 {
288 struct termios terminfo;
289
290 tcgetattr(serpfd, &terminfo);
291 #ifdef __CYGWIN32__
292 /* Expedient, but it works. */
293 terminfo.c_iflag = 0;
294 terminfo.c_oflag = 0;
295 terminfo.c_cflag = 48;
296 terminfo.c_lflag = 0;
297 terminfo.c_cc[VMIN] = 0;
298 terminfo.c_cc[VTIME] = 1;
299 #else
300 terminfo.c_lflag &= ~(ICANON | ISIG | ECHO | IEXTEN);
301 terminfo.c_iflag &= ~(IGNCR | INPCK | ISTRIP | ICRNL | BRKINT);
302 terminfo.c_iflag |= (IXON | IXOFF | IGNBRK);
303 terminfo.c_cflag = (terminfo.c_cflag & ~CSIZE) | CS8 | CREAD;
304 terminfo.c_cflag &= ~PARENB;
305 terminfo.c_cc[VMIN] = 1;
306 terminfo.c_cc[VTIME] = 0;
307 terminfo.c_oflag &= ~OPOST;
308 #endif
309 tcsetattr(serpfd, TCSAFLUSH, &terminfo);
310 }
311
312 extern void Unix_SetSerialBaudRate(int baudrate)
313 {
314 struct termios terminfo;
315
316 tcgetattr(serpfd, &terminfo);
317 cfsetospeed(&terminfo, baudrate);
318 cfsetispeed(&terminfo, baudrate);
319 tcsetattr(serpfd, TCSAFLUSH, &terminfo);
320 }
321
322 extern void Unix_ioctlNonBlocking(void)
323 {
324 #if defined(BSD)
325 int nonblockingIO = 1;
326 (void)ioctl(serpfd, FIONBIO, &nonblockingIO);
327
328 if (parpfd != -1)
329 (void)ioctl(parpfd, FIONBIO, &nonblockingIO);
330 #endif
331 }
332
333 extern void Unix_IsValidParallelDevice(
334 const char *portstring, char **sername, char **parname)
335 {
336 int i=0;
337 *sername=NULL;
338 *parname=NULL;
339
340 /* Do not recognise a NULL portstring */
341 if (portstring==NULL) return;
342
343 do {
344 switch (portstring[i]) {
345 case ',':
346 /* Skip over commas */
347 i++;
348 break;
349
350 default:
351 case 0:
352 /* End of string or bad characcter means we have finished */
353 return;
354
355 case 's':
356 case 'S':
357 case 'p':
358 case 'P':
359 case 'h':
360 case 'H': {
361 char ch = tolower(portstring[i]);
362 int j, continue_from, len;
363
364 /* If the next character is a comma or a NULL then this is
365 * a request for the default Serial or Parallel port
366 */
367 if (portstring[++i] == 0 || portstring[i] == ',') {
368 if (ch=='s') *sername=SERPORT1;
369 else if (ch=='p') *parname=PARPORT1;
370 break;
371 }
372
373 /* Next character must be an = */
374 if (portstring[i] != '=') return;
375 /* Search for the end of the port spec. (ends in NULL or ,) */
376 for (j= ++i; portstring[j] != 0 && portstring[j] != ','; j++)
377 ; /* Do nothing */
378 /* Notice whether this is the last thing to parse or not
379 * and also calaculate the length of the string
380 */
381 if (portstring[j] == '0') continue_from = -1;
382 else continue_from = j;
383 len=(j-i);
384
385 /* And now try to match the serial / parallel port */
386 switch (ch) {
387 case 's': {
388 /* Match serial port */
389 if (len==1) {
390 if (portstring[i]=='1') *sername=SERPORT1;
391 else if (portstring[i]=='2') *sername=SERPORT2;
392 } else if (len==strlen(SERPORT1)) {
393 if (strncmp(portstring+i,SERPORT1,strlen(SERPORT1)) == 0)
394 *sername=SERPORT1;
395 else if (strncmp(portstring+i,SERPORT2,strlen(SERPORT2)) == 0)
396 *sername=SERPORT2;
397 }
398 break;
399 }
400
401 case 'p': {
402 /* Match parallel port */
403 if (len==1) {
404 if (portstring[i]=='1') *parname=PARPORT1;
405 else if (portstring[i]=='2') *parname=PARPORT2;
406 } else if (len==strlen(PARPORT1)) {
407 if (strncmp(portstring+i,PARPORT1,strlen(PARPORT1)) == 0)
408 *parname=PARPORT1;
409 else if (strncmp(portstring+i,PARPORT2,strlen(PARPORT2)) == 0)
410 *parname=PARPORT2;
411 }
412 break;
413 }
414
415 case 'h':
416 /* We don't actually deal with the H case here, we just
417 * match it and allow it through.
418 */
419 break;
420 }
421
422 if (continue_from == -1) return;
423 i = continue_from;
424 break;
425 }
426 }
427 } while (1);
428 return; /* Will never get here */
429 }
430
431 extern int Unix_IsParallelInUse(void)
432 {
433 if (parpfd >= 0)
434 return -1;
435
436 return 0;
437 }
438
439 extern int Unix_OpenParallel(const char *name)
440 {
441 #if defined(BSD)
442 parpfd = open(name, O_RDWR);
443 #else
444 parpfd = open(name, O_RDWR | O_NONBLOCK);
445 #endif
446
447 if (parpfd < 0)
448 {
449 char errbuf[256];
450
451 sprintf(errbuf, "open %s", name);
452 perror(errbuf);
453
454 return -1;
455 }
456
457 return 0;
458 }
459
460 extern void Unix_CloseParallel(void)
461 {
462 if (parpfd >= 0)
463 {
464 (void)close(parpfd);
465 parpfd = -1;
466 }
467 }
468
469
470 extern unsigned int Unix_WriteParallel(unsigned char *buf, int n)
471 {
472 int ngone;
473
474 if ((ngone = write(parpfd, buf, n)) < 0)
475 {
476 /*
477 * we ignore errors (except for debug purposes)
478 */
479 #ifdef DEBUG
480 char errbuf[256];
481
482 sprintf(errbuf, "send_packet: write");
483 perror(errbuf);
484 #endif
485 ngone = 0;
486 }
487
488 /* finished */
489 return (unsigned int)ngone;
490 }
491
492
493 #ifdef sun
494 extern void Unix_ResetParallel(void)
495 {
496 struct bpp_transfer_parms tp;
497
498 #ifdef DEBUG
499 printf("serpar_reset\n");
500 #endif
501
502 /*
503 * we need to set the parallel port up for BUSY handshaking,
504 * and select the timeout
505 */
506 if (ioctl(parpfd, BPPIOC_GETPARMS, &tp) < 0)
507 {
508 #ifdef DEBUG
509 perror("ioctl(BPPIOCGETPARMS)");
510 #endif
511 panic("serpar_reset: cannot get BPP parameters");
512 }
513
514 tp.write_handshake = BPP_BUSY_HS;
515 tp.write_timeout = PP_TIMEOUT;
516
517 if (ioctl(parpfd, BPPIOC_SETPARMS, &tp) < 0)
518 {
519 #ifdef DEBUG
520 perror("ioctl(BPPIOC_SETPARMS)");
521 #endif
522 panic("serpar_reset: cannot set BPP parameters");
523 }
524 }
525
526 #else
527
528 /* Parallel not supported on HP */
529
530 extern void Unix_ResetParallel(void)
531 {
532 }
533
534 #endif
535
This page took 0.04267 seconds and 5 git commands to generate.