1. 25 1月, 2016 3 次提交
  2. 19 12月, 2015 1 次提交
    • A
      USB: fix invalid memory access in hub_activate() · e50293ef
      Alan Stern 提交于
      Commit 8520f380 ("USB: change hub initialization sleeps to
      delayed_work") changed the hub_activate() routine to make part of it
      run in a workqueue.  However, the commit failed to take a reference to
      the usb_hub structure or to lock the hub interface while doing so.  As
      a result, if a hub is plugged in and quickly unplugged before the work
      routine can run, the routine will try to access memory that has been
      deallocated.  Or, if the hub is unplugged while the routine is
      running, the memory may be deallocated while it is in active use.
      
      This patch fixes the problem by taking a reference to the usb_hub at
      the start of hub_activate() and releasing it at the end (when the work
      is finished), and by locking the hub interface while the work routine
      is running.  It also adds a check at the start of the routine to see
      if the hub has already been disconnected, in which nothing should be
      done.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      Reported-by: NAlexandru Cornea <alexandru.cornea@intel.com>
      Tested-by: NAlexandru Cornea <alexandru.cornea@intel.com>
      Fixes: 8520f380 ("USB: change hub initialization sleeps to delayed_work")
      CC: <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e50293ef
  3. 12 12月, 2015 1 次提交
  4. 05 12月, 2015 1 次提交
  5. 02 12月, 2015 3 次提交
    • L
      usb: core: lpm: add sysfs node for usb3 lpm permit · 513072d9
      Lu Baolu 提交于
      USB3 LPM is default on in Linux kernel if both xHCI host controller
      and the USB devices declare to be LPM-capable. Unfortunately, some
      devices are known to work well with LPM disabled, but to be broken
      if LPM is enabled, although it declares the LPM capability.  Users
      won't be able to use this kind of devices, until someone puts them
      in the kernel blacklist and gets the kernel upgraded.
      
      This patch adds a sysfs node to permit or forbit USB3 LPM U1 or U2
      entry for a port. The settings apply to both before and after device
      enumeration. Supported values are "0" - neither u1 nor u2 permitted,
      "u1" - only u1 is permitted, "u2" - only u2 is permitted, "u1_u2" -
      both u1 and u2 are permitted. With this interface, users can use an
      LPM-unfriendly USB device on a released Linux kernel.
      Signed-off-by: NLu Baolu <baolu.lu@linux.intel.com>
      Signed-off-by: NZhuang Jin Can <jin.can.zhuang@intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      513072d9
    • L
      usb: core: lpm: fix usb3_hardware_lpm sysfs node · bf5ce5bf
      Lu Baolu 提交于
      Commit 655fe4ef ("usbcore: add sysfs support to xHCI usb3
      hardware LPM") introduced usb3_hardware_lpm sysfs node. This
      doesn't show the correct status of USB3 U1 and U2 LPM status.
      
      This patch fixes this by replacing usb3_hardware_lpm with two
      nodes, usb3_hardware_lpm_u1 (for U1) and usb3_hardware_lpm_u2
      (for U2), and recording the U1/U2 LPM status in right places.
      
      This patch should be back-ported to kernels as old as 4.3,
      that contains Commit 655fe4ef ("usbcore: add sysfs support
      to xHCI usb3 hardware LPM").
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NLu Baolu <baolu.lu@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      bf5ce5bf
    • H
      usb: core : hub: Fix BOS 'NULL pointer' kernel panic · 464ad8c4
      Hans Yang 提交于
      When a USB 3.0 mass storage device is disconnected in transporting
      state, storage device driver may handle it as a transport error and
      reset the device by invoking usb_reset_and_verify_device()
      and following could happen:
      
      in usb_reset_and_verify_device():
         udev->bos = NULL;
      
      For U1/U2 enabled devices, driver will disable LPM, and in some
      conditions:
         from usb_unlocked_disable_lpm()
          --> usb_disable_lpm()
          --> usb_enable_lpm()
              udev->bos->ss_cap->bU1devExitLat;
      
      And it causes 'NULL pointer' and 'kernel panic':
      
      [  157.976257] Unable to handle kernel NULL pointer dereference
      at virtual address 00000010
      ...
      [  158.026400] PC is at usb_enable_link_state+0x34/0x2e0
      [  158.031442] LR is at usb_enable_lpm+0x98/0xac
      ...
      [  158.137368] [<ffffffc0006a1cac>] usb_enable_link_state+0x34/0x2e0
      [  158.143451] [<ffffffc0006a1fec>] usb_enable_lpm+0x94/0xac
      [  158.148840] [<ffffffc0006a20e8>] usb_disable_lpm+0xa8/0xb4
      ...
      [  158.214954] Kernel panic - not syncing: Fatal exception
      
      This commit moves 'udev->bos = NULL' behind usb_unlocked_disable_lpm()
      to prevent from NULL pointer access.
      
      Issue can be reproduced by following setup:
      1) A SS pen drive behind a SS hub connected to the host.
      2) Transporting data between the pen drive and the host.
      3) Abruptly disconnect hub and pen drive from host.
      4) With a chance it crashes.
      Signed-off-by: NHans Yang <hansy@nvidia.com>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Cc: stable <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      464ad8c4
  6. 04 10月, 2015 3 次提交
  7. 15 8月, 2015 2 次提交
  8. 09 8月, 2015 1 次提交
  9. 23 7月, 2015 2 次提交
  10. 31 5月, 2015 1 次提交
    • R
      usb: core: Fix USB 3.0 devices lost in NOTATTACHED state after a hub port reset · fb6d1f7d
      Robert Schlabbach 提交于
      Fix USB 3.0 devices lost in NOTATTACHED state after a hub port reset.
      
      Dissolve the function hub_port_finish_reset() completely and divide the
      actions to be taken into those which need to be done after each reset
      attempt and those which need to be done after the full procedure is
      complete, and place them in the appropriate places in hub_port_reset().
      Also, remove an unneeded forward declaration of hub_port_reset().
      
      Verbose Problem Description:
      
      USB 3.0 devices may be "lost for good" during a hub port reset.
      This makes Linux unable to boot from USB 3.0 devices in certain
      constellations of host controllers and devices, because the USB device is
      lost during initialization, preventing the rootfs from being mounted.
      
      The underlying problem is that in the affected constellations, during the
      processing inside hub_port_reset(), the hub link state goes from 0 to
      SS.inactive after the initial reset, and back to 0 again only after the
      following "warm" reset.
      
      However, hub_port_finish_reset() is called after each reset attempt and
      sets the state the connected USB device based on the "preliminary" status
      of the hot reset to USB_STATE_NOTATTACHED due to SS.inactive, yet when
      the following warm reset is complete and hub_port_finish_reset() is
      called again, its call to set the device to USB_STATE_DEFAULT is blocked
      by usb_set_device_state() which does not allow taking USB devices out of
      USB_STATE_NOTATTACHED state.
      
      Thanks to Alan Stern for guiding me to the proper solution and how to
      submit it.
      
      Link: http://lkml.kernel.org/r/trinity-25981484-72a9-4d46-bf17-9c1cf9301a31-1432073240136%20()%203capp-gmx-bs27Signed-off-by: NRobert Schlabbach <robert_s@gmx.net>
      Cc: stable <stable@vger.kernel.org>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      fb6d1f7d
  11. 10 5月, 2015 1 次提交
  12. 08 5月, 2015 3 次提交
  13. 08 4月, 2015 1 次提交
  14. 09 2月, 2015 1 次提交
  15. 04 2月, 2015 2 次提交
  16. 25 1月, 2015 2 次提交
    • D
      usb: core: hub: modify hub reset logic in hub driver · fbaecff0
      Deepak Das 提交于
      Currently if port power is turned off by user on hub port
      using USBDEVFS then port power is turned back ON
      by hub driver.
      This commit modifies hub reset logic in hub_port_connect() to prevent
      hub driver from turning back the port power ON if port is not owned
      by kernel.
      Signed-off-by: NDeepak Das <deepakdas.linux@gmail.com>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      fbaecff0
    • 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
  17. 04 12月, 2014 1 次提交
  18. 04 11月, 2014 4 次提交
  19. 29 9月, 2014 2 次提交
  20. 24 9月, 2014 5 次提交
    • P
      usb: hub: allow to process more usb hub events in parallel · 638139eb
      Petr Mladek 提交于
      It seems that only choose_devnum() was not ready to process more hub
      events at the same time.
      
      All should be fine if we take bus->usb_address0_mutex there. It will
      make sure that more devnums will not be chosen for the given bus and
      the related devices at the same time.
      Signed-off-by: NPetr Mladek <pmladek@suse.cz>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      638139eb
    • P
      usb: hub: rename khubd to hub_wq in documentation and comments · 37ebb549
      Petr Mladek 提交于
      USB hub has started to use a workqueue instead of kthread. Let's update
      the documentation and comments here and there.
      
      This patch mostly just replaces "khubd" with "hub_wq". There are only few
      exceptions where the whole sentence was updated. These more complicated
      changes can be found in the following files:
      
      	   Documentation/usb/hotplug.txt
      	   drivers/net/usb/usbnet.c
      	   drivers/usb/core/hcd.c
      	   drivers/usb/host/ohci-hcd.c
      	   drivers/usb/host/xhci.c
      Signed-off-by: NPetr Mladek <pmladek@suse.cz>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      37ebb549
    • P
      usb: hub: rename usb_kick_khubd() to usb_kick_hub_wq() · 59d48b3f
      Petr Mladek 提交于
      USB hub started to use a workqueue instead of kthread. Let's make it clear from
      the function names.
      Signed-off-by: NPetr Mladek <pmladek@suse.cz>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      59d48b3f
    • P
      usb: hub: convert khubd into workqueue · 32a69589
      Petr Mladek 提交于
      There is no need to have separate kthread for handling USB hub events.
      It is more elegant to use the workqueue framework.
      
      The workqueue is allocated as freezable because the original thread was
      freezable as well.
      
      Also it is allocated as ordered because the code is not ready for parallel
      processing of hub events, see choose_devnum().
      
      struct usb_hub is passed via the work item. Therefore we do not need
      hub_event_list.
      
      Also hub_thread() is not longer needed. It would call only hub_event().
      The rest of the code did manipulate the kthread and it is handled by the
      workqueue framework now.
      
      kick_khubd is renamed to kick_hub_wq() to make the function clear. And the
      protection against races is done another way, see below.
      
      hub_event_lock has been removed. It cannot longer be used to protect struct
      usb_hub between hub_event() and hub_disconnect(). Instead we need to get
      hub->kref already in kick_hub_wq().
      
      The lock is not really needed for the other scenarios as well. queue_work()
      returns whether it succeeded. We could revert the needed operations
      accordingly. This is enough to avoid duplicity and inconsistencies.
      
      Yes, the removed lock causes that there is not longer such a strong
      synchronization between scheduling the work and manipulating
      hub->disconnected.
      
      But kick_hub_wq() must never be called together with hub_disconnect()
      otherwise even the original code would have failed. Any callers are
      responsible for this.
      
      Therefore the only problem is that hub_disconnect() could be called in parallel
      with hub_event(). But this was possible even in the past. struct usb_hub is
      still guarded by hub->kref and released in hub_events() when needed.
      
      Note that the source file is still full of the obsolete "khubd" strings.
      Let's remove them in a follow up patch. This patch already is complex enough.
      
      Thanks a lot Alan Stern <stern@rowland.harvard.edu> for code review, many useful
      tips and guidance. Also thanks to Tejun Heo <tj@kernel.org> for hints how to
      allocate the workqueue.
      Signed-off-by: NPetr Mladek <pmladek@suse.cz>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      32a69589
    • P
      usb: hub: rename hub_events() to hub_event() and handle only one event there · eb6e2924
      Petr Mladek 提交于
      We would like to convert khubd kthread to a workqueue. As a result hub_events()
      will handle only one event per call.
      
      In fact, we could do this already now because there is another cycle in
      hub_thread(). It calls hub_events() until hub_event_list is empty.
      
      This patch renames the function to hub_event(), removes the while cycle, and
      renames the goto targets from loop* to out*.
      
      When touching the code, it fixes also formatting of dev_err() and dev_dbg()
      calls to make checkpatch.pl happy :-)
      Signed-off-by: NPetr Mladek <pmladek@suse.cz>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      eb6e2924