rfcomm disconnection and session refcount
Subsystems (2)
PATCH 1/1 rfcomm disconnection and session refcount
Hi Marcel,
I made two patches that solves two issues in rfcomm. Comments are in patches that I'll send as reply to this mail.
Signature · 1 line
Ville
PATCH 1/2 Check that device is in rfcomm_dev_list before deleting
If RFCOMM_RELEASE_ONHUP flag is on and rfcomm_release_dev is called before connection is closed rfcomm_dev is deleted twice from the rfcomm_dev_list list and refcount is messed up. This patch add check before deleting device that the device actually is listed.
Signed-off-by Ville Tervo <[email protected]>
--- net/bluetooth/rfcomm/tty.c | 11 ++++++++--- 1 files changed, 8 insertions(+), 3 deletions(-)
net/bluetooth/rfcomm/tty.c +8 -3
@@ -517,9 +517,10 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)if (dlc->state ==BT_CLOSED ) {if (!dev->tty) {if (test_bit (RFCOMM_RELEASE_ONHUP , &dev->flags)) { -rfcomm_dev_hold (dev); -rfcomm_dev_del (dev); +if (rfcomm_dev_get (dev->id) ==NULL ) +return ; +rfcomm_dev_del (dev);/* We have to drop DLC lock here, otherwise rfcomm_dev_put() will dead lock if it's the last reference. */
@@ -974,8 +975,12 @@ static void rfcomm_tty_hangup(struct tty_struct *tty)rfcomm_tty_flush_buffer (tty); -if (test_bit (RFCOMM_RELEASE_ONHUP , &dev->flags)) +if (test_bit (RFCOMM_RELEASE_ONHUP , &dev->flags)) { +if (rfcomm_dev_get (dev->id) ==NULL ) +return ;rfcomm_dev_del (dev); +rfcomm_dev_put (dev); + } }static int rfcomm_tty_read_proc (char *buf,char **start,off_t offset,int len,int *eof,void *unused)
Signature · 1 line
1.5.1.1
PATCH 2/2 Disconnect l2cap connection after last dlc
Rfcomm spec says that the device closing the last connection (DLC) on a particular session is responsible for closing the multiplexer by closing the corresponding L2CAP channel.
Signed-off-by Ville Tervo <[email protected]>
--- net/bluetooth/rfcomm/core.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
net/bluetooth/rfcomm/core.c +9 -0
@@ -1058,6 +1058,12 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)case BT_DISCONN : d->state =BT_CLOSED ;__rfcomm_dlc_close (d,0 ); + +if (list_empty (&s->dlcs)) { + s->state =BT_DISCONN ; +rfcomm_send_disc (s,0 ); + } +break ; } }else {
@@ -1067,6 +1073,9 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) s->state =BT_CONNECTED ;rfcomm_process_connect (s);break ; +case BT_DISCONN : +rfcomm_session_put (s); +break ; } }return 0 ;
Signature · 1 line
1.5.1.1