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