[Bluetooth] Store remote modem status for RFCOMM TTY
[pandora-kernel.git] / net / bluetooth / rfcomm / tty.c
index e4c779b..8fcca08 100644 (file)
@@ -271,6 +271,9 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 
        dlc->owner = dev;
        dev->dlc   = dlc;
+
+       rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig);
+
        rfcomm_dlc_unlock(dlc);
 
        /* It's safe to call __module_get() here because socket already
@@ -566,14 +569,20 @@ 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)) {
-                               if (rfcomm_dev_get(dev->id) == NULL)
+                               /* Drop DLC lock here to avoid deadlock
+                                * 1. rfcomm_dev_get will take rfcomm_dev_lock
+                                *    but in rfcomm_dev_add there's lock order:
+                                *    rfcomm_dev_lock -> dlc lock
+                                * 2. rfcomm_dev_put will deadlock if it's
+                                *    the last reference
+                                */
+                               rfcomm_dlc_unlock(dlc);
+                               if (rfcomm_dev_get(dev->id) == NULL) {
+                                       rfcomm_dlc_lock(dlc);
                                        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. */
-                               rfcomm_dlc_unlock(dlc);
                                rfcomm_dev_put(dev);
                                rfcomm_dlc_lock(dlc);
                        }
@@ -1117,6 +1126,7 @@ int rfcomm_init_ttys(void)
        rfcomm_tty_driver->flags        = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        rfcomm_tty_driver->init_termios = tty_std_termios;
        rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+       rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
        tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
 
        if (tty_register_driver(rfcomm_tty_driver)) {