From: Nathan Fearnley Subject: Re: ntdll: Adds support for custom serial port baudrates on Mac Message-Id: Date: Thu, 4 Dec 2014 18:52:28 -0500 I forgot to try compiling it. I've fixed some bugs that creeped in since the last change. On 4 December 2014 at 15:50, Nathan Fearnley wrote: > I've tried to update the code to be a little more cleanly separated, and > fixed the issue with BOOL. This code really just runs as an exception when > a custom baudrate is requested. Otherwise, it pretty much shares the same > code. If someone can suggest a better way to organize the code, I'd be > happy to implement it. >
I forgot to try compiling it. I've fixed some bugs that creeped in since the last change.

On 4 December 2014 at 15:50, Nathan Fearnley <nathan.fearnley@slugsource.com> wrote:
I've tried to update the code to be a little more cleanly separated, and fixed the issue with BOOL. This code really just runs as an exception when a custom baudrate is requested. Otherwise, it pretty much shares the same code. If someone can suggest a better way to organize the code, I'd be happy to implement it.

From 24df7420606cdbfb4c9ac056d90ee40bc99a28c9 Mon Sep 17 00:00:00 2001 From: Nathan Fearnley Date: Thu, 4 Dec 2014 18:33:11 -0500 Subject: Adds support for custom serial port baudrates on Mac OS X --- dlls/ntdll/serial.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c index b03ac61..bea483d 100644 --- a/dlls/ntdll/serial.c +++ b/dlls/ntdll/serial.c @@ -81,6 +81,10 @@ #define TIOCINQ FIONREAD #endif +#if defined (__APPLE__) +#define IOSSIOSPEED 0x80045402 +#endif + WINE_DEFAULT_DEBUG_CHANNEL(comm); static const char* iocode2str(DWORD ioc) @@ -429,10 +433,65 @@ static NTSTATUS purge(int fd, DWORD flags) return STATUS_SUCCESS; } +#if defined(__APPLE__) +static BOOL is_standard_baud_rate(speed_t baud_rate) +{ + BOOL standardBaudRate = FALSE; + switch (baud_rate) + { + case 0: + case 50: + case 75: + case 110: + case 134: + case 150: + case 200: + case 300: + case 600: + case 1200: + case 1800: + case 2400: + case 4800: + case 9600: + case 19200: + case 38400: +#ifdef B57600 + case 57600: +#endif +#ifdef B115200 + case 115200: +#endif +#ifdef B230400 + case 230400: +#endif +#ifdef B460800 + case 460800: +#endif + standardBaudRate = TRUE; + default: + standardBaudRate = FALSE; + } + return standardBaudRate; +} + +static NTSTATUS set_custom_baud_rate(int fd, speed_t baud_rate) +{ + if (ioctl(fd, IOSSIOSPEED, baud_rate) == -1) + { + ERR("IOSSIOSPEED error '%s'\n", strerror(errno)); + return FILE_GetNtStatus(); + } + return STATUS_SUCCESS; +} +#endif + static NTSTATUS set_baud_rate(int fd, const SERIAL_BAUD_RATE* sbr) { struct termios port; - + #if defined (__APPLE__) + BOOL standardBaudRate = TRUE; + #endif + if (tcgetattr(fd, &port) == -1) { ERR("tcgetattr error '%s'\n", strerror(errno)); @@ -501,11 +560,20 @@ static NTSTATUS set_baud_rate(int fd, const SERIAL_BAUD_RATE* sbr) cfsetospeed( &port, B38400 ); } break; +#elif defined (__APPLE__) /* Custom Baud Rate for Mac OS X */ + standardBaudRate = FALSE; + break; #else /* Don't have linux/serial.h or lack TIOCSSERIAL */ ERR("baudrate %d\n", sbr->BaudRate); return STATUS_NOT_SUPPORTED; #endif /* Don't have linux/serial.h or lack TIOCSSERIAL */ } +#if defined (__APPLE__) /* Custom Baud Rate for Mac OS X */ + if (!standardBaudRate) + { + return set_custom_baud_rate(fd, &sbr->BaudRate); + } +#endif cfsetispeed( &port, cfgetospeed(&port) ); if (tcsetattr(fd, TCSANOW, &port) == -1) { @@ -580,11 +648,30 @@ static NTSTATUS set_handflow(int fd, const SERIAL_HANDFLOW* shf) port.c_iflag |= IXON; else port.c_iflag &= ~IXON; + + #if defined (__APPLE__) + BOOL standardBaudRate = is_standard_baud_rate(port.c_ispeed) && is_standard_baud_rate(port.c_ospeed); + speed_t customRate = 0; + if (!standardBaudRate) /* tcsetattr doesn't support custom rates, so temporarily set a standard rate */ + { + customRate = port.c_ispeed; + port.c_ispeed = 9600; + port.c_ospeed = 9600; + } + #endif + if (tcsetattr(fd, TCSANOW, &port) == -1) { ERR("tcsetattr error '%s'\n", strerror(errno)); return FILE_GetNtStatus(); } + + #if defined (__APPLE__) + if (!standardBaudRate) /* tcsetattr doesn't support custom rates, so temporarily set a standard rate */ + { + return set_custom_baud_rate(fd, customRate); + } + #endif return STATUS_SUCCESS; } @@ -692,12 +779,32 @@ static NTSTATUS set_line_control(int fd, const SERIAL_LINE_CONTROL* slc) FIXME("StopBits %d is not supported\n", stopbits); return STATUS_NOT_SUPPORTED; } + + #if defined (__APPLE__) + BOOL standardBaudRate = is_standard_baud_rate(port.c_ispeed) && is_standard_baud_rate(port.c_ospeed); + speed_t customRate = 0; + if (!standardBaudRate) /* tcsetattr doesn't support custom rates, so temporarily set a standard rate */ + { + customRate = port.c_ispeed; + port.c_ispeed = 9600; + port.c_ospeed = 9600; + } + #endif + /* otherwise it hangs with pending input*/ if (tcsetattr(fd, TCSANOW, &port) == -1) { ERR("tcsetattr error '%s'\n", strerror(errno)); return FILE_GetNtStatus(); } + + #if defined (__APPLE__) + if (!standardBaudRate) /* tcsetattr doesn't support custom rates, so temporarily set a standard rate */ + { + return set_custom_baud_rate(fd, customRate); + } + #endif + return STATUS_SUCCESS; } @@ -724,11 +831,31 @@ static NTSTATUS set_special_chars(int fd, const SERIAL_CHARS* sc) port.c_cc[VSTART] = sc->XonChar; port.c_cc[VSTOP ] = sc->XoffChar; + + #if defined (__APPLE__) + BOOL standardBaudRate = is_standard_baud_rate(port.c_ispeed) && is_standard_baud_rate(port.c_ospeed); + speed_t customRate = 0; + if (!standardBaudRate) /* tcsetattr doesn't support custom rates, so temporarily set a standard rate */ + { + customRate = port.c_ispeed; + port.c_ispeed = 9600; + port.c_ospeed = 9600; + } + #endif + if (tcsetattr(fd, TCSANOW, &port) == -1) { ERR("tcsetattr error '%s'\n", strerror(errno)); return FILE_GetNtStatus(); } + + #if defined (__APPLE__) + if (!standardBaudRate) /* tcsetattr doesn't support custom rates, so temporarily set a standard rate */ + { + return set_custom_baud_rate(fd, customRate); + } + #endif + return STATUS_SUCCESS; } -- 2.2.0