Commit bc6f557b authored by Chethan T N's avatar Chethan T N Committed by Luiz Augusto von Dentz
Browse files

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 04425292 ("Bluetooth: Introduce HCI Driver protocol")

Signed-off-by: default avatarChethan T N <chethan.tumkur.narayan@intel.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent a8b38d19
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_drv.h>

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