From 788a4ee607e8d138269fdba7c53f6f233b0e2e36 Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Sun, 19 Apr 2020 18:36:07 +0530 Subject: [PATCH 1/4] USB: serial: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in header files related to USB Serial device configuration. For C header files Documentation/process/license-rules.rst mandates C-like comments (opposed to C source files where C++ style should be used). Changes made by using a script provided by Joe Perches here: https://lkml.org/lkml/2019/2/7/46. Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Signed-off-by: Johan Hovold --- drivers/usb/serial/belkin_sa.h | 2 +- drivers/usb/serial/io_16654.h | 2 +- drivers/usb/serial/io_edgeport.h | 2 +- drivers/usb/serial/io_ionsp.h | 2 +- drivers/usb/serial/io_ti.h | 2 +- drivers/usb/serial/io_usbvend.h | 2 +- drivers/usb/serial/iuu_phoenix.h | 2 +- drivers/usb/serial/mct_u232.h | 2 +- drivers/usb/serial/oti6858.h | 2 +- drivers/usb/serial/pl2303.h | 2 +- drivers/usb/serial/visor.h | 2 +- drivers/usb/serial/whiteheat.h | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/serial/belkin_sa.h b/drivers/usb/serial/belkin_sa.h index a13a98d284f2..89ec30c63cc6 100644 --- a/drivers/usb/serial/belkin_sa.h +++ b/drivers/usb/serial/belkin_sa.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Definitions for Belkin USB Serial Adapter Driver * diff --git a/drivers/usb/serial/io_16654.h b/drivers/usb/serial/io_16654.h index 4980f72dc56f..f18501f056cf 100644 --- a/drivers/usb/serial/io_16654.h +++ b/drivers/usb/serial/io_16654.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /************************************************************************ * * 16654.H Definitions for 16C654 UART used on EdgePorts diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h index 2e7fedbaf2ff..43ba53a3a6fa 100644 --- a/drivers/usb/serial/io_edgeport.h +++ b/drivers/usb/serial/io_edgeport.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /************************************************************************ * * io_edgeport.h Edgeport Linux Interface definitions diff --git a/drivers/usb/serial/io_ionsp.h b/drivers/usb/serial/io_ionsp.h index 4b8e4823bd45..db4fce815c97 100644 --- a/drivers/usb/serial/io_ionsp.h +++ b/drivers/usb/serial/io_ionsp.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /************************************************************************ * * IONSP.H Definitions for I/O Networks Serial Protocol diff --git a/drivers/usb/serial/io_ti.h b/drivers/usb/serial/io_ti.h index 9bbcee37524e..50b899d55ed0 100644 --- a/drivers/usb/serial/io_ti.h +++ b/drivers/usb/serial/io_ti.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /***************************************************************************** * * Copyright (C) 1997-2002 Inside Out Networks, Inc. diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h index 0d1a5bb4636e..52cbc353051f 100644 --- a/drivers/usb/serial/io_usbvend.h +++ b/drivers/usb/serial/io_usbvend.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /************************************************************************ * * USBVEND.H Vendor-specific USB definitions diff --git a/drivers/usb/serial/iuu_phoenix.h b/drivers/usb/serial/iuu_phoenix.h index b400b262f72e..87992b24d904 100644 --- a/drivers/usb/serial/iuu_phoenix.h +++ b/drivers/usb/serial/iuu_phoenix.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Infinity Unlimited USB Phoenix driver * diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h index 0084edf518e8..e3d09a83cab1 100644 --- a/drivers/usb/serial/mct_u232.h +++ b/drivers/usb/serial/mct_u232.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Definitions for MCT (Magic Control Technology) USB-RS232 Converter Driver * diff --git a/drivers/usb/serial/oti6858.h b/drivers/usb/serial/oti6858.h index 1226bf2347eb..5c25836fdcd9 100644 --- a/drivers/usb/serial/oti6858.h +++ b/drivers/usb/serial/oti6858.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Ours Technology Inc. OTi-6858 USB to serial adapter driver. */ diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 52db5519aaf0..7d3090ee7e0c 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Prolific PL2303 USB to serial adaptor driver header file */ diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h index 4bd69d047036..622d639ce74e 100644 --- a/drivers/usb/serial/visor.h +++ b/drivers/usb/serial/visor.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * USB HandSpring Visor driver * diff --git a/drivers/usb/serial/whiteheat.h b/drivers/usb/serial/whiteheat.h index 269e727a92f9..7e63074c9128 100644 --- a/drivers/usb/serial/whiteheat.h +++ b/drivers/usb/serial/whiteheat.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * USB ConnectTech WhiteHEAT driver * From 986c1748c84d7727defeaeca74a73b37f7d5cce1 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Wed, 13 May 2020 16:36:46 -0500 Subject: [PATCH 2/4] USB: serial: usb_wwan: do not resubmit rx urb on fatal errors usb_wwan_indat_callback() shouldn't resubmit rx urb if the previous urb status is a fatal error. Or the usb controller would keep processing the new urbs then run into interrupt storm, and has no chance to recover. Fixes: 6c1ee66a0b2b ("USB-Serial: Fix error handling of usb_wwan") Cc: stable@vger.kernel.org Signed-off-by: Bin Liu Signed-off-by: Johan Hovold --- drivers/usb/serial/usb_wwan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 13be21aad2f4..4b9845807bee 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -270,6 +270,10 @@ static void usb_wwan_indat_callback(struct urb *urb) if (status) { dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n", __func__, status, endpoint); + + /* don't resubmit on fatal errors */ + if (status == -ESHUTDOWN || status == -ENOENT) + return; } else { if (urb->actual_length) { tty_insert_flip_string(&port->port, data, From c404bf4aa9236cb4d1068e499ae42acf48a6ff97 Mon Sep 17 00:00:00 2001 From: Michael Hanselmann Date: Tue, 31 Mar 2020 23:37:18 +0000 Subject: [PATCH 3/4] USB: serial: ch341: add basis for quirk detection A subset of CH341 devices does not support all features, namely the prescaler is limited to a reduced precision and there is no support for sending a RS232 break condition. This patch adds a detection function which will be extended to set quirk flags as they're implemented. The author's affected device has an imprint of "340" on the turquoise-colored plug, but not all such devices appear to be affected. Signed-off-by: Michael Hanselmann Link: https://lore.kernel.org/r/1e1ae0da6082bb528a44ef323d4e1d3733d38858.1585697281.git.public@hansmi.ch [ johan: use long type for quirks; rephrase and use port device for messages; handle short reads; set quirk flags directly in helper function ] Cc: stable # 5.5 Signed-off-by: Johan Hovold --- drivers/usb/serial/ch341.c | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index c5ecdcd51ffc..f2b93f4554a7 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -87,6 +87,7 @@ struct ch341_private { u8 mcr; u8 msr; u8 lcr; + unsigned long quirks; }; static void ch341_set_termios(struct tty_struct *tty, @@ -308,6 +309,53 @@ out: kfree(buffer); return r; } +static int ch341_detect_quirks(struct usb_serial_port *port) +{ + struct ch341_private *priv = usb_get_serial_port_data(port); + struct usb_device *udev = port->serial->dev; + const unsigned int size = 2; + unsigned long quirks = 0; + char *buffer; + int r; + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + /* + * A subset of CH34x devices does not support all features. The + * prescaler is limited and there is no support for sending a RS232 + * break condition. A read failure when trying to set up the latter is + * used to detect these devices. + */ + r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), CH341_REQ_READ_REG, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT); + if (r == -EPIPE) { + dev_dbg(&port->dev, "break control not supported\n"); + r = 0; + goto out; + } + + if (r != size) { + if (r >= 0) + r = -EIO; + dev_err(&port->dev, "failed to read break control: %d\n", r); + goto out; + } + + r = 0; +out: + kfree(buffer); + + if (quirks) { + dev_dbg(&port->dev, "enabling quirk flags: 0x%02lx\n", quirks); + priv->quirks |= quirks; + } + + return r; +} + static int ch341_port_probe(struct usb_serial_port *port) { struct ch341_private *priv; @@ -330,6 +378,11 @@ static int ch341_port_probe(struct usb_serial_port *port) goto error; usb_set_serial_port_data(port, priv); + + r = ch341_detect_quirks(port); + if (r < 0) + goto error; + return 0; error: kfree(priv); From c432df155919582a3cefa35a8f86256c830fa9a4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 14 May 2020 11:36:45 +0200 Subject: [PATCH 4/4] USB: serial: ch341: fix lockup of devices with limited prescaler Michael Hanselmann reports that [a] subset of all CH341 devices stop responding to bulk transfers, usually after the third byte, when the highest prescaler bit (0b100) is set. There is one exception, namely a prescaler of exactly 0b111 (fact=1, ps=3). Fix this by forcing a lower base clock (fact = 0) whenever needed. This specifically makes the standard rates 110, 134 and 200 bps work again with these devices. Fixes: 35714565089e ("USB: serial: ch341: reimplement line-speed handling") Cc: stable # 5.5 Reported-by: Michael Hanselmann Link: https://lore.kernel.org/r/20200514141743.GE25962@localhost Signed-off-by: Johan Hovold --- drivers/usb/serial/ch341.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index f2b93f4554a7..89675ee29645 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -73,6 +73,8 @@ #define CH341_LCR_CS6 0x01 #define CH341_LCR_CS5 0x00 +#define CH341_QUIRK_LIMITED_PRESCALER BIT(0) + static const struct usb_device_id id_table[] = { { USB_DEVICE(0x4348, 0x5523) }, { USB_DEVICE(0x1a86, 0x7523) }, @@ -160,9 +162,11 @@ static const speed_t ch341_min_rates[] = { * 2 <= div <= 256 if fact = 0, or * 9 <= div <= 256 if fact = 1 */ -static int ch341_get_divisor(speed_t speed) +static int ch341_get_divisor(struct ch341_private *priv) { unsigned int fact, div, clk_div; + speed_t speed = priv->baud_rate; + bool force_fact0 = false; int ps; /* @@ -188,8 +192,12 @@ static int ch341_get_divisor(speed_t speed) clk_div = CH341_CLK_DIV(ps, fact); div = CH341_CLKRATE / (clk_div * speed); + /* Some devices require a lower base clock if ps < 3. */ + if (ps < 3 && (priv->quirks & CH341_QUIRK_LIMITED_PRESCALER)) + force_fact0 = true; + /* Halve base clock (fact = 0) if required. */ - if (div < 9 || div > 255) { + if (div < 9 || div > 255 || force_fact0) { div /= 2; clk_div *= 2; fact = 0; @@ -228,7 +236,7 @@ static int ch341_set_baudrate_lcr(struct usb_device *dev, if (!priv->baud_rate) return -EINVAL; - val = ch341_get_divisor(priv->baud_rate); + val = ch341_get_divisor(priv); if (val < 0) return -EINVAL; @@ -333,6 +341,7 @@ static int ch341_detect_quirks(struct usb_serial_port *port) CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT); if (r == -EPIPE) { dev_dbg(&port->dev, "break control not supported\n"); + quirks = CH341_QUIRK_LIMITED_PRESCALER; r = 0; goto out; }