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