* [PATCH 1/4] Bluetooth: hci_sync: pin conn across hci_le_create_conn_sync
From: Michael Bommarito @ 2026-05-11 14:34 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, linux-bluetooth,
linux-kernel
Cc: Mat Martineau, netdev, stable, Pauli Virtanen, Aaron Esau,
Michael Bommarito
In-Reply-To: <cover.1778506829.git.michael.bommarito@gmail.com>
hci_le_create_conn_sync() runs from the cmd_sync workqueue with a
struct hci_conn pointer it interprets out of the work item's void
*data argument. The hci_conn_valid() check at function entry is a
TOCTOU: nothing prevents hci_disconn_complete_evt() (executing on
hdev->workqueue rx_work) from running between the
hci_conn_hash_lookup walk in hci_conn_valid() and the body's first
deref. hci_disconn_complete_evt() -> hci_conn_del() -> hci_conn_cleanup()
unregisters the device and drops the final kref, which kfrees the
hci_conn slot. The cmd_sync callback then writes through the freed
pointer (clear_bit on conn->flags, conn->state, the four
le_conn_*_interval fields).
A KASAN slab-use-after-free splat in cache kmalloc-8k confirms the
bug on linux-next tip commit bee6ea30c487 ("Add linux-next specific
files for 20260421") under UML+KASAN, matching the slab geometry of
the syzbot trace fixed in commit 035c25007c9e ("Bluetooth: hci_sync:
Fix UAF in le_read_features_complete").
Follow the reference-pinning pattern from commit 035c25007c9e
("Bluetooth: hci_sync: Fix UAF in le_read_features_complete") and
commit 0beddb0c380b ("Bluetooth: hci_conn: fix potential UAF in
create_big_sync"): the queue site takes a reference via
hci_conn_get() so the slot is not freed between
hci_disconn_complete_evt() retiring the conn and the cmd_sync
callback / completion handler returning. The completion handler
drops the reference on every exit path, including the -ECANCELED
short-circuit.
Introduce a static helper hci_cmd_sync_queue_conn_once() so the
get/put pair is not open-coded at every queue site. See the
helper's kerneldoc for the -EEXIST contract.
The hci_conn_valid() check in the callback body is retained: a
logically-deleted-but-still-referenced conn has stale
hdev->conn_hash.list state, and continuing to drive a connection
attempt on it would be a logic bug even though the memory is safe.
Pauli Virtanen posted a series-wide variant of this fix as
https://lore.kernel.org/linux-bluetooth/e18591f264c50e15917cb8b9e5f9798d9880979d.1762100290.git.pav@iki.fi/
(PATCH v2 8/8, 2025-11-02). KASAN reproducer captured under
UML+KASAN (linux-next tip bee6ea30c487).
Fixes: 881559af5f5c ("Bluetooth: hci_sync: Attempt to dequeue connection attempt")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
net/bluetooth/hci_sync.c | 41 ++++++++++++++++++++++++++++++++--------
1 file changed, 34 insertions(+), 7 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index fd3aacdea512..b20e07474257 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -786,6 +786,31 @@ int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
}
EXPORT_SYMBOL(hci_cmd_sync_queue_once);
+/* Queue an HCI command entry once, pinning a hci_conn for the duration.
+ *
+ * On success, the cmd_sync queue owns one hci_conn_get() reference;
+ * the supplied destroy callback must hci_conn_put() to balance.
+ *
+ * On any failure return (including -EEXIST, where
+ * hci_cmd_sync_queue_once() neither invokes destroy nor consumes the
+ * data pointer because an existing entry already owns the slot), the
+ * helper releases the reference before returning, so callers do not
+ * need to discriminate failure codes to keep the refcount balanced.
+ */
+static int hci_cmd_sync_queue_conn_once(struct hci_dev *hdev,
+ hci_cmd_sync_work_func_t func,
+ struct hci_conn *conn,
+ hci_cmd_sync_work_destroy_t destroy)
+{
+ int err;
+
+ err = hci_cmd_sync_queue_once(hdev, func, hci_conn_get(conn), destroy);
+ if (err)
+ hci_conn_put(conn);
+
+ return err;
+}
+
/* Run HCI command:
*
* - hdev must be running
@@ -6982,36 +7007,38 @@ static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
bt_dev_dbg(hdev, "err %d", err);
if (err == -ECANCELED)
- return;
+ goto done;
hci_dev_lock(hdev);
if (!hci_conn_valid(hdev, conn))
- goto done;
+ goto unlock;
if (!err) {
hci_connect_le_scan_cleanup(conn, 0x00);
- goto done;
+ goto unlock;
}
/* Check if connection is still pending */
if (conn != hci_lookup_le_connect(hdev))
- goto done;
+ goto unlock;
/* Flush to make sure we send create conn cancel command if needed */
flush_delayed_work(&conn->le_conn_timeout);
hci_conn_failed(conn, bt_status(err));
-done:
+unlock:
hci_dev_unlock(hdev);
+done:
+ hci_conn_put(conn);
}
int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn)
{
int err;
- err = hci_cmd_sync_queue_once(hdev, hci_le_create_conn_sync, conn,
- create_le_conn_complete);
+ err = hci_cmd_sync_queue_conn_once(hdev, hci_le_create_conn_sync, conn,
+ create_le_conn_complete);
return (err == -EEXIST) ? 0 : err;
}
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] Bluetooth: btmtk: accept too short WMT FUNC_CTRL events
From: patchwork-bot+bluetooth @ 2026-05-11 14:30 UTC (permalink / raw)
To: Pauli Virtanen
Cc: linux-bluetooth, marcel, luiz.dentz, tristan, linux-mediatek,
sean.wang, mark-yw.chen
In-Reply-To: <770d36b07311bf88210c187923f243fb9f126f04.1777058551.git.pav@iki.fi>
Hello:
This patch was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Fri, 24 Apr 2026 22:24:29 +0300 you wrote:
> MT7925 (USB ID 0e8d:e025) on fw version 20260106153314 sends WMT
> FUNC_CTRL events that are missing the status field.
>
> Prior to commit 006b9943b982 ("Bluetooth: btmtk: validate WMT event SKB
> length before struct access") the status was read from out-of-bounds of
> SKB data, which usually would result to success with
> BTMTK_WMT_ON_UNDONE, although I don't know the intent here. The bounds
> check added in that commit returns with error instead, producing
> "Bluetooth: hci0: Failed to send wmt func ctrl (-22)" and makes the
> device unusable.
>
> [...]
Here is the summary with links:
- Bluetooth: btmtk: accept too short WMT FUNC_CTRL events
https://git.kernel.org/bluetooth/bluetooth-next/c/162b1adeb057
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* RE: /bap: Handle CIS loss during streaming
From: bluez.test.bot @ 2026-05-11 14:28 UTC (permalink / raw)
To: linux-bluetooth, raghavendra.rao
In-Reply-To: <20260511105845.8008-2-raghavendra.rao@collabora.com>
[-- Attachment #1: Type: text/plain, Size: 3201 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1092705
---Test result---
Test Summary:
CheckPatch FAIL 0.48 seconds
GitLint FAIL 0.33 seconds
BuildEll PASS 20.02 seconds
BluezMake PASS 607.34 seconds
MakeCheck PASS 12.70 seconds
MakeDistcheck PASS 232.61 seconds
CheckValgrind PASS 253.53 seconds
CheckSmatch WARNING 323.06 seconds
bluezmakeextell PASS 164.34 seconds
IncrementalBuild PASS 607.15 seconds
ScanBuild PASS 915.09 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,1/1] bap: set QOS state when CIS is lost while the state is streaming/enabling
WARNING:LONG_LINE: line length of 81 exceeds 80 columns
#126: FILE: src/shared/bap.c:6720:
+ queue_foreach(stream->links, stream_link_io_qos_disconnect, sio);
/github/workspace/src/patch/14565299.patch total: 0 errors, 1 warnings, 50 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/patch/14565299.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,1/1] bap: set QOS state when CIS is lost while the state is streaming/enabling
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
1: T1 Title exceeds max length (85>80): "[BlueZ,1/1] bap: set QOS state when CIS is lost while the state is streaming/enabling"
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
src/shared/bap.c:312:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:312:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structuressrc/shared/bap.c:312:25: warning: array of flexible structuressrc/shared/bap.c: note: in included file:./src/shared/ascs.h:88:25: warning: array of flexible structures
https://github.com/bluez/bluez/pull/2116
---
Regards,
Linux Bluetooth
^ permalink raw reply
* RE: [BlueZ,1/3] mesh: Remove unused but set variable
From: bluez.test.bot @ 2026-05-11 14:27 UTC (permalink / raw)
To: linux-bluetooth, hadess
In-Reply-To: <20260511113511.1217887-1-hadess@hadess.net>
[-- Attachment #1: Type: text/plain, Size: 4068 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1092724
---Test result---
Test Summary:
CheckPatch FAIL 1.45 seconds
GitLint FAIL 1.04 seconds
BuildEll PASS 20.50 seconds
BluezMake PASS 610.73 seconds
MakeCheck PASS 1.04 seconds
MakeDistcheck PASS 235.67 seconds
CheckValgrind PASS 201.97 seconds
CheckSmatch PASS 322.12 seconds
bluezmakeextell PASS 164.82 seconds
IncrementalBuild PASS 604.45 seconds
ScanBuild PASS 905.83 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,2/3] mesh: Fix str{r,}chr usage
WARNING:LONG_LINE: line length of 82 exceeds 80 columns
#95: FILE: tools/mesh/mesh-db.c:2589:
+ str_s = json_object_to_json_string_ext(expt_cfg, JSON_C_TO_STRING_PRETTY |
/github/workspace/src/patch/14565358.patch total: 0 errors, 1 warnings, 41 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/patch/14565358.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,1/3] mesh: Remove unused but set variable
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
6: B1 Line exceeds max length (98>80): "mesh/net.c:1569:18: error: variable ‘ack_copy’ set but not used [-Werror=unused-but-set-variable=]"
[BlueZ,2/3] mesh: Fix str{r,}chr usage
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
8: B1 Line exceeds max length (130>80): "tools/mesh/mesh-db.c:2598:13: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]"
11: B1 Line exceeds max length (130>80): "tools/mesh/mesh-db.c:2604:13: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]"
14: B1 Line exceeds max length (130>80): "tools/mesh/mesh-db.c:2613:13: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]"
[BlueZ,3/3] mesh: Fix const qualifier dropping when using strchr()
WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
7: B1 Line exceeds max length (120>80): "mesh/util.c:108:14: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]"
https://github.com/bluez/bluez/pull/2117
---
Regards,
Linux Bluetooth
^ permalink raw reply
* RE: Bluetooth: L2CAP: ecred_reconfigure: send packed pdu, not stack pointer
From: bluez.test.bot @ 2026-05-11 14:24 UTC (permalink / raw)
To: linux-bluetooth, michael.bommarito
In-Reply-To: <20260511122641.437434-1-michael.bommarito@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1734 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1092764
---Test result---
Test Summary:
CheckPatch FAIL 0.59 seconds
GitLint PASS 0.23 seconds
SubjectPrefix PASS 0.08 seconds
BuildKernel PASS 25.17 seconds
CheckAllWarning PASS 27.71 seconds
CheckSparse PASS 26.40 seconds
BuildKernel32 PASS 24.56 seconds
TestRunnerSetup PASS 525.11 seconds
TestRunner_l2cap-tester PASS 378.39 seconds
IncrementalBuild PASS 24.25 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
Bluetooth: L2CAP: ecred_reconfigure: send packed pdu, not stack pointer
WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?)
#104:
Commit 1c08108f3014 ("Bluetooth: L2CAP: Avoid -Wflex-array-member-not-at-end
total: 0 errors, 1 warnings, 0 checks, 8 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/patch/14565486.patch has style problems, please review.
NOTE: Ignored message types: UNKNOWN_COMMIT_ID
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
https://github.com/bluez/bluetooth-next/pull/165
---
Regards,
Linux Bluetooth
^ permalink raw reply
* Re: [PATCH 6.1.y 1/2] Bluetooth: hci_sync: Remove remaining dependencies of hci_request
From: Sasha Levin @ 2026-05-11 14:21 UTC (permalink / raw)
To: gregkh, stable, luiz.von.dentz
Cc: Sasha Levin, patches, linux-kernel, marcel, johan.hedberg,
luiz.dentz, davem, edumazet, kuba, pabeni, linux-bluetooth,
netdev, Fang Wang
In-Reply-To: <tencent_CA96C7486F1CF8F0C72A2274E56AD1766708@qq.com>
On Mon, May 11, 2026 at 02:34:05PM +0800, Fang Wang wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> [ Upstream commit f2d89775358606c7ab6b6b6c4a02fe1e8cd270b1 ]
>
> This removes the dependencies of hci_req_init and hci_request_cancel_all
> from hci_sync.c.
Queued for 6.1 as the prerequisite for 2/2 (the btintel hci_req_sync_lock
fix), thanks.
Note: this commit is pure refactoring upstream and would not normally be
a stable candidate on its own; we're taking it here only to make
hci_req_sync_lock visible from drivers/bluetooth/btintel.c in 6.1.y so
that 2/2 builds. A Stable-dep-of: 94d8e6fe5d08 trailer would have been
the conventional way to document that on the backport (see commit
8d83194e8a880 on 6.6.y for an example). I won't block on it for this
submission, but please add such a trailer if you submit similar
prerequisite refactors in the future.
--
Sasha
^ permalink raw reply
* Re: [PATCH 6.1.y 2/2] Bluetooth: btintel: serialize btintel_hw_error() with hci_req_sync_lock
From: Sasha Levin @ 2026-05-11 14:21 UTC (permalink / raw)
To: gregkh, stable, zzzccc427
Cc: Sasha Levin, patches, linux-kernel, marcel, johan.hedberg,
luiz.dentz, linux-bluetooth, luiz.von.dentz, Fang Wang
In-Reply-To: <tencent_3D46FCA5631E9197F2E9E88FB394E389B707@qq.com>
On Mon, May 11, 2026 at 02:35:39PM +0800, Fang Wang wrote:
> From: Cen Zhang <zzzccc427@gmail.com>
>
> [ Upstream commit 94d8e6fe5d0818e9300e514e095a200bd5ff93ae ]
>
> btintel_hw_error() issues two __hci_cmd_sync() calls (HCI_OP_RESET
> and Intel exception-info retrieval) without holding
> hci_req_sync_lock().
Queued for 6.1 (along with 1/2 as the prerequisite), thanks.
--
Sasha
^ permalink raw reply
* Re: [PATCH net-next 6/7] selftests: net: getsockopt_iter: cover SCO BT_CODEC conversion
From: Breno Leitao @ 2026-05-11 14:19 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Marcel Holtmann, Luiz Augusto von Dentz, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Shuah Khan,
linux-bluetooth, linux-kernel, netdev, linux-kselftest,
kernel-team
In-Reply-To: <20260511064729.11c507b1@kernel.org>
On Mon, May 11, 2026 at 06:47:29AM -0700, Jakub Kicinski wrote:
> On Mon, 11 May 2026 03:41:51 -0700 Breno Leitao wrote:
> > tools/testing/selftests/net/getsockopt_iter.c | 65 +++++++++++++++++++++++++++
>
> please don't add Bluetooth tests under net/ (or at least they must
> cleanly XFAIL if Bluetooth is not enabled). Also Bluetooth has its
> own tree so not net-next in the subject.
Sorry about it. I will update.
Thanks,
--breno
^ permalink raw reply
* RE: [v1] Bluetooth: btintel_pcie: Reset controller before configuring MSI-X
From: bluez.test.bot @ 2026-05-11 14:19 UTC (permalink / raw)
To: linux-bluetooth, kiran.k
In-Reply-To: <20260511132711.1216139-1-kiran.k@intel.com>
[-- Attachment #1: Type: text/plain, Size: 882 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1092796
---Test result---
Test Summary:
CheckPatch PASS 0.67 seconds
GitLint PASS 0.28 seconds
SubjectPrefix PASS 1.58 seconds
BuildKernel PASS 26.84 seconds
CheckAllWarning PASS 29.54 seconds
CheckSparse PASS 28.25 seconds
BuildKernel32 PASS 26.49 seconds
TestRunnerSetup PASS 576.72 seconds
IncrementalBuild PASS 25.73 seconds
https://github.com/bluez/bluetooth-next/pull/166
---
Regards,
Linux Bluetooth
^ permalink raw reply
* RE: [v1] Bluetooth: btintel_pcie: Simplify MAC access request/release
From: bluez.test.bot @ 2026-05-11 14:19 UTC (permalink / raw)
To: linux-bluetooth, kiran.k
In-Reply-To: <20260511133932.1217624-1-kiran.k@intel.com>
[-- Attachment #1: Type: text/plain, Size: 882 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1092797
---Test result---
Test Summary:
CheckPatch PASS 0.94 seconds
GitLint PASS 0.33 seconds
SubjectPrefix PASS 0.13 seconds
BuildKernel PASS 26.55 seconds
CheckAllWarning PASS 29.35 seconds
CheckSparse PASS 27.82 seconds
BuildKernel32 PASS 25.85 seconds
TestRunnerSetup PASS 570.86 seconds
IncrementalBuild PASS 25.18 seconds
https://github.com/bluez/bluetooth-next/pull/167
---
Regards,
Linux Bluetooth
^ permalink raw reply
* Re: [PATCH BlueZ 1/1] bap: set QOS state when CIS is lost while the state is streaming/enabling
From: Luiz Augusto von Dentz @ 2026-05-11 14:09 UTC (permalink / raw)
To: raghu447; +Cc: linux-bluetooth
In-Reply-To: <20260511105845.8008-2-raghavendra.rao@collabora.com>
Hi,
On Mon, May 11, 2026 at 6:59 AM raghu447 <raghavendra.rao@collabora.com> wrote:
>
> This is used to Pass PTS tests BAP/USR/SCC/BV-167-C abd BV-168-C.
> ---
> src/shared/bap.c | 35 +++++++++++++++++++++++++++++++++++
> 1 file changed, 35 insertions(+)
>
> diff --git a/src/shared/bap.c b/src/shared/bap.c
> index 78ba22259..2edd4b249 100644
> --- a/src/shared/bap.c
> +++ b/src/shared/bap.c
> @@ -6670,9 +6670,38 @@ bool bt_bap_match_bcast_sink_stream(const void *data, const void *user_data)
> return stream->lpac->type == BT_BAP_BCAST_SINK;
> }
>
> +static void stream_io_qos_disconnect(struct bt_bap_stream *stream,
> + struct bt_bap_stream_io *io)
> +{
> + uint8_t state;
> +
> + if (!stream || !stream->ep || stream->io != io)
> + return;
> +
> + state = stream->ep->state;
> +
> + DBG(stream->bap, "CIS disconnected for stream %p state %u", stream,
> + state);
> +
> + if (state != BT_ASCS_ASE_STATE_ENABLING &&
> + state != BT_ASCS_ASE_STATE_STREAMING)
> + return;
> +
> + DBG(stream->bap, "Moving ASE %u to QoS Configured after CIS loss",
> + stream->ep->id);
> +
> + stream_set_state(stream, BT_BAP_STREAM_STATE_QOS);
> +}
> +
> +static void stream_link_io_qos_disconnect(void *data, void *user_data)
> +{
> + stream_io_qos_disconnect(data, user_data);
> +}
> +
> static bool stream_io_disconnected(struct io *io, void *user_data)
> {
> struct bt_bap_stream *stream = user_data;
> + struct bt_bap_stream_io *sio;
>
> DBG(stream->bap, "stream %p io disconnected", stream);
>
> @@ -6685,6 +6714,12 @@ static bool stream_io_disconnected(struct io *io, void *user_data)
> return false;
> }
>
> + sio = stream->io;
> + if (sio) {
> + stream_io_qos_disconnect(stream, sio);
> + queue_foreach(stream->links, stream_link_io_qos_disconnect, sio);
> + }
> +
Hmm, this should already been doing by the likes of
bt_bap_stream_set_io(-1) -> bap_stream_set_io -> bap_stream_io_detach,
so perhaps there is something missing there, or perhaps
bap_stream_set_io is not handling all the states.
> if (stream->ep->state == BT_ASCS_ASE_STATE_RELEASING)
> stream_set_state(stream, BT_BAP_STREAM_STATE_CONFIG);
>
> --
> 2.43.0
>
>
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH v6] Bluetooth: hci_qca: Convert timeout from jiffies to ms
From: Shuai Zhang @ 2026-05-11 13:58 UTC (permalink / raw)
To: Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz
Cc: linux-arm-msm, linux-bluetooth, linux-kernel, cheng.jiang,
quic_chezhou, wei.deng, jinwang.li, mengshi.wu, shuai.zhang,
stable, Paul Menzel, Bartosz Golaszewski
Since the timer uses jiffies as its unit rather than ms, the timeout value
must be converted from ms to jiffies when configuring the timer. Otherwise,
the intended 8s timeout is incorrectly set to approximately 33s.
To improve readability, embed msecs_to_jiffies() directly in the macro
definitions and drop the _MS suffix from macros that now yield jiffies
values: MEMDUMP_TIMEOUT, FW_DOWNLOAD_TIMEOUT, IBS_DISABLE_SSR_TIMEOUT,
CMD_TRANS_TIMEOUT, and IBS_BTSOC_TX_IDLE_TIMEOUT.
IBS_WAKE_RETRANS_TIMEOUT_MS and IBS_HOST_TX_IDLE_TIMEOUT_MS are
intentionally left unchanged. Their values are stored in the struct fields
wake_retrans and tx_idle_delay, which hold ms values at runtime and can be
modified via debugfs. The msecs_to_jiffies() conversion happens at each
call site against the field value, so it cannot be embedded in the macro.
Wake timer depends on commit c347ca17d62a
Cc: stable@vger.kernel.org
Fixes: d841502c79e3 ("Bluetooth: hci_qca: Collect controller memory dump during SSR")
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
---
Changes v6:
- Move msecs_to_jiffies() into macro definitions instead of wrapping
each call site
- Rename macros by dropping the _MS suffix to reflect that they now yield jiffies values.
- Change wait_timeout from u32 to unsigned long to properly hold jiffies values.
- Link to v5:
https://lore.kernel.org/all/20260429123802.1310681-1-shuai.zhang@oss.qualcomm.com/
Changes v5:
- add depends on commit
- Link to v4
https://lore.kernel.org/all/20260327082941.1396521-1-shuai.zhang@oss.qualcomm.com/
Changes v4:
- add review-by signoff
- Link to v3
https://lore.kernel.org/all/20251107033924.3707495-1-quic_shuaz@quicinc.com/
Changes v3:
- add Fixes tag
- Link to v2
https://lore.kernel.org/all/20251106140103.1406081-1-quic_shuaz@quicinc.com/
Changes v2:
- Split timeout conversion into a separate patch.
- Clarified commit messages and added test case description.
- Link to v1
https://lore.kernel.org/all/20251104112601.2670019-1-quic_shuaz@quicinc.com/
---
drivers/bluetooth/hci_qca.c | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index cd1834246..ed280399b 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -48,13 +48,12 @@
#define HCI_MAX_IBS_SIZE 10
#define IBS_WAKE_RETRANS_TIMEOUT_MS 100
-#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS 200
+#define IBS_BTSOC_TX_IDLE_TIMEOUT msecs_to_jiffies(200)
#define IBS_HOST_TX_IDLE_TIMEOUT_MS 2000
-#define CMD_TRANS_TIMEOUT_MS 100
-#define MEMDUMP_TIMEOUT_MS 8000
-#define IBS_DISABLE_SSR_TIMEOUT_MS \
- (MEMDUMP_TIMEOUT_MS + FW_DOWNLOAD_TIMEOUT_MS)
-#define FW_DOWNLOAD_TIMEOUT_MS 3000
+#define CMD_TRANS_TIMEOUT msecs_to_jiffies(100)
+#define MEMDUMP_TIMEOUT msecs_to_jiffies(8000)
+#define FW_DOWNLOAD_TIMEOUT msecs_to_jiffies(3000)
+#define IBS_DISABLE_SSR_TIMEOUT (MEMDUMP_TIMEOUT + FW_DOWNLOAD_TIMEOUT)
/* susclk rate */
#define SUSCLK_RATE_32KHZ 32768
@@ -1096,7 +1095,7 @@ static void qca_controller_memdump(struct work_struct *work)
queue_delayed_work(qca->workqueue,
&qca->ctrl_memdump_timeout,
- msecs_to_jiffies(MEMDUMP_TIMEOUT_MS));
+ MEMDUMP_TIMEOUT);
skb_pull(skb, sizeof(qca_memdump->ram_dump_size));
qca_memdump->current_seq_no = 0;
qca_memdump->received_dump = 0;
@@ -1369,7 +1368,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
if (hu->serdev)
serdev_device_wait_until_sent(hu->serdev,
- msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
+ CMD_TRANS_TIMEOUT);
/* Give the controller time to process the request */
switch (qca_soc_type(hu)) {
@@ -1401,8 +1400,8 @@ static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed)
static int qca_send_power_pulse(struct hci_uart *hu, bool on)
{
+ int timeout = CMD_TRANS_TIMEOUT;
int ret;
- int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
u8 cmd = on ? QCA_WCN3990_POWERON_PULSE : QCA_WCN3990_POWEROFF_PULSE;
/* These power pulses are single byte command which are sent
@@ -1607,7 +1606,7 @@ static void qca_wait_for_dump_collection(struct hci_dev *hdev)
struct qca_data *qca = hu->priv;
wait_on_bit_timeout(&qca->flags, QCA_MEMDUMP_COLLECTION,
- TASK_UNINTERRUPTIBLE, MEMDUMP_TIMEOUT_MS);
+ TASK_UNINTERRUPTIBLE, MEMDUMP_TIMEOUT);
clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
}
@@ -2591,7 +2590,7 @@ static void qca_serdev_remove(struct serdev_device *serdev)
static void qca_serdev_shutdown(struct serdev_device *serdev)
{
int ret;
- int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
+ int timeout = CMD_TRANS_TIMEOUT;
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
struct hci_uart *hu = &qcadev->serdev_hu;
struct hci_dev *hdev = hu->hdev;
@@ -2648,7 +2647,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
bool tx_pending = false;
int ret = 0;
u8 cmd;
- u32 wait_timeout = 0;
+ unsigned long wait_timeout = 0;
set_bit(QCA_SUSPENDING, &qca->flags);
@@ -2669,15 +2668,15 @@ static int __maybe_unused qca_suspend(struct device *dev)
if (test_bit(QCA_IBS_DISABLED, &qca->flags) ||
test_bit(QCA_SSR_TRIGGERED, &qca->flags)) {
wait_timeout = test_bit(QCA_SSR_TRIGGERED, &qca->flags) ?
- IBS_DISABLE_SSR_TIMEOUT_MS :
- FW_DOWNLOAD_TIMEOUT_MS;
+ IBS_DISABLE_SSR_TIMEOUT :
+ FW_DOWNLOAD_TIMEOUT;
/* QCA_IBS_DISABLED flag is set to true, During FW download
* and during memory dump collection. It is reset to false,
* After FW download complete.
*/
wait_on_bit_timeout(&qca->flags, QCA_IBS_DISABLED,
- TASK_UNINTERRUPTIBLE, msecs_to_jiffies(wait_timeout));
+ TASK_UNINTERRUPTIBLE, wait_timeout);
if (test_bit(QCA_IBS_DISABLED, &qca->flags)) {
bt_dev_err(hu->hdev, "SSR or FW download time out");
@@ -2729,7 +2728,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
if (tx_pending) {
serdev_device_wait_until_sent(hu->serdev,
- msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
+ CMD_TRANS_TIMEOUT);
serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
}
@@ -2738,7 +2737,7 @@ static int __maybe_unused qca_suspend(struct device *dev)
*/
ret = wait_event_interruptible_timeout(qca->suspend_wait_q,
qca->rx_ibs_state == HCI_IBS_RX_ASLEEP,
- msecs_to_jiffies(IBS_BTSOC_TX_IDLE_TIMEOUT_MS));
+ IBS_BTSOC_TX_IDLE_TIMEOUT);
if (ret == 0) {
ret = -ETIMEDOUT;
goto error;
--
2.34.1
^ permalink raw reply related
* Re: [PATCH net-next 6/7] selftests: net: getsockopt_iter: cover SCO BT_CODEC conversion
From: Jakub Kicinski @ 2026-05-11 13:47 UTC (permalink / raw)
To: Breno Leitao
Cc: Marcel Holtmann, Luiz Augusto von Dentz, David S. Miller,
Eric Dumazet, Paolo Abeni, Simon Horman, Shuah Khan,
linux-bluetooth, linux-kernel, netdev, linux-kselftest,
kernel-team
In-Reply-To: <20260511-getsock_three-v1-6-1461fa8786ab@debian.org>
On Mon, 11 May 2026 03:41:51 -0700 Breno Leitao wrote:
> tools/testing/selftests/net/getsockopt_iter.c | 65 +++++++++++++++++++++++++++
please don't add Bluetooth tests under net/ (or at least they must
cleanly XFAIL if Bluetooth is not enabled). Also Bluetooth has its
own tree so not net-next in the subject.
^ permalink raw reply
* [bluez/bluez] 9c42e0: mesh: Remove unused but set variable
From: hadess @ 2026-05-11 13:35 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1092724
Home: https://github.com/bluez/bluez
Commit: 9c42e065a6d6935510b7708942d9a3b709b8b846
https://github.com/bluez/bluez/commit/9c42e065a6d6935510b7708942d9a3b709b8b846
Author: Bastien Nocera <hadess@hadess.net>
Date: 2026-05-11 (Mon, 11 May 2026)
Changed paths:
M mesh/net.c
Log Message:
-----------
mesh: Remove unused but set variable
We played around with the bits, but didn't do anything with it.
mesh/net.c: In function ‘ack_received’:
mesh/net.c:1569:18: error: variable ‘ack_copy’ set but not used [-Werror=unused-but-set-variable=]
1569 | uint32_t ack_copy = ack_flag;
| ^~~~~~~~
Commit: a099005271bf7c6203c2e359de7486d6147bd717
https://github.com/bluez/bluez/commit/a099005271bf7c6203c2e359de7486d6147bd717
Author: Bastien Nocera <hadess@hadess.net>
Date: 2026-05-11 (Mon, 11 May 2026)
Changed paths:
M tools/mesh/mesh-db.c
Log Message:
-----------
mesh: Fix str{r,}chr usage
Fix the code manipulating "const char *" return values from
json_object_to_json_string_ext() to modify it for printing, we're
not allowed to do that.
tools/mesh/mesh-db.c: In function ‘mesh_db_finish_export’:
tools/mesh/mesh-db.c:2598:13: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
2598 | pos = strrchr(hdr, '}');
| ^
tools/mesh/mesh-db.c:2604:13: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
2604 | pos = strrchr(hdr, '"');
| ^
tools/mesh/mesh-db.c:2613:13: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
2613 | pos = strchr(str, '{');
| ^
Commit: 8493905fe64d4cb18f5b08e47d37a77687baecd3
https://github.com/bluez/bluez/commit/8493905fe64d4cb18f5b08e47d37a77687baecd3
Author: Bastien Nocera <hadess@hadess.net>
Date: 2026-05-11 (Mon, 11 May 2026)
Changed paths:
M mesh/util.c
Log Message:
-----------
mesh: Fix const qualifier dropping when using strchr()
strchr() with a const string returns a const string, we don't change
that string or "next", so make both const and get rid of the warning.
mesh/util.c: In function ‘create_dir’:
mesh/util.c:108:14: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
108 | prev = strchr(dir_name, '/');
| ^
Compare: https://github.com/bluez/bluez/compare/9c42e065a6d6%5E...8493905fe64d
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez] 4246ca: bap: set QOS state when CIS is lost while the stat...
From: raghava447 @ 2026-05-11 13:35 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1092705
Home: https://github.com/bluez/bluez
Commit: 4246cabd1ecf06193ce603f6950c85fe57d043ba
https://github.com/bluez/bluez/commit/4246cabd1ecf06193ce603f6950c85fe57d043ba
Author: raghu447 <raghavendra.rao@collabora.com>
Date: 2026-05-11 (Mon, 11 May 2026)
Changed paths:
M src/shared/bap.c
Log Message:
-----------
bap: set QOS state when CIS is lost while the state is streaming/enabling
This is used to Pass PTS tests BAP/USR/SCC/BV-167-C abd BV-168-C.
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* RE: [BlueZ,v3,4/6] main: Use _cleanup_() to simplify configuration parsing
From: bluez.test.bot @ 2026-05-11 13:35 UTC (permalink / raw)
To: linux-bluetooth, hadess
In-Reply-To: <20260511132131.1283892-5-hadess@hadess.net>
[-- Attachment #1: Type: text/plain, Size: 522 bytes --]
This is an automated email and please do not reply to this email.
Dear Submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
While preparing the CI tests, the patches you submitted couldn't be applied to the current HEAD of the repository.
----- Output -----
error: patch failed: src/main.c:205
error: src/main.c: patch does not apply
hint: Use 'git am --show-current-patch' to see the failed patch
Please resolve the issue and submit the patches again.
---
Regards,
Linux Bluetooth
^ permalink raw reply
* [BlueZ v3 2/6] shared/util: Add helper for "cleanup" variable attribute
From: Bastien Nocera @ 2026-05-11 13:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260511132131.1283892-1-hadess@hadess.net>
Use the widespread "cleanup" variable attribute:
https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-cleanup
It is implemented by both GCC and clang on platforms where bluez is
used, and can help reduce memory leaks, while improving readability.
This implements:
- generic cleanup (_cleanup_free_)
- cleanup with specific free function (_cleanup_())
- cleanup for specific types (_cleanup_type_(type))
- cleanup for file descriptors
- capturing a variable before it is freed (so it is only freed in error
paths for example, _steal_() and _steal_fd())
This commit includes tests which should cover all those new helpers.
See also:
https://systemd.io/CODING_STYLE/#memory-allocation
https://docs.gtk.org/glib/auto-cleanup.html
---
src/shared/util.h | 40 +++++++++++++++++++++++++++++
unit/test-util.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 105 insertions(+)
diff --git a/src/shared/util.h b/src/shared/util.h
index 67629dddfaa9..c8ce90c5f1b5 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -15,9 +15,11 @@
#include <stdbool.h>
#include <alloca.h>
#include <byteswap.h>
+#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/uio.h>
+#include <unistd.h>
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define BIT(n) (1 << (n))
@@ -93,6 +95,44 @@ do { \
#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
#define malloc0(n) (calloc(1, (n)))
+static inline void freep(void *p)
+{
+ free(*(void **) p);
+}
+
+static inline void * _steal_(void *p)
+{
+ void **orig = (void **) p;
+ void *ret = *orig;
+ *orig = NULL;
+ return ret;
+}
+
+static inline int _steal_fd_(int *fdp)
+{
+ int fd = *fdp;
+ *fdp = -1;
+ return fd;
+}
+
+static inline void closefd(int *fdp)
+{
+ int errno_save = errno;
+ int fd = *fdp;
+ *fdp = -1;
+ if (fd < 0)
+ return;
+ close(fd);
+ errno = errno_save;
+}
+
+#define CLEANUP_FREEFUNC(type, func) static inline void cleanup_##type (type **_ptr) { (func) (*_ptr); }
+
+#define _cleanup_(f) __attribute__((cleanup(f)))
+#define _cleanup_type_(type) __attribute__((cleanup(cleanup_##type)))
+#define _cleanup_free_ _cleanup_(freep)
+#define _cleanup_fd_ _cleanup_(closefd)
+
char *strdelimit(char *str, char *del, char c);
int strsuffix(const char *str, const char *suffix);
char *strstrip(char *str);
diff --git a/unit/test-util.c b/unit/test-util.c
index 443c4f70362c..1672b32eb39c 100644
--- a/unit/test-util.c
+++ b/unit/test-util.c
@@ -9,14 +9,73 @@
*/
#include <assert.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "src/shared/util.h"
#include "src/shared/tester.h"
+#include "bluetooth/bluetooth.h"
/* XXX glib.h must not be included, or it will clobber the
* MIN/MAX macros.
*/
+static void test_cleanup_free(const void *data)
+{
+ _cleanup_free_ char *p1 = NULL;
+ _cleanup_free_ char *p2 = NULL;
+ _cleanup_free_ char *is_null = NULL;
+
+ p1 = malloc0(10);
+ p2 = malloc0(15);
+
+ p1[0] = 1;
+ p2[0] = 1;
+
+ {
+ _cleanup_free_ uint8_t *data = NULL;
+ _cleanup_free_ uint8_t *is_null_too = NULL;
+
+ data = malloc0(128);
+ data[0] = 1;
+
+ assert(is_null_too == NULL);
+ }
+ {
+ _cleanup_free_ uint8_t *data = NULL;
+ data = malloc0(128 * 2);
+ data[0] = 3;
+ }
+
+ assert(is_null == NULL);
+ tester_test_passed();
+}
+
+CLEANUP_FREEFUNC(bdaddr_t, free);
+
+static void test_cleanup_type(const void *data)
+{
+#define ADDR "FF:FF:FF:FF:FF:FF"
+ _cleanup_type_(bdaddr_t) bdaddr_t *address = NULL;
+ char str[33];
+
+ address = strtoba(ADDR);
+ assert(bacmp(address, BDADDR_ALL) == 0);
+ printf("%d = ba2str(address, str)\n", ba2str(address, str));
+ assert(ba2str(address, str) == 17);
+ assert(strcmp(str, ADDR) == 0);
+ tester_test_passed();
+}
+
+static void test_cleanup_fd(const void *data)
+{
+ _cleanup_fd_ int fd = -1;
+
+ fd = open("/dev/null", O_RDONLY);
+ assert(fd != 0);
+ tester_test_passed();
+}
+
static void test_min_max(const void *data)
{
assert(MIN(3, 4) == 3);
@@ -30,6 +89,12 @@ int main(int argc, char *argv[])
tester_add("/util/min_max", NULL, NULL,
test_min_max, NULL);
+ tester_add("/util/cleanup_free", NULL, NULL,
+ test_cleanup_free, NULL);
+ tester_add("/util/cleanup_type", NULL, NULL,
+ test_cleanup_type, NULL);
+ tester_add("/util/cleanup_fd", NULL, NULL,
+ test_cleanup_fd, NULL);
return tester_run();
}
--
2.54.0
^ permalink raw reply related
* [BlueZ v3 5/6] client: Use _cleanup_fd_ to simplify urandom access
From: Bastien Nocera @ 2026-05-11 13:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260511132131.1283892-1-hadess@hadess.net>
fd gets auto-closed before exiting the scope.
---
client/mgmt.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/client/mgmt.c b/client/mgmt.c
index 50558a313866..e199c30540e4 100644
--- a/client/mgmt.c
+++ b/client/mgmt.c
@@ -2681,7 +2681,7 @@ static void cmd_privacy(int argc, char **argv)
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
} else {
- int fd;
+ _cleanup_fd_ int fd = -1;
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
@@ -2691,11 +2691,8 @@ static void cmd_privacy(int argc, char **argv)
if (read(fd, cp.irk, sizeof(cp.irk)) != sizeof(cp.irk)) {
error("Reading from urandom failed");
- close(fd);
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
-
- close(fd);
}
if (send_cmd(mgmt, MGMT_OP_SET_PRIVACY, index, sizeof(cp), &cp,
--
2.54.0
^ permalink raw reply related
* [BlueZ v3 3/6] doc: Recommend using _cleanup_ and friends
From: Bastien Nocera @ 2026-05-11 13:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260511132131.1283892-1-hadess@hadess.net>
---
doc/maintainer-guidelines.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/maintainer-guidelines.rst b/doc/maintainer-guidelines.rst
index 44d3e258db6e..b67c6596f4c1 100644
--- a/doc/maintainer-guidelines.rst
+++ b/doc/maintainer-guidelines.rst
@@ -98,6 +98,9 @@ do this:
The above assumes that a kernel tree resides in ``~/src/linux/``.
+Also make sure to use ``_cleanup_free_`` and ``_cleanup_(free_func)`` when
+possible. It makes your code much nicer to read (and shorter), and avoids
+common memory leaks on error paths.
Rule 4: Pay extra attention to adding new files to the tree
-----------------------------------------------------------
--
2.54.0
^ permalink raw reply related
* [BlueZ v3 1/6] all: Remove more unneeded MIN/MAX macro definition
From: Bastien Nocera @ 2026-05-11 13:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260511132131.1283892-1-hadess@hadess.net>
---
lib/bluetooth/hci.c | 4 ----
src/main.c | 4 ----
src/shared/gatt-server.c | 8 --------
3 files changed, 16 deletions(-)
diff --git a/lib/bluetooth/hci.c b/lib/bluetooth/hci.c
index 44eea054b0ac..f50a30c610be 100644
--- a/lib/bluetooth/hci.c
+++ b/lib/bluetooth/hci.c
@@ -33,10 +33,6 @@
#include "hci.h"
#include "hci_lib.h"
-#ifndef MIN
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-#endif
-
typedef struct {
char *str;
unsigned int val;
diff --git a/src/main.c b/src/main.c
index 9a3d2da25d4d..8aa19a3e3346 100644
--- a/src/main.c
+++ b/src/main.c
@@ -205,10 +205,6 @@ static const struct group_table {
{ }
};
-#ifndef MIN
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-#endif
-
static int8_t check_sirk_alpha_numeric(char *str)
{
int8_t val = 0;
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 6273899965c0..709a8f94bb6a 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -26,14 +26,6 @@
#include "src/shared/util.h"
#include "src/shared/timeout.h"
-#ifndef MAX
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-#ifndef MIN
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
/*
* TODO: This is an arbitrary limit. Come up with something reasonable or
* perhaps an API to set this value if there is a use case for it.
--
2.54.0
^ permalink raw reply related
* [BlueZ v3 6/6] btattach: Use _cleanup_fd_ to simplify error paths
From: Bastien Nocera @ 2026-05-11 13:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260511132131.1283892-1-hadess@hadess.net>
Use _cleanup_fd_ and _steal_fd() to simplify error paths, and only
"steal" the file descriptor on success.
---
tools/btattach.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/tools/btattach.c b/tools/btattach.c
index 5f7d19093698..8868871b0128 100644
--- a/tools/btattach.c
+++ b/tools/btattach.c
@@ -40,7 +40,8 @@
static int open_serial(const char *path, unsigned int speed, bool flowctl)
{
struct termios ti;
- int fd, saved_ldisc, ldisc = N_HCI;
+ _cleanup_fd_ int fd = -1;
+ int saved_ldisc, ldisc = N_HCI;
fd = open(path, O_RDWR | O_NOCTTY);
if (fd < 0) {
@@ -50,13 +51,11 @@ static int open_serial(const char *path, unsigned int speed, bool flowctl)
if (tcflush(fd, TCIOFLUSH) < 0) {
perror("Failed to flush serial port");
- close(fd);
return -1;
}
if (ioctl(fd, TIOCGETD, &saved_ldisc) < 0) {
perror("Failed get serial line discipline");
- close(fd);
return -1;
}
@@ -73,19 +72,17 @@ static int open_serial(const char *path, unsigned int speed, bool flowctl)
if (tcsetattr(fd, TCSANOW, &ti) < 0) {
perror("Failed to set serial port settings");
- close(fd);
return -1;
}
if (ioctl(fd, TIOCSETD, &ldisc) < 0) {
perror("Failed set serial line discipline");
- close(fd);
return -1;
}
printf("Switched line discipline from %d to %d\n", saved_ldisc, ldisc);
- return fd;
+ return _steal_fd_(&fd);
}
static void local_version_callback(const void *data, uint8_t size,
@@ -99,7 +96,8 @@ static void local_version_callback(const void *data, uint8_t size,
static int attach_proto(const char *path, unsigned int proto,
unsigned int speed, bool flowctl, unsigned int flags)
{
- int fd, dev_id;
+ _cleanup_fd_ int fd = -1;
+ int dev_id;
fd = open_serial(path, speed, flowctl);
if (fd < 0)
@@ -107,20 +105,17 @@ static int attach_proto(const char *path, unsigned int proto,
if (ioctl(fd, HCIUARTSETFLAGS, flags) < 0) {
perror("Failed to set flags");
- close(fd);
return -1;
}
if (ioctl(fd, HCIUARTSETPROTO, proto) < 0) {
perror("Failed to set protocol");
- close(fd);
return -1;
}
dev_id = ioctl(fd, HCIUARTGETDEVICE);
if (dev_id < 0) {
perror("Failed to get device id");
- close(fd);
return -1;
}
@@ -140,7 +135,6 @@ static int attach_proto(const char *path, unsigned int proto,
if (!hci) {
fprintf(stderr, "Failed to open HCI user channel\n");
- close(fd);
return -1;
}
@@ -149,7 +143,7 @@ static int attach_proto(const char *path, unsigned int proto,
(bt_hci_destroy_func_t) bt_hci_unref);
}
- return fd;
+ return _steal_fd_(&fd);
}
static void uart_callback(int fd, uint32_t events, void *user_data)
--
2.54.0
^ permalink raw reply related
* [BlueZ v3 0/6] Add helper for "cleanup" variable attribute
From: Bastien Nocera @ 2026-05-11 13:18 UTC (permalink / raw)
To: linux-bluetooth
As discussed in:
https://lore.kernel.org/linux-bluetooth/ed949f2550f79a4bef19bd482bf8b069ad5b7e0c.camel@hadess.net/
Implement a cleanup helper.
The MIN/MAX fix is here because it touches the same hunk in src/main.c
as the other patches. Feel free to pick it up straight away while the
rest is discussed.
Changes since v2:
- Add macros to declare cleanup for specific types
- Add file descriptor cleanup
- Add "steal" helpers for fd and pointers
- Add unit tests
Changes since v1:
- Fixed checkpatch warnings
Bastien Nocera (6):
all: Remove more unneeded MIN/MAX macro definition
shared/util: Add helper for "cleanup" variable attribute
doc: Recommend using _cleanup_ and friends
main: Use _cleanup_() to simplify configuration parsing
client: Use _cleanup_fd_ to simplify urandom access
btattach: Use _cleanup_fd_ to simplify error paths
client/mgmt.c | 5 +-
doc/maintainer-guidelines.rst | 3 +
lib/bluetooth/hci.c | 4 --
src/main.c | 103 ++++++++++------------------------
src/shared/gatt-server.c | 8 ---
src/shared/util.h | 40 +++++++++++++
tools/btattach.c | 18 ++----
unit/test-util.c | 65 +++++++++++++++++++++
8 files changed, 145 insertions(+), 101 deletions(-)
--
2.54.0
^ permalink raw reply
* [BlueZ v3 4/6] main: Use _cleanup_() to simplify configuration parsing
From: Bastien Nocera @ 2026-05-11 13:18 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20260511132131.1283892-1-hadess@hadess.net>
Use helpers to simplify temporary string usage, and cleanup in error
paths.
---
src/main.c | 101 ++++++++++++++++-------------------------------------
1 file changed, 31 insertions(+), 70 deletions(-)
diff --git a/src/main.c b/src/main.c
index 8aa19a3e3346..9053e74aaf75 100644
--- a/src/main.c
+++ b/src/main.c
@@ -205,6 +205,9 @@ static const struct group_table {
{ }
};
+CLEANUP_FREEFUNC(GError, g_error_free);
+CLEANUP_FREEFUNC(GKeyFile, g_key_file_free);
+
static int8_t check_sirk_alpha_numeric(char *str)
{
int8_t val = 0;
@@ -252,8 +255,8 @@ GKeyFile *btd_get_main_conf(void)
static GKeyFile *load_config(const char *name)
{
- GError *err = NULL;
- GKeyFile *keyfile;
+ _cleanup_type_(GError) GError *err = NULL;
+ _cleanup_type_(GKeyFile) GKeyFile *keyfile = NULL;
int len;
if (name)
@@ -285,12 +288,10 @@ static GKeyFile *load_config(const char *name)
if (!g_error_matches(err, G_FILE_ERROR, G_FILE_ERROR_NOENT))
error("Parsing %s failed: %s", main_conf_file_path,
err->message);
- g_error_free(err);
- g_key_file_free(keyfile);
return NULL;
}
- return keyfile;
+ return _steal_(keyfile);
}
static void parse_did(const char *did)
@@ -436,14 +437,13 @@ static int get_mode(const char *str)
static bool parse_config_string(GKeyFile *config, const char *group,
const char *key, char **val)
{
- GError *err = NULL;
+ _cleanup_type_(GError) GError *err = NULL;
char *tmp;
tmp = g_key_file_get_string(config, group, key, &err);
if (err) {
if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
DBG("%s", err->message);
- g_error_free(err);
return false;
}
@@ -462,7 +462,7 @@ static bool parse_config_int(GKeyFile *config, const char *group,
size_t min, size_t max)
{
size_t tmp;
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
char *endptr = NULL;
if (!parse_config_string(config, group, key, &str))
@@ -471,25 +471,21 @@ static bool parse_config_int(GKeyFile *config, const char *group,
tmp = strtol(str, &endptr, 0);
if (!endptr || *endptr != '\0') {
error("%s.%s = %s is not integer", group, key, str);
- g_free(str);
return false;
}
if (tmp < min) {
- g_free(str);
warn("%s.%s = %zu is out of range (< %zu)", group, key, tmp,
min);
return false;
}
if (tmp > max) {
- g_free(str);
warn("%s.%s = %zu is out of range (> %zu)", group, key, tmp,
max);
return false;
}
- g_free(str);
if (val)
*val = tmp;
@@ -500,10 +496,9 @@ static bool parse_config_signed_int(GKeyFile *config, const char *group,
const char *key, int8_t *val,
long min, long max)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
char *endptr = NULL;
long tmp;
- bool result = false;
str = g_key_file_get_string(config, group, key, NULL);
if (!str)
@@ -512,28 +507,24 @@ static bool parse_config_signed_int(GKeyFile *config, const char *group,
tmp = strtol(str, &endptr, 0);
if (!endptr || *endptr != '\0') {
warn("%s.%s = %s is not integer", group, key, str);
- goto cleanup;
+ return false;
}
if (tmp < min) {
warn("%s.%s = %ld is out of range (< %ld)", group, key, tmp,
min);
- goto cleanup;
+ return false;
}
if (tmp > max) {
warn("%s.%s = %ld is out of range (> %ld)", group, key, tmp,
max);
- goto cleanup;
+ return false;
}
if (val)
*val = (int8_t) tmp;
- result = true;
-
-cleanup:
- g_free(str);
- return result;
+ return true;
}
struct config_param {
@@ -894,14 +885,13 @@ static bool parse_config_u8(GKeyFile *config, const char *group,
static bool parse_config_bool(GKeyFile *config, const char *group,
const char *key, bool *val)
{
- GError *err = NULL;
+ _cleanup_type_(GError) GError *err = NULL;
gboolean tmp;
tmp = g_key_file_get_boolean(config, group, key, &err);
if (err) {
if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
DBG("%s", err->message);
- g_error_free(err);
return false;
}
@@ -915,7 +905,7 @@ static bool parse_config_bool(GKeyFile *config, const char *group,
static void parse_privacy(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
if (!parse_config_string(config, "General", "Privacy", &str)) {
btd_opts.privacy = 0x00;
@@ -948,13 +938,11 @@ static void parse_privacy(GKeyFile *config)
DBG("Invalid privacy option: %s", str);
btd_opts.privacy = 0x00;
}
-
- g_free(str);
}
static void parse_repairing(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
if (!parse_config_string(config, "General", "JustWorksRepairing",
&str)) {
@@ -963,13 +951,12 @@ static void parse_repairing(GKeyFile *config)
}
btd_opts.jw_repairing = parse_jw_repairing(str);
- g_free(str);
}
static bool parse_config_hex(GKeyFile *config, char *group,
const char *key, uint32_t *val)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
if (!parse_config_string(config, group, key, &str))
return false;
@@ -977,37 +964,34 @@ static bool parse_config_hex(GKeyFile *config, char *group,
if (val)
*val = strtol(str, NULL, 16);
- g_free(str);
return true;
}
static void parse_device_id(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
parse_config_string(config, "General", "DeviceID", &str);
if (!str)
return;
parse_did(str);
- g_free(str);
}
static void parse_ctrl_mode(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
parse_config_string(config, "General", "ControllerMode", &str);
if (!str)
return;
btd_opts.mode = get_mode(str);
- g_free(str);
}
static void parse_multi_profile(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
parse_config_string(config, "General", "MultiProfile", &str);
if (!str)
@@ -1019,8 +1003,6 @@ static void parse_multi_profile(GKeyFile *config)
btd_opts.mps = MPS_MULTIPLE;
else
btd_opts.mps = MPS_OFF;
-
- g_free(str);
}
static gboolean parse_kernel_experimental(const char *key, const char *value,
@@ -1043,20 +1025,18 @@ static gboolean parse_kernel_experimental(const char *key, const char *value,
static void parse_kernel_exp(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
if (!parse_config_string(config, "General", "KernelExperimental",
&str))
return;
parse_kernel_experimental(NULL, str, NULL, NULL);
-
- g_free(str);
}
static void parse_secure_conns(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
if (!parse_config_string(config, "General", "SecureConnections",
&str))
@@ -1068,8 +1048,6 @@ static void parse_secure_conns(GKeyFile *config)
btd_opts.secure_conn = SC_ON;
else if (!strcmp(str, "only"))
btd_opts.secure_conn = SC_ONLY;
-
- g_free(str);
}
static void parse_general(GKeyFile *config)
@@ -1120,14 +1098,13 @@ static void parse_general(GKeyFile *config)
static void parse_gatt_cache(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
parse_config_string(config, "GATT", "Cache", &str);
if (!str)
return;
btd_opts.gatt_cache = parse_gatt_cache_str(str);
- g_free(str);
}
static enum bt_gatt_export_t parse_gatt_export_str(const char *str)
@@ -1147,14 +1124,13 @@ static enum bt_gatt_export_t parse_gatt_export_str(const char *str)
static void parse_gatt_export(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
parse_config_string(config, "GATT", "ExportClaimedServices", &str);
if (!str)
return;
btd_opts.gatt_export = parse_gatt_export_str(str);
- g_free(str);
}
static uint8_t parse_gatt_seclevel_str(const char *str)
@@ -1176,7 +1152,7 @@ static uint8_t parse_gatt_seclevel_str(const char *str)
static void parse_gatt_seclevel(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
if (!btd_opts.testing)
return;
@@ -1186,7 +1162,6 @@ static void parse_gatt_seclevel(GKeyFile *config)
return;
btd_opts.gatt_seclevel = parse_gatt_seclevel_str(str);
- g_free(str);
}
static void parse_gatt(GKeyFile *config)
@@ -1204,7 +1179,7 @@ static void parse_gatt(GKeyFile *config)
static void parse_csis_sirk(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
if (!parse_config_string(config, "CSIS", "SIRK", &str))
return;
@@ -1213,8 +1188,6 @@ static void parse_csis_sirk(GKeyFile *config)
hex2bin(str, btd_opts.csis.sirk, sizeof(btd_opts.csis.sirk));
else if (!gen_sirk(str))
DBG("Unable to generate SIRK from string");
-
- g_free(str);
}
static void parse_csis(GKeyFile *config)
@@ -1231,8 +1204,8 @@ static void parse_csis(GKeyFile *config)
static bool parse_cs_role(GKeyFile *config, const char *group,
const char *key, uint8_t *val)
{
- GError *err = NULL;
- char *str = NULL;
+ _cleanup_type_(GError) GError *err = NULL;
+ _cleanup_(g_free) char *str = NULL;
char *endptr = NULL;
int numeric_val;
@@ -1241,7 +1214,6 @@ static bool parse_cs_role(GKeyFile *config, const char *group,
if (err) {
if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
DBG("%s", err->message);
- g_error_free(err);
return false;
}
@@ -1251,17 +1223,14 @@ static bool parse_cs_role(GKeyFile *config, const char *group,
if (!strcmp(str, "Initiator") || !strcmp(str, "initiator")) {
if (val)
*val = 1;
- g_free(str);
return true;
} else if (!strcmp(str, "Reflector") || !strcmp(str, "reflector")) {
if (val)
*val = 2;
- g_free(str);
return true;
} else if (!strcmp(str, "Both") || !strcmp(str, "both")) {
if (val)
*val = 3;
- g_free(str);
return true;
}
@@ -1272,7 +1241,6 @@ static bool parse_cs_role(GKeyFile *config, const char *group,
warn("%s.%s = %s is not a valid value. "
"Expected: 1/Initiator, 2/Reflector, or 3/Both",
group, key, str);
- g_free(str);
return false;
}
@@ -1280,14 +1248,12 @@ static bool parse_cs_role(GKeyFile *config, const char *group,
warn("%s.%s = %d is out of range. "
"Valid values: 1 (Initiator), 2 (Reflector), 3 (Both)",
group, key, numeric_val);
- g_free(str);
return false;
}
if (val)
*val = numeric_val;
- g_free(str);
return true;
}
@@ -1305,7 +1271,7 @@ static void parse_le_cs_config(GKeyFile *config)
static void parse_avdtp_session_mode(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
if (!parse_config_string(config, "AVDTP", "SessionMode", &str))
return;
@@ -1318,13 +1284,11 @@ static void parse_avdtp_session_mode(GKeyFile *config)
DBG("Invalid mode option: %s", str);
btd_opts.avdtp.session_mode = BT_IO_MODE_BASIC;
}
-
- g_free(str);
}
static void parse_avdtp_stream_mode(GKeyFile *config)
{
- char *str = NULL;
+ _cleanup_(g_free) char *str = NULL;
if (!parse_config_string(config, "AVDTP", "StreamMode", &str))
return;
@@ -1337,8 +1301,6 @@ static void parse_avdtp_stream_mode(GKeyFile *config)
DBG("Invalid mode option: %s", str);
btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC;
}
-
- g_free(str);
}
static void parse_avdtp(GKeyFile *config)
@@ -1605,7 +1567,7 @@ static GOptionEntry options[] = {
int main(int argc, char *argv[])
{
GOptionContext *context;
- GError *err = NULL;
+ _cleanup_type_(GError) GError *err = NULL;
uint16_t sdp_mtu = 0;
uint32_t sdp_flags = 0;
int gdbus_flags = 0;
@@ -1618,7 +1580,6 @@ int main(int argc, char *argv[])
if (g_option_context_parse(context, &argc, &argv, &err) == FALSE) {
if (err != NULL) {
g_printerr("%s\n", err->message);
- g_error_free(err);
} else
g_printerr("An unknown error occurred\n");
exit(1);
--
2.54.0
^ permalink raw reply related
* [PATCH v1] Bluetooth: btintel_pcie: Simplify MAC access request/release
From: Kiran K @ 2026-05-11 13:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: ravishankar.srivatsa, chethan.tumkur.narayan, Kiran K
Drop the STOP_MAC_ACCESS_DIS and XTAL_CLK_REQ bit manipulations from
btintel_pcie_get_mac_access() and btintel_pcie_release_mac_access().
These bits are no longer required to be toggled by the host driver for
MAC access on the supported parts; the controller manages them
internally.
Also fix the idempotency check in btintel_pcie_get_mac_access(): only
assert MAC_ACCESS_REQ if it is not already set, instead of keying the
read-modify-write off the MAC_ACCESS_STS bit (which reflects grant,
not request, state).
Remove the now-unused STOP_MAC_ACCESS_DIS and XTAL_CLK_REQ register
defines from btintel_pcie.h.
Signed-off-by: Kiran K <kiran.k@intel.com>
---
drivers/bluetooth/btintel_pcie.c | 10 +---------
drivers/bluetooth/btintel_pcie.h | 3 ---
2 files changed, 1 insertion(+), 12 deletions(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index fda474406003..53a4ad80b871 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -594,9 +594,7 @@ static int btintel_pcie_get_mac_access(struct btintel_pcie_data *data)
reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
- reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS;
- reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ;
- if ((reg & BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_STS) == 0)
+ if (!(reg & BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ))
reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ;
btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);
@@ -622,12 +620,6 @@ static void btintel_pcie_release_mac_access(struct btintel_pcie_data *data)
if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ)
reg &= ~BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ;
- if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS)
- reg &= ~BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS;
-
- if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ)
- reg &= ~BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ;
-
btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);
}
diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h
index 2db85f71b2f8..7fc8c46ed689 100644
--- a/drivers/bluetooth/btintel_pcie.h
+++ b/drivers/bluetooth/btintel_pcie.h
@@ -34,9 +34,6 @@
#define BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_STS (BIT(20))
#define BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ (BIT(21))
-/* Stop MAC Access disconnection request */
-#define BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS (BIT(22))
-#define BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ (BIT(23))
#define BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_STS (BIT(28))
#define BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_DISCON (BIT(29))
--
2.53.0
^ permalink raw reply related
* [PATCH v1] Bluetooth: btintel_pcie: Reset controller before configuring MSI-X
From: Kiran K @ 2026-05-11 13:27 UTC (permalink / raw)
To: linux-bluetooth
Cc: ravishankar.srivatsa, chethan.tumkur.narayan, aluvala.sai.teja,
Kiran K
From: Sai Teja Aluvala <aluvala.sai.teja@intel.com>
Perform the shared hardware reset in btintel_pcie_probe() before
configuring MSI-X so the controller starts from a known clean state.
While here, move btintel_pcie_config_msix() out of
btintel_pcie_config_pcie() and into the probe sequence, and propagate
errors from btintel_pcie_reset_bt() so probe fails cleanly if the
shared HW reset does not complete.
Signed-off-by: Sai Teja Aluvala <aluvala.sai.teja@intel.com>
Signed-off-by: Kiran K <kiran.k@intel.com>
---
drivers/bluetooth/btintel_pcie.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index fda474406003..6ff08de9ec78 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -1646,9 +1646,6 @@ static int btintel_pcie_config_pcie(struct pci_dev *pdev,
if (err)
return err;
- /* Configure MSI-X with causes list */
- btintel_pcie_config_msix(data);
-
return 0;
}
@@ -2659,6 +2656,14 @@ static int btintel_pcie_probe(struct pci_dev *pdev,
if (err)
goto exit_error;
+ err = btintel_pcie_reset_bt(data);
+ if (err) {
+ dev_err(&pdev->dev, "Bluetooth shared HW reset failed (%d)\n", err);
+ goto exit_error;
+ }
+
+ /* Configure MSI-X with causes list */
+ btintel_pcie_config_msix(data);
pci_set_drvdata(pdev, data);
err = btintel_pcie_alloc(data);
--
2.53.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox