Loading include/net/bluetooth/hci_core.h +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ struct bdaddr_list { struct bt_uuid { struct list_head list; u8 uuid[16]; u8 size; u8 svc_hint; }; Loading net/bluetooth/hci_core.c +3 −7 Original line number Diff line number Diff line Loading @@ -1183,14 +1183,10 @@ static void hci_discov_off(struct work_struct *work) int hci_uuids_clear(struct hci_dev *hdev) { struct list_head *p, *n; list_for_each_safe(p, n, &hdev->uuids) { struct bt_uuid *uuid; struct bt_uuid *uuid, *tmp; uuid = list_entry(p, struct bt_uuid, list); list_del(p); list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { list_del(&uuid->list); kfree(uuid); } Loading net/bluetooth/hci_event.c +0 −4 Original line number Diff line number Diff line Loading @@ -3988,8 +3988,6 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) void *ptr = &skb->data[1]; s8 rssi; hci_dev_lock(hdev); while (num_reports--) { struct hci_ev_le_advertising_info *ev = ptr; Loading @@ -3999,8 +3997,6 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) ptr += sizeof(*ev) + ev->length + 1; } hci_dev_unlock(hdev); } static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) Loading net/bluetooth/mgmt.c +136 −83 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ bool enable_hs; #define MGMT_VERSION 1 #define MGMT_REVISION 2 #define MGMT_REVISION 3 static const u16 mgmt_commands[] = { MGMT_OP_READ_INDEX_LIST, Loading Loading @@ -435,35 +435,117 @@ static u32 get_current_settings(struct hci_dev *hdev) #define PNP_INFO_SVCLASS_ID 0x1200 static u8 bluetooth_base_uuid[] = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static u8 *create_uuid16_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) { u8 *ptr = data, *uuids_start = NULL; struct bt_uuid *uuid; if (len < 4) return ptr; list_for_each_entry(uuid, &hdev->uuids, list) { u16 uuid16; if (uuid->size != 16) continue; uuid16 = get_unaligned_le16(&uuid->uuid[12]); if (uuid16 < 0x1100) continue; if (uuid16 == PNP_INFO_SVCLASS_ID) continue; if (!uuids_start) { uuids_start = ptr; uuids_start[0] = 1; uuids_start[1] = EIR_UUID16_ALL; ptr += 2; } /* Stop if not enough space to put next UUID */ if ((ptr - data) + sizeof(u16) > len) { uuids_start[1] = EIR_UUID16_SOME; break; } *ptr++ = (uuid16 & 0x00ff); *ptr++ = (uuid16 & 0xff00) >> 8; uuids_start[0] += sizeof(uuid16); } static u16 get_uuid16(u8 *uuid128) return ptr; } static u8 *create_uuid32_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) { u32 val; int i; u8 *ptr = data, *uuids_start = NULL; struct bt_uuid *uuid; for (i = 0; i < 12; i++) { if (bluetooth_base_uuid[i] != uuid128[i]) return 0; if (len < 6) return ptr; list_for_each_entry(uuid, &hdev->uuids, list) { if (uuid->size != 32) continue; if (!uuids_start) { uuids_start = ptr; uuids_start[0] = 1; uuids_start[1] = EIR_UUID32_ALL; ptr += 2; } val = get_unaligned_le32(&uuid128[12]); if (val > 0xffff) return 0; /* Stop if not enough space to put next UUID */ if ((ptr - data) + sizeof(u32) > len) { uuids_start[1] = EIR_UUID32_SOME; break; } memcpy(ptr, &uuid->uuid[12], sizeof(u32)); ptr += sizeof(u32); uuids_start[0] += sizeof(u32); } return ptr; } static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) { u8 *ptr = data, *uuids_start = NULL; struct bt_uuid *uuid; if (len < 18) return ptr; list_for_each_entry(uuid, &hdev->uuids, list) { if (uuid->size != 128) continue; if (!uuids_start) { uuids_start = ptr; uuids_start[0] = 1; uuids_start[1] = EIR_UUID128_ALL; ptr += 2; } return (u16) val; /* Stop if not enough space to put next UUID */ if ((ptr - data) + 16 > len) { uuids_start[1] = EIR_UUID128_SOME; break; } memcpy(ptr, uuid->uuid, 16); ptr += 16; uuids_start[0] += 16; } return ptr; } static void create_eir(struct hci_dev *hdev, u8 *data) { u8 *ptr = data; u16 eir_len = 0; u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; int i, truncated = 0; struct bt_uuid *uuid; size_t name_len; name_len = strlen(hdev->dev_name); Loading @@ -481,7 +563,6 @@ static void create_eir(struct hci_dev *hdev, u8 *data) memcpy(ptr + 2, hdev->dev_name, name_len); eir_len += (name_len + 2); ptr += (name_len + 2); } Loading @@ -490,7 +571,6 @@ static void create_eir(struct hci_dev *hdev, u8 *data) ptr[1] = EIR_TX_POWER; ptr[2] = (u8) hdev->inq_tx_power; eir_len += 3; ptr += 3; } Loading @@ -503,60 +583,12 @@ static void create_eir(struct hci_dev *hdev, u8 *data) put_unaligned_le16(hdev->devid_product, ptr + 6); put_unaligned_le16(hdev->devid_version, ptr + 8); eir_len += 10; ptr += 10; } memset(uuid16_list, 0, sizeof(uuid16_list)); /* Group all UUID16 types */ list_for_each_entry(uuid, &hdev->uuids, list) { u16 uuid16; uuid16 = get_uuid16(uuid->uuid); if (uuid16 == 0) return; if (uuid16 < 0x1100) continue; if (uuid16 == PNP_INFO_SVCLASS_ID) continue; /* Stop if not enough space to put next UUID */ if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) { truncated = 1; break; } /* Check for duplicates */ for (i = 0; uuid16_list[i] != 0; i++) if (uuid16_list[i] == uuid16) break; if (uuid16_list[i] == 0) { uuid16_list[i] = uuid16; eir_len += sizeof(u16); } } if (uuid16_list[0] != 0) { u8 *length = ptr; /* EIR Data type */ ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; ptr += 2; eir_len += 2; for (i = 0; uuid16_list[i] != 0; i++) { *ptr++ = (uuid16_list[i] & 0x00ff); *ptr++ = (uuid16_list[i] & 0xff00) >> 8; } /* EIR Data length */ *length = (i * sizeof(u16)) + 1; } ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); ptr = create_uuid32_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); } static int update_eir(struct hci_dev *hdev) Loading Loading @@ -728,13 +760,9 @@ static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, void *data), void *data) { struct list_head *p, *n; list_for_each_safe(p, n, &hdev->mgmt_pending) { struct pending_cmd *cmd; cmd = list_entry(p, struct pending_cmd, list); struct pending_cmd *cmd, *tmp; list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { if (opcode > 0 && cmd->opcode != opcode) continue; Loading Loading @@ -1304,6 +1332,25 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) return err; } static const u8 bluetooth_base_uuid[] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static u8 get_uuid_size(const u8 *uuid) { u32 val; if (memcmp(uuid, bluetooth_base_uuid, 12)) return 128; val = get_unaligned_le32(&uuid[12]); if (val > 0xffff) return 32; return 16; } static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_add_uuid *cp = data; Loading @@ -1329,8 +1376,9 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) memcpy(uuid->uuid, cp->uuid, 16); uuid->svc_hint = cp->svc_hint; uuid->size = get_uuid_size(cp->uuid); list_add(&uuid->list, &hdev->uuids); list_add_tail(&uuid->list, &hdev->uuids); err = update_class(hdev); if (err < 0) Loading Loading @@ -1374,7 +1422,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, { struct mgmt_cp_remove_uuid *cp = data; struct pending_cmd *cmd; struct list_head *p, *n; struct bt_uuid *match, *tmp; u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int err, found; Loading Loading @@ -1402,9 +1450,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, found = 0; list_for_each_safe(p, n, &hdev->uuids) { struct bt_uuid *match = list_entry(p, struct bt_uuid, list); list_for_each_entry_safe(match, tmp, &hdev->uuids, list) { if (memcmp(match->uuid, cp->uuid, 16) != 0) continue; Loading Loading @@ -3023,6 +3069,8 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); if (powered) { u8 link_sec; if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && !lmp_host_ssp_capable(hdev)) { u8 ssp = 1; Loading @@ -3046,6 +3094,11 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) sizeof(cp), &cp); } link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags); if (link_sec != test_bit(HCI_AUTH, &hdev->flags)) hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(link_sec), &link_sec); if (lmp_bredr_capable(hdev)) { set_bredr_scan(hdev); update_class(hdev); Loading net/bluetooth/sco.c +10 −8 Original line number Diff line number Diff line Loading @@ -900,8 +900,6 @@ static void sco_conn_ready(struct sco_conn *conn) BT_DBG("conn %p", conn); sco_conn_lock(conn); if (sk) { sco_sock_clear_timer(sk); bh_lock_sock(sk); Loading @@ -909,9 +907,13 @@ static void sco_conn_ready(struct sco_conn *conn) sk->sk_state_change(sk); bh_unlock_sock(sk); } else { sco_conn_lock(conn); parent = sco_get_sock_listen(conn->src); if (!parent) goto done; if (!parent) { sco_conn_unlock(conn); return; } bh_lock_sock(parent); Loading @@ -919,7 +921,8 @@ static void sco_conn_ready(struct sco_conn *conn) BTPROTO_SCO, GFP_ATOMIC); if (!sk) { bh_unlock_sock(parent); goto done; sco_conn_unlock(conn); return; } sco_sock_init(sk, parent); Loading @@ -939,11 +942,10 @@ static void sco_conn_ready(struct sco_conn *conn) parent->sk_data_ready(parent, 1); bh_unlock_sock(parent); } done: sco_conn_unlock(conn); } } /* ----- SCO interface with lower layer (HCI) ----- */ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) Loading Loading
include/net/bluetooth/hci_core.h +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ struct bdaddr_list { struct bt_uuid { struct list_head list; u8 uuid[16]; u8 size; u8 svc_hint; }; Loading
net/bluetooth/hci_core.c +3 −7 Original line number Diff line number Diff line Loading @@ -1183,14 +1183,10 @@ static void hci_discov_off(struct work_struct *work) int hci_uuids_clear(struct hci_dev *hdev) { struct list_head *p, *n; list_for_each_safe(p, n, &hdev->uuids) { struct bt_uuid *uuid; struct bt_uuid *uuid, *tmp; uuid = list_entry(p, struct bt_uuid, list); list_del(p); list_for_each_entry_safe(uuid, tmp, &hdev->uuids, list) { list_del(&uuid->list); kfree(uuid); } Loading
net/bluetooth/hci_event.c +0 −4 Original line number Diff line number Diff line Loading @@ -3988,8 +3988,6 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) void *ptr = &skb->data[1]; s8 rssi; hci_dev_lock(hdev); while (num_reports--) { struct hci_ev_le_advertising_info *ev = ptr; Loading @@ -3999,8 +3997,6 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) ptr += sizeof(*ev) + ev->length + 1; } hci_dev_unlock(hdev); } static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) Loading
net/bluetooth/mgmt.c +136 −83 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ bool enable_hs; #define MGMT_VERSION 1 #define MGMT_REVISION 2 #define MGMT_REVISION 3 static const u16 mgmt_commands[] = { MGMT_OP_READ_INDEX_LIST, Loading Loading @@ -435,35 +435,117 @@ static u32 get_current_settings(struct hci_dev *hdev) #define PNP_INFO_SVCLASS_ID 0x1200 static u8 bluetooth_base_uuid[] = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static u8 *create_uuid16_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) { u8 *ptr = data, *uuids_start = NULL; struct bt_uuid *uuid; if (len < 4) return ptr; list_for_each_entry(uuid, &hdev->uuids, list) { u16 uuid16; if (uuid->size != 16) continue; uuid16 = get_unaligned_le16(&uuid->uuid[12]); if (uuid16 < 0x1100) continue; if (uuid16 == PNP_INFO_SVCLASS_ID) continue; if (!uuids_start) { uuids_start = ptr; uuids_start[0] = 1; uuids_start[1] = EIR_UUID16_ALL; ptr += 2; } /* Stop if not enough space to put next UUID */ if ((ptr - data) + sizeof(u16) > len) { uuids_start[1] = EIR_UUID16_SOME; break; } *ptr++ = (uuid16 & 0x00ff); *ptr++ = (uuid16 & 0xff00) >> 8; uuids_start[0] += sizeof(uuid16); } static u16 get_uuid16(u8 *uuid128) return ptr; } static u8 *create_uuid32_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) { u32 val; int i; u8 *ptr = data, *uuids_start = NULL; struct bt_uuid *uuid; for (i = 0; i < 12; i++) { if (bluetooth_base_uuid[i] != uuid128[i]) return 0; if (len < 6) return ptr; list_for_each_entry(uuid, &hdev->uuids, list) { if (uuid->size != 32) continue; if (!uuids_start) { uuids_start = ptr; uuids_start[0] = 1; uuids_start[1] = EIR_UUID32_ALL; ptr += 2; } val = get_unaligned_le32(&uuid128[12]); if (val > 0xffff) return 0; /* Stop if not enough space to put next UUID */ if ((ptr - data) + sizeof(u32) > len) { uuids_start[1] = EIR_UUID32_SOME; break; } memcpy(ptr, &uuid->uuid[12], sizeof(u32)); ptr += sizeof(u32); uuids_start[0] += sizeof(u32); } return ptr; } static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) { u8 *ptr = data, *uuids_start = NULL; struct bt_uuid *uuid; if (len < 18) return ptr; list_for_each_entry(uuid, &hdev->uuids, list) { if (uuid->size != 128) continue; if (!uuids_start) { uuids_start = ptr; uuids_start[0] = 1; uuids_start[1] = EIR_UUID128_ALL; ptr += 2; } return (u16) val; /* Stop if not enough space to put next UUID */ if ((ptr - data) + 16 > len) { uuids_start[1] = EIR_UUID128_SOME; break; } memcpy(ptr, uuid->uuid, 16); ptr += 16; uuids_start[0] += 16; } return ptr; } static void create_eir(struct hci_dev *hdev, u8 *data) { u8 *ptr = data; u16 eir_len = 0; u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; int i, truncated = 0; struct bt_uuid *uuid; size_t name_len; name_len = strlen(hdev->dev_name); Loading @@ -481,7 +563,6 @@ static void create_eir(struct hci_dev *hdev, u8 *data) memcpy(ptr + 2, hdev->dev_name, name_len); eir_len += (name_len + 2); ptr += (name_len + 2); } Loading @@ -490,7 +571,6 @@ static void create_eir(struct hci_dev *hdev, u8 *data) ptr[1] = EIR_TX_POWER; ptr[2] = (u8) hdev->inq_tx_power; eir_len += 3; ptr += 3; } Loading @@ -503,60 +583,12 @@ static void create_eir(struct hci_dev *hdev, u8 *data) put_unaligned_le16(hdev->devid_product, ptr + 6); put_unaligned_le16(hdev->devid_version, ptr + 8); eir_len += 10; ptr += 10; } memset(uuid16_list, 0, sizeof(uuid16_list)); /* Group all UUID16 types */ list_for_each_entry(uuid, &hdev->uuids, list) { u16 uuid16; uuid16 = get_uuid16(uuid->uuid); if (uuid16 == 0) return; if (uuid16 < 0x1100) continue; if (uuid16 == PNP_INFO_SVCLASS_ID) continue; /* Stop if not enough space to put next UUID */ if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) { truncated = 1; break; } /* Check for duplicates */ for (i = 0; uuid16_list[i] != 0; i++) if (uuid16_list[i] == uuid16) break; if (uuid16_list[i] == 0) { uuid16_list[i] = uuid16; eir_len += sizeof(u16); } } if (uuid16_list[0] != 0) { u8 *length = ptr; /* EIR Data type */ ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; ptr += 2; eir_len += 2; for (i = 0; uuid16_list[i] != 0; i++) { *ptr++ = (uuid16_list[i] & 0x00ff); *ptr++ = (uuid16_list[i] & 0xff00) >> 8; } /* EIR Data length */ *length = (i * sizeof(u16)) + 1; } ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); ptr = create_uuid32_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); } static int update_eir(struct hci_dev *hdev) Loading Loading @@ -728,13 +760,9 @@ static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, void *data), void *data) { struct list_head *p, *n; list_for_each_safe(p, n, &hdev->mgmt_pending) { struct pending_cmd *cmd; cmd = list_entry(p, struct pending_cmd, list); struct pending_cmd *cmd, *tmp; list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { if (opcode > 0 && cmd->opcode != opcode) continue; Loading Loading @@ -1304,6 +1332,25 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) return err; } static const u8 bluetooth_base_uuid[] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static u8 get_uuid_size(const u8 *uuid) { u32 val; if (memcmp(uuid, bluetooth_base_uuid, 12)) return 128; val = get_unaligned_le32(&uuid[12]); if (val > 0xffff) return 32; return 16; } static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { struct mgmt_cp_add_uuid *cp = data; Loading @@ -1329,8 +1376,9 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) memcpy(uuid->uuid, cp->uuid, 16); uuid->svc_hint = cp->svc_hint; uuid->size = get_uuid_size(cp->uuid); list_add(&uuid->list, &hdev->uuids); list_add_tail(&uuid->list, &hdev->uuids); err = update_class(hdev); if (err < 0) Loading Loading @@ -1374,7 +1422,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, { struct mgmt_cp_remove_uuid *cp = data; struct pending_cmd *cmd; struct list_head *p, *n; struct bt_uuid *match, *tmp; u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int err, found; Loading Loading @@ -1402,9 +1450,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, found = 0; list_for_each_safe(p, n, &hdev->uuids) { struct bt_uuid *match = list_entry(p, struct bt_uuid, list); list_for_each_entry_safe(match, tmp, &hdev->uuids, list) { if (memcmp(match->uuid, cp->uuid, 16) != 0) continue; Loading Loading @@ -3023,6 +3069,8 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); if (powered) { u8 link_sec; if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && !lmp_host_ssp_capable(hdev)) { u8 ssp = 1; Loading @@ -3046,6 +3094,11 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) sizeof(cp), &cp); } link_sec = test_bit(HCI_LINK_SECURITY, &hdev->dev_flags); if (link_sec != test_bit(HCI_AUTH, &hdev->flags)) hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(link_sec), &link_sec); if (lmp_bredr_capable(hdev)) { set_bredr_scan(hdev); update_class(hdev); Loading
net/bluetooth/sco.c +10 −8 Original line number Diff line number Diff line Loading @@ -900,8 +900,6 @@ static void sco_conn_ready(struct sco_conn *conn) BT_DBG("conn %p", conn); sco_conn_lock(conn); if (sk) { sco_sock_clear_timer(sk); bh_lock_sock(sk); Loading @@ -909,9 +907,13 @@ static void sco_conn_ready(struct sco_conn *conn) sk->sk_state_change(sk); bh_unlock_sock(sk); } else { sco_conn_lock(conn); parent = sco_get_sock_listen(conn->src); if (!parent) goto done; if (!parent) { sco_conn_unlock(conn); return; } bh_lock_sock(parent); Loading @@ -919,7 +921,8 @@ static void sco_conn_ready(struct sco_conn *conn) BTPROTO_SCO, GFP_ATOMIC); if (!sk) { bh_unlock_sock(parent); goto done; sco_conn_unlock(conn); return; } sco_sock_init(sk, parent); Loading @@ -939,11 +942,10 @@ static void sco_conn_ready(struct sco_conn *conn) parent->sk_data_ready(parent, 1); bh_unlock_sock(parent); } done: sco_conn_unlock(conn); } } /* ----- SCO interface with lower layer (HCI) ----- */ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) Loading