mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 15:47:36 +00:00
Merge branch 'bluetooth-fixes-from-next'
Cherry-pick what looks like safe fixes from the bluetooth net-next PR. The other changes will have to wait for 6.6 Link: https://lore.kernel.org/all/20230627191004.2586540-1-luiz.dentz@gmail.com/ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
56f66ce1fd
13 changed files with 130 additions and 66 deletions
|
@ -637,7 +637,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||||
snprintf(config.fwname, sizeof(config.fwname),
|
snprintf(config.fwname, sizeof(config.fwname),
|
||||||
"qca/%s", firmware_name);
|
"qca/%s", firmware_name);
|
||||||
else if (qca_is_wcn399x(soc_type)) {
|
else if (qca_is_wcn399x(soc_type)) {
|
||||||
if (ver.soc_id == QCA_WCN3991_SOC_ID) {
|
if (le32_to_cpu(ver.soc_id) == QCA_WCN3991_SOC_ID) {
|
||||||
snprintf(config.fwname, sizeof(config.fwname),
|
snprintf(config.fwname, sizeof(config.fwname),
|
||||||
"qca/crnv%02xu.bin", rom_ver);
|
"qca/crnv%02xu.bin", rom_ver);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1367,14 +1367,30 @@ MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_fw.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_config.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_config.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_fw.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_fw.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_config.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_config.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8723d_fw.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8723d_config.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8761a_config.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8761a_config.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8761b_fw.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8761b_config.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8761bu_fw.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8761bu_config.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8821a_fw.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8821a_fw.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8821a_config.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8821a_config.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8821c_fw.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8821c_config.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8821cs_fw.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8821cs_config.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8822b_fw.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8822b_fw.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8822b_config.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8822b_config.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8822cs_fw.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8822cs_config.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8822cu_fw.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8822cu_config.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8851bu_fw.bin");
|
||||||
|
MODULE_FIRMWARE("rtl_bt/rtl8851bu_config.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8852au_fw.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8852au_fw.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8852au_config.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8852au_config.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8852bs_fw.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8852bs_fw.bin");
|
||||||
|
@ -1383,5 +1399,3 @@ MODULE_FIRMWARE("rtl_bt/rtl8852bu_fw.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8852cu_config.bin");
|
MODULE_FIRMWARE("rtl_bt/rtl8852cu_config.bin");
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8851bu_fw.bin");
|
|
||||||
MODULE_FIRMWARE("rtl_bt/rtl8851bu_config.bin");
|
|
||||||
|
|
|
@ -613,6 +613,9 @@ static const struct usb_device_id blacklist_table[] = {
|
||||||
{ USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK |
|
{ USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK |
|
||||||
BTUSB_WIDEBAND_SPEECH |
|
BTUSB_WIDEBAND_SPEECH |
|
||||||
BTUSB_VALID_LE_STATES },
|
BTUSB_VALID_LE_STATES },
|
||||||
|
{ USB_DEVICE(0x0489, 0xe0f5), .driver_info = BTUSB_MEDIATEK |
|
||||||
|
BTUSB_WIDEBAND_SPEECH |
|
||||||
|
BTUSB_VALID_LE_STATES },
|
||||||
{ USB_DEVICE(0x13d3, 0x3568), .driver_info = BTUSB_MEDIATEK |
|
{ USB_DEVICE(0x13d3, 0x3568), .driver_info = BTUSB_MEDIATEK |
|
||||||
BTUSB_WIDEBAND_SPEECH |
|
BTUSB_WIDEBAND_SPEECH |
|
||||||
BTUSB_VALID_LE_STATES },
|
BTUSB_VALID_LE_STATES },
|
||||||
|
@ -655,6 +658,8 @@ static const struct usb_device_id blacklist_table[] = {
|
||||||
BTUSB_WIDEBAND_SPEECH },
|
BTUSB_WIDEBAND_SPEECH },
|
||||||
{ USB_DEVICE(0x0bda, 0x8771), .driver_info = BTUSB_REALTEK |
|
{ USB_DEVICE(0x0bda, 0x8771), .driver_info = BTUSB_REALTEK |
|
||||||
BTUSB_WIDEBAND_SPEECH },
|
BTUSB_WIDEBAND_SPEECH },
|
||||||
|
{ USB_DEVICE(0x6655, 0x8771), .driver_info = BTUSB_REALTEK |
|
||||||
|
BTUSB_WIDEBAND_SPEECH },
|
||||||
{ USB_DEVICE(0x7392, 0xc611), .driver_info = BTUSB_REALTEK |
|
{ USB_DEVICE(0x7392, 0xc611), .driver_info = BTUSB_REALTEK |
|
||||||
BTUSB_WIDEBAND_SPEECH },
|
BTUSB_WIDEBAND_SPEECH },
|
||||||
{ USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK |
|
{ USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK |
|
||||||
|
|
|
@ -643,7 +643,8 @@ static int bcm_setup(struct hci_uart *hu)
|
||||||
* Allow the bootloader to set a valid address through the
|
* Allow the bootloader to set a valid address through the
|
||||||
* device tree.
|
* device tree.
|
||||||
*/
|
*/
|
||||||
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hu->hdev->quirks);
|
if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks))
|
||||||
|
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hu->hdev->quirks);
|
||||||
|
|
||||||
if (!bcm_request_irq(bcm))
|
if (!bcm_request_irq(bcm))
|
||||||
err = bcm_setup_sleep(hu);
|
err = bcm_setup_sleep(hu);
|
||||||
|
|
|
@ -185,7 +185,7 @@ struct bt_iso_ucast_qos {
|
||||||
struct bt_iso_bcast_qos {
|
struct bt_iso_bcast_qos {
|
||||||
__u8 big;
|
__u8 big;
|
||||||
__u8 bis;
|
__u8 bis;
|
||||||
__u8 sync_interval;
|
__u8 sync_factor;
|
||||||
__u8 packing;
|
__u8 packing;
|
||||||
__u8 framing;
|
__u8 framing;
|
||||||
struct bt_iso_io_qos in;
|
struct bt_iso_io_qos in;
|
||||||
|
|
|
@ -979,6 +979,7 @@ struct mgmt_ev_auth_failed {
|
||||||
#define MGMT_DEV_FOUND_NOT_CONNECTABLE BIT(2)
|
#define MGMT_DEV_FOUND_NOT_CONNECTABLE BIT(2)
|
||||||
#define MGMT_DEV_FOUND_INITIATED_CONN BIT(3)
|
#define MGMT_DEV_FOUND_INITIATED_CONN BIT(3)
|
||||||
#define MGMT_DEV_FOUND_NAME_REQUEST_FAILED BIT(4)
|
#define MGMT_DEV_FOUND_NAME_REQUEST_FAILED BIT(4)
|
||||||
|
#define MGMT_DEV_FOUND_SCAN_RSP BIT(5)
|
||||||
|
|
||||||
#define MGMT_EV_DEVICE_FOUND 0x0012
|
#define MGMT_EV_DEVICE_FOUND 0x0012
|
||||||
struct mgmt_ev_device_found {
|
struct mgmt_ev_device_found {
|
||||||
|
|
|
@ -775,6 +775,11 @@ static void le_conn_timeout(struct work_struct *work)
|
||||||
hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
|
hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct iso_cig_params {
|
||||||
|
struct hci_cp_le_set_cig_params cp;
|
||||||
|
struct hci_cis_params cis[0x1f];
|
||||||
|
};
|
||||||
|
|
||||||
struct iso_list_data {
|
struct iso_list_data {
|
||||||
union {
|
union {
|
||||||
u8 cig;
|
u8 cig;
|
||||||
|
@ -786,10 +791,7 @@ struct iso_list_data {
|
||||||
u16 sync_handle;
|
u16 sync_handle;
|
||||||
};
|
};
|
||||||
int count;
|
int count;
|
||||||
struct {
|
struct iso_cig_params pdu;
|
||||||
struct hci_cp_le_set_cig_params cp;
|
|
||||||
struct hci_cis_params cis[0x11];
|
|
||||||
} pdu;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bis_list(struct hci_conn *conn, void *data)
|
static void bis_list(struct hci_conn *conn, void *data)
|
||||||
|
@ -1764,10 +1766,33 @@ static int hci_le_create_big(struct hci_conn *conn, struct bt_iso_qos *qos)
|
||||||
return hci_send_cmd(hdev, HCI_OP_LE_CREATE_BIG, sizeof(cp), &cp);
|
return hci_send_cmd(hdev, HCI_OP_LE_CREATE_BIG, sizeof(cp), &cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_cig_params_complete(struct hci_dev *hdev, void *data, int err)
|
||||||
|
{
|
||||||
|
struct iso_cig_params *pdu = data;
|
||||||
|
|
||||||
|
bt_dev_dbg(hdev, "");
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
bt_dev_err(hdev, "Unable to set CIG parameters: %d", err);
|
||||||
|
|
||||||
|
kfree(pdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_cig_params_sync(struct hci_dev *hdev, void *data)
|
||||||
|
{
|
||||||
|
struct iso_cig_params *pdu = data;
|
||||||
|
u32 plen;
|
||||||
|
|
||||||
|
plen = sizeof(pdu->cp) + pdu->cp.num_cis * sizeof(pdu->cis[0]);
|
||||||
|
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_CIG_PARAMS, plen, pdu,
|
||||||
|
HCI_CMD_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
|
static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
|
||||||
{
|
{
|
||||||
struct hci_dev *hdev = conn->hdev;
|
struct hci_dev *hdev = conn->hdev;
|
||||||
struct iso_list_data data;
|
struct iso_list_data data;
|
||||||
|
struct iso_cig_params *pdu;
|
||||||
|
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
|
|
||||||
|
@ -1837,12 +1862,16 @@ static bool hci_le_set_cig_params(struct hci_conn *conn, struct bt_iso_qos *qos)
|
||||||
if (qos->ucast.cis == BT_ISO_QOS_CIS_UNSET || !data.pdu.cp.num_cis)
|
if (qos->ucast.cis == BT_ISO_QOS_CIS_UNSET || !data.pdu.cp.num_cis)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (hci_send_cmd(hdev, HCI_OP_LE_SET_CIG_PARAMS,
|
pdu = kmemdup(&data.pdu, sizeof(*pdu), GFP_KERNEL);
|
||||||
sizeof(data.pdu.cp) +
|
if (!pdu)
|
||||||
(data.pdu.cp.num_cis * sizeof(*data.pdu.cis)),
|
|
||||||
&data.pdu) < 0)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (hci_cmd_sync_queue(hdev, set_cig_params_sync, pdu,
|
||||||
|
set_cig_params_complete) < 0) {
|
||||||
|
kfree(pdu);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2044,10 +2073,10 @@ static int create_big_sync(struct hci_dev *hdev, void *data)
|
||||||
flags |= MGMT_ADV_FLAG_SEC_2M;
|
flags |= MGMT_ADV_FLAG_SEC_2M;
|
||||||
|
|
||||||
/* Align intervals */
|
/* Align intervals */
|
||||||
interval = qos->bcast.out.interval / 1250;
|
interval = (qos->bcast.out.interval / 1250) * qos->bcast.sync_factor;
|
||||||
|
|
||||||
if (qos->bcast.bis)
|
if (qos->bcast.bis)
|
||||||
sync_interval = qos->bcast.sync_interval * 1600;
|
sync_interval = interval * 4;
|
||||||
|
|
||||||
err = hci_start_per_adv_sync(hdev, qos->bcast.bis, conn->le_per_adv_data_len,
|
err = hci_start_per_adv_sync(hdev, qos->bcast.bis, conn->le_per_adv_data_len,
|
||||||
conn->le_per_adv_data, flags, interval,
|
conn->le_per_adv_data, flags, interval,
|
||||||
|
|
|
@ -3812,7 +3812,8 @@ static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data,
|
||||||
bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
|
bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
|
||||||
|
|
||||||
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_CIG_PARAMS);
|
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_CIG_PARAMS);
|
||||||
if (!cp || rp->num_handles != cp->num_cis || rp->cig_id != cp->cig_id) {
|
if (!rp->status && (!cp || rp->num_handles != cp->num_cis ||
|
||||||
|
rp->cig_id != cp->cig_id)) {
|
||||||
bt_dev_err(hdev, "unexpected Set CIG Parameters response data");
|
bt_dev_err(hdev, "unexpected Set CIG Parameters response data");
|
||||||
status = HCI_ERROR_UNSPECIFIED;
|
status = HCI_ERROR_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
@ -6316,23 +6317,18 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When receiving non-connectable or scannable undirected
|
/* When receiving a scan response, then there is no way to
|
||||||
* advertising reports, this means that the remote device is
|
|
||||||
* not connectable and then clearly indicate this in the
|
|
||||||
* device found event.
|
|
||||||
*
|
|
||||||
* When receiving a scan response, then there is no way to
|
|
||||||
* know if the remote device is connectable or not. However
|
* know if the remote device is connectable or not. However
|
||||||
* since scan responses are merged with a previously seen
|
* since scan responses are merged with a previously seen
|
||||||
* advertising report, the flags field from that report
|
* advertising report, the flags field from that report
|
||||||
* will be used.
|
* will be used.
|
||||||
*
|
*
|
||||||
* In the really unlikely case that a controller get confused
|
* In the unlikely case that a controller just sends a scan
|
||||||
* and just sends a scan response event, then it is marked as
|
* response event that doesn't match the pending report, then
|
||||||
* not connectable as well.
|
* it is marked as a standalone SCAN_RSP.
|
||||||
*/
|
*/
|
||||||
if (type == LE_ADV_SCAN_RSP)
|
if (type == LE_ADV_SCAN_RSP)
|
||||||
flags = MGMT_DEV_FOUND_NOT_CONNECTABLE;
|
flags = MGMT_DEV_FOUND_SCAN_RSP;
|
||||||
|
|
||||||
/* If there's nothing pending either store the data from this
|
/* If there's nothing pending either store the data from this
|
||||||
* event or send an immediate device found event if the data
|
* event or send an immediate device found event if the data
|
||||||
|
@ -6790,6 +6786,7 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
|
||||||
{
|
{
|
||||||
struct hci_evt_le_cis_established *ev = data;
|
struct hci_evt_le_cis_established *ev = data;
|
||||||
struct hci_conn *conn;
|
struct hci_conn *conn;
|
||||||
|
struct bt_iso_qos *qos;
|
||||||
u16 handle = __le16_to_cpu(ev->handle);
|
u16 handle = __le16_to_cpu(ev->handle);
|
||||||
|
|
||||||
bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
|
bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
|
||||||
|
@ -6811,21 +6808,39 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->role == HCI_ROLE_SLAVE) {
|
qos = &conn->iso_qos;
|
||||||
__le32 interval;
|
|
||||||
|
|
||||||
memset(&interval, 0, sizeof(interval));
|
/* Convert ISO Interval (1.25 ms slots) to SDU Interval (us) */
|
||||||
|
qos->ucast.in.interval = le16_to_cpu(ev->interval) * 1250;
|
||||||
|
qos->ucast.out.interval = qos->ucast.in.interval;
|
||||||
|
|
||||||
memcpy(&interval, ev->c_latency, sizeof(ev->c_latency));
|
switch (conn->role) {
|
||||||
conn->iso_qos.ucast.in.interval = le32_to_cpu(interval);
|
case HCI_ROLE_SLAVE:
|
||||||
memcpy(&interval, ev->p_latency, sizeof(ev->p_latency));
|
/* Convert Transport Latency (us) to Latency (msec) */
|
||||||
conn->iso_qos.ucast.out.interval = le32_to_cpu(interval);
|
qos->ucast.in.latency =
|
||||||
conn->iso_qos.ucast.in.latency = le16_to_cpu(ev->interval);
|
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
|
||||||
conn->iso_qos.ucast.out.latency = le16_to_cpu(ev->interval);
|
1000);
|
||||||
conn->iso_qos.ucast.in.sdu = le16_to_cpu(ev->c_mtu);
|
qos->ucast.out.latency =
|
||||||
conn->iso_qos.ucast.out.sdu = le16_to_cpu(ev->p_mtu);
|
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
|
||||||
conn->iso_qos.ucast.in.phy = ev->c_phy;
|
1000);
|
||||||
conn->iso_qos.ucast.out.phy = ev->p_phy;
|
qos->ucast.in.sdu = le16_to_cpu(ev->c_mtu);
|
||||||
|
qos->ucast.out.sdu = le16_to_cpu(ev->p_mtu);
|
||||||
|
qos->ucast.in.phy = ev->c_phy;
|
||||||
|
qos->ucast.out.phy = ev->p_phy;
|
||||||
|
break;
|
||||||
|
case HCI_ROLE_MASTER:
|
||||||
|
/* Convert Transport Latency (us) to Latency (msec) */
|
||||||
|
qos->ucast.out.latency =
|
||||||
|
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->c_latency),
|
||||||
|
1000);
|
||||||
|
qos->ucast.in.latency =
|
||||||
|
DIV_ROUND_CLOSEST(get_unaligned_le24(ev->p_latency),
|
||||||
|
1000);
|
||||||
|
qos->ucast.out.sdu = le16_to_cpu(ev->c_mtu);
|
||||||
|
qos->ucast.in.sdu = le16_to_cpu(ev->p_mtu);
|
||||||
|
qos->ucast.out.phy = ev->c_phy;
|
||||||
|
qos->ucast.in.phy = ev->p_phy;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ev->status) {
|
if (!ev->status) {
|
||||||
|
|
|
@ -4623,26 +4623,18 @@ static int hci_dev_setup_sync(struct hci_dev *hdev)
|
||||||
* BD_ADDR invalid before creating the HCI device or in
|
* BD_ADDR invalid before creating the HCI device or in
|
||||||
* its setup callback.
|
* its setup callback.
|
||||||
*/
|
*/
|
||||||
invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
|
invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) ||
|
||||||
|
test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) {
|
if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) &&
|
||||||
if (!bacmp(&hdev->public_addr, BDADDR_ANY))
|
!bacmp(&hdev->public_addr, BDADDR_ANY))
|
||||||
hci_dev_get_bd_addr_from_property(hdev);
|
hci_dev_get_bd_addr_from_property(hdev);
|
||||||
|
|
||||||
if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
|
if (invalid_bdaddr && bacmp(&hdev->public_addr, BDADDR_ANY) &&
|
||||||
hdev->set_bdaddr) {
|
hdev->set_bdaddr) {
|
||||||
ret = hdev->set_bdaddr(hdev,
|
ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
|
||||||
&hdev->public_addr);
|
if (!ret)
|
||||||
|
invalid_bdaddr = false;
|
||||||
/* If setting of the BD_ADDR from the device
|
|
||||||
* property succeeds, then treat the address
|
|
||||||
* as valid even if the invalid BD_ADDR
|
|
||||||
* quirk indicates otherwise.
|
|
||||||
*/
|
|
||||||
if (!ret)
|
|
||||||
invalid_bdaddr = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
#include <net/bluetooth/hci_core.h>
|
#include <net/bluetooth/hci_core.h>
|
||||||
|
|
||||||
static struct class *bt_class;
|
static const struct class bt_class = {
|
||||||
|
.name = "bluetooth",
|
||||||
|
};
|
||||||
|
|
||||||
static void bt_link_release(struct device *dev)
|
static void bt_link_release(struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -36,7 +38,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn)
|
||||||
BT_DBG("conn %p", conn);
|
BT_DBG("conn %p", conn);
|
||||||
|
|
||||||
conn->dev.type = &bt_link;
|
conn->dev.type = &bt_link;
|
||||||
conn->dev.class = bt_class;
|
conn->dev.class = &bt_class;
|
||||||
conn->dev.parent = &hdev->dev;
|
conn->dev.parent = &hdev->dev;
|
||||||
|
|
||||||
device_initialize(&conn->dev);
|
device_initialize(&conn->dev);
|
||||||
|
@ -104,7 +106,7 @@ void hci_init_sysfs(struct hci_dev *hdev)
|
||||||
struct device *dev = &hdev->dev;
|
struct device *dev = &hdev->dev;
|
||||||
|
|
||||||
dev->type = &bt_host;
|
dev->type = &bt_host;
|
||||||
dev->class = bt_class;
|
dev->class = &bt_class;
|
||||||
|
|
||||||
__module_get(THIS_MODULE);
|
__module_get(THIS_MODULE);
|
||||||
device_initialize(dev);
|
device_initialize(dev);
|
||||||
|
@ -112,12 +114,10 @@ void hci_init_sysfs(struct hci_dev *hdev)
|
||||||
|
|
||||||
int __init bt_sysfs_init(void)
|
int __init bt_sysfs_init(void)
|
||||||
{
|
{
|
||||||
bt_class = class_create("bluetooth");
|
return class_register(&bt_class);
|
||||||
|
|
||||||
return PTR_ERR_OR_ZERO(bt_class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_sysfs_cleanup(void)
|
void bt_sysfs_cleanup(void)
|
||||||
{
|
{
|
||||||
class_destroy(bt_class);
|
class_unregister(&bt_class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -704,7 +704,7 @@ static struct bt_iso_qos default_qos = {
|
||||||
.bcast = {
|
.bcast = {
|
||||||
.big = BT_ISO_QOS_BIG_UNSET,
|
.big = BT_ISO_QOS_BIG_UNSET,
|
||||||
.bis = BT_ISO_QOS_BIS_UNSET,
|
.bis = BT_ISO_QOS_BIS_UNSET,
|
||||||
.sync_interval = 0x00,
|
.sync_factor = 0x01,
|
||||||
.packing = 0x00,
|
.packing = 0x00,
|
||||||
.framing = 0x00,
|
.framing = 0x00,
|
||||||
.in = DEFAULT_IO_QOS,
|
.in = DEFAULT_IO_QOS,
|
||||||
|
@ -1213,7 +1213,7 @@ static bool check_ucast_qos(struct bt_iso_qos *qos)
|
||||||
|
|
||||||
static bool check_bcast_qos(struct bt_iso_qos *qos)
|
static bool check_bcast_qos(struct bt_iso_qos *qos)
|
||||||
{
|
{
|
||||||
if (qos->bcast.sync_interval > 0x07)
|
if (qos->bcast.sync_factor == 0x00)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (qos->bcast.packing > 0x01)
|
if (qos->bcast.packing > 0x01)
|
||||||
|
|
|
@ -6374,9 +6374,14 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
|
||||||
if (!chan)
|
if (!chan)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
chan = l2cap_chan_hold_unless_zero(chan);
|
||||||
|
if (!chan)
|
||||||
|
goto done;
|
||||||
|
|
||||||
l2cap_chan_lock(chan);
|
l2cap_chan_lock(chan);
|
||||||
l2cap_chan_del(chan, ECONNREFUSED);
|
l2cap_chan_del(chan, ECONNREFUSED);
|
||||||
l2cap_chan_unlock(chan);
|
l2cap_chan_unlock(chan);
|
||||||
|
l2cap_chan_put(chan);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
mutex_unlock(&conn->chan_lock);
|
mutex_unlock(&conn->chan_lock);
|
||||||
|
|
|
@ -46,6 +46,7 @@ static const struct proto_ops l2cap_sock_ops;
|
||||||
static void l2cap_sock_init(struct sock *sk, struct sock *parent);
|
static void l2cap_sock_init(struct sock *sk, struct sock *parent);
|
||||||
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
|
static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
|
||||||
int proto, gfp_t prio, int kern);
|
int proto, gfp_t prio, int kern);
|
||||||
|
static void l2cap_sock_cleanup_listen(struct sock *parent);
|
||||||
|
|
||||||
bool l2cap_is_socket(struct socket *sock)
|
bool l2cap_is_socket(struct socket *sock)
|
||||||
{
|
{
|
||||||
|
@ -1415,6 +1416,7 @@ static int l2cap_sock_release(struct socket *sock)
|
||||||
if (!sk)
|
if (!sk)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
l2cap_sock_cleanup_listen(sk);
|
||||||
bt_sock_unlink(&l2cap_sk_list, sk);
|
bt_sock_unlink(&l2cap_sk_list, sk);
|
||||||
|
|
||||||
err = l2cap_sock_shutdown(sock, SHUT_RDWR);
|
err = l2cap_sock_shutdown(sock, SHUT_RDWR);
|
||||||
|
|
Loading…
Reference in a new issue