From bc6f557b3387d807e08ffb8d638f149fedb75bf6 Mon Sep 17 00:00:00 2001 From: Chethan T N Date: Fri, 7 Nov 2025 11:10:11 +0530 Subject: [PATCH] Bluetooth: btintel_pcie: Introduce HCI Driver protocol This patch adds the infrastructure that allow the user space program to talk to intel pcie driver directly for fetching basic driver details. The changes introduced are referred form commit 04425292a62c15 ("Bluetooth: Introduce HCI Driver protocol") Signed-off-by: Chethan T N Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btintel_pcie.c | 59 ++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index b0ad3c759ef5..2936b535479f 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -19,6 +19,7 @@ #include #include +#include #include "btintel.h" #include "btintel_pcie.h" @@ -2360,6 +2361,63 @@ static bool btintel_pcie_wakeup(struct hci_dev *hdev) return device_may_wakeup(&data->pdev->dev); } +static const struct { + u16 opcode; + const char *desc; +} btintel_pcie_hci_drv_supported_commands[] = { + /* Common commands */ + { HCI_DRV_OP_READ_INFO, "Read Info" }, +}; + +static int btintel_pcie_hci_drv_read_info(struct hci_dev *hdev, void *data, + u16 data_len) +{ + struct hci_drv_rp_read_info *rp; + size_t rp_size; + int err, i; + u16 opcode, num_supported_commands = + ARRAY_SIZE(btintel_pcie_hci_drv_supported_commands); + + rp_size = sizeof(*rp) + num_supported_commands * 2; + + rp = kmalloc(rp_size, GFP_KERNEL); + if (!rp) + return -ENOMEM; + + strscpy_pad(rp->driver_name, KBUILD_MODNAME); + + rp->num_supported_commands = cpu_to_le16(num_supported_commands); + for (i = 0; i < num_supported_commands; i++) { + opcode = btintel_pcie_hci_drv_supported_commands[i].opcode; + bt_dev_dbg(hdev, + "Supported HCI Drv command (0x%02x|0x%04x): %s", + hci_opcode_ogf(opcode), + hci_opcode_ocf(opcode), + btintel_pcie_hci_drv_supported_commands[i].desc); + rp->supported_commands[i] = cpu_to_le16(opcode); + } + + err = hci_drv_cmd_complete(hdev, HCI_DRV_OP_READ_INFO, + HCI_DRV_STATUS_SUCCESS, + rp, rp_size); + + kfree(rp); + return err; +} + +static const struct hci_drv_handler btintel_pcie_hci_drv_common_handlers[] = { + { btintel_pcie_hci_drv_read_info, HCI_DRV_READ_INFO_SIZE }, +}; + +static const struct hci_drv_handler btintel_pcie_hci_drv_specific_handlers[] = {}; + +static struct hci_drv btintel_pcie_hci_drv = { + .common_handler_count = ARRAY_SIZE(btintel_pcie_hci_drv_common_handlers), + .common_handlers = btintel_pcie_hci_drv_common_handlers, + .specific_handler_count = ARRAY_SIZE(btintel_pcie_hci_drv_specific_handlers), + .specific_handlers = btintel_pcie_hci_drv_specific_handlers, +}; + static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) { int err; @@ -2386,6 +2444,7 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data) hdev->set_bdaddr = btintel_set_bdaddr; hdev->reset = btintel_pcie_reset; hdev->wakeup = btintel_pcie_wakeup; + hdev->hci_drv = &btintel_pcie_hci_drv; err = hci_register_dev(hdev); if (err < 0) {