diff --git a/include/grub/serial.h b/include/grub/serial.h index 97e97004c..7828a7c98 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -26,27 +26,30 @@ #include struct grub_serial_port; +struct grub_serial_config; struct grub_serial_driver { grub_err_t (*configure) (struct grub_serial_port *port, - unsigned speed, - unsigned short word_len, - unsigned int parity, - unsigned short stop_bits); + struct grub_serial_config *config); int (*fetch) (struct grub_serial_port *port); void (*put) (struct grub_serial_port *port, const int c); }; +struct grub_serial_config +{ + unsigned speed; + unsigned short word_len; + unsigned int parity; + unsigned short stop_bits; +}; + struct grub_serial_port { struct grub_serial_port *next; char *name; - unsigned speed; - unsigned short word_len; - unsigned int parity; - unsigned short stop_bits; struct grub_serial_driver *driver; + struct grub_serial_config config; int configured; /* This should be void *data but since serial is useful as an early console when malloc isn't available it's a union. @@ -86,15 +89,19 @@ void grub_serial_unregister (struct grub_serial_port *port); static inline grub_err_t grub_serial_config_defaults (struct grub_serial_port *port) { - return port->driver->configure (port, - + struct grub_serial_config config = + { #ifdef GRUB_MACHINE_MIPS_YEELOONG - 115200, + .speed = 115200, #else - 9600, + .speed = 9600, #endif - UART_8BITS_WORD, UART_NO_PARITY, - UART_1_STOP_BIT); + .word_len = UART_8BITS_WORD, + .parity = UART_NO_PARITY, + .stop_bits = UART_1_STOP_BIT + }; + + return port->driver->configure (port, &config); } void grub_ns8250_init (void); diff --git a/include/grub/usb.h b/include/grub/usb.h index f9c3d61ff..b3acd3c5e 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -48,6 +48,11 @@ typedef enum GRUB_USB_SPEED_HIGH } grub_usb_speed_t; +enum + { + GRUB_USB_REQTYPE_VENDOR_OUT = 0x40 + }; + /* Call HOOK with each device, until HOOK returns non-zero. */ int grub_usb_iterate (int (*hook) (grub_usb_device_t dev)); diff --git a/term/ns8250.c b/term/ns8250.c index 53e94b899..c63bc6494 100644 --- a/term/ns8250.c +++ b/term/ns8250.c @@ -81,7 +81,7 @@ do_real_config (struct grub_serial_port *port) if (port->configured) return; - divisor = serial_get_divisor (port->speed); + divisor = serial_get_divisor (port->config.speed); /* Shouldn't happen. */ if (divisor == 0) return; @@ -97,7 +97,8 @@ do_real_config (struct grub_serial_port *port) grub_outb (divisor >> 8, port->port + UART_DLH); /* Set the line status. */ - status |= (port->parity | port->word_len | port->stop_bits); + status |= (port->config.parity | port->config.word_len + | port->config.stop_bits); grub_outb (status, port->port + UART_LCR); /* In Yeeloong serial port has only 3 wires. */ @@ -161,20 +162,15 @@ serial_hw_put (struct grub_serial_port *port, const int c) macros. */ static grub_err_t serial_hw_configure (struct grub_serial_port *port, - unsigned speed, unsigned short word_len, - unsigned int parity, unsigned short stop_bits) + struct grub_serial_config *config) { unsigned short divisor; - divisor = serial_get_divisor (speed); + divisor = serial_get_divisor (config->speed); if (divisor == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed"); - port->speed = speed; - port->word_len = word_len; - port->parity = parity; - port->stop_bits = stop_bits; - + port->config = *config; port->configured = 0; /* FIXME: should check if the serial terminal was found. */ diff --git a/term/serial.c b/term/serial.c index d3b2ba143..00214cb4c 100644 --- a/term/serial.c +++ b/term/serial.c @@ -154,10 +154,7 @@ grub_cmd_serial (grub_extcmd_t cmd, int argc, char **args) char pname[40]; char *name = NULL; struct grub_serial_port *port; - signed speed = -1; - signed short word_len = -1; - signed int parity = -1; - signed short stop_bits = -1; + struct grub_serial_config config; grub_err_t err; if (state[0].set) @@ -184,24 +181,21 @@ grub_cmd_serial (grub_extcmd_t cmd, int argc, char **args) if (!port) return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown serial port"); - speed = port->speed; - word_len = port->word_len; - parity = port->parity; - stop_bits = port->stop_bits; + config = port->config; if (state[2].set) - speed = grub_strtoul (state[2].arg, 0, 0); + config.speed = grub_strtoul (state[2].arg, 0, 0); if (state[3].set) { if (! grub_strcmp (state[3].arg, "5")) - word_len = UART_5BITS_WORD; + config.word_len = UART_5BITS_WORD; else if (! grub_strcmp (state[3].arg, "6")) - word_len = UART_6BITS_WORD; + config.word_len = UART_6BITS_WORD; else if (! grub_strcmp (state[3].arg, "7")) - word_len = UART_7BITS_WORD; + config.word_len = UART_7BITS_WORD; else if (! grub_strcmp (state[3].arg, "8")) - word_len = UART_8BITS_WORD; + config.word_len = UART_8BITS_WORD; else return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad word length"); } @@ -209,11 +203,11 @@ grub_cmd_serial (grub_extcmd_t cmd, int argc, char **args) if (state[4].set) { if (! grub_strcmp (state[4].arg, "no")) - parity = UART_NO_PARITY; + config.parity = UART_NO_PARITY; else if (! grub_strcmp (state[4].arg, "odd")) - parity = UART_ODD_PARITY; + config.parity = UART_ODD_PARITY; else if (! grub_strcmp (state[4].arg, "even")) - parity = UART_EVEN_PARITY; + config.parity = UART_EVEN_PARITY; else return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad parity"); } @@ -221,15 +215,15 @@ grub_cmd_serial (grub_extcmd_t cmd, int argc, char **args) if (state[5].set) { if (! grub_strcmp (state[5].arg, "1")) - stop_bits = UART_1_STOP_BIT; + config.stop_bits = UART_1_STOP_BIT; else if (! grub_strcmp (state[5].arg, "2")) - stop_bits = UART_2_STOP_BITS; + config.stop_bits = UART_2_STOP_BITS; else return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad number of stop bits"); } /* Initialize with new settings. */ - err = port->driver->configure (port, speed, word_len, parity, stop_bits); + err = port->driver->configure (port, &config); if (err) return err; if (!registered) diff --git a/term/usbserial.c b/term/usbserial.c index e25084548..258187ff9 100644 --- a/term/usbserial.c +++ b/term/usbserial.c @@ -23,12 +23,24 @@ #include #include +static void +real_config (struct grub_serial_port *port) +{ + if (port->configured) + return; + + port->configured = 1; +} + /* Fetch a key. */ static int usbserial_hw_fetch (struct grub_serial_port *port) { char cc[3]; grub_usb_err_t err; + + real_config (port); + err = grub_usb_bulk_read (port->usbdev, port->in_endp->endp_addr, 2, cc); if (err != GRUB_USB_ERR_NAK) return -1; @@ -45,20 +57,18 @@ static void usbserial_hw_put (struct grub_serial_port *port, const int c) { char cc = c; + + real_config (port); + grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc); } /* FIXME */ static grub_err_t usbserial_hw_configure (struct grub_serial_port *port, - unsigned speed, unsigned short word_len, - unsigned int parity, unsigned short stop_bits) + struct grub_serial_config *config) { - port->speed = speed; - port->word_len = word_len; - port->parity = parity; - port->stop_bits = stop_bits; - + port->config = *config; port->configured = 0; return GRUB_ERR_NONE;