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