diff options
Diffstat (limited to 'net/bluetooth/rfcomm/core.c')
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 167 |
1 files changed, 79 insertions, 88 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index b23e2713fea8..ca957d34b0c8 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -69,7 +69,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, | |||
69 | u8 sec_level, | 69 | u8 sec_level, |
70 | int *err); | 70 | int *err); |
71 | static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst); | 71 | static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst); |
72 | static void rfcomm_session_del(struct rfcomm_session *s); | 72 | static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s); |
73 | 73 | ||
74 | /* ---- RFCOMM frame parsing macros ---- */ | 74 | /* ---- RFCOMM frame parsing macros ---- */ |
75 | #define __get_dlci(b) ((b & 0xfc) >> 2) | 75 | #define __get_dlci(b) ((b & 0xfc) >> 2) |
@@ -108,12 +108,6 @@ static void rfcomm_schedule(void) | |||
108 | wake_up_process(rfcomm_thread); | 108 | wake_up_process(rfcomm_thread); |
109 | } | 109 | } |
110 | 110 | ||
111 | static void rfcomm_session_put(struct rfcomm_session *s) | ||
112 | { | ||
113 | if (atomic_dec_and_test(&s->refcnt)) | ||
114 | rfcomm_session_del(s); | ||
115 | } | ||
116 | |||
117 | /* ---- RFCOMM FCS computation ---- */ | 111 | /* ---- RFCOMM FCS computation ---- */ |
118 | 112 | ||
119 | /* reversed, 8-bit, poly=0x07 */ | 113 | /* reversed, 8-bit, poly=0x07 */ |
@@ -249,16 +243,14 @@ static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout) | |||
249 | { | 243 | { |
250 | BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout); | 244 | BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout); |
251 | 245 | ||
252 | if (!mod_timer(&s->timer, jiffies + timeout)) | 246 | mod_timer(&s->timer, jiffies + timeout); |
253 | rfcomm_session_hold(s); | ||
254 | } | 247 | } |
255 | 248 | ||
256 | static void rfcomm_session_clear_timer(struct rfcomm_session *s) | 249 | static void rfcomm_session_clear_timer(struct rfcomm_session *s) |
257 | { | 250 | { |
258 | BT_DBG("session %p state %ld", s, s->state); | 251 | BT_DBG("session %p state %ld", s, s->state); |
259 | 252 | ||
260 | if (del_timer(&s->timer)) | 253 | del_timer_sync(&s->timer); |
261 | rfcomm_session_put(s); | ||
262 | } | 254 | } |
263 | 255 | ||
264 | /* ---- RFCOMM DLCs ---- */ | 256 | /* ---- RFCOMM DLCs ---- */ |
@@ -336,8 +328,6 @@ static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d) | |||
336 | { | 328 | { |
337 | BT_DBG("dlc %p session %p", d, s); | 329 | BT_DBG("dlc %p session %p", d, s); |
338 | 330 | ||
339 | rfcomm_session_hold(s); | ||
340 | |||
341 | rfcomm_session_clear_timer(s); | 331 | rfcomm_session_clear_timer(s); |
342 | rfcomm_dlc_hold(d); | 332 | rfcomm_dlc_hold(d); |
343 | list_add(&d->list, &s->dlcs); | 333 | list_add(&d->list, &s->dlcs); |
@@ -356,8 +346,6 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d) | |||
356 | 346 | ||
357 | if (list_empty(&s->dlcs)) | 347 | if (list_empty(&s->dlcs)) |
358 | rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT); | 348 | rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT); |
359 | |||
360 | rfcomm_session_put(s); | ||
361 | } | 349 | } |
362 | 350 | ||
363 | static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci) | 351 | static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci) |
@@ -493,12 +481,34 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) | |||
493 | 481 | ||
494 | int rfcomm_dlc_close(struct rfcomm_dlc *d, int err) | 482 | int rfcomm_dlc_close(struct rfcomm_dlc *d, int err) |
495 | { | 483 | { |
496 | int r; | 484 | int r = 0; |
485 | struct rfcomm_dlc *d_list; | ||
486 | struct rfcomm_session *s, *s_list; | ||
487 | |||
488 | BT_DBG("dlc %p state %ld dlci %d err %d", d, d->state, d->dlci, err); | ||
497 | 489 | ||
498 | rfcomm_lock(); | 490 | rfcomm_lock(); |
499 | 491 | ||
500 | r = __rfcomm_dlc_close(d, err); | 492 | s = d->session; |
493 | if (!s) | ||
494 | goto no_session; | ||
495 | |||
496 | /* after waiting on the mutex check the session still exists | ||
497 | * then check the dlc still exists | ||
498 | */ | ||
499 | list_for_each_entry(s_list, &session_list, list) { | ||
500 | if (s_list == s) { | ||
501 | list_for_each_entry(d_list, &s->dlcs, list) { | ||
502 | if (d_list == d) { | ||
503 | r = __rfcomm_dlc_close(d, err); | ||
504 | break; | ||
505 | } | ||
506 | } | ||
507 | break; | ||
508 | } | ||
509 | } | ||
501 | 510 | ||
511 | no_session: | ||
502 | rfcomm_unlock(); | 512 | rfcomm_unlock(); |
503 | return r; | 513 | return r; |
504 | } | 514 | } |
@@ -609,7 +619,7 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state) | |||
609 | return s; | 619 | return s; |
610 | } | 620 | } |
611 | 621 | ||
612 | static void rfcomm_session_del(struct rfcomm_session *s) | 622 | static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s) |
613 | { | 623 | { |
614 | int state = s->state; | 624 | int state = s->state; |
615 | 625 | ||
@@ -617,15 +627,14 @@ static void rfcomm_session_del(struct rfcomm_session *s) | |||
617 | 627 | ||
618 | list_del(&s->list); | 628 | list_del(&s->list); |
619 | 629 | ||
620 | if (state == BT_CONNECTED) | ||
621 | rfcomm_send_disc(s, 0); | ||
622 | |||
623 | rfcomm_session_clear_timer(s); | 630 | rfcomm_session_clear_timer(s); |
624 | sock_release(s->sock); | 631 | sock_release(s->sock); |
625 | kfree(s); | 632 | kfree(s); |
626 | 633 | ||
627 | if (state != BT_LISTEN) | 634 | if (state != BT_LISTEN) |
628 | module_put(THIS_MODULE); | 635 | module_put(THIS_MODULE); |
636 | |||
637 | return NULL; | ||
629 | } | 638 | } |
630 | 639 | ||
631 | static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst) | 640 | static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst) |
@@ -644,17 +653,16 @@ static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst) | |||
644 | return NULL; | 653 | return NULL; |
645 | } | 654 | } |
646 | 655 | ||
647 | static void rfcomm_session_close(struct rfcomm_session *s, int err) | 656 | static struct rfcomm_session *rfcomm_session_close(struct rfcomm_session *s, |
657 | int err) | ||
648 | { | 658 | { |
649 | struct rfcomm_dlc *d; | 659 | struct rfcomm_dlc *d; |
650 | struct list_head *p, *n; | 660 | struct list_head *p, *n; |
651 | 661 | ||
652 | BT_DBG("session %p state %ld err %d", s, s->state, err); | ||
653 | |||
654 | rfcomm_session_hold(s); | ||
655 | |||
656 | s->state = BT_CLOSED; | 662 | s->state = BT_CLOSED; |
657 | 663 | ||
664 | BT_DBG("session %p state %ld err %d", s, s->state, err); | ||
665 | |||
658 | /* Close all dlcs */ | 666 | /* Close all dlcs */ |
659 | list_for_each_safe(p, n, &s->dlcs) { | 667 | list_for_each_safe(p, n, &s->dlcs) { |
660 | d = list_entry(p, struct rfcomm_dlc, list); | 668 | d = list_entry(p, struct rfcomm_dlc, list); |
@@ -663,7 +671,7 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err) | |||
663 | } | 671 | } |
664 | 672 | ||
665 | rfcomm_session_clear_timer(s); | 673 | rfcomm_session_clear_timer(s); |
666 | rfcomm_session_put(s); | 674 | return rfcomm_session_del(s); |
667 | } | 675 | } |
668 | 676 | ||
669 | static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, | 677 | static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, |
@@ -715,8 +723,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, | |||
715 | if (*err == 0 || *err == -EINPROGRESS) | 723 | if (*err == 0 || *err == -EINPROGRESS) |
716 | return s; | 724 | return s; |
717 | 725 | ||
718 | rfcomm_session_del(s); | 726 | return rfcomm_session_del(s); |
719 | return NULL; | ||
720 | 727 | ||
721 | failed: | 728 | failed: |
722 | sock_release(sock); | 729 | sock_release(sock); |
@@ -1105,7 +1112,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) | |||
1105 | } | 1112 | } |
1106 | 1113 | ||
1107 | /* ---- RFCOMM frame reception ---- */ | 1114 | /* ---- RFCOMM frame reception ---- */ |
1108 | static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) | 1115 | static struct rfcomm_session *rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) |
1109 | { | 1116 | { |
1110 | BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); | 1117 | BT_DBG("session %p state %ld dlci %d", s, s->state, dlci); |
1111 | 1118 | ||
@@ -1114,7 +1121,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) | |||
1114 | struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci); | 1121 | struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci); |
1115 | if (!d) { | 1122 | if (!d) { |
1116 | rfcomm_send_dm(s, dlci); | 1123 | rfcomm_send_dm(s, dlci); |
1117 | return 0; | 1124 | return s; |
1118 | } | 1125 | } |
1119 | 1126 | ||
1120 | switch (d->state) { | 1127 | switch (d->state) { |
@@ -1150,25 +1157,14 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) | |||
1150 | break; | 1157 | break; |
1151 | 1158 | ||
1152 | case BT_DISCONN: | 1159 | case BT_DISCONN: |
1153 | /* rfcomm_session_put is called later so don't do | 1160 | s = rfcomm_session_close(s, ECONNRESET); |
1154 | * anything here otherwise we will mess up the session | ||
1155 | * reference counter: | ||
1156 | * | ||
1157 | * (a) when we are the initiator dlc_unlink will drive | ||
1158 | * the reference counter to 0 (there is no initial put | ||
1159 | * after session_add) | ||
1160 | * | ||
1161 | * (b) when we are not the initiator rfcomm_rx_process | ||
1162 | * will explicitly call put to balance the initial hold | ||
1163 | * done after session add. | ||
1164 | */ | ||
1165 | break; | 1161 | break; |
1166 | } | 1162 | } |
1167 | } | 1163 | } |
1168 | return 0; | 1164 | return s; |
1169 | } | 1165 | } |
1170 | 1166 | ||
1171 | static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci) | 1167 | static struct rfcomm_session *rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci) |
1172 | { | 1168 | { |
1173 | int err = 0; | 1169 | int err = 0; |
1174 | 1170 | ||
@@ -1192,13 +1188,13 @@ static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci) | |||
1192 | else | 1188 | else |
1193 | err = ECONNRESET; | 1189 | err = ECONNRESET; |
1194 | 1190 | ||
1195 | s->state = BT_CLOSED; | 1191 | s = rfcomm_session_close(s, err); |
1196 | rfcomm_session_close(s, err); | ||
1197 | } | 1192 | } |
1198 | return 0; | 1193 | return s; |
1199 | } | 1194 | } |
1200 | 1195 | ||
1201 | static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci) | 1196 | static struct rfcomm_session *rfcomm_recv_disc(struct rfcomm_session *s, |
1197 | u8 dlci) | ||
1202 | { | 1198 | { |
1203 | int err = 0; | 1199 | int err = 0; |
1204 | 1200 | ||
@@ -1227,11 +1223,9 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci) | |||
1227 | else | 1223 | else |
1228 | err = ECONNRESET; | 1224 | err = ECONNRESET; |
1229 | 1225 | ||
1230 | s->state = BT_CLOSED; | 1226 | s = rfcomm_session_close(s, err); |
1231 | rfcomm_session_close(s, err); | ||
1232 | } | 1227 | } |
1233 | 1228 | return s; | |
1234 | return 0; | ||
1235 | } | 1229 | } |
1236 | 1230 | ||
1237 | void rfcomm_dlc_accept(struct rfcomm_dlc *d) | 1231 | void rfcomm_dlc_accept(struct rfcomm_dlc *d) |
@@ -1652,11 +1646,18 @@ drop: | |||
1652 | return 0; | 1646 | return 0; |
1653 | } | 1647 | } |
1654 | 1648 | ||
1655 | static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) | 1649 | static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s, |
1650 | struct sk_buff *skb) | ||
1656 | { | 1651 | { |
1657 | struct rfcomm_hdr *hdr = (void *) skb->data; | 1652 | struct rfcomm_hdr *hdr = (void *) skb->data; |
1658 | u8 type, dlci, fcs; | 1653 | u8 type, dlci, fcs; |
1659 | 1654 | ||
1655 | if (!s) { | ||
1656 | /* no session, so free socket data */ | ||
1657 | kfree_skb(skb); | ||
1658 | return s; | ||
1659 | } | ||
1660 | |||
1660 | dlci = __get_dlci(hdr->addr); | 1661 | dlci = __get_dlci(hdr->addr); |
1661 | type = __get_type(hdr->ctrl); | 1662 | type = __get_type(hdr->ctrl); |
1662 | 1663 | ||
@@ -1667,7 +1668,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) | |||
1667 | if (__check_fcs(skb->data, type, fcs)) { | 1668 | if (__check_fcs(skb->data, type, fcs)) { |
1668 | BT_ERR("bad checksum in packet"); | 1669 | BT_ERR("bad checksum in packet"); |
1669 | kfree_skb(skb); | 1670 | kfree_skb(skb); |
1670 | return -EILSEQ; | 1671 | return s; |
1671 | } | 1672 | } |
1672 | 1673 | ||
1673 | if (__test_ea(hdr->len)) | 1674 | if (__test_ea(hdr->len)) |
@@ -1683,22 +1684,23 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) | |||
1683 | 1684 | ||
1684 | case RFCOMM_DISC: | 1685 | case RFCOMM_DISC: |
1685 | if (__test_pf(hdr->ctrl)) | 1686 | if (__test_pf(hdr->ctrl)) |
1686 | rfcomm_recv_disc(s, dlci); | 1687 | s = rfcomm_recv_disc(s, dlci); |
1687 | break; | 1688 | break; |
1688 | 1689 | ||
1689 | case RFCOMM_UA: | 1690 | case RFCOMM_UA: |
1690 | if (__test_pf(hdr->ctrl)) | 1691 | if (__test_pf(hdr->ctrl)) |
1691 | rfcomm_recv_ua(s, dlci); | 1692 | s = rfcomm_recv_ua(s, dlci); |
1692 | break; | 1693 | break; |
1693 | 1694 | ||
1694 | case RFCOMM_DM: | 1695 | case RFCOMM_DM: |
1695 | rfcomm_recv_dm(s, dlci); | 1696 | s = rfcomm_recv_dm(s, dlci); |
1696 | break; | 1697 | break; |
1697 | 1698 | ||
1698 | case RFCOMM_UIH: | 1699 | case RFCOMM_UIH: |
1699 | if (dlci) | 1700 | if (dlci) { |
1700 | return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb); | 1701 | rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb); |
1701 | 1702 | return s; | |
1703 | } | ||
1702 | rfcomm_recv_mcc(s, skb); | 1704 | rfcomm_recv_mcc(s, skb); |
1703 | break; | 1705 | break; |
1704 | 1706 | ||
@@ -1707,7 +1709,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) | |||
1707 | break; | 1709 | break; |
1708 | } | 1710 | } |
1709 | kfree_skb(skb); | 1711 | kfree_skb(skb); |
1710 | return 0; | 1712 | return s; |
1711 | } | 1713 | } |
1712 | 1714 | ||
1713 | /* ---- Connection and data processing ---- */ | 1715 | /* ---- Connection and data processing ---- */ |
@@ -1844,7 +1846,7 @@ static void rfcomm_process_dlcs(struct rfcomm_session *s) | |||
1844 | } | 1846 | } |
1845 | } | 1847 | } |
1846 | 1848 | ||
1847 | static void rfcomm_process_rx(struct rfcomm_session *s) | 1849 | static struct rfcomm_session *rfcomm_process_rx(struct rfcomm_session *s) |
1848 | { | 1850 | { |
1849 | struct socket *sock = s->sock; | 1851 | struct socket *sock = s->sock; |
1850 | struct sock *sk = sock->sk; | 1852 | struct sock *sk = sock->sk; |
@@ -1856,17 +1858,15 @@ static void rfcomm_process_rx(struct rfcomm_session *s) | |||
1856 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { | 1858 | while ((skb = skb_dequeue(&sk->sk_receive_queue))) { |
1857 | skb_orphan(skb); | 1859 | skb_orphan(skb); |
1858 | if (!skb_linearize(skb)) | 1860 | if (!skb_linearize(skb)) |
1859 | rfcomm_recv_frame(s, skb); | 1861 | s = rfcomm_recv_frame(s, skb); |
1860 | else | 1862 | else |
1861 | kfree_skb(skb); | 1863 | kfree_skb(skb); |
1862 | } | 1864 | } |
1863 | 1865 | ||
1864 | if (sk->sk_state == BT_CLOSED) { | 1866 | if (s && (sk->sk_state == BT_CLOSED)) |
1865 | if (!s->initiator) | 1867 | s = rfcomm_session_close(s, sk->sk_err); |
1866 | rfcomm_session_put(s); | ||
1867 | 1868 | ||
1868 | rfcomm_session_close(s, sk->sk_err); | 1869 | return s; |
1869 | } | ||
1870 | } | 1870 | } |
1871 | 1871 | ||
1872 | static void rfcomm_accept_connection(struct rfcomm_session *s) | 1872 | static void rfcomm_accept_connection(struct rfcomm_session *s) |
@@ -1891,8 +1891,6 @@ static void rfcomm_accept_connection(struct rfcomm_session *s) | |||
1891 | 1891 | ||
1892 | s = rfcomm_session_add(nsock, BT_OPEN); | 1892 | s = rfcomm_session_add(nsock, BT_OPEN); |
1893 | if (s) { | 1893 | if (s) { |
1894 | rfcomm_session_hold(s); | ||
1895 | |||
1896 | /* We should adjust MTU on incoming sessions. | 1894 | /* We should adjust MTU on incoming sessions. |
1897 | * L2CAP MTU minus UIH header and FCS. */ | 1895 | * L2CAP MTU minus UIH header and FCS. */ |
1898 | s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu, | 1896 | s->mtu = min(l2cap_pi(nsock->sk)->chan->omtu, |
@@ -1903,7 +1901,7 @@ static void rfcomm_accept_connection(struct rfcomm_session *s) | |||
1903 | sock_release(nsock); | 1901 | sock_release(nsock); |
1904 | } | 1902 | } |
1905 | 1903 | ||
1906 | static void rfcomm_check_connection(struct rfcomm_session *s) | 1904 | static struct rfcomm_session *rfcomm_check_connection(struct rfcomm_session *s) |
1907 | { | 1905 | { |
1908 | struct sock *sk = s->sock->sk; | 1906 | struct sock *sk = s->sock->sk; |
1909 | 1907 | ||
@@ -1921,10 +1919,10 @@ static void rfcomm_check_connection(struct rfcomm_session *s) | |||
1921 | break; | 1919 | break; |
1922 | 1920 | ||
1923 | case BT_CLOSED: | 1921 | case BT_CLOSED: |
1924 | s->state = BT_CLOSED; | 1922 | s = rfcomm_session_close(s, sk->sk_err); |
1925 | rfcomm_session_close(s, sk->sk_err); | ||
1926 | break; | 1923 | break; |
1927 | } | 1924 | } |
1925 | return s; | ||
1928 | } | 1926 | } |
1929 | 1927 | ||
1930 | static void rfcomm_process_sessions(void) | 1928 | static void rfcomm_process_sessions(void) |
@@ -1940,7 +1938,6 @@ static void rfcomm_process_sessions(void) | |||
1940 | if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) { | 1938 | if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) { |
1941 | s->state = BT_DISCONN; | 1939 | s->state = BT_DISCONN; |
1942 | rfcomm_send_disc(s, 0); | 1940 | rfcomm_send_disc(s, 0); |
1943 | rfcomm_session_put(s); | ||
1944 | continue; | 1941 | continue; |
1945 | } | 1942 | } |
1946 | 1943 | ||
@@ -1949,21 +1946,18 @@ static void rfcomm_process_sessions(void) | |||
1949 | continue; | 1946 | continue; |
1950 | } | 1947 | } |
1951 | 1948 | ||
1952 | rfcomm_session_hold(s); | ||
1953 | |||
1954 | switch (s->state) { | 1949 | switch (s->state) { |
1955 | case BT_BOUND: | 1950 | case BT_BOUND: |
1956 | rfcomm_check_connection(s); | 1951 | s = rfcomm_check_connection(s); |
1957 | break; | 1952 | break; |
1958 | 1953 | ||
1959 | default: | 1954 | default: |
1960 | rfcomm_process_rx(s); | 1955 | s = rfcomm_process_rx(s); |
1961 | break; | 1956 | break; |
1962 | } | 1957 | } |
1963 | 1958 | ||
1964 | rfcomm_process_dlcs(s); | 1959 | if (s) |
1965 | 1960 | rfcomm_process_dlcs(s); | |
1966 | rfcomm_session_put(s); | ||
1967 | } | 1961 | } |
1968 | 1962 | ||
1969 | rfcomm_unlock(); | 1963 | rfcomm_unlock(); |
@@ -2010,10 +2004,11 @@ static int rfcomm_add_listener(bdaddr_t *ba) | |||
2010 | 2004 | ||
2011 | /* Add listening session */ | 2005 | /* Add listening session */ |
2012 | s = rfcomm_session_add(sock, BT_LISTEN); | 2006 | s = rfcomm_session_add(sock, BT_LISTEN); |
2013 | if (!s) | 2007 | if (!s) { |
2008 | err = -ENOMEM; | ||
2014 | goto failed; | 2009 | goto failed; |
2010 | } | ||
2015 | 2011 | ||
2016 | rfcomm_session_hold(s); | ||
2017 | return 0; | 2012 | return 0; |
2018 | failed: | 2013 | failed: |
2019 | sock_release(sock); | 2014 | sock_release(sock); |
@@ -2071,8 +2066,6 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) | |||
2071 | if (!s) | 2066 | if (!s) |
2072 | return; | 2067 | return; |
2073 | 2068 | ||
2074 | rfcomm_session_hold(s); | ||
2075 | |||
2076 | list_for_each_safe(p, n, &s->dlcs) { | 2069 | list_for_each_safe(p, n, &s->dlcs) { |
2077 | d = list_entry(p, struct rfcomm_dlc, list); | 2070 | d = list_entry(p, struct rfcomm_dlc, list); |
2078 | 2071 | ||
@@ -2104,8 +2097,6 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) | |||
2104 | set_bit(RFCOMM_AUTH_REJECT, &d->flags); | 2097 | set_bit(RFCOMM_AUTH_REJECT, &d->flags); |
2105 | } | 2098 | } |
2106 | 2099 | ||
2107 | rfcomm_session_put(s); | ||
2108 | |||
2109 | rfcomm_schedule(); | 2100 | rfcomm_schedule(); |
2110 | } | 2101 | } |
2111 | 2102 | ||