diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2012-02-20 08:50:35 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-20 08:58:59 -0500 |
commit | 7cc2ade2cbc6f71090f0f8d0e11cb68886ddc65e (patch) | |
tree | 7ba106e3e172853d1bcc7af8c60a6c1c9766b1c7 /net | |
parent | 3a208627f3ac83d3b749608770f7eb631db31a77 (diff) |
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')
-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 | |||
367 | if (haddr.hci_family != AF_BLUETOOTH) | 367 | if (haddr.hci_family != AF_BLUETOOTH) |
368 | return -EINVAL; | 368 | return -EINVAL; |
369 | 369 | ||
370 | if (haddr.hci_channel > HCI_CHANNEL_CONTROL) | ||
371 | return -EINVAL; | ||
372 | |||
373 | if (haddr.hci_channel == HCI_CHANNEL_CONTROL) { | ||
374 | if (!enable_mgmt) | ||
375 | return -EINVAL; | ||
376 | set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags); | ||
377 | } | ||
378 | |||
379 | lock_sock(sk); | 370 | lock_sock(sk); |
380 | 371 | ||
381 | if (sk->sk_state == BT_BOUND || hci_pi(sk)->hdev) { | 372 | if (sk->sk_state == BT_BOUND) { |
382 | err = -EALREADY; | 373 | err = -EALREADY; |
383 | goto done; | 374 | goto done; |
384 | } | 375 | } |
385 | 376 | ||
386 | if (haddr.hci_dev != HCI_DEV_NONE) { | 377 | switch (haddr.hci_channel) { |
387 | hdev = hci_dev_get(haddr.hci_dev); | 378 | case HCI_CHANNEL_RAW: |
388 | if (!hdev) { | 379 | if (hci_pi(sk)->hdev) { |
389 | err = -ENODEV; | 380 | err = -EALREADY; |
390 | goto done; | 381 | goto done; |
391 | } | 382 | } |
392 | 383 | ||
393 | atomic_inc(&hdev->promisc); | 384 | if (haddr.hci_dev != HCI_DEV_NONE) { |
385 | hdev = hci_dev_get(haddr.hci_dev); | ||
386 | if (!hdev) { | ||
387 | err = -ENODEV; | ||
388 | goto done; | ||
389 | } | ||
390 | |||
391 | atomic_inc(&hdev->promisc); | ||
392 | } | ||
393 | |||
394 | hci_pi(sk)->hdev = hdev; | ||
395 | break; | ||
396 | |||
397 | case HCI_CHANNEL_CONTROL: | ||
398 | if (haddr.hci_dev != HCI_DEV_NONE || !enable_mgmt) { | ||
399 | err = -EINVAL; | ||
400 | goto done; | ||
401 | } | ||
402 | |||
403 | set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags); | ||
404 | break; | ||
405 | |||
406 | default: | ||
407 | err = -EINVAL; | ||
408 | goto done; | ||
394 | } | 409 | } |
395 | 410 | ||
411 | |||
396 | hci_pi(sk)->channel = haddr.hci_channel; | 412 | hci_pi(sk)->channel = haddr.hci_channel; |
397 | hci_pi(sk)->hdev = hdev; | ||
398 | sk->sk_state = BT_BOUND; | 413 | sk->sk_state = BT_BOUND; |
399 | 414 | ||
400 | done: | 415 | done: |