From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB3793C3F73; Mon, 17 Aug 2026 14:24:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786976693; cv=none; b=ue2FKCBE/93iBMfX7aToPNpn6GxUgaEX9HrT50pbF6NLaRcB1rD6GS90cvCwiQ3LygL77D9wOcZMaXX0kPxZLu5tv/LuCUdoroDNp5ZLkAPHjQCWY3Z1hF4ZVd7agO2tpMRFxtTZXZn4lTop1KavMeECEQK4rnqMGgbhslh0mzs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786976693; c=relaxed/simple; bh=vZ7i9quISnXynSnFA2REWDL8U7Lw1gtYYHgLkUT0P9k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fw6QcEdXr2xphiqDzPuJsFp/GgqCfM+1czoeLS1+rCsVH4m4bOJ0O1Lfp8u6lmhq3pBwSu/xatDDKP6AP47Xz8x+7EbLuuLyg8hnd95qOg1wpjhBIblIeLQUFNmOe6nSJF0CG5/QOKrJrdO/YcLyPued0jPA3ATjVzObl3U3y8A= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=SZ/VXit+; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="SZ/VXit+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2155D1F000E9; Mon, 17 Aug 2026 14:24:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1786976691; bh=URamC4OeYjRK+LwRzm4P9/WexwxS6C9vnWYeTlwahSo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=SZ/VXit+1LVniYrKh9KMme+qUY1j6uNr10sEOXWlm/KHL0a4lfZwZCCkhIcEwg0TX oMN7h3eYz5iMcvTuUVb+WPrtW/iGcUyYvYTb49xrELjoHuQTzmPtlC8kZfdB8poFKl 3Vra5rwUR9rPdglP9V+X7O6J6XlGwOo4JRiJY0PI= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Johan Hovold Subject: [PATCH 5.15 072/456] USB: serial: keyspan_pda: fix data loss on receive throttling Date: Mon, 17 Aug 2026 15:27:42 +0200 Message-ID: <20260817132542.884744319@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260817132539.792407575@linuxfoundation.org> References: <20260817132539.792407575@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Johan Hovold commit 42a97c0480f96a2977e6d51ce512adc780f1ef5d upstream. Killing the interrupt-in urb when the line disciple requests throttling may lead to data loss if an ongoing transfer is cancelled. Instead set a flag to prevent the completion handler from resubmitting the urb until the port is unthrottled. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/keyspan_pda.c | 44 +++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -35,6 +35,8 @@ struct keyspan_pda_private { struct work_struct unthrottle_work; struct usb_serial *serial; struct usb_serial_port *port; + bool throttled; + bool throttle_req; }; static int keyspan_pda_write_start(struct usb_serial_port *port); @@ -159,6 +161,7 @@ static void keyspan_pda_rx_interrupt(str int retval; int status = urb->status; struct keyspan_pda_private *priv; + bool throttled = false; unsigned long flags; priv = usb_get_serial_port_data(port); @@ -220,16 +223,24 @@ static void keyspan_pda_rx_interrupt(str } exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - dev_err(&port->dev, - "%s - usb_submit_urb failed with result %d\n", - __func__, retval); + spin_lock_irqsave(&port->lock, flags); + if (priv->throttle_req) { + priv->throttled = true; + throttled = true; + } + spin_unlock_irqrestore(&port->lock, flags); + + if (!throttled) { + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + dev_err(&port->dev, "failed to resubmit in urb: %d\n", retval); + } } static void keyspan_pda_rx_throttle(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; + struct keyspan_pda_private *priv = usb_get_serial_port_data(port); /* * Stop receiving characters. We just turn off the URB request, and @@ -239,16 +250,29 @@ static void keyspan_pda_rx_throttle(stru * send an XOFF, although it might make sense to foist that off upon * the device too. */ - usb_kill_urb(port->interrupt_in_urb); + spin_lock_irq(&port->lock); + priv->throttle_req = true; + spin_unlock_irq(&port->lock); } static void keyspan_pda_rx_unthrottle(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; + struct keyspan_pda_private *priv = usb_get_serial_port_data(port); + bool throttled; + int ret; + + spin_lock_irq(&port->lock); + throttled = priv->throttled; + priv->throttled = false; + priv->throttle_req = false; + spin_unlock_irq(&port->lock); - /* just restart the receive interrupt URB */ - if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL)) - dev_dbg(&port->dev, "usb_submit_urb(read urb) failed\n"); + if (throttled) { + ret = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (ret) + dev_err(&port->dev, "failed to submit in urb: %d\n", ret); + } } static speed_t keyspan_pda_setbaud(struct usb_serial *serial, speed_t baud) @@ -585,6 +609,8 @@ static int keyspan_pda_open(struct tty_s spin_lock_irq(&port->lock); priv->tx_room = rc; + priv->throttled = false; + priv->throttle_req = false; spin_unlock_irq(&port->lock); rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);