From patchwork Thu Aug 20 09:22:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 265622 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7776C433E1 for ; Thu, 20 Aug 2020 10:50:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B44D320738 for ; Thu, 20 Aug 2020 10:50:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597920635; bh=NpEfmaKHeUijj1qkQb+570DDHX861Pxw0DtZh3WCRSY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=zELmBAeH0b2KNKc5MAb8crx31rH5a3saek6mb82eRSL7mSP2X6UWQkzsJKLNWkAhP KAFt74IBt+Z1hZiKeg2cZERmD6HD1z/Vr8+SGAZyfdsmto/QELliq2gERPdu12wpR1 uP8xt6jTNyXdlMY5SGSmohArUdYsBvHtNWtnzgvU= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730727AbgHTKue (ORCPT ); Thu, 20 Aug 2020 06:50:34 -0400 Received: from mail.kernel.org ([198.145.29.99]:34456 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731239AbgHTKPQ (ORCPT ); Thu, 20 Aug 2020 06:15:16 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 416312067C; Thu, 20 Aug 2020 10:15:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597918515; bh=NpEfmaKHeUijj1qkQb+570DDHX861Pxw0DtZh3WCRSY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WY0/wYwgfZ7IbtErk94iPg/HQhQYXiRqtnFH4l/tmxE6XiBRxY/3GdpZMgIX4FITv YrPnAmWBtCaqLeiSU7urCqpsXjQZOIdci40KEzNQu3ZdPIKpVB+RY26t4wN4eeqsKR d/lc4rQb4sTeJ4ccgT2H7S3Hdz+vCVG3Ah0EZcX0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Johan Hovold , Sasha Levin Subject: [PATCH 4.14 199/228] USB: serial: ftdi_sio: fix break and sysrq handling Date: Thu, 20 Aug 2020 11:22:54 +0200 Message-Id: <20200820091617.506494293@linuxfoundation.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200820091607.532711107@linuxfoundation.org> References: <20200820091607.532711107@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Johan Hovold [ Upstream commit 733fff67941dad64b8a630450b8372b1873edc41 ] Only the last NUL in a packet should be flagged as a break character, for example, to avoid dropping unrelated characters when IGNBRK is set. Also make sysrq work by consuming the break character instead of having it immediately cancel the sysrq request, and by not processing it prematurely to avoid triggering a sysrq based on an unrelated character received in the same packet (which was received *before* the break). Note that the break flag can be left set also for a packet received immediately following a break and that and an ending NUL in such a packet will continue to be reported as a break as there's no good way to tell it apart from an actual break. Tested on FT232R and FT232H. Fixes: 72fda3ca6fc1 ("USB: serial: ftd_sio: implement sysrq handling on break") Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold Signed-off-by: Sasha Levin --- drivers/usb/serial/ftdi_sio.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8abb30c797d30..0574bf03b3171 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2045,6 +2045,7 @@ static int ftdi_process_packet(struct usb_serial_port *port, struct ftdi_private *priv, unsigned char *buf, int len) { unsigned char status; + bool brkint = false; int i; char flag; @@ -2096,13 +2097,17 @@ static int ftdi_process_packet(struct usb_serial_port *port, */ flag = TTY_NORMAL; if (buf[1] & FTDI_RS_ERR_MASK) { - /* Break takes precedence over parity, which takes precedence - * over framing errors */ - if (buf[1] & FTDI_RS_BI) { - flag = TTY_BREAK; + /* + * Break takes precedence over parity, which takes precedence + * over framing errors. Note that break is only associated + * with the last character in the buffer and only when it's a + * NUL. + */ + if (buf[1] & FTDI_RS_BI && buf[len - 1] == '\0') { port->icount.brk++; - usb_serial_handle_break(port); - } else if (buf[1] & FTDI_RS_PE) { + brkint = true; + } + if (buf[1] & FTDI_RS_PE) { flag = TTY_PARITY; port->icount.parity++; } else if (buf[1] & FTDI_RS_FE) { @@ -2118,8 +2123,13 @@ static int ftdi_process_packet(struct usb_serial_port *port, port->icount.rx += len - 2; - if (port->port.console && port->sysrq) { + if (brkint || (port->port.console && port->sysrq)) { for (i = 2; i < len; i++) { + if (brkint && i == len - 1) { + if (usb_serial_handle_break(port)) + return len - 3; + flag = TTY_BREAK; + } if (usb_serial_handle_sysrq_char(port, buf[i])) continue; tty_insert_flip_char(&port->port, buf[i], flag);