1. 02 9月, 2020 1 次提交
  2. 06 6月, 2020 1 次提交
    • A
      USB: core: Fix misleading driver bug report · b06e7b67
      Alan Stern 提交于
      [ Upstream commit ac854131d9844f79e2fdcef67a7707227538d78a ]
      
      The syzbot fuzzer found a race between URB submission to endpoint 0
      and device reset.  Namely, during the reset we call usb_ep0_reinit()
      because the characteristics of ep0 may have changed (if the reset
      follows a firmware update, for example).  While usb_ep0_reinit() is
      running there is a brief period during which the pointers stored in
      udev->ep_in[0] and udev->ep_out[0] are set to NULL, and if an URB is
      submitted to ep0 during that period, usb_urb_ep_type_check() will
      report it as a driver bug.  In the absence of those pointers, the
      routine thinks that the endpoint doesn't exist.  The log message looks
      like this:
      
      ------------[ cut here ]------------
      usb 2-1: BOGUS urb xfer, pipe 2 != type 2
      WARNING: CPU: 0 PID: 9241 at drivers/usb/core/urb.c:478
      usb_submit_urb+0x1188/0x1460 drivers/usb/core/urb.c:478
      
      Now, although submitting an URB while the device is being reset is a
      questionable thing to do, it shouldn't count as a driver bug as severe
      as submitting an URB for an endpoint that doesn't exist.  Indeed,
      endpoint 0 always exists, even while the device is in its unconfigured
      state.
      
      To prevent these misleading driver bug reports, this patch updates
      usb_disable_endpoint() to avoid clearing the ep_in[] and ep_out[]
      pointers when the endpoint being disabled is ep0.  There's no danger
      of leaving a stale pointer in place, because the usb_host_endpoint
      structure being pointed to is stored permanently in udev->ep0; it
      doesn't get deallocated until the entire usb_device structure does.
      
      Reported-and-tested-by: syzbot+db339689b2101f6f6071@syzkaller.appspotmail.com
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      
      Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2005011558590.903-100000@netrider.rowland.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      b06e7b67
  3. 09 5月, 2020 1 次提交
    • A
      USB: core: Fix free-while-in-use bug in the USB S-Glibrary · 63f5508e
      Alan Stern 提交于
      mainline inclusion
      from mainline-v5.7-rc3
      commit 056ad39ee9253873522f6469c3364964a322912b
      category: bugfix
      bugzilla: 13690
      CVE: CVE-2020-12464
      
      -------------------------------------------------
      
      FuzzUSB (a variant of syzkaller) found a free-while-still-in-use bug
      in the USB scatter-gather library:
      
      BUG: KASAN: use-after-free in atomic_read
      include/asm-generic/atomic-instrumented.h:26 [inline]
      BUG: KASAN: use-after-free in usb_hcd_unlink_urb+0x5f/0x170
      drivers/usb/core/hcd.c:1607
      Read of size 4 at addr ffff888065379610 by task kworker/u4:1/27
      
      CPU: 1 PID: 27 Comm: kworker/u4:1 Not tainted 5.5.11 #2
      Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
      1.10.2-1ubuntu1 04/01/2014
      Workqueue: scsi_tmf_2 scmd_eh_abort_handler
      Call Trace:
       __dump_stack lib/dump_stack.c:77 [inline]
       dump_stack+0xce/0x128 lib/dump_stack.c:118
       print_address_description.constprop.4+0x21/0x3c0 mm/kasan/report.c:374
       __kasan_report+0x153/0x1cb mm/kasan/report.c:506
       kasan_report+0x12/0x20 mm/kasan/common.c:639
       check_memory_region_inline mm/kasan/generic.c:185 [inline]
       check_memory_region+0x152/0x1b0 mm/kasan/generic.c:192
       __kasan_check_read+0x11/0x20 mm/kasan/common.c:95
       atomic_read include/asm-generic/atomic-instrumented.h:26 [inline]
       usb_hcd_unlink_urb+0x5f/0x170 drivers/usb/core/hcd.c:1607
       usb_unlink_urb+0x72/0xb0 drivers/usb/core/urb.c:657
       usb_sg_cancel+0x14e/0x290 drivers/usb/core/message.c:602
       usb_stor_stop_transport+0x5e/0xa0 drivers/usb/storage/transport.c:937
      
      This bug occurs when cancellation of the S-G transfer races with
      transfer completion.  When that happens, usb_sg_cancel() may continue
      to access the transfer's URBs after usb_sg_wait() has freed them.
      
      The bug is caused by the fact that usb_sg_cancel() does not take any
      sort of reference to the transfer, and so there is nothing to prevent
      the URBs from being deallocated while the routine is trying to use
      them.  The fix is to take such a reference by incrementing the
      transfer's io->count field while the cancellation is in progres and
      decrementing it afterward.  The transfer's URBs are not deallocated
      until io->complete is triggered, which happens when io->count reaches
      zero.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      Reported-and-tested-by: NKyungtae Kim <kt0755@gmail.com>
      CC: <stable@vger.kernel.org>
      
      Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2003281615140.14837-100000@netrider.rowland.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
      Reviewed-by: NJason Yan <yanaijie@huawei.com>
      Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
      63f5508e
  4. 27 12月, 2019 4 次提交
  5. 05 9月, 2018 1 次提交
  6. 28 6月, 2018 1 次提交
  7. 13 6月, 2018 1 次提交
    • K
      treewide: kmalloc() -> kmalloc_array() · 6da2ec56
      Kees Cook 提交于
      The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
      patch replaces cases of:
      
              kmalloc(a * b, gfp)
      
      with:
              kmalloc_array(a * b, gfp)
      
      as well as handling cases of:
      
              kmalloc(a * b * c, gfp)
      
      with:
      
              kmalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kmalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kmalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The tools/ directory was manually excluded, since it has its own
      implementation of kmalloc().
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kmalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kmalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kmalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kmalloc
      + kmalloc_array
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kmalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(sizeof(THING) * C2, ...)
      |
        kmalloc(sizeof(TYPE) * C2, ...)
      |
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(C1 * C2, ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      6da2ec56
  8. 31 5月, 2018 1 次提交
  9. 07 3月, 2018 1 次提交
    • D
      usb: quirks: add control message delay for 1b1c:1b20 · cb88a058
      Danilo Krummrich 提交于
      Corsair Strafe RGB keyboard does not respond to usb control messages
      sometimes and hence generates timeouts.
      
      Commit de3af5bf ("usb: quirks: add delay init quirk for Corsair
      Strafe RGB keyboard") tried to fix those timeouts by adding
      USB_QUIRK_DELAY_INIT.
      
      Unfortunately, even with this quirk timeouts of usb_control_msg()
      can still be seen, but with a lower frequency (approx. 1 out of 15):
      
      [   29.103520] usb 1-8: string descriptor 0 read error: -110
      [   34.363097] usb 1-8: can't set config #1, error -110
      
      Adding further delays to different locations where usb control
      messages are issued just moves the timeouts to other locations,
      e.g.:
      
      [   35.400533] usbhid 1-8:1.0: can't add hid device: -110
      [   35.401014] usbhid: probe of 1-8:1.0 failed with error -110
      
      The only way to reliably avoid those issues is having a pause after
      each usb control message. In approx. 200 boot cycles no more timeouts
      were seen.
      
      Addionaly, keep USB_QUIRK_DELAY_INIT as it turned out to be necessary
      to have the delay in hub_port_connect() after hub_port_init().
      
      The overall boot time seems not to be influenced by these additional
      delays, even on fast machines and lightweight distributions.
      
      Fixes: de3af5bf ("usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard")
      Cc: stable@vger.kernel.org
      Signed-off-by: NDanilo Krummrich <danilokrummrich@dk-develop.de>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      cb88a058
  10. 16 12月, 2017 1 次提交
  11. 06 12月, 2017 1 次提交
  12. 28 11月, 2017 2 次提交
    • J
      USB: add device-tree support for interfaces · 1a7e3948
      Johan Hovold 提交于
      Add OF device-tree support for USB interfaces.
      
      USB "interface nodes" are children of USB "device nodes" and are
      identified by an interface number and a configuration value:
      
      	&usb1 { /* host controller */
      		dev1: device@1 { /* device at port 1 */
      			compatible = "usb1234,5678";
      			reg = <1>;
      
      			#address-cells = <2>;
      			#size-cells = <0>;
      
      			interface@0,2 { /* interface 0 of configuration 2 */
      				compatible = "usbif1234,5678.config2.0";
      				reg = <0 2>;
      			};
      		};
      	};
      
      The configuration component is not included in the textual
      representation of an interface-node unit address for configuration 1:
      
      	&dev1 {
      		interface@0 {	/* interface 0 of configuration 1 */
      			compatible = "usbif1234,5678.config1.0";
      			reg = <0 1>;
      		};
      	};
      
      When a USB device of class 0 or 9 (hub) has only a single configuration
      with a single interface, a special case "combined node" is used instead
      of a device node with an interface node:
      
      	&usb1 {
      		device@2 {
      			compatible = "usb1234,abcd";
      			reg = <2>;
      		};
      	};
      
      Combined nodes are shared by the two device structures representing the
      USB device and its interface in the kernel's device model.
      
      Note that, as for device nodes, the compatible strings for interface
      nodes are currently not used.
      
      For more details see "Open Firmware Recommended Practice: Universal
      Serial Bus Version 1" and the binding documentation.
      Signed-off-by: NJohan Hovold <johan@kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1a7e3948
    • K
      usb: core: lower log level when device is not able to deal with string · 2124c888
      Kai-Heng Feng 提交于
      USB devices should work just fine when they don't support language id.
      
      Lower the log level so user won't panic in the future.
      
      BugLink: https://bugs.launchpad.net/bugs/1729618Signed-off-by: NKai-Heng Feng <kai.heng.feng@canonical.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2124c888
  13. 09 11月, 2017 1 次提交
  14. 07 11月, 2017 3 次提交
  15. 03 11月, 2017 1 次提交
  16. 21 9月, 2017 1 次提交
  17. 12 4月, 2017 1 次提交
  18. 19 1月, 2017 1 次提交
    • J
      usb: core: update comments for send message functions · 123b7b30
      Jaejoong Kim 提交于
      The commonly use of bottom halves are tasklet and workqueue. The big
      difference between tasklet and workqueue is that the tasklet runs in
      an interrupt context and the workqueue runs in a process context,
      which means it can sleep if need be.
      
      The comment for usb_control/interrupt/bulk_msg() functions note that do
      not use this function within an interrupt context, like a 'bottom half'
      handler. With this comment, it makes confuse about usage of these
      functions.
      
      To more clarify, remove 'bottom half' comment.
      Signed-off-by: NJaejoong Kim <climbbb.kim@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      123b7b30
  19. 30 10月, 2016 1 次提交
  20. 13 9月, 2016 1 次提交
    • R
      usb: core: setup dma_pfn_offset for USB devices and, interfaces · b44bbc46
      Roger Quadros 提交于
      If dma_pfn_offset is not inherited correctly from the host controller,
      it might result in sub-optimal configuration as bounce
      buffer limit might be set to less than optimal level.
      
      Consider the mass storage device case.
      USB storage driver creates a scsi host for the mass storage interface in
      drivers/usb/storage/usb.c
      The scsi host parent device is nothing but the the USB interface device.
      Now, __scsi_init_queue() calls scsi_calculate_bounce_limit() to find out
      and set the block layer bounce limit.
      scsi_calculate_bounce_limit() uses dma_max_pfn(host_dev) to get the
      bounce_limit. host_dev is nothing but the device representing the
      mass storage interface.
      If that device doesn't have the right dma_pfn_offset, then dma_max_pfn()
      is messed up and the bounce buffer limit is wrong.
      
      e.g. On Keystone 2 systems, dma_max_pfn() is 0x87FFFF and dma_mask_pfn
      is 0xFFFFF. Consider a mass storage use case: Without this patch,
      usb scsi host device (usb-storage) will get a dma_pfn_offset of 0 resulting
      in a dma_max_pfn() of 0xFFFFF within the scsi layer
      (scsi_calculate_bounce_limit()).
      This will result in bounce buffers being unnecessarily used.
      
      Hint: On 32-bit ARM platforms dma_max_pfn() = dma_mask_pfn + dma_pfn_offset
      Signed-off-by: NRoger Quadros <rogerq@ti.com>
      Acked-by: NArnd Bergmann <arnd@arndb.de>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b44bbc46
  21. 31 8月, 2016 1 次提交
  22. 18 7月, 2016 1 次提交
  23. 27 4月, 2016 2 次提交
  24. 04 10月, 2015 1 次提交
  25. 23 9月, 2015 2 次提交
  26. 19 8月, 2015 2 次提交
  27. 15 8月, 2015 2 次提交
  28. 25 1月, 2015 1 次提交
    • A
      USB: don't cancel queued resets when unbinding drivers · 524134d4
      Alan Stern 提交于
      The USB stack provides a mechanism for drivers to request an
      asynchronous device reset (usb_queue_reset_device()).  The mechanism
      uses a work item (reset_ws) embedded in the usb_interface structure
      used by the driver, and the reset is carried out by a work queue
      routine.
      
      The asynchronous reset can race with driver unbinding.  When this
      happens, we try to cancel the queued reset before unbinding the
      driver, on the theory that the driver won't care about any resets once
      it is unbound.
      
      However, thanks to the fact that lockdep now tracks work queue
      accesses, this can provoke a lockdep warning in situations where the
      device reset causes another interface's driver to be unbound; see
      
      	http://marc.info/?l=linux-usb&m=141893165203776&w=2
      
      for an example.  The reason is that the work routine for reset_ws in
      one interface calls cancel_queued_work() for the reset_ws in another
      interface.  Lockdep thinks this might lead to a work routine trying to
      cancel itself.  The simplest solution is not to cancel queued resets
      when unbinding drivers.
      
      This means we now need to acquire a reference to the usb_interface
      when queuing a reset_ws work item and to drop the reference when the
      work routine finishes.  We also need to make sure that the
      usb_interface structure doesn't outlive its parent usb_device; this
      means acquiring and dropping a reference when the interface is created
      and destroyed.
      
      In addition, cancelling a queued reset can fail (if the device is in
      the middle of an earlier reset), and this can cause usb_reset_device()
      to try to rebind an interface that has been deallocated (see
      http://marc.info/?l=linux-usb&m=142175717016628&w=2 for details).
      Acquiring the extra references prevents this failure.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      Reported-by: NRussell King - ARM Linux <linux@arm.linux.org.uk>
      Reported-by: NOlivier Sobrie <olivier@sobrie.be>
      Tested-by: NOlivier Sobrie <olivier@sobrie.be>
      Cc: stable <stable@vger.kernel.org> # 3.19
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      524134d4
  29. 29 9月, 2014 1 次提交
  30. 05 3月, 2014 1 次提交