aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2013-01-20 07:27:21 -0500
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-01-22 23:02:42 -0500
commit06a63b19e9eb90402e465d60d4c2564afd3ca211 (patch)
treef83280092926c8a81a21eefbc684308fbbe22244 /net/bluetooth
parent118da70b760f04bb2b8130ced97a9f9cc173440a (diff)
Bluetooth: Fix returning proper cmd_complete for mgmt_disconnect
The Disconnect Management command should return Command Complete instead of Command Status whenever possible so that user space can distinguish exactly which command failed in the case of multiple commands. This patch does the necessary changes in the disconnect command handler to return the right event to user space. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/mgmt.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e5e865d8afa8..7b8bc7c658b2 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1654,6 +1654,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1654 u16 len) 1654 u16 len)
1655{ 1655{
1656 struct mgmt_cp_disconnect *cp = data; 1656 struct mgmt_cp_disconnect *cp = data;
1657 struct mgmt_rp_disconnect rp;
1657 struct hci_cp_disconnect dc; 1658 struct hci_cp_disconnect dc;
1658 struct pending_cmd *cmd; 1659 struct pending_cmd *cmd;
1659 struct hci_conn *conn; 1660 struct hci_conn *conn;
@@ -1661,21 +1662,26 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1661 1662
1662 BT_DBG(""); 1663 BT_DBG("");
1663 1664
1665 memset(&rp, 0, sizeof(rp));
1666 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1667 rp.addr.type = cp->addr.type;
1668
1664 if (!bdaddr_type_is_valid(cp->addr.type)) 1669 if (!bdaddr_type_is_valid(cp->addr.type))
1665 return cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1670 return cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1666 MGMT_STATUS_INVALID_PARAMS); 1671 MGMT_STATUS_INVALID_PARAMS,
1672 &rp, sizeof(rp));
1667 1673
1668 hci_dev_lock(hdev); 1674 hci_dev_lock(hdev);
1669 1675
1670 if (!test_bit(HCI_UP, &hdev->flags)) { 1676 if (!test_bit(HCI_UP, &hdev->flags)) {
1671 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1677 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1672 MGMT_STATUS_NOT_POWERED); 1678 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
1673 goto failed; 1679 goto failed;
1674 } 1680 }
1675 1681
1676 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { 1682 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) {
1677 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1683 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1678 MGMT_STATUS_BUSY); 1684 MGMT_STATUS_BUSY, &rp, sizeof(rp));
1679 goto failed; 1685 goto failed;
1680 } 1686 }
1681 1687
@@ -1686,8 +1692,8 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1686 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); 1692 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
1687 1693
1688 if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) { 1694 if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) {
1689 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1695 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1690 MGMT_STATUS_NOT_CONNECTED); 1696 MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp));
1691 goto failed; 1697 goto failed;
1692 } 1698 }
1693 1699