diff options
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 79 |
1 files changed, 39 insertions, 40 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 2ca7b4427e34..be198f382ed8 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -43,8 +43,6 @@ struct pending_cmd { | |||
43 | void *user_data; | 43 | void *user_data; |
44 | }; | 44 | }; |
45 | 45 | ||
46 | static LIST_HEAD(cmd_list); | ||
47 | |||
48 | static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | 46 | static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) |
49 | { | 47 | { |
50 | struct sk_buff *skb; | 48 | struct sk_buff *skb; |
@@ -227,7 +225,8 @@ static void mgmt_pending_free(struct pending_cmd *cmd) | |||
227 | } | 225 | } |
228 | 226 | ||
229 | static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | 227 | static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, |
230 | u16 index, void *data, u16 len) | 228 | struct hci_dev *hdev, |
229 | void *data, u16 len) | ||
231 | { | 230 | { |
232 | struct pending_cmd *cmd; | 231 | struct pending_cmd *cmd; |
233 | 232 | ||
@@ -236,7 +235,7 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | |||
236 | return NULL; | 235 | return NULL; |
237 | 236 | ||
238 | cmd->opcode = opcode; | 237 | cmd->opcode = opcode; |
239 | cmd->index = index; | 238 | cmd->index = hdev->id; |
240 | 239 | ||
241 | cmd->param = kmalloc(len, GFP_ATOMIC); | 240 | cmd->param = kmalloc(len, GFP_ATOMIC); |
242 | if (!cmd->param) { | 241 | if (!cmd->param) { |
@@ -250,7 +249,7 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | |||
250 | cmd->sk = sk; | 249 | cmd->sk = sk; |
251 | sock_hold(sk); | 250 | sock_hold(sk); |
252 | 251 | ||
253 | list_add(&cmd->list, &cmd_list); | 252 | list_add(&cmd->list, &hdev->mgmt_pending); |
254 | 253 | ||
255 | return cmd; | 254 | return cmd; |
256 | } | 255 | } |
@@ -261,7 +260,7 @@ static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, | |||
261 | { | 260 | { |
262 | struct list_head *p, *n; | 261 | struct list_head *p, *n; |
263 | 262 | ||
264 | list_for_each_safe(p, n, &cmd_list) { | 263 | list_for_each_safe(p, n, &hdev->mgmt_pending) { |
265 | struct pending_cmd *cmd; | 264 | struct pending_cmd *cmd; |
266 | 265 | ||
267 | cmd = list_entry(p, struct pending_cmd, list); | 266 | cmd = list_entry(p, struct pending_cmd, list); |
@@ -276,15 +275,15 @@ static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, | |||
276 | } | 275 | } |
277 | } | 276 | } |
278 | 277 | ||
279 | static struct pending_cmd *mgmt_pending_find(u16 opcode, int index) | 278 | static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev) |
280 | { | 279 | { |
281 | struct pending_cmd *cmd; | 280 | struct pending_cmd *cmd; |
282 | 281 | ||
283 | list_for_each_entry(cmd, &cmd_list, list) { | 282 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { |
284 | if (cmd->opcode != opcode) | 283 | if (cmd->opcode != opcode) |
285 | continue; | 284 | continue; |
286 | 285 | ||
287 | if (index >= 0 && cmd->index != index) | 286 | if (hdev && cmd->index != hdev->id) |
288 | continue; | 287 | continue; |
289 | 288 | ||
290 | return cmd; | 289 | return cmd; |
@@ -325,12 +324,12 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
325 | goto failed; | 324 | goto failed; |
326 | } | 325 | } |
327 | 326 | ||
328 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, index)) { | 327 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) { |
329 | err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY); | 328 | err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY); |
330 | goto failed; | 329 | goto failed; |
331 | } | 330 | } |
332 | 331 | ||
333 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, index, data, len); | 332 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, data, len); |
334 | if (!cmd) { | 333 | if (!cmd) { |
335 | err = -ENOMEM; | 334 | err = -ENOMEM; |
336 | goto failed; | 335 | goto failed; |
@@ -376,8 +375,8 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
376 | goto failed; | 375 | goto failed; |
377 | } | 376 | } |
378 | 377 | ||
379 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) || | 378 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
380 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) { | 379 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
381 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EBUSY); | 380 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EBUSY); |
382 | goto failed; | 381 | goto failed; |
383 | } | 382 | } |
@@ -388,7 +387,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
388 | goto failed; | 387 | goto failed; |
389 | } | 388 | } |
390 | 389 | ||
391 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, index, data, len); | 390 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len); |
392 | if (!cmd) { | 391 | if (!cmd) { |
393 | err = -ENOMEM; | 392 | err = -ENOMEM; |
394 | goto failed; | 393 | goto failed; |
@@ -442,8 +441,8 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
442 | goto failed; | 441 | goto failed; |
443 | } | 442 | } |
444 | 443 | ||
445 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) || | 444 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
446 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) { | 445 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
447 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY); | 446 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY); |
448 | goto failed; | 447 | goto failed; |
449 | } | 448 | } |
@@ -453,7 +452,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
453 | goto failed; | 452 | goto failed; |
454 | } | 453 | } |
455 | 454 | ||
456 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, index, data, len); | 455 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len); |
457 | if (!cmd) { | 456 | if (!cmd) { |
458 | err = -ENOMEM; | 457 | err = -ENOMEM; |
459 | goto failed; | 458 | goto failed; |
@@ -1038,7 +1037,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1038 | goto failed; | 1037 | goto failed; |
1039 | } | 1038 | } |
1040 | 1039 | ||
1041 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, index)) { | 1040 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { |
1042 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY); | 1041 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY); |
1043 | goto failed; | 1042 | goto failed; |
1044 | } | 1043 | } |
@@ -1052,7 +1051,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1052 | goto failed; | 1051 | goto failed; |
1053 | } | 1052 | } |
1054 | 1053 | ||
1055 | cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, index, data, len); | 1054 | cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, data, len); |
1056 | if (!cmd) { | 1055 | if (!cmd) { |
1057 | err = -ENOMEM; | 1056 | err = -ENOMEM; |
1058 | goto failed; | 1057 | goto failed; |
@@ -1143,7 +1142,7 @@ static int send_pin_code_neg_reply(struct sock *sk, u16 index, | |||
1143 | struct pending_cmd *cmd; | 1142 | struct pending_cmd *cmd; |
1144 | int err; | 1143 | int err; |
1145 | 1144 | ||
1146 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index, cp, | 1145 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, hdev, cp, |
1147 | sizeof(*cp)); | 1146 | sizeof(*cp)); |
1148 | if (!cmd) | 1147 | if (!cmd) |
1149 | return -ENOMEM; | 1148 | return -ENOMEM; |
@@ -1204,7 +1203,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1204 | goto failed; | 1203 | goto failed; |
1205 | } | 1204 | } |
1206 | 1205 | ||
1207 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len); | 1206 | cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, data, len); |
1208 | if (!cmd) { | 1207 | if (!cmd) { |
1209 | err = -ENOMEM; | 1208 | err = -ENOMEM; |
1210 | goto failed; | 1209 | goto failed; |
@@ -1297,7 +1296,7 @@ static inline struct pending_cmd *find_pairing(struct hci_conn *conn) | |||
1297 | struct hci_dev *hdev = conn->hdev; | 1296 | struct hci_dev *hdev = conn->hdev; |
1298 | struct pending_cmd *cmd; | 1297 | struct pending_cmd *cmd; |
1299 | 1298 | ||
1300 | list_for_each_entry(cmd, &cmd_list, list) { | 1299 | list_for_each_entry(cmd, &hdev->mgmt_pending, list) { |
1301 | if (cmd->opcode != MGMT_OP_PAIR_DEVICE) | 1300 | if (cmd->opcode != MGMT_OP_PAIR_DEVICE) |
1302 | continue; | 1301 | continue; |
1303 | 1302 | ||
@@ -1396,7 +1395,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1396 | goto unlock; | 1395 | goto unlock; |
1397 | } | 1396 | } |
1398 | 1397 | ||
1399 | cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, index, data, len); | 1398 | cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len); |
1400 | if (!cmd) { | 1399 | if (!cmd) { |
1401 | err = -ENOMEM; | 1400 | err = -ENOMEM; |
1402 | hci_conn_put(conn); | 1401 | hci_conn_put(conn); |
@@ -1458,7 +1457,7 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1458 | goto failed; | 1457 | goto failed; |
1459 | } | 1458 | } |
1460 | 1459 | ||
1461 | cmd = mgmt_pending_add(sk, mgmt_op, index, data, len); | 1460 | cmd = mgmt_pending_add(sk, mgmt_op, hdev, data, len); |
1462 | if (!cmd) { | 1461 | if (!cmd) { |
1463 | err = -ENOMEM; | 1462 | err = -ENOMEM; |
1464 | goto failed; | 1463 | goto failed; |
@@ -1495,7 +1494,7 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, | |||
1495 | 1494 | ||
1496 | hci_dev_lock_bh(hdev); | 1495 | hci_dev_lock_bh(hdev); |
1497 | 1496 | ||
1498 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len); | 1497 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len); |
1499 | if (!cmd) { | 1498 | if (!cmd) { |
1500 | err = -ENOMEM; | 1499 | err = -ENOMEM; |
1501 | goto failed; | 1500 | goto failed; |
@@ -1541,12 +1540,12 @@ static int read_local_oob_data(struct sock *sk, u16 index) | |||
1541 | goto unlock; | 1540 | goto unlock; |
1542 | } | 1541 | } |
1543 | 1542 | ||
1544 | if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index)) { | 1543 | if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) { |
1545 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY); | 1544 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY); |
1546 | goto unlock; | 1545 | goto unlock; |
1547 | } | 1546 | } |
1548 | 1547 | ||
1549 | cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, index, NULL, 0); | 1548 | cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0); |
1550 | if (!cmd) { | 1549 | if (!cmd) { |
1551 | err = -ENOMEM; | 1550 | err = -ENOMEM; |
1552 | goto unlock; | 1551 | goto unlock; |
@@ -1650,7 +1649,7 @@ static int start_discovery(struct sock *sk, u16 index) | |||
1650 | goto failed; | 1649 | goto failed; |
1651 | } | 1650 | } |
1652 | 1651 | ||
1653 | cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0); | 1652 | cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0); |
1654 | if (!cmd) { | 1653 | if (!cmd) { |
1655 | err = -ENOMEM; | 1654 | err = -ENOMEM; |
1656 | goto failed; | 1655 | goto failed; |
@@ -1681,7 +1680,7 @@ static int stop_discovery(struct sock *sk, u16 index) | |||
1681 | 1680 | ||
1682 | hci_dev_lock_bh(hdev); | 1681 | hci_dev_lock_bh(hdev); |
1683 | 1682 | ||
1684 | cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, index, NULL, 0); | 1683 | cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0); |
1685 | if (!cmd) { | 1684 | if (!cmd) { |
1686 | err = -ENOMEM; | 1685 | err = -ENOMEM; |
1687 | goto failed; | 1686 | goto failed; |
@@ -2147,7 +2146,7 @@ int mgmt_disconnect_failed(struct hci_dev *hdev) | |||
2147 | struct pending_cmd *cmd; | 2146 | struct pending_cmd *cmd; |
2148 | int err; | 2147 | int err; |
2149 | 2148 | ||
2150 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev->id); | 2149 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev); |
2151 | if (!cmd) | 2150 | if (!cmd) |
2152 | return -ENOENT; | 2151 | return -ENOENT; |
2153 | 2152 | ||
@@ -2188,7 +2187,7 @@ int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
2188 | struct mgmt_rp_pin_code_reply rp; | 2187 | struct mgmt_rp_pin_code_reply rp; |
2189 | int err; | 2188 | int err; |
2190 | 2189 | ||
2191 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev->id); | 2190 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev); |
2192 | if (!cmd) | 2191 | if (!cmd) |
2193 | return -ENOENT; | 2192 | return -ENOENT; |
2194 | 2193 | ||
@@ -2210,7 +2209,7 @@ int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
2210 | struct mgmt_rp_pin_code_reply rp; | 2209 | struct mgmt_rp_pin_code_reply rp; |
2211 | int err; | 2210 | int err; |
2212 | 2211 | ||
2213 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev->id); | 2212 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev); |
2214 | if (!cmd) | 2213 | if (!cmd) |
2215 | return -ENOENT; | 2214 | return -ENOENT; |
2216 | 2215 | ||
@@ -2247,7 +2246,7 @@ static int confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
2247 | struct mgmt_rp_user_confirm_reply rp; | 2246 | struct mgmt_rp_user_confirm_reply rp; |
2248 | int err; | 2247 | int err; |
2249 | 2248 | ||
2250 | cmd = mgmt_pending_find(opcode, hdev->id); | 2249 | cmd = mgmt_pending_find(opcode, hdev); |
2251 | if (!cmd) | 2250 | if (!cmd) |
2252 | return -ENOENT; | 2251 | return -ENOENT; |
2253 | 2252 | ||
@@ -2293,7 +2292,7 @@ int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) | |||
2293 | memset(&ev, 0, sizeof(ev)); | 2292 | memset(&ev, 0, sizeof(ev)); |
2294 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 2293 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
2295 | 2294 | ||
2296 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev->id); | 2295 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev); |
2297 | if (!cmd) | 2296 | if (!cmd) |
2298 | goto send_event; | 2297 | goto send_event; |
2299 | 2298 | ||
@@ -2330,7 +2329,7 @@ int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, | |||
2330 | 2329 | ||
2331 | BT_DBG("%s status %u", hdev->name, status); | 2330 | BT_DBG("%s status %u", hdev->name, status); |
2332 | 2331 | ||
2333 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev->id); | 2332 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev); |
2334 | if (!cmd) | 2333 | if (!cmd) |
2335 | return -ENOENT; | 2334 | return -ENOENT; |
2336 | 2335 | ||
@@ -2390,7 +2389,7 @@ int mgmt_inquiry_failed(struct hci_dev *hdev, u8 status) | |||
2390 | struct pending_cmd *cmd; | 2389 | struct pending_cmd *cmd; |
2391 | int err; | 2390 | int err; |
2392 | 2391 | ||
2393 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev->id); | 2392 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); |
2394 | if (!cmd) | 2393 | if (!cmd) |
2395 | return -ENOENT; | 2394 | return -ENOENT; |
2396 | 2395 | ||
@@ -2405,9 +2404,9 @@ int mgmt_discovering(struct hci_dev *hdev, u8 discovering) | |||
2405 | struct pending_cmd *cmd; | 2404 | struct pending_cmd *cmd; |
2406 | 2405 | ||
2407 | if (discovering) | 2406 | if (discovering) |
2408 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev->id); | 2407 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); |
2409 | else | 2408 | else |
2410 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev->id); | 2409 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev); |
2411 | 2410 | ||
2412 | if (cmd != NULL) { | 2411 | if (cmd != NULL) { |
2413 | cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0); | 2412 | cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0); |
@@ -2423,7 +2422,7 @@ int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
2423 | struct pending_cmd *cmd; | 2422 | struct pending_cmd *cmd; |
2424 | struct mgmt_ev_device_blocked ev; | 2423 | struct mgmt_ev_device_blocked ev; |
2425 | 2424 | ||
2426 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev->id); | 2425 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev); |
2427 | 2426 | ||
2428 | bacpy(&ev.bdaddr, bdaddr); | 2427 | bacpy(&ev.bdaddr, bdaddr); |
2429 | 2428 | ||
@@ -2436,7 +2435,7 @@ int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
2436 | struct pending_cmd *cmd; | 2435 | struct pending_cmd *cmd; |
2437 | struct mgmt_ev_device_unblocked ev; | 2436 | struct mgmt_ev_device_unblocked ev; |
2438 | 2437 | ||
2439 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev->id); | 2438 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev); |
2440 | 2439 | ||
2441 | bacpy(&ev.bdaddr, bdaddr); | 2440 | bacpy(&ev.bdaddr, bdaddr); |
2442 | 2441 | ||