diff options
author | Ulisses Furquim <ulisses@profusion.mobi> | 2011-12-21 07:11:33 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-12-22 11:07:29 -0500 |
commit | 686ebf283ba19f82abd8aaec023cd124749be9ec (patch) | |
tree | 9d10d8bc79779756dd8833a2c6ef8d5ad019ac81 /net/bluetooth | |
parent | 68a8aea45973c8d0bc05f58389ce9e82e04bb5f6 (diff) |
Bluetooth: Make HCI call directly into SCO and L2CAP event functions
The struct hci_proto and all related register/unregister and dispatching
code was removed. HCI core code now call directly the SCO and L2CAP
event functions.
Signed-off-by: Ulisses Furquim <ulisses@profusion.mobi>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 59 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 51 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 38 |
3 files changed, 15 insertions, 133 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index fea8dad72e3a..22c8331cd0d5 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -69,10 +69,6 @@ DEFINE_RWLOCK(hci_dev_list_lock); | |||
69 | LIST_HEAD(hci_cb_list); | 69 | LIST_HEAD(hci_cb_list); |
70 | DEFINE_RWLOCK(hci_cb_list_lock); | 70 | DEFINE_RWLOCK(hci_cb_list_lock); |
71 | 71 | ||
72 | /* HCI protocols */ | ||
73 | #define HCI_MAX_PROTO 2 | ||
74 | struct hci_proto *hci_proto[HCI_MAX_PROTO]; | ||
75 | |||
76 | /* HCI notifiers list */ | 72 | /* HCI notifiers list */ |
77 | static ATOMIC_NOTIFIER_HEAD(hci_notifier); | 73 | static ATOMIC_NOTIFIER_HEAD(hci_notifier); |
78 | 74 | ||
@@ -1830,43 +1826,6 @@ EXPORT_SYMBOL(hci_recv_stream_fragment); | |||
1830 | 1826 | ||
1831 | /* ---- Interface to upper protocols ---- */ | 1827 | /* ---- Interface to upper protocols ---- */ |
1832 | 1828 | ||
1833 | /* Register/Unregister protocols. */ | ||
1834 | int hci_register_proto(struct hci_proto *hp) | ||
1835 | { | ||
1836 | int err = 0; | ||
1837 | |||
1838 | BT_DBG("%p name %s id %d", hp, hp->name, hp->id); | ||
1839 | |||
1840 | if (hp->id >= HCI_MAX_PROTO) | ||
1841 | return -EINVAL; | ||
1842 | |||
1843 | if (!hci_proto[hp->id]) | ||
1844 | hci_proto[hp->id] = hp; | ||
1845 | else | ||
1846 | err = -EEXIST; | ||
1847 | |||
1848 | return err; | ||
1849 | } | ||
1850 | EXPORT_SYMBOL(hci_register_proto); | ||
1851 | |||
1852 | int hci_unregister_proto(struct hci_proto *hp) | ||
1853 | { | ||
1854 | int err = 0; | ||
1855 | |||
1856 | BT_DBG("%p name %s id %d", hp, hp->name, hp->id); | ||
1857 | |||
1858 | if (hp->id >= HCI_MAX_PROTO) | ||
1859 | return -EINVAL; | ||
1860 | |||
1861 | if (hci_proto[hp->id]) | ||
1862 | hci_proto[hp->id] = NULL; | ||
1863 | else | ||
1864 | err = -ENOENT; | ||
1865 | |||
1866 | return err; | ||
1867 | } | ||
1868 | EXPORT_SYMBOL(hci_unregister_proto); | ||
1869 | |||
1870 | int hci_register_cb(struct hci_cb *cb) | 1829 | int hci_register_cb(struct hci_cb *cb) |
1871 | { | 1830 | { |
1872 | BT_DBG("%p name %s", cb, cb->name); | 1831 | BT_DBG("%p name %s", cb, cb->name); |
@@ -2470,16 +2429,11 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2470 | hci_dev_unlock(hdev); | 2429 | hci_dev_unlock(hdev); |
2471 | 2430 | ||
2472 | if (conn) { | 2431 | if (conn) { |
2473 | register struct hci_proto *hp; | ||
2474 | |||
2475 | hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); | 2432 | hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); |
2476 | 2433 | ||
2477 | /* Send to upper protocol */ | 2434 | /* Send to upper protocol */ |
2478 | hp = hci_proto[HCI_PROTO_L2CAP]; | 2435 | l2cap_recv_acldata(conn, skb, flags); |
2479 | if (hp && hp->recv_acldata) { | 2436 | return; |
2480 | hp->recv_acldata(conn, skb, flags); | ||
2481 | return; | ||
2482 | } | ||
2483 | } else { | 2437 | } else { |
2484 | BT_ERR("%s ACL packet for unknown connection handle %d", | 2438 | BT_ERR("%s ACL packet for unknown connection handle %d", |
2485 | hdev->name, handle); | 2439 | hdev->name, handle); |
@@ -2508,14 +2462,9 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2508 | hci_dev_unlock(hdev); | 2462 | hci_dev_unlock(hdev); |
2509 | 2463 | ||
2510 | if (conn) { | 2464 | if (conn) { |
2511 | register struct hci_proto *hp; | ||
2512 | |||
2513 | /* Send to upper protocol */ | 2465 | /* Send to upper protocol */ |
2514 | hp = hci_proto[HCI_PROTO_SCO]; | 2466 | sco_recv_scodata(conn, skb); |
2515 | if (hp && hp->recv_scodata) { | 2467 | return; |
2516 | hp->recv_scodata(conn, skb); | ||
2517 | return; | ||
2518 | } | ||
2519 | } else { | 2468 | } else { |
2520 | BT_ERR("%s SCO packet for unknown connection handle %d", | 2469 | BT_ERR("%s SCO packet for unknown connection handle %d", |
2521 | hdev->name, handle); | 2470 | hdev->name, handle); |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a898285e3ea6..173218345a10 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -4413,14 +4413,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
4413 | 4413 | ||
4414 | /* ---- L2CAP interface with lower layer (HCI) ---- */ | 4414 | /* ---- L2CAP interface with lower layer (HCI) ---- */ |
4415 | 4415 | ||
4416 | static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | 4416 | int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) |
4417 | { | 4417 | { |
4418 | int exact = 0, lm1 = 0, lm2 = 0; | 4418 | int exact = 0, lm1 = 0, lm2 = 0; |
4419 | struct l2cap_chan *c; | 4419 | struct l2cap_chan *c; |
4420 | 4420 | ||
4421 | if (type != ACL_LINK) | ||
4422 | return -EINVAL; | ||
4423 | |||
4424 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 4421 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); |
4425 | 4422 | ||
4426 | /* Find listening sockets and check their link_mode */ | 4423 | /* Find listening sockets and check their link_mode */ |
@@ -4447,15 +4444,12 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
4447 | return exact ? lm1 : lm2; | 4444 | return exact ? lm1 : lm2; |
4448 | } | 4445 | } |
4449 | 4446 | ||
4450 | static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | 4447 | int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) |
4451 | { | 4448 | { |
4452 | struct l2cap_conn *conn; | 4449 | struct l2cap_conn *conn; |
4453 | 4450 | ||
4454 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 4451 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
4455 | 4452 | ||
4456 | if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK)) | ||
4457 | return -EINVAL; | ||
4458 | |||
4459 | if (!status) { | 4453 | if (!status) { |
4460 | conn = l2cap_conn_add(hcon, status); | 4454 | conn = l2cap_conn_add(hcon, status); |
4461 | if (conn) | 4455 | if (conn) |
@@ -4466,27 +4460,22 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | |||
4466 | return 0; | 4460 | return 0; |
4467 | } | 4461 | } |
4468 | 4462 | ||
4469 | static int l2cap_disconn_ind(struct hci_conn *hcon) | 4463 | int l2cap_disconn_ind(struct hci_conn *hcon) |
4470 | { | 4464 | { |
4471 | struct l2cap_conn *conn = hcon->l2cap_data; | 4465 | struct l2cap_conn *conn = hcon->l2cap_data; |
4472 | 4466 | ||
4473 | BT_DBG("hcon %p", hcon); | 4467 | BT_DBG("hcon %p", hcon); |
4474 | 4468 | ||
4475 | if ((hcon->type != ACL_LINK && hcon->type != LE_LINK) || !conn) | 4469 | if (!conn) |
4476 | return HCI_ERROR_REMOTE_USER_TERM; | 4470 | return HCI_ERROR_REMOTE_USER_TERM; |
4477 | |||
4478 | return conn->disc_reason; | 4471 | return conn->disc_reason; |
4479 | } | 4472 | } |
4480 | 4473 | ||
4481 | static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) | 4474 | int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) |
4482 | { | 4475 | { |
4483 | BT_DBG("hcon %p reason %d", hcon, reason); | 4476 | BT_DBG("hcon %p reason %d", hcon, reason); |
4484 | 4477 | ||
4485 | if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK)) | ||
4486 | return -EINVAL; | ||
4487 | |||
4488 | l2cap_conn_del(hcon, bt_to_errno(reason)); | 4478 | l2cap_conn_del(hcon, bt_to_errno(reason)); |
4489 | |||
4490 | return 0; | 4479 | return 0; |
4491 | } | 4480 | } |
4492 | 4481 | ||
@@ -4507,7 +4496,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) | |||
4507 | } | 4496 | } |
4508 | } | 4497 | } |
4509 | 4498 | ||
4510 | static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | 4499 | int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) |
4511 | { | 4500 | { |
4512 | struct l2cap_conn *conn = hcon->l2cap_data; | 4501 | struct l2cap_conn *conn = hcon->l2cap_data; |
4513 | struct l2cap_chan *chan; | 4502 | struct l2cap_chan *chan; |
@@ -4607,7 +4596,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4607 | return 0; | 4596 | return 0; |
4608 | } | 4597 | } |
4609 | 4598 | ||
4610 | static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) | 4599 | int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) |
4611 | { | 4600 | { |
4612 | struct l2cap_conn *conn = hcon->l2cap_data; | 4601 | struct l2cap_conn *conn = hcon->l2cap_data; |
4613 | 4602 | ||
@@ -4754,17 +4743,6 @@ static const struct file_operations l2cap_debugfs_fops = { | |||
4754 | 4743 | ||
4755 | static struct dentry *l2cap_debugfs; | 4744 | static struct dentry *l2cap_debugfs; |
4756 | 4745 | ||
4757 | static struct hci_proto l2cap_hci_proto = { | ||
4758 | .name = "L2CAP", | ||
4759 | .id = HCI_PROTO_L2CAP, | ||
4760 | .connect_ind = l2cap_connect_ind, | ||
4761 | .connect_cfm = l2cap_connect_cfm, | ||
4762 | .disconn_ind = l2cap_disconn_ind, | ||
4763 | .disconn_cfm = l2cap_disconn_cfm, | ||
4764 | .security_cfm = l2cap_security_cfm, | ||
4765 | .recv_acldata = l2cap_recv_acldata | ||
4766 | }; | ||
4767 | |||
4768 | int __init l2cap_init(void) | 4746 | int __init l2cap_init(void) |
4769 | { | 4747 | { |
4770 | int err; | 4748 | int err; |
@@ -4773,13 +4751,6 @@ int __init l2cap_init(void) | |||
4773 | if (err < 0) | 4751 | if (err < 0) |
4774 | return err; | 4752 | return err; |
4775 | 4753 | ||
4776 | err = hci_register_proto(&l2cap_hci_proto); | ||
4777 | if (err < 0) { | ||
4778 | BT_ERR("L2CAP protocol registration failed"); | ||
4779 | bt_sock_unregister(BTPROTO_L2CAP); | ||
4780 | goto error; | ||
4781 | } | ||
4782 | |||
4783 | if (bt_debugfs) { | 4754 | if (bt_debugfs) { |
4784 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, | 4755 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, |
4785 | bt_debugfs, NULL, &l2cap_debugfs_fops); | 4756 | bt_debugfs, NULL, &l2cap_debugfs_fops); |
@@ -4788,19 +4759,11 @@ int __init l2cap_init(void) | |||
4788 | } | 4759 | } |
4789 | 4760 | ||
4790 | return 0; | 4761 | return 0; |
4791 | |||
4792 | error: | ||
4793 | l2cap_cleanup_sockets(); | ||
4794 | return err; | ||
4795 | } | 4762 | } |
4796 | 4763 | ||
4797 | void l2cap_exit(void) | 4764 | void l2cap_exit(void) |
4798 | { | 4765 | { |
4799 | debugfs_remove(l2cap_debugfs); | 4766 | debugfs_remove(l2cap_debugfs); |
4800 | |||
4801 | if (hci_unregister_proto(&l2cap_hci_proto) < 0) | ||
4802 | BT_ERR("L2CAP protocol unregistration failed"); | ||
4803 | |||
4804 | l2cap_cleanup_sockets(); | 4767 | l2cap_cleanup_sockets(); |
4805 | } | 4768 | } |
4806 | 4769 | ||
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 725e10d487f2..0d59e61d7822 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -893,15 +893,12 @@ done: | |||
893 | } | 893 | } |
894 | 894 | ||
895 | /* ----- SCO interface with lower layer (HCI) ----- */ | 895 | /* ----- SCO interface with lower layer (HCI) ----- */ |
896 | static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | 896 | int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) |
897 | { | 897 | { |
898 | register struct sock *sk; | 898 | register struct sock *sk; |
899 | struct hlist_node *node; | 899 | struct hlist_node *node; |
900 | int lm = 0; | 900 | int lm = 0; |
901 | 901 | ||
902 | if (type != SCO_LINK && type != ESCO_LINK) | ||
903 | return -EINVAL; | ||
904 | |||
905 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 902 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); |
906 | 903 | ||
907 | /* Find listening sockets */ | 904 | /* Find listening sockets */ |
@@ -921,13 +918,9 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | |||
921 | return lm; | 918 | return lm; |
922 | } | 919 | } |
923 | 920 | ||
924 | static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) | 921 | int sco_connect_cfm(struct hci_conn *hcon, __u8 status) |
925 | { | 922 | { |
926 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 923 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
927 | |||
928 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | ||
929 | return -EINVAL; | ||
930 | |||
931 | if (!status) { | 924 | if (!status) { |
932 | struct sco_conn *conn; | 925 | struct sco_conn *conn; |
933 | 926 | ||
@@ -940,19 +933,15 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) | |||
940 | return 0; | 933 | return 0; |
941 | } | 934 | } |
942 | 935 | ||
943 | static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) | 936 | int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) |
944 | { | 937 | { |
945 | BT_DBG("hcon %p reason %d", hcon, reason); | 938 | BT_DBG("hcon %p reason %d", hcon, reason); |
946 | 939 | ||
947 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | ||
948 | return -EINVAL; | ||
949 | |||
950 | sco_conn_del(hcon, bt_to_errno(reason)); | 940 | sco_conn_del(hcon, bt_to_errno(reason)); |
951 | |||
952 | return 0; | 941 | return 0; |
953 | } | 942 | } |
954 | 943 | ||
955 | static int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) | 944 | int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) |
956 | { | 945 | { |
957 | struct sco_conn *conn = hcon->sco_data; | 946 | struct sco_conn *conn = hcon->sco_data; |
958 | 947 | ||
@@ -1028,15 +1017,6 @@ static const struct net_proto_family sco_sock_family_ops = { | |||
1028 | .create = sco_sock_create, | 1017 | .create = sco_sock_create, |
1029 | }; | 1018 | }; |
1030 | 1019 | ||
1031 | static struct hci_proto sco_hci_proto = { | ||
1032 | .name = "SCO", | ||
1033 | .id = HCI_PROTO_SCO, | ||
1034 | .connect_ind = sco_connect_ind, | ||
1035 | .connect_cfm = sco_connect_cfm, | ||
1036 | .disconn_cfm = sco_disconn_cfm, | ||
1037 | .recv_scodata = sco_recv_scodata | ||
1038 | }; | ||
1039 | |||
1040 | int __init sco_init(void) | 1020 | int __init sco_init(void) |
1041 | { | 1021 | { |
1042 | int err; | 1022 | int err; |
@@ -1051,13 +1031,6 @@ int __init sco_init(void) | |||
1051 | goto error; | 1031 | goto error; |
1052 | } | 1032 | } |
1053 | 1033 | ||
1054 | err = hci_register_proto(&sco_hci_proto); | ||
1055 | if (err < 0) { | ||
1056 | BT_ERR("SCO protocol registration failed"); | ||
1057 | bt_sock_unregister(BTPROTO_SCO); | ||
1058 | goto error; | ||
1059 | } | ||
1060 | |||
1061 | if (bt_debugfs) { | 1034 | if (bt_debugfs) { |
1062 | sco_debugfs = debugfs_create_file("sco", 0444, | 1035 | sco_debugfs = debugfs_create_file("sco", 0444, |
1063 | bt_debugfs, NULL, &sco_debugfs_fops); | 1036 | bt_debugfs, NULL, &sco_debugfs_fops); |
@@ -1081,9 +1054,6 @@ void __exit sco_exit(void) | |||
1081 | if (bt_sock_unregister(BTPROTO_SCO) < 0) | 1054 | if (bt_sock_unregister(BTPROTO_SCO) < 0) |
1082 | BT_ERR("SCO socket unregistration failed"); | 1055 | BT_ERR("SCO socket unregistration failed"); |
1083 | 1056 | ||
1084 | if (hci_unregister_proto(&sco_hci_proto) < 0) | ||
1085 | BT_ERR("SCO protocol unregistration failed"); | ||
1086 | |||
1087 | proto_unregister(&sco_proto); | 1057 | proto_unregister(&sco_proto); |
1088 | } | 1058 | } |
1089 | 1059 | ||