drivers/bluetooth/hci_ath.c

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

File Facts

System
Linux kernel
Corpus path
drivers/bluetooth/hci_ath.c
Extension
.c
Size
5402 bytes
Lines
272
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 ath_struct {
	struct hci_uart *hu;
	unsigned int cur_sleep;

	struct sk_buff *rx_skb;
	struct sk_buff_head txq;
	struct work_struct ctxtsw;
};

#define OP_WRITE_TAG	0x01

#define INDEX_BDADDR	0x01

struct ath_vendor_cmd {
	__u8 opcode;
	__le16 index;
	__u8 len;
	__u8 data[251];
} __packed;

static int ath_wakeup_ar3k(struct tty_struct *tty)
{
	int status = tty->driver->ops->tiocmget(tty);

	if (status & TIOCM_CTS)
		return status;

	/* Clear RTS first */
	tty->driver->ops->tiocmget(tty);
	tty->driver->ops->tiocmset(tty, 0x00, TIOCM_RTS);
	msleep(20);

	/* Set RTS, wake up board */
	tty->driver->ops->tiocmget(tty);
	tty->driver->ops->tiocmset(tty, TIOCM_RTS, 0x00);
	msleep(20);

	status = tty->driver->ops->tiocmget(tty);
	return status;
}

static void ath_hci_uart_work(struct work_struct *work)
{
	int status;
	struct ath_struct *ath;
	struct hci_uart *hu;
	struct tty_struct *tty;

	ath = container_of(work, struct ath_struct, ctxtsw);

	hu = ath->hu;
	tty = hu->tty;

	/* verify and wake up controller */
	if (ath->cur_sleep) {
		status = ath_wakeup_ar3k(tty);
		if (!(status & TIOCM_CTS))
			return;
	}

	/* Ready to send Data */
	clear_bit(HCI_UART_SENDING, &hu->tx_state);
	hci_uart_tx_wakeup(hu);
}

static int ath_open(struct hci_uart *hu)
{
	struct ath_struct *ath;

	BT_DBG("hu %p", hu);

	if (!hci_uart_has_flow_control(hu))
		return -EOPNOTSUPP;

	ath = kzalloc_obj(*ath);
	if (!ath)
		return -ENOMEM;

	skb_queue_head_init(&ath->txq);

	hu->priv = ath;
	ath->hu = hu;

	INIT_WORK(&ath->ctxtsw, ath_hci_uart_work);

	return 0;
}

static int ath_close(struct hci_uart *hu)
{

Annotation

Implementation Notes