2 * Copyright 1993-2003 by The XFree86 Project, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * Except as contained in this notice, the name of the XFree86 Project shall
23 * not be used in advertising or otherwise to promote the sale, use or other
24 * dealings in this Software without prior written authorization from the
29 * Copyright (c) 1997 Metro Link Incorporated
31 * Permission is hereby granted, free of charge, to any person obtaining a
32 * copy of this software and associated documentation files (the "Software"),
33 * to deal in the Software without restriction, including without limitation
34 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35 * and/or sell copies of the Software, and to permit persons to whom the
36 * Software is furnished to do so, subject to the following conditions:
38 * The above copyright notice and this permission notice shall be included in
39 * all copies or substantial portions of the Software.
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
45 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
46 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
49 * Except as contained in this notice, the name of the Metro Link shall not be
50 * used in advertising or otherwise to promote the sale, use or other dealings
51 * in this Software without prior written authorization from Metro Link.
55 #ifdef HAVE_XORG_CONFIG_H
56 #include <xorg-config.h>
62 #include "xf86_OSlib.h"
88 if (baudrate
== 19200)
92 if (baudrate
== 38400)
96 if (baudrate
== 57600)
100 if (baudrate
== 115200)
104 if (baudrate
== 230400)
108 if (baudrate
== 460800)
115 xf86OpenSerial(XF86OptionPtr options
)
121 dev
= xf86SetStrOption(options
, "Device", NULL
);
123 xf86Msg(X_ERROR
, "xf86OpenSerial: No Device specified.\n");
127 SYSCALL(fd
= open(dev
, O_RDWR
| O_NONBLOCK
));
130 "xf86OpenSerial: Cannot open device %s\n\t%s.\n",
131 dev
, strerror(errno
));
137 /* Allow non-tty devices to be opened. */
142 /* set up default port parameters */
143 SYSCALL(tcgetattr(fd
, &t
));
144 t
.c_iflag
&= ~(IGNBRK
| BRKINT
| PARMRK
| ISTRIP
| INLCR
145 | IGNCR
| ICRNL
| IXON
);
147 t
.c_lflag
&= ~(ECHO
| ECHONL
| ICANON
| ISIG
| IEXTEN
);
148 t
.c_cflag
&= ~(CSIZE
| PARENB
);
149 t
.c_cflag
|= CS8
| CLOCAL
;
151 cfsetispeed(&t
, B9600
);
152 cfsetospeed(&t
, B9600
);
156 SYSCALL(tcsetattr(fd
, TCSANOW
, &t
));
158 if (xf86SetSerial(fd
, options
) == -1) {
164 SYSCALL(i
= fcntl(fd
, F_GETFL
, 0));
171 SYSCALL(i
= fcntl(fd
, F_SETFL
, i
));
182 xf86SetSerial(int fd
, XF86OptionPtr options
)
192 /* Don't try to set parameters for non-tty devices. */
196 SYSCALL(tcgetattr(fd
, &t
));
198 if ((val
= xf86SetIntOption(options
, "BaudRate", 0))) {
199 if ((baud
= GetBaud(val
))) {
200 cfsetispeed(&t
, baud
);
201 cfsetospeed(&t
, baud
);
204 xf86Msg(X_ERROR
, "Invalid Option BaudRate value: %d\n", val
);
209 if ((val
= xf86SetIntOption(options
, "StopBits", 0))) {
212 t
.c_cflag
&= ~(CSTOPB
);
218 xf86Msg(X_ERROR
, "Invalid Option StopBits value: %d\n", val
);
224 if ((val
= xf86SetIntOption(options
, "DataBits", 0))) {
227 t
.c_cflag
&= ~(CSIZE
);
231 t
.c_cflag
&= ~(CSIZE
);
235 t
.c_cflag
&= ~(CSIZE
);
239 t
.c_cflag
&= ~(CSIZE
);
243 xf86Msg(X_ERROR
, "Invalid Option DataBits value: %d\n", val
);
249 if ((s
= xf86SetStrOption(options
, "Parity", NULL
))) {
250 if (xf86NameCmp(s
, "Odd") == 0) {
251 t
.c_cflag
|= PARENB
| PARODD
;
253 else if (xf86NameCmp(s
, "Even") == 0) {
255 t
.c_cflag
&= ~(PARODD
);
257 else if (xf86NameCmp(s
, "None") == 0) {
258 t
.c_cflag
&= ~(PARENB
);
261 xf86Msg(X_ERROR
, "Invalid Option Parity value: %s\n", s
);
266 if ((val
= xf86SetIntOption(options
, "Vmin", -1)) != -1) {
269 if ((val
= xf86SetIntOption(options
, "Vtime", -1)) != -1) {
273 if ((s
= xf86SetStrOption(options
, "FlowControl", NULL
))) {
274 xf86MarkOptionUsedByName(options
, "FlowControl");
275 if (xf86NameCmp(s
, "Xoff") == 0) {
278 else if (xf86NameCmp(s
, "Xon") == 0) {
281 else if (xf86NameCmp(s
, "XonXoff") == 0) {
282 t
.c_iflag
|= IXON
| IXOFF
;
284 else if (xf86NameCmp(s
, "None") == 0) {
285 t
.c_iflag
&= ~(IXON
| IXOFF
);
288 xf86Msg(X_ERROR
, "Invalid Option FlowControl value: %s\n", s
);
293 if ((xf86SetBoolOption(options
, "ClearDTR", FALSE
))) {
294 #ifdef CLEARDTR_SUPPORT
295 #if defined(TIOCMBIC)
297 SYSCALL(ioctl(fd
, TIOCMBIC
, &val
));
299 SYSCALL(ioctl(fd
, TIOCCDTR
, NULL
));
302 xf86Msg(X_WARNING
, "Option ClearDTR not supported on this OS\n");
305 xf86MarkOptionUsedByName(options
, "ClearDTR");
308 if ((xf86SetBoolOption(options
, "ClearRTS", FALSE
))) {
309 xf86Msg(X_WARNING
, "Option ClearRTS not supported on this OS\n");
311 xf86MarkOptionUsedByName(options
, "ClearRTS");
314 SYSCALL(r
= tcsetattr(fd
, TCSANOW
, &t
));
319 xf86SetSerialSpeed(int fd
, int speed
)
327 /* Don't try to set parameters for non-tty devices. */
331 SYSCALL(tcgetattr(fd
, &t
));
333 if ((baud
= GetBaud(speed
))) {
334 cfsetispeed(&t
, baud
);
335 cfsetospeed(&t
, baud
);
338 xf86Msg(X_ERROR
, "Invalid Option BaudRate value: %d\n", speed
);
342 SYSCALL(r
= tcsetattr(fd
, TCSANOW
, &t
));
347 xf86ReadSerial(int fd
, void *buf
, int count
)
352 SYSCALL(r
= read(fd
, buf
, count
));
353 DebugF("ReadingSerial: 0x%x", (unsigned char) *(((unsigned char *) buf
)));
354 for (i
= 1; i
< r
; i
++)
355 DebugF(", 0x%x", (unsigned char) *(((unsigned char *) buf
) + i
));
361 xf86WriteSerial(int fd
, const void *buf
, int count
)
366 DebugF("WritingSerial: 0x%x", (unsigned char) *(((unsigned char *) buf
)));
367 for (i
= 1; i
< count
; i
++)
368 DebugF(", 0x%x", (unsigned char) *(((unsigned char *) buf
) + i
));
370 SYSCALL(r
= write(fd
, buf
, count
));
375 xf86CloseSerial(int fd
)
379 SYSCALL(r
= close(fd
));
384 xf86WaitForInput(int fd
, int timeout
)
393 FD_SET(fd
, &readfds
);
396 to
.tv_sec
= timeout
/ 1000000;
397 to
.tv_usec
= timeout
% 1000000;
400 SYSCALL(r
= select(FD_SETSIZE
, &readfds
, NULL
, NULL
, &to
));
403 SYSCALL(r
= select(FD_SETSIZE
, NULL
, NULL
, NULL
, &to
));
405 xf86ErrorFVerb(9, "select returned %d\n", r
);
410 xf86SerialSendBreak(int fd
, int duration
)
414 SYSCALL(r
= tcsendbreak(fd
, duration
));
420 xf86FlushInput(int fd
)
423 struct timeval timeout
;
424 /* this needs to be big enough to flush an evdev event. */
427 DebugF("FlushingSerial\n");
428 if (tcflush(fd
, TCIFLUSH
) == 0)
435 while (select(FD_SETSIZE
, &fds
, NULL
, NULL
, &timeout
) > 0) {
436 if (read(fd
, &c
, sizeof(c
)) < 1)
444 static struct states
{
450 XF86_M_LE
, TIOCM_LE
},
454 XF86_M_DTR
, TIOCM_DTR
},
458 XF86_M_RTS
, TIOCM_RTS
},
462 XF86_M_ST
, TIOCM_ST
},
466 XF86_M_SR
, TIOCM_SR
},
470 XF86_M_CTS
, TIOCM_CTS
},
474 XF86_M_CAR
, TIOCM_CAR
},
475 #elif defined(TIOCM_CD)
477 XF86_M_CAR
, TIOCM_CD
},
481 XF86_M_RNG
, TIOCM_RNG
},
482 #elif defined(TIOCM_RI)
484 XF86_M_CAR
, TIOCM_RI
},
488 XF86_M_DSR
, TIOCM_DSR
},
492 static int numStates
= sizeof(modemStates
) / sizeof(modemStates
[0]);
495 xf2osState(int state
)
500 for (i
= 0; i
< numStates
; i
++)
501 if (state
& modemStates
[i
].xf
)
502 ret
|= modemStates
[i
].os
;
507 os2xfState(int state
)
512 for (i
= 0; i
< numStates
; i
++)
513 if (state
& modemStates
[i
].os
)
514 ret
|= modemStates
[i
].xf
;
524 for (i
= 0; i
< numStates
; i
++)
525 ret
|= modemStates
[i
].os
;
529 static int osStateMask
= 0;
532 xf86SetSerialModemState(int fd
, int state
)
540 /* Don't try to set parameters for non-tty devices. */
548 osStateMask
= getOsStateMask();
550 state
= xf2osState(state
);
551 SYSCALL((ret
= ioctl(fd
, TIOCMGET
, &s
)));
556 SYSCALL((ret
= ioctl(fd
, TIOCMSET
, &s
)));
565 xf86GetSerialModemState(int fd
)
573 /* Don't try to set parameters for non-tty devices. */
580 SYSCALL((ret
= ioctl(fd
, TIOCMGET
, &s
)));
583 return os2xfState(s
);
588 xf86SerialModemSetBits(int fd
, int bits
)
596 /* Don't try to set parameters for non-tty devices. */
603 s
= xf2osState(bits
);
604 SYSCALL((ret
= ioctl(fd
, TIOCMBIS
, &s
)));
610 xf86SerialModemClearBits(int fd
, int bits
)
618 /* Don't try to set parameters for non-tty devices. */
625 s
= xf2osState(bits
);
626 SYSCALL((ret
= ioctl(fd
, TIOCMBIC
, &s
)));