serial: allow specifying baudrate to use via udev tags

A new 'ID_MM_TTY_BAUDRATE' per-port udev tag is introduced, which
allows specifying the baudrate that will be used when opening a
specific serial port.

E.g.:

    ACTION!="add|change|move", GOTO="mm_my_modem_end"
    DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.3/*", ENV{ID_MM_TTY_BAUDRATE}="115200"
    LABEL="mm_my_modem_end"

https://bugs.freedesktop.org/show_bug.cgi?id=100158
This commit is contained in:
Aleksander Morgado
2017-03-03 23:28:46 +01:00
parent 00fb9e98f6
commit 11a26f1066
3 changed files with 39 additions and 95 deletions

View File

@@ -219,6 +219,12 @@ mm_base_modem_grab_port (MMBaseModem *self,
"timed-out", "timed-out",
G_CALLBACK (serial_port_timed_out_cb), G_CALLBACK (serial_port_timed_out_cb),
self); self);
/* For serial ports, optionally use a specific baudrate */
if (mm_kernel_device_has_property (kernel_device, "ID_MM_TTY_BAUDRATE"))
g_object_set (port,
MM_PORT_SERIAL_BAUD, mm_kernel_device_get_property_as_int (kernel_device, "ID_MM_TTY_BAUDRATE"),
NULL);
} }
/* Net ports... */ /* Net ports... */
else if (g_str_equal (subsys, "net")) { else if (g_str_equal (subsys, "net")) {

View File

@@ -712,6 +712,11 @@ serial_probe_qcdm (MMPortProbe *self)
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
if (mm_kernel_device_has_property (self->priv->port, "ID_MM_TTY_BAUDRATE"))
g_object_set (ctx->serial,
MM_PORT_SERIAL_BAUD, mm_kernel_device_get_property_as_int (self->priv->port, "ID_MM_TTY_BAUDRATE"),
NULL);
/* Try to open the port */ /* Try to open the port */
if (!mm_port_serial_open (ctx->serial, &error)) { if (!mm_port_serial_open (ctx->serial, &error)) {
port_probe_task_return_error (self, port_probe_task_return_error (self,
@@ -1220,6 +1225,11 @@ serial_open_at (MMPortProbe *self)
MM_PORT_SERIAL_AT_SEND_LF, ctx->at_send_lf, MM_PORT_SERIAL_AT_SEND_LF, ctx->at_send_lf,
NULL); NULL);
if (mm_kernel_device_has_property (self->priv->port, "ID_MM_TTY_BAUDRATE"))
g_object_set (ctx->serial,
MM_PORT_SERIAL_BAUD, mm_kernel_device_get_property_as_int (self->priv->port, "ID_MM_TTY_BAUDRATE"),
NULL);
parser = mm_serial_parser_v1_new (); parser = mm_serial_parser_v1_new ();
mm_serial_parser_v1_add_filter (parser, mm_serial_parser_v1_add_filter (parser,
serial_parser_filter_cb, serial_parser_filter_cb,

View File

@@ -210,95 +210,13 @@ mm_port_serial_command (MMPortSerial *self,
/*****************************************************************************/ /*****************************************************************************/
#if 0 static gboolean
static const char * parse_baudrate (guint baudrate_num,
baud_to_string (int baud) guint *out_baudrate_speed)
{ {
const char *speed = NULL; guint speed;
switch (baud) { switch (baudrate_num) {
case B0:
speed = "0";
break;
case B50:
speed = "50";
break;
case B75:
speed = "75";
break;
case B110:
speed = "110";
break;
case B150:
speed = "150";
break;
case B300:
speed = "300";
break;
case B600:
speed = "600";
break;
case B1200:
speed = "1200";
break;
case B2400:
speed = "2400";
break;
case B4800:
speed = "4800";
break;
case B9600:
speed = "9600";
break;
case B19200:
speed = "19200";
break;
case B38400:
speed = "38400";
break;
case B57600:
speed = "57600";
break;
case B115200:
speed = "115200";
break;
case B460800:
speed = "460800";
break;
default:
break;
}
return speed;
}
void
mm_port_serial_print_config (MMPortSerial *port,
const char *detail)
{
struct termios stbuf;
int err;
err = tcgetattr (self->priv->fd, &stbuf);
if (err) {
mm_warn ("*** %s (%s): (%s) tcgetattr() error %d",
__func__, detail, mm_port_get_device (MM_PORT (port)), errno);
return;
}
mm_info ("(%s): (%s) baud rate: %d (%s)",
detail, mm_port_get_device (MM_PORT (port)),
stbuf.c_cflag & CBAUD,
baud_to_string (stbuf.c_cflag & CBAUD));
}
#endif
static int
parse_baudrate (guint i)
{
int speed;
switch (i) {
case 0: case 0:
speed = B0; speed = B0;
break; break;
@@ -348,11 +266,12 @@ parse_baudrate (guint i)
speed = B460800; speed = B460800;
break; break;
default: default:
mm_warn ("Invalid baudrate '%d'", i); return FALSE;
speed = B9600;
} }
return speed; if (out_baudrate_speed)
*out_baudrate_speed = speed;
return TRUE;
} }
static int static int
@@ -431,16 +350,25 @@ static gboolean
real_config_fd (MMPortSerial *self, int fd, GError **error) real_config_fd (MMPortSerial *self, int fd, GError **error)
{ {
struct termios stbuf, other; struct termios stbuf, other;
int speed; guint speed;
int bits; gint bits;
int parity; gint parity;
int stopbits; gint stopbits;
/* No setup if not a tty */ /* No setup if not a tty */
if (mm_port_get_subsys (MM_PORT (self)) != MM_PORT_SUBSYS_TTY) if (mm_port_get_subsys (MM_PORT (self)) != MM_PORT_SUBSYS_TTY)
return TRUE; return TRUE;
speed = parse_baudrate (self->priv->baud); mm_dbg ("(%s): setting up baudrate: %u",
mm_port_get_device (MM_PORT (self)),
self->priv->baud);
if (!parse_baudrate (self->priv->baud, &speed) || speed == B0) {
mm_warn ("(%s): baudrate invalid: %u; defaulting to 57600",
mm_port_get_device (MM_PORT (self)),
self->priv->baud);
speed = B57600;
}
bits = parse_bits (self->priv->bits); bits = parse_bits (self->priv->bits);
parity = parse_parity (self->priv->parity); parity = parse_parity (self->priv->parity);
stopbits = parse_stopbits (self->priv->stopbits); stopbits = parse_stopbits (self->priv->stopbits);