diff --git a/headers/posix/termios.h b/headers/posix/termios.h index 2f843111aa..3d590e67ed 100644 --- a/headers/posix/termios.h +++ b/headers/posix/termios.h @@ -9,21 +9,25 @@ #include -typedef __haiku_uint32 tcflag_t; -typedef unsigned char speed_t; +typedef __haiku_uint16 tcflag_t; +typedef __haiku_uint32 speed_t; typedef unsigned char cc_t; #define NCCS 11 /* number of control characters */ struct termios { - tcflag_t c_iflag; /* input modes */ - tcflag_t c_oflag; /* output modes */ - tcflag_t c_cflag; /* control modes */ - tcflag_t c_lflag; /* local modes */ - char c_line; /* line discipline */ - speed_t c_ispeed; /* custom input baudrate */ - speed_t c_ospeed; /* custom output baudrate */ - cc_t c_cc[NCCS]; /* control characters */ + tcflag_t c_iflag; /* input modes */ + tcflag_t c_ispeed; /* input baudrate */ + tcflag_t c_oflag; /* output modes */ + tcflag_t c_ospeed; /* output baudrate */ + tcflag_t c_cflag; /* control modes */ + tcflag_t c_ispeed_high; /* high word of input baudrate */ + tcflag_t c_lflag; /* local modes */ + tcflag_t c_ospeed_high; /* high word of output baudrate */ + char c_line; /* line discipline */ + unsigned char _padding; /* unused */ + unsigned char _padding2; /* unused */ + cc_t c_cc[NCCS]; /* control characters */ }; /* control characters */ diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp b/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp index 8056983060..6000e0c99d 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp +++ b/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp @@ -160,10 +160,11 @@ SerialDevice::SetModes(struct termios *tios) TRACE_FUNCRES(trace_termios, tios); uint8 baud = tios->c_cflag & CBAUD; - int32 speed = baud_index_to_speed(baud); - if (speed < 0) { - baud = CBAUD; - speed = tios->c_ospeed; + int32 speed; + if (baud == CBAUD) { + speed = tios->c_ospeed + (tios->c_ospeed_high << 16); + } else { + speed = baud_index_to_speed(baud); } // update our master config in full diff --git a/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.cpp b/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.cpp index be3b3684fb..dfee837ae9 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.cpp +++ b/src/add-ons/kernel/drivers/ports/usb_serial/Tracing.cpp @@ -106,17 +106,18 @@ void trace_termios(struct termios *tios) { TRACE("struct termios:\n" - "\tc_iflag: 0x%08x\n" - "\tc_oflag: 0x%08x\n" - "\tc_cflag: 0x%08x\n" - "\tc_lflag: 0x%08x\n" - "\tc_line: 0x%08x\n" - "\tc_ispeed: 0x%08x\n" - "\tc_ospeed: 0x%08x\n" + "\tc_iflag: 0x%04x\n" + "\tc_oflag: 0x%04x\n" + "\tc_cflag: 0x%04x\n" + "\tc_lflag: 0x%04x\n" + "\tc_line: 0x%04x\n" + "\tc_ispeed: %u\n" + "\tc_ospeed: %u\n" "\tc_cc[0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x]\n", tios->c_iflag, tios->c_oflag, tios->c_cflag, tios->c_lflag, tios->c_line, - tios->c_ispeed, tios->c_ospeed, + tios->c_ispeed + ((uint32_t)tios->c_ispeed_high << 16), + tios->c_ospeed + (tios->c_ospeed_high << 16), tios->c_cc[0], tios->c_cc[1], tios->c_cc[2], tios->c_cc[3], tios->c_cc[4], tios->c_cc[5], tios->c_cc[6], tios->c_cc[7], tios->c_cc[8], tios->c_cc[9], tios->c_cc[10]); diff --git a/src/add-ons/kernel/generic/tty/module.cpp b/src/add-ons/kernel/generic/tty/module.cpp index d9f501251c..830400e86e 100644 --- a/src/add-ons/kernel/generic/tty/module.cpp +++ b/src/add-ons/kernel/generic/tty/module.cpp @@ -28,17 +28,19 @@ dump_tty_settings(struct tty_settings& settings) kprintf(" session_id: %" B_PRId32 "\n", settings.session_id); kprintf(" termios:\n"); - kprintf(" c_iflag: 0x%08" B_PRIx32 "\n", settings.termios.c_iflag); - kprintf(" c_oflag: 0x%08" B_PRIx32 "\n", settings.termios.c_oflag); - kprintf(" c_cflag: 0x%08" B_PRIx32 "\n", settings.termios.c_cflag); - kprintf(" c_lflag: 0x%08" B_PRIx32 "\n", settings.termios.c_lflag); - kprintf(" c_line: %d\n", settings.termios.c_line); - kprintf(" c_ispeed: %u\n", settings.termios.c_ispeed); - kprintf(" c_ospeed: %u\n", settings.termios.c_ospeed); + kprintf(" c_iflag: 0x%08" B_PRIx32 "\n", settings.termios.c_iflag); + kprintf(" c_oflag: 0x%08" B_PRIx32 "\n", settings.termios.c_oflag); + kprintf(" c_cflag: 0x%08" B_PRIx32 "\n", settings.termios.c_cflag); + kprintf(" c_lflag: 0x%08" B_PRIx32 "\n", settings.termios.c_lflag); + kprintf(" c_line: %d\n", settings.termios.c_line); + kprintf(" c_ispeed: %u\n", settings.termios.c_ispeed + + ((uint32_t)settings.termios.c_ispeed_high << 16)); + kprintf(" c_ospeed: %u\n", settings.termios.c_ospeed + + ((uint32_t)settings.termios.c_ospeed_high << 16)); for (int i = 0; i < NCCS; i++) - kprintf(" c_cc[%02d]: %d\n", i, settings.termios.c_cc[i]); + kprintf(" c_cc[%02d]: %d\n", i, settings.termios.c_cc[i]); - kprintf(" wsize: %u x %u c, %u x %u pxl\n", + kprintf(" wsize: %u x %u c, %u x %u pxl\n", settings.window_size.ws_row, settings.window_size.ws_col, settings.window_size.ws_xpixel, settings.window_size.ws_ypixel); } diff --git a/src/add-ons/kernel/generic/tty/tty.cpp b/src/add-ons/kernel/generic/tty/tty.cpp index ddae54a01c..dea650b6e8 100644 --- a/src/add-ons/kernel/generic/tty/tty.cpp +++ b/src/add-ons/kernel/generic/tty/tty.cpp @@ -760,8 +760,10 @@ reset_termios(struct termios& termios) termios.c_cflag = B19200 | CS8 | CREAD | HUPCL; // enable receiver, hang up on last close termios.c_lflag = ECHO | ISIG | ICANON; - termios.c_ispeed = B19200; - termios.c_ospeed = B19200; + termios.c_ispeed = 0; + termios.c_ospeed = 0; + termios.c_ispeed_high = 0; + termios.c_ospeed_high = 0; // control characters termios.c_cc[VINTR] = CTRL('C'); diff --git a/src/libs/bsd/termios.c b/src/libs/bsd/termios.c index 1049aeea6a..0513b33f25 100644 --- a/src/libs/bsd/termios.c +++ b/src/libs/bsd/termios.c @@ -11,12 +11,14 @@ int cfsetspeed(struct termios *termios, speed_t speed) { - /* Custom speed values are stored in c_ispeed and c_ospeed. + /* Custom values are stored in two parts for ABI compatibility reasons. * Standard values are inlined in c_cflag. */ if (speed > B31250) { termios->c_cflag |= CBAUD; - termios->c_ispeed = speed; - termios->c_ospeed = speed; + termios->c_ospeed = speed & 0xFFFF; + termios->c_ospeed_high = speed >> 16; + termios->c_ispeed = termios->c_ospeed; + termios->c_ispeed_high = termios->c_ospeed_high; return 0; } diff --git a/src/system/libroot/posix/termios.c b/src/system/libroot/posix/termios.c index ce0ebed5f4..8b2e949fea 100644 --- a/src/system/libroot/posix/termios.c +++ b/src/system/libroot/posix/termios.c @@ -106,7 +106,7 @@ speed_t cfgetispeed(const struct termios *termios) { if ((termios->c_cflag & CBAUD) == CBAUD) - return termios->c_ispeed; + return termios->c_ispeed + ((uint32_t)termios->c_ispeed_high << 16); return termios->c_cflag & CBAUD; } @@ -121,7 +121,8 @@ cfsetispeed(struct termios *termios, speed_t speed) detected only when the tcsetattr() function is called */ if (speed > B31250) { termios->c_cflag |= CBAUD; - termios->c_ispeed = speed; + termios->c_ispeed = speed & 0xFFFF; + termios->c_ispeed_high = speed >> 16; return 0; } @@ -135,7 +136,7 @@ speed_t cfgetospeed(const struct termios *termios) { if ((termios->c_cflag & CBAUD) == CBAUD) - return termios->c_ospeed; + return termios->c_ospeed + ((uint32_t)termios->c_ospeed_high << 16); return termios->c_cflag & CBAUD; } @@ -147,7 +148,8 @@ cfsetospeed(struct termios *termios, speed_t speed) /* Check for custom speed values (see above) */ if (speed > B31250) { termios->c_cflag |= CBAUD; - termios->c_ospeed = speed; + termios->c_ospeed = speed & 0xFFFF; + termios->c_ospeed_high = speed >> 16; return 0; }