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) {