1. 17 4月, 2013 5 次提交
    • D
      Bluetooth: hidp: add new session-management helpers · b4f34d8d
      David Herrmann 提交于
      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: NDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: NMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
      b4f34d8d
    • D
      Bluetooth: hidp: move hidp_schedule() to core.c · 3764eaa9
      David Herrmann 提交于
      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: NDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: NMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
      3764eaa9
    • D
      Bluetooth: hidp: test "terminate" before sleeping · e3492dc3
      David Herrmann 提交于
      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: NDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: NMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
      e3492dc3
    • D
      Bluetooth: hidp: remove unused session->state field · dcc07647
      David Herrmann 提交于
      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: NDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: NMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
      dcc07647
    • D
      Bluetooth: remove unneeded hci_conn_hold/put_device() · fc225c3f
      David Herrmann 提交于
      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: NDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: NMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
      fc225c3f
  2. 06 4月, 2013 1 次提交
  3. 08 3月, 2013 1 次提交
  4. 10 1月, 2013 1 次提交
  5. 07 12月, 2012 1 次提交
  6. 28 9月, 2012 1 次提交
  7. 10 6月, 2012 1 次提交
  8. 05 6月, 2012 2 次提交
  9. 01 5月, 2012 2 次提交
  10. 19 12月, 2011 1 次提交
  11. 08 11月, 2011 3 次提交
  12. 07 10月, 2011 10 次提交
  13. 28 9月, 2011 1 次提交
  14. 21 9月, 2011 1 次提交
  15. 12 8月, 2011 4 次提交
  16. 01 7月, 2011 1 次提交
    • P
      Bluetooth: Fix hidp disconnect deadlocks and lost wakeup · 7bb59df8
      Peter Hurley 提交于
      Partial revert of commit aabf6f89. When the hidp session thread
      was converted from kernel_thread to kthread, the atomic/wakeups
      were replaced with kthread_stop. kthread_stop has blocking semantics
      which are inappropriate for the hidp session kthread. In addition,
      the kthread signals itself to terminate in hidp_process_hid_control()
      - it cannot do this with kthread_stop().
      
      Lastly, a wakeup can be lost if the wakeup happens between checking
      for the loop exit condition and setting the current state to
      TASK_INTERRUPTIBLE. (Without appropriate synchronization mechanisms,
      the task state should not be changed between the condition test and
      the yield - via schedule() - as this creates a race between the
      wakeup and resetting the state back to interruptible.)
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGustavo F. Padovan <padovan@profusion.mobi>
      7bb59df8
  17. 28 4月, 2011 1 次提交
  18. 05 4月, 2011 1 次提交
  19. 01 4月, 2011 1 次提交
  20. 22 2月, 2011 1 次提交