Problems with the serial interface

Reinhard Karcher rkarcher at
Sat Dec 30 02:34:55 CST 2006

Hello wine developers,

the attached patch fixes some issues I had with the 16 bit configuration
program for our SOHO PBX.

- The first fix corrects the logic for SERIAL_DTR_CONTROL. If it is
  *cleared*, TIOCM_DTR has to be released and if it is *set* TIOCM_DTR
  has to be asserted. The way I have rewritten it is based on the
  style of condition used for RTS some line below.
- The second fix I am not really sure about, but checking for
  DSR_HANDSHAKE does not really make sense to me when the coded
  guarded by that is just about RTS.
  I suppose it is meant to not toggle the RTS line when CRTSCTS is
  in effect, as on unix one cannot toggle RTS and CTS handshaking
  on its own.
- The third fix removes a delaying issue, as the mentioned application
  calls GetCommError16 twice per character received (via ReadComm16
  with a buffer size of 1), which causes a delay of 20 ms per
  character, as long as no further characters arrive. Because the
  (Visual Basic) application is so slow that it does not keep up with
  the PBX sending date, the one-line responses are received much more
  quickly than the program reads the characters from the buffer; during
  emptying the buffer no further characters arrive.
  I don't really get the point of sleeping at that point at all, but
  suppose it is a hack against busy-waiting. This hack can be safely
  disabled if characters are in the input buffer.
- The fourth fix prevents the timeout value "0" be interpreted as "timeout
  now" instead of "timeout never", as it is meant to be. This bug broke
  the asynchronous reads on the serial port.

Michael Karcher

diff -ur ../wine-0.9.28/dlls/ntdll/serial.c ../wine-0.9.28n/dlls/ntdll/serial.c
--- ../wine-0.9.28/dlls/ntdll/serial.c	2006-11-25 12:00:22.000000000 +0100
+++ ../wine-0.9.28n/dlls/ntdll/serial.c	2006-12-28 18:21:54.000000000 +0100
@@ -595,13 +595,13 @@
     if (shf->ControlHandShake & SERIAL_DTR_HANDSHAKE)
         WARN("DSR/DTR flow control not supported\n");
-    } else if (shf->ControlHandShake & SERIAL_DTR_CONTROL)
+    } else if ((shf->ControlHandShake & SERIAL_DTR_CONTROL) == 0)
         whack_modem(fd, ~TIOCM_DTR, 0);
         whack_modem(fd, 0, TIOCM_DTR);
 #ifdef TIOCM_RTS
-    if (!(shf->ControlHandShake & SERIAL_DSR_HANDSHAKE))
+    if (!(shf->ControlHandShake & SERIAL_CTS_HANDSHAKE))
         if ((shf->FlowReplace & (SERIAL_RTS_CONTROL|SERIAL_RTS_HANDSHAKE)) == 0)
             whack_modem(fd, ~TIOCM_RTS, 0);
diff -ur ../wine-0.9.28/dlls/user32/comm16.c ../wine-0.9.28n/dlls/user32/comm16.c
--- ../wine-0.9.28/dlls/user32/comm16.c	2006-11-25 12:00:23.000000000 +0100
+++ ../wine-0.9.28n/dlls/user32/comm16.c	2006-12-28 19:25:45.000000000 +0100
@@ -722,7 +722,8 @@
 	if (lpStat) {
 		lpStat->status = 0;
-		SleepEx(1,TRUE);
+		if (comm_inbuf(ptr) == 0)
+			SleepEx(1,TRUE);
 		lpStat->cbOutQue = comm_outbuf(ptr);
 		lpStat->cbInQue = comm_inbuf(ptr);
diff -ur ../wine-0.9.28/server/serial.c ../wine-0.9.28n/server/serial.c
--- ../wine-0.9.28/server/serial.c	2006-11-25 12:00:23.000000000 +0100
+++ ../wine-0.9.28n/server/serial.c	2006-12-28 15:48:43.000000000 +0100
@@ -272,7 +272,7 @@
     add_timeout( &when, timeout );
-    if (!create_async( current, &when, queue, apc, user, iosb )) return;
+    if (!create_async( current, timeout ? &when : NULL, queue, apc, user, iosb )) return;
     /* Check if the new pending request can be served immediately */
     events = check_fd_events( fd, serial_get_poll_events( fd ) );

More information about the wine-patches mailing list