aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/bluetooth/rfcomm/tty.c46
1 files changed, 12 insertions, 34 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 583f7135c811..3e078b73cc22 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -324,23 +324,6 @@ free:
324 return err; 324 return err;
325} 325}
326 326
327static void rfcomm_dev_del(struct rfcomm_dev *dev)
328{
329 unsigned long flags;
330 BT_DBG("dev %p", dev);
331
332 BUG_ON(test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags));
333
334 spin_lock_irqsave(&dev->port.lock, flags);
335 if (dev->port.count > 0) {
336 spin_unlock_irqrestore(&dev->port.lock, flags);
337 return;
338 }
339 spin_unlock_irqrestore(&dev->port.lock, flags);
340
341 tty_port_put(&dev->port);
342}
343
344/* ---- Send buffer ---- */ 327/* ---- Send buffer ---- */
345static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc) 328static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
346{ 329{
@@ -454,8 +437,9 @@ static int rfcomm_release_dev(void __user *arg)
454 tty_kref_put(tty); 437 tty_kref_put(tty);
455 } 438 }
456 439
457 if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) 440 if (!test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags))
458 rfcomm_dev_del(dev); 441 tty_port_put(&dev->port);
442
459 tty_port_put(&dev->port); 443 tty_port_put(&dev->port);
460 return 0; 444 return 0;
461} 445}
@@ -607,6 +591,9 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
607 * rfcomm_dev_lock -> dlc lock 591 * rfcomm_dev_lock -> dlc lock
608 * 2. tty_port_put will deadlock if it's 592 * 2. tty_port_put will deadlock if it's
609 * the last reference 593 * the last reference
594 *
595 * FIXME: when we release the lock anything
596 * could happen to dev, even its destruction
610 */ 597 */
611 rfcomm_dlc_unlock(dlc); 598 rfcomm_dlc_unlock(dlc);
612 if (rfcomm_dev_get(dev->id) == NULL) { 599 if (rfcomm_dev_get(dev->id) == NULL) {
@@ -614,7 +601,10 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
614 return; 601 return;
615 } 602 }
616 603
617 rfcomm_dev_del(dev); 604 if (!test_and_set_bit(RFCOMM_TTY_RELEASED,
605 &dev->flags))
606 tty_port_put(&dev->port);
607
618 tty_port_put(&dev->port); 608 tty_port_put(&dev->port);
619 rfcomm_dlc_lock(dlc); 609 rfcomm_dlc_lock(dlc);
620 } 610 }
@@ -741,16 +731,10 @@ static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
741{ 731{
742 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 732 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
743 733
744 if (!dev)
745 return;
746
747 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, 734 BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc,
748 dev->port.count); 735 dev->port.count);
749 736
750 tty_port_close(&dev->port, tty, filp); 737 tty_port_close(&dev->port, tty, filp);
751
752 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
753 tty_port_put(&dev->port);
754} 738}
755 739
756static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) 740static int rfcomm_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1050,17 +1034,11 @@ static void rfcomm_tty_hangup(struct tty_struct *tty)
1050 1034
1051 BT_DBG("tty %p dev %p", tty, dev); 1035 BT_DBG("tty %p dev %p", tty, dev);
1052 1036
1053 if (!dev)
1054 return;
1055
1056 tty_port_hangup(&dev->port); 1037 tty_port_hangup(&dev->port);
1057 1038
1058 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) { 1039 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) &&
1059 if (rfcomm_dev_get(dev->id) == NULL) 1040 !test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags))
1060 return;
1061 rfcomm_dev_del(dev);
1062 tty_port_put(&dev->port); 1041 tty_port_put(&dev->port);
1063 }
1064} 1042}
1065 1043
1066static int rfcomm_tty_tiocmget(struct tty_struct *tty) 1044static int rfcomm_tty_tiocmget(struct tty_struct *tty)