Loading drivers/bluetooth/btusb.c +1 −0 Original line number Diff line number Diff line Loading @@ -1619,6 +1619,7 @@ static struct usb_driver btusb_driver = { #ifdef CONFIG_PM .suspend = btusb_suspend, .resume = btusb_resume, .reset_resume = btusb_resume, #endif .id_table = btusb_table, .supports_autosuspend = 1, Loading include/net/bluetooth/hci.h +0 −1 Original line number Diff line number Diff line Loading @@ -107,7 +107,6 @@ enum { HCI_MGMT, HCI_PAIRABLE, HCI_SERVICE_CACHE, HCI_LINK_KEYS, HCI_DEBUG_KEYS, HCI_UNREGISTER, Loading include/net/bluetooth/hci_core.h +11 −18 Original line number Diff line number Diff line Loading @@ -117,13 +117,6 @@ struct oob_data { u8 randomizer[16]; }; struct le_scan_params { u8 type; u16 interval; u16 window; int timeout; }; #define HCI_MAX_SHORT_NAME_LENGTH 10 struct amp_assoc { Loading Loading @@ -283,9 +276,6 @@ struct hci_dev { struct delayed_work le_scan_disable; struct work_struct le_scan; struct le_scan_params le_scan_params; __s8 adv_tx_power; __u8 adv_data[HCI_MAX_AD_LENGTH]; __u8 adv_data_len; Loading Loading @@ -432,6 +422,7 @@ void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, struct inquiry_entry *ie); bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, bool name_known, bool *ssp); void hci_inquiry_cache_flush(struct hci_dev *hdev); /* ----- HCI Connections ----- */ enum { Loading Loading @@ -1114,6 +1105,16 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); BIT(BDADDR_LE_PUBLIC) | \ BIT(BDADDR_LE_RANDOM)) /* These LE scan and inquiry parameters were chosen according to LE General * Discovery Procedure specification. */ #define DISCOV_LE_SCAN_WIN 0x12 #define DISCOV_LE_SCAN_INT 0x12 #define DISCOV_LE_TIMEOUT msecs_to_jiffies(10240) #define DISCOV_INTERLEAVED_TIMEOUT msecs_to_jiffies(5120) #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04 #define DISCOV_BREDR_INQUIRY_LEN 0x08 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); int mgmt_index_added(struct hci_dev *hdev); int mgmt_index_removed(struct hci_dev *hdev); Loading Loading @@ -1169,10 +1170,7 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 ssp, u8 *eir, u16 eir_len); int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, s8 rssi, u8 *name, u8 name_len); int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status); int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status); int mgmt_discovering(struct hci_dev *hdev, u8 discovering); int mgmt_interleaved_discovery(struct hci_dev *hdev); int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); bool mgmt_valid_hdev(struct hci_dev *hdev); Loading Loading @@ -1212,11 +1210,6 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, u16 to_multiplier); void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], __u8 ltk[16]); int hci_do_inquiry(struct hci_dev *hdev, u8 length); int hci_cancel_inquiry(struct hci_dev *hdev); int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, int timeout); int hci_cancel_le_scan(struct hci_dev *hdev); u8 bdaddr_to_le(u8 bdaddr_type); Loading include/net/bluetooth/l2cap.h +1 −1 Original line number Diff line number Diff line Loading @@ -242,7 +242,7 @@ struct l2cap_conn_rsp { #define L2CAP_CID_SIGNALING 0x0001 #define L2CAP_CID_CONN_LESS 0x0002 #define L2CAP_CID_A2MP 0x0003 #define L2CAP_CID_LE_DATA 0x0004 #define L2CAP_CID_ATT 0x0004 #define L2CAP_CID_LE_SIGNALING 0x0005 #define L2CAP_CID_SMP 0x0006 #define L2CAP_CID_DYN_START 0x0040 Loading net/bluetooth/hci_core.c +60 −132 Original line number Diff line number Diff line Loading @@ -597,7 +597,15 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) struct hci_dev *hdev = req->hdev; u8 p; /* Only send HCI_Delete_Stored_Link_Key if it is supported */ /* Some Broadcom based Bluetooth controllers do not support the * Delete Stored Link Key command. They are clearly indicating its * absence in the bit mask of supported commands. * * Check the supported commands and only if the the command is marked * as supported send it. If not supported assume that the controller * does not have actual support for stored link keys which makes this * command redundant anyway. */ if (hdev->commands[6] & 0x80) { struct hci_cp_delete_stored_link_key cp; Loading Loading @@ -751,7 +759,7 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state) hdev->discovery.state = state; } static void inquiry_cache_flush(struct hci_dev *hdev) void hci_inquiry_cache_flush(struct hci_dev *hdev) { struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *p, *n; Loading Loading @@ -964,7 +972,7 @@ int hci_inquiry(void __user *arg) hci_dev_lock(hdev); if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { inquiry_cache_flush(hdev); hci_inquiry_cache_flush(hdev); do_inquiry = 1; } hci_dev_unlock(hdev); Loading Loading @@ -1201,8 +1209,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) { BT_DBG("%s %p", hdev->name, hdev); cancel_work_sync(&hdev->le_scan); cancel_delayed_work(&hdev->power_off); hci_req_cancel(hdev, ENODEV); Loading Loading @@ -1230,7 +1236,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) cancel_delayed_work_sync(&hdev->le_scan_disable); hci_dev_lock(hdev); inquiry_cache_flush(hdev); hci_inquiry_cache_flush(hdev); hci_conn_hash_flush(hdev); hci_dev_unlock(hdev); Loading Loading @@ -1331,7 +1337,7 @@ int hci_dev_reset(__u16 dev) skb_queue_purge(&hdev->cmd_q); hci_dev_lock(hdev); inquiry_cache_flush(hdev); hci_inquiry_cache_flush(hdev); hci_conn_hash_flush(hdev); hci_dev_unlock(hdev); Loading Loading @@ -1991,80 +1997,59 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) return mgmt_device_unblocked(hdev, bdaddr, type); } static void le_scan_param_req(struct hci_request *req, unsigned long opt) static void inquiry_complete(struct hci_dev *hdev, u8 status) { struct le_scan_params *param = (struct le_scan_params *) opt; struct hci_cp_le_set_scan_param cp; memset(&cp, 0, sizeof(cp)); cp.type = param->type; cp.interval = cpu_to_le16(param->interval); cp.window = cpu_to_le16(param->window); if (status) { BT_ERR("Failed to start inquiry: status %d", status); hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); hci_dev_lock(hdev); hci_discovery_set_state(hdev, DISCOVERY_STOPPED); hci_dev_unlock(hdev); return; } static void le_scan_enable_req(struct hci_request *req, unsigned long opt) { struct hci_cp_le_set_scan_enable cp; memset(&cp, 0, sizeof(cp)); cp.enable = LE_SCAN_ENABLE; cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); } static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, int timeout) static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) { long timeo = msecs_to_jiffies(3000); struct le_scan_params param; /* General inquiry access code (GIAC) */ u8 lap[3] = { 0x33, 0x8b, 0x9e }; struct hci_request req; struct hci_cp_inquiry cp; int err; BT_DBG("%s", hdev->name); if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) return -EINPROGRESS; param.type = type; param.interval = interval; param.window = window; if (status) { BT_ERR("Failed to disable LE scanning: status %d", status); return; } hci_req_lock(hdev); switch (hdev->discovery.type) { case DISCOV_TYPE_LE: hci_dev_lock(hdev); hci_discovery_set_state(hdev, DISCOVERY_STOPPED); hci_dev_unlock(hdev); break; err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) ¶m, timeo); if (!err) err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo); case DISCOV_TYPE_INTERLEAVED: hci_req_init(&req, hdev); hci_req_unlock(hdev); memset(&cp, 0, sizeof(cp)); memcpy(&cp.lap, lap, sizeof(cp.lap)); cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); if (err < 0) return err; hci_dev_lock(hdev); queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, timeout); hci_inquiry_cache_flush(hdev); return 0; err = hci_req_run(&req, inquiry_complete); if (err) { BT_ERR("Inquiry request failed: err %d", err); hci_discovery_set_state(hdev, DISCOVERY_STOPPED); } int hci_cancel_le_scan(struct hci_dev *hdev) { BT_DBG("%s", hdev->name); if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) return -EALREADY; if (cancel_delayed_work(&hdev->le_scan_disable)) { struct hci_cp_le_set_scan_enable cp; /* Send HCI command to disable LE Scan */ memset(&cp, 0, sizeof(cp)); hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); hci_dev_unlock(hdev); break; } return 0; } static void le_scan_disable_work(struct work_struct *work) Loading @@ -2072,46 +2057,20 @@ static void le_scan_disable_work(struct work_struct *work) struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan_disable.work); struct hci_cp_le_set_scan_enable cp; struct hci_request req; int err; BT_DBG("%s", hdev->name); memset(&cp, 0, sizeof(cp)); hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); } static void le_scan_work(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); struct le_scan_params *param = &hdev->le_scan_params; BT_DBG("%s", hdev->name); hci_do_le_scan(hdev, param->type, param->interval, param->window, param->timeout); } int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, int timeout) { struct le_scan_params *param = &hdev->le_scan_params; BT_DBG("%s", hdev->name); if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) return -ENOTSUPP; if (work_busy(&hdev->le_scan)) return -EINPROGRESS; param->type = type; param->interval = interval; param->window = window; param->timeout = timeout; hci_req_init(&req, hdev); queue_work(system_long_wq, &hdev->le_scan); memset(&cp, 0, sizeof(cp)); cp.enable = LE_SCAN_DISABLE; hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); return 0; err = hci_req_run(&req, le_scan_disable_work_complete); if (err) BT_ERR("Disable LE scanning request failed: err %d", err); } /* Alloc HCI device */ Loading Loading @@ -2148,7 +2107,6 @@ struct hci_dev *hci_alloc_dev(void) INIT_WORK(&hdev->cmd_work, hci_cmd_work); INIT_WORK(&hdev->tx_work, hci_tx_work); INIT_WORK(&hdev->power_on, hci_power_on); INIT_WORK(&hdev->le_scan, le_scan_work); INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); Loading Loading @@ -3551,36 +3509,6 @@ static void hci_cmd_work(struct work_struct *work) } } int hci_do_inquiry(struct hci_dev *hdev, u8 length) { /* General inquiry access code (GIAC) */ u8 lap[3] = { 0x33, 0x8b, 0x9e }; struct hci_cp_inquiry cp; BT_DBG("%s", hdev->name); if (test_bit(HCI_INQUIRY, &hdev->flags)) return -EINPROGRESS; inquiry_cache_flush(hdev); memset(&cp, 0, sizeof(cp)); memcpy(&cp.lap, lap, sizeof(cp.lap)); cp.length = length; return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); } int hci_cancel_inquiry(struct hci_dev *hdev) { BT_DBG("%s", hdev->name); if (!test_bit(HCI_INQUIRY, &hdev->flags)) return -EALREADY; return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); } u8 bdaddr_to_le(u8 bdaddr_type) { switch (bdaddr_type) { Loading Loading
drivers/bluetooth/btusb.c +1 −0 Original line number Diff line number Diff line Loading @@ -1619,6 +1619,7 @@ static struct usb_driver btusb_driver = { #ifdef CONFIG_PM .suspend = btusb_suspend, .resume = btusb_resume, .reset_resume = btusb_resume, #endif .id_table = btusb_table, .supports_autosuspend = 1, Loading
include/net/bluetooth/hci.h +0 −1 Original line number Diff line number Diff line Loading @@ -107,7 +107,6 @@ enum { HCI_MGMT, HCI_PAIRABLE, HCI_SERVICE_CACHE, HCI_LINK_KEYS, HCI_DEBUG_KEYS, HCI_UNREGISTER, Loading
include/net/bluetooth/hci_core.h +11 −18 Original line number Diff line number Diff line Loading @@ -117,13 +117,6 @@ struct oob_data { u8 randomizer[16]; }; struct le_scan_params { u8 type; u16 interval; u16 window; int timeout; }; #define HCI_MAX_SHORT_NAME_LENGTH 10 struct amp_assoc { Loading Loading @@ -283,9 +276,6 @@ struct hci_dev { struct delayed_work le_scan_disable; struct work_struct le_scan; struct le_scan_params le_scan_params; __s8 adv_tx_power; __u8 adv_data[HCI_MAX_AD_LENGTH]; __u8 adv_data_len; Loading Loading @@ -432,6 +422,7 @@ void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, struct inquiry_entry *ie); bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, bool name_known, bool *ssp); void hci_inquiry_cache_flush(struct hci_dev *hdev); /* ----- HCI Connections ----- */ enum { Loading Loading @@ -1114,6 +1105,16 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); BIT(BDADDR_LE_PUBLIC) | \ BIT(BDADDR_LE_RANDOM)) /* These LE scan and inquiry parameters were chosen according to LE General * Discovery Procedure specification. */ #define DISCOV_LE_SCAN_WIN 0x12 #define DISCOV_LE_SCAN_INT 0x12 #define DISCOV_LE_TIMEOUT msecs_to_jiffies(10240) #define DISCOV_INTERLEAVED_TIMEOUT msecs_to_jiffies(5120) #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04 #define DISCOV_BREDR_INQUIRY_LEN 0x08 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); int mgmt_index_added(struct hci_dev *hdev); int mgmt_index_removed(struct hci_dev *hdev); Loading Loading @@ -1169,10 +1170,7 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 ssp, u8 *eir, u16 eir_len); int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, s8 rssi, u8 *name, u8 name_len); int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status); int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status); int mgmt_discovering(struct hci_dev *hdev, u8 discovering); int mgmt_interleaved_discovery(struct hci_dev *hdev); int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); bool mgmt_valid_hdev(struct hci_dev *hdev); Loading Loading @@ -1212,11 +1210,6 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, u16 to_multiplier); void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], __u8 ltk[16]); int hci_do_inquiry(struct hci_dev *hdev, u8 length); int hci_cancel_inquiry(struct hci_dev *hdev); int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, int timeout); int hci_cancel_le_scan(struct hci_dev *hdev); u8 bdaddr_to_le(u8 bdaddr_type); Loading
include/net/bluetooth/l2cap.h +1 −1 Original line number Diff line number Diff line Loading @@ -242,7 +242,7 @@ struct l2cap_conn_rsp { #define L2CAP_CID_SIGNALING 0x0001 #define L2CAP_CID_CONN_LESS 0x0002 #define L2CAP_CID_A2MP 0x0003 #define L2CAP_CID_LE_DATA 0x0004 #define L2CAP_CID_ATT 0x0004 #define L2CAP_CID_LE_SIGNALING 0x0005 #define L2CAP_CID_SMP 0x0006 #define L2CAP_CID_DYN_START 0x0040 Loading
net/bluetooth/hci_core.c +60 −132 Original line number Diff line number Diff line Loading @@ -597,7 +597,15 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) struct hci_dev *hdev = req->hdev; u8 p; /* Only send HCI_Delete_Stored_Link_Key if it is supported */ /* Some Broadcom based Bluetooth controllers do not support the * Delete Stored Link Key command. They are clearly indicating its * absence in the bit mask of supported commands. * * Check the supported commands and only if the the command is marked * as supported send it. If not supported assume that the controller * does not have actual support for stored link keys which makes this * command redundant anyway. */ if (hdev->commands[6] & 0x80) { struct hci_cp_delete_stored_link_key cp; Loading Loading @@ -751,7 +759,7 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state) hdev->discovery.state = state; } static void inquiry_cache_flush(struct hci_dev *hdev) void hci_inquiry_cache_flush(struct hci_dev *hdev) { struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *p, *n; Loading Loading @@ -964,7 +972,7 @@ int hci_inquiry(void __user *arg) hci_dev_lock(hdev); if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { inquiry_cache_flush(hdev); hci_inquiry_cache_flush(hdev); do_inquiry = 1; } hci_dev_unlock(hdev); Loading Loading @@ -1201,8 +1209,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) { BT_DBG("%s %p", hdev->name, hdev); cancel_work_sync(&hdev->le_scan); cancel_delayed_work(&hdev->power_off); hci_req_cancel(hdev, ENODEV); Loading Loading @@ -1230,7 +1236,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) cancel_delayed_work_sync(&hdev->le_scan_disable); hci_dev_lock(hdev); inquiry_cache_flush(hdev); hci_inquiry_cache_flush(hdev); hci_conn_hash_flush(hdev); hci_dev_unlock(hdev); Loading Loading @@ -1331,7 +1337,7 @@ int hci_dev_reset(__u16 dev) skb_queue_purge(&hdev->cmd_q); hci_dev_lock(hdev); inquiry_cache_flush(hdev); hci_inquiry_cache_flush(hdev); hci_conn_hash_flush(hdev); hci_dev_unlock(hdev); Loading Loading @@ -1991,80 +1997,59 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) return mgmt_device_unblocked(hdev, bdaddr, type); } static void le_scan_param_req(struct hci_request *req, unsigned long opt) static void inquiry_complete(struct hci_dev *hdev, u8 status) { struct le_scan_params *param = (struct le_scan_params *) opt; struct hci_cp_le_set_scan_param cp; memset(&cp, 0, sizeof(cp)); cp.type = param->type; cp.interval = cpu_to_le16(param->interval); cp.window = cpu_to_le16(param->window); if (status) { BT_ERR("Failed to start inquiry: status %d", status); hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); hci_dev_lock(hdev); hci_discovery_set_state(hdev, DISCOVERY_STOPPED); hci_dev_unlock(hdev); return; } static void le_scan_enable_req(struct hci_request *req, unsigned long opt) { struct hci_cp_le_set_scan_enable cp; memset(&cp, 0, sizeof(cp)); cp.enable = LE_SCAN_ENABLE; cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); } static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, int timeout) static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) { long timeo = msecs_to_jiffies(3000); struct le_scan_params param; /* General inquiry access code (GIAC) */ u8 lap[3] = { 0x33, 0x8b, 0x9e }; struct hci_request req; struct hci_cp_inquiry cp; int err; BT_DBG("%s", hdev->name); if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) return -EINPROGRESS; param.type = type; param.interval = interval; param.window = window; if (status) { BT_ERR("Failed to disable LE scanning: status %d", status); return; } hci_req_lock(hdev); switch (hdev->discovery.type) { case DISCOV_TYPE_LE: hci_dev_lock(hdev); hci_discovery_set_state(hdev, DISCOVERY_STOPPED); hci_dev_unlock(hdev); break; err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) ¶m, timeo); if (!err) err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo); case DISCOV_TYPE_INTERLEAVED: hci_req_init(&req, hdev); hci_req_unlock(hdev); memset(&cp, 0, sizeof(cp)); memcpy(&cp.lap, lap, sizeof(cp.lap)); cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); if (err < 0) return err; hci_dev_lock(hdev); queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, timeout); hci_inquiry_cache_flush(hdev); return 0; err = hci_req_run(&req, inquiry_complete); if (err) { BT_ERR("Inquiry request failed: err %d", err); hci_discovery_set_state(hdev, DISCOVERY_STOPPED); } int hci_cancel_le_scan(struct hci_dev *hdev) { BT_DBG("%s", hdev->name); if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) return -EALREADY; if (cancel_delayed_work(&hdev->le_scan_disable)) { struct hci_cp_le_set_scan_enable cp; /* Send HCI command to disable LE Scan */ memset(&cp, 0, sizeof(cp)); hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); hci_dev_unlock(hdev); break; } return 0; } static void le_scan_disable_work(struct work_struct *work) Loading @@ -2072,46 +2057,20 @@ static void le_scan_disable_work(struct work_struct *work) struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan_disable.work); struct hci_cp_le_set_scan_enable cp; struct hci_request req; int err; BT_DBG("%s", hdev->name); memset(&cp, 0, sizeof(cp)); hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); } static void le_scan_work(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); struct le_scan_params *param = &hdev->le_scan_params; BT_DBG("%s", hdev->name); hci_do_le_scan(hdev, param->type, param->interval, param->window, param->timeout); } int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, int timeout) { struct le_scan_params *param = &hdev->le_scan_params; BT_DBG("%s", hdev->name); if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) return -ENOTSUPP; if (work_busy(&hdev->le_scan)) return -EINPROGRESS; param->type = type; param->interval = interval; param->window = window; param->timeout = timeout; hci_req_init(&req, hdev); queue_work(system_long_wq, &hdev->le_scan); memset(&cp, 0, sizeof(cp)); cp.enable = LE_SCAN_DISABLE; hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); return 0; err = hci_req_run(&req, le_scan_disable_work_complete); if (err) BT_ERR("Disable LE scanning request failed: err %d", err); } /* Alloc HCI device */ Loading Loading @@ -2148,7 +2107,6 @@ struct hci_dev *hci_alloc_dev(void) INIT_WORK(&hdev->cmd_work, hci_cmd_work); INIT_WORK(&hdev->tx_work, hci_tx_work); INIT_WORK(&hdev->power_on, hci_power_on); INIT_WORK(&hdev->le_scan, le_scan_work); INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); Loading Loading @@ -3551,36 +3509,6 @@ static void hci_cmd_work(struct work_struct *work) } } int hci_do_inquiry(struct hci_dev *hdev, u8 length) { /* General inquiry access code (GIAC) */ u8 lap[3] = { 0x33, 0x8b, 0x9e }; struct hci_cp_inquiry cp; BT_DBG("%s", hdev->name); if (test_bit(HCI_INQUIRY, &hdev->flags)) return -EINPROGRESS; inquiry_cache_flush(hdev); memset(&cp, 0, sizeof(cp)); memcpy(&cp.lap, lap, sizeof(cp.lap)); cp.length = length; return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); } int hci_cancel_inquiry(struct hci_dev *hdev) { BT_DBG("%s", hdev->name); if (!test_bit(HCI_INQUIRY, &hdev->flags)) return -EALREADY; return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); } u8 bdaddr_to_le(u8 bdaddr_type) { switch (bdaddr_type) { Loading