Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: hci_sync: Refactor remove Adv Monitor

Make use of hci_cmd_sync_queue for removing an advertisement monitor.

Signed-off-by: Manish Mandlik <mmandlik@google.com>
Reviewed-by: Miao-chen Chou <mcchou@google.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Manish Mandlik and committed by
Luiz Augusto von Dentz
7cf5c297 b747a836

+75 -178
+2 -4
include/net/bluetooth/hci_core.h
··· 1420 1420 1421 1421 void hci_adv_monitors_clear(struct hci_dev *hdev); 1422 1422 void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor); 1423 - int hci_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status); 1424 1423 int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor); 1425 - bool hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle, int *err); 1426 - bool hci_remove_all_adv_monitor(struct hci_dev *hdev, int *err); 1424 + int hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle); 1425 + int hci_remove_all_adv_monitor(struct hci_dev *hdev); 1427 1426 bool hci_is_adv_monitoring(struct hci_dev *hdev); 1428 1427 int hci_get_adv_monitor_offload_ext(struct hci_dev *hdev); 1429 1428 ··· 1882 1883 u8 instance); 1883 1884 void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle); 1884 1885 int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip); 1885 - int mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status); 1886 1886 void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle, 1887 1887 bdaddr_t *bdaddr, u8 addr_type); 1888 1888
+28 -53
net/bluetooth/hci_core.c
··· 1880 1880 kfree(monitor); 1881 1881 } 1882 1882 1883 - int hci_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status) 1884 - { 1885 - return mgmt_remove_adv_monitor_complete(hdev, status); 1886 - } 1887 - 1888 1883 /* Assigns handle to a monitor, and if offloading is supported and power is on, 1889 1884 * also attempts to forward the request to the controller. 1890 1885 * This function requires the caller holds hci_req_sync_lock. ··· 1928 1933 1929 1934 /* Attempts to tell the controller and free the monitor. If somehow the 1930 1935 * controller doesn't have a corresponding handle, remove anyway. 1931 - * Returns true if request is forwarded (result is pending), false otherwise. 1932 - * This function requires the caller holds hdev->lock. 1936 + * This function requires the caller holds hci_req_sync_lock. 1933 1937 */ 1934 - static bool hci_remove_adv_monitor(struct hci_dev *hdev, 1935 - struct adv_monitor *monitor, 1936 - u16 handle, int *err) 1938 + static int hci_remove_adv_monitor(struct hci_dev *hdev, 1939 + struct adv_monitor *monitor) 1937 1940 { 1938 - *err = 0; 1941 + int status = 0; 1939 1942 1940 1943 switch (hci_get_adv_monitor_offload_ext(hdev)) { 1941 1944 case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */ 1945 + bt_dev_dbg(hdev, "%s remove monitor %d status %d", hdev->name, 1946 + monitor->handle, status); 1942 1947 goto free_monitor; 1948 + 1943 1949 case HCI_ADV_MONITOR_EXT_MSFT: 1944 - *err = msft_remove_monitor(hdev, monitor, handle); 1950 + status = msft_remove_monitor(hdev, monitor); 1951 + bt_dev_dbg(hdev, "%s remove monitor %d msft status %d", 1952 + hdev->name, monitor->handle, status); 1945 1953 break; 1946 1954 } 1947 1955 1948 1956 /* In case no matching handle registered, just free the monitor */ 1949 - if (*err == -ENOENT) 1957 + if (status == -ENOENT) 1950 1958 goto free_monitor; 1951 1959 1952 - return (*err == 0); 1960 + return status; 1953 1961 1954 1962 free_monitor: 1955 - if (*err == -ENOENT) 1963 + if (status == -ENOENT) 1956 1964 bt_dev_warn(hdev, "Removing monitor with no matching handle %d", 1957 1965 monitor->handle); 1958 1966 hci_free_adv_monitor(hdev, monitor); 1959 1967 1960 - *err = 0; 1961 - return false; 1968 + return status; 1962 1969 } 1963 1970 1964 - /* Returns true if request is forwarded (result is pending), false otherwise. 1965 - * This function requires the caller holds hdev->lock. 1966 - */ 1967 - bool hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle, int *err) 1971 + /* This function requires the caller holds hci_req_sync_lock */ 1972 + int hci_remove_single_adv_monitor(struct hci_dev *hdev, u16 handle) 1968 1973 { 1969 1974 struct adv_monitor *monitor = idr_find(&hdev->adv_monitors_idr, handle); 1970 - bool pending; 1971 1975 1972 - if (!monitor) { 1973 - *err = -EINVAL; 1974 - return false; 1975 - } 1976 + if (!monitor) 1977 + return -EINVAL; 1976 1978 1977 - pending = hci_remove_adv_monitor(hdev, monitor, handle, err); 1978 - if (!*err && !pending) 1979 - hci_update_passive_scan(hdev); 1980 - 1981 - bt_dev_dbg(hdev, "%s remove monitor handle %d, status %d, %spending", 1982 - hdev->name, handle, *err, pending ? "" : "not "); 1983 - 1984 - return pending; 1979 + return hci_remove_adv_monitor(hdev, monitor); 1985 1980 } 1986 1981 1987 - /* Returns true if request is forwarded (result is pending), false otherwise. 1988 - * This function requires the caller holds hdev->lock. 1989 - */ 1990 - bool hci_remove_all_adv_monitor(struct hci_dev *hdev, int *err) 1982 + /* This function requires the caller holds hci_req_sync_lock */ 1983 + int hci_remove_all_adv_monitor(struct hci_dev *hdev) 1991 1984 { 1992 1985 struct adv_monitor *monitor; 1993 1986 int idr_next_id = 0; 1994 - bool pending = false; 1995 - bool update = false; 1987 + int status = 0; 1996 1988 1997 - *err = 0; 1998 - 1999 - while (!*err && !pending) { 1989 + while (1) { 2000 1990 monitor = idr_get_next(&hdev->adv_monitors_idr, &idr_next_id); 2001 1991 if (!monitor) 2002 1992 break; 2003 1993 2004 - pending = hci_remove_adv_monitor(hdev, monitor, 0, err); 1994 + status = hci_remove_adv_monitor(hdev, monitor); 1995 + if (status) 1996 + return status; 2005 1997 2006 - if (!*err && !pending) 2007 - update = true; 1998 + idr_next_id++; 2008 1999 } 2009 2000 2010 - if (update) 2011 - hci_update_passive_scan(hdev); 2012 - 2013 - bt_dev_dbg(hdev, "%s remove all monitors status %d, %spending", 2014 - hdev->name, *err, pending ? "" : "not "); 2015 - 2016 - return pending; 2001 + return status; 2017 2002 } 2018 2003 2019 2004 /* This function requires the caller holds hdev->lock */
+24 -38
net/bluetooth/mgmt.c
··· 4861 4861 MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI); 4862 4862 } 4863 4863 4864 - int mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status) 4864 + static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, 4865 + void *data, int status) 4865 4866 { 4866 4867 struct mgmt_rp_remove_adv_monitor rp; 4867 - struct mgmt_cp_remove_adv_monitor *cp; 4868 - struct mgmt_pending_cmd *cmd; 4869 - int err = 0; 4868 + struct mgmt_pending_cmd *cmd = data; 4869 + struct mgmt_cp_remove_adv_monitor *cp = cmd->param; 4870 4870 4871 4871 hci_dev_lock(hdev); 4872 4872 4873 - cmd = pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev); 4874 - if (!cmd) 4875 - goto done; 4876 - 4877 - cp = cmd->param; 4878 4873 rp.monitor_handle = cp->monitor_handle; 4879 4874 4880 4875 if (!status) 4881 4876 hci_update_passive_scan(hdev); 4882 4877 4883 - err = mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, 4884 - mgmt_status(status), &rp, sizeof(rp)); 4878 + mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, 4879 + mgmt_status(status), &rp, sizeof(rp)); 4885 4880 mgmt_pending_remove(cmd); 4886 4881 4887 - done: 4888 4882 hci_dev_unlock(hdev); 4889 - bt_dev_dbg(hdev, "remove monitor %d complete, status %u", 4883 + bt_dev_dbg(hdev, "remove monitor %d complete, status %d", 4890 4884 rp.monitor_handle, status); 4885 + } 4891 4886 4892 - return err; 4887 + static int mgmt_remove_adv_monitor_sync(struct hci_dev *hdev, void *data) 4888 + { 4889 + struct mgmt_pending_cmd *cmd = data; 4890 + struct mgmt_cp_remove_adv_monitor *cp = cmd->param; 4891 + u16 handle = __le16_to_cpu(cp->monitor_handle); 4892 + 4893 + if (!handle) 4894 + return hci_remove_all_adv_monitor(hdev); 4895 + 4896 + return hci_remove_single_adv_monitor(hdev, handle); 4893 4897 } 4894 4898 4895 4899 static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev, 4896 4900 void *data, u16 len) 4897 4901 { 4898 - struct mgmt_cp_remove_adv_monitor *cp = data; 4899 - struct mgmt_rp_remove_adv_monitor rp; 4900 4902 struct mgmt_pending_cmd *cmd; 4901 - u16 handle = __le16_to_cpu(cp->monitor_handle); 4902 4903 int err, status; 4903 - bool pending; 4904 - 4905 - BT_DBG("request for %s", hdev->name); 4906 - rp.monitor_handle = cp->monitor_handle; 4907 4904 4908 4905 hci_dev_lock(hdev); 4909 4906 ··· 4918 4921 goto unlock; 4919 4922 } 4920 4923 4921 - if (handle) 4922 - pending = hci_remove_single_adv_monitor(hdev, handle, &err); 4923 - else 4924 - pending = hci_remove_all_adv_monitor(hdev, &err); 4924 + err = hci_cmd_sync_queue(hdev, mgmt_remove_adv_monitor_sync, cmd, 4925 + mgmt_remove_adv_monitor_complete); 4925 4926 4926 4927 if (err) { 4927 4928 mgmt_pending_remove(cmd); 4928 4929 4929 - if (err == -ENOENT) 4930 - status = MGMT_STATUS_INVALID_INDEX; 4930 + if (err == -ENOMEM) 4931 + status = MGMT_STATUS_NO_RESOURCES; 4931 4932 else 4932 4933 status = MGMT_STATUS_FAILED; 4933 4934 4935 + mgmt_pending_remove(cmd); 4934 4936 goto unlock; 4935 4937 } 4936 4938 4937 - /* monitor can be removed without forwarding request to controller */ 4938 - if (!pending) { 4939 - mgmt_pending_remove(cmd); 4940 - hci_dev_unlock(hdev); 4941 - 4942 - return mgmt_cmd_complete(sk, hdev->id, 4943 - MGMT_OP_REMOVE_ADV_MONITOR, 4944 - MGMT_STATUS_SUCCESS, 4945 - &rp, sizeof(rp)); 4946 - } 4947 - 4948 4939 hci_dev_unlock(hdev); 4940 + 4949 4941 return 0; 4950 4942 4951 4943 unlock:
+19 -79
net/bluetooth/msft.c
··· 99 99 __u8 evt_prefix_len; 100 100 __u8 *evt_prefix; 101 101 struct list_head handle_map; 102 - __u16 pending_remove_handle; 103 102 __u8 resuming; 104 103 __u8 suspending; 105 104 __u8 filter_enabled; 106 105 }; 107 - 108 - static int __msft_remove_monitor(struct hci_dev *hdev, 109 - struct adv_monitor *monitor, u16 handle); 110 106 111 107 bool msft_monitor_supported(struct hci_dev *hdev) 112 108 { ··· 251 255 return status; 252 256 } 253 257 254 - static void msft_le_cancel_monitor_advertisement_cb(struct hci_dev *hdev, 255 - u8 status, u16 opcode, 256 - struct sk_buff *skb) 258 + static int msft_le_cancel_monitor_advertisement_cb(struct hci_dev *hdev, 259 + u16 opcode, 260 + struct adv_monitor *monitor, 261 + struct sk_buff *skb) 257 262 { 258 - struct msft_cp_le_cancel_monitor_advertisement *cp; 259 263 struct msft_rp_le_cancel_monitor_advertisement *rp; 260 - struct adv_monitor *monitor; 261 264 struct msft_monitor_advertisement_handle_data *handle_data; 262 265 struct msft_data *msft = hdev->msft_data; 263 - int err; 264 - bool pending; 265 - 266 - if (status) 267 - goto done; 266 + int status = 0; 268 267 269 268 rp = (struct msft_rp_le_cancel_monitor_advertisement *)skb->data; 270 269 if (skb->len < sizeof(*rp)) { ··· 267 276 goto done; 268 277 } 269 278 279 + status = rp->status; 280 + if (status) 281 + goto done; 282 + 270 283 hci_dev_lock(hdev); 271 284 272 - cp = hci_sent_cmd_data(hdev, hdev->msft_opcode); 273 - handle_data = msft_find_handle_data(hdev, cp->handle, false); 285 + handle_data = msft_find_handle_data(hdev, monitor->handle, true); 274 286 275 287 if (handle_data) { 276 - monitor = idr_find(&hdev->adv_monitors_idr, 277 - handle_data->mgmt_handle); 278 - 279 - if (monitor && monitor->state == ADV_MONITOR_STATE_OFFLOADED) 288 + if (monitor->state == ADV_MONITOR_STATE_OFFLOADED) 280 289 monitor->state = ADV_MONITOR_STATE_REGISTERED; 281 290 282 291 /* Do not free the monitor if it is being removed due to 283 292 * suspend. It will be re-monitored on resume. 284 293 */ 285 - if (monitor && !msft->suspending) { 294 + if (!msft->suspending) { 286 295 hci_free_adv_monitor(hdev, monitor); 287 296 288 297 /* Clear any monitored devices by this Adv Monitor */ ··· 294 303 kfree(handle_data); 295 304 } 296 305 297 - /* If remove all monitors is required, we need to continue the process 298 - * here because the earlier it was paused when waiting for the 299 - * response from controller. 300 - */ 301 - if (msft->pending_remove_handle == 0) { 302 - pending = hci_remove_all_adv_monitor(hdev, &err); 303 - if (pending) { 304 - hci_dev_unlock(hdev); 305 - return; 306 - } 307 - 308 - if (err) 309 - status = HCI_ERROR_UNSPECIFIED; 310 - } 311 - 312 306 hci_dev_unlock(hdev); 313 307 314 308 done: 315 - if (!msft->suspending) 316 - hci_remove_adv_monitor_complete(hdev, status); 309 + return status; 317 310 } 318 311 312 + /* This function requires the caller holds hci_req_sync_lock */ 319 313 static int msft_remove_monitor_sync(struct hci_dev *hdev, 320 314 struct adv_monitor *monitor) 321 315 { 322 316 struct msft_cp_le_cancel_monitor_advertisement cp; 323 317 struct msft_monitor_advertisement_handle_data *handle_data; 324 318 struct sk_buff *skb; 325 - u8 status; 326 319 327 320 handle_data = msft_find_handle_data(hdev, monitor->handle, true); 328 321 ··· 322 347 if (IS_ERR(skb)) 323 348 return PTR_ERR(skb); 324 349 325 - status = skb->data[0]; 326 - skb_pull(skb, 1); 327 - 328 - msft_le_cancel_monitor_advertisement_cb(hdev, status, hdev->msft_opcode, 329 - skb); 330 - 331 - return status; 350 + return msft_le_cancel_monitor_advertisement_cb(hdev, hdev->msft_opcode, 351 + monitor, skb); 332 352 } 333 353 334 354 /* This function requires the caller holds hci_req_sync_lock */ ··· 781 811 return msft_add_monitor_sync(hdev, monitor); 782 812 } 783 813 784 - /* This function requires the caller holds hdev->lock */ 785 - static int __msft_remove_monitor(struct hci_dev *hdev, 786 - struct adv_monitor *monitor, u16 handle) 787 - { 788 - struct msft_cp_le_cancel_monitor_advertisement cp; 789 - struct msft_monitor_advertisement_handle_data *handle_data; 790 - struct hci_request req; 791 - struct msft_data *msft = hdev->msft_data; 792 - int err = 0; 793 - 794 - handle_data = msft_find_handle_data(hdev, monitor->handle, true); 795 - 796 - /* If no matched handle, just remove without telling controller */ 797 - if (!handle_data) 798 - return -ENOENT; 799 - 800 - cp.sub_opcode = MSFT_OP_LE_CANCEL_MONITOR_ADVERTISEMENT; 801 - cp.handle = handle_data->msft_handle; 802 - 803 - hci_req_init(&req, hdev); 804 - hci_req_add(&req, hdev->msft_opcode, sizeof(cp), &cp); 805 - err = hci_req_run_skb(&req, msft_le_cancel_monitor_advertisement_cb); 806 - 807 - if (!err) 808 - msft->pending_remove_handle = handle; 809 - 810 - return err; 811 - } 812 - 813 - /* This function requires the caller holds hdev->lock */ 814 - int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor, 815 - u16 handle) 814 + /* This function requires the caller holds hci_req_sync_lock */ 815 + int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) 816 816 { 817 817 struct msft_data *msft = hdev->msft_data; 818 818 ··· 792 852 if (msft->resuming || msft->suspending) 793 853 return -EBUSY; 794 854 795 - return __msft_remove_monitor(hdev, monitor, handle); 855 + return msft_remove_monitor_sync(hdev, monitor); 796 856 } 797 857 798 858 void msft_req_add_set_filter_enable(struct hci_request *req, bool enable)
+2 -4
net/bluetooth/msft.h
··· 20 20 void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb); 21 21 __u64 msft_get_features(struct hci_dev *hdev); 22 22 int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor); 23 - int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor, 24 - u16 handle); 23 + int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor); 25 24 void msft_req_add_set_filter_enable(struct hci_request *req, bool enable); 26 25 int msft_set_filter_enable(struct hci_dev *hdev, bool enable); 27 26 int msft_suspend_sync(struct hci_dev *hdev); ··· 48 49 } 49 50 50 51 static inline int msft_remove_monitor(struct hci_dev *hdev, 51 - struct adv_monitor *monitor, 52 - u16 handle) 52 + struct adv_monitor *monitor) 53 53 { 54 54 return -EOPNOTSUPP; 55 55 }