1. 14 Feb, 2014 14 commits
    • Peter Hurley's avatar
      Bluetooth: Refactor dlc disconnect logic in rfcomm_dlc_close() · f622357a
      Peter Hurley authored
      Prepare for directly closing dlc if the RFCOMM session has not
      yet been started; refactor the dlc disconnect logic into a separate
      local function, __rfcomm_dlc_disconn(). Retains functional
      equivalence.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      f622357a
    • Peter Hurley's avatar
      Bluetooth: Refactor deferred setup test in rfcomm_dlc_close() · 5998e040
      Peter Hurley authored
      Prepare for directly closing dlc if the RFCOMM session has not
      yet been started; refactor the deferred setup test for only those
      dlc states to which the test applies. Retains functional
      equivalence.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      5998e040
    • Peter Hurley's avatar
      Bluetooth: Simplify RFCOMM session state eval · 4339c25a
      Peter Hurley authored
      Merge conditional test for BT_LISTEN session state into following
      switch statement (which is functionally equivalent).
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      4339c25a
    • Peter Hurley's avatar
      Bluetooth: Verify dlci not in use before rfcomm_dev create · c10a848c
      Peter Hurley authored
      Only one session/channel combination may be in use at any one
      time. However, the failure does not occur until the tty is
      opened (in rfcomm_dlc_open()).
      
      Because these settings are actually bound at rfcomm device
      creation (via RFCOMMCREATEDEV ioctl), validate and fail before
      creating the rfcomm tty device.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      c10a848c
    • Peter Hurley's avatar
      Bluetooth: Fix RFCOMM tty teardown race · c949c224
      Peter Hurley authored
      RFCOMM tty device teardown can race with new tty device registration
      for the same device id:
      
      CPU 0                           | CPU 1
      rfcomm_dev_add                  | rfcomm_dev_destruct
                                      |   spin_lock
                                      |   list_del   <== dev_id no longer used
                                      |   spin_unlock
        spin_lock                     |     .
        [search rfcomm_dev_list]      |     .
        [dev_id not in use]           |     .
        [initialize new rfcomm_dev]   |     .
        spin_unlock                   |     .
                                      |     .
        tty_port_register_device      |   tty_unregister_device
      
      Don't remove rfcomm_dev from the device list until after tty device
      unregistration has completed.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      c949c224
    • Peter Hurley's avatar
      Bluetooth: Fix unreleased rfcomm_dev reference · 80ea7337
      Peter Hurley authored
      When RFCOMM_RELEASE_ONHUP is set, the rfcomm tty driver 'takes over'
      the initial rfcomm_dev reference created by the RFCOMMCREATEDEV ioctl.
      The assumption is that the rfcomm tty driver will release the
      rfcomm_dev reference when the tty is freed (in rfcomm_tty_cleanup()).
      However, if the tty is never opened, the 'take over' never occurs,
      so when RFCOMMRELEASEDEV ioctl is called, the reference is not
      released.
      
      Track the state of the reference 'take over' so that the release
      is guaranteed by either the RFCOMMRELEASEDEV ioctl or the rfcomm tty
      driver.
      
      Note that the synchronous hangup in rfcomm_release_dev() ensures
      that rfcomm_tty_install() cannot race with the RFCOMMRELEASEDEV ioctl.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      80ea7337
    • Peter Hurley's avatar
      Bluetooth: Release rfcomm_dev only once · 1c64834e
      Peter Hurley authored
      No logic prevents an rfcomm_dev from being released multiple
      times. For example, if the rfcomm_dev ref count is large due
      to pending tx, then multiple RFCOMMRELEASEDEV ioctls may
      mistakenly release the rfcomm_dev too many times. Note that
      concurrent ioctls are not required to create this condition.
      
      Introduce RFCOMM_DEV_RELEASED status bit which guarantees the
      rfcomm_dev can only be released once.
      
      NB: Since the flags are exported to userspace, introduce the status
      field to track state for which userspace should not be aware.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      1c64834e
    • Peter Hurley's avatar
      Bluetooth: Exclude released devices from RFCOMMGETDEVLIST ioctl · 960603a5
      Peter Hurley authored
      When enumerating RFCOMM devices in the rfcomm_dev_list, holding
      the rfcomm_dev_lock only guarantees the existence of the enumerated
      rfcomm_dev in memory, and not safe access to its state. Testing
      the device state (such as RFCOMM_TTY_RELEASED) does not guarantee
      the device will remain in that state for the subsequent access
      to the rfcomm_dev's fields, nor guarantee that teardown has not
      commenced.
      
      Obtain an rfcomm_dev reference for the duration of rfcomm_dev
      access.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      960603a5
    • Peter Hurley's avatar
      Bluetooth: Fix racy acquire of rfcomm_dev reference · 082a1532
      Peter Hurley authored
      rfcomm_dev_get() can return a rfcomm_dev reference for a
      device for which destruction may be commencing. This can happen
      on tty destruction, which calls rfcomm_tty_cleanup(), the last
      port reference may have been released but RFCOMM_TTY_RELEASED
      was not set. The following race is also possible:
      
      CPU 0                            | CPU 1
                                       | rfcomm_release_dev
      rfcomm_dev_get                   |   .
        spin_lock                      |   .
          dev  = __rfcomm_dev_get      |   .
          if dev                       |   .
            if test_bit(TTY_RELEASED)  |   .
                                       |   !test_and_set_bit(TTY_RELEASED)
                                       |     tty_port_put   <<<< last reference
            else                       |
              tty_port_get             |
      
      The reference acquire is bogus because destruction will commence
      with the release of the last reference.
      
      Ignore the external state change of TTY_RELEASED and instead rely
      on the reference acquire itself to determine if the reference is
      valid.
      
      Cc: Jiri Slaby <jslaby@suse.cz>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      082a1532
    • Peter Hurley's avatar
      tty: Fix ref counting for port krefs · c0fdfb80
      Peter Hurley authored
      The tty core supports two models for handling tty_port lifetimes;
      the tty_port can use the kref supplied by tty_port (which will
      automatically destruct the tty_port when the ref count drops to
      zero) or it can destruct the tty_port manually.
      
      For tty drivers that choose to use the port kref to manage the
      tty_port lifetime, it is not possible to safely acquire a port
      reference conditionally. If the last reference is released after
      evaluating the condition but before acquiring the reference, a
      bogus reference will be held while the tty_port destruction
      commences.
      
      Rather, only acquire a port reference if the ref count is non-zero
      and allow the caller to distinguish if a reference has successfully
      been acquired.
      
      Cc: Jiri Slaby <jslaby@suse.cz>
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      c0fdfb80
    • Peter Hurley's avatar
      Revert "Bluetooth: Move rfcomm_get_device() before rfcomm_dev_activate()" · f87c24e7
      Peter Hurley authored
      This reverts commit e228b633.
      
      This is the third of a 3-patch revert, together with
      Revert "Bluetooth: Remove rfcomm_carrier_raised()" and
      Revert "Bluetooth: Always wait for a connection on RFCOMM open()".
      
      Commit 4a2fb3ec,
      "Bluetooth: Always wait for a connection on RFCOMM open()" open-codes
      blocking on tty open(), rather than using the default behavior
      implemented by the tty port.
      
      The reasons for reverting that patch are detailed in that changelog;
      this patch restores required functionality for that revert.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      f87c24e7
    • Peter Hurley's avatar
      Revert "Bluetooth: Always wait for a connection on RFCOMM open()" · 136c373b
      Peter Hurley authored
      This reverts commit 4a2fb3ec.
      
      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 cad348a1,
        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 cad348a1,
        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: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      136c373b
    • Peter Hurley's avatar
      Revert "Bluetooth: Remove rfcomm_carrier_raised()" · 7f717b91
      Peter Hurley authored
      This reverts commit f86772af.
      
      This is the first of a 3-patch revert, together with
      Revert "Bluetooth: Always wait for a connection on RFCOMM open()" and
      Revert "Bluetooth: Move rfcomm_get_device() before rfcomm_dev_activate()".
      
      Commit 4a2fb3ec,
      "Bluetooth: Always wait for a connection on RFCOMM open()" open-codes
      blocking on tty open(), rather than using the default behavior
      implemented by the tty port.
      
      The reasons for reverting that patch are detailed in that changelog;
      this patch restores required functionality for that revert.
      Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
      Tested-By: default avatarAlexander Holler <holler@ahsoftware.de>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      7f717b91
    • Johan Hedberg's avatar
      Bluetooth: Enable LE L2CAP CoC support by default · 9b7655ea
      Johan Hedberg authored
      Now that the LE L2CAP Connection Oriented Channel support has undergone a
      decent amount of testing we can make it officially supported. This patch
      removes the enable_lecoc module parameter which was previously needed to
      enable support for LE L2CAP CoC.
      Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
      Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      9b7655ea
  2. 13 Feb, 2014 26 commits