Re: [PATCH v5 4/4] Bluetooth: btusb: Add support for Qualcomm multi-subsystem QCC2072
From: Pauli Virtanen
Date: Fri Sep 11 2026 - 16:06:41 EST
Hi,
pe, 2026-09-11 kello 01:00 -0700, Zijun Hu kirjoitti:
> QCC2072 has a Peripheral (PERI) subsystem to support the BT function
> unit, the transport wire is owned by PERI and carries both BT-HCI and
> PERI-HCI frames, as shown below:
>
> _______________________________
> USB I/F | internal link |
> BTHOST -------- |---- PERI -------------- BT |
> |_______________________________|
> (other on-chip subsystems omitted)
>
> PERI has its own command/event/ACL traffic, memdump, and firmware
> (PATCH and NVM), all different from BT's own, and BTHOST needs to
> interact with PERI directly.
>
> To support multi-subsystem controllers, add btusb_qcom.c/.h as a new
> transport-specific design:
>
> - Multi-subsystem memdump collection.
> - Generic PERI event handling, and sending a PERI frame then
> syncing an event sequence.
> - Downloading PERI firmware (rampatch and NVM).
> - Recovery on command timeout or hardware error event.
[clip]
>
> +/*
> + * btusb_qcom_send_frame - send a frame for BT or PERI
> + * @hdev: the HCI device
> + * @skb: the frame to send
> + *
> + * Implements hdev->send().
> + *
> + * Return: 0 on success, or a negative errno on failure.
> + */
> +int btusb_qcom_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
This one should have __context_unsafe(/* conditional locking */)
annotation, or no if (need_lock), to avoid warnings on LLVM 23.
> +{
> + struct btusb_qcom *xport_data = btusb_qcom_xport_data(hdev);
> + struct btqcom_data *qbt_data = hci_get_priv(hdev);
> + bool is_vendor;
> + bool need_lock;
> + u8 pkt_type;
> + int ret;
> +
> + if (qbt_data->category != QBTC_CAT_MSUBSYS)
> + return xport_data->send_bt_frame(hdev, skb);
> +
> + pkt_type = hci_skb_pkt_type(skb);
> + is_vendor = pkt_type == HCI_VENDOR_PKT;
> + /* an empty vendor packet has no path to reach here */
> + if (is_vendor)
> + hci_skb_pkt_type(skb) = *(const u8 *)skb_pull_data(skb, 1);
> +
> + pkt_type = hci_skb_pkt_type(skb);
> + need_lock = pkt_type == HCI_COMMAND_PKT ||
> + pkt_type == QPERI_COMMAND_PKT;
> +
> + if (need_lock)
> + mutex_lock(&xport_data->tx_mutex);
> +
> + if (is_vendor)
> + ret = xport_data->send_vendor_frame(hdev, skb);
> + else
> + ret = xport_data->send_bt_frame(hdev, skb);
> +
> + if (need_lock)
> + mutex_unlock(&xport_data->tx_mutex);
> +
> + return ret;
> +}
--
Pauli Virtanen