diff --git a/headers/os/drivers/tty/tty_module.h b/headers/os/drivers/tty/tty_module.h index 3229e87059..3993242129 100644 --- a/headers/os/drivers/tty/tty_module.h +++ b/headers/os/drivers/tty/tty_module.h @@ -39,6 +39,7 @@ typedef bool (*tty_service_func)(struct tty *tty, uint32 op, void *buffer, #define TTYSETDTR 6 /* bool dataTerminalReady */ #define TTYSETRTS 7 /* bool requestToSend */ #define TTYGETSIGNALS 8 /* call tty_hardware_signal for all bits */ +#define TTYFLUSH 9 /* clear input and/or output buffers */ typedef struct tty_module_info tty_module_info; diff --git a/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.cpp b/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.cpp index 7e482db3e5..b473831329 100644 --- a/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.cpp +++ b/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.cpp @@ -359,6 +359,19 @@ SerialDevice::Service(struct tty *tty, uint32 op, void *buffer, size_t length) return true; } + case TTYFLUSH: + { + int directions = *(int*)buffer; + uint8 mask = 0; + if (directions & TCIFLUSH) + mask |= FCR_RX_RST; + if (directions & TCOFLUSH) + mask |= FCR_TX_RST; + // These bits clear themselves when flushing is complete + OrReg8(FCR, mask); + + return true; + } default: return false; } 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 b9c5521192..93f517fc65 100644 --- a/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp +++ b/src/add-ons/kernel/drivers/ports/usb_serial/SerialDevice.cpp @@ -274,6 +274,7 @@ SerialDevice::Service(struct tty *tty, uint32 op, void *buffer, size_t length) case TTYOSTART: case TTYOSYNC: case TTYSETBREAK: + case TTYFLUSH: TRACE("TTY other\n"); return true; } diff --git a/src/add-ons/kernel/generic/tty/tty.cpp b/src/add-ons/kernel/generic/tty/tty.cpp index 8d09fa95c6..3a8053affb 100644 --- a/src/add-ons/kernel/generic/tty/tty.cpp +++ b/src/add-ons/kernel/generic/tty/tty.cpp @@ -1810,6 +1810,28 @@ tty_control(tty_cookie* cookie, uint32 op, void* buffer, size_t length) return B_ERROR; } + + case TCFLSH: + { + int value; + if (user_memcpy(&value, buffer, sizeof(value)) != B_OK) + return B_BAD_ADDRESS; + if (value & TCOFLUSH) { + struct tty* otherTTY = cookie->other_tty; + if (otherTTY->open_count <= 0) + return B_ERROR; + + clear_line_buffer(otherTTY->input_buffer); + } + + if (value & TCIFLUSH) + clear_line_buffer(tty->input_buffer); + + if (tty->service_func(tty, TTYFLUSH, &value, sizeof(value))) + return B_OK; + + return B_ERROR; + } } TRACE(("tty: unsupported opcode %lu\n", op));