#include <grub/list.h>
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_port
+struct grub_serial_config
{
- struct grub_serial_port *next;
- char *name;
unsigned speed;
unsigned short word_len;
unsigned int parity;
unsigned short stop_bits;
+};
+
+struct grub_serial_port
+{
+ struct grub_serial_port *next;
+ char *name;
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.
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);
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));
if (port->configured)
return;
- divisor = serial_get_divisor (port->speed);
+ divisor = serial_get_divisor (port->config.speed);
/* Shouldn't happen. */
if (divisor == 0)
return;
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. */
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. */
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)
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");
}
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");
}
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)
#include <grub/mm.h>
#include <grub/usb.h>
+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;
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;