1. 17 2月, 2014 3 次提交
  2. 29 1月, 2014 1 次提交
  3. 13 12月, 2013 1 次提交
  4. 02 12月, 2013 3 次提交
  5. 19 11月, 2013 1 次提交
  6. 25 10月, 2013 1 次提交
  7. 09 10月, 2013 2 次提交
  8. 02 9月, 2013 1 次提交
  9. 27 8月, 2013 1 次提交
  10. 31 7月, 2013 3 次提交
    • D
      HID: usbhid: use generic hidinput_input_event() · bfde79cb
      David Herrmann 提交于
      HID core provides the same functionality as we do, so drop the custom
      hidinput_input_event() handler.
      Signed-off-by: NDavid Herrmann <dh.herrmann@gmail.com>
      Reviewed-by: NBenjamin Tissoires <benjamin.tissoires@redhat.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      bfde79cb
    • D
      HID: usbhid: update LED fields unlocked · 60682284
      David Herrmann 提交于
      Report fields can be updated from HID drivers unlocked via
      hid_set_field(). It is protected by input_lock in HID core so only a
      single input event is handled at a time. USBHID can thus update the field
      unlocked and doesn't conflict with any HID vendor/device drivers. Note,
      many HID drivers make heavy use of hid_set_field() in that way.
      
      But usbhid also schedules a work to gather multiple LED changes in a
      single report. Hence, we used to lock the LED field update so the work can
      read a consistent state. However, hid_set_field() only writes a single
      integer field, which is guaranteed to be allocated all the time. So the
      worst possible race-condition is a garbage read on the LED field.
      
      Therefore, there is no need to protect the update. In fact, the only thing
      that is prevented by locking hid_set_field(), is an LED update while the
      scheduled work currently writes an older LED update out. However, this
      means, a new work is scheduled directly when the old one is done writing
      the new state to the device. So we actually _win_ by not protecting the
      write and allowing the write to be combined with the current write. A new
      worker is still scheduled, but will not write any new state. So the LED
      will not blink unnecessarily on the device.
      
      Assume we have the LED set to 0. Two request come in which enable the LED
      and immediately disable it. The current situation with two CPUs would be:
      
        usb_hidinput_input_event()       |      hid_led()
        ---------------------------------+----------------------------------
          spin_lock(&usbhid->lock);
          hid_set_field(1);
          spin_unlock(&usbhid->lock);
          schedule_work(...);
                                            spin_lock(&usbhid->lock);
                                            __usbhid_submit_report(..1..);
                                            spin_unlock(&usbhid->lock);
          spin_lock(&usbhid->lock);
          hid_set_field(0);
          spin_unlock(&usbhid->lock);
          schedule_work(...);
                                            spin_lock(&usbhid->lock);
                                            __usbhid_submit_report(..0..);
                                            spin_unlock(&usbhid->lock);
      
      With the locking removed, we _might_ end up with (look at the changed
      __usbhid_submit_report() parameters in the first try!):
      
        usb_hidinput_input_event()       |      hid_led()
        ---------------------------------+----------------------------------
          hid_set_field(1);
          schedule_work(...);
                                            spin_lock(&usbhid->lock);
          hid_set_field(0);
          schedule_work(...);
                                            __usbhid_submit_report(..0..);
                                            spin_unlock(&usbhid->lock);
      
                                            ... next work ...
      
                                            spin_lock(&usbhid->lock);
                                            __usbhid_submit_report(..0..);
                                            spin_unlock(&usbhid->lock);
      
      As one can see, we no longer send the "LED ON" signal as it is disabled
      immediately afterwards and the following "LED OFF" request overwrites the
      pending "LED ON".
      
      It is important to note that hid_set_field() is not atomic, so we might
      also end up with any other value. But that doesn't matter either as we
      _always_ schedule the next work with a correct value and schedule_work()
      acts as memory barrier, anyways. So in the worst case, we run
      __usbhid_submit_report(..<garbage>..) in the first case and the following
      __usbhid_submit_report() will write the correct value. But LED states are
      booleans so any garbage will be converted to either 0 or 1 and the remote
      device will never see invalid requests.
      
      Why all this? It avoids any custom locking around hid_set_field() in
      usbhid and finally allows us to provide a generic hidinput_input_event()
      handler for all HID transport drivers.
      Signed-off-by: NDavid Herrmann <dh.herrmann@gmail.com>
      Reviewed-by: NBenjamin Tissoires <benjamin.tissoires@redhat.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      60682284
    • D
      HID: usbhid: make usbhid_set_leds() static · ddf64a3c
      David Herrmann 提交于
      usbhid_set_leds() is only used inside of usbhid/hid-core.c so no need to
      export it.
      Signed-off-by: NDavid Herrmann <dh.herrmann@gmail.com>
      Reviewed-by: NBenjamin Tissoires <benjamin.tissoires@redhat.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      ddf64a3c
  11. 22 7月, 2013 1 次提交
    • J
      HID: fix data access in implement() · 27ce4050
      Jiri Kosina 提交于
      implement() is setting bytes in LE data stream. In case the data is not
      aligned to 64bits, it reads past the allocated buffer. It doesn't really
      change any value there (it's properly bitmasked), but in case that this
      read past the boundary hits a page boundary, pagefault happens when
      accessing 64bits of 'x' in implement(), and kernel oopses.
      
      This happens much more often when numbered reports are in use, as the
      initial 8bit skip in the buffer makes the whole process work on values
      which are not aligned to 64bits.
      
      This problem dates back to attempts in 2005 and 2006 to make implement()
      and extract() as generic as possible, and even back then the problem
      was realized by Adam Kroperlin, but falsely assumed to be impossible
      to cause any harm:
      
        http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg47690.html
      
      I have made several attempts at fixing it "on the spot" directly in
      implement(), but the results were horrible; the special casing for processing
      last 64bit chunk and switching to different math makes it unreadable mess.
      
      I therefore took a path to allocate a few bytes more which will never make
      it into final report, but are there as a cushion for all the 64bit math
      operations happening in implement() and extract().
      
      All callers of hid_output_report() are converted at the same time to allocate
      the buffer by newly introduced hid_alloc_report_buf() helper.
      
      Bruno noticed that the whole raw_size test can be dropped as well, as
      hid_alloc_report_buf() makes sure that the buffer is always of a proper
      size.
      Reviewed-by: NBenjamin Tissoires <benjamin.tissoires@redhat.com>
      Acked-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      27ce4050
  12. 26 3月, 2013 1 次提交
  13. 18 3月, 2013 3 次提交
  14. 07 3月, 2013 1 次提交
  15. 25 2月, 2013 4 次提交
  16. 03 1月, 2013 1 次提交
  17. 28 11月, 2012 1 次提交
    • J
      HID: hiddev: fix nonblocking read semantics wrt EIO/ERESTARTSYS · 13f19624
      Jiri Kosina 提交于
      When the file has been open in non-blocking mode, EIO or ERESTARTSYS
      would never be returned even if they should (for example when device
      has been unplugged, you want EIO and not EAGAIN to be returned).
      
      Move the O_NONBLOCK check after other checks have been performed.
      
      Base on similar patch done to hidraw by
      Founder Fang <founder.fang@gmail.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      13f19624
  18. 26 11月, 2012 1 次提交
  19. 23 11月, 2012 1 次提交
  20. 16 11月, 2012 1 次提交
  21. 15 11月, 2012 1 次提交
  22. 01 10月, 2012 1 次提交
    • K
      HID: keep dev_rdesc unmodified and use it for comparisons · 86e6b77e
      Kevin Daughtridge 提交于
      The dev_rdesc member of the hid_device structure is meant to store the original
      report descriptor received from the device, but it is currently passed to any
      report_fixup method before it is copied to the rdesc member. This patch uses a
      temporary buffer to shield dev_rdesc from the side effects of many HID drivers'
      report_fixup implementations.
      
      usbhid's hid_post_reset checks the report descriptor currently returned by the
      device against a descriptor that may have been modified by a driver's
      report_fixup method. That leaves some devices nonfunctional after a resume, with
      a "reset_resume error 1" reported. This patch checks the new descriptor against
      the unmodified dev_rdesc instead and uses the original, instead of modified,
      report size.
      
      BugLink: http://bugs.launchpad.net/bugs/1049623Signed-off-by: NKevin Daughtridge <kevin@kdau.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      86e6b77e
  23. 27 8月, 2012 2 次提交
  24. 15 8月, 2012 1 次提交
  25. 20 7月, 2012 3 次提交