From nobody Mon Sep 28 20:50:19 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 EB575367B9C; Tue, 18 Aug 2026 03:00:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787022050; cv=none; b=uhy2MSDr8yjOXPJaZyRSSZ6uzU0lFt+8q9qeQ2lFUwHuDvPG8+uhw8ntoGwoI+3Ayjq/3ZrrBPF5c2mzbjLZBHMslWiEK7Bb4XqSUvOldqx7JTw9i5SIdGlEcYzev+R2rcIwVBDwQ3gBn+16wPtMWUfkbPfY5qbmclPkp2YXLKw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787022050; c=relaxed/simple; bh=g9XLW7UcPt4/hTN4AzgZ6uktrVB634M81KfTlI/jUrQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rtlVDEsBX3vIJqhAXAvPbHmUHiU8/Ka2sD+c3UmjFPntQntiX08oylX4mIEbfQq3RA5s8+Wzl9i529wPiW8eNQ72V+GepU9792MPhWrtf5mZV7A8Zgjrjc23Mi+dInSxoo8wPTewso/QNOTLkY5Hh7BjOZ59zbPitZPc0mE5ryY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GT3BHGwJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GT3BHGwJ" Received: by smtp.kernel.org (Postfix) with ESMTPS id AE45CC2BCF7; Tue, 18 Aug 2026 03:00:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787022049; bh=g9XLW7UcPt4/hTN4AzgZ6uktrVB634M81KfTlI/jUrQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=GT3BHGwJcRE+rSKnyl9h38PSZ9/V/9N1HTB7vSsnRb3fFkE7cZne/UpF9SmLOOmSD okKywtALR5KS3KJPR9X9+D7eVLf8O2KWZGS/Cns/MAE5IJpz0yfBDtq+sqsVR1FiRu adqMqLe3VevTagLZHbXMS/jCwKhm3hJRKQZmlGEj96tN+GzSO81zK6VyQYs3ftgniP SYpd1BSPjHD8IJ5MplqAnlWbazISOC+p78oee5ZNELGggCYZ+4jqDNXFfdeudqiNjO A5DutE7hSnVbtoq+2uruQVkWmL/ShfpYmYAxttTLcw+V68J4UyWHumJaOy6tsRMGAh V+peLn0oDg0FA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 999F6C5B572; Tue, 18 Aug 2026 03:00:49 +0000 (UTC) From: George Maraveyas via B4 Relay Date: Tue, 18 Aug 2026 04:55:20 +0200 Subject: [PATCH RFC 1/2] USB: core: add helper to queue device re-enumeration Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260818-mt7925-rfc-v1-1-284d856ac572@gmail.com> References: <20260818-mt7925-rfc-v1-0-284d856ac572@gmail.com> In-Reply-To: <20260818-mt7925-rfc-v1-0-284d856ac572@gmail.com> To: Greg Kroah-Hartman , Marcel Holtmann , Luiz Augusto von Dentz , Matthias Brugger , AngeloGioacchino Del Regno Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, George Maraveyas X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787022047; l=4731; i=george.0xfff@gmail.com; s=20260818; h=from:subject:message-id; bh=LhOMiuJkFZB8vjWmzvqH/IlXANYNGRaUBImp9cDEvUE=; b=QuWR3tLnrOCzrGaSnaIZkR2uHdWvmptm5sTiiiAiW3Eep00puYXgmpwDeEBL9c9CKl1b75KBC ehFm4F+ABGyBF/fFA7duWiUvyBMr/772ri2HcsUGsMGoXN3epiLdcpR X-Developer-Key: i=george.0xfff@gmail.com; a=ed25519; pk=Jz8kMnumjUlo1GJvJ5kdfkF3ZP8DjPbYaYQR5J8IHMI= X-Endpoint-Received: by B4 Relay for george.0xfff@gmail.com/20260818 with auth_id=960 X-Original-From: George Maraveyas Reply-To: george.0xfff@gmail.com From: George Maraveyas USB drivers can use usb_queue_reset_device() when they need USB core to reset an already enumerated device asynchronously. There is currently no driver-facing helper corresponding to usb_queue_reset_device() which allows an interface driver to ask USB core to remove the current usb_device and enumerate the physical device on the port again. The difference between the two is that a device reset continues using the existing usb_device and its current enumeration state while re-enumeration removes the existing usb_device and returns the port to the hub code, which then discovers the device again through the normal USB enumeration path. Add usb_queue_reenumerate_device() to provide this facility. The helper queues a logical disconnect on the parent hub port. hub_port_logical_disconnect() disables the port, records a logical connect-change event and queues the hub work. The hub work later disconnects the existing usb_device and, if the physical device remains connected, attempts to enumerate it again through the normal hub path. Any retries or port recovery required during the subsequent enumeration remain the responsibility of the existing hub code. usb_remove_device() cannot provide the same behaviour because it also marks the port in removed_bits. The hub connection path does not enumerate a device on a port while that bit remains set. The helper takes the device lock required by usb_hub_to_struct_hub() and holds a runtime-PM reference on the parent hub interface while the logical disconnect is queued. The helper does not decide when re-enumeration is needed. That decision remains with the calling driver. The following MT7925 Bluetooth patch is the first user of the helper. It requests re-enumeration after the controller has already enumerated successfully but later fails during Bluetooth setup and cannot be recovered by its existing reset path. Signed-off-by: George Maraveyas --- drivers/usb/core/hub.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++= ++++ include/linux/usb.h | 1 + 2 files changed, 55 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index fcac92bd7..22279d438 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -6503,6 +6503,60 @@ void usb_queue_reset_device(struct usb_interface *if= ace) } EXPORT_SYMBOL_GPL(usb_queue_reset_device); =20 +/** + * usb_queue_reenumerate_device - queue logical disconnect and re-enumerat= ion + * @iface: USB interface belonging to the device to re-enumerate + * + * Request that USB core logically disconnect the device and subsequently + * re-enumerate its parent hub port. The actual device teardown and + * re-enumeration are handled asynchronously by the hub workqueue. + * + * This is intended for failures where resetting the existing usb_device is + * insufficient and the driver needs USB core to perform a full logical + * disconnect/re-enumeration cycle. + * + * Return: 0 if re-enumeration was queued successfully, or a negative error + * code otherwise. + */ +int usb_queue_reenumerate_device(struct usb_interface *iface) +{ + struct usb_device *udev =3D interface_to_usbdev(iface); + struct usb_interface *hub_intf; + struct usb_hub *hub; + int ret; + + usb_lock_device(udev); + + if (!udev->parent || udev->state =3D=3D USB_STATE_NOTATTACHED) { + ret =3D -ENODEV; + goto out_unlock; + } + + /* + * usb_hub_to_struct_hub() requires either the hub or one of its + * children to be locked. @udev is locked above. + */ + hub =3D usb_hub_to_struct_hub(udev->parent); + if (!hub) { + ret =3D -ENODEV; + goto out_unlock; + } + + hub_intf =3D to_usb_interface(hub->intfdev); + ret =3D usb_autopm_get_interface(hub_intf); + if (ret < 0) + goto out_unlock; + + hub_port_logical_disconnect(hub, udev->portnum); + usb_autopm_put_interface(hub_intf); + ret =3D 0; + +out_unlock: + usb_unlock_device(udev); + return ret; +} +EXPORT_SYMBOL_GPL(usb_queue_reenumerate_device); + /** * usb_hub_find_child - Get the pointer of child device * attached to the port which is specified by @port1. diff --git a/include/linux/usb.h b/include/linux/usb.h index 49ab8dbb8..9841029a2 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -789,6 +789,7 @@ extern int usb_lock_device_for_reset(struct usb_device = *udev, /* USB port reset for device reinitialization */ extern int usb_reset_device(struct usb_device *dev); extern void usb_queue_reset_device(struct usb_interface *dev); +int usb_queue_reenumerate_device(struct usb_interface *iface); =20 extern struct device *usb_intf_get_dma_device(struct usb_interface *intf); =20 --=20 2.53.0 From nobody Mon Sep 28 20:50:19 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 EB610388868; Tue, 18 Aug 2026 03:00:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787022050; cv=none; b=FkR3dsrT0rUyMmQo/xQOYNxGkNCCkpGiXBHpsjSYSFnM5okKQdjbZLfThqBX4aHBPLyx9/JJrWBVkb94Dxg3jN7UOoxTnAA3o5iyozQ4dCf2pjXsCxQhj5YmZg0MIWySdOLZtAOW9UYzlzx5kejxVp2spXbZZ/L894OljVLBD80= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787022050; c=relaxed/simple; bh=lN8gr0eID1lGrFTTNUIMwNSjyBOb3TsnREZbiNkECnI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CUq8vaUfWBwKtWg9C51puEybJPRyQanNqmkTE0V6iaYLFUXSMw0L1DlZbBnwmuPAkUXOS/gnr34TnsmUUnQj7xnz9aFcPnRhJpKcFVqCxtPEYioADqZ1eTLnAWkIyhF0sfvQiTs/w51gCoGrCOqEJW9S+F4PLGBbHwRGAC4nd+k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PCg+PM7W; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PCg+PM7W" Received: by smtp.kernel.org (Postfix) with ESMTPS id BB7E2C2BCF6; Tue, 18 Aug 2026 03:00:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787022049; bh=lN8gr0eID1lGrFTTNUIMwNSjyBOb3TsnREZbiNkECnI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=PCg+PM7Wu34xP4J6pU+hUNvIEVAclWRTyQ35wJ2I8BJphLNlnrQ19zTlMmSrRMo7Z mcspFGeJhVb549bJfvEPONTECS5gsFq4Fa2atgbHYjiT7cxTj0n169oLzL7PV8+Jy8 LYp5q4FGeY6AH8uTCmRloQcLCkxjWupaE0RqSaq70WK4+ncD6YHTV8Sn5bNYBqGEVY czgUiCY/AFwl47Y2epxQodJS8RymI0y3JX9DgEduVLAlNNwjHFJqq++DyRwSkxdMn3 l2xRjBRSFv1bdD9hwROctuH7wKekAzUIK4ga3ZSP079AihIEVsjDb9lxQSaQh9PILE DUzGWhKMzOi/A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8F4EC5DF74; Tue, 18 Aug 2026 03:00:49 +0000 (UTC) From: George Maraveyas via B4 Relay Date: Tue, 18 Aug 2026 04:55:21 +0200 Subject: [PATCH RFC 2/2] Bluetooth: mt7925: recover subsystem-reset timeout through USB re-enumeration Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260818-mt7925-rfc-v1-2-284d856ac572@gmail.com> References: <20260818-mt7925-rfc-v1-0-284d856ac572@gmail.com> In-Reply-To: <20260818-mt7925-rfc-v1-0-284d856ac572@gmail.com> To: Greg Kroah-Hartman , Marcel Holtmann , Luiz Augusto von Dentz , Matthias Brugger , AngeloGioacchino Del Regno Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, George Maraveyas X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787022047; l=5329; i=george.0xfff@gmail.com; s=20260818; h=from:subject:message-id; bh=tw21DpwflFbWWZ7xCtmAWfoLs4aafF589lcKdxB+wGk=; b=Ix8UDLUTd3fPtF4Fj9V9Qd5tWoAqB0bL7oV7Wy8yEsyle2hgNl34XqyvZ4pF2vAGU+VqagctJ 6n8FspmR5/4CqOkdPqZG3dZEfv488nXnL9APzijyoGt5lNuJYL0VPI/ X-Developer-Key: i=george.0xfff@gmail.com; a=ed25519; pk=Jz8kMnumjUlo1GJvJ5kdfkF3ZP8DjPbYaYQR5J8IHMI= X-Endpoint-Received: by B4 Relay for george.0xfff@gmail.com/20260818 with auth_id=960 X-Original-From: George Maraveyas Reply-To: george.0xfff@gmail.com From: George Maraveyas The MT7925 Bluetooth controller on an ASUS ROG Strix B850-I Gaming WiFi can remain unusable after a warm reboot even though its USB function initially enumerates normally. The Bluetooth USB function on the test system is: idVendor=3D13d3, idProduct=3D3602 Manufacturer: MediaTek Inc. Product: Wireless_Device The problem was reproduced with ASUS motherboard BIOS versions 1644 and 1681. Updating from BIOS 1644 to 1681 did not change the failure. The Bluetooth firmware reported during testing was: HW/SW Version: 0x00000000 Build Time: 20260605184935 A typical Windows 11-to-Linux failure is: 1. The MT7925 USB function enumerates as 13d3:3602. 2. Bluetooth setup begins. 3. The WMT function-control command times out with -ETIMEDOUT (-110). 4. The existing MediaTek reset work runs. 5. btmtk_usb_subsys_reset() also times out. 6. Resetting the existing usb_device does not recover the controller. The relevant log contains: Bluetooth: hci0: Execution of wmt command timed out Bluetooth: hci0: Failed to send wmt func ctrl (-110) Bluetooth: hci0: MT7925 WMT func ctrl timed out (dev_id=3D0x7925), schedu= ling device reset Bluetooth: hci0: Failed to read uhw reg(-110) The WMT timeout handling and scheduling of the MediaTek reset already exist before this change. This patch begins later, inside btusb_mtk_reset(), after btmtk_usb_subsys_reset() has returned. The existing path calls btmtk_usb_subsys_reset() and then queues usb_queue_reset_device(). On the affected MT7925 the subsystem reset returns -ETIMEDOUT, and resetting the existing usb_device does not recover the controller. After btmtk_usb_subsys_reset() returns, check for an MT7925 device and an -ETIMEDOUT result. When both conditions are present, request re-enumeration through usb_queue_reenumerate_device(), added by Patch 1. If the re-enumeration request is queued successfully, clear BTMTK_HW_RESET_ACTIVE and return the original subsystem-reset error. If the request cannot be queued, report the error and continue into the existing usb_queue_reset_device() path. Other MediaTek devices and MT7925 reset results other than -ETIMEDOUT continue to use the existing recovery path unchanged. The re-enumeration request gives the MT7925 another chance to go through normal USB enumeration via the helper in Patch 1, which does this. This patch calls that helper when the MT7925 subsystem reset has timed out. Chia-Lin Kao's preceding _PRR patch is required for the port recovery used on this machine. Re-enumeration does not itself request a port power-cycle or an ACPI _PRR reset. If the re-enumerated device continues to fail during enumeration, the existing hub retry path can reach its port power-cycle, where the _PRR prerequisite supplies the ACPI reset. The _PRR prerequisite does not fix this failure by itself because the first USB enumeration has already succeeded before the WMT timeout and subsequent subsystem-reset timeout occur. A representative successful recovery was: Bluetooth: hci0: MT7925 subsystem reset timed out, requesting USB re-enum= eration usb 1-11: USB disconnect, device number 4 usb 1-11: device descriptor read/64, error -110 usb 1-11: device descriptor read/64, error -110 usb usb1-port11: attempt power cycle usb 1-11: New USB device found, idVendor=3D13d3, idProduct=3D3602 Three Windows 11-to-Linux warm restart tests recovered successfully with this series. The observed average interval from the initial WMT timeout to successful Bluetooth setup was about 70.9 seconds. Bluetooth remains unavailable during most of this interval, so recovery should not be expected immediately after usb_queue_reenumerate_device() is called. Signed-off-by: George Maraveyas --- drivers/bluetooth/btmtk.c | 4 ++++ drivers/bluetooth/btusb.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c index 66b346761..e8f02f1e3 100644 --- a/drivers/bluetooth/btmtk.c +++ b/drivers/bluetooth/btmtk.c @@ -1413,6 +1413,10 @@ int btmtk_usb_setup(struct hci_dev *hdev) err =3D btmtk_usb_hci_wmt_sync(hdev, &wmt_params); if (err < 0) { bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); + + if (dev_id =3D=3D 0x7925 && err =3D=3D -ETIMEDOUT) + btmtk_reset_sync(hdev); + return err; } =20 diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 2bae85b00..5b56c26de 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2943,6 +2943,22 @@ static int btusb_mtk_reset(struct hci_dev *hdev, voi= d *rst_data) =20 err =3D btmtk_usb_subsys_reset(hdev, btmtk_data->dev_id); =20 + if (btmtk_data->dev_id =3D=3D 0x7925 && err =3D=3D -ETIMEDOUT) { + int reenum_err; + + bt_dev_warn(hdev, + "MT7925 subsystem reset timed out, requesting USB re-enumeration"); + + reenum_err =3D usb_queue_reenumerate_device(data->intf); + if (!reenum_err) { + clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags); + return err; + } + + bt_dev_err(hdev, "Failed to queue USB re-enumeration (%d)", + reenum_err); + } + usb_queue_reset_device(data->intf); clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags); =20 --=20 2.53.0 From nobody Mon Sep 28 20:50:19 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 40062435529; Fri, 21 Aug 2026 23:38:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787355499; cv=none; b=rpE2tSy61e6SW1AtT7bWZ/EaZRw9UNLRPVPkdeiWHON9h91bltHDl+nA/jLgXEBetNC3uUsJTqMb+Dtj8QDSs1Aaf1YPjnkYgO4s8InQN5cI+JcLbmIE+LYHdbyEUOigKscMt3x6Rpe80mfB1h0/jXevtip7p1IW3gwOCRmBxxw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787355499; c=relaxed/simple; bh=rlbSOuaEzyKo5jZHsV6n7SSdJDwWMAOutuR6tIJXPhI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id: In-Reply-To:References:To:Cc; b=EWqznUHN+GOBXYyDvP3OU9S8Rf9qHyVmpFw2Z4yOMgfo/Ik80p5XlSGys7+d2/LrFWKg7AGmIGRXCsMQCU+Gwtmw+H4HwS9VsAbw2Imvd4n22N1Pzti+AAHYCqyJINZCvE8JuAtKM4s7117JF/KorHMU6HXWvhuGPjOXNZy1P4E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FUrG4kTV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FUrG4kTV" Received: by smtp.kernel.org (Postfix) with ESMTPS id C3DECC2BCB3; Fri, 21 Aug 2026 23:38:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1787355498; bh=rlbSOuaEzyKo5jZHsV6n7SSdJDwWMAOutuR6tIJXPhI=; h=From:Date:Subject:In-Reply-To:References:To:Cc:Reply-To:From; b=FUrG4kTVRofbSX4GusS4dinoTUhR3Zlq5YLIqWfW9EFBdcKP2JZUtXoaN4nWQ/sYJ 1+QutDQMnjOaO3bvwZlRcVa8bngeoYegBEq8wrepAYDieMCSoQFE8mRtl9mjuFLJG4 fsqHOf7788o6Jpq1+Ta29JClM4hH9ow6hZsRLbT7GGi2HSSEvrBR6wWWC9rqRko7N6 na9/5ZrxbVMqsJsDVjfWVc2Wcfh4glM0IYLdIIlVYlHHFTByheZF3Wr/46WlIK07jW w6dBh+r/ShK7J6MOwHDbV0MoBQNaEwK76WWeASuFyek5zelCeIhZAYwIxBbDAI0YXl xm3s3NnkZdTew== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9B288C5DF8C; Fri, 21 Aug 2026 23:38:18 +0000 (UTC) From: George Maraveyas via B4 Relay Date: Sat, 22 Aug 2026 01:37:33 +0200 Subject: [PATCH RFC v2] Bluetooth: mt7925: trigger reset on WMT timeout Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260822-mt7925-rfc-v2-1-c88e3bcf7eb8@gmail.com> X-B4-Tracking: v=1; b=H4sIAAAAAAAC/22QTW7DIBCFr2KxLhZgCBBVVaRKPUC3VRZjGCe0w U7AsVpFvnsJzbLLNz/vezM3kjEFzGTb3EjCJeQwjUWIp4a4I4wHpMEXTQQTG2a4oXHWViiaBkf R+07iwDruLSkL54RD+K5mH+T97ZXs/4r52n+im+82j7GEl2tBzY/ZiDlDRW2b50rSrNAY57rtt JJKMcopODzB2H7BtHMwTmNwcGrdFF/upj1kpEXEMJf0xjMucOhlJ/RgnVZeIZMCtLMcLShZmmB NDXgMeZ7ST/3Awmue/45dOGVUGOmN2oBTWuwOEUINQPbruv4Cg3ggnkoBAAA= X-Change-ID: 20260818-mt7925-rfc-edd34ef031d9 In-Reply-To: <20260818-mt7925-rfc-v1-0-284d856ac572@gmail.com> References: <20260818-mt7925-rfc-v1-0-284d856ac572@gmail.com> To: Alan Stern , Marcel Holtmann , Luiz Augusto von Dentz , Matthias Brugger , AngeloGioacchino Del Regno Cc: linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, Chia-Lin Kao , George Maraveyas X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787355496; l=6566; i=george.0xfff@gmail.com; s=20260818; h=from:subject:message-id; bh=eD0xVzdZ+MLHOp0LYT7FNSr4T7TwQldMA7EKYnGOfwE=; b=KzR8Sr3nxgfX34AVXTYV5vC9vEHxjKPdJwG4SnjP+eVVVNb4Lr3dDHZ9AHC9kLB0seaa6bQhE xikvwO/kzEFCglAqfeeihvlm/BkmqyUPUoFtKYgTO0XaWAzFqK7PRDp X-Developer-Key: i=george.0xfff@gmail.com; a=ed25519; pk=Jz8kMnumjUlo1GJvJ5kdfkF3ZP8DjPbYaYQR5J8IHMI= X-Endpoint-Received: by B4 Relay for george.0xfff@gmail.com/20260818 with auth_id=960 X-Original-From: George Maraveyas Reply-To: george.0xfff@gmail.com From: George Maraveyas The MT7925 Bluetooth USB function can enumerate successfully after a warm reboot while the WMT function-control command remains unresponsive. When that command times out, btmtk_usb_setup() currently returns -ETIMEDOUT without entering the existing MediaTek reset path. The existing USB reset and recovery machinery is therefore never reached. For MT7925, call btmtk_reset_sync() when the WMT function-control command times out. This enters the existing reset path in btusb_mtk_reset(), which performs the MediaTek subsystem reset and queues a USB device reset. Runtime tracing on the affected hardware showed the resulting path through usb_queue_reset_device(), usb_reset_device() and usb_reset_and_verify_device(). When reset and verification could not restore the device, the USB core escalated to a logical disconnect and re-enumeration. Recovery succeeded in three controlled Windows-to-Linux tests. Runtime tracing showed the existing USB reset path escalating to logical disconnect and re-enumeration. In two of those tests, tracing continued through the subsequent enumeration failures and directly captured usb_acpi_port_prr_reset(), after which the MT7925 re-enumerated and Bluetooth recovered. These tests were performed on top of Chia-Lin Kao's ACPI _PRR hub patch, which remains a prerequisite for this patch. A fourth Windows-to-Linux test was then performed with the diagnostic btusb blacklist removed and btusb binding normally during boot. The WMT timeout reproduced and Bluetooth recovered automatically without manual intervention. Signed-off-by: George Maraveyas --- Dear Alan, Thank you for taking the time to look into my patch and for pointing me towards the existing reset path. I have now traced the failure on the affected MT7925 hardware and tested the individual parts separately. You were correct that a new USB re-enumeration helper is unnecessary. Once the MT7925 failure is made to enter the existing reset path, I can see: btmtk_reset_sync() -> btmtk_usb_subsys_reset() -> usb_queue_reset_device() -> usb_reset_device() -> usb_reset_and_verify_device() When reset and verification cannot restore the device, usb_reset_and_verify_device() eventually reaches: hub_port_logical_disconnect() and normal hub re-enumeration follows. I have therefore dropped the proposed USB helper from v1. The problem I found is earlier in the Bluetooth path. When MT7925 WMT FUNC_CTRL times out, btmtk_usb_setup() currently returns -ETIMEDOUT without entering the existing MediaTek reset machinery. The revised patch now consists only of the part of my original submission that makes this timeout enter the existing reset path: if (dev_id =3D=3D 0x7925 && err =3D=3D -ETIMEDOUT) btmtk_reset_sync(hdev); I tested this both with and without Chia-Lin Kao's _PRR hub patch. I want to stress that this v2 is based on and dependent on Kao's patch; that remains the configuration in which I have validated recovery. Kao's patch alone does not recover this failure because the WMT timeout never enters the reset path. With the WMT trigger but without Kao's patch, the reset/disconnect/re-enumeration sequence started, but the device did not recover in that test. With Kao's patch plus the WMT trigger, I reproduced and recovered the Windows-to-Linux failure in three controlled tests. Runtime tracing showed the existing reset path escalating through usb_queue_reset_device(), usb_reset_and_verify_device() and hub_port_logical_disconnect(). In two of those runs, tracing continued through the subsequent enumeration failures and directly captured: usb_acpi_port_prr_reset() <- hub_event.cold The MT7925 subsequently re-enumerated and Bluetooth recovered. I then removed the diagnostic btusb blacklist and repeated the test as a normal Windows-to-Linux restart, allowing btusb to bind automatically. The WMT command again timed out with -110 and the adapter recovered without any manual module loading or other intervention. One behavioural difference is recovery time. The original RFC, which requested logical disconnect/re-enumeration directly after the MT7925 subsystem reset timed out, recovered Bluetooth in about 71 seconds on average. Using the existing usb_queue_reset_device() path takes about 133 seconds to complete Bluetooth setup in the current tests, with successful USB re-enumeration at about 114-115 seconds. The traces account for most of that difference: usb_reset_and_verify_device() spends roughly 65 seconds attempting reset and verification before escalating to hub_port_logical_disconnect(). In practice this was long enough that, during the first test of the reduced patch, I almost concluded that recovery had failed and rebooted to start the test again before the device eventually returned. I do not think that recovery-time difference justifies retaining the new USB API, but it seemed worth mentioning because it is a noticeable behavioural difference between v1 and the reduced approach. Changes in v2: - Drop the proposed USB re-enumeration helper. - Drop the direct MT7925 re-enumeration handling which depended on it. - Reduce the series from two patches to one Bluetooth patch. - Retain only the part of the original Bluetooth patch that enters the existing reset path on an MT7925 WMT -ETIMEDOUT. - Keep Chia-Lin Kao's ACPI _PRR hub patch as a prerequisite. - Add the new runtime trace and recovery results. - Link to v1: https://patch.msgid.link/20260818-mt7925-rfc-v1-0-284d856ac57= 2@gmail.com Thanks again for the review. Kind regards, George --- drivers/bluetooth/btmtk.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c index 66b346761..e8f02f1e3 100644 --- a/drivers/bluetooth/btmtk.c +++ b/drivers/bluetooth/btmtk.c @@ -1413,6 +1413,10 @@ int btmtk_usb_setup(struct hci_dev *hdev) err =3D btmtk_usb_hci_wmt_sync(hdev, &wmt_params); if (err < 0) { bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); + + if (dev_id =3D=3D 0x7925 && err =3D=3D -ETIMEDOUT) + btmtk_reset_sync(hdev); + return err; } =20 --- base-commit: 28d012efb4327f9c75d5e042a7c91e9a542efa98 change-id: 20260818-mt7925-rfc-edd34ef031d9 prerequisite-message-id: <20260706080117.3754550-1-acelan.kao@canonical.com> prerequisite-patch-id: 47a2729fbc473534f8ba52052b00723c54a26c17 Best regards, -- =20 George Maraveyas