From: Peter Hurley <peter@hurleysoftware.com>
To: Marcel Holtmann <marcel@holtmann.org>
Cc: Gustavo Padovan <gustavo@padovan.org>,
Johan Hedberg <johan.hedberg@gmail.com>,
Gianluca Anzolin <gianluca@sottospazio.it>,
Alexander Holler <holler@ahsoftware.de>,
Andrey Vihrov <andrey.vihrov@gmail.com>,
Sander Eikelenboom <linux@eikelenboom.it>,
linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org,
Peter Hurley <peter@hurleysoftware.com>
Subject: [PATCH 02/24] Revert "Bluetooth: Always wait for a connection on RFCOMM open()"
Date: Sun, 9 Feb 2014 20:59:02 -0500 [thread overview]
Message-ID: <1391997564-1805-3-git-send-email-peter@hurleysoftware.com> (raw)
In-Reply-To: <1391997564-1805-1-git-send-email-peter@hurleysoftware.com>
This reverts commit 4a2fb3ecc7467c775b154813861f25a0ddc11aa0.
This is the second of a 3-patch revert, together with
Revert "Bluetooth: Remove rfcomm_carrier_raised()" and
Revert "Bluetooth: Move rfcomm_get_device() before rfcomm_dev_activate()".
Before commit cad348a17e170451ea8688b532a6ca3e98c63b60,
Bluetooth: Implement .activate, .shutdown and .carrier_raised methods,
tty_port_block_til_ready() was open-coded in rfcomm_tty_install() as
part of the RFCOMM tty open().
Unfortunately, it did not implement non-blocking open nor CLOCAL open,
but rather always blocked for carrier. This is not the expected or
typical behavior for ttys, and prevents several common terminal
programming idioms from working (eg., opening in non-blocking
mode to initialize desired termios settings then re-opening for
connection).
Commit cad348a17e170451ea8688b532a6ca3e98c63b60,
Bluetooth: Implement .activate, .shutdown and .carrier_raised methods,
added the necessary tty_port methods to use the default tty_port_open().
However, this triggered two important user-space regressions.
The first regression involves the complicated mechanism for reparenting
the rfcomm tty device to the ACL link device which represents an
open link to a specific bluetooth host. This regression causes ModemManager
to conclude the rfcomm tty device does not front a modem so it makes
no attempt to initialize an attached modem. This regression is
caused by the lack of a device_move() if the dlc is already open (and
not specifically related to the open-coded block_til_ready()).
A more appropriate solution is submitted in
"Bluetooth: Fix unsafe RFCOMM device parenting" and
"Bluetooth: Fix RFCOMM parent device for reused dlc"
The second regression involves "rfcomm bind" and wvdial (a ppp dialer).
rfcomm bind creates a device node for a /dev/rfcomm<n>. wvdial opens
that device in non-blocking mode (because it expects the connection
to have already been established). In addition, subsequent writes
to the rfcomm tty device fail (because the link is not yet connected;
rfcomm connection begins with the actual tty open()).
However, restoring the original behavior (in the patch which
this reverts) was undesirable.
Firstly, the original reporter notes that a trivial userspace
"workaround" already exists: rfcomm connect, which creates the
device node and establishes the expected connection.
Secondly, the failed writes occur because the rfcomm tty driver
does not buffer writes to an unconnected device; this contrasts with
the dozen of other tty drivers (in fact, all of them) that do just
that. The submitted patch "Bluetooth: Don't fail RFCOMM tty writes"
corrects this.
Thirdly, it was a long-standing bug to block on non-blocking open,
which is re-fixed by revert.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
---
net/bluetooth/rfcomm/tty.c | 46 ++++++++--------------------------------------
1 file changed, 8 insertions(+), 38 deletions(-)
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index aeabade..32ef9f9 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -58,7 +58,6 @@ struct rfcomm_dev {
uint modem_status;
struct rfcomm_dlc *dlc;
- wait_queue_head_t conn_wait;
struct device *tty_dev;
@@ -124,40 +123,8 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty)
{
struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
- DEFINE_WAIT(wait);
- int err;
-
- err = rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel);
- if (err)
- return err;
-
- while (1) {
- prepare_to_wait(&dev->conn_wait, &wait, TASK_INTERRUPTIBLE);
- if (dev->dlc->state == BT_CLOSED) {
- err = -dev->err;
- break;
- }
-
- if (dev->dlc->state == BT_CONNECTED)
- break;
-
- if (signal_pending(current)) {
- err = -ERESTARTSYS;
- break;
- }
-
- tty_unlock(tty);
- schedule();
- tty_lock(tty);
- }
- finish_wait(&dev->conn_wait, &wait);
-
- if (!err)
- device_move(dev->tty_dev, rfcomm_get_device(dev),
- DPM_ORDER_DEV_AFTER_PARENT);
-
- return err;
+ return rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel);
}
/* we block the open until the dlc->state becomes BT_CONNECTED */
@@ -184,6 +151,7 @@ static const struct tty_port_operations rfcomm_port_ops = {
.destruct = rfcomm_dev_destruct,
.activate = rfcomm_dev_activate,
.shutdown = rfcomm_dev_shutdown,
+ .carrier_raised = rfcomm_dev_carrier_raised,
};
static struct rfcomm_dev *__rfcomm_dev_get(int id)
@@ -290,7 +258,6 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
tty_port_init(&dev->port);
dev->port.ops = &rfcomm_port_ops;
- init_waitqueue_head(&dev->conn_wait);
skb_queue_head_init(&dev->pending);
@@ -609,9 +576,12 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
dev->err = err;
- wake_up_interruptible(&dev->conn_wait);
+ if (dlc->state == BT_CONNECTED) {
+ device_move(dev->tty_dev, rfcomm_get_device(dev),
+ DPM_ORDER_DEV_AFTER_PARENT);
- if (dlc->state == BT_CLOSED)
+ wake_up_interruptible(&dev->port.open_wait);
+ } else if (dlc->state == BT_CLOSED)
tty_port_tty_hangup(&dev->port, false);
}
@@ -1133,7 +1103,7 @@ int __init rfcomm_init_ttys(void)
rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
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_cflag = B9600 | CS8 | CREAD | HUPCL;
rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
--
1.8.1.2
next prev parent reply other threads:[~2014-02-10 2:20 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-10 1:59 [PATCH 00/24] rfcomm fixes Peter Hurley
2014-02-10 1:59 ` [PATCH 01/24] Revert "Bluetooth: Remove rfcomm_carrier_raised()" Peter Hurley
2014-02-10 1:59 ` Peter Hurley [this message]
2014-02-10 1:59 ` [PATCH 03/24] Revert "Bluetooth: Move rfcomm_get_device() before rfcomm_dev_activate()" Peter Hurley
2014-02-10 1:59 ` [PATCH 04/24] tty: Fix ref counting for port krefs Peter Hurley
2014-02-13 18:36 ` Greg Kroah-Hartman
2014-02-10 1:59 ` [PATCH 05/24] Bluetooth: Fix racy acquire of rfcomm_dev reference Peter Hurley
2014-02-10 1:59 ` [PATCH 06/24] Bluetooth: Exclude released devices from RFCOMMGETDEVLIST ioctl Peter Hurley
2014-02-10 1:59 ` [PATCH 07/24] Bluetooth: Release rfcomm_dev only once Peter Hurley
2014-02-10 1:59 ` [PATCH 08/24] Bluetooth: Fix unreleased rfcomm_dev reference Peter Hurley
2014-02-10 1:59 ` [PATCH 09/24] Bluetooth: Fix RFCOMM tty teardown race Peter Hurley
2014-02-10 1:59 ` [PATCH 10/24] Bluetooth: Verify dlci not in use before rfcomm_dev create Peter Hurley
2014-02-10 1:59 ` [PATCH 11/24] Bluetooth: Simplify RFCOMM session state eval Peter Hurley
2014-02-10 1:59 ` [PATCH 12/24] Bluetooth: Refactor deferred setup test in rfcomm_dlc_close() Peter Hurley
2014-02-10 1:59 ` [PATCH 13/24] Bluetooth: Refactor dlc disconnect logic " Peter Hurley
2014-02-10 1:59 ` [PATCH 14/24] Bluetooth: Directly close dlc for not yet started RFCOMM session Peter Hurley
2014-02-10 1:59 ` [PATCH 15/24] Bluetooth: Fix unsafe RFCOMM device parenting Peter Hurley
2014-02-10 1:59 ` [PATCH 16/24] Bluetooth: Fix RFCOMM parent device for reused dlc Peter Hurley
2014-02-10 1:59 ` [PATCH 17/24] Bluetooth: Rename __rfcomm_dev_get() to __rfcomm_dev_lookup() Peter Hurley
2014-02-10 1:59 ` [PATCH 18/24] Bluetooth: Serialize RFCOMMCREATEDEV and RFCOMMRELEASEDEV ioctls Peter Hurley
2014-02-10 1:59 ` [PATCH 19/24] Bluetooth: Refactor rfcomm_dev_add() Peter Hurley
2014-02-10 1:59 ` [PATCH 20/24] Bluetooth: Cleanup RFCOMM device registration error handling Peter Hurley
2014-02-10 1:59 ` [PATCH 21/24] Bluetooth: Force -EIO from tty read/write if .activate() fails Peter Hurley
2014-02-10 1:59 ` [PATCH 22/24] Bluetooth: Don't fail RFCOMM tty writes Peter Hurley
2014-02-10 1:59 ` [PATCH 23/24] Bluetooth: Refactor write_room() calculation Peter Hurley
2014-02-10 1:59 ` [PATCH 24/24] Bluetooth: Fix " Peter Hurley
2014-02-10 22:09 ` [PATCH 00/24] rfcomm fixes Marcel Holtmann
2014-02-10 23:00 ` Peter Hurley
2014-02-12 22:58 ` Marcel Holtmann
2014-02-13 0:38 ` Peter Hurley
2014-02-13 21:48 ` Alexander Holler
2014-02-12 11:06 ` Sander Eikelenboom
2014-03-03 19:38 ` Sander Eikelenboom
2014-03-10 8:38 ` [RC6 Bell Chime] " Sander Eikelenboom
2014-03-10 15:08 ` John W. Linville
2014-03-11 15:14 ` [RC6 Bell Chime] " Marcel Holtmann
2014-03-14 0:49 ` Sander Eikelenboom
2014-03-14 1:28 ` Marcel Holtmann
2014-03-14 1:29 ` Peter Hurley
2014-03-15 13:51 ` Sander Eikelenboom
2014-03-15 17:53 ` Linus Torvalds
2014-03-15 20:45 ` Peter Hurley
2014-03-15 22:20 ` Sander Eikelenboom
2014-03-16 0:16 ` Linus Torvalds
2014-02-13 21:41 ` Alexander Holler
2014-02-14 21:45 ` Marcel Holtmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1391997564-1805-3-git-send-email-peter@hurleysoftware.com \
--to=peter@hurleysoftware.com \
--cc=andrey.vihrov@gmail.com \
--cc=gianluca@sottospazio.it \
--cc=gustavo@padovan.org \
--cc=holler@ahsoftware.de \
--cc=johan.hedberg@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@eikelenboom.it \
--cc=marcel@holtmann.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox