diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2012-02-20 14:50:35 +0100 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-20 15:58:59 +0200 |
commit | 7cc2ade2cbc6f71090f0f8d0e11cb68886ddc65e (patch) | |
tree | 7ba106e3e172853d1bcc7af8c60a6c1c9766b1c7 /net/bluetooth/hci_sock.c | |
parent | 3a208627f3ac83d3b749608770f7eb631db31a77 (diff) | |
download | linux-stable-7cc2ade2cbc6f71090f0f8d0e11cb68886ddc65e.tar.gz linux-stable-7cc2ade2cbc6f71090f0f8d0e11cb68886ddc65e.tar.bz2 linux-stable-7cc2ade2cbc6f71090f0f8d0e11cb68886ddc65e.zip |
Bluetooth: Simplify HCI socket bind handling
The HCI socket bind handling checks a few too many times the channel
we are binding. So centralize this and make the function easier to read.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth/hci_sock.c')
-rw-r--r-- | net/bluetooth/hci_sock.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 71a02adbaa77..4dda4574db3e 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -367,34 +367,49 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le if (haddr.hci_family != AF_BLUETOOTH) return -EINVAL; - if (haddr.hci_channel > HCI_CHANNEL_CONTROL) - return -EINVAL; - - if (haddr.hci_channel == HCI_CHANNEL_CONTROL) { - if (!enable_mgmt) - return -EINVAL; - set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags); - } - lock_sock(sk); - if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) { + if (sk->sk_state == BT_BOUND) { err = -EALREADY; goto done; } - if (haddr.hci_dev != HCI_DEV_NONE) { - hdev = hci_dev_get(haddr.hci_dev); - if (!hdev) { - err = -ENODEV; + switch (haddr.hci_channel) { + case HCI_CHANNEL_RAW: + if (hci_pi(sk)->hdev) { + err = -EALREADY; goto done; } - atomic_inc(&hdev->promisc); + if (haddr.hci_dev != HCI_DEV_NONE) { + hdev = hci_dev_get(haddr.hci_dev); + if (!hdev) { + err = -ENODEV; + goto done; + } + + atomic_inc(&hdev->promisc); + } + + hci_pi(sk)->hdev = hdev; + break; + + case HCI_CHANNEL_CONTROL: + if (haddr.hci_dev != HCI_DEV_NONE || !enable_mgmt) { + err = -EINVAL; + goto done; + } + + set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags); + break; + + default: + err = -EINVAL; + goto done; } + hci_pi(sk)->channel = haddr.hci_channel; - hci_pi(sk)->hdev = hdev; sk->sk_state = BT_BOUND; done: |