Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH] Bluetooth: mgmt: copy pending command data under the list lock
From: Luiz Augusto von Dentz @ 2026-06-18 15:46 UTC (permalink / raw)
  To: Cen Zhang; +Cc: Marcel Holtmann, linux-bluetooth, linux-kernel, baijiaju1990
In-Reply-To: <20260618102134.3339999-1-zzzccc427@gmail.com>

Hi Cen,

On Thu, Jun 18, 2026 at 6:21 AM Cen Zhang <zzzccc427@gmail.com> wrote:
>
> mgmt_pending_find() only protects the pending list lookup. Once it
> returns, a caller that dereferences the returned command has no lifetime
> guarantee unless another lock or ownership transfer keeps the command from
> being removed and freed.
>
> mgmt_powering_down() only needs the requested SET_POWERED mode, but it
> currently keeps the raw pending command pointer after the list lock has
> been dropped and then reads cmd->param and cp->val.
>
> The buggy scenario involves two paths, with each column showing the order
> within that path:
>
> hci_suspend_dev()/hci_resume_dev():     SET_POWERED completion:
>   1. mgmt_powering_down() calls           1. mgmt_set_powered_complete()
>      pending_find()
>   2. pending_find() drops                 2. mgmt_pending_valid() delists
>      mgmt_pending_lock                       the command
>                                           3. mgmt_pending_free() frees the
>                                              command and parameter buffer
>   3. mgmt_powering_down() reads
>      cmd->param
>   4. mgmt_powering_down() reads
>      cp->val
>
> Add a helper that copies a requested pending-command parameter slice while
> mgmt_pending_lock is still held. Use it for the mgmt_mode readers in
> mgmt.c so they take a snapshot of the pending request instead of keeping an
> unlocked raw command pointer just to inspect the requested mode.
>
> Validation reproduced this kernel report:
> BUG: KASAN: slab-use-after-free in mgmt_powering_down+0xa0/0xf0
>
> Call Trace:
>  <TASK>
>  dump_stack_lvl+0x66/0xa0
>  print_report+0xce/0x5f0
>  ? mgmt_powering_down+0xa0/0xf0
>  ? srso_alias_return_thunk+0x5/0xfbef5
>  ? __virt_addr_valid+0x19f/0x330
>  ? mgmt_powering_down+0xa0/0xf0
>  kasan_report+0xe0/0x110
>  ? mgmt_powering_down+0xa0/0xf0
>  mgmt_powering_down+0xa0/0xf0
>  hci_suspend_dev+0xc0/0x2d0
>  ? vhci_suspend_work+0x31/0x50
>  process_one_work+0x4fd/0xbc0
>  ? __pfx_process_one_work+0x10/0x10
>  ? srso_alias_return_thunk+0x5/0xfbef5
>  ? srso_alias_return_thunk+0x5/0xfbef5
>  ? __list_add_valid_or_report+0x37/0xf0
>  ? __pfx_vhci_suspend_work+0x10/0x10
>  ? srso_alias_return_thunk+0x5/0xfbef5
>  worker_thread+0x2d8/0x570
>  ? srso_alias_return_thunk+0x5/0xfbef5
>  ? __pfx_worker_thread+0x10/0x10
>  kthread+0x1ad/0x1f0
>  ? __pfx_kthread+0x10/0x10
>  ret_from_fork+0x3c9/0x540
>  ? __pfx_ret_from_fork+0x10/0x10
>  ? srso_alias_return_thunk+0x5/0xfbef5
>  ? __switch_to+0x2e9/0x730
>  ? __pfx_kthread+0x10/0x10
>  ret_from_fork_asm+0x1a/0x30
>  </TASK>
>
> Allocated by task 336 on cpu 2 at 98.764916s:
>  kasan_save_stack+0x33/0x60
>  kasan_save_track+0x17/0x60
>  __kasan_kmalloc+0xaa/0xb0
>  mgmt_pending_new+0x44/0x130
>  mgmt_pending_add+0x22/0x110
>  set_powered+0x1ad/0x310
>  hci_sock_sendmsg+0x96b/0xf80
>  sock_write_iter+0x28e/0x2a0
>  do_iter_readv_writev+0x211/0x390
>  vfs_writev+0x266/0x7b0
>  do_writev+0x191/0x1d0
>  do_syscall_64+0x115/0x6a0
>  entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
> Freed by task 314 on cpu 0 at 101.816391s:
>  kasan_save_stack+0x33/0x60
>  kasan_save_track+0x17/0x60
>  kasan_save_free_info+0x3b/0x60
>  __kasan_slab_free+0x5f/0x80
>  kfree+0x313/0x590
>  mgmt_pending_foreach+0x144/0x190
>  __mgmt_power_off+0xca/0x250
>  hci_dev_close_sync+0x8ba/0xb00
>  hci_set_powered_sync+0x384/0x480
>  hci_cmd_sync_work+0x187/0x210
>  process_one_work+0x4fd/0xbc0
>  worker_thread+0x2d8/0x570
>  kthread+0x1ad/0x1f0
>  ret_from_fork+0x3c9/0x540
>  ret_from_fork_asm+0x1a/0x30
>
> Assisted-by: Codex:gpt-5.5
> Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
> ---
>  net/bluetooth/mgmt.c      | 37 ++++++++++++++++++-------------------
>  net/bluetooth/mgmt_util.c | 27 +++++++++++++++++++++++++++
>  net/bluetooth/mgmt_util.h |  2 ++
>  3 files changed, 47 insertions(+), 19 deletions(-)
>
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index d23ca1dd0893..91272640864a 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -960,19 +960,25 @@ static struct mgmt_pending_cmd *pending_find(u16 opcode, struct hci_dev *hdev)
>         return mgmt_pending_find(HCI_CHANNEL_CONTROL, opcode, hdev);
>  }
>
> +static bool pending_find_copy(u16 opcode, struct hci_dev *hdev, void *data,
> +                             size_t len)
> +{
> +       return mgmt_pending_find_copy(HCI_CHANNEL_CONTROL, opcode, hdev,
> +                                     data, len);
> +}
> +
>  u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev)
>  {
> -       struct mgmt_pending_cmd *cmd;
> +       struct mgmt_mode cp;
>
>         /* If there's a pending mgmt command the flags will not yet have
>          * their final values, so check for this first.
>          */
> -       cmd = pending_find(MGMT_OP_SET_DISCOVERABLE, hdev);
> -       if (cmd) {
> -               struct mgmt_mode *cp = cmd->param;
> -               if (cp->val == 0x01)
> +       if (pending_find_copy(MGMT_OP_SET_DISCOVERABLE, hdev, &cp,
> +                             sizeof(cp))) {
> +               if (cp.val == 0x01)
>                         return LE_AD_GENERAL;
> -               else if (cp->val == 0x02)
> +               else if (cp.val == 0x02)
>                         return LE_AD_LIMITED;
>         } else {
>                 if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
> @@ -986,17 +992,13 @@ u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev)
>
>  bool mgmt_get_connectable(struct hci_dev *hdev)
>  {
> -       struct mgmt_pending_cmd *cmd;
> +       struct mgmt_mode cp;
>
>         /* If there's a pending mgmt command the flag will not yet have
>          * it's final value, so check for this first.
>          */
> -       cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
> -       if (cmd) {
> -               struct mgmt_mode *cp = cmd->param;
> -
> -               return cp->val;
> -       }
> +       if (pending_find_copy(MGMT_OP_SET_CONNECTABLE, hdev, &cp, sizeof(cp)))
> +               return cp.val;
>
>         return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
>  }
> @@ -9826,18 +9828,15 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data)
>
>  bool mgmt_powering_down(struct hci_dev *hdev)
>  {
> -       struct mgmt_pending_cmd *cmd;
> -       struct mgmt_mode *cp;
> +       struct mgmt_mode cp;
>
>         if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN))
>                 return true;
>
> -       cmd = pending_find(MGMT_OP_SET_POWERED, hdev);
> -       if (!cmd)
> +       if (!pending_find_copy(MGMT_OP_SET_POWERED, hdev, &cp, sizeof(cp)))
>                 return false;
>
> -       cp = cmd->param;
> -       if (!cp->val)
> +       if (!cp.val)
>                 return true;
>
>         return false;
> diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c
> index 6ea107c0e054..5d6d13ccadd2 100644
> --- a/net/bluetooth/mgmt_util.c
> +++ b/net/bluetooth/mgmt_util.c
> @@ -233,6 +233,33 @@ struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
>         return NULL;
>  }
>
> +bool mgmt_pending_find_copy(unsigned short channel, u16 opcode,
> +                           struct hci_dev *hdev, void *data, size_t len)
> +{
> +       struct mgmt_pending_cmd *cmd, *tmp;
> +       bool found = false;
> +
> +       mutex_lock(&hdev->mgmt_pending_lock);
> +
> +       list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
> +               if (hci_sock_get_channel(cmd->sk) != channel)
> +                       continue;
> +
> +               if (cmd->opcode != opcode)
> +                       continue;
> +
> +               if (cmd->param_len >= len) {
> +                       memcpy(data, cmd->param, len);
> +                       found = true;
> +               }
> +               break;
> +       }
> +
> +       mutex_unlock(&hdev->mgmt_pending_lock);
> +
> +       return found;
> +}

Or we could just add a kref to mgmt_pending_cmd so mgmt_pending_find
can return a reference which is then unref'd when finished accessing
it.

>  void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove,
>                           void (*cb)(struct mgmt_pending_cmd *cmd, void *data),
>                           void *data)
> diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h
> index 20810cf06e81..4cccb71c8a1f 100644
> --- a/net/bluetooth/mgmt_util.h
> +++ b/net/bluetooth/mgmt_util.h
> @@ -51,6 +51,8 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
>
>  struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
>                                            struct hci_dev *hdev);
> +bool mgmt_pending_find_copy(unsigned short channel, u16 opcode,
> +                           struct hci_dev *hdev, void *data, size_t len);
>  void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove,
>                           void (*cb)(struct mgmt_pending_cmd *cmd, void *data),
>                           void *data);
> --
> 2.43.0
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH BlueZ] set: Abandon the use of the existing set gatt-db
From: Luiz Augusto von Dentz @ 2026-06-18 13:33 UTC (permalink / raw)
  To: zhangchen200426; +Cc: linux-bluetooth, Chen Zhang
In-Reply-To: <20260618025239.420860-1-zhangchen200426@163.com>

Hi,

On Wed, Jun 17, 2026 at 10:53 PM <zhangchen200426@163.com> wrote:
>
> From: Chen Zhang <zhangchen01@kylinos.cn>
>
> When pairing and connecting a pair of earbuds, if you attempt to connect the
> second earbud while one earbud is already connected, reusing the existing
> set gatt-db will interrupt the GATT procedure. Subsequently, the attribute
> values will no longer be read, and the ASE state will not switch. This will
> eventually prevent the second earbud from creating a CIS, resulting in no sound
> output from the later-connected earbud during music playback.

Why would it prevent any operation of the ASE though? Perhaps we have
a different problem and this change is just a workaround. Anyway, the
intent is to prevent only the discovery procedure not ASE procedures.

> Signed-off-by: Zhang Chen <zhangchen01@kylinos.cn>
> ---
>  src/set.c | 14 --------------
>  1 file changed, 14 deletions(-)
>
> diff --git a/src/set.c b/src/set.c
> index 4ca2f78c3..0f2e9613c 100644
> --- a/src/set.c
> +++ b/src/set.c
> @@ -282,20 +282,6 @@ static void foreach_rsi(void *data, void *user_data)
>         if (memcmp(ad->data, res, sizeof(res)))
>                 return;
>
> -       /* Attempt to use existing gatt_db from set if device has never been
> -        * connected before.
> -        *
> -        * If dbs don't really match bt_gatt_client will attempt to rediscover
> -        * the ranges that don't match.
> -        */
> -       if (gatt_db_isempty(btd_device_get_gatt_db(set->device))) {
> -               struct btd_device *device;
> -
> -               device = queue_get_entries(set->devices)->data;
> -               btd_device_set_gatt_db(set->device,
> -                                       btd_device_get_gatt_db(device));
> -       }
> -
>         device_connect_le(set->device);
>  }
>
> --
> 2.25.1
>
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* RE: Bluetooth: hci_debugfs: serialize force_bredr_smp writes
From: bluez.test.bot @ 2026-06-18 13:21 UTC (permalink / raw)
  To: linux-bluetooth, zzzccc427
In-Reply-To: <20260618102150.3340673-1-zzzccc427@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 3165 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=1113387

---Test result---

Test Summary:
CheckPatch                    FAIL      0.53 seconds
VerifyFixes                   PASS      0.06 seconds
VerifySignedoff               PASS      0.06 seconds
GitLint                       PASS      0.18 seconds
SubjectPrefix                 PASS      0.05 seconds
BuildKernel                   PASS      26.74 seconds
CheckAllWarning               PASS      29.66 seconds
CheckSparse                   PASS      27.99 seconds
BuildKernel32                 PASS      25.94 seconds
CheckKernelLLVM               SKIP      0.00 seconds
TestRunnerSetup               PASS      581.10 seconds
TestRunner_l2cap-tester       PASS      60.19 seconds
TestRunner_iso-tester         PASS      79.55 seconds
TestRunner_bnep-tester        PASS      18.66 seconds
TestRunner_mgmt-tester        FAIL      212.01 seconds
TestRunner_rfcomm-tester      PASS      24.97 seconds
TestRunner_sco-tester         PASS      32.66 seconds
TestRunner_ioctl-tester       PASS      28.46 seconds
TestRunner_mesh-tester        FAIL      25.84 seconds
TestRunner_smp-tester         PASS      23.43 seconds
TestRunner_userchan-tester    PASS      19.82 seconds
TestRunner_6lowpan-tester     PASS      22.93 seconds
IncrementalBuild              PASS      25.13 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
Bluetooth: hci_debugfs: serialize force_bredr_smp writes
WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?)
#108: 
  2. test HCI_FORCE_BREDR_SMP as set        2. test HCI_FORCE_BREDR_SMP as set

total: 0 errors, 1 warnings, 0 checks, 9 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/14635033.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.


##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4

Failed Test Cases
Read Exp Feature - Success                           Failed       0.245 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0

Failed Test Cases
Mesh - Send cancel - 1                               Timed out    2.549 seconds
Mesh - Send cancel - 2                               Timed out    1.982 seconds


https://github.com/bluez/bluetooth-next/pull/332

---
Regards,
Linux Bluetooth


^ permalink raw reply

* RE: Bluetooth: mgmt: copy pending command data under the list lock
From: bluez.test.bot @ 2026-06-18 13:20 UTC (permalink / raw)
  To: linux-bluetooth, zzzccc427
In-Reply-To: <20260618102134.3339999-1-zzzccc427@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 3087 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=1113386

---Test result---

Test Summary:
CheckPatch                    FAIL      1.09 seconds
VerifyFixes                   PASS      0.10 seconds
VerifySignedoff               PASS      0.10 seconds
GitLint                       PASS      0.26 seconds
SubjectPrefix                 PASS      0.09 seconds
BuildKernel                   PASS      27.00 seconds
CheckAllWarning               PASS      29.02 seconds
CheckSparse                   PASS      28.07 seconds
BuildKernel32                 PASS      25.88 seconds
CheckKernelLLVM               SKIP      0.00 seconds
TestRunnerSetup               PASS      575.19 seconds
TestRunner_l2cap-tester       PASS      57.33 seconds
TestRunner_iso-tester         PASS      77.04 seconds
TestRunner_bnep-tester        PASS      18.66 seconds
TestRunner_mgmt-tester        FAIL      207.50 seconds
TestRunner_rfcomm-tester      PASS      25.16 seconds
TestRunner_sco-tester         PASS      31.86 seconds
TestRunner_ioctl-tester       PASS      25.58 seconds
TestRunner_mesh-tester        FAIL      25.86 seconds
TestRunner_smp-tester         PASS      22.94 seconds
TestRunner_userchan-tester    PASS      20.24 seconds
TestRunner_6lowpan-tester     PASS      22.17 seconds
IncrementalBuild              PASS      25.48 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
Bluetooth: mgmt: copy pending command data under the list lock
WARNING: The commit message has 'Call Trace:', perhaps it also needs a 'Fixes:' tag?

total: 0 errors, 1 warnings, 0 checks, 113 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/14635032.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.


##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4

Failed Test Cases
Read Exp Feature - Success                           Failed       0.237 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0

Failed Test Cases
Mesh - Send cancel - 1                               Timed out    2.645 seconds
Mesh - Send cancel - 2                               Timed out    1.990 seconds


https://github.com/bluez/bluetooth-next/pull/331

---
Regards,
Linux Bluetooth


^ permalink raw reply

* RE: Add PCIe M.2 Key E connector support for NXP i.MX boards
From: bluez.test.bot @ 2026-06-18 12:45 UTC (permalink / raw)
  To: linux-bluetooth, sherry.sun
In-Reply-To: <20260618101047.4185497-2-sherry.sun@oss.nxp.com>

[-- Attachment #1: Type: text/plain, Size: 577 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: drivers/pci/controller/dwc/pci-imx6.c:1382
error: drivers/pci/controller/dwc/pci-imx6.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

* RE: [BlueZ,v1] shared/rap: Fix Mode 0 step serialization
From: bluez.test.bot @ 2026-06-18 11:48 UTC (permalink / raw)
  To: linux-bluetooth, prathibha.madugonde
In-Reply-To: <20260618075529.98419-1-prathm@qti.qualcomm.com>

[-- Attachment #1: Type: text/plain, Size: 989 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=1113283

---Test result---

Test Summary:
CheckPatch                    PASS      0.30 seconds
GitLint                       PASS      0.20 seconds
BuildEll                      PASS      20.73 seconds
BluezMake                     PASS      658.34 seconds
MakeCheck                     PASS      0.95 seconds
MakeDistcheck                 PASS      246.72 seconds
CheckValgrind                 PASS      222.75 seconds
CheckSmatch                   PASS      350.52 seconds
bluezmakeextell               PASS      185.67 seconds
IncrementalBuild              PASS      663.38 seconds
ScanBuild                     PASS      1039.96 seconds



https://github.com/bluez/bluez/pull/2239

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [bluez/bluez] 14e39d: shared/rap: Fix Mode 0 step serialization
From: prathibhamadugonde @ 2026-06-18 10:51 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1113283
  Home:   https://github.com/bluez/bluez
  Commit: 14e39d635f2c1d426c7abe8b8d423d5b2efe1db8
      https://github.com/bluez/bluez/commit/14e39d635f2c1d426c7abe8b8d423d5b2efe1db8
  Author: Prathibha Madugonde <prathibha.madugonde@oss.qualcomm.com>
  Date:   2026-06-18 (Thu, 18 Jun 2026)

  Changed paths:
    M src/shared/rap.c

  Log Message:
  -----------
  shared/rap: Fix Mode 0 step serialization

Replace raw struct byte dump with field-by-field serialization
that conditionally includes init_measured_freq_offset only for
the Initiator role, matching the RAS wire format (5 bytes for
Initiator, 3 bytes for Reflector)



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply

* RE: [v2,1/2] Bluetooth: hci_core: Add reset_type parameter to hdev->reset() callback
From: bluez.test.bot @ 2026-06-18 10:25 UTC (permalink / raw)
  To: linux-bluetooth, chandrashekar.devegowda
In-Reply-To: <20260618085016.9173-1-chandrashekar.devegowda@intel.com>

[-- Attachment #1: Type: text/plain, Size: 2389 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=1113309

---Test result---

Test Summary:
CheckPatch                    PASS      3.18 seconds
VerifyFixes                   PASS      0.07 seconds
VerifySignedoff               PASS      0.07 seconds
GitLint                       PASS      0.40 seconds
SubjectPrefix                 PASS      0.12 seconds
BuildKernel                   PASS      26.91 seconds
CheckAllWarning               PASS      30.25 seconds
CheckSparse                   PASS      28.70 seconds
BuildKernel32                 PASS      26.46 seconds
CheckKernelLLVM               SKIP      0.00 seconds
TestRunnerSetup               PASS      581.35 seconds
TestRunner_l2cap-tester       PASS      58.38 seconds
TestRunner_iso-tester         PASS      92.91 seconds
TestRunner_bnep-tester        PASS      18.82 seconds
TestRunner_mgmt-tester        FAIL      208.89 seconds
TestRunner_rfcomm-tester      PASS      25.41 seconds
TestRunner_sco-tester         PASS      33.27 seconds
TestRunner_ioctl-tester       PASS      25.48 seconds
TestRunner_mesh-tester        FAIL      25.95 seconds
TestRunner_smp-tester         PASS      23.08 seconds
TestRunner_userchan-tester    PASS      19.83 seconds
TestRunner_6lowpan-tester     PASS      22.69 seconds
IncrementalBuild              PASS      27.01 seconds

Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4

Failed Test Cases
Read Exp Feature - Success                           Failed       0.236 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0

Failed Test Cases
Mesh - Send cancel - 1                               Timed out    2.705 seconds
Mesh - Send cancel - 2                               Timed out    1.985 seconds


https://github.com/bluez/bluetooth-next/pull/330

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [PATCH] Bluetooth: hci_debugfs: serialize force_bredr_smp writes
From: Cen Zhang @ 2026-06-18 10:21 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: linux-bluetooth, baijiaju1990, zzzccc427

force_bredr_smp_write() calls smp_force_bredr() without hci_dev_lock().
That helper checks HCI_FORCE_BREDR_SMP, updates hdev->smp_bredr_data, and
then toggles the force flag.  Two same-value writers can therefore both
pass the -EALREADY gate and run the same enable or disable transition on
one hdev.

The buggy scenario involves two paths, with each column showing the order
within that path:

debugfs writer A:                         debugfs writer B:
  1. parse enable = false                   1. parse enable = false
  2. test HCI_FORCE_BREDR_SMP as set        2. test HCI_FORCE_BREDR_SMP as set
  3. read hdev->smp_bredr_data              3. read hdev->smp_bredr_data
  4. clear hdev->smp_bredr_data             4. clear hdev->smp_bredr_data
  5. call smp_del_chan(chan)                5. call smp_del_chan(chan)
  6. toggle HCI_FORCE_BREDR_SMP             6. toggle HCI_FORCE_BREDR_SMP

If writer B reaches step 3 after writer A has cleared
hdev->smp_bredr_data but before writer A toggles HCI_FORCE_BREDR_SMP,
writer B still passed the old flag check and can pass NULL into
smp_del_chan().  The double toggle can also leave the force flag
mismatched with the requested state.

Take hci_dev_lock() around smp_force_bredr() in the debugfs write path so
each request observes and applies one stable BR/EDR SMP transition.

Validation reproduced this kernel report:
KASAN null-ptr-deref in smp_del_chan+0x31/0x90
RIP: 0033:0x7faae680d340
RIP: 0010:smp_del_chan+0x31/0x90 [bluetooth]
Read of size 8
Call trace:
  dump_stack_lvl+0x66/0xa0
  kasan_report+0xe0/0x110
  smp_del_chan+0x31/0x90
  smp_force_bredr+0x69/0xc0
  trace_clock_x86_tsc+0x20/0x20
  srso_alias_return_thunk+0x5/0xfbef5
  lock_acquire+0xd0/0x300
  ksys_write+0xd2/0x170
  full_proxy_write+0x9e/0xd0
  vfs_write+0x1b0/0x810
  find_held_lock+0x2b/0x80
  do_user_addr_fault+0x65a/0x890
  rcu_is_watching+0x20/0x50
  do_syscall_64+0x115/0x6a0 (arch/x86/entry/syscall_64.c:87)
  entry_SYSCALL_64_after_hwframe+0x77/0x7f

Fixes: 300acfdec916 ("Bluetooth: Introduce force_bredr_smp debugfs option for testing")
Assisted-by: Codex:gpt-5.5
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
 net/bluetooth/hci_debugfs.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
index 99e2e9fc70e8..89cc93f5984e 100644
--- a/net/bluetooth/hci_debugfs.c
+++ b/net/bluetooth/hci_debugfs.c
@@ -524,7 +524,9 @@ static ssize_t force_bredr_smp_write(struct file *file,
 	if (err)
 		return err;
 
+	hci_dev_lock(hdev);
 	err = smp_force_bredr(hdev, enable);
+	hci_dev_unlock(hdev);
 	if (err)
 		return err;
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH] Bluetooth: mgmt: copy pending command data under the list lock
From: Cen Zhang @ 2026-06-18 10:21 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: linux-bluetooth, linux-kernel, baijiaju1990, zzzccc427

mgmt_pending_find() only protects the pending list lookup. Once it
returns, a caller that dereferences the returned command has no lifetime
guarantee unless another lock or ownership transfer keeps the command from
being removed and freed.

mgmt_powering_down() only needs the requested SET_POWERED mode, but it
currently keeps the raw pending command pointer after the list lock has
been dropped and then reads cmd->param and cp->val.

The buggy scenario involves two paths, with each column showing the order
within that path:

hci_suspend_dev()/hci_resume_dev():     SET_POWERED completion:
  1. mgmt_powering_down() calls           1. mgmt_set_powered_complete()
     pending_find()
  2. pending_find() drops                 2. mgmt_pending_valid() delists
     mgmt_pending_lock                       the command
                                          3. mgmt_pending_free() frees the
                                             command and parameter buffer
  3. mgmt_powering_down() reads
     cmd->param
  4. mgmt_powering_down() reads
     cp->val

Add a helper that copies a requested pending-command parameter slice while
mgmt_pending_lock is still held. Use it for the mgmt_mode readers in
mgmt.c so they take a snapshot of the pending request instead of keeping an
unlocked raw command pointer just to inspect the requested mode.

Validation reproduced this kernel report:
BUG: KASAN: slab-use-after-free in mgmt_powering_down+0xa0/0xf0

Call Trace:
 <TASK>
 dump_stack_lvl+0x66/0xa0
 print_report+0xce/0x5f0
 ? mgmt_powering_down+0xa0/0xf0
 ? srso_alias_return_thunk+0x5/0xfbef5
 ? __virt_addr_valid+0x19f/0x330
 ? mgmt_powering_down+0xa0/0xf0
 kasan_report+0xe0/0x110
 ? mgmt_powering_down+0xa0/0xf0
 mgmt_powering_down+0xa0/0xf0
 hci_suspend_dev+0xc0/0x2d0
 ? vhci_suspend_work+0x31/0x50
 process_one_work+0x4fd/0xbc0
 ? __pfx_process_one_work+0x10/0x10
 ? srso_alias_return_thunk+0x5/0xfbef5
 ? srso_alias_return_thunk+0x5/0xfbef5
 ? __list_add_valid_or_report+0x37/0xf0
 ? __pfx_vhci_suspend_work+0x10/0x10
 ? srso_alias_return_thunk+0x5/0xfbef5
 worker_thread+0x2d8/0x570
 ? srso_alias_return_thunk+0x5/0xfbef5
 ? __pfx_worker_thread+0x10/0x10
 kthread+0x1ad/0x1f0
 ? __pfx_kthread+0x10/0x10
 ret_from_fork+0x3c9/0x540
 ? __pfx_ret_from_fork+0x10/0x10
 ? srso_alias_return_thunk+0x5/0xfbef5
 ? __switch_to+0x2e9/0x730
 ? __pfx_kthread+0x10/0x10
 ret_from_fork_asm+0x1a/0x30
 </TASK>

Allocated by task 336 on cpu 2 at 98.764916s:
 kasan_save_stack+0x33/0x60
 kasan_save_track+0x17/0x60
 __kasan_kmalloc+0xaa/0xb0
 mgmt_pending_new+0x44/0x130
 mgmt_pending_add+0x22/0x110
 set_powered+0x1ad/0x310
 hci_sock_sendmsg+0x96b/0xf80
 sock_write_iter+0x28e/0x2a0
 do_iter_readv_writev+0x211/0x390
 vfs_writev+0x266/0x7b0
 do_writev+0x191/0x1d0
 do_syscall_64+0x115/0x6a0
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

Freed by task 314 on cpu 0 at 101.816391s:
 kasan_save_stack+0x33/0x60
 kasan_save_track+0x17/0x60
 kasan_save_free_info+0x3b/0x60
 __kasan_slab_free+0x5f/0x80
 kfree+0x313/0x590
 mgmt_pending_foreach+0x144/0x190
 __mgmt_power_off+0xca/0x250
 hci_dev_close_sync+0x8ba/0xb00
 hci_set_powered_sync+0x384/0x480
 hci_cmd_sync_work+0x187/0x210
 process_one_work+0x4fd/0xbc0
 worker_thread+0x2d8/0x570
 kthread+0x1ad/0x1f0
 ret_from_fork+0x3c9/0x540
 ret_from_fork_asm+0x1a/0x30

Assisted-by: Codex:gpt-5.5
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
 net/bluetooth/mgmt.c      | 37 ++++++++++++++++++-------------------
 net/bluetooth/mgmt_util.c | 27 +++++++++++++++++++++++++++
 net/bluetooth/mgmt_util.h |  2 ++
 3 files changed, 47 insertions(+), 19 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d23ca1dd0893..91272640864a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -960,19 +960,25 @@ static struct mgmt_pending_cmd *pending_find(u16 opcode, struct hci_dev *hdev)
 	return mgmt_pending_find(HCI_CHANNEL_CONTROL, opcode, hdev);
 }
 
+static bool pending_find_copy(u16 opcode, struct hci_dev *hdev, void *data,
+			      size_t len)
+{
+	return mgmt_pending_find_copy(HCI_CHANNEL_CONTROL, opcode, hdev,
+				      data, len);
+}
+
 u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev)
 {
-	struct mgmt_pending_cmd *cmd;
+	struct mgmt_mode cp;
 
 	/* If there's a pending mgmt command the flags will not yet have
 	 * their final values, so check for this first.
 	 */
-	cmd = pending_find(MGMT_OP_SET_DISCOVERABLE, hdev);
-	if (cmd) {
-		struct mgmt_mode *cp = cmd->param;
-		if (cp->val == 0x01)
+	if (pending_find_copy(MGMT_OP_SET_DISCOVERABLE, hdev, &cp,
+			      sizeof(cp))) {
+		if (cp.val == 0x01)
 			return LE_AD_GENERAL;
-		else if (cp->val == 0x02)
+		else if (cp.val == 0x02)
 			return LE_AD_LIMITED;
 	} else {
 		if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
@@ -986,17 +992,13 @@ u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev)
 
 bool mgmt_get_connectable(struct hci_dev *hdev)
 {
-	struct mgmt_pending_cmd *cmd;
+	struct mgmt_mode cp;
 
 	/* If there's a pending mgmt command the flag will not yet have
 	 * it's final value, so check for this first.
 	 */
-	cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
-	if (cmd) {
-		struct mgmt_mode *cp = cmd->param;
-
-		return cp->val;
-	}
+	if (pending_find_copy(MGMT_OP_SET_CONNECTABLE, hdev, &cp, sizeof(cp)))
+		return cp.val;
 
 	return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
 }
@@ -9826,18 +9828,15 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data)
 
 bool mgmt_powering_down(struct hci_dev *hdev)
 {
-	struct mgmt_pending_cmd *cmd;
-	struct mgmt_mode *cp;
+	struct mgmt_mode cp;
 
 	if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN))
 		return true;
 
-	cmd = pending_find(MGMT_OP_SET_POWERED, hdev);
-	if (!cmd)
+	if (!pending_find_copy(MGMT_OP_SET_POWERED, hdev, &cp, sizeof(cp)))
 		return false;
 
-	cp = cmd->param;
-	if (!cp->val)
+	if (!cp.val)
 		return true;
 
 	return false;
diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c
index 6ea107c0e054..5d6d13ccadd2 100644
--- a/net/bluetooth/mgmt_util.c
+++ b/net/bluetooth/mgmt_util.c
@@ -233,6 +233,33 @@ struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
 	return NULL;
 }
 
+bool mgmt_pending_find_copy(unsigned short channel, u16 opcode,
+			    struct hci_dev *hdev, void *data, size_t len)
+{
+	struct mgmt_pending_cmd *cmd, *tmp;
+	bool found = false;
+
+	mutex_lock(&hdev->mgmt_pending_lock);
+
+	list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) {
+		if (hci_sock_get_channel(cmd->sk) != channel)
+			continue;
+
+		if (cmd->opcode != opcode)
+			continue;
+
+		if (cmd->param_len >= len) {
+			memcpy(data, cmd->param, len);
+			found = true;
+		}
+		break;
+	}
+
+	mutex_unlock(&hdev->mgmt_pending_lock);
+
+	return found;
+}
+
 void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove,
 			  void (*cb)(struct mgmt_pending_cmd *cmd, void *data),
 			  void *data)
diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h
index 20810cf06e81..4cccb71c8a1f 100644
--- a/net/bluetooth/mgmt_util.h
+++ b/net/bluetooth/mgmt_util.h
@@ -51,6 +51,8 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
 
 struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode,
 					   struct hci_dev *hdev);
+bool mgmt_pending_find_copy(unsigned short channel, u16 opcode,
+			    struct hci_dev *hdev, void *data, size_t len);
 void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove,
 			  void (*cb)(struct mgmt_pending_cmd *cmd, void *data),
 			  void *data);
-- 
2.43.0


^ permalink raw reply related

* [PATCH 8/8] arm64: dts: imx8qxp-mek: Describe the PCIe M.2 Key E connector
From: Sherry Sun (OSS) @ 2026-06-18 10:10 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-1-sherry.sun@oss.nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

The i.MX8QXP-MEK has the PCIe M.2 Mechanical Key E connector to connect
wireless connectivity cards over PCIe and UART interfaces. Hence,
describe the connector node and link it with the PCIe b Root Port and
LPUART1 nodes through graph port/endpoint.

The M.2 Key E connector is powered by a 3.3V fixed regulator
(reg_3v3) on board.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 54 ++++++++++++++-----
 1 file changed, 41 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index a9b967d0a9be..c9fe4034cc2d 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -40,6 +40,37 @@ memory@80000000 {
 		reg = <0x00000000 0x80000000 0 0x40000000>;
 	};
 
+	m2-connector {
+		compatible = "pcie-m2-e-connector";
+		vpcie3v3-supply = <&reg_3v3>;
+		w-disable1-gpios = <&pca9557_a 2 GPIO_ACTIVE_LOW>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				m2_e_pcie_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&pcieb_port0_ep>;
+				};
+			};
+
+			port@3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+				m2_e_uart_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&lpuart1_ep>;
+				};
+			};
+		};
+	};
+
 	reg_usdhc2_vmmc: usdhc2-vmmc {
 		compatible = "regulator-fixed";
 		regulator-name = "SD1_SPWR";
@@ -157,15 +188,6 @@ reg_3v3: regulator-3v3 {
 		regulator-max-microvolt = <3300000>;
 	};
 
-	reg_pcieb: regulator-pcie {
-		compatible = "regulator-fixed";
-		regulator-max-microvolt = <3300000>;
-		regulator-min-microvolt = <3300000>;
-		regulator-name = "mpcie_3v3";
-		gpio = <&pca9557_a 2 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
 	reg_audio: regulator-audio {
 		compatible = "regulator-fixed";
 		regulator-max-microvolt = <3300000>;
@@ -696,8 +718,10 @@ &lpuart1 {
 	pinctrl-0 = <&pinctrl_lpuart1>;
 	status = "okay";
 
-	bluetooth {
-		compatible = "nxp,88w8987-bt";
+	port {
+		lpuart1_ep: endpoint {
+			remote-endpoint = <&m2_e_uart_ep>;
+		};
 	};
 };
 
@@ -746,8 +770,12 @@ &pcie0_ep {
 
 &pcieb_port0 {
 	reset-gpios = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
-	vpcie-supply = <&reg_pcieb>;
-	vpcie3v3aux-supply = <&reg_pcieb>;
+
+	port {
+		pcieb_port0_ep: endpoint {
+			remote-endpoint = <&m2_e_pcie_ep>;
+		};
+	};
 };
 
 &scu_key {
-- 
2.50.1


^ permalink raw reply related

* [PATCH 7/8] arm64: dts: imx8qm-mek: Describe the PCIe M.2 Key E connector
From: Sherry Sun (OSS) @ 2026-06-18 10:10 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-1-sherry.sun@oss.nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

The i.MX8QM-MEK has the PCIe M.2 Mechanical Key E connector to connect
wireless connectivity cards over PCIe and UART interfaces. Hence,
describe the connector node and link it with the PCIe a Root Port and
LPUART1 nodes through graph port/endpoint.

The M.2 Key E connector is powered by a 3.3V fixed regulator
(reg_3v3) on board.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qm-mek.dts | 58 +++++++++++++++-----
 1 file changed, 43 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
index 5e725ad8aef9..4c02592cfe14 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
@@ -32,6 +32,39 @@ memory@80000000 {
 		reg = <0x00000000 0x80000000 0 0x40000000>;
 	};
 
+	m2-connector {
+		compatible = "pcie-m2-e-connector";
+		pinctrl-0 = <&pinctrl_pciea_reg>;
+		pinctrl-names = "default";
+		vpcie3v3-supply = <&reg_3v3>;
+		w-disable1-gpios = <&lsio_gpio1 13 GPIO_ACTIVE_LOW>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				m2_e_pcie_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&pciea_port0_ep>;
+				};
+			};
+
+			port@3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+				m2_e_uart_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&lpuart1_ep>;
+				};
+			};
+		};
+	};
+
 	xtal24m: clock-xtal24m {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
@@ -320,17 +353,6 @@ reg_can2_stby: regulator-can2-stby {
 		vin-supply = <&reg_can2_en>;
 	};
 
-	reg_pciea: regulator-pcie {
-		compatible = "regulator-fixed";
-		pinctrl-0 = <&pinctrl_pciea_reg>;
-		pinctrl-names = "default";
-		regulator-max-microvolt = <3300000>;
-		regulator-min-microvolt = <3300000>;
-		regulator-name = "mpcie_3v3";
-		gpio = <&lsio_gpio1 13 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
 	reg_usb_otg1_vbus: regulator-usbotg1-vbus {
 		compatible = "regulator-fixed";
 		regulator-name = "usb_otg1_vbus";
@@ -718,8 +740,10 @@ &lpuart1 {
 	pinctrl-0 = <&pinctrl_lpuart1>;
 	status = "okay";
 
-	bluetooth {
-		compatible = "nxp,88w8987-bt";
+	port {
+		lpuart1_ep: endpoint {
+			remote-endpoint = <&m2_e_uart_ep>;
+		};
 	};
 };
 
@@ -818,8 +842,12 @@ &pciea {
 
 &pciea_port0 {
 	reset-gpios = <&lsio_gpio4 29 GPIO_ACTIVE_LOW>;
-	vpcie-supply = <&reg_pciea>;
-	vpcie3v3aux-supply = <&reg_pciea>;
+
+	port {
+		pciea_port0_ep: endpoint {
+			remote-endpoint = <&m2_e_pcie_ep>;
+		};
+	};
 };
 
 &pcieb {
-- 
2.50.1


^ permalink raw reply related

* [PATCH 6/8] arm64: dts: imx8dxl-evk: Describe the PCIe M.2 Key E connector
From: Sherry Sun (OSS) @ 2026-06-18 10:10 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-1-sherry.sun@oss.nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

The i.MX8DXL-EVK has the PCIe M.2 Mechanical Key E connector to connect
wireless connectivity cards over PCIe and UART interfaces. Hence,
describe the connector node and link it with the PCIe b Root Port and
LPUART1 nodes through graph port/endpoint.

The M.2 Key E connector is powered by a 3.3V fixed regulator
(reg_audio_3v3), add a reg_3v3 label to avoid confusion.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts | 56 ++++++++++++++-----
 1 file changed, 42 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
index 1084164d1381..6afee1f1a9fc 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
@@ -42,6 +42,37 @@ memory@80000000 {
 		reg = <0x00000000 0x80000000 0 0x40000000>;
 	};
 
+	m2-connector {
+		compatible = "pcie-m2-e-connector";
+		vpcie3v3-supply = <&reg_3v3>;
+		w-disable1-gpios = <&pca6416_1 13 GPIO_ACTIVE_LOW>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				m2_e_pcie_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&pcieb_port0_ep>;
+				};
+			};
+
+			port@3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+				m2_e_uart_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&lpuart1_ep>;
+				};
+			};
+		};
+	};
+
 	reserved-memory {
 		#address-cells = <2>;
 		#size-cells = <2>;
@@ -182,15 +213,6 @@ mii_select: regulator-4 {
 		regulator-always-on;
 	};
 
-	reg_pcieb: regulator-pcieb {
-		compatible = "regulator-fixed";
-		regulator-max-microvolt = <3300000>;
-		regulator-min-microvolt = <3300000>;
-		regulator-name = "reg_pcieb";
-		gpio = <&pca6416_1 13 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
 	reg_audio_5v: regulator-audio-pwr {
 		compatible = "regulator-fixed";
 		regulator-name = "audio-5v";
@@ -200,7 +222,7 @@ reg_audio_5v: regulator-audio-pwr {
 		regulator-boot-on;
 	};
 
-	reg_audio_3v3: regulator-audio-3v3 {
+	reg_3v3: reg_audio_3v3: regulator-audio-3v3 {
 		compatible = "regulator-fixed";
 		regulator-name = "audio-3v3";
 		regulator-min-microvolt = <3300000>;
@@ -623,8 +645,10 @@ &lpuart1 {
 	pinctrl-0 = <&pinctrl_lpuart1>;
 	status = "okay";
 
-	bluetooth {
-		compatible = "nxp,88w8987-bt";
+	port {
+		lpuart1_ep: endpoint {
+			remote-endpoint = <&m2_e_uart_ep>;
+		};
 	};
 };
 
@@ -690,8 +714,12 @@ &pcie0_ep {
 
 &pcieb_port0 {
 	reset-gpios = <&lsio_gpio4 0 GPIO_ACTIVE_LOW>;
-	vpcie-supply = <&reg_pcieb>;
-	vpcie3v3aux-supply = <&reg_pcieb>;
+
+	port {
+		pcieb_port0_ep: endpoint {
+			remote-endpoint = <&m2_e_pcie_ep>;
+		};
+	};
 };
 
 &sai0 {
-- 
2.50.1


^ permalink raw reply related

* [PATCH 5/8] arm64: dts: imx95-19x19-evk: Describe the PCIe M.2 Key E connector
From: Sherry Sun (OSS) @ 2026-06-18 10:10 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-1-sherry.sun@oss.nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

The i.MX95-19x19-EVK has the PCIe M.2 Mechanical Key E connector to
connect wireless connectivity cards over PCIe and UART interfaces. Hence,
describe the connector node and link it with the PCIe 0 Root Port and
LPUART5 nodes through graph port/endpoint.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 .../boot/dts/freescale/imx95-19x19-evk.dts    | 55 ++++++++++++++-----
 1 file changed, 41 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
index c08731dfb1ee..d2c0345f0d61 100644
--- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -57,6 +57,37 @@ memory@80000000 {
 		reg = <0x0 0x80000000 0 0x80000000>;
 	};
 
+	m2-connector {
+		compatible = "pcie-m2-e-connector";
+		vpcie3v3-supply = <&reg_m2_pwr>;
+		w-disable1-gpios = <&i2c7_pcal6524 6 GPIO_ACTIVE_LOW>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				m2_e_pcie_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&pcie0_port0_ep>;
+				};
+			};
+
+			port@3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+				m2_e_uart_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&lpuart5_ep>;
+				};
+			};
+		};
+	};
+
 	fan0: pwm-fan {
 		compatible = "pwm-fan";
 		#cooling-cells = <2>;
@@ -145,16 +176,6 @@ reg_m2_pwr: regulator-m2-pwr {
 		startup-delay-us = <5000>;
 	};
 
-	reg_pcie0: regulator-pcie {
-		compatible = "regulator-fixed";
-		regulator-name = "PCIE_WLAN_EN";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&reg_m2_pwr>;
-		gpio = <&i2c7_pcal6524 6 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
 	reg_slot_pwr: regulator-slot-pwr {
 		compatible = "regulator-fixed";
 		regulator-name = "PCIe slot-power";
@@ -477,8 +498,10 @@ &lpuart5 {
 	pinctrl-0 = <&pinctrl_uart5>;
 	status = "okay";
 
-	bluetooth {
-		compatible = "nxp,88w8987-bt";
+	port {
+		lpuart5_ep: endpoint {
+			remote-endpoint = <&m2_e_uart_ep>;
+		};
 	};
 };
 
@@ -555,8 +578,12 @@ &pcie0_ep {
 
 &pcie0_port0 {
 	reset-gpios = <&i2c7_pcal6524 5 GPIO_ACTIVE_LOW>;
-	vpcie-supply = <&reg_pcie0>;
-	vpcie3v3aux-supply = <&reg_pcie0>;
+
+	port {
+		pcie0_port0_ep: endpoint {
+			remote-endpoint = <&m2_e_pcie_ep>;
+		};
+	};
 };
 
 &pcie1 {
-- 
2.50.1


^ permalink raw reply related

* [PATCH 4/8] arm64: dts: imx8mq-evk: Describe the PCIe M.2 Key E connector
From: Sherry Sun (OSS) @ 2026-06-18 10:10 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-1-sherry.sun@oss.nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

The i.MX8MQ-EVK has the PCIe M.2 Mechanical Key E connector to connect
wireless connectivity cards over PCIe and UART interfaces. Hence,
describe the connector node and link it with the PCIe 1 Root Port and
UART3 nodes through graph port/endpoint.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts | 44 ++++++++++++++++++--
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index 71504a0af87f..482e5203e879 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -21,6 +21,36 @@ memory@40000000 {
 		reg = <0x00000000 0x40000000 0 0xc0000000>;
 	};
 
+	m2-connector {
+		compatible = "pcie-m2-e-connector";
+		vpcie3v3-supply = <&reg_pcie1>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+				m2_e_pcie_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&pcie1_port0_ep>;
+				};
+			};
+
+			port@3 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <3>;
+				m2_e_uart_ep: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&uart3_ep>;
+				};
+			};
+		};
+	};
+
 	pcie0_refclk: pcie0-refclk {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
@@ -420,8 +450,12 @@ &pcie1_ep {
 
 &pcie1_port0 {
 	reset-gpios = <&gpio5 12 GPIO_ACTIVE_LOW>;
-	vpcie-supply = <&reg_pcie1>;
-	vpcie3v3aux-supply = <&reg_pcie1>;
+
+	port {
+		pcie1_port0_ep: endpoint {
+			remote-endpoint = <&m2_e_pcie_ep>;
+		};
+	};
 };
 
 &pgc_gpu {
@@ -506,8 +540,10 @@ &uart3 { /* BT */
 	uart-has-rtscts;
 	status = "okay";
 
-	bluetooth {
-		compatible = "nxp,88w8987-bt";
+	port {
+		uart3_ep: endpoint {
+			remote-endpoint = <&m2_e_uart_ep>;
+		};
 	};
 };
 
-- 
2.50.1


^ permalink raw reply related

* [PATCH 3/8] Bluetooth: btnxpuart: Add M.2 Bluetooth device support using pwrseq
From: Sherry Sun (OSS) @ 2026-06-18 10:10 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-1-sherry.sun@oss.nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

Power supply to the M.2 Bluetooth device attached to the host using M.2
connector is controlled using the 'uart' pwrseq device. So add support for
getting the pwrseq device if the OF graph link is present. Once obtained,
the existing pwrseq APIs can be used to control the power supplies of the
M.2 card.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 drivers/bluetooth/btnxpuart.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index e7036a48ce48..1aa8972f0dab 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -9,6 +9,8 @@
 
 #include <linux/serdev.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/pwrseq/consumer.h>
 #include <linux/skbuff.h>
 #include <linux/unaligned.h>
 #include <linux/firmware.h>
@@ -211,6 +213,7 @@ struct btnxpuart_dev {
 
 	struct ps_data psdata;
 	struct btnxpuart_data *nxp_data;
+	struct pwrseq_desc *pwrseq;
 	struct reset_control *pdn;
 	struct hci_uart hu;
 };
@@ -1866,11 +1869,27 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
 		return err;
 	}
 
+	if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
+		struct pwrseq_desc *pwrseq;
+
+		pwrseq = devm_pwrseq_get(&serdev->ctrl->dev, "uart");
+		if (IS_ERR(pwrseq))
+			return PTR_ERR(pwrseq);
+
+		nxpdev->pwrseq = pwrseq;
+		err = pwrseq_power_on(pwrseq);
+		if (err) {
+			dev_err(&serdev->dev, "Failed to power on pwrseq\n");
+			return err;
+		}
+	}
+
 	/* Initialize and register HCI device */
 	hdev = hci_alloc_dev();
 	if (!hdev) {
 		dev_err(&serdev->dev, "Can't allocate HCI device\n");
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_pwrseq_power_off;
 	}
 
 	reset_control_deassert(nxpdev->pdn);
@@ -1903,11 +1922,14 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
 
 	if (hci_register_dev(hdev) < 0) {
 		dev_err(&serdev->dev, "Can't register HCI device\n");
+		err = -ENODEV;
 		goto probe_fail;
 	}
 
-	if (ps_setup(hdev))
+	if (ps_setup(hdev)) {
+		err = -ENODEV;
 		goto probe_fail;
+	}
 
 	hci_devcd_register(hdev, nxp_coredump, nxp_coredump_hdr,
 			   nxp_coredump_notify);
@@ -1917,7 +1939,10 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
 probe_fail:
 	reset_control_assert(nxpdev->pdn);
 	hci_free_dev(hdev);
-	return -ENODEV;
+err_pwrseq_power_off:
+	if (nxpdev->pwrseq)
+		pwrseq_power_off(nxpdev->pwrseq);
+	return err;
 }
 
 static void nxp_serdev_remove(struct serdev_device *serdev)
@@ -1944,6 +1969,8 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
 	ps_cleanup(nxpdev);
 	hci_unregister_dev(hdev);
 	reset_control_assert(nxpdev->pdn);
+	if (nxpdev->pwrseq)
+		pwrseq_power_off(nxpdev->pwrseq);
 	hci_free_dev(hdev);
 }
 
-- 
2.50.1


^ permalink raw reply related

* [PATCH 2/8] power: sequencing: pcie-m2: Add PCI ID for NXP 88W9098 and AW693 Bluetooth
From: Sherry Sun (OSS) @ 2026-06-18 10:10 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-1-sherry.sun@oss.nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

88W9098 is a NXP Wi-Fi/BT combo chip with PCI device ID 0x2b43 under
Marvell Extended vendor ID. AW693 is a NXP Wi-Fi/BT combo chip with
PCI device ID 0x3003 under NXP/Philips vendor ID.

Add both chips to pwrseq_m2_pci_ids[] so that the pwrseq-pcie-m2 driver
can create the Bluetooth serdev device when these cards are inserted into
a PCIe M.2 Key E connector.

Both chips use "nxp,88w8987-bt" as the serdev compatible string, which
is the entry point for the btnxpuart driver. The driver identifies the
actual chip variant at runtime via chip ID auto-detection and loads the
appropriate firmware accordingly.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 drivers/power/sequencing/pwrseq-pcie-m2.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c
index 94c3f4b7ee36..9217ffcfa6e5 100644
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -186,6 +186,10 @@ static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
 }
 
 static const struct pci_device_id pwrseq_m2_pci_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x2b43),
+	  .driver_data = (kernel_ulong_t)"nxp,88w8987-bt" },
+	{ PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, 0x3003),
+	  .driver_data = (kernel_ulong_t)"nxp,88w8987-bt" },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x1107),
 	  .driver_data = (kernel_ulong_t)"qcom,wcn7850-bt" },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x1103),
-- 
2.50.1


^ permalink raw reply related

* [PATCH 1/8] PCI: imx6: Add skip_pwrctrl_off flag support
From: Sherry Sun (OSS) @ 2026-06-18 10:10 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun
In-Reply-To: <20260618101047.4185497-1-sherry.sun@oss.nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

Use dw_pcie::skip_pwrctrl_off to avoid powering off devices during suspend
to preserve wakeup capability of the devices and also not to power on the
devices in the init path.
This allows controller power-off to be skipped when some devices(e.g. M.2
cards key E without auxiliary power) required to support PCIe L2 link state
and wake-up mechanisms.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 36 +++++++++++++++++----------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 0fa716d1ed75..ff5a9565dbbf 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1382,16 +1382,20 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
 		}
 	}
 
-	ret = pci_pwrctrl_create_devices(dev);
-	if (ret) {
-		dev_err(dev, "failed to create pwrctrl devices\n");
-		goto err_reg_disable;
+	if (!pci->suspended) {
+		ret = pci_pwrctrl_create_devices(dev);
+		if (ret) {
+			dev_err(dev, "failed to create pwrctrl devices\n");
+			goto err_reg_disable;
+		}
 	}
 
-	ret = pci_pwrctrl_power_on_devices(dev);
-	if (ret) {
-		dev_err(dev, "failed to power on pwrctrl devices\n");
-		goto err_pwrctrl_destroy;
+	if (!pp->skip_pwrctrl_off) {
+		ret = pci_pwrctrl_power_on_devices(dev);
+		if (ret) {
+			dev_err(dev, "failed to power on pwrctrl devices\n");
+			goto err_pwrctrl_destroy;
+		}
 	}
 
 	ret = imx_pcie_clk_enable(imx_pcie);
@@ -1460,9 +1464,10 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
 err_clk_disable:
 	imx_pcie_clk_disable(imx_pcie);
 err_pwrctrl_power_off:
-	pci_pwrctrl_power_off_devices(dev);
+	if (!pp->skip_pwrctrl_off)
+		pci_pwrctrl_power_off_devices(dev);
 err_pwrctrl_destroy:
-	if (ret != -EPROBE_DEFER)
+	if (ret != -EPROBE_DEFER && !pci->suspended)
 		pci_pwrctrl_destroy_devices(dev);
 err_reg_disable:
 	if (imx_pcie->vpcie)
@@ -1482,7 +1487,8 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp)
 	}
 	imx_pcie_clk_disable(imx_pcie);
 
-	pci_pwrctrl_power_off_devices(pci->dev);
+	if (!pci->pp.skip_pwrctrl_off)
+		pci_pwrctrl_power_off_devices(pci->dev);
 	if (imx_pcie->vpcie)
 		regulator_disable(imx_pcie->vpcie);
 }
@@ -1990,12 +1996,16 @@ static int imx_pcie_probe(struct platform_device *pdev)
 static void imx_pcie_shutdown(struct platform_device *pdev)
 {
 	struct imx_pcie *imx_pcie = platform_get_drvdata(pdev);
+	struct dw_pcie *pci = imx_pcie->pci;
+	struct dw_pcie_rp *pp = &pci->pp;
 
 	/* bring down link, so bootloader gets clean state in case of reboot */
 	imx_pcie_assert_core_reset(imx_pcie);
 	imx_pcie_assert_perst(imx_pcie, true);
-	pci_pwrctrl_power_off_devices(&pdev->dev);
-	pci_pwrctrl_destroy_devices(&pdev->dev);
+	if (!pp->skip_pwrctrl_off)
+		pci_pwrctrl_power_off_devices(&pdev->dev);
+	if (!pci->suspended)
+		pci_pwrctrl_destroy_devices(&pdev->dev);
 }
 
 static const struct imx_pcie_drvdata drvdata[] = {
-- 
2.50.1


^ permalink raw reply related

* [PATCH 0/8] Add PCIe M.2 Key E connector support for NXP i.MX boards
From: Sherry Sun (OSS) @ 2026-06-18 10:10 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	amitkumar.karwar, neeraj.sanjaykale, marcel, luiz.dentz,
	hongxing.zhu, l.stach, lpieralisi, kwilczynski, mani, bhelgaas,
	brgl
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	linux-bluetooth, linux-pm, sherry.sun

From: Sherry Sun <sherry.sun@nxp.com>

This series adds support for NXP Wi-Fi/BT combo chips (88W9098, AW693)
inserted into PCIe M.2 Key E connectors on several i.MX EVK/MEK boards.

For M.2 cards that rely on PCIe L2 link state and wake-up mechanisms, the
card must remain powered during suspend. Patch 1 uses the existing
dw_pcie_rp::skip_pwrctrl_off flag to skip power-off during suspend and skip
power-on during the init path.

Alsp the btnxpuart driver is extended to obtain a pwrseq descriptor via the
OF graph on the UART controller device in patch 2.

Sherry Sun (8):
  PCI: imx6: Add skip_pwrctrl_off flag support
  power: sequencing: pcie-m2: Add PCI ID for NXP 88W9098 and AW693
    Bluetooth
  Bluetooth: btnxpuart: Add M.2 Bluetooth device support using pwrseq
  arm64: dts: imx8mq-evk: Describe the PCIe M.2 Key E connector
  arm64: dts: imx95-19x19-evk: Describe the PCIe M.2 Key E connector
  arm64: dts: imx8dxl-evk: Describe the PCIe M.2 Key E connector
  arm64: dts: imx8qm-mek: Describe the PCIe M.2 Key E connector
  arm64: dts: imx8qxp-mek: Describe the PCIe M.2 Key E connector

 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts | 56 +++++++++++++-----
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts  | 44 ++++++++++++--
 arch/arm64/boot/dts/freescale/imx8qm-mek.dts  | 58 ++++++++++++++-----
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 54 ++++++++++++-----
 .../boot/dts/freescale/imx95-19x19-evk.dts    | 55 +++++++++++++-----
 drivers/bluetooth/btnxpuart.c                 | 33 ++++++++++-
 drivers/pci/controller/dwc/pci-imx6.c         | 36 +++++++-----
 drivers/power/sequencing/pwrseq-pcie-m2.c     |  4 ++
 8 files changed, 264 insertions(+), 76 deletions(-)

-- 
2.50.1


^ permalink raw reply

* [PATCH v2 2/2] Bluetooth: btintel_pcie: Fix TOCTOU race in reset path
From: Chandrashekar Devegowda @ 2026-06-18  8:50 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: linux-pci, bhelgaas, ravishankar.srivatsa, chethan.tumkur.narayan,
	Chandrashekar Devegowda
In-Reply-To: <20260618085016.9173-1-chandrashekar.devegowda@intel.com>

Move the test_and_set_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS) check
before the SETUP_DONE check to fix a Time-Of-Check to Time-Of-Use
race. Previously, multiple callers could pass the SETUP_DONE check
concurrently and then race on the RECOVERY_IN_PROGRESS flag,
potentially scheduling conflicting removal work.

By reordering the existing atomic guard to execute first, concurrent
reset requests are atomically rejected before any state is inspected.
The RECOVERY_IN_PROGRESS flag is cleared on the early-exit path
(setup not done) to allow future reset attempts.

Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
---
v2:
  - No changes
v1:
  - Initial version
---
 drivers/bluetooth/btintel_pcie.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index d3a03cf96421..f4f400421833 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -2686,11 +2686,15 @@ static void btintel_pcie_reset(struct hci_dev *hdev, u8 reset_type)
 
 	data = hci_get_drvdata(hdev);
 
-	if (!test_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags))
+	if (test_and_set_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags)) {
+		bt_dev_warn(hdev, "Reset rejected: recovery already in progress");
 		return;
+	}
 
-	if (test_and_set_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags))
+	if (!test_bit(BTINTEL_PCIE_SETUP_DONE, &data->flags)) {
+		clear_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags);
 		return;
+	}
 
 	data->reset_type = (reset_type == 1) ?
 			    BTINTEL_PCIE_IOSF_PRR_PLDR : BTINTEL_PCIE_IOSF_PRR_FLR;
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 1/2] Bluetooth: hci_core: Add reset_type parameter to hdev->reset() callback
From: Chandrashekar Devegowda @ 2026-06-18  8:50 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: linux-pci, bhelgaas, ravishankar.srivatsa, chethan.tumkur.narayan,
	Chandrashekar Devegowda

Add a u8 reset_type parameter to the hdev->reset() callback to allow
userspace to select the reset level via sysfs. Each driver interprets
the level according to its own capabilities.

The reset_type values are:
  0 - default reset
  1 - deeper reset

Writing any value other than 1 defaults to level 0.

Internal callers (command timeout, suspend/resume, coredump)
default to level 0.

All drivers implementing the reset callback are updated to accept
the new parameter:
  - btusb: btusb_intel_reset, btusb_qca_reset, btusb_rtl_reset
  - hci_qca: qca_reset
  - btmtksdio: btmtksdio_reset
  - btmtk: btmtk_reset_sync
  - btnxpuart: nxp_reset
  - btintel_pcie: btintel_pcie_reset

Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
---
v2:
  - Use generic reset level terminology instead of Intel-specific
    FLR/PLDR in sysfs ABI documentation and commit message (Luiz)
  - Fix docutils formatting warning by adding blank lines around
    the indented list in sysfs-class-bluetooth (kernel test robot)
v1:
  - Initial version
---
 Documentation/ABI/stable/sysfs-class-bluetooth |  9 ++++++++-
 drivers/bluetooth/btintel_pcie.c               | 17 +++++++++++------
 drivers/bluetooth/btmtk.c                      |  6 +++---
 drivers/bluetooth/btmtk.h                      |  4 ++--
 drivers/bluetooth/btmtksdio.c                  |  2 +-
 drivers/bluetooth/btnxpuart.c                  |  2 +-
 drivers/bluetooth/btusb.c                      |  6 +++---
 drivers/bluetooth/hci_qca.c                    |  2 +-
 include/net/bluetooth/hci_core.h               |  2 +-
 net/bluetooth/hci_core.c                       |  2 +-
 net/bluetooth/hci_sysfs.c                      | 10 ++++++++--
 11 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/Documentation/ABI/stable/sysfs-class-bluetooth b/Documentation/ABI/stable/sysfs-class-bluetooth
index 36be02471174..fb445e20f972 100644
--- a/Documentation/ABI/stable/sysfs-class-bluetooth
+++ b/Documentation/ABI/stable/sysfs-class-bluetooth
@@ -3,7 +3,14 @@ Date:		14-Jan-2025
 KernelVersion:	6.13
 Contact:	linux-bluetooth@vger.kernel.org
 Description: 	This write-only attribute allows users to trigger the vendor reset
-		method on the Bluetooth device when arbitrary data is written.
+		method on the Bluetooth device. The value written selects the
+		reset level. Each driver interprets the level according to its
+		own capabilities:
+
+		  - 0: default reset
+		  - 1: deeper reset
+
+		Writing any value other than 1 defaults to level 0.
 		The reset may or may not be done through the device transport
 		(e.g., UART/USB), and can also be done through an out-of-band
 		approach such as GPIO.
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 9e39327dc1fe..d3a03cf96421 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -2486,7 +2486,7 @@ static void btintel_pcie_inc_recovery_count(struct pci_dev *pdev,
 }
 
 static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data);
-static void btintel_pcie_reset(struct hci_dev *hdev);
+static void btintel_pcie_reset(struct hci_dev *hdev, u8 reset_type);
 
 static int btintel_pcie_acpi_reset_method(struct btintel_pcie_data *data)
 {
@@ -2680,7 +2680,7 @@ static void btintel_pcie_reset_work(struct work_struct *wk)
 	pci_unlock_rescan_remove();
 }
 
-static void btintel_pcie_reset(struct hci_dev *hdev)
+static void btintel_pcie_reset(struct hci_dev *hdev, u8 reset_type)
 {
 	struct btintel_pcie_data *data;
 
@@ -2692,6 +2692,12 @@ static void btintel_pcie_reset(struct hci_dev *hdev)
 	if (test_and_set_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags))
 		return;
 
+	data->reset_type = (reset_type == 1) ?
+			    BTINTEL_PCIE_IOSF_PRR_PLDR : BTINTEL_PCIE_IOSF_PRR_FLR;
+
+	bt_dev_info(hdev, "Reset triggered: %s",
+		    data->reset_type == BTINTEL_PCIE_IOSF_PRR_PLDR ? "PLDR" : "FLR");
+
 	pci_dev_get(data->pdev);
 	schedule_work(&data->reset_work);
 }
@@ -2729,7 +2735,7 @@ static void btintel_pcie_hw_error(struct hci_dev *hdev, u8 code)
 		return;
 	}
 	btintel_pcie_inc_recovery_count(pdev, &hdev->dev);
-	btintel_pcie_reset(hdev);
+	btintel_pcie_reset(hdev, (code == 0x13) ? 1 : 0);
 }
 
 static bool btintel_pcie_wakeup(struct hci_dev *hdev)
@@ -3111,8 +3117,7 @@ static int btintel_pcie_resume(struct device *dev)
 	if (data->pm_sx_event == PM_EVENT_FREEZE ||
 	    data->pm_sx_event == PM_EVENT_HIBERNATE) {
 		set_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags);
-		data->reset_type = BTINTEL_PCIE_IOSF_PRR_FLR;
-		btintel_pcie_reset(data->hdev);
+		btintel_pcie_reset(data->hdev, 0);
 		return 0;
 	}
 
@@ -3143,7 +3148,7 @@ static int btintel_pcie_resume(struct device *dev)
 			queue_work(data->coredump_workqueue, &data->coredump_work);
 		}
 		set_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags);
-		btintel_pcie_reset(data->hdev);
+		btintel_pcie_reset(data->hdev, 0);
 	}
 	return err;
 }
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 02a96342e964..641f62912f63 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -104,7 +104,7 @@ static void btmtk_coredump_notify(struct hci_dev *hdev, int state)
 	case HCI_DEVCOREDUMP_ABORT:
 	case HCI_DEVCOREDUMP_DONE:
 		data->cd_info.state = HCI_DEVCOREDUMP_IDLE;
-		btmtk_reset_sync(hdev);
+		btmtk_reset_sync(hdev, 0);
 		break;
 	}
 }
@@ -384,7 +384,7 @@ int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 }
 EXPORT_SYMBOL_GPL(btmtk_set_bdaddr);
 
-void btmtk_reset_sync(struct hci_dev *hdev)
+void btmtk_reset_sync(struct hci_dev *hdev, u8 reset_type)
 {
 	struct btmtk_data *reset_work = hci_get_priv(hdev);
 	int err;
@@ -1403,7 +1403,7 @@ int btmtk_usb_setup(struct hci_dev *hdev)
 		if (err < 0) {
 			/* retry once if setup firmware error */
 			if (!test_and_set_bit(BTMTK_FIRMWARE_DL_RETRY, &btmtk_data->flags))
-				btmtk_reset_sync(hdev);
+				btmtk_reset_sync(hdev, 0);
 			bt_dev_err(hdev, "Failed to set up firmware (%d)", err);
 			return err;
 		}
diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
index c83c24897c95..5cda42444e94 100644
--- a/drivers/bluetooth/btmtk.h
+++ b/drivers/bluetooth/btmtk.h
@@ -196,7 +196,7 @@ int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
 int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
 			 wmt_cmd_sync_func_t wmt_cmd_sync);
 
-void btmtk_reset_sync(struct hci_dev *hdev);
+void btmtk_reset_sync(struct hci_dev *hdev, u8 reset_type);
 
 int btmtk_register_coredump(struct hci_dev *hdev, const char *name,
 			    u32 fw_version);
@@ -244,7 +244,7 @@ static inline int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
 	return -EOPNOTSUPP;
 }
 
-static inline void btmtk_reset_sync(struct hci_dev *hdev)
+static inline void btmtk_reset_sync(struct hci_dev *hdev, u8 reset_type)
 {
 }
 
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index c6f80c419e90..3c4401ce1e00 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -1269,7 +1269,7 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 	return 0;
 }
 
-static void btmtksdio_reset(struct hci_dev *hdev)
+static void btmtksdio_reset(struct hci_dev *hdev, u8 reset_type)
 {
 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
 	u32 status;
diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c
index e7036a48ce48..e2416b48116c 100644
--- a/drivers/bluetooth/btnxpuart.c
+++ b/drivers/bluetooth/btnxpuart.c
@@ -1539,7 +1539,7 @@ static bool nxp_wakeup(struct hci_dev *hdev)
 	return false;
 }
 
-static void nxp_reset(struct hci_dev *hdev)
+static void nxp_reset(struct hci_dev *hdev, u8 reset_type)
 {
 	struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 7f14ce96319b..ffe109b3b587 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1045,7 +1045,7 @@ static void btusb_reset(struct hci_dev *hdev)
 	usb_queue_reset_device(data->intf);
 }
 
-static void btusb_intel_reset(struct hci_dev *hdev)
+static void btusb_intel_reset(struct hci_dev *hdev, u8 reset_type)
 {
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	struct gpio_desc *reset_gpio = data->reset_gpio;
@@ -1123,7 +1123,7 @@ static inline void btusb_rtl_alloc_devcoredump(struct hci_dev *hdev,
 	}
 }
 
-static void btusb_rtl_reset(struct hci_dev *hdev)
+static void btusb_rtl_reset(struct hci_dev *hdev, u8 reset_type)
 {
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	struct gpio_desc *reset_gpio = data->reset_gpio;
@@ -1167,7 +1167,7 @@ static void btusb_rtl_hw_error(struct hci_dev *hdev, u8 code)
 	btusb_rtl_alloc_devcoredump(hdev, &hdr, NULL, 0);
 }
 
-static void btusb_qca_reset(struct hci_dev *hdev)
+static void btusb_qca_reset(struct hci_dev *hdev, u8 reset_type)
 {
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	struct gpio_desc *reset_gpio = data->reset_gpio;
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 244447195619..02b4afe77669 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -1693,7 +1693,7 @@ static void qca_hw_error(struct hci_dev *hdev, u8 code)
 	clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
 }
 
-static void qca_reset(struct hci_dev *hdev)
+static void qca_reset(struct hci_dev *hdev, u8 reset_type)
 {
 	struct hci_uart *hu = hci_get_drvdata(hdev);
 	struct qca_data *qca = hu->priv;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 7e15da47fe3a..00421352fcb5 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -650,7 +650,7 @@ struct hci_dev {
 	int (*post_init)(struct hci_dev *hdev);
 	int (*set_diag)(struct hci_dev *hdev, bool enable);
 	int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
-	void (*reset)(struct hci_dev *hdev);
+	void (*reset)(struct hci_dev *hdev, u8 reset_type);
 	bool (*wakeup)(struct hci_dev *hdev);
 	int (*set_quality_report)(struct hci_dev *hdev, bool enable);
 	int (*get_data_path_id)(struct hci_dev *hdev, __u8 *data_path);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5ba9fe8261ec..360b329ae6da 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1435,7 +1435,7 @@ static void hci_cmd_timeout(struct work_struct *work)
 	}
 
 	if (hdev->reset)
-		hdev->reset(hdev);
+		hdev->reset(hdev, 0);
 
 	atomic_set(&hdev->cmd_cnt, 1);
 	queue_work(hdev->workqueue, &hdev->cmd_work);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 8957ce7c21b7..a4fe329158cf 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -97,8 +97,14 @@ static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
 {
 	struct hci_dev *hdev = to_hci_dev(dev);
 
-	if (hdev->reset)
-		hdev->reset(hdev);
+	if (hdev->reset) {
+		int val;
+
+		if (kstrtoint(buf, 10, &val) || val != 1)
+			hdev->reset(hdev, 0);
+		else
+			hdev->reset(hdev, 1);
+	}
 
 	return count;
 }
-- 
2.43.0


^ permalink raw reply related

* [PATCH BlueZ v1] shared/rap: Fix Mode 0 step serialization
From: Prathibha Madugonde @ 2026-06-18  7:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg

From: Prathibha Madugonde <prathibha.madugonde@oss.qualcomm.com>

Replace raw struct byte dump with field-by-field serialization
that conditionally includes init_measured_freq_offset only for
the Initiator role, matching the RAS wire format (5 bytes for
Initiator, 3 bytes for Reflector)
---
 src/shared/rap.c | 41 +++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/shared/rap.c b/src/shared/rap.c
index 390fd3080..ecf7df5a7 100644
--- a/src/shared/rap.c
+++ b/src/shared/rap.c
@@ -1307,15 +1307,40 @@ static void process_cs_mode_zero(struct bt_rap *rap,
 				const struct cs_step_data *step,
 				uint8_t idx, uint8_t mode_byte)
 {
-	const uint8_t *payload;
-	uint8_t plen;
+	const struct cs_mode_zero_data *m0 =
+		&step->step_mode_data.mode_zero_data;
+	struct cstracker *resptracker = rap->resptracker;
+	enum cs_role cs_role = resptracker->role;
+	struct iovec temp_iov = { 0 };
+
+	temp_iov.iov_base = malloc(8);
+	if (!temp_iov.iov_base) {
+		DBG(rap, "Mode0 ERROR: malloc failed!");
+		return;
+	}
+	temp_iov.iov_len = 0;
+
+	if (!util_iov_push_u8(&temp_iov, m0->packet_quality) ||
+	    !util_iov_push_u8(&temp_iov, m0->packet_rssi_dbm) ||
+	    !util_iov_push_u8(&temp_iov, m0->packet_ant))
+		goto done;
+
+	if (cs_role == CS_ROLE_INITIATOR) {
+		if (!util_iov_push_le16(&temp_iov,
+					m0->init_measured_freq_offset))
+			goto done;
+	}
 
-	/* Mode 0: use raw structure bytes */
-	payload = (const uint8_t *)&step->step_mode_data;
-	plen = step->step_data_length;
-	cs_pd_ras_append_subevent_bytes(proc, payload, plen);
-	DBG(rap, "step[%u]: mode=0x%02x Mode0 payload_len=%u sent",
-		idx, mode_byte, (unsigned int)plen);
+	cs_pd_ras_append_subevent_bytes(proc, temp_iov.iov_base,
+					temp_iov.iov_len);
+
+done:
+	free(temp_iov.iov_base);
+
+	DBG(rap, "step[%u]: mode=0x%02x Mode0 serialized payload_len=%zu "
+		"role=%s",
+		idx, mode_byte, temp_iov.iov_len,
+		cs_role == CS_ROLE_INITIATOR ? "INIT" : "REFL");
 }
 
 static void process_cs_mode_one(struct bt_rap *rap,
-- 
2.34.1


^ permalink raw reply related

* [PATCH v1] shared/rap: Fix Mode 0 step serialization
From: Prathibha Madugonde @ 2026-06-18  7:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg

From: Prathibha Madugonde <prathibha.madugonde@oss.qualcomm.com>

Replace raw struct byte dump with field-by-field serialization
that conditionally includes init_measured_freq_offset only for
the Initiator role, matching the RAS wire format (5 bytes for
Initiator, 3 bytes for Reflector)
---
 src/shared/rap.c | 41 +++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/shared/rap.c b/src/shared/rap.c
index 390fd3080..ecf7df5a7 100644
--- a/src/shared/rap.c
+++ b/src/shared/rap.c
@@ -1307,15 +1307,40 @@ static void process_cs_mode_zero(struct bt_rap *rap,
 				const struct cs_step_data *step,
 				uint8_t idx, uint8_t mode_byte)
 {
-	const uint8_t *payload;
-	uint8_t plen;
+	const struct cs_mode_zero_data *m0 =
+		&step->step_mode_data.mode_zero_data;
+	struct cstracker *resptracker = rap->resptracker;
+	enum cs_role cs_role = resptracker->role;
+	struct iovec temp_iov = { 0 };
+
+	temp_iov.iov_base = malloc(8);
+	if (!temp_iov.iov_base) {
+		DBG(rap, "Mode0 ERROR: malloc failed!");
+		return;
+	}
+	temp_iov.iov_len = 0;
+
+	if (!util_iov_push_u8(&temp_iov, m0->packet_quality) ||
+	    !util_iov_push_u8(&temp_iov, m0->packet_rssi_dbm) ||
+	    !util_iov_push_u8(&temp_iov, m0->packet_ant))
+		goto done;
+
+	if (cs_role == CS_ROLE_INITIATOR) {
+		if (!util_iov_push_le16(&temp_iov,
+					m0->init_measured_freq_offset))
+			goto done;
+	}
 
-	/* Mode 0: use raw structure bytes */
-	payload = (const uint8_t *)&step->step_mode_data;
-	plen = step->step_data_length;
-	cs_pd_ras_append_subevent_bytes(proc, payload, plen);
-	DBG(rap, "step[%u]: mode=0x%02x Mode0 payload_len=%u sent",
-		idx, mode_byte, (unsigned int)plen);
+	cs_pd_ras_append_subevent_bytes(proc, temp_iov.iov_base,
+					temp_iov.iov_len);
+
+done:
+	free(temp_iov.iov_base);
+
+	DBG(rap, "step[%u]: mode=0x%02x Mode0 serialized payload_len=%zu "
+		"role=%s",
+		idx, mode_byte, temp_iov.iov_len,
+		cs_role == CS_ROLE_INITIATOR ? "INIT" : "REFL");
 }
 
 static void process_cs_mode_one(struct bt_rap *rap,
-- 
2.34.1


^ permalink raw reply related

* RE: [BlueZ] set: Abandon the use of the existing set gatt-db
From: bluez.test.bot @ 2026-06-18  7:14 UTC (permalink / raw)
  To: linux-bluetooth, zhangchen200426
In-Reply-To: <20260618025239.420860-1-zhangchen200426@163.com>

[-- Attachment #1: Type: text/plain, Size: 1781 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=1113188

---Test result---

Test Summary:
CheckPatch                    FAIL      0.43 seconds
GitLint                       PASS      0.33 seconds
BuildEll                      PASS      20.57 seconds
BluezMake                     PASS      667.03 seconds
CheckSmatch                   PASS      355.38 seconds
bluezmakeextell               PASS      184.89 seconds
IncrementalBuild              PASS      654.82 seconds
ScanBuild                     PASS      1045.56 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ] set: Abandon the use of the existing set gatt-db
WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#65: 
When pairing and connecting a pair of earbuds, if you attempt to connect the

/github/workspace/src/patch/14634422.patch total: 0 errors, 1 warnings, 20 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/14634422.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.




https://github.com/bluez/bluez/pull/2238

---
Regards,
Linux Bluetooth


^ permalink raw reply

* [bluez/bluez] 0b6c6d: set: Abandon the use of the existing set gatt-db
From: github-actions[bot] @ 2026-06-18  6:25 UTC (permalink / raw)
  To: linux-bluetooth

  Branch: refs/heads/1113188
  Home:   https://github.com/bluez/bluez
  Commit: 0b6c6d816e5845827ee783782bd4d975069d5a3c
      https://github.com/bluez/bluez/commit/0b6c6d816e5845827ee783782bd4d975069d5a3c
  Author: Chen Zhang <zhangchen01@kylinos.cn>
  Date:   2026-06-18 (Thu, 18 Jun 2026)

  Changed paths:
    M src/set.c

  Log Message:
  -----------
  set: Abandon the use of the existing set gatt-db

When pairing and connecting a pair of earbuds, if you attempt to connect the
second earbud while one earbud is already connected, reusing the existing
set gatt-db will interrupt the GATT procedure. Subsequently, the attribute
values will no longer be read, and the ASE state will not switch. This will
eventually prevent the second earbud from creating a CIS, resulting in no sound
output from the later-connected earbud during music playback.

Signed-off-by: Zhang Chen <zhangchen01@kylinos.cn>



To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox