Encapsulate serial config in dedicated structure
This commit is contained in:
parent
34364df689
commit
8c8e269906
5 changed files with 62 additions and 50 deletions
|
@ -26,27 +26,30 @@
|
||||||
#include <grub/list.h>
|
#include <grub/list.h>
|
||||||
|
|
||||||
struct grub_serial_port;
|
struct grub_serial_port;
|
||||||
|
struct grub_serial_config;
|
||||||
|
|
||||||
struct grub_serial_driver
|
struct grub_serial_driver
|
||||||
{
|
{
|
||||||
grub_err_t (*configure) (struct grub_serial_port *port,
|
grub_err_t (*configure) (struct grub_serial_port *port,
|
||||||
unsigned speed,
|
struct grub_serial_config *config);
|
||||||
unsigned short word_len,
|
|
||||||
unsigned int parity,
|
|
||||||
unsigned short stop_bits);
|
|
||||||
int (*fetch) (struct grub_serial_port *port);
|
int (*fetch) (struct grub_serial_port *port);
|
||||||
void (*put) (struct grub_serial_port *port, const int c);
|
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
|
||||||
{
|
{
|
||||||
struct grub_serial_port *next;
|
struct grub_serial_port *next;
|
||||||
char *name;
|
char *name;
|
||||||
unsigned speed;
|
|
||||||
unsigned short word_len;
|
|
||||||
unsigned int parity;
|
|
||||||
unsigned short stop_bits;
|
|
||||||
struct grub_serial_driver *driver;
|
struct grub_serial_driver *driver;
|
||||||
|
struct grub_serial_config config;
|
||||||
int configured;
|
int configured;
|
||||||
/* This should be void *data but since serial is useful as an early console
|
/* This should be void *data but since serial is useful as an early console
|
||||||
when malloc isn't available it's a union.
|
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
|
static inline grub_err_t
|
||||||
grub_serial_config_defaults (struct grub_serial_port *port)
|
grub_serial_config_defaults (struct grub_serial_port *port)
|
||||||
{
|
{
|
||||||
return port->driver->configure (port,
|
struct grub_serial_config config =
|
||||||
|
{
|
||||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
||||||
115200,
|
.speed = 115200,
|
||||||
#else
|
#else
|
||||||
9600,
|
.speed = 9600,
|
||||||
#endif
|
#endif
|
||||||
UART_8BITS_WORD, UART_NO_PARITY,
|
.word_len = UART_8BITS_WORD,
|
||||||
UART_1_STOP_BIT);
|
.parity = UART_NO_PARITY,
|
||||||
|
.stop_bits = UART_1_STOP_BIT
|
||||||
|
};
|
||||||
|
|
||||||
|
return port->driver->configure (port, &config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grub_ns8250_init (void);
|
void grub_ns8250_init (void);
|
||||||
|
|
|
@ -48,6 +48,11 @@ typedef enum
|
||||||
GRUB_USB_SPEED_HIGH
|
GRUB_USB_SPEED_HIGH
|
||||||
} grub_usb_speed_t;
|
} grub_usb_speed_t;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GRUB_USB_REQTYPE_VENDOR_OUT = 0x40
|
||||||
|
};
|
||||||
|
|
||||||
/* Call HOOK with each device, until HOOK returns non-zero. */
|
/* Call HOOK with each device, until HOOK returns non-zero. */
|
||||||
int grub_usb_iterate (int (*hook) (grub_usb_device_t dev));
|
int grub_usb_iterate (int (*hook) (grub_usb_device_t dev));
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ do_real_config (struct grub_serial_port *port)
|
||||||
if (port->configured)
|
if (port->configured)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
divisor = serial_get_divisor (port->speed);
|
divisor = serial_get_divisor (port->config.speed);
|
||||||
/* Shouldn't happen. */
|
/* Shouldn't happen. */
|
||||||
if (divisor == 0)
|
if (divisor == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -97,7 +97,8 @@ do_real_config (struct grub_serial_port *port)
|
||||||
grub_outb (divisor >> 8, port->port + UART_DLH);
|
grub_outb (divisor >> 8, port->port + UART_DLH);
|
||||||
|
|
||||||
/* Set the line status. */
|
/* 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);
|
grub_outb (status, port->port + UART_LCR);
|
||||||
|
|
||||||
/* In Yeeloong serial port has only 3 wires. */
|
/* In Yeeloong serial port has only 3 wires. */
|
||||||
|
@ -161,20 +162,15 @@ serial_hw_put (struct grub_serial_port *port, const int c)
|
||||||
macros. */
|
macros. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
serial_hw_configure (struct grub_serial_port *port,
|
serial_hw_configure (struct grub_serial_port *port,
|
||||||
unsigned speed, unsigned short word_len,
|
struct grub_serial_config *config)
|
||||||
unsigned int parity, unsigned short stop_bits)
|
|
||||||
{
|
{
|
||||||
unsigned short divisor;
|
unsigned short divisor;
|
||||||
|
|
||||||
divisor = serial_get_divisor (speed);
|
divisor = serial_get_divisor (config->speed);
|
||||||
if (divisor == 0)
|
if (divisor == 0)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed");
|
||||||
|
|
||||||
port->speed = speed;
|
port->config = *config;
|
||||||
port->word_len = word_len;
|
|
||||||
port->parity = parity;
|
|
||||||
port->stop_bits = stop_bits;
|
|
||||||
|
|
||||||
port->configured = 0;
|
port->configured = 0;
|
||||||
|
|
||||||
/* FIXME: should check if the serial terminal was found. */
|
/* FIXME: should check if the serial terminal was found. */
|
||||||
|
|
|
@ -154,10 +154,7 @@ grub_cmd_serial (grub_extcmd_t cmd, int argc, char **args)
|
||||||
char pname[40];
|
char pname[40];
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
struct grub_serial_port *port;
|
struct grub_serial_port *port;
|
||||||
signed speed = -1;
|
struct grub_serial_config config;
|
||||||
signed short word_len = -1;
|
|
||||||
signed int parity = -1;
|
|
||||||
signed short stop_bits = -1;
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
if (state[0].set)
|
if (state[0].set)
|
||||||
|
@ -184,24 +181,21 @@ grub_cmd_serial (grub_extcmd_t cmd, int argc, char **args)
|
||||||
if (!port)
|
if (!port)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown serial port");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown serial port");
|
||||||
|
|
||||||
speed = port->speed;
|
config = port->config;
|
||||||
word_len = port->word_len;
|
|
||||||
parity = port->parity;
|
|
||||||
stop_bits = port->stop_bits;
|
|
||||||
|
|
||||||
if (state[2].set)
|
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 (state[3].set)
|
||||||
{
|
{
|
||||||
if (! grub_strcmp (state[3].arg, "5"))
|
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"))
|
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"))
|
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"))
|
else if (! grub_strcmp (state[3].arg, "8"))
|
||||||
word_len = UART_8BITS_WORD;
|
config.word_len = UART_8BITS_WORD;
|
||||||
else
|
else
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad word length");
|
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 (state[4].set)
|
||||||
{
|
{
|
||||||
if (! grub_strcmp (state[4].arg, "no"))
|
if (! grub_strcmp (state[4].arg, "no"))
|
||||||
parity = UART_NO_PARITY;
|
config.parity = UART_NO_PARITY;
|
||||||
else if (! grub_strcmp (state[4].arg, "odd"))
|
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"))
|
else if (! grub_strcmp (state[4].arg, "even"))
|
||||||
parity = UART_EVEN_PARITY;
|
config.parity = UART_EVEN_PARITY;
|
||||||
else
|
else
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad parity");
|
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 (state[5].set)
|
||||||
{
|
{
|
||||||
if (! grub_strcmp (state[5].arg, "1"))
|
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"))
|
else if (! grub_strcmp (state[5].arg, "2"))
|
||||||
stop_bits = UART_2_STOP_BITS;
|
config.stop_bits = UART_2_STOP_BITS;
|
||||||
else
|
else
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad number of stop bits");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad number of stop bits");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize with new settings. */
|
/* Initialize with new settings. */
|
||||||
err = port->driver->configure (port, speed, word_len, parity, stop_bits);
|
err = port->driver->configure (port, &config);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
if (!registered)
|
if (!registered)
|
||||||
|
|
|
@ -23,12 +23,24 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/usb.h>
|
#include <grub/usb.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
real_config (struct grub_serial_port *port)
|
||||||
|
{
|
||||||
|
if (port->configured)
|
||||||
|
return;
|
||||||
|
|
||||||
|
port->configured = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Fetch a key. */
|
/* Fetch a key. */
|
||||||
static int
|
static int
|
||||||
usbserial_hw_fetch (struct grub_serial_port *port)
|
usbserial_hw_fetch (struct grub_serial_port *port)
|
||||||
{
|
{
|
||||||
char cc[3];
|
char cc[3];
|
||||||
grub_usb_err_t err;
|
grub_usb_err_t err;
|
||||||
|
|
||||||
|
real_config (port);
|
||||||
|
|
||||||
err = grub_usb_bulk_read (port->usbdev, port->in_endp->endp_addr, 2, cc);
|
err = grub_usb_bulk_read (port->usbdev, port->in_endp->endp_addr, 2, cc);
|
||||||
if (err != GRUB_USB_ERR_NAK)
|
if (err != GRUB_USB_ERR_NAK)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -45,20 +57,18 @@ static void
|
||||||
usbserial_hw_put (struct grub_serial_port *port, const int c)
|
usbserial_hw_put (struct grub_serial_port *port, const int c)
|
||||||
{
|
{
|
||||||
char cc = c;
|
char cc = c;
|
||||||
|
|
||||||
|
real_config (port);
|
||||||
|
|
||||||
grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc);
|
grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
usbserial_hw_configure (struct grub_serial_port *port,
|
usbserial_hw_configure (struct grub_serial_port *port,
|
||||||
unsigned speed, unsigned short word_len,
|
struct grub_serial_config *config)
|
||||||
unsigned int parity, unsigned short stop_bits)
|
|
||||||
{
|
{
|
||||||
port->speed = speed;
|
port->config = *config;
|
||||||
port->word_len = word_len;
|
|
||||||
port->parity = parity;
|
|
||||||
port->stop_bits = stop_bits;
|
|
||||||
|
|
||||||
port->configured = 0;
|
port->configured = 0;
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
Loading…
Reference in a new issue