From patchwork Fri May 27 22:27:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Mychaela N. Falconia" X-Patchwork-Id: 577043 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70057C433F5 for ; Fri, 27 May 2022 22:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354143AbiE0Wgo (ORCPT ); Fri, 27 May 2022 18:36:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55124 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229996AbiE0Wgn (ORCPT ); Fri, 27 May 2022 18:36:43 -0400 Received: from freecalypso.org (freecalypso.org [195.154.163.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52CFE2408A; Fri, 27 May 2022 15:36:42 -0700 (PDT) Received: by freecalypso.org (Postfix, from userid 1001) id 1AC8837401F1; Fri, 27 May 2022 22:27:09 +0000 (UTC) From: "Mychaela N. Falconia" To: Johan Hovold , Greg Kroah-Hartman , Jiri Slaby Cc: linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, mychaela.falconia@gmail.com Subject: [PATCH 1/6] tty: add port flag to suppress raising DTR & RTS on open Message-Id: <20220527222709.1AC8837401F1@freecalypso.org> Date: Fri, 27 May 2022 22:27:08 +0000 (UTC) Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org There exist special serial devices (either attaching to generic serial ports or containing a built-in USB-serial chip) in which DTR and/or RTS have been repurposed for non-standard uses. Depending on exactly how these signals are repurposed, standard POSIX/SUS behaviour of unconditionally raising both signals on open may range from harmless to undesirable to a total killer, precluding the use of Linux with such custom hardware. The newly added TTY_PORT_MANUAL_RTSDTR flag switches an individual serial port from POSIX/SUS standard to non-standard behaviour: when set, it suppresses the built-in action of raising DTR & RTS on serial port open. This flag can be exported through sysfs, and it can also be set by USB-serial device drivers when they see a custom hw device (identified by VID:PID) that is known to be wired in a way that requires this flag to be set. Co-developed-by: Johan Hovold Signed-off-by: Johan Hovold Signed-off-by: Mychaela N. Falconia --- drivers/tty/tty_port.c | 2 +- include/linux/tty_port.h | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 880608a65773..59f1c49bb23c 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -441,7 +441,7 @@ EXPORT_SYMBOL(tty_port_carrier_raised); */ void tty_port_raise_dtr_rts(struct tty_port *port) { - if (port->ops->dtr_rts) + if (port->ops->dtr_rts && !tty_port_manual_rtsdtr(port)) port->ops->dtr_rts(port, 1); } EXPORT_SYMBOL(tty_port_raise_dtr_rts); diff --git a/include/linux/tty_port.h b/include/linux/tty_port.h index 58e9619116b7..9e5ad46d8a53 100644 --- a/include/linux/tty_port.h +++ b/include/linux/tty_port.h @@ -133,6 +133,7 @@ struct tty_port { #define TTY_PORT_CHECK_CD 4 /* carrier detect enabled */ #define TTY_PORT_KOPENED 5 /* device exclusively opened by kernel */ +#define TTY_PORT_MANUAL_RTSDTR 6 /* do not raise DTR & RTS on open */ void tty_port_init(struct tty_port *port); void tty_port_link_device(struct tty_port *port, struct tty_driver *driver, @@ -226,6 +227,16 @@ static inline void tty_port_set_kopened(struct tty_port *port, bool val) assign_bit(TTY_PORT_KOPENED, &port->iflags, val); } +static inline bool tty_port_manual_rtsdtr(const struct tty_port *port) +{ + return test_bit(TTY_PORT_MANUAL_RTSDTR, &port->iflags); +} + +static inline void tty_port_set_manual_rtsdtr(struct tty_port *port, bool val) +{ + assign_bit(TTY_PORT_MANUAL_RTSDTR, &port->iflags, val); +} + struct tty_struct *tty_port_tty_get(struct tty_port *port); void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); int tty_port_carrier_raised(struct tty_port *port); From patchwork Fri May 27 22:27:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Mychaela N. Falconia" X-Patchwork-Id: 577042 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 983E9C4332F for ; Fri, 27 May 2022 22:36:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354815AbiE0Wgq (ORCPT ); Fri, 27 May 2022 18:36:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354787AbiE0Wgo (ORCPT ); Fri, 27 May 2022 18:36:44 -0400 Received: from freecalypso.org (freecalypso.org [195.154.163.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC71C255AF; Fri, 27 May 2022 15:36:42 -0700 (PDT) Received: by freecalypso.org (Postfix, from userid 1001) id A369E3740211; Fri, 27 May 2022 22:27:13 +0000 (UTC) From: "Mychaela N. Falconia" To: Johan Hovold , Greg Kroah-Hartman , Jiri Slaby Cc: linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, mychaela.falconia@gmail.com Subject: [PATCH 2/6] serial: core: add sysfs attribute to suppress raising DTR & RTS on open Message-Id: <20220527222713.A369E3740211@freecalypso.org> Date: Fri, 27 May 2022 22:27:13 +0000 (UTC) Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Add a manual_rtsdtr sysfs attribute to suppress automatic raising of DTR and RTS modem control signals on serial port open. This special mode can be used to prevent undesirable side effects on open for applications where these lines are used for non-standard purposes such as generating power-on and reset pulses. Co-developed-by: Johan Hovold Signed-off-by: Johan Hovold Signed-off-by: Mychaela N. Falconia --- Documentation/ABI/testing/sysfs-tty | 10 ++++++++++ drivers/tty/serial/serial_core.c | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index 820e412d38a8..3e666538451b 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -161,3 +161,13 @@ Contact: Andy Shevchenko Description: Allows user to detach or attach back the given device as kernel console. It shows and accepts a boolean variable. + +What: /sys/class/tty/tty/manual_rtsdtr +Date: May 2022 +Contact: Mychaela N. Falconia +Description: + Writing 1 into this flag attribute suppresses automatic + assertion of DTR & RTS on serial port open, putting these + signals under manual control (TIOCMBIS & TIOCMBIC). + Writing 0 restores standard POSIX/SUS behaviour of + automatically asserting both DTR and RTS on open. diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 9a85b41caa0a..b47004a3fb77 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2870,6 +2870,31 @@ static ssize_t console_store(struct device *dev, return ret < 0 ? ret : count; } +static ssize_t manual_rtsdtr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tty_port *port = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", tty_port_manual_rtsdtr(port)); +} + +static ssize_t manual_rtsdtr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct tty_port *port = dev_get_drvdata(dev); + bool val; + int ret; + + ret = kstrtobool(buf, &val); + if (ret) + return ret; + + tty_port_set_manual_rtsdtr(port, val); + + return count; +} + static DEVICE_ATTR_RO(uartclk); static DEVICE_ATTR_RO(type); static DEVICE_ATTR_RO(line); @@ -2884,6 +2909,7 @@ static DEVICE_ATTR_RO(io_type); static DEVICE_ATTR_RO(iomem_base); static DEVICE_ATTR_RO(iomem_reg_shift); static DEVICE_ATTR_RW(console); +static DEVICE_ATTR_RW(manual_rtsdtr); static struct attribute *tty_dev_attrs[] = { &dev_attr_uartclk.attr, @@ -2900,6 +2926,7 @@ static struct attribute *tty_dev_attrs[] = { &dev_attr_iomem_base.attr, &dev_attr_iomem_reg_shift.attr, &dev_attr_console.attr, + &dev_attr_manual_rtsdtr.attr, NULL }; From patchwork Fri May 27 22:27:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Mychaela N. Falconia" X-Patchwork-Id: 576807 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9BB74C43219 for ; Fri, 27 May 2022 22:36:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354787AbiE0Wgs (ORCPT ); Fri, 27 May 2022 18:36:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55198 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354806AbiE0Wgo (ORCPT ); Fri, 27 May 2022 18:36:44 -0400 Received: from freecalypso.org (freecalypso.org [195.154.163.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC87326AE8; Fri, 27 May 2022 15:36:42 -0700 (PDT) Received: by freecalypso.org (Postfix, from userid 1001) id A21433740218; Fri, 27 May 2022 22:27:18 +0000 (UTC) From: "Mychaela N. Falconia" To: Johan Hovold , Greg Kroah-Hartman , Jiri Slaby Cc: linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, mychaela.falconia@gmail.com Subject: [PATCH 3/6] serial: core: fully suppress raising DTR & RTS on open if manual_rtsdtr Message-Id: <20220527222718.A21433740218@freecalypso.org> Date: Fri, 27 May 2022 22:27:18 +0000 (UTC) Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org When manual_rtsdtr sysfs attribute is written as 1, TTY_PORT_MANUAL_RTSDTR is set, and the call to raise DTR & RTS in tty_port_raise_dtr_rts() is suppressed. However, there is one other place where these signals are also raised on open: uart_port_startup() in drivers/tty/serial/serial_core.c - this other point of raising DTR & RTS also needs to be suppressed if TTY_PORT_MANUAL_RTSDTR is set. Signed-off-by: Mychaela N. Falconia --- drivers/tty/serial/serial_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index b47004a3fb77..e5e00732e8fa 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -236,7 +236,8 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, * Setup the RTS and DTR signals once the * port is open and ready to respond. */ - if (init_hw && C_BAUD(tty)) + if (init_hw && !tty_port_manual_rtsdtr(&state->port) && + C_BAUD(tty)) uart_port_dtr_rts(uport, 1); } From patchwork Fri May 27 22:27:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Mychaela N. Falconia" X-Patchwork-Id: 576806 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72708C433F5 for ; Fri, 27 May 2022 22:36:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354819AbiE0Wgy (ORCPT ); Fri, 27 May 2022 18:36:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354809AbiE0Wgq (ORCPT ); Fri, 27 May 2022 18:36:46 -0400 Received: from freecalypso.org (freecalypso.org [195.154.163.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C952262130; Fri, 27 May 2022 15:36:44 -0700 (PDT) Received: by freecalypso.org (Postfix, from userid 1001) id 676313740227; Fri, 27 May 2022 22:27:23 +0000 (UTC) From: "Mychaela N. Falconia" To: Johan Hovold , Greg Kroah-Hartman , Jiri Slaby Cc: linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, mychaela.falconia@gmail.com Subject: [PATCH 4/6] USB: serial: add sysfs attribute to suppress raising DTR & RTS on open Message-Id: <20220527222723.676313740227@freecalypso.org> Date: Fri, 27 May 2022 22:27:23 +0000 (UTC) Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Add a manual_rtsdtr sysfs attribute to suppress automatic raising of DTR and RTS modem control signals on serial port open. This special mode can be used to prevent undesirable side effects on open for applications where these lines are used for non-standard purposes such as generating power-on and reset pulses. Co-developed-by: Johan Hovold Signed-off-by: Johan Hovold Signed-off-by: Mychaela N. Falconia --- drivers/usb/serial/bus.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 9e38142acd38..f1559d082fad 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -29,6 +29,38 @@ static int usb_serial_device_match(struct device *dev, return 0; } +static ssize_t manual_rtsdtr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_serial_port *port = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", tty_port_manual_rtsdtr(&port->port)); +} + +static ssize_t manual_rtsdtr_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct usb_serial_port *port = dev_get_drvdata(dev); + bool val; + int ret; + + ret = kstrtobool(buf, &val); + if (ret) + return ret; + + tty_port_set_manual_rtsdtr(&port->port, val); + + return count; +} +static DEVICE_ATTR_RW(manual_rtsdtr); + +static struct attribute *tty_attrs[] = { + &dev_attr_manual_rtsdtr.attr, + NULL +}; +ATTRIBUTE_GROUPS(tty); + static int usb_serial_device_probe(struct device *dev) { struct usb_serial_port *port = to_usb_serial_port(dev); @@ -50,8 +82,8 @@ static int usb_serial_device_probe(struct device *dev) } minor = port->minor; - tty_dev = tty_port_register_device(&port->port, usb_serial_tty_driver, - minor, dev); + tty_dev = tty_port_register_device_attr(&port->port, + usb_serial_tty_driver, minor, dev, port, tty_groups); if (IS_ERR(tty_dev)) { retval = PTR_ERR(tty_dev); goto err_port_remove; From patchwork Fri May 27 22:27:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Mychaela N. Falconia" X-Patchwork-Id: 576808 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A644C433F5 for ; Fri, 27 May 2022 22:36:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354812AbiE0Wgq (ORCPT ); Fri, 27 May 2022 18:36:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354779AbiE0Wgo (ORCPT ); Fri, 27 May 2022 18:36:44 -0400 Received: from freecalypso.org (freecalypso.org [195.154.163.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC5F724BE4; Fri, 27 May 2022 15:36:42 -0700 (PDT) Received: by freecalypso.org (Postfix, from userid 1001) id 2AB56374022D; Fri, 27 May 2022 22:27:28 +0000 (UTC) From: "Mychaela N. Falconia" To: Johan Hovold , Greg Kroah-Hartman , Jiri Slaby Cc: linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, mychaela.falconia@gmail.com Subject: [PATCH 5/6] USB: serial: ftdi_sio: pass port to quirk port_probe functions Message-Id: <20220527222728.2AB56374022D@freecalypso.org> Date: Fri, 27 May 2022 22:27:28 +0000 (UTC) Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The original code passed only the pointer to the ftdi_private struct to quirk port_probe functions. However, some quirks may need to be applied conditionally only to some channels of a multichannel FT2232x or FT4232H device, and if a given quirk's port_probe function needs to figure out which channel of a multichannel device is currently being considered, it needs access to the port pointer passed to the ftdi_sio_port_probe() function, so it can traverse USB data structures from there. Signed-off-by: Mychaela N. Falconia --- drivers/usb/serial/ftdi_sio.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 49c08f07c969..6523a36dcc45 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -88,15 +88,15 @@ struct ftdi_private { struct ftdi_sio_quirk { int (*probe)(struct usb_serial *); /* Special settings for probed ports. */ - void (*port_probe)(struct ftdi_private *); + void (*port_probe)(struct usb_serial_port *); }; static int ftdi_jtag_probe(struct usb_serial *serial); static int ftdi_NDI_device_setup(struct usb_serial *serial); static int ftdi_stmclite_probe(struct usb_serial *serial); static int ftdi_8u2232c_probe(struct usb_serial *serial); -static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); -static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); +static void ftdi_USB_UIRT_setup(struct usb_serial_port *port); +static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port); static const struct ftdi_sio_quirk ftdi_jtag_quirk = { .probe = ftdi_jtag_probe, @@ -2238,11 +2238,11 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) mutex_init(&priv->cfg_lock); - if (quirk && quirk->port_probe) - quirk->port_probe(priv); - usb_set_serial_port_data(port, priv); + if (quirk && quirk->port_probe) + quirk->port_probe(port); + ftdi_determine_type(port); ftdi_set_max_packet_size(port); if (read_latency_timer(port) < 0) @@ -2263,8 +2263,10 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) /* Setup for the USB-UIRT device, which requires hardwired * baudrate (38400 gets mapped to 312500) */ /* Called from usbserial:serial_probe */ -static void ftdi_USB_UIRT_setup(struct ftdi_private *priv) +static void ftdi_USB_UIRT_setup(struct usb_serial_port *port) { + struct ftdi_private *priv = usb_get_serial_port_data(port); + priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 77; priv->force_baud = 38400; @@ -2273,8 +2275,10 @@ static void ftdi_USB_UIRT_setup(struct ftdi_private *priv) /* Setup for the HE-TIRA1 device, which requires hardwired * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ -static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) +static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port) { + struct ftdi_private *priv = usb_get_serial_port_data(port); + priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 240; priv->force_baud = 38400; From patchwork Fri May 27 22:27:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Mychaela N. Falconia" X-Patchwork-Id: 576809 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 760C8C433EF for ; Fri, 27 May 2022 22:36:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351833AbiE0WgP (ORCPT ); Fri, 27 May 2022 18:36:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229996AbiE0WgO (ORCPT ); Fri, 27 May 2022 18:36:14 -0400 X-Greylist: delayed 527 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Fri, 27 May 2022 15:36:12 PDT Received: from freecalypso.org (freecalypso.org [195.154.163.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5D31766C96; Fri, 27 May 2022 15:36:12 -0700 (PDT) Received: by freecalypso.org (Postfix, from userid 1001) id DA00D374025E; Fri, 27 May 2022 22:27:32 +0000 (UTC) From: "Mychaela N. Falconia" To: Johan Hovold , Greg Kroah-Hartman , Jiri Slaby Cc: linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, mychaela.falconia@gmail.com Subject: [PATCH 6/6] USB: serial: ftdi_sio: add support for FreeCalypso DUART28C adapter Message-Id: <20220527222732.DA00D374025E@freecalypso.org> Date: Fri, 27 May 2022 22:27:32 +0000 (UTC) Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4 on the chip) have been repurposed to drive PWON and RESET controls on Calypso targets. The circuit is wired such that BDBUS[24] high (RTS/DTR inactive) is the normal state with Iota VRPC controls NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON the corresponding open drain control signal drivers. A special ftdi_sio driver quirk is needed in order to suppress automatic assertion of DTR & RTS on device open: this device's special PWON and RESET control drivers MUST NOT be activated when the port is ordinarily opened for plain serial communication, instead they must only be activated when a special userspace application explicitly requests such activation with a TIOCMBIS ioctl. These special userspace applications are responsible for making the needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence. The special quirk is conditionalized on the DUART28C adapter's custom USB ID, and is further limited to FT2232D Channel B only: Channel A is wired normally, with the chip's ADBUS2 and ADBUS4 outputs actually being RTS and DTR rather than something else. Signed-off-by: Mychaela N. Falconia --- drivers/usb/serial/ftdi_sio.c | 25 +++++++++++++++++++++++++ drivers/usb/serial/ftdi_sio_ids.h | 1 + 2 files changed, 26 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6523a36dcc45..49b792313378 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -97,6 +97,7 @@ static int ftdi_stmclite_probe(struct usb_serial *serial); static int ftdi_8u2232c_probe(struct usb_serial *serial); static void ftdi_USB_UIRT_setup(struct usb_serial_port *port); static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port); +static void ftdi_duart28c_setup(struct usb_serial_port *port); static const struct ftdi_sio_quirk ftdi_jtag_quirk = { .probe = ftdi_jtag_probe, @@ -122,6 +123,10 @@ static const struct ftdi_sio_quirk ftdi_8u2232c_quirk = { .probe = ftdi_8u2232c_probe, }; +static const struct ftdi_sio_quirk ftdi_duart28c_quirk = { + .port_probe = ftdi_duart28c_setup, +}; + /* * The 8U232AM has the same API as the sio except for: * - it can support MUCH higher baudrates; up to: @@ -1050,6 +1055,8 @@ static const struct usb_device_id id_table_combined[] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_DUART28C_PID), + .driver_info = (kernel_ulong_t)&ftdi_duart28c_quirk }, { } /* Terminating entry */ }; @@ -2372,6 +2379,24 @@ static int ftdi_stmclite_probe(struct usb_serial *serial) return 0; } +/* + * FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter + * with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4 + * on the chip) have been repurposed to drive PWON and RESET controls. + * + * Only Channel B is subject to the quirk - Channel A needs to retain + * standard POSIX/SUS behaviour. + */ +static void ftdi_duart28c_setup(struct usb_serial_port *port) +{ + struct usb_serial *serial = port->serial; + struct usb_interface *intf = serial->interface; + int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + + if (ifnum == 1) + tty_port_set_manual_rtsdtr(&port->port, true); +} + static void ftdi_sio_port_remove(struct usb_serial_port *port) { struct ftdi_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index d1a9564697a4..6ff2509e54a2 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -45,6 +45,7 @@ */ #define FTDI_FALCONIA_JTAG_BUF_PID 0x7150 #define FTDI_FALCONIA_JTAG_UNBUF_PID 0x7151 +#define FTDI_FALCONIA_DUART28C_PID 0x7152 /* Sienna Serial Interface by Secyourit GmbH */ #define FTDI_SIENNA_PID 0x8348