1. 25 10月, 2013 1 次提交
  2. 09 10月, 2013 2 次提交
  3. 02 9月, 2013 1 次提交
  4. 27 8月, 2013 1 次提交
  5. 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
  6. 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
  7. 26 3月, 2013 1 次提交
  8. 18 3月, 2013 3 次提交
  9. 07 3月, 2013 1 次提交
  10. 25 2月, 2013 4 次提交
  11. 03 1月, 2013 1 次提交
  12. 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
  13. 26 11月, 2012 1 次提交
  14. 23 11月, 2012 1 次提交
  15. 16 11月, 2012 1 次提交
  16. 15 11月, 2012 1 次提交
  17. 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
  18. 27 8月, 2012 2 次提交
  19. 15 8月, 2012 1 次提交
  20. 20 7月, 2012 6 次提交
    • A
      HID: usbhid: fix error paths in suspend · eb055fd0
      Alan Stern 提交于
      This patch (as1597) fixes some of the error paths in usbhid's suspend
      routine.  The driver was not careful to restart everything that might
      have been stopped, in cases where a suspend failed.
      
      For example, once the HID_SUSPENDED flag is set, an output report
      submission would not restart the corresponding URB queue.  If a
      suspend fails, it's therefore necessary to check whether the queues
      need to be restarted.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      CC: Oliver Neukum <oliver@neukum.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      eb055fd0
    • A
      HID: usbhid: check for suspend or reset before restarting · d4150c8f
      Alan Stern 提交于
      This patch (as1596) improves the queue-restart logic in usbhid by
      checking to see if the device is suspended or a reset is about to
      occur.  There's no point submitting an URB if either of those is
      true.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      CC: Oliver Neukum <oliver@neukum.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      d4150c8f
    • A
      HID: usbhid: replace HID_REPORTED_IDLE with HID_SUSPENDED · f2b5264d
      Alan Stern 提交于
      This patch (as1595) improves the usbhid driver by using the
      HID_SUSPENDED bitflag to indicate that the device is suspended rather
      than using HID_REPORTED_IDLE, which the patch removes.
      
      Since HID_SUSPENDED was not being used for anything, and since the
      name "HID_REPORTED_IDLE" doesn't convey much meaning, the end result
      is easier to read and understand.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      CC: Oliver Neukum <oliver@neukum.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      f2b5264d
    • A
      HID: usbhid: inline some simple routines · 93101af3
      Alan Stern 提交于
      This patch (as1594) simplifies the usbhid driver by inlining a couple
      of routines.  As a result of an earlier patch, irq_out_pump_restart()
      and ctrl_pump_restart() are each used in only one place.  Since they
      don't really do what their names say, and since they each involve only
      about two lines of actual code, there's no reason to keep them as
      separate functions.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      CC: Oliver Neukum <oliver@neukum.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      93101af3
    • A
      HID: usbhid: fix autosuspend calls · 01a7c984
      Alan Stern 提交于
      This patch (as1593) fixes some logic errors in the usbhid driver
      relating to runtime PM.  The driver does not balance its calls to
      usb_autopm_get_interface_async() and usb_autopm_put_interface_async().
      
      For example, when the control queue is restarted the driver does a
      _get.  But the resume won't happen immediately, so the driver leaves
      the queue stopped.  When the resume does occur, the queue is restarted
      and a second _get occurs, with no balancing _put.
      
      The patch fixes the problem by rearranging the logic for restarting
      the queues.  All the _get/_put calls and bitflag settings in
      __usbhid_submit_report() are moved into the queue-restart routines.  A
      balancing _put call is added for the case where the queue is still
      suspended.  A call to irq_out_pump_restart(), which doesn't take all
      the right actions for restarting the irq-OUT queue, is replaced by a
      call to usbhid_restart_out_queue(), which does.  Similarly for
      ctrl_pump_restart().
      
      Finally, new code is added to prevent an autosuspend from happening
      every time an URB is cancelled, and the comments explaining what
      happens when an URB needs to be cancelled are expanded and clarified.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      CC: Oliver Neukum <oliver@neukum.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      01a7c984
    • A
      HID: usbhid: fix use-after-free bug · 668160e5
      Alan Stern 提交于
      This patch (as1592) fixes an obscure problem in the usbhid driver.
      Under some circumstances, a control or interrupt-OUT URB can be
      submitted twice.  This will happen if the first submission fails; the
      queue pointers aren't updated, so the next time the queue is restarted
      the same URB will be submitted again.
      
      The problem is that raw_report gets deallocated during the first
      submission.  The second submission will then dereference and try to
      free an already-freed region of memory.  The patch fixes the problem
      by setting raw_report to NULL when it is deallocated and checking for
      NULL before dereferencing it.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      CC: Oliver Neukum <oliver@neukum.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      668160e5
  21. 09 7月, 2012 1 次提交
  22. 25 6月, 2012 1 次提交
  23. 02 5月, 2012 2 次提交
  24. 01 5月, 2012 2 次提交