mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

Although commit75ddcd5ad4
("Bluetooth: btusb: Configure altsetting for HCI_USER_CHANNEL") has enabled the HCI_USER_CHANNEL user to send out SCO data through USB Bluetooth chips, it's observed that with the patch HFP is flaky on most of the existing USB Bluetooth controllers: Intel chips sometimes send out no packet for Transparent codec; MTK chips may generate SCO data with a wrong handle for CVSD codec; RTK could split the data with a wrong packet size for Transparent codec; ... etc. To address the issue above one needs to reset the altsetting back to zero when there is no active SCO connection, which is the same as the BlueZ behavior, and another benefit is the bus doesn't need to reserve bandwidth when no SCO connection. This patch adds the infrastructure that allow the user space program to talk to Bluetooth drivers directly: - Define the new packet type HCI_DRV_PKT which is specifically used for communication between the user space program and the Bluetooth drviers - hci_send_frame intercepts the packets and invokes drivers' HCI Drv callbacks (so far only defined for btusb) - 2 kinds of events to user space: Command Status and Command Complete, the former simply returns the status while the later may contain additional response data. Cc: chromeos-bluetooth-upstreaming@chromium.org Fixes:b16b327edb
("Bluetooth: btusb: add sysfs attribute to control USB alt setting") Signed-off-by: Hsin-chen Chuang <chharry@chromium.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
76 lines
1.8 KiB
C
76 lines
1.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (C) 2025 Google Corporation
|
|
*/
|
|
|
|
#ifndef __HCI_DRV_H
|
|
#define __HCI_DRV_H
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <net/bluetooth/bluetooth.h>
|
|
#include <net/bluetooth/hci.h>
|
|
|
|
struct hci_drv_cmd_hdr {
|
|
__le16 opcode;
|
|
__le16 len;
|
|
} __packed;
|
|
|
|
struct hci_drv_ev_hdr {
|
|
__le16 opcode;
|
|
__le16 len;
|
|
} __packed;
|
|
|
|
#define HCI_DRV_EV_CMD_STATUS 0x0000
|
|
struct hci_drv_ev_cmd_status {
|
|
__le16 opcode;
|
|
__u8 status;
|
|
} __packed;
|
|
|
|
#define HCI_DRV_EV_CMD_COMPLETE 0x0001
|
|
struct hci_drv_ev_cmd_complete {
|
|
__le16 opcode;
|
|
__u8 status;
|
|
__u8 data[];
|
|
} __packed;
|
|
|
|
#define HCI_DRV_STATUS_SUCCESS 0x00
|
|
#define HCI_DRV_STATUS_UNSPECIFIED_ERROR 0x01
|
|
#define HCI_DRV_STATUS_UNKNOWN_COMMAND 0x02
|
|
#define HCI_DRV_STATUS_INVALID_PARAMETERS 0x03
|
|
|
|
#define HCI_DRV_MAX_DRIVER_NAME_LENGTH 32
|
|
|
|
/* Common commands that make sense on all drivers start from 0x0000 */
|
|
#define HCI_DRV_OP_READ_INFO 0x0000
|
|
#define HCI_DRV_READ_INFO_SIZE 0
|
|
struct hci_drv_rp_read_info {
|
|
__u8 driver_name[HCI_DRV_MAX_DRIVER_NAME_LENGTH];
|
|
__le16 num_supported_commands;
|
|
__le16 supported_commands[];
|
|
} __packed;
|
|
|
|
/* Driver specific OGF (Opcode Group Field)
|
|
* Commands in this group may have different meanings across different drivers.
|
|
*/
|
|
#define HCI_DRV_OGF_DRIVER_SPECIFIC 0x01
|
|
|
|
int hci_drv_cmd_status(struct hci_dev *hdev, u16 cmd, u8 status);
|
|
int hci_drv_cmd_complete(struct hci_dev *hdev, u16 cmd, u8 status, void *rp,
|
|
size_t rp_len);
|
|
int hci_drv_process_cmd(struct hci_dev *hdev, struct sk_buff *cmd_skb);
|
|
|
|
struct hci_drv_handler {
|
|
int (*func)(struct hci_dev *hdev, void *data, u16 data_len);
|
|
size_t data_len;
|
|
};
|
|
|
|
struct hci_drv {
|
|
size_t common_handler_count;
|
|
const struct hci_drv_handler *common_handlers;
|
|
|
|
size_t specific_handler_count;
|
|
const struct hci_drv_handler *specific_handlers;
|
|
};
|
|
|
|
#endif /* __HCI_DRV_H */
|