aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2012-02-20 08:50:35 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-20 08:58:59 -0500
commit7cc2ade2cbc6f71090f0f8d0e11cb68886ddc65e (patch)
tree7ba106e3e172853d1bcc7af8c60a6c1c9766b1c7 /net
parent3a208627f3ac83d3b749608770f7eb631db31a77 (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.c47
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
400done: 415done: