--- a/net/bluetooth/rfcomm/tty.c 2014-01-17 14:08:15.360264074 -0500 +++ b/net/bluetooth/rfcomm/tty.c 2014-01-17 14:14:53.440265440 -0500 @@ -437,7 +437,8 @@ static int rfcomm_release_dev(void __use tty_kref_put(tty); } - if (!test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)) + if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) && + !test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)) tty_port_put(&dev->port); tty_port_put(&dev->port); @@ -670,10 +671,21 @@ static int rfcomm_tty_install(struct tty /* install the tty_port */ err = tty_port_install(&dev->port, driver, tty); - if (err) + if (err) { rfcomm_tty_cleanup(tty); + return err; + } + + /* take over the tty_port reference if the port was created with the + * flag RFCOMM_RELEASE_ONHUP. This will force the release of the port + * when the last process closes the tty. The behaviour is expected by + * userspace. + */ + if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) + tty_port_put(&dev->port); + + return 0; - return err; } static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) @@ -1010,10 +1022,6 @@ static void rfcomm_tty_hangup(struct tty BT_DBG("tty %p dev %p", tty, dev); tty_port_hangup(&dev->port); - - if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) && - !test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags)) - tty_port_put(&dev->port); } static int rfcomm_tty_tiocmget(struct tty_struct *tty)