aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/rfcomm
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/rfcomm')
-rw-r--r--net/bluetooth/rfcomm/core.c27
-rw-r--r--net/bluetooth/rfcomm/sock.c4
2 files changed, 22 insertions, 9 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index bd46e8927f29..155a2b93760e 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -52,8 +52,9 @@
52#define BT_DBG(D...) 52#define BT_DBG(D...)
53#endif 53#endif
54 54
55#define VERSION "1.7" 55#define VERSION "1.8"
56 56
57static int disable_cfc = 0;
57static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU; 58static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU;
58 59
59static struct task_struct *rfcomm_thread; 60static struct task_struct *rfcomm_thread;
@@ -533,7 +534,7 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
533 s->sock = sock; 534 s->sock = sock;
534 535
535 s->mtu = RFCOMM_DEFAULT_MTU; 536 s->mtu = RFCOMM_DEFAULT_MTU;
536 s->cfc = RFCOMM_CFC_UNKNOWN; 537 s->cfc = disable_cfc ? RFCOMM_CFC_DISABLED : RFCOMM_CFC_UNKNOWN;
537 538
538 /* Do not increment module usage count for listening sessions. 539 /* Do not increment module usage count for listening sessions.
539 * Otherwise we won't be able to unload the module. */ 540 * Otherwise we won't be able to unload the module. */
@@ -1149,6 +1150,8 @@ static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d)
1149 1150
1150static void rfcomm_dlc_accept(struct rfcomm_dlc *d) 1151static void rfcomm_dlc_accept(struct rfcomm_dlc *d)
1151{ 1152{
1153 struct sock *sk = d->session->sock->sk;
1154
1152 BT_DBG("dlc %p", d); 1155 BT_DBG("dlc %p", d);
1153 1156
1154 rfcomm_send_ua(d->session, d->dlci); 1157 rfcomm_send_ua(d->session, d->dlci);
@@ -1158,6 +1161,9 @@ static void rfcomm_dlc_accept(struct rfcomm_dlc *d)
1158 d->state_change(d, 0); 1161 d->state_change(d, 0);
1159 rfcomm_dlc_unlock(d); 1162 rfcomm_dlc_unlock(d);
1160 1163
1164 if (d->link_mode & RFCOMM_LM_MASTER)
1165 hci_conn_switch_role(l2cap_pi(sk)->conn->hcon, 0x00);
1166
1161 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig); 1167 rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
1162} 1168}
1163 1169
@@ -1222,14 +1228,18 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
1222 BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d", 1228 BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
1223 d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits); 1229 d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
1224 1230
1225 if (pn->flow_ctrl == 0xf0 || pn->flow_ctrl == 0xe0) { 1231 if ((pn->flow_ctrl == 0xf0 && s->cfc != RFCOMM_CFC_DISABLED) ||
1226 d->cfc = s->cfc = RFCOMM_CFC_ENABLED; 1232 pn->flow_ctrl == 0xe0) {
1233 d->cfc = RFCOMM_CFC_ENABLED;
1227 d->tx_credits = pn->credits; 1234 d->tx_credits = pn->credits;
1228 } else { 1235 } else {
1229 d->cfc = s->cfc = RFCOMM_CFC_DISABLED; 1236 d->cfc = RFCOMM_CFC_DISABLED;
1230 set_bit(RFCOMM_TX_THROTTLED, &d->flags); 1237 set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1231 } 1238 }
1232 1239
1240 if (s->cfc == RFCOMM_CFC_UNKNOWN)
1241 s->cfc = d->cfc;
1242
1233 d->priority = pn->priority; 1243 d->priority = pn->priority;
1234 1244
1235 d->mtu = s->mtu = btohs(pn->mtu); 1245 d->mtu = s->mtu = btohs(pn->mtu);
@@ -2035,7 +2045,7 @@ static int __init rfcomm_init(void)
2035 2045
2036 kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); 2046 kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
2037 2047
2038 class_create_file(&bt_class, &class_attr_rfcomm_dlc); 2048 class_create_file(bt_class, &class_attr_rfcomm_dlc);
2039 2049
2040 rfcomm_init_sockets(); 2050 rfcomm_init_sockets();
2041 2051
@@ -2050,7 +2060,7 @@ static int __init rfcomm_init(void)
2050 2060
2051static void __exit rfcomm_exit(void) 2061static void __exit rfcomm_exit(void)
2052{ 2062{
2053 class_remove_file(&bt_class, &class_attr_rfcomm_dlc); 2063 class_remove_file(bt_class, &class_attr_rfcomm_dlc);
2054 2064
2055 hci_unregister_cb(&rfcomm_cb); 2065 hci_unregister_cb(&rfcomm_cb);
2056 2066
@@ -2073,6 +2083,9 @@ static void __exit rfcomm_exit(void)
2073module_init(rfcomm_init); 2083module_init(rfcomm_init);
2074module_exit(rfcomm_exit); 2084module_exit(rfcomm_exit);
2075 2085
2086module_param(disable_cfc, bool, 0644);
2087MODULE_PARM_DESC(disable_cfc, "Disable credit based flow control");
2088
2076module_param(l2cap_mtu, uint, 0644); 2089module_param(l2cap_mtu, uint, 0644);
2077MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection"); 2090MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
2078 2091
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 4e9962c8cfa6..220fee04e7f2 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -944,7 +944,7 @@ int __init rfcomm_init_sockets(void)
944 if (err < 0) 944 if (err < 0)
945 goto error; 945 goto error;
946 946
947 class_create_file(&bt_class, &class_attr_rfcomm); 947 class_create_file(bt_class, &class_attr_rfcomm);
948 948
949 BT_INFO("RFCOMM socket layer initialized"); 949 BT_INFO("RFCOMM socket layer initialized");
950 950
@@ -958,7 +958,7 @@ error:
958 958
959void __exit rfcomm_cleanup_sockets(void) 959void __exit rfcomm_cleanup_sockets(void)
960{ 960{
961 class_remove_file(&bt_class, &class_attr_rfcomm); 961 class_remove_file(bt_class, &class_attr_rfcomm);
962 962
963 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) 963 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
964 BT_ERR("RFCOMM socket layer unregistration failed"); 964 BT_ERR("RFCOMM socket layer unregistration failed");