1. 17 Apr, 2013 11 commits
    • David Herrmann's avatar
      Bluetooth: hidp: handle kernel_sendmsg() errors correctly · 2df01200
      David Herrmann authored
      We shouldn't push back the skbs if kernel_sendmsg() fails. Instead, we
      terminate the connection and drop the skb. Only on EAGAIN we push it back
      and return.
      l2cap doesn't return EAGAIN, yet, but this guarantees we're safe if it
      will at some time in the future.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      2df01200
    • David Herrmann's avatar
      Bluetooth: hidp: remove old session-management · 5205185d
      David Herrmann authored
      We have the full new session-management now available so lets switch over
      and remove all the old code. Few semantics changed, so we need to adjust
      the sock.c callers a bit. But this mostly simplifies the logic.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      5205185d
    • David Herrmann's avatar
      Bluetooth: hidp: add new session-management helpers · b4f34d8d
      David Herrmann authored
      This is a rewrite of the HIDP session management. It implements HIDP as an
      l2cap_user sub-module so we get proper notification when the underlying
      connection goes away.
      
      The helpers are not yet used but only added in this commit. The old
      session management is still used and will be removed in a following patch.
      
      The old session-management was flawed. Hotplugging is horribly broken and
      we have no way of getting notified when the underlying connection goes
      down. The whole idea of removing the HID/input sub-devices from within the
      session itself is broken and suffers from major dead-locks. We never can
      guarantee that the session can unregister itself as long as we use
      synchronous shutdowns. This can only work with asynchronous shutdowns.
      However, in this case we _must_ be able to unregister the session from the
      outside as otherwise the l2cap_conn object might be unlinked before we
      are.
      
      The new session-management is based on l2cap_user. There is only one
      way how to add a session and how to delete a session: "probe" and "remove"
      callbacks from l2cap_user.
      This guarantees that the session can be registered and unregistered at
      _any_ time without any synchronous shutdown.
      On the other hand, much work has been put into proper session-refcounting.
      We can unregister/unlink the session only if we can guarantee that it will
      stay alive. But for asynchronous shutdowns we never know when the last
      user goes away so we must use proper ref-counting.
      
      The old ->conn field has been renamed to ->hconn so we can reuse ->conn in
      the new session management. No other existing HIDP code is modified.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      b4f34d8d
    • David Herrmann's avatar
      Bluetooth: l2cap: add l2cap_user sub-modules · 2c8e1411
      David Herrmann authored
      Several sub-modules like HIDP, rfcomm, ... need to track l2cap
      connections. The l2cap_conn->hcon->dev object is used as parent for sysfs
      devices so the sub-modules need to be notified when the hci_conn object is
      removed from sysfs.
      
      As submodules normally use the l2cap layer, the l2cap_user objects are
      registered there instead of on the underlying hci_conn object. This avoids
      any direct dependency on the HCI layer and lets the l2cap core handle any
      specifics.
      
      This patch introduces l2cap_user objects which contain a "probe" and
      "remove" callback. You can register them on any l2cap_conn object and if
      it is active, the "probe" callback will get called. Otherwise, an error is
      returned.
      
      The l2cap_conn object will call your "remove" callback directly before it
      is removed from user-space. This allows you to remove your submodules
      _before_ the parent l2cap_conn and hci_conn object is removed.
      
      At any time you can asynchronously unregister your l2cap_user object if
      your submodule vanishes before the l2cap_conn object does.
      
      There is no way around l2cap_user. If we want wire-protocols in the
      kernel, we always want the hci_conn object as parent in the sysfs tree. We
      cannot use a channel here since we might need multiple channels for a
      single protocol.
      But the problem is, we _must_ get notified when an l2cap_conn object is
      removed. We cannot use reference-counting for object-removal! This is not
      how it works. If a hardware is removed, we should immediately remove the
      object from sysfs. Any other behavior would be inconsistent with the rest
      of the system. Also note that device_del() might sleep, but it doesn't
      wait for user-space or block very long. It only _unlinks_ the object from
      sysfs and the whole device-tree. Everything else is handled by ref-counts!
      This is exactly what the other sub-modules must do: unlink their devices
      when the "remove" l2cap_user callback is called. They should not do any
      cleanup or synchronous shutdowns.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      2c8e1411
    • David Herrmann's avatar
      Bluetooth: l2cap: introduce l2cap_conn ref-counting · 9c903e37
      David Herrmann authored
      If we want to use l2cap_conn outside of l2cap_core.c, we need refcounting
      for these objects. Otherwise, we cannot synchronize l2cap locks with
      outside locks and end up with deadlocks.
      
      Hence, introduce ref-counting for l2cap_conn objects. This doesn't affect
      l2cap internals at all, as they use a direct synchronization.
      We also keep a reference to the parent hci_conn for locking purposes as
      l2cap_conn depends on this. This doesn't affect the connection itself but
      only the lifetime of the (dead) object.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      9c903e37
    • David Herrmann's avatar
      Bluetooth: hidp: move hidp_schedule() to core.c · 3764eaa9
      David Herrmann authored
      There is no reason to keep this helper in the header file. No other file
      depends on it so move it into hidp/core.c where it belongs.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      3764eaa9
    • David Herrmann's avatar
      Bluetooth: allow constant arguments for bacmp()/bacpy() · f53c20e9
      David Herrmann authored
      There is no reason to require the source arguments to be writeable so fix
      this to allow constant source addresses.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      f53c20e9
    • David Herrmann's avatar
      Bluetooth: hidp: test "terminate" before sleeping · e3492dc3
      David Herrmann authored
      The "terminate" flag is guaranteed to be set before the session terminates
      and the handlers are woken up. Hence, we need to add it to the
      sleep-condition.
      
      Note that testing the flags is not enough as nothing prevents us from
      setting the flags again after the session-handler terminated.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      e3492dc3
    • David Herrmann's avatar
      Bluetooth: hidp: remove unused session->state field · dcc07647
      David Herrmann authored
      This field is always BT_CONNECTED. Remove it and set it to BT_CONNECTED in
      hidp_copy_session() unconditionally.
      
      Also note that this field is totally bogus. Userspace can query an
      hidp-session for its state. However, whenever user-space queries us, this
      field should be BT_CONNECTED. If it wasn't BT_CONNECTED, then we would be
      currently cleaning up the session and the session itself would exit in the
      next few milliseconds. Hence, there is no reason to let user-space know
      that the session will exit now if they cannot make _any_ use of that.
      
      Thus, remove the field and let user-space think that a session is always
      BT_CONNECTED as long as they can query it.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      dcc07647
    • David Herrmann's avatar
      Bluetooth: introduce hci_conn ref-counting · 8d12356f
      David Herrmann authored
      We currently do not allow using hci_conn from outside of HCI-core.
      However, several other users could make great use of it. This includes
      HIDP, rfcomm and all other sub-protocols that rely on an active
      connection.
      
      Hence, we now introduce hci_conn ref-counting. We currently never call
      get_device(). put_device() is exclusively used in hci_conn_del_sysfs().
      Hence, we currently never have a greater device-refcnt than 1.
      Therefore, it is safe to move the put_device() call from
      hci_conn_del_sysfs() to hci_conn_del() (it's the only caller). In fact,
      this even fixes a "use-after-free" bug as we access hci_conn after calling
      hci_conn_del_sysfs() in hci_conn_del().
      
      From now on we can add references to hci_conn objects in other layers
      (like l2cap_sock, HIDP, rfcomm, ...) and grab a reference via
      hci_conn_get(). This does _not_ guarantee, that the connection is still
      alive. But, this isn't what we want. We can simply lock the hci_conn
      device and use "device_is_registered(hci_conn->dev)" to test that.
      However, this is hardly necessary as outside users should never rely on
      the HCI connection to be alive, anyway. Instead, they should solely rely
      on the device-object to be available.
      But if sub-devices want the hci_conn object as sysfs parent, they need to
      be notified when the connection drops. This will be introduced in later
      patches with l2cap_users.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      8d12356f
    • David Herrmann's avatar
      Bluetooth: remove unneeded hci_conn_hold/put_device() · fc225c3f
      David Herrmann authored
      hci_conn_hold/put_device() is used to control when hci_conn->dev is no
      longer needed and can be deleted from the system. Lets first look how they
      are currently used throughout the code (excluding HIDP!).
      
      All code that uses hci_conn_hold_device() looks like this:
          ...
          hci_conn_hold_device();
          hci_conn_add_sysfs();
          ...
      On the other side, hci_conn_put_device() is exclusively used in
      hci_conn_del().
      
      So, considering that hci_conn_del() must not be called twice (which would
      fail horribly), we know that hci_conn_put_device() is only called _once_
      (which is in hci_conn_del()).
      On the other hand, hci_conn_add_sysfs() must not be called twice, either
      (it would call device_add twice, which breaks the device, see
      drivers/base/core.c). So we know that hci_conn_hold_device() is also
      called only once (it's only called directly before hci_conn_add_sysfs()).
      
      So hold and put are known to be called only once. That means we can safely
      remove them and directly call hci_conn_del_sysfs() in hci_conn_del().
      
      But there is one issue left: HIDP also uses hci_conn_hold/put_device().
      However, this case can be ignored and simply removed as it is totally
      broken. The issue is, the only thing HIDP delays with
      hci_conn_hold_device() is the removal of the hci_conn->dev from sysfs.
      But, the hci_conn device has no mechanism to get notified when its own
      parent (hci_dev) gets removed from sysfs. hci_dev_hold/put() does _not_
      control when it is removed but only when the device object is created
      and destroyed.
      And hci_dev calls hci_conn_flush_*() when it removes itself from sysfs,
      which itself causes hci_conn_del() to be called, but it does _not_ cause
      hci_conn_del_sysfs() to be called, which is wrong.
      
      Hence, we fix it to call hci_conn_del_sysfs() in hci_conn_del(). This
      guarantees that a hci_conn object is removed from sysfs _before_ its
      parent hci_dev is removed.
      
      The changes to HIDP look scary, wrong and broken. However, if you look at
      the HIDP session management, you will notice they're already broken in the
      exact _same_ way (ever tried "unplugging" HIDP devices? Breaks _all_ the
      time).
      So this patch only makes HIDP look _scary_ and _obviously broken_. It does
      not break HIDP itself, it already is!
      
      See later patches in this series which fix HIDP to use proper
      session-management.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      fc225c3f
  2. 11 Apr, 2013 7 commits
  3. 06 Apr, 2013 2 commits
  4. 04 Apr, 2013 14 commits
  5. 03 Apr, 2013 6 commits