drivers/bluetooth/hci_h5.c

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

File Facts

System
Linux kernel
Corpus path
drivers/bluetooth/hci_h5.c
Extension
.c
Size
27199 bytes
Lines
1178
Domain
Driver Families
Bucket
drivers/bluetooth
Inferred role
Driver Families: implementation source
Status
source 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

struct h5 {
	/* Must be the first member, hci_serdev.c expects this. */
	struct hci_uart		serdev_hu;

	struct sk_buff_head	unack;		/* Unack'ed packets queue */
	struct sk_buff_head	rel;		/* Reliable packets queue */
	struct sk_buff_head	unrel;		/* Unreliable packets queue */

	unsigned long		flags;

	struct sk_buff		*rx_skb;	/* Receive buffer */
	size_t			rx_pending;	/* Expecting more bytes */
	u8			rx_ack;		/* Last ack number received */

	int			(*rx_func)(struct hci_uart *hu, u8 c);

	struct timer_list	timer;		/* Retransmission timer */
	struct hci_uart		*hu;		/* Parent HCI UART */

	u8			tx_seq;		/* Next seq number to send */
	u8			tx_ack;		/* Next ack number to send */
	u8			tx_win;		/* Sliding window size */

	enum {
		H5_UNINITIALIZED,
		H5_INITIALIZED,
		H5_ACTIVE,
	} state;

	enum {
		H5_AWAKE,
		H5_SLEEPING,
		H5_WAKING_UP,
	} sleep;

	const struct h5_vnd *vnd;
	const char *id;

	struct gpio_desc *enable_gpio;
	struct gpio_desc *device_wake_gpio;
};

enum h5_driver_info {
	H5_INFO_WAKEUP_DISABLE = BIT(0),
};

struct h5_vnd {
	int (*setup)(struct h5 *h5);
	void (*open)(struct h5 *h5);
	void (*close)(struct h5 *h5);
	int (*suspend)(struct h5 *h5);
	int (*resume)(struct h5 *h5);
	const struct acpi_gpio_mapping *acpi_gpio_map;
	int sizeof_priv;
};

struct h5_device_data {
	uint32_t driver_info;
	struct h5_vnd *vnd;
};

static void h5_reset_rx(struct h5 *h5);

static void h5_link_control(struct hci_uart *hu, const void *data, size_t len)
{
	struct h5 *h5 = hu->priv;
	struct sk_buff *nskb;

	nskb = alloc_skb(3, GFP_ATOMIC);
	if (!nskb)
		return;

	hci_skb_pkt_type(nskb) = HCI_3WIRE_LINK_PKT;

	skb_put_data(nskb, data, len);

	skb_queue_tail(&h5->unrel, nskb);
}

static u8 h5_cfg_field(struct h5 *h5)
{
	/* Sliding window size (first 3 bits) and CRC request (fifth bit). */
	return (h5->tx_win & 0x07) | 0x10;
}

static void h5_timed_event(struct timer_list *t)
{
	const unsigned char sync_req[] = { 0x01, 0x7e };
	unsigned char conf_req[3] = { 0x03, 0xfc };
	struct h5 *h5 = timer_container_of(h5, t, timer);

Annotation

Implementation Notes