aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorGianluca Anzolin <gianluca@sottospazio.it>2014-01-06 15:23:52 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-01-06 16:51:45 -0500
commit4a2fb3ecc7467c775b154813861f25a0ddc11aa0 (patch)
tree7673d900599d3fe9c053483d58e171d20aa55e69 /net/bluetooth
parente228b63390536f5b737056059a9a04ea016b1abf (diff)
Bluetooth: Always wait for a connection on RFCOMM open()
This patch fixes two regressions introduced with the recent rfcomm tty rework. The current code uses the carrier_raised() method to wait for the bluetooth connection when a process opens the tty. However processes may open the port with the O_NONBLOCK flag or set the CLOCAL termios flag: in these cases the open() syscall returns immediately without waiting for the bluetooth connection to complete. This behaviour confuses userspace which expects an established bluetooth connection. The patch restores the old behaviour by waiting for the connection in rfcomm_dev_activate() and removes carrier_raised() from the tty_port ops. As a side effect the new code also fixes the case in which the rfcomm tty device is created with the flag RFCOMM_REUSE_DLC: the old code didn't call device_move() and ModemManager skipped the detection probe. Now device_move() is always called inside rfcomm_dev_activate(). Signed-off-by: Gianluca Anzolin <gianluca@sottospazio.it> Reported-by: Andrey Vihrov <andrey.vihrov@gmail.com> Reported-by: Beson Chow <blc+bluez@mail.vanade.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/rfcomm/tty.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 32ef9f91965c..aeabadeef82b 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -58,6 +58,7 @@ struct rfcomm_dev {
58 uint modem_status; 58 uint modem_status;
59 59
60 struct rfcomm_dlc *dlc; 60 struct rfcomm_dlc *dlc;
61 wait_queue_head_t conn_wait;
61 62
62 struct device *tty_dev; 63 struct device *tty_dev;
63 64
@@ -123,8 +124,40 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
123static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty) 124static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty)
124{ 125{
125 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port); 126 struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
127 DEFINE_WAIT(wait);
128 int err;
129
130 err = rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel);
131 if (err)
132 return err;
133
134 while (1) {
135 prepare_to_wait(&dev->conn_wait, &wait, TASK_INTERRUPTIBLE);
126 136
127 return rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel); 137 if (dev->dlc->state == BT_CLOSED) {
138 err = -dev->err;
139 break;
140 }
141
142 if (dev->dlc->state == BT_CONNECTED)
143 break;
144
145 if (signal_pending(current)) {
146 err = -ERESTARTSYS;
147 break;
148 }
149
150 tty_unlock(tty);
151 schedule();
152 tty_lock(tty);
153 }
154 finish_wait(&dev->conn_wait, &wait);
155
156 if (!err)
157 device_move(dev->tty_dev, rfcomm_get_device(dev),
158 DPM_ORDER_DEV_AFTER_PARENT);
159
160 return err;
128} 161}
129 162
130/* we block the open until the dlc->state becomes BT_CONNECTED */ 163/* we block the open until the dlc->state becomes BT_CONNECTED */
@@ -151,7 +184,6 @@ static const struct tty_port_operations rfcomm_port_ops = {
151 .destruct = rfcomm_dev_destruct, 184 .destruct = rfcomm_dev_destruct,
152 .activate = rfcomm_dev_activate, 185 .activate = rfcomm_dev_activate,
153 .shutdown = rfcomm_dev_shutdown, 186 .shutdown = rfcomm_dev_shutdown,
154 .carrier_raised = rfcomm_dev_carrier_raised,
155}; 187};
156 188
157static struct rfcomm_dev *__rfcomm_dev_get(int id) 189static struct rfcomm_dev *__rfcomm_dev_get(int id)
@@ -258,6 +290,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
258 290
259 tty_port_init(&dev->port); 291 tty_port_init(&dev->port);
260 dev->port.ops = &rfcomm_port_ops; 292 dev->port.ops = &rfcomm_port_ops;
293 init_waitqueue_head(&dev->conn_wait);
261 294
262 skb_queue_head_init(&dev->pending); 295 skb_queue_head_init(&dev->pending);
263 296
@@ -576,12 +609,9 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
576 BT_DBG("dlc %p dev %p err %d", dlc, dev, err); 609 BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
577 610
578 dev->err = err; 611 dev->err = err;
579 if (dlc->state == BT_CONNECTED) { 612 wake_up_interruptible(&dev->conn_wait);
580 device_move(dev->tty_dev, rfcomm_get_device(dev),
581 DPM_ORDER_DEV_AFTER_PARENT);
582 613
583 wake_up_interruptible(&dev->port.open_wait); 614 if (dlc->state == BT_CLOSED)
584 } else if (dlc->state == BT_CLOSED)
585 tty_port_tty_hangup(&dev->port, false); 615 tty_port_tty_hangup(&dev->port, false);
586} 616}
587 617
@@ -1103,7 +1133,7 @@ int __init rfcomm_init_ttys(void)
1103 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL; 1133 rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
1104 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 1134 rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
1105 rfcomm_tty_driver->init_termios = tty_std_termios; 1135 rfcomm_tty_driver->init_termios = tty_std_termios;
1106 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; 1136 rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1107 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; 1137 rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
1108 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); 1138 tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
1109 1139