From 9f8acdaa5d333d43210f92a1aabc2b3c9998c9e9 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Fri, 8 Nov 2013 18:20:20 +0100 Subject: [PATCH] * grub-core/term/serial.c: Add option for enabling/disabling RTS/CTS flow control. --- ChangeLog | 5 +++++ grub-core/bus/usb/serial/ftdi.c | 6 ++++-- grub-core/bus/usb/serial/pl2303.c | 2 +- grub-core/term/efi/serial.c | 4 ++++ grub-core/term/ns8250.c | 26 ++++++++++++++------------ grub-core/term/serial.c | 15 ++++++++++++++- include/grub/efi/api.h | 3 ++- include/grub/serial.h | 4 ++++ 8 files changed, 48 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84c65799e..ae852e156 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-11-08 Vladimir Serbinenko + + * b/grub-core/term/serial.c: Add option for enabling/disabling + RTS/CTS flow control. + 2013-11-08 Vladimir Serbinenko * grub-core/lib/libgcrypt/cipher/idea.c (mul_inv): Remove signed diff --git a/grub-core/bus/usb/serial/ftdi.c b/grub-core/bus/usb/serial/ftdi.c index 25c1d6f32..1a99cba17 100644 --- a/grub-core/bus/usb/serial/ftdi.c +++ b/grub-core/bus/usb/serial/ftdi.c @@ -91,11 +91,13 @@ real_config (struct grub_serial_port *port) grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, GRUB_FTDI_MODEM_CTRL, - GRUB_FTDI_MODEM_CTRL_DTRRTS, 0, 0, 0); + port->config.rtscts ? GRUB_FTDI_MODEM_CTRL_DTRRTS : 0, + 0, 0, 0); grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, GRUB_FTDI_FLOW_CTRL, - GRUB_FTDI_FLOW_CTRL_DTRRTS, 0, 0, 0); + port->config.rtscts ? GRUB_FTDI_FLOW_CTRL_DTRRTS : 0, + 0, 0, 0); divisor = get_divisor (port->config.speed); grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, diff --git a/grub-core/bus/usb/serial/pl2303.c b/grub-core/bus/usb/serial/pl2303.c index 92b00efa8..08095622a 100644 --- a/grub-core/bus/usb/serial/pl2303.c +++ b/grub-core/bus/usb/serial/pl2303.c @@ -125,7 +125,7 @@ real_config (struct grub_serial_port *port) 0x22, 3, 0, 0, 0); grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - 1, 0, 0x61, 0, 0); + 1, 0, port->config.rtscts ? 0x61 : 0, 0, 0); port->configured = 1; } diff --git a/grub-core/term/efi/serial.c b/grub-core/term/efi/serial.c index dc5f33b40..c0911ad7b 100644 --- a/grub-core/term/efi/serial.c +++ b/grub-core/term/efi/serial.c @@ -58,6 +58,10 @@ do_real_config (struct grub_serial_port *port) stop_bits[port->config.stop_bits]); if (status != GRUB_EFI_SUCCESS) port->broken = 1; + + status = efi_call_2 (port->interface->set_control_bits, port->interface, + port->config.rtscts ? 0x4002 : 0x2); + port->configured = 1; } diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c index b428235cc..2959632a9 100644 --- a/grub-core/term/ns8250.c +++ b/grub-core/term/ns8250.c @@ -107,20 +107,22 @@ do_real_config (struct grub_serial_port *port) | stop_bits[port->config.stop_bits]); grub_outb (status, port->port + UART_LCR); - /* On Loongson machines serial port has only 3 wires. */ -#ifndef GRUB_MACHINE_MIPS_LOONGSON - /* Enable the FIFO. */ - grub_outb (UART_ENABLE_FIFO_TRIGGER1, port->port + UART_FCR); + if (port->config.rtscts) + { + /* Enable the FIFO. */ + grub_outb (UART_ENABLE_FIFO_TRIGGER1, port->port + UART_FCR); - /* Turn on DTR and RTS. */ - grub_outb (UART_ENABLE_DTRRTS, port->port + UART_MCR); -#else - /* Enable the FIFO. */ - grub_outb (UART_ENABLE_FIFO_TRIGGER14, port->port + UART_FCR); + /* Turn on DTR and RTS. */ + grub_outb (UART_ENABLE_DTRRTS, port->port + UART_MCR); + } + else + { + /* Enable the FIFO. */ + grub_outb (UART_ENABLE_FIFO_TRIGGER14, port->port + UART_FCR); - /* Turn on DTR, RTS, and OUT2. */ - grub_outb (UART_ENABLE_DTRRTS | UART_ENABLE_OUT2, port->port + UART_MCR); -#endif + /* Turn on DTR, RTS, and OUT2. */ + grub_outb (UART_ENABLE_DTRRTS | UART_ENABLE_OUT2, port->port + UART_MCR); + } /* Drain the input buffer. */ endtime = grub_get_time_ms () + 1000; diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index 2b97fcc6d..eac665c85 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -47,7 +47,8 @@ enum OPTION_WORD, OPTION_PARITY, OPTION_STOP, - OPTION_BASE_CLOCK + OPTION_BASE_CLOCK, + OPTION_RTSCTS }; /* Argument options. */ @@ -60,6 +61,7 @@ static const struct grub_arg_option options[] = {"parity", 'r', 0, N_("Set the serial port parity."), 0, ARG_TYPE_STRING}, {"stop", 't', 0, N_("Set the serial port stop bits."), 0, ARG_TYPE_INT}, {"base-clock", 'b', 0, N_("Set the base clock."), 0, ARG_TYPE_STRING}, + {"rtscts", 'f', 0, N_("Enable/disable RTS/CTS."), "on|off", ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; @@ -237,6 +239,17 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) N_("unsupported serial port parity")); } + if (state[OPTION_RTSCTS].set) + { + if (grub_strcmp (state[OPTION_PARITY].arg, "on") == 0) + config.rtscts = 1; + if (grub_strcmp (state[OPTION_PARITY].arg, "off") == 0) + config.rtscts = 0; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port flow")); + } + if (state[OPTION_STOP].set) { if (! grub_strcmp (state[OPTION_STOP].arg, "1")) diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index 69bcd0ccf..f7503406c 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -1244,7 +1244,8 @@ struct grub_efi_serial_io_interface grub_efi_parity_type_t parity, grub_uint8_t word_len, grub_efi_stop_bits_t stop_bits); - void (*set_control_bits) (void); + grub_efi_status_t (*set_control_bits) (struct grub_efi_serial_io_interface *this, + grub_efi_uint32_t flags); void (*get_control_bits) (void); grub_efi_status_t (*write) (struct grub_efi_serial_io_interface *this, grub_efi_uintn_t *buf_size, diff --git a/include/grub/serial.h b/include/grub/serial.h index 7d981f927..67379de45 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -68,6 +68,7 @@ struct grub_serial_config grub_serial_parity_t parity; grub_serial_stop_bits_t stop_bits; grub_uint64_t base_clock; + int rtscts; }; struct grub_serial_port @@ -159,8 +160,11 @@ grub_serial_config_defaults (struct grub_serial_port *port) { #ifdef GRUB_MACHINE_MIPS_LOONGSON .speed = 115200, + /* On Loongson machines serial port has only 3 wires. */ + .rtscts = 0, #else .speed = 9600, + .rtscts = 1, #endif .word_len = 8, .parity = GRUB_SERIAL_PARITY_NONE,