diff options
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 4726876298f0..bf17a62a1bef 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -3082,6 +3082,24 @@ static void set_bredr_scan(struct hci_request *req) | |||
3082 | hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | 3082 | hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); |
3083 | } | 3083 | } |
3084 | 3084 | ||
3085 | static void powered_complete(struct hci_dev *hdev, u8 status) | ||
3086 | { | ||
3087 | struct cmd_lookup match = { NULL, hdev }; | ||
3088 | |||
3089 | BT_DBG("status 0x%02x", status); | ||
3090 | |||
3091 | hci_dev_lock(hdev); | ||
3092 | |||
3093 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); | ||
3094 | |||
3095 | new_settings(hdev, match.sk); | ||
3096 | |||
3097 | hci_dev_unlock(hdev); | ||
3098 | |||
3099 | if (match.sk) | ||
3100 | sock_put(match.sk); | ||
3101 | } | ||
3102 | |||
3085 | static int powered_update_hci(struct hci_dev *hdev) | 3103 | static int powered_update_hci(struct hci_dev *hdev) |
3086 | { | 3104 | { |
3087 | struct hci_request req; | 3105 | struct hci_request req; |
@@ -3123,32 +3141,36 @@ static int powered_update_hci(struct hci_dev *hdev) | |||
3123 | update_eir(&req); | 3141 | update_eir(&req); |
3124 | } | 3142 | } |
3125 | 3143 | ||
3126 | return hci_req_run(&req, NULL); | 3144 | return hci_req_run(&req, powered_complete); |
3127 | } | 3145 | } |
3128 | 3146 | ||
3129 | int mgmt_powered(struct hci_dev *hdev, u8 powered) | 3147 | int mgmt_powered(struct hci_dev *hdev, u8 powered) |
3130 | { | 3148 | { |
3131 | struct cmd_lookup match = { NULL, hdev }; | 3149 | struct cmd_lookup match = { NULL, hdev }; |
3150 | u8 status_not_powered = MGMT_STATUS_NOT_POWERED; | ||
3151 | u8 zero_cod[] = { 0, 0, 0 }; | ||
3132 | int err; | 3152 | int err; |
3133 | 3153 | ||
3134 | if (!test_bit(HCI_MGMT, &hdev->dev_flags)) | 3154 | if (!test_bit(HCI_MGMT, &hdev->dev_flags)) |
3135 | return 0; | 3155 | return 0; |
3136 | 3156 | ||
3137 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); | ||
3138 | |||
3139 | if (powered) { | 3157 | if (powered) { |
3140 | powered_update_hci(hdev); | 3158 | if (powered_update_hci(hdev) == 0) |
3141 | } else { | 3159 | return 0; |
3142 | u8 status = MGMT_STATUS_NOT_POWERED; | ||
3143 | u8 zero_cod[] = { 0, 0, 0 }; | ||
3144 | |||
3145 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); | ||
3146 | 3160 | ||
3147 | if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) | 3161 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, |
3148 | mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, | 3162 | &match); |
3149 | zero_cod, sizeof(zero_cod), NULL); | 3163 | goto new_settings; |
3150 | } | 3164 | } |
3151 | 3165 | ||
3166 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); | ||
3167 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status_not_powered); | ||
3168 | |||
3169 | if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) | ||
3170 | mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, | ||
3171 | zero_cod, sizeof(zero_cod), NULL); | ||
3172 | |||
3173 | new_settings: | ||
3152 | err = new_settings(hdev, match.sk); | 3174 | err = new_settings(hdev, match.sk); |
3153 | 3175 | ||
3154 | if (match.sk) | 3176 | if (match.sk) |