diff options
-rw-r--r-- | include/net/bluetooth/hci.h | 1 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 29 |
2 files changed, 28 insertions, 2 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index c97cf0872ac9..05bd9aca4054 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -100,6 +100,7 @@ enum { | |||
100 | HCI_CONNECTABLE, | 100 | HCI_CONNECTABLE, |
101 | HCI_DISCOVERABLE, | 101 | HCI_DISCOVERABLE, |
102 | HCI_LINK_SECURITY, | 102 | HCI_LINK_SECURITY, |
103 | HCI_PENDING_CLASS, | ||
103 | }; | 104 | }; |
104 | 105 | ||
105 | /* HCI ioctl defines */ | 106 | /* HCI ioctl defines */ |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 79fe57573463..9f912dc71bae 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -570,6 +570,7 @@ static u8 get_service_classes(struct hci_dev *hdev) | |||
570 | static int update_class(struct hci_dev *hdev) | 570 | static int update_class(struct hci_dev *hdev) |
571 | { | 571 | { |
572 | u8 cod[3]; | 572 | u8 cod[3]; |
573 | int err; | ||
573 | 574 | ||
574 | BT_DBG("%s", hdev->name); | 575 | BT_DBG("%s", hdev->name); |
575 | 576 | ||
@@ -586,7 +587,11 @@ static int update_class(struct hci_dev *hdev) | |||
586 | if (memcmp(cod, hdev->dev_class, 3) == 0) | 587 | if (memcmp(cod, hdev->dev_class, 3) == 0) |
587 | return 0; | 588 | return 0; |
588 | 589 | ||
589 | return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); | 590 | err = hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); |
591 | if (err == 0) | ||
592 | set_bit(HCI_PENDING_CLASS, &hdev->dev_flags); | ||
593 | |||
594 | return err; | ||
590 | } | 595 | } |
591 | 596 | ||
592 | static void service_cache_off(struct work_struct *work) | 597 | static void service_cache_off(struct work_struct *work) |
@@ -1344,6 +1349,12 @@ static int add_uuid(struct sock *sk, u16 index, void *data, u16 len) | |||
1344 | 1349 | ||
1345 | hci_dev_lock(hdev); | 1350 | hci_dev_lock(hdev); |
1346 | 1351 | ||
1352 | if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { | ||
1353 | err = cmd_status(sk, index, MGMT_OP_ADD_UUID, | ||
1354 | MGMT_STATUS_BUSY); | ||
1355 | goto failed; | ||
1356 | } | ||
1357 | |||
1347 | uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); | 1358 | uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); |
1348 | if (!uuid) { | 1359 | if (!uuid) { |
1349 | err = -ENOMEM; | 1360 | err = -ENOMEM; |
@@ -1393,6 +1404,12 @@ static int remove_uuid(struct sock *sk, u16 index, void *data, u16 len) | |||
1393 | 1404 | ||
1394 | hci_dev_lock(hdev); | 1405 | hci_dev_lock(hdev); |
1395 | 1406 | ||
1407 | if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { | ||
1408 | err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID, | ||
1409 | MGMT_STATUS_BUSY); | ||
1410 | goto unlock; | ||
1411 | } | ||
1412 | |||
1396 | if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { | 1413 | if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { |
1397 | err = hci_uuids_clear(hdev); | 1414 | err = hci_uuids_clear(hdev); |
1398 | 1415 | ||
@@ -1460,6 +1477,12 @@ static int set_dev_class(struct sock *sk, u16 index, void *data, u16 len) | |||
1460 | 1477 | ||
1461 | hci_dev_lock(hdev); | 1478 | hci_dev_lock(hdev); |
1462 | 1479 | ||
1480 | if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { | ||
1481 | err = cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, | ||
1482 | MGMT_STATUS_BUSY); | ||
1483 | goto unlock; | ||
1484 | } | ||
1485 | |||
1463 | hdev->major_class = cp->major; | 1486 | hdev->major_class = cp->major; |
1464 | hdev->minor_class = cp->minor; | 1487 | hdev->minor_class = cp->minor; |
1465 | 1488 | ||
@@ -3259,7 +3282,7 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
3259 | bacpy(&ev->addr.bdaddr, bdaddr); | 3282 | bacpy(&ev->addr.bdaddr, bdaddr); |
3260 | ev->addr.type = link_to_mgmt(link_type, addr_type); | 3283 | ev->addr.type = link_to_mgmt(link_type, addr_type); |
3261 | 3284 | ||
3262 | put_unaligned_le32(flags, &ev->flags); | 3285 | ev->flags = __cpu_to_le32(flags); |
3263 | 3286 | ||
3264 | if (name_len > 0) | 3287 | if (name_len > 0) |
3265 | eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, | 3288 | eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, |
@@ -3614,6 +3637,8 @@ int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, | |||
3614 | { | 3637 | { |
3615 | int err; | 3638 | int err; |
3616 | 3639 | ||
3640 | clear_bit(HCI_PENDING_CLASS, &hdev->dev_flags); | ||
3641 | |||
3617 | err = mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, 3, NULL); | 3642 | err = mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, 3, NULL); |
3618 | 3643 | ||
3619 | return err; | 3644 | return err; |