Linux wireless drivers development
 help / color / mirror / Atom feed
From: rcfa <kernel@cubiculum.net>
To: Ping-Ke Shih <pkshih@realtek.com>
Cc: linux-wireless@vger.kernel.org,
	Bitterblue Smith <rtl8821cerfe2@gmail.com>
Subject: [PATCH rtw-next] wifi: rtw89: usb: keep the endpoints until the driver lets go on unbind
Date: Sat,  7 Nov 2026 23:05:47 +0000	[thread overview]
Message-ID: <20261107230547.3673679-1-kernel@cubiculum.net> (raw)

When the driver is unbound from a device that is still attached (rmmod,
or an unbind through sysfs), usbcore disables the interface's endpoints
and kills their URBs before it calls the disconnect method, unless the
driver sets soft_unbind. rtw89_core_unregister() then still
deauthenticates, flushes the queues and stops the chip, but the bulk
endpoints that carry H2C and C2H are already gone. On an RTL8922AU with
an association, every unload logged:

  c2h reg timeout
  timed out to flush queues    (3 times)
  read HWSI is busy            (18 times)

Set soft_unbind for the USB drivers, and in rtw89_usb_disconnect()
unregister before cancelling the RX and TX URBs while the device is
still attached. After an unplug the device is gone, so the order stays
as it was; usbcore disables the endpoints first in that case (state
NOTATTACHED) whether soft_unbind is set or not.

Tested on an RTL8922AU (a USB 2 adapter) with the out-of-tree copy of
this driver (morrownr/rtw89, which carries rtw-next as of 2026-11-05),
kernels 7.1.5 and 7.2.15. Every unload while associated now logs only
the deauthentication and "deregistering interface driver", with no
warnings. A physical unplug while associated logs what it logged before
(the messages above), with no warnings and nothing stuck. Reordering
rtw89_usb_disconnect() without soft_unbind changed nothing. The other
USB chips share rtw89_usb_disconnect() but were not tested.

The problem was found with Claude Code (Claude Opus 5.5) while testing
the driver, and this change and changelog were written in the same
session.

Fixes: 2135c28be6a8 ("wifi: rtw89: Add usb.{c,h}")
Signed-off-by: rcfa <kernel@cubiculum.net>
---
 drivers/net/wireless/realtek/rtw89/rtw8851bu.c |  1 +
 drivers/net/wireless/realtek/rtw89/rtw8852au.c |  1 +
 drivers/net/wireless/realtek/rtw89/rtw8852bu.c |  1 +
 drivers/net/wireless/realtek/rtw89/rtw8852cu.c |  1 +
 drivers/net/wireless/realtek/rtw89/rtw8922au.c |  1 +
 drivers/net/wireless/realtek/rtw89/usb.c       | 17 ++++++++++++++---
 6 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851bu.c b/drivers/net/wireless/realtek/rtw89/rtw8851bu.c
index 6672ebe68f17..e89d5dd05fc8 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851bu.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851bu.c
@@ -70,6 +70,7 @@ static struct usb_driver rtw_8851bu_driver = {
 	.id_table = rtw_8851bu_id_table,
 	.probe = rtw8851bu_probe,
 	.disconnect = rtw89_usb_disconnect,
+	.soft_unbind = 1,
 };
 module_usb_driver(rtw_8851bu_driver);
 
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852au.c b/drivers/net/wireless/realtek/rtw89/rtw8852au.c
index 1a2e5dfbaab3..ef34a56f4cf9 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852au.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852au.c
@@ -84,6 +84,7 @@ static struct usb_driver rtw_8852au_driver = {
 	.id_table = rtw_8852au_id_table,
 	.probe = rtw8852au_probe,
 	.disconnect = rtw89_usb_disconnect,
+	.soft_unbind = 1,
 };
 module_usb_driver(rtw_8852au_driver);
 
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bu.c b/drivers/net/wireless/realtek/rtw89/rtw8852bu.c
index 550fc4ac7a21..9c53bc686bca 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852bu.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bu.c
@@ -84,6 +84,7 @@ static struct usb_driver rtw_8852bu_driver = {
 	.id_table = rtw_8852bu_id_table,
 	.probe = rtw8852bu_probe,
 	.disconnect = rtw89_usb_disconnect,
+	.soft_unbind = 1,
 };
 module_usb_driver(rtw_8852bu_driver);
 
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852cu.c b/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
index 2e46b05b05ee..dbc2274dfc49 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
@@ -145,6 +145,7 @@ static struct usb_driver rtw_8852cu_driver = {
 	.id_table = rtw_8852cu_id_table,
 	.probe = rtw8852cu_probe,
 	.disconnect = rtw89_usb_disconnect,
+	.soft_unbind = 1,
 };
 module_usb_driver(rtw_8852cu_driver);
 
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922au.c b/drivers/net/wireless/realtek/rtw89/rtw8922au.c
index b146bd79c675..c64bc1db1737 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922au.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922au.c
@@ -91,6 +91,7 @@ static struct usb_driver rtw_8922au_driver = {
 	.id_table = rtw_8922au_id_table,
 	.probe = rtw8922au_probe,
 	.disconnect = rtw89_usb_disconnect,
+	.soft_unbind = 1,
 };
 module_usb_driver(rtw_8922au_driver);
 
diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireless/realtek/rtw89/usb.c
index 8dc2c93e502e..435544165d5c 100644
--- a/drivers/net/wireless/realtek/rtw89/usb.c
+++ b/drivers/net/wireless/realtek/rtw89/usb.c
@@ -1314,10 +1314,21 @@ void rtw89_usb_disconnect(struct usb_interface *intf)
 	rtwdev = hw->priv;
 	rtwusb = rtw89_usb_priv(rtwdev);
 
-	rtw89_usb_cancel_rx_bufs(rtwusb);
-	rtw89_usb_cancel_tx_bufs(rtwusb);
+	/* After an unplug the device is gone, so stop the transfers first. When
+	 * the driver is unbound from a device that is still attached (rmmod),
+	 * rtw89_core_unregister() still talks to the firmware and needs the RX
+	 * transfers for the replies.
+	 */
+	if (rtwusb->udev->state == USB_STATE_NOTATTACHED) {
+		rtw89_usb_cancel_rx_bufs(rtwusb);
+		rtw89_usb_cancel_tx_bufs(rtwusb);
+		rtw89_core_unregister(rtwdev);
+	} else {
+		rtw89_core_unregister(rtwdev);
+		rtw89_usb_cancel_rx_bufs(rtwusb);
+		rtw89_usb_cancel_tx_bufs(rtwusb);
+	}
 
-	rtw89_core_unregister(rtwdev);
 	rtw89_core_deinit(rtwdev);
 	rtw89_usb_deinit_rx(rtwdev);
 	rtw89_usb_free_rx_bufs(rtwusb);

base-commit: dc16902cad9c6b08df9395a510c7be44fbab545d
-- 
2.53.0


             reply	other threads:[~2026-11-07 23:06 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-07 23:05 rcfa [this message]
2026-11-11  3:04 ` [PATCH rtw-next] wifi: rtw89: usb: keep the endpoints until the driver lets go on unbind Ping-Ke Shih

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=20261107230547.3673679-1-kernel@cubiculum.net \
    --to=kernel@cubiculum.net \
    --cc=linux-wireless@vger.kernel.org \
    --cc=pkshih@realtek.com \
    --cc=rtl8821cerfe2@gmail.com \
    /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