From 4cfba8adb1ed3317c06d4d414c6820bc1b6db119 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Sep 2021 14:19:36 +0200 Subject: [PATCH] 5.10-stable patches added patches: usb-serial-cp210x-fix-dropped-characters-with-cp2102.patch --- queue-5.10/series | 1 + ...x-fix-dropped-characters-with-cp2102.patch | 124 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 queue-5.10/usb-serial-cp210x-fix-dropped-characters-with-cp2102.patch diff --git a/queue-5.10/series b/queue-5.10/series index e045e50d81b..258aba6bf77 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -98,3 +98,4 @@ spi-fix-tegra20-build-with-config_pm-n.patch edac-synopsys-fix-wrong-value-type-assignment-for-edac_mode.patch edac-dmc520-assign-the-proper-type-to-dimm-edac_mode.patch thermal-drivers-int340x-do-not-set-a-wrong-tcc-offset-on-resume.patch +usb-serial-cp210x-fix-dropped-characters-with-cp2102.patch diff --git a/queue-5.10/usb-serial-cp210x-fix-dropped-characters-with-cp2102.patch b/queue-5.10/usb-serial-cp210x-fix-dropped-characters-with-cp2102.patch new file mode 100644 index 00000000000..bfeafddfeb1 --- /dev/null +++ b/queue-5.10/usb-serial-cp210x-fix-dropped-characters-with-cp2102.patch @@ -0,0 +1,124 @@ +From c32dfec6c1c36bbbcd5d33e949d99aeb215877ec Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 22 Sep 2021 13:30:59 +0200 +Subject: USB: serial: cp210x: fix dropped characters with CP2102 + +From: Johan Hovold + +commit c32dfec6c1c36bbbcd5d33e949d99aeb215877ec upstream. + +Some CP2102 do not support event-insertion mode but return no error when +attempting to enable it. + +This means that any event escape characters in the input stream will not +be escaped by the device and consequently regular data may be +interpreted as escape sequences and be removed from the stream by the +driver. + +The reporter's device has batch number DCL00X etched into it and as +discovered by the SHA2017 Badge team, counterfeit devices with that +marking can be detected by sending malformed vendor requests. [1][2] + +Tests confirm that the possibly counterfeit CP2102 returns a single byte +in response to a malformed two-byte part-number request, while an +original CP2102 returns two bytes. Assume that every CP2102 that behaves +this way also does not support event-insertion mode (e.g. cannot report +parity errors). + +[1] https://mobile.twitter.com/sha2017badge/status/1167902087289532418 +[2] https://hackaday.com/2017/08/14/hands-on-with-the-shacamp-2017-badge/#comment-3903376 + +Reported-by: Malte Di Donato +Tested-by: Malte Di Donato +Fixes: a7207e9835a4 ("USB: serial: cp210x: add support for line-status events") +Cc: stable@vger.kernel.org # 5.9 +Link: https://lore.kernel.org/r/20210922113100.20888-1-johan@kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cp210x.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 46 insertions(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -261,6 +261,7 @@ struct cp210x_serial_private { + speed_t min_speed; + speed_t max_speed; + bool use_actual_rate; ++ bool no_event_mode; + }; + + enum cp210x_event_state { +@@ -1332,12 +1333,16 @@ static void cp210x_change_speed(struct t + + static void cp210x_enable_event_mode(struct usb_serial_port *port) + { ++ struct cp210x_serial_private *priv = usb_get_serial_data(port->serial); + struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); + int ret; + + if (port_priv->event_mode) + return; + ++ if (priv->no_event_mode) ++ return; ++ + port_priv->event_state = ES_DATA; + port_priv->event_mode = true; + +@@ -2087,6 +2092,46 @@ static void cp210x_init_max_speed(struct + priv->use_actual_rate = use_actual_rate; + } + ++static void cp2102_determine_quirks(struct usb_serial *serial) ++{ ++ struct cp210x_serial_private *priv = usb_get_serial_data(serial); ++ u8 *buf; ++ int ret; ++ ++ buf = kmalloc(2, GFP_KERNEL); ++ if (!buf) ++ return; ++ /* ++ * Some (possibly counterfeit) CP2102 do not support event-insertion ++ * mode and respond differently to malformed vendor requests. ++ * Specifically, they return one instead of two bytes when sent a ++ * two-byte part-number request. ++ */ ++ ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), ++ CP210X_VENDOR_SPECIFIC, REQTYPE_DEVICE_TO_HOST, ++ CP210X_GET_PARTNUM, 0, buf, 2, USB_CTRL_GET_TIMEOUT); ++ if (ret == 1) { ++ dev_dbg(&serial->interface->dev, ++ "device does not support event-insertion mode\n"); ++ priv->no_event_mode = true; ++ } ++ ++ kfree(buf); ++} ++ ++static void cp210x_determine_quirks(struct usb_serial *serial) ++{ ++ struct cp210x_serial_private *priv = usb_get_serial_data(serial); ++ ++ switch (priv->partnum) { ++ case CP210X_PARTNUM_CP2102: ++ cp2102_determine_quirks(serial); ++ break; ++ default: ++ break; ++ } ++} ++ + static int cp210x_attach(struct usb_serial *serial) + { + int result; +@@ -2107,6 +2152,7 @@ static int cp210x_attach(struct usb_seri + + usb_set_serial_data(serial, priv); + ++ cp210x_determine_quirks(serial); + cp210x_init_max_speed(serial); + + result = cp210x_gpio_init(serial); -- 2.47.3