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