Moxa UPort 1450I

Попался мне такой зверь в составе последнего ПТК. Драйвер в ядре вроде есть, но работает как-то странно. Точнее вообще не работает.

После разбирательств оказалось, что хотя железка и поддерживает режимы RS232/RS422/RS485, и даже соответствующие дефайны в драйвере присутствуют, но инициализируются порты только в RS232, а возможности изменить режим через setserial или напрямую через ioctl(TIOCSSERIAL,…) нет по причине отсутствия реализации ioctl (любых) в собственно драйвере.

Драйвера, стянутые с сайта мохи мне сразу не понравились. Лапша и оверхед, который включает в себя еще и собственную похаченую реализацию usb-serial. Ну их

Сначала думал запилилить реализацию ioctl в драйвер, но потом решил – нахер мне этот гемор, когда установить режим мне нужно только один раз, и менять его в последствии я не собираюсь.
Потому обошелся обычной опцией. Патчик, кому надо. Добавляет опцию modes – массив до 16 чисел, начальные режимы каждого из портов

--- linux/drivers/usb/serial/mxuport.c.orig     2020-09-03 12:19:28.000000000 +0300
+++ linux/drivers/usb/serial/mxuport.c     2020-09-07 09:37:25.653498042 +0300
@@ -155,6 +155,9 @@
 #define MX_UPORT_8_PORT                       BIT(2)
 #define MX_UPORT_16_PORT              BIT(3)
 
+/* initial ports modes */
+static int modes[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
 /* This structure holds all of the local port information */
 struct mxuport_port {
       u8 mcr_state;           /* Last MCR state */
@@ -1136,10 +1139,11 @@
       if (err)
               return err;
 
-  /* Set interface (RS-232) */
+  /* Set interface mode (RS-232/RS-422/RS-485) */
+  dev_info(&serial->interface->dev, "Set port %d to mode %d\n", 
+                   port->port_number, modes[port->port_number]);
       return mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_INTERFACE,
-                               MX_INT_RS232,
-                               port->port_number);
+                               modes[port->port_number], port->port_number);
 }
 
 static int mxuport_alloc_write_urb(struct usb_serial *serial,
@@ -1398,3 +1402,6 @@
 MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
 MODULE_AUTHOR("<support@moxa.com>");
 MODULE_LICENSE("GPL");
+
+module_param_array(modes, int, NULL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(modes, "Initial modes for ports (up to 16). 0 - RS232, 1 - RS485(2W), 2 - RS422, 3 - RS485(4W)");