From: Jan Niehusmann Subject: Patch to fix setting USB-serial adapters to 38400 bps Bug-Debian: http://bugs.debian.org/740098 Forwarded: no Description: The following patch should fix the reported issue. . On serial ports not supporting the TIOCGSERIAL/TIOCSSERIAL mechanism, this still means that the custom baud rates do not work, but at least 38400 works, again. . Perhaps an even better fix would be switching to the newer termios2 API, as described here: https://mail.python.org/pipermail/python-list/2012-October/633871.html . That API allows setting custom baud rates on the USB serial adapters I have tested, where TIOCGSERIAL/TIOCSSERIAL was not supported. . But unfortunately, termios2 is not available through glibc, so one would need to call linux-specific ioctls directly, which wouldn't be portable at all, and I don't know how it interacts with the BSD / Hurd ports. . Therefore this is the minimal fix, for now. Upstream-Status: Pending --- a/src/SerialImp.c +++ b/src/SerialImp.c @@ -872,10 +872,14 @@ out and select baud rates 38400 then 28800 then 38400, you will get a final baud rate of 28800 because you did not update the divisor. + However, if the serial port doesn't support TIOCGSERIAL or custom speeds, + don't fail: In this case, just use B38400 and assume that there is no way + to set a custom speed on this port. + See the next ifdef below for the divisor. */ #if defined(TIOCGSERIAL) - if ( cspeed == B38400 ) + if ( cspeed == B38400 && ioctl( fd, TIOCGSERIAL, &sstruct ) == 0 ) cspeed = 38400; #endif /* TIOCGSERIAL */ if( cfsetispeed( &ttyset, cspeed ) < 0 || @@ -905,10 +909,9 @@ return(1); } sstruct.custom_divisor = ( sstruct.baud_base/cspeed ); - cspeed = B38400; #endif /* TIOCGSERIAL */ - if( cfsetispeed( &ttyset, cspeed ) < 0 || - cfsetospeed( &ttyset, cspeed ) < 0 ) + if( cfsetispeed( &ttyset, B38400 ) < 0 || + cfsetospeed( &ttyset, B38400 ) < 0 ) { /* OK, we tried everything */ report( "nativeSetSerialPortParams: Cannot Set Speed\n" ); @@ -916,8 +919,11 @@ } #if defined(TIOCSSERIAL) /* It is assumed Win32 does this for us */ + /* Ignore errors if the target speed is 38400: In this case, + * just assume TIOCSSERIAL is not supported and custom speeds are + * not available. */ if ( sstruct.baud_base < 1 || - ioctl( fd, TIOCSSERIAL, &sstruct ) < 0 ) + ioctl( fd, TIOCSSERIAL, &sstruct ) < 0 && cspeed != 38400 ) { return( 1 ); }