aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-02-03 17:50:35 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:43:30 -0500
commitbb58f747e519aba07a6f05a78d58cf8a0788e2d5 (patch)
treed65743650d5f1a164bbb709a8aa7df4b13250623
parent0a708f8fc46fde3be2116b8d79f7469a24097c90 (diff)
Bluetooth: Initial work for L2CAP split.
This patch tries to do the minimal to move l2cap_sock_create() and its dependencies to l2cap_sock.c. It create a API to initialize and cleanup the L2CAP sockets from l2cap_core.c through l2cap_init_sockets() and l2cap_cleanup_sockets(). Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r--include/net/bluetooth/l2cap.h15
-rw-r--r--net/bluetooth/Makefile2
-rw-r--r--net/bluetooth/l2cap_core.c187
-rw-r--r--net/bluetooth/l2cap_sock.c213
4 files changed, 240 insertions, 177 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 7f88a87d7a46..fce5274a4f7b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -424,6 +424,21 @@ static inline int l2cap_tx_window_full(struct sock *sk)
424#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) 424#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE)
425#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) 425#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
426 426
427extern int disable_ertm;
428extern const struct proto_ops l2cap_sock_ops;
429extern struct bt_sock_list l2cap_sk_list;
430
431int l2cap_init_sockets(void);
432void l2cap_cleanup_sockets(void);
433
434void l2cap_sock_set_timer(struct sock *sk, long timeout);
435void __l2cap_sock_close(struct sock *sk, int reason);
436void l2cap_sock_kill(struct sock *sk);
437void l2cap_sock_init(struct sock *sk, struct sock *parent);
438struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
439 int proto, gfp_t prio);
440
441
427void l2cap_load(void); 442void l2cap_load(void);
428 443
429#endif /* __L2CAP_H */ 444#endif /* __L2CAP_H */
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index bf2945e1d9ef..339b42932b33 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -11,4 +11,4 @@ obj-$(CONFIG_BT_CMTP) += cmtp/
11obj-$(CONFIG_BT_HIDP) += hidp/ 11obj-$(CONFIG_BT_HIDP) += hidp/
12 12
13bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o 13bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o
14l2cap-y := l2cap_core.o 14l2cap-y := l2cap_core.o l2cap_sock.o
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 28d2954f94a4..af678efec15f 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -24,7 +24,7 @@
24 SOFTWARE IS DISCLAIMED. 24 SOFTWARE IS DISCLAIMED.
25*/ 25*/
26 26
27/* Bluetooth L2CAP core and sockets. */ 27/* Bluetooth L2CAP core. */
28 28
29#include <linux/module.h> 29#include <linux/module.h>
30 30
@@ -57,24 +57,20 @@
57 57
58#define VERSION "2.15" 58#define VERSION "2.15"
59 59
60static int disable_ertm; 60int disable_ertm;
61 61
62static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; 62static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
63static u8 l2cap_fixed_chan[8] = { 0x02, }; 63static u8 l2cap_fixed_chan[8] = { 0x02, };
64 64
65static const struct proto_ops l2cap_sock_ops;
66
67static struct workqueue_struct *_busy_wq; 65static struct workqueue_struct *_busy_wq;
68 66
69static struct bt_sock_list l2cap_sk_list = { 67struct bt_sock_list l2cap_sk_list = {
70 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) 68 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
71}; 69};
72 70
73static void l2cap_busy_work(struct work_struct *work); 71static void l2cap_busy_work(struct work_struct *work);
74 72
75static void __l2cap_sock_close(struct sock *sk, int reason);
76static void l2cap_sock_close(struct sock *sk); 73static void l2cap_sock_close(struct sock *sk);
77static void l2cap_sock_kill(struct sock *sk);
78 74
79static int l2cap_build_conf_req(struct sock *sk, void *data); 75static int l2cap_build_conf_req(struct sock *sk, void *data);
80static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, 76static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
@@ -83,7 +79,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
83static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); 79static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb);
84 80
85/* ---- L2CAP timers ---- */ 81/* ---- L2CAP timers ---- */
86static void l2cap_sock_set_timer(struct sock *sk, long timeout) 82void l2cap_sock_set_timer(struct sock *sk, long timeout)
87{ 83{
88 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); 84 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
89 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); 85 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
@@ -95,39 +91,6 @@ static void l2cap_sock_clear_timer(struct sock *sk)
95 sk_stop_timer(sk, &sk->sk_timer); 91 sk_stop_timer(sk, &sk->sk_timer);
96} 92}
97 93
98static void l2cap_sock_timeout(unsigned long arg)
99{
100 struct sock *sk = (struct sock *) arg;
101 int reason;
102
103 BT_DBG("sock %p state %d", sk, sk->sk_state);
104
105 bh_lock_sock(sk);
106
107 if (sock_owned_by_user(sk)) {
108 /* sk is owned by user. Try again later */
109 l2cap_sock_set_timer(sk, HZ / 5);
110 bh_unlock_sock(sk);
111 sock_put(sk);
112 return;
113 }
114
115 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
116 reason = ECONNREFUSED;
117 else if (sk->sk_state == BT_CONNECT &&
118 l2cap_pi(sk)->sec_level != BT_SECURITY_SDP)
119 reason = ECONNREFUSED;
120 else
121 reason = ETIMEDOUT;
122
123 __l2cap_sock_close(sk, reason);
124
125 bh_unlock_sock(sk);
126
127 l2cap_sock_kill(sk);
128 sock_put(sk);
129}
130
131/* ---- L2CAP channels ---- */ 94/* ---- L2CAP channels ---- */
132static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) 95static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
133{ 96{
@@ -801,14 +764,6 @@ static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
801 return node ? sk : sk1; 764 return node ? sk : sk1;
802} 765}
803 766
804static void l2cap_sock_destruct(struct sock *sk)
805{
806 BT_DBG("sk %p", sk);
807
808 skb_queue_purge(&sk->sk_receive_queue);
809 skb_queue_purge(&sk->sk_write_queue);
810}
811
812static void l2cap_sock_cleanup_listen(struct sock *parent) 767static void l2cap_sock_cleanup_listen(struct sock *parent)
813{ 768{
814 struct sock *sk; 769 struct sock *sk;
@@ -826,7 +781,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
826/* Kill socket (only if zapped and orphan) 781/* Kill socket (only if zapped and orphan)
827 * Must be called on unlocked socket. 782 * Must be called on unlocked socket.
828 */ 783 */
829static void l2cap_sock_kill(struct sock *sk) 784void l2cap_sock_kill(struct sock *sk)
830{ 785{
831 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) 786 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
832 return; 787 return;
@@ -839,7 +794,7 @@ static void l2cap_sock_kill(struct sock *sk)
839 sock_put(sk); 794 sock_put(sk);
840} 795}
841 796
842static void __l2cap_sock_close(struct sock *sk, int reason) 797void __l2cap_sock_close(struct sock *sk, int reason)
843{ 798{
844 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); 799 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
845 800
@@ -904,111 +859,6 @@ static void l2cap_sock_close(struct sock *sk)
904 l2cap_sock_kill(sk); 859 l2cap_sock_kill(sk);
905} 860}
906 861
907static void l2cap_sock_init(struct sock *sk, struct sock *parent)
908{
909 struct l2cap_pinfo *pi = l2cap_pi(sk);
910
911 BT_DBG("sk %p", sk);
912
913 if (parent) {
914 sk->sk_type = parent->sk_type;
915 bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup;
916
917 pi->imtu = l2cap_pi(parent)->imtu;
918 pi->omtu = l2cap_pi(parent)->omtu;
919