| From eafb27fa5283599ce6c5492ea18cf636a28222bb Mon Sep 17 00:00:00 2001 |
| From: Macpaul Lin <macpaul.lin@mediatek.com> |
| Date: Wed, 19 Dec 2018 12:11:03 +0800 |
| Subject: cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader. |
| |
| From: Macpaul Lin <macpaul.lin@mediatek.com> |
| |
| commit eafb27fa5283599ce6c5492ea18cf636a28222bb upstream. |
| |
| Mediatek Preloader is a proprietary embedded boot loader for loading |
| Little Kernel and Linux into device DRAM. |
| |
| This boot loader also handle firmware update. Mediatek Preloader will be |
| enumerated as a virtual COM port when the device is connected to Windows |
| or Linux OS via CDC-ACM class driver. When the USB enumeration has been |
| done, Mediatek Preloader will send out handshake command "READY" to PC |
| actively instead of waiting command from the download tool. |
| |
| Since Linux 4.12, the commit "tty: reset termios state on device |
| registration" (93857edd9829e144acb6c7e72d593f6e01aead66) causes Mediatek |
| Preloader receiving some abnoraml command like "READYXX" as it sent. |
| This will be recognized as an incorrect response. The behavior change |
| also causes the download handshake fail. This change only affects |
| subsequent connects if the reconnected device happens to get the same minor |
| number. |
| |
| By disabling the ECHO termios flag could avoid this problem. However, it |
| cannot be done by user space configuration when download tool open |
| /dev/ttyACM0. This is because the device running Mediatek Preloader will |
| send handshake command "READY" immediately once the CDC-ACM driver is |
| ready. |
| |
| This patch wants to fix above problem by introducing "DISABLE_ECHO" |
| property in driver_info. When Mediatek Preloader is connected, the |
| CDC-ACM driver could disable ECHO flag in termios to avoid the problem. |
| |
| Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com> |
| Cc: stable@vger.kernel.org |
| Reviewed-by: Johan Hovold <johan@kernel.org> |
| Acked-by: Oliver Neukum <oneukum@suse.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/class/cdc-acm.c | 10 ++++++++++ |
| drivers/usb/class/cdc-acm.h | 1 + |
| 2 files changed, 11 insertions(+) |
| |
| --- a/drivers/usb/class/cdc-acm.c |
| +++ b/drivers/usb/class/cdc-acm.c |
| @@ -502,6 +502,13 @@ static int acm_tty_install(struct tty_dr |
| if (retval) |
| goto error_init_termios; |
| |
| + /* |
| + * Suppress initial echoing for some devices which might send data |
| + * immediately after acm driver has been installed. |
| + */ |
| + if (acm->quirks & DISABLE_ECHO) |
| + tty->termios.c_lflag &= ~ECHO; |
| + |
| tty->driver_data = acm; |
| |
| return 0; |
| @@ -1620,6 +1627,9 @@ static const struct usb_device_id acm_id |
| { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ |
| .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
| }, |
| + { USB_DEVICE(0x0e8d, 0x2000), /* MediaTek Inc Preloader */ |
| + .driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */ |
| + }, |
| { USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */ |
| .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
| }, |
| --- a/drivers/usb/class/cdc-acm.h |
| +++ b/drivers/usb/class/cdc-acm.h |
| @@ -134,3 +134,4 @@ struct acm { |
| #define QUIRK_CONTROL_LINE_STATE BIT(6) |
| #define CLEAR_HALT_CONDITIONS BIT(7) |
| #define SEND_ZERO_PACKET BIT(8) |
| +#define DISABLE_ECHO BIT(9) |