52
71
#define ODD_PARITY 1
53
72
#define EVEN_PARITY 2
56
struct termios termios;
60
uint32 queue_in_size, queue_out_size;
62
uint8 stop_bits, parity, word_length;
74
#define SERIAL_PURGE_TXABORT 0x00000001
75
#define SERIAL_PURGE_RXABORT 0x00000002
76
#define SERIAL_PURGE_TXCLEAR 0x00000004
77
#define SERIAL_PURGE_RXCLEAR 0x00000008
79
/* SERIAL_WAIT_ON_MASK */
80
#define SERIAL_EV_RXCHAR 0x0001 /* Any Character received */
81
#define SERIAL_EV_RXFLAG 0x0002 /* Received certain character */
82
#define SERIAL_EV_TXEMPTY 0x0004 /* Transmitt Queue Empty */
83
#define SERIAL_EV_CTS 0x0008 /* CTS changed state */
84
#define SERIAL_EV_DSR 0x0010 /* DSR changed state */
85
#define SERIAL_EV_RLSD 0x0020 /* RLSD changed state */
86
#define SERIAL_EV_BREAK 0x0040 /* BREAK received */
87
#define SERIAL_EV_ERR 0x0080 /* Line status error occurred */
88
#define SERIAL_EV_RING 0x0100 /* Ring signal detected */
89
#define SERIAL_EV_PERR 0x0200 /* Printer error occured */
90
#define SERIAL_EV_RX80FULL 0x0400 /* Receive buffer is 80 percent full */
91
#define SERIAL_EV_EVENT1 0x0800 /* Provider specific event 1 */
92
#define SERIAL_EV_EVENT2 0x1000 /* Provider specific event 2 */
95
#define SERIAL_MS_DTR 0x01
96
#define SERIAL_MS_RTS 0x02
97
#define SERIAL_MS_CTS 0x10
98
#define SERIAL_MS_DSR 0x20
99
#define SERIAL_MS_RNG 0x40
100
#define SERIAL_MS_CAR 0x80
103
#define SERIAL_DTR_CONTROL 0x01
104
#define SERIAL_CTS_HANDSHAKE 0x08
105
#define SERIAL_ERROR_ABORT 0x80000000
107
#define SERIAL_XON_HANDSHAKE 0x01
108
#define SERIAL_XOFF_HANDSHAKE 0x02
109
#define SERIAL_DSR_SENSITIVITY 0x40
111
#define SERIAL_CHAR_EOF 0
112
#define SERIAL_CHAR_ERROR 1
113
#define SERIAL_CHAR_BREAK 2
114
#define SERIAL_CHAR_EVENT 3
115
#define SERIAL_CHAR_XON 4
116
#define SERIAL_CHAR_XOFF 5
122
/* FIONREAD should really do the same thing as TIOCINQ, where it is
124
#if !defined(TIOCINQ) && defined(FIONREAD)
125
#define TIOCINQ FIONREAD
127
#if !defined(TIOCOUTQ) && defined(FIONWRITE)
128
#define TIOCOUTQ FIONWRITE
131
extern RDPDR_DEVICE g_rdpdr_device[];
133
static SERIAL_DEVICE *
134
get_serial_info(NTHANDLE handle)
138
for (index = 0; index < RDPDR_MAX_DEVICES; index++)
140
if (handle == g_rdpdr_device[index].handle)
141
return (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
147
get_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
69
if (tcgetattr(serial_fd, &termios) == -1)
150
struct termios *ptermios;
152
ptermios = pser_inf->ptermios;
154
if (tcgetattr(serial_fd, ptermios) == -1)
72
speed = cfgetispeed(&termios);
157
speed = cfgetispeed(ptermios);
162
pser_inf->baud_rate = 75;
167
pser_inf->baud_rate = 110;
172
pser_inf->baud_rate = 134;
177
pser_inf->baud_rate = 150;
182
pser_inf->baud_rate = 300;
187
pser_inf->baud_rate = 600;
192
pser_inf->baud_rate = 1200;
197
pser_inf->baud_rate = 1800;
202
pser_inf->baud_rate = 2400;
207
pser_inf->baud_rate = 4800;
212
pser_inf->baud_rate = 9600;
217
pser_inf->baud_rate = 19200;
222
pser_inf->baud_rate = 38400;
227
pser_inf->baud_rate = 57600;
232
pser_inf->baud_rate = 115200;
237
pser_inf->baud_rate = 230400;
242
pser_inf->baud_rate = 460800;
246
pser_inf->baud_rate = 9600;
155
speed = cfgetospeed(&termios);
156
dtr = (speed == B0) ? 0 : 1;
250
speed = cfgetospeed(ptermios);
251
pser_inf->dtr = (speed == B0) ? 0 : 1;
158
stop_bits = (termios.c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;
160
c_cflag & PARENB) ? ((termios.
161
c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
162
switch (termios.c_cflag & CSIZE)
253
pser_inf->stop_bits = (ptermios->c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;
256
c_cflag & PARENB) ? ((ptermios->
257
c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
258
switch (ptermios->c_cflag & CSIZE)
261
pser_inf->word_length = 5;
264
pser_inf->word_length = 6;
267
pser_inf->word_length = 7;
270
pser_inf->word_length = 8;
274
if (ptermios->c_cflag & CRTSCTS)
276
pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_CTS_HANDSHAKE | SERIAL_ERROR_ABORT;
280
pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_ERROR_ABORT;
283
pser_inf->xonoff = SERIAL_DSR_SENSITIVITY;
284
if (ptermios->c_iflag & IXON)
285
pser_inf->xonoff |= SERIAL_XON_HANDSHAKE;
287
if (ptermios->c_iflag & IXOFF)
288
pser_inf->xonoff |= SERIAL_XOFF_HANDSHAKE;
290
pser_inf->chars[SERIAL_CHAR_XON] = ptermios->c_cc[VSTART];
291
pser_inf->chars[SERIAL_CHAR_XOFF] = ptermios->c_cc[VSTOP];
292
pser_inf->chars[SERIAL_CHAR_EOF] = ptermios->c_cc[VEOF];
293
pser_inf->chars[SERIAL_CHAR_BREAK] = ptermios->c_cc[VINTR];
294
pser_inf->chars[SERIAL_CHAR_ERROR] = ptermios->c_cc[VKILL];
300
set_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
304
struct termios *ptermios;
306
ptermios = pser_inf->ptermios;
309
switch (pser_inf->baud_rate)
402
ptermios->c_cflag &= ~CBAUD;
403
ptermios->c_cflag |= speed;
268
405
/* on systems with separate ispeed and ospeed, we can remember the speed
269
406
in ispeed while changing DTR with ospeed */
270
cfsetispeed(&termios, speed);
271
cfsetospeed(&termios, dtr ? speed : 0);
407
cfsetispeed(pser_inf->ptermios, speed);
408
cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
273
termios.c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);
411
ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
412
switch (pser_inf->stop_bits)
276
414
case STOP_BITS_2:
277
termios.c_cflag |= CSTOPB;
415
ptermios->c_cflag |= CSTOPB;
418
ptermios->c_cflag &= ~CSTOPB;
422
switch (pser_inf->parity)
282
424
case EVEN_PARITY:
283
termios.c_cflag |= PARENB;
425
ptermios->c_cflag |= PARENB;
286
termios.c_cflag |= PARENB | PARODD;
428
ptermios->c_cflag |= PARENB | PARODD;
431
ptermios->c_cflag &= ~(PARENB | PARODD);
435
switch (pser_inf->word_length)
292
termios.c_cflag |= CS5;
438
ptermios->c_cflag |= CS5;
295
termios.c_cflag |= CS6;
441
ptermios->c_cflag |= CS6;
298
termios.c_cflag |= CS7;
444
ptermios->c_cflag |= CS7;
301
termios.c_cflag |= CS8;
447
ptermios->c_cflag |= CS8;
305
tcsetattr(serial_fd, TCSANOW, &termios);
453
ptermios->c_cflag |= CRTSCTS;
455
ptermios->c_cflag &= ~CRTSCTS;
458
if (pser_inf->control & SERIAL_CTS_HANDSHAKE)
460
ptermios->c_cflag |= CRTSCTS;
464
ptermios->c_cflag &= ~CRTSCTS;
468
if (pser_inf->xonoff & SERIAL_XON_HANDSHAKE)
470
ptermios->c_iflag |= IXON | IMAXBEL;
472
if (pser_inf->xonoff & SERIAL_XOFF_HANDSHAKE)
474
ptermios->c_iflag |= IXOFF | IMAXBEL;
477
if ((pser_inf->xonoff & (SERIAL_XOFF_HANDSHAKE | SERIAL_XON_HANDSHAKE)) == 0)
479
ptermios->c_iflag &= ~IXON;
480
ptermios->c_iflag &= ~IXOFF;
483
ptermios->c_cc[VSTART] = pser_inf->chars[SERIAL_CHAR_XON];
484
ptermios->c_cc[VSTOP] = pser_inf->chars[SERIAL_CHAR_XOFF];
485
ptermios->c_cc[VEOF] = pser_inf->chars[SERIAL_CHAR_EOF];
486
ptermios->c_cc[VINTR] = pser_inf->chars[SERIAL_CHAR_BREAK];
487
ptermios->c_cc[VKILL] = pser_inf->chars[SERIAL_CHAR_ERROR];
489
tcsetattr(serial_fd, TCSANOW, ptermios);
492
/* Enumeration of devices from rdesktop.c */
493
/* returns numer of units found and initialized. */
494
/* optarg looks like ':com1=/dev/ttyS0' */
495
/* when it arrives to this function. */
496
/* :com1=/dev/ttyS0,com2=/dev/ttyS1 */
498
serial_enum_devices(uint32 * id, char *optarg)
500
SERIAL_DEVICE *pser_inf;
506
/* skip the first colon */
508
while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
510
/* Init data structures for device */
511
pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));
512
pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));
513
memset(pser_inf->ptermios, 0, sizeof(struct termios));
514
pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));
515
memset(pser_inf->pold_termios, 0, sizeof(struct termios));
517
pos2 = next_arg(optarg, '=');
518
strcpy(g_rdpdr_device[*id].name, optarg);
520
toupper_str(g_rdpdr_device[*id].name);
522
g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
523
strcpy(g_rdpdr_device[*id].local_path, pos2);
524
printf("SERIAL %s to %s\n", g_rdpdr_device[*id].name,
525
g_rdpdr_device[*id].local_path);
526
/* set device type */
527
g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL;
528
g_rdpdr_device[*id].pdevice_data = (void *) pser_inf;
309
serial_create(HANDLE * handle)
538
serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
539
uint32 flags_and_attributes, char *filename, NTHANDLE * handle)
311
/* XXX do we have to handle concurrent open attempts? */
312
serial_fd = open("/dev/ttyS0", O_RDWR);
542
SERIAL_DEVICE *pser_inf;
543
struct termios *ptermios;
545
pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;
546
ptermios = pser_inf->ptermios;
547
serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY | O_NONBLOCK);
313
549
if (serial_fd == -1)
314
return STATUS_ACCESS_DENIED;
317
return STATUS_ACCESS_DENIED;
320
return STATUS_SUCCESS;
324
serial_close(HANDLE handle)
327
return STATUS_SUCCESS;
331
serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 * result)
333
*result = read(serial_fd, data, length);
334
return STATUS_SUCCESS;
338
serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 * result)
340
*result = write(serial_fd, data, length);
341
return STATUS_SUCCESS;
345
serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)
552
return STATUS_ACCESS_DENIED;
555
if (!get_termios(pser_inf, serial_fd))
557
printf("INFO: SERIAL %s access denied\n", g_rdpdr_device[device_id].name);
559
return STATUS_ACCESS_DENIED;
562
/* Store handle for later use */
563
g_rdpdr_device[device_id].handle = serial_fd;
565
/* some sane information */
566
DEBUG_SERIAL(("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u, rts %u\n", g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path, pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr, pser_inf->rts));
568
pser_inf->ptermios->c_iflag &=
569
~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
570
pser_inf->ptermios->c_oflag &= ~OPOST;
571
pser_inf->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
572
pser_inf->ptermios->c_cflag &= ~(CSIZE | PARENB);
573
pser_inf->ptermios->c_cflag |= CS8;
575
tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios);
577
pser_inf->event_txempty = 0;
578
pser_inf->event_cts = 0;
579
pser_inf->event_dsr = 0;
580
pser_inf->event_rlsd = 0;
581
pser_inf->event_pending = 0;
585
/* all read and writes should be non blocking */
586
if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)
589
pser_inf->read_total_timeout_constant = 5;
591
return STATUS_SUCCESS;
595
serial_close(NTHANDLE handle)
597
int i = get_device_index(handle);
599
g_rdpdr_device[i].handle = 0;
601
rdpdr_abort_io(handle, 0, STATUS_TIMEOUT);
603
return STATUS_SUCCESS;
607
serial_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
610
SERIAL_DEVICE *pser_inf;
611
struct termios *ptermios;
612
#ifdef WITH_DEBUG_SERIAL
618
pser_inf = get_serial_info(handle);
619
ptermios = pser_inf->ptermios;
621
/* Set timeouts kind of like the windows serial timeout parameters. Multiply timeout
622
with requested read size */
623
if (pser_inf->read_total_timeout_multiplier | pser_inf->read_total_timeout_constant)
626
(pser_inf->read_total_timeout_multiplier * length +
627
pser_inf->read_total_timeout_constant + 99) / 100;
629
else if (pser_inf->read_interval_timeout)
631
timeout = (pser_inf->read_interval_timeout * length + 99) / 100;
634
/* If a timeout is set, do a blocking read, which times out after some time.
635
It will make rdesktop less responsive, but it will improve serial performance, by not
636
reading one character at a time. */
639
ptermios->c_cc[VTIME] = 0;
640
ptermios->c_cc[VMIN] = 0;
644
ptermios->c_cc[VTIME] = timeout;
645
ptermios->c_cc[VMIN] = 1;
647
tcsetattr(handle, TCSANOW, ptermios);
649
#if defined(WITH_DEBUG_SERIAL) && defined(TIOCINQ)
650
ioctl(handle, TIOCINQ, &bytes_inqueue);
651
DEBUG_SERIAL(("serial_read inqueue: %d expected %d\n", bytes_inqueue, length));
654
*result = read(handle, data, length);
656
#ifdef WITH_DEBUG_SERIAL
657
DEBUG_SERIAL(("serial_read Bytes %d\n", *result));
659
hexdump(data, *result);
662
return STATUS_SUCCESS;
666
serial_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
668
SERIAL_DEVICE *pser_inf;
670
pser_inf = get_serial_info(handle);
672
*result = write(handle, data, length);
675
pser_inf->event_txempty = *result;
677
DEBUG_SERIAL(("serial_write length %d, offset %d result %d\n", length, offset, *result));
679
return STATUS_SUCCESS;
683
serial_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
685
int flush_mask, purge_mask;
686
uint32 result, modemstate;
688
SERIAL_DEVICE *pser_inf;
689
struct termios *ptermios;
350
691
if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)
351
692
return STATUS_INVALID_PARAMETER;
694
pser_inf = get_serial_info(handle);
695
ptermios = pser_inf->ptermios;
353
697
/* extract operation */
355
699
request &= 0xfff;
357
printf("SERIAL IOCTL %d\n", request);
361
703
case SERIAL_SET_BAUD_RATE:
362
in_uint32_le(in, baud_rate);
704
in_uint32_le(in, pser_inf->baud_rate);
705
set_termios(pser_inf, handle);
706
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BAUD_RATE %d\n",
707
pser_inf->baud_rate));
365
709
case SERIAL_GET_BAUD_RATE:
366
out_uint32_le(out, baud_rate);
710
out_uint32_le(out, pser_inf->baud_rate);
711
DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_BAUD_RATE %d\n",
712
pser_inf->baud_rate));
368
714
case SERIAL_SET_QUEUE_SIZE:
369
in_uint32_le(in, queue_in_size);
370
in_uint32_le(in, queue_out_size);
715
in_uint32_le(in, pser_inf->queue_in_size);
716
in_uint32_le(in, pser_inf->queue_out_size);
717
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_QUEUE_SIZE in %d out %d\n",
718
pser_inf->queue_in_size, pser_inf->queue_out_size));
372
720
case SERIAL_SET_LINE_CONTROL:
373
in_uint8(in, stop_bits);
374
in_uint8(in, parity);
375
in_uint8(in, word_length);
721
in_uint8(in, pser_inf->stop_bits);
722
in_uint8(in, pser_inf->parity);
723
in_uint8(in, pser_inf->word_length);
724
set_termios(pser_inf, handle);
725
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_LINE_CONTROL stop %d parity %d word %d\n", pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length));
378
727
case SERIAL_GET_LINE_CONTROL:
379
out_uint8(out, stop_bits);
380
out_uint8(out, parity);
381
out_uint8(out, word_length);
728
DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_LINE_CONTROL\n"));
729
out_uint8(out, pser_inf->stop_bits);
730
out_uint8(out, pser_inf->parity);
731
out_uint8(out, pser_inf->word_length);
383
733
case SERIAL_IMMEDIATE_CHAR:
734
DEBUG_SERIAL(("serial_ioctl -> SERIAL_IMMEDIATE_CHAR\n"));
384
735
in_uint8(in, immediate);
385
serial_write(handle, &immediate, 1, &result);
736
serial_write(handle, &immediate, 1, 0, &result);
387
738
case SERIAL_CONFIG_SIZE:
739
DEBUG_SERIAL(("serial_ioctl -> SERIAL_CONFIG_SIZE\n"));
388
740
out_uint32_le(out, 0);
390
742
case SERIAL_GET_CHARS:
743
DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_CHARS\n"));
744
out_uint8a(out, pser_inf->chars, 6);
393
746
case SERIAL_SET_CHARS:
747
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_CHARS\n"));
748
in_uint8a(in, pser_inf->chars, 6);
749
#ifdef WITH_DEBUG_SERIAL
750
hexdump(pser_inf->chars, 6);
752
set_termios(pser_inf, handle);
396
754
case SERIAL_GET_HANDFLOW:
397
out_uint32_le(out, 0);
398
out_uint32_le(out, 3); /* Xon/Xoff */
399
out_uint32_le(out, 0);
400
out_uint32_le(out, 0);
755
DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_HANDFLOW\n"));
756
get_termios(pser_inf, handle);
757
out_uint32_le(out, pser_inf->control);
758
out_uint32_le(out, pser_inf->xonoff); /* Xon/Xoff */
759
out_uint32_le(out, pser_inf->onlimit);
760
out_uint32_le(out, pser_inf->offlimit);
402
762
case SERIAL_SET_HANDFLOW:
763
in_uint32_le(in, pser_inf->control);
764
in_uint32_le(in, pser_inf->xonoff);
765
in_uint32_le(in, pser_inf->onlimit);
766
in_uint32_le(in, pser_inf->offlimit);
767
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_HANDFLOW %x %x %x %x\n",
768
pser_inf->control, pser_inf->xonoff, pser_inf->onlimit,
770
set_termios(pser_inf, handle);
405
772
case SERIAL_SET_TIMEOUTS:
773
in_uint32(in, pser_inf->read_interval_timeout);
774
in_uint32(in, pser_inf->read_total_timeout_multiplier);
775
in_uint32(in, pser_inf->read_total_timeout_constant);
776
in_uint32(in, pser_inf->write_total_timeout_multiplier);
777
in_uint32(in, pser_inf->write_total_timeout_constant);
778
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_TIMEOUTS read timeout %d %d %d\n",
779
pser_inf->read_interval_timeout,
780
pser_inf->read_total_timeout_multiplier,
781
pser_inf->read_total_timeout_constant));
408
783
case SERIAL_GET_TIMEOUTS:
784
DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_TIMEOUTS read timeout %d %d %d\n",
785
pser_inf->read_interval_timeout,
786
pser_inf->read_total_timeout_multiplier,
787
pser_inf->read_total_timeout_constant));
789
out_uint32(out, pser_inf->read_interval_timeout);
790
out_uint32(out, pser_inf->read_total_timeout_multiplier);
791
out_uint32(out, pser_inf->read_total_timeout_constant);
792
out_uint32(out, pser_inf->write_total_timeout_multiplier);
793
out_uint32(out, pser_inf->write_total_timeout_constant);
411
795
case SERIAL_GET_WAIT_MASK:
412
out_uint32(out, wait_mask);
796
DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_WAIT_MASK %X\n",
797
pser_inf->wait_mask));
798
out_uint32(out, pser_inf->wait_mask);
414
800
case SERIAL_SET_WAIT_MASK:
415
in_uint32(in, wait_mask);
801
in_uint32(in, pser_inf->wait_mask);
802
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_WAIT_MASK %X\n",
803
pser_inf->wait_mask));
417
805
case SERIAL_SET_DTR:
806
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_DTR\n"));
807
ioctl(handle, TIOCMGET, &result);
809
ioctl(handle, TIOCMSET, &result);
421
812
case SERIAL_CLR_DTR:
813
DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_DTR\n"));
814
ioctl(handle, TIOCMGET, &result);
815
result &= ~TIOCM_DTR;
816
ioctl(handle, TIOCMSET, &result);
820
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_RTS\n"));
821
ioctl(handle, TIOCMGET, &result);
823
ioctl(handle, TIOCMSET, &result);
827
DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_RTS\n"));
828
ioctl(handle, TIOCMGET, &result);
829
result &= ~TIOCM_RTS;
830
ioctl(handle, TIOCMSET, &result);
833
case SERIAL_GET_MODEMSTATUS:
836
ioctl(handle, TIOCMGET, &result);
837
if (result & TIOCM_CTS)
838
modemstate |= SERIAL_MS_CTS;
839
if (result & TIOCM_DSR)
840
modemstate |= SERIAL_MS_DSR;
841
if (result & TIOCM_RNG)
842
modemstate |= SERIAL_MS_RNG;
843
if (result & TIOCM_CAR)
844
modemstate |= SERIAL_MS_CAR;
845
if (result & TIOCM_DTR)
846
modemstate |= SERIAL_MS_DTR;
847
if (result & TIOCM_RTS)
848
modemstate |= SERIAL_MS_RTS;
850
DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X\n", modemstate));
851
out_uint32_le(out, modemstate);
853
case SERIAL_GET_COMMSTATUS:
854
out_uint32_le(out, 0); /* Errors */
855
out_uint32_le(out, 0); /* Hold reasons */
859
ioctl(handle, TIOCINQ, &result);
861
out_uint32_le(out, result); /* Amount in in queue */
863
DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d\n",
868
ioctl(handle, TIOCOUTQ, &result);
870
out_uint32_le(out, result); /* Amount in out queue */
872
DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d\n", result));
874
out_uint8(out, 0); /* EofReceived */
875
out_uint8(out, 0); /* WaitForImmediate */
878
in_uint32(in, purge_mask);
879
DEBUG_SERIAL(("serial_ioctl -> SERIAL_PURGE purge_mask %X\n", purge_mask));
881
if (purge_mask & SERIAL_PURGE_TXCLEAR)
882
flush_mask |= TCOFLUSH;
883
if (purge_mask & SERIAL_PURGE_RXCLEAR)
884
flush_mask |= TCIFLUSH;
886
tcflush(handle, flush_mask);
887
if (purge_mask & SERIAL_PURGE_TXABORT)
888
rdpdr_abort_io(handle, 4, STATUS_CANCELLED);
889
if (purge_mask & SERIAL_PURGE_RXABORT)
890
rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
426
892
case SERIAL_WAIT_ON_MASK:
427
/* XXX implement me */
893
DEBUG_SERIAL(("serial_ioctl -> SERIAL_WAIT_ON_MASK %X\n",
894
pser_inf->wait_mask));
895
pser_inf->event_pending = 1;
896
if (serial_get_event(handle, &result))
898
DEBUG_SERIAL(("WAIT end event = %x\n", result));
899
out_uint32_le(out, result);
902
return STATUS_PENDING;
429
904
case SERIAL_SET_BREAK_ON:
430
tcsendbreak(serial_fd, 0);
433
in_uint32(purge_mask);
905
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_ON\n"));
906
tcsendbreak(handle, 0);
436
908
case SERIAL_RESET_DEVICE:
909
DEBUG_SERIAL(("serial_ioctl -> SERIAL_RESET_DEVICE\n"));
437
911
case SERIAL_SET_BREAK_OFF:
912
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_OFF\n"));
440
914
case SERIAL_SET_XOFF:
915
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XOFF\n"));
441
917
case SERIAL_SET_XON:
918
DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XON\n"));
919
tcflow(handle, TCION);
447
922
unimpl("SERIAL IOCTL %d\n", request);
448
923
return STATUS_INVALID_PARAMETER;