linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marc Kleine-Budde <mkl@pengutronix.de>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, kuba@kernel.org, linux-can@vger.kernel.org,
	kernel@pengutronix.de, "Stefan Mätje" <stefan.maetje@esd.eu>,
	"Marc Kleine-Budde" <mkl@pengutronix.de>
Subject: [PATCH net-next 21/48] can: esd_usb: Avoid errors triggered from USB disconnect
Date: Thu, 25 Sep 2025 14:07:58 +0200	[thread overview]
Message-ID: <20250925121332.848157-22-mkl@pengutronix.de> (raw)
In-Reply-To: <20250925121332.848157-1-mkl@pengutronix.de>

From: Stefan Mätje <stefan.maetje@esd.eu>

The USB stack calls during disconnect the esd_usb_disconnect() callback.
esd_usb_disconnect() calls netdev_unregister() for each network which
in turn calls the net_device_ops::ndo_stop callback esd_usb_close() if
the net device is up.

The esd_usb_close() callback tries to disable all CAN Ids and to reset
the CAN controller of the device sending appropriate control messages.

Sending these messages in .disconnect() is moot and always fails because
either the device is gone or the USB communication is already torn down
by the USB stack in the course of a rmmod operation.

Move the code that sends these control messages to a new function
esd_usb_stop() which is approximately the counterpart of
esd_usb_start() to make code structure less convoluted.

Then change esd_usb_close() not to send the control messages at all if
the ndo_stop() callback is executed from the USB .disconnect()
callback. Add a new flag in_usb_disconnect to the struct esd_usb
device structure to mark this condition which is checked by
esd_usb_close() whether to skip the send operations in esd_usb_start().

Signed-off-by: Stefan Mätje <stefan.maetje@esd.eu>
Link: https://patch.msgid.link/20250821143422.3567029-6-stefan.maetje@esd.eu
[mkl: minor change patch description to imperative language]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/usb/esd_usb.c | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
index 14b5df4d5543..9bc1824d7be6 100644
--- a/drivers/net/can/usb/esd_usb.c
+++ b/drivers/net/can/usb/esd_usb.c
@@ -275,6 +275,7 @@ struct esd_usb {
 	int net_count;
 	u32 version;
 	int rxinitdone;
+	int in_usb_disconnect;
 	void *rxbuf[ESD_USB_MAX_RX_URBS];
 	dma_addr_t rxbuf_dma[ESD_USB_MAX_RX_URBS];
 };
@@ -947,9 +948,9 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
 	return ret;
 }
 
-static int esd_usb_close(struct net_device *netdev)
+/* Stop interface */
+static int esd_usb_stop(struct esd_usb_net_priv *priv)
 {
-	struct esd_usb_net_priv *priv = netdev_priv(netdev);
 	union esd_usb_msg *msg;
 	int err;
 	int i;
@@ -966,8 +967,10 @@ static int esd_usb_close(struct net_device *netdev)
 	for (i = 0; i <= ESD_USB_MAX_ID_SEGMENT; i++)
 		msg->filter.mask[i] = 0;
 	err = esd_usb_send_msg(priv->usb, msg);
-	if (err < 0)
-		netdev_err(netdev, "sending idadd message failed: %pe\n", ERR_PTR(err));
+	if (err < 0) {
+		netdev_err(priv->netdev, "sending idadd message failed: %pe\n", ERR_PTR(err));
+		goto bail;
+	}
 
 	/* set CAN controller to reset mode */
 	msg->hdr.len = sizeof(struct esd_usb_set_baudrate_msg) / sizeof(u32); /* # of 32bit words */
@@ -977,7 +980,23 @@ static int esd_usb_close(struct net_device *netdev)
 	msg->setbaud.baud = cpu_to_le32(ESD_USB_NO_BAUDRATE);
 	err = esd_usb_send_msg(priv->usb, msg);
 	if (err < 0)
-		netdev_err(netdev, "sending setbaud message failed: %pe\n", ERR_PTR(err));
+		netdev_err(priv->netdev, "sending setbaud message failed: %pe\n", ERR_PTR(err));
+
+bail:
+	kfree(msg);
+
+	return err;
+}
+
+static int esd_usb_close(struct net_device *netdev)
+{
+	struct esd_usb_net_priv *priv = netdev_priv(netdev);
+	int err = 0;
+
+	if (!priv->usb->in_usb_disconnect) {
+		/* It's moot to try this in usb_disconnect()! */
+		err = esd_usb_stop(priv);
+	}
 
 	priv->can.state = CAN_STATE_STOPPED;
 
@@ -985,9 +1004,7 @@ static int esd_usb_close(struct net_device *netdev)
 
 	close_candev(netdev);
 
-	kfree(msg);
-
-	return 0;
+	return err;
 }
 
 static const struct net_device_ops esd_usb_netdev_ops = {
@@ -1357,6 +1374,7 @@ static void esd_usb_disconnect(struct usb_interface *intf)
 	usb_set_intfdata(intf, NULL);
 
 	if (dev) {
+		dev->in_usb_disconnect = 1;
 		for (i = 0; i < dev->net_count; i++) {
 			if (dev->nets[i]) {
 				netdev = dev->nets[i]->netdev;
-- 
2.51.0


  parent reply	other threads:[~2025-09-25 12:13 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-25 12:07 [PATCH net-next 0/48] pull-request: can-next 2025-09-25 Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 01/48] can: m_can: use us_to_ktime() where appropriate Marc Kleine-Budde
2025-09-26 22:01   ` patchwork-bot+netdevbpf
2025-09-25 12:07 ` [PATCH net-next 02/48] MAINTAINERS: update Vincent Mailhol's email address Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 03/48] can: dev: sort includes by alphabetical order Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 04/48] can: peak: Modification of references to email accounts being deleted Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 05/48] can: rcar_canfd: Update bit rate constants for RZ/G3E and R-Car Gen4 Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 06/48] can: rcar_canfd: Update RCANFD_CFG_* macros Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 07/48] can: rcar_canfd: Simplify nominal bit rate config Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 08/48] can: rcar_canfd: Simplify data " Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 09/48] can: rcar_can: Consistently use ndev for net_device pointers Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 10/48] can: rcar_can: Add helper variable dev to rcar_can_probe() Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 11/48] can: rcar_can: Convert to Runtime PM Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 12/48] can: rcar_can: Convert to BIT() Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 13/48] can: rcar_can: Convert to GENMASK() Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 14/48] can: rcar_can: CTLR bitfield conversion Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 15/48] can: rcar_can: TFCR " Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 16/48] can: rcar_can: BCR " Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 17/48] can: rcar_can: Mailbox " Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 18/48] can: rcar_can: Do not print alloc_candev() failures Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 19/48] can: rcar_can: Convert to %pe Marc Kleine-Budde
2025-09-25 12:07 ` [PATCH net-next 20/48] can: esd_usb: Rework display of error messages Marc Kleine-Budde
2025-09-25 12:07 ` Marc Kleine-Budde [this message]
2025-09-25 12:07 ` [PATCH net-next 22/48] can: raw: reorder struct uniqframe's members to optimise packing Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 23/48] can: raw: use bitfields to store flags in struct raw_sock Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 24/48] can: raw: reorder struct raw_sock's members to optimise packing Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 25/48] can: annotate mtu accesses with READ_ONCE() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 26/48] can: dev: turn can_set_static_ctrlmode() into a non-inline function Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 27/48] can: populate the minimum and maximum MTU values Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 28/48] can: enable CAN XL for virtual CAN devices by default Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 29/48] can: dev: move struct data_bittiming_params to linux/can/bittiming.h Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 30/48] can: dev: make can_get_relative_tdco() FD agnostic and move it to bittiming.h Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 31/48] can: netlink: document which symbols are FD specific Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 32/48] can: netlink: refactor can_validate_bittiming() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 33/48] can: netlink: add can_validate_tdc() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 34/48] can: netlink: add can_validate_databittiming() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 35/48] can: netlink: refactor CAN_CTRLMODE_TDC_{AUTO,MANUAL} flag reset logic Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 36/48] can: netlink: remove useless check in can_tdc_changelink() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 37/48] can: netlink: make can_tdc_changelink() FD agnostic Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 38/48] can: netlink: add can_dtb_changelink() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 39/48] can: netlink: add can_ctrlmode_changelink() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 40/48] can: netlink: make can_tdc_get_size() FD agnostic Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 41/48] can: netlink: add can_data_bittiming_get_size() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 42/48] can: netlink: add can_bittiming_fill_info() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 43/48] can: netlink: add can_bittiming_const_fill_info() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 44/48] can: netlink: add can_bitrate_const_fill_info() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 45/48] can: netlink: make can_tdc_fill_info() FD agnostic Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 46/48] can: calc_bittiming: make can_calc_tdco() " Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 47/48] can: dev: add can_get_ctrlmode_str() Marc Kleine-Budde
2025-09-25 12:08 ` [PATCH net-next 48/48] can: netlink: add userland error messages Marc Kleine-Budde
  -- strict thread matches above, loose matches on Subject: below --
2025-09-24  8:06 [PATCH net-next 0/48] pull-request: can-next 2025-09-24 Marc Kleine-Budde
2025-09-24  8:06 ` [PATCH net-next 21/48] can: esd_usb: Avoid errors triggered from USB disconnect Marc Kleine-Budde

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250925121332.848157-22-mkl@pengutronix.de \
    --to=mkl@pengutronix.de \
    --cc=davem@davemloft.net \
    --cc=kernel@pengutronix.de \
    --cc=kuba@kernel.org \
    --cc=linux-can@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=stefan.maetje@esd.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).