drivers/bluetooth/btusb.c

Source file repositories/reference/linux-study-clean/drivers/bluetooth/btusb.c

File Facts

System
Linux kernel
Corpus path
drivers/bluetooth/btusb.c
Extension
.c
Size
136256 bytes
Lines
4730
Domain
Driver Families
Bucket
drivers/bluetooth
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations force_poll_sync_fops = {
	.owner		= THIS_MODULE,
	.open		= simple_open,
	.read		= force_poll_sync_read,
	.write		= force_poll_sync_write,
	.llseek		= default_llseek,
};

#define BTUSB_HCI_DRV_OP_SUPPORTED_ALTSETTINGS \
		hci_opcode_pack(HCI_DRV_OGF_DRIVER_SPECIFIC, 0x0000)
#define BTUSB_HCI_DRV_SUPPORTED_ALTSETTINGS_SIZE	0
struct btusb_hci_drv_rp_supported_altsettings {
	__u8	num;
	__u8	altsettings[];
} __packed;

#define BTUSB_HCI_DRV_OP_SWITCH_ALTSETTING \
		hci_opcode_pack(HCI_DRV_OGF_DRIVER_SPECIFIC, 0x0001)
#define BTUSB_HCI_DRV_SWITCH_ALTSETTING_SIZE		1
struct btusb_hci_drv_cmd_switch_altsetting {
	__u8	altsetting;
} __packed;

static const struct {
	u16 opcode;
	const char *desc;
} btusb_hci_drv_supported_commands[] = {
	/* Common commands */
	{ HCI_DRV_OP_READ_INFO, "Read Info" },

	/* Driver specific commands */
	{ BTUSB_HCI_DRV_OP_SUPPORTED_ALTSETTINGS, "Supported Altsettings" },
	{ BTUSB_HCI_DRV_OP_SWITCH_ALTSETTING,     "Switch Altsetting" },
};
static int btusb_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(btusb_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, btusb_driver.name);

	rp->num_supported_commands = cpu_to_le16(num_supported_commands);
	for (i = 0; i < num_supported_commands; i++) {
		opcode = btusb_hci_drv_supported_commands[i].opcode;
		bt_dev_info(hdev,
			    "Supported HCI Drv command (0x%02x|0x%04x): %s",
			    hci_opcode_ogf(opcode),
			    hci_opcode_ocf(opcode),
			    btusb_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 int btusb_hci_drv_supported_altsettings(struct hci_dev *hdev, void *data,
					       u16 data_len)
{
	struct btusb_data *drvdata = hci_get_drvdata(hdev);
	struct btusb_hci_drv_rp_supported_altsettings *rp;
	size_t rp_size;
	int err;
	u8 i;

	/* There are at most 7 alt (0 - 6) */
	rp = kmalloc(sizeof(*rp) + 7, GFP_KERNEL);
	if (!rp)
		return -ENOMEM;

	rp->num = 0;
	if (!drvdata->isoc)
		goto done;

	for (i = 0; i <= 6; i++) {
		if (btusb_find_altsetting(drvdata, i))
			rp->altsettings[rp->num++] = i;

Annotation

Implementation Notes