[PATCH] serial: allow specifying baudrate to use via udev tags

Aleksander Morgado aleksander at aleksander.es
Sat Mar 11 12:15:03 UTC 2017


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
---

Hey,

How about this patch? It really is a nice thing to have when integrating non-USB RS232 modems, as we avoid requiring to stick to 57600bps when the device can work perfectly with a much higher baudrate.

---
 src/mm-base-modem.c  |   6 +++
 src/mm-port-probe.c  |  10 +++++
 src/mm-port-serial.c | 118 ++++++++++-----------------------------------------
 3 files changed, 39 insertions(+), 95 deletions(-)

diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 50717471..430ce59d 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -219,6 +219,12 @@ mm_base_modem_grab_port (MMBaseModem         *self,
                           "timed-out",
                           G_CALLBACK (serial_port_timed_out_cb),
                           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... */
     else if (g_str_equal (subsys, "net")) {
diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c
index f5dc90d2..c6c5897f 100644
--- a/src/mm-port-probe.c
+++ b/src/mm-port-probe.c
@@ -712,6 +712,11 @@ serial_probe_qcdm (MMPortProbe *self)
         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 */
     if (!mm_port_serial_open (ctx->serial, &error)) {
         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,
                       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 ();
         mm_serial_parser_v1_add_filter (parser,
                                         serial_parser_filter_cb,
diff --git a/src/mm-port-serial.c b/src/mm-port-serial.c
index 470de031..2b6b92d3 100644
--- a/src/mm-port-serial.c
+++ b/src/mm-port-serial.c
@@ -210,95 +210,13 @@ mm_port_serial_command (MMPortSerial *self,

 /*****************************************************************************/

-#if 0
-static const char *
-baud_to_string (int baud)
-{
-    const char *speed = NULL;
-
-    switch (baud) {
-    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)
+static gboolean
+parse_baudrate (guint  baudrate_num,
+                guint *out_baudrate_speed)
 {
-    int speed;
+    guint speed;

-    switch (i) {
+    switch (baudrate_num) {
     case 0:
         speed = B0;
         break;
@@ -348,11 +266,12 @@ parse_baudrate (guint i)
         speed = B460800;
         break;
     default:
-        mm_warn ("Invalid baudrate '%d'", i);
-        speed = B9600;
+        return FALSE;
     }

-    return speed;
+    if (out_baudrate_speed)
+        *out_baudrate_speed = speed;
+    return TRUE;
 }

 static int
@@ -431,16 +350,25 @@ static gboolean
 real_config_fd (MMPortSerial *self, int fd, GError **error)
 {
     struct termios stbuf, other;
-    int speed;
-    int bits;
-    int parity;
-    int stopbits;
+    guint speed;
+    gint bits;
+    gint parity;
+    gint stopbits;

     /* No setup if not a tty */
     if (mm_port_get_subsys (MM_PORT (self)) != MM_PORT_SUBSYS_TTY)
         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);
     parity = parse_parity (self->priv->parity);
     stopbits = parse_stopbits (self->priv->stopbits);
--
2.12.0


More information about the ModemManager-devel mailing list