1. 15 11月, 2011 3 次提交
    • T
      USB: EHCI: fix HUB TT scheduling issue with iso transfer · 811c926c
      Thomas Poussevin 提交于
      The current TT scheduling doesn't allow to play and then record on a
      full-speed device connected to a high speed hub.
      
      The IN iso stream can only start on the first uframe (0-2 for a 165 us)
      because of CSPLIT transactions.
      For the OUT iso stream there no such restriction. uframe 0-5 are possible.
      
      The idea of this patch is that the first uframe are precious (for IN TT iso
      stream) and we should allocate the last uframes first if possible.
      
      For that we reverse the order of uframe allocation (last uframe first).
      
      Here an example :
      
      hid interrupt stream
      ----------------------------------------------------------------------
      uframe                |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |
      ----------------------------------------------------------------------
      max_tt_usecs          | 125 | 125 | 125 | 125 | 125 | 125 | 30  |  0  |
      ----------------------------------------------------------------------
      used usecs on a frame | 13  |  0  |  0  |  0  |  0  |  0  |  0  |  0  |
      ----------------------------------------------------------------------
      
      iso OUT stream
      ----------------------------------------------------------------------
      uframe                |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |
      ----------------------------------------------------------------------
      max_tt_usecs          | 125 | 125 | 125 | 125 | 125 | 125 | 30  |  0  |
      ----------------------------------------------------------------------
      used usecs on a frame | 13  | 125 |  39 |  0  |  0  |  0  |  0  |  0  |
      ----------------------------------------------------------------------
      
      There no place for iso IN stream  (uframe 0-2 are used) and we got "cannot
      submit datapipe for urb 0, error -28: not enough bandwidth" error.
      
      With the patch this become.
      
      iso OUT stream
      ----------------------------------------------------------------------
      uframe                |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |
      ----------------------------------------------------------------------
      max_tt_usecs          | 125 | 125 | 125 | 125 | 125 | 125 | 30  |  0  |
      ----------------------------------------------------------------------
      used usecs on a frame |  13 |  0  |  0  |  0  | 125 |  39 |  0  |  0  |
      ----------------------------------------------------------------------
      
      iso IN stream
      ----------------------------------------------------------------------
      uframe                |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |
      ----------------------------------------------------------------------
      max_tt_usecs          | 125 | 125 | 125 | 125 | 125 | 125 | 30  |  0  |
      ----------------------------------------------------------------------
      used usecs on a frame |  13 |  0  | 125 | 40  | 125 |  39 |  0  |  0  |
      ----------------------------------------------------------------------
      Signed-off-by: NMatthieu Castet <matthieu.castet@parrot.com>
      Signed-off-by: NThomas Poussevin <thomas.poussevin@parrot.com>
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      Cc: stable <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
      811c926c
    • A
      USB: XHCI: resume root hubs when the controller resumes · f69e3120
      Alan Stern 提交于
      This patch (as1494) fixes a problem in xhci-hcd's resume routine.
      When the controller is runtime-resumed, this can only mean that one of
      the two root hubs has made a wakeup request and therefore needs to be
      resumed as well.  Rather than try to determine which root hub requires
      attention (which might be difficult in the case where a new
      non-SuperSpeed device has been plugged in), the patch simply resumes
      both root hubs.
      
      Without this change, there is a race: The controller might be put back
      to sleep before it can activate its IRQ line, and the wakeup condition
      might never get handled.
      
      The patch also simplifies the logic in xhci_resume a little, combining
      some repeated flag settings into a single pair of statements.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      CC: Sarah Sharp <sarah.a.sharp@linux.intel.com>
      Cc: stable <stable@vger.kernel.org>
      Tested-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
      f69e3120
    • A
      USB: workaround for bug in old version of GCC · 97ff22ee
      Alan Stern 提交于
      This patch (as1491) works around a bug in GCC-3.4.6, which is still
      supposed to be supported.  The number of microseconds in the udelay()
      call in quirk_usb_disable_ehci() is fixed at 100, but the compiler
      doesn't understand this and generates a link-time error.  So we
      replace the otherwise unused variable "delta" with a simple constant
      100.  This same pattern is already used in other delay loops in that
      source file.
      Signed-off-by: NAlan Stern <stern@rowland.harvard.edu>
      Reported-by: NKonrad Rzepecki <krzepecki@dentonet.pl>
      Tested-by: NKonrad Rzepecki <krzepecki@dentonet.pl>
      Cc: stable <stable@vger.kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
      97ff22ee
  2. 05 11月, 2011 1 次提交
    • S
      xhci: Set slot and ep0 flags for address command. · d31c285b
      Sarah Sharp 提交于
      Matt's AsMedia xHCI host controller was responding with a Context Error
      to an address device command after a configured device reset.  Some
      sequence of events leads both the slot and endpoint zero add flags
      cleared to zero, which the AsMedia host doesn't like:
      
      [  223.701839] xhci_hcd 0000:03:00.0: Slot ID 1 Input Context:
      [  223.701841] xhci_hcd 0000:03:00.0: @ffff880137b25000 (virt) @ffffc000 (dma) 0x000000 - drop flags
      [  223.701843] xhci_hcd 0000:03:00.0: @ffff880137b25004 (virt) @ffffc004 (dma) 0x000000 - add flags
      [  223.701846] xhci_hcd 0000:03:00.0: @ffff880137b25008 (virt) @ffffc008 (dma) 0x000000 - rsvd2[0]
      [  223.701848] xhci_hcd 0000:03:00.0: @ffff880137b2500c (virt) @ffffc00c (dma) 0x000000 - rsvd2[1]
      [  223.701850] xhci_hcd 0000:03:00.0: @ffff880137b25010 (virt) @ffffc010 (dma) 0x000000 - rsvd2[2]
      [  223.701852] xhci_hcd 0000:03:00.0: @ffff880137b25014 (virt) @ffffc014 (dma) 0x000000 - rsvd2[3]
      [  223.701854] xhci_hcd 0000:03:00.0: @ffff880137b25018 (virt) @ffffc018 (dma) 0x000000 - rsvd2[4]
      [  223.701857] xhci_hcd 0000:03:00.0: @ffff880137b2501c (virt) @ffffc01c (dma) 0x000000 - rsvd2[5]
      [  223.701858] xhci_hcd 0000:03:00.0: Slot Context:
      [  223.701860] xhci_hcd 0000:03:00.0: @ffff880137b25020 (virt) @ffffc020 (dma) 0x8400000 - dev_info
      [  223.701862] xhci_hcd 0000:03:00.0: @ffff880137b25024 (virt) @ffffc024 (dma) 0x010000 - dev_info2
      [  223.701864] xhci_hcd 0000:03:00.0: @ffff880137b25028 (virt) @ffffc028 (dma) 0x000000 - tt_info
      [  223.701866] xhci_hcd 0000:03:00.0: @ffff880137b2502c (virt) @ffffc02c (dma) 0x000000 - dev_state
      [  223.701869] xhci_hcd 0000:03:00.0: @ffff880137b25030 (virt) @ffffc030 (dma) 0x000000 - rsvd[0]
      [  223.701871] xhci_hcd 0000:03:00.0: @ffff880137b25034 (virt) @ffffc034 (dma) 0x000000 - rsvd[1]
      [  223.701873] xhci_hcd 0000:03:00.0: @ffff880137b25038 (virt) @ffffc038 (dma) 0x000000 - rsvd[2]
      [  223.701875] xhci_hcd 0000:03:00.0: @ffff880137b2503c (virt) @ffffc03c (dma) 0x000000 - rsvd[3]
      [  223.701877] xhci_hcd 0000:03:00.0: Endpoint 00 Context:
      [  223.701879] xhci_hcd 0000:03:00.0: @ffff880137b25040 (virt) @ffffc040 (dma) 0x000000 - ep_info
      [  223.701881] xhci_hcd 0000:03:00.0: @ffff880137b25044 (virt) @ffffc044 (dma) 0x2000026 - ep_info2
      [  223.701883] xhci_hcd 0000:03:00.0: @ffff880137b25048 (virt) @ffffc048 (dma) 0xffffe8e0 - deq
      [  223.701885] xhci_hcd 0000:03:00.0: @ffff880137b25050 (virt) @ffffc050 (dma) 0x000000 - tx_info
      [  223.701887] xhci_hcd 0000:03:00.0: @ffff880137b25054 (virt) @ffffc054 (dma) 0x000000 - rsvd[0]
      [  223.701889] xhci_hcd 0000:03:00.0: @ffff880137b25058 (virt) @ffffc058 (dma) 0x000000 - rsvd[1]
      [  223.701892] xhci_hcd 0000:03:00.0: @ffff880137b2505c (virt) @ffffc05c (dma) 0x000000 - rsvd[2]
      ...
      [  223.701927] xhci_hcd 0000:03:00.0: // Ding dong!
      [  223.701992] xhci_hcd 0000:03:00.0: Setup ERROR: address device command for slot 1.
      
      The xHCI spec says that both flags must be set to one for the Address
      Device command.  When the device is first enumerated,
      xhci_setup_addressable_virt_dev() does set those flags.  However, when
      the device is addressed after it has been reset in the configured state,
      xhci_setup_addressable_virt_dev() is not called, and
      xhci_copy_ep0_dequeue_into_input_ctx() is called instead.  That function
      relies on the flags being set up by previous commands, which apparently
      isn't a good assumption.
      
      Move the setting of the flags into the common parent function.
      
      This should be queued for stable kernels as old as 2.6.35, since that
      was the first introduction of xhci_copy_ep0_dequeue_into_input_ctx.
      Signed-off-by: NSarah Sharp <sarah.a.sharp@linux.intel.com>
      Tested-by: NMatt <mdm@iinet.net.au>
      Cc: stable@vger.kernel.org
      d31c285b
  3. 03 11月, 2011 1 次提交
    • D
      usb, xhci: fix lockdep warning on endpoint timeout · f43d6231
      Don Zickus 提交于
      While debugging a usb3 problem, I stumbled upon this lockdep warning.
      
      Oct 18 21:41:17 dhcp47-74 kernel: =================================
      Oct 18 21:41:17 dhcp47-74 kernel: [ INFO: inconsistent lock state ]
      Oct 18 21:41:17 dhcp47-74 kernel: 3.1.0-rc4nmi+ #456
      Oct 18 21:41:17 dhcp47-74 kernel: ---------------------------------
      Oct 18 21:41:17 dhcp47-74 kernel: inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
      Oct 18 21:41:17 dhcp47-74 kernel: swapper/0 [HC0[0]:SC1[1]:HE1:SE0] takes:
      Oct 18 21:41:17 dhcp47-74 kernel: (&(&xhci->lock)->rlock){?.-...}, at: [<ffffffffa0228990>] xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd]
      Oct 18 21:41:17 dhcp47-74 kernel: {IN-HARDIRQ-W} state was registered at:
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8109a941>] __lock_acquire+0x781/0x1660
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8109bed7>] lock_acquire+0x97/0x170
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81501b46>] _raw_spin_lock+0x46/0x80
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa02299fa>] xhci_irq+0x3a/0x1960 [xhci_hcd]
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa022b351>] xhci_msi_irq+0x31/0x40 [xhci_hcd]
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810d2305>] handle_irq_event_percpu+0x85/0x320
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810d25e8>] handle_irq_event+0x48/0x70
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810d537d>] handle_edge_irq+0x6d/0x130
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810048c9>] handle_irq+0x49/0xa0
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8150d56d>] do_IRQ+0x5d/0xe0
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff815029b0>] ret_from_intr+0x0/0x13
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81388aca>] usb_set_device_state+0x8a/0x180
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8138f038>] usb_add_hcd+0x2b8/0x730
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa022ed7e>] xhci_pci_probe+0x9e/0xd4 [xhci_hcd]
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8127915f>] local_pci_probe+0x5f/0xd0
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8127a569>] pci_device_probe+0x119/0x120
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81334473>] driver_probe_device+0xa3/0x2c0
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8133473b>] __driver_attach+0xab/0xb0
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8133373c>] bus_for_each_dev+0x6c/0xa0
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff813341fe>] driver_attach+0x1e/0x20
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81333b88>] bus_add_driver+0x1f8/0x2b0
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81334df6>] driver_register+0x76/0x140
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8127a7c6>] __pci_register_driver+0x66/0xe0
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa013c04a>] snd_timer_find+0x4a/0x70 [snd_timer]
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa013c00e>] snd_timer_find+0xe/0x70 [snd_timer]
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810001d3>] do_one_initcall+0x43/0x180
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810a9ed2>] sys_init_module+0x92/0x1f0
      Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8150ab6b>] system_call_fastpath+0x16/0x1b
      Oct 18 21:41:17 dhcp47-74 kernel: irq event stamp: 631984
      Oct 18 21:41:17 dhcp47-74 kernel: hardirqs last  enabled at (631984): [<ffffffff81502720>] _raw_spin_unlock_irq+0x30/0x50
      Oct 18 21:41:17 dhcp47-74 kernel: hardirqs last disabled at (631983): [<ffffffff81501c49>] _raw_spin_lock_irq+0x19/0x90
      Oct 18 21:41:17 dhcp47-74 kernel: softirqs last  enabled at (631980): [<ffffffff8105ff63>] _local_bh_enable+0x13/0x20
      Oct 18 21:41:17 dhcp47-74 kernel: softirqs last disabled at (631981): [<ffffffff8150ce6c>] call_softirq+0x1c/0x30
      Oct 18 21:41:17 dhcp47-74 kernel:
      Oct 18 21:41:17 dhcp47-74 kernel: other info that might help us debug this:
      Oct 18 21:41:17 dhcp47-74 kernel: Possible unsafe locking scenario:
      Oct 18 21:41:17 dhcp47-74 kernel:
      Oct 18 21:41:17 dhcp47-74 kernel:       CPU0
      Oct 18 21:41:17 dhcp47-74 kernel:       ----
      Oct 18 21:41:17 dhcp47-74 kernel:  lock(&(&xhci->lock)->rlock);
      Oct 18 21:41:17 dhcp47-74 kernel:  <Interrupt>
      Oct 18 21:41:17 dhcp47-74 kernel:    lock(&(&xhci->lock)->rlock);
      Oct 18 21:41:17 dhcp47-74 kernel:
      Oct 18 21:41:17 dhcp47-74 kernel: *** DEADLOCK ***
      Oct 18 21:41:17 dhcp47-74 kernel:
      Oct 18 21:41:17 dhcp47-74 kernel: 1 lock held by swapper/0:
      Oct 18 21:41:17 dhcp47-74 kernel: #0:  (&ep->stop_cmd_timer){+.-...}, at: [<ffffffff8106abf2>] run_timer_softirq+0x162/0x570
      Oct 18 21:41:17 dhcp47-74 kernel:
      Oct 18 21:41:17 dhcp47-74 kernel: stack backtrace:
      Oct 18 21:41:17 dhcp47-74 kernel: Pid: 0, comm: swapper Tainted: G        W   3.1.0-rc4nmi+ #456
      Oct 18 21:41:17 dhcp47-74 kernel: Call Trace:
      Oct 18 21:41:17 dhcp47-74 kernel: <IRQ>  [<ffffffff81098ed7>] print_usage_bug+0x227/0x270
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff810999c6>] mark_lock+0x346/0x410
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8109a7de>] __lock_acquire+0x61e/0x1660
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81099893>] ? mark_lock+0x213/0x410
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8109bed7>] lock_acquire+0x97/0x170
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffffa0228990>] ? xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd]
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81501b46>] _raw_spin_lock+0x46/0x80
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffffa0228990>] ? xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd]
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffffa0228990>] xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd]
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8106abf2>] ? run_timer_softirq+0x162/0x570
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8106ac9d>] run_timer_softirq+0x20d/0x570
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8106abf2>] ? run_timer_softirq+0x162/0x570
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffffa0228960>] ? xhci_queue_isoc_tx_prepare+0x8e0/0x8e0 [xhci_hcd]
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff810604d2>] __do_softirq+0xf2/0x3f0
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81020edd>] ? lapic_next_event+0x1d/0x30
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81090d4e>] ? clockevents_program_event+0x5e/0x90
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8150ce6c>] call_softirq+0x1c/0x30
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8100484d>] do_softirq+0x8d/0xc0
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8105ff35>] irq_exit+0xe5/0x100
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8150d65e>] smp_apic_timer_interrupt+0x6e/0x99
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8150b6f0>] apic_timer_interrupt+0x70/0x80
      Oct 18 21:41:17 dhcp47-74 kernel: <EOI>  [<ffffffff81095d8d>] ? trace_hardirqs_off+0xd/0x10
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff812ddb76>] ? acpi_idle_enter_bm+0x227/0x25b
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff812ddb71>] ? acpi_idle_enter_bm+0x222/0x25b
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff813eda63>] cpuidle_idle_call+0x103/0x290
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81002155>] cpu_idle+0xe5/0x160
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff814e7f50>] rest_init+0xe0/0xf0
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff814e7e70>] ? csum_partial_copy_generic+0x170/0x170
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81df8e23>] start_kernel+0x3fc/0x407
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81df8321>] x86_64_start_reservations+0x131/0x135
      Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81df8412>] x86_64_start_kernel+0xed/0xf4
      Oct 18 21:41:17 dhcp47-74 kernel: xhci_hcd 0000:00:14.0: xHCI host not responding to stop endpoint command.
      Oct 18 21:41:17 dhcp47-74 kernel: xhci_hcd 0000:00:14.0: Assuming host is dying, halting host.
      Oct 18 21:41:17 dhcp47-74 kernel: xhci_hcd 0000:00:14.0: HC died; cleaning up
      Oct 18 21:41:17 dhcp47-74 kernel: usb 3-4: device descriptor read/8, error -110
      Oct 18 21:41:17 dhcp47-74 kernel: usb 3-4: device descriptor read/8, error -22
      Oct 18 21:41:17 dhcp47-74 kernel: hub 3-0:1.0: cannot disable port 4 (err = -19)
      
      Basically what is happening is in xhci_stop_endpoint_command_watchdog()
      the xhci->lock is grabbed with just spin_lock.  What lockdep deduces is
      that if an interrupt occurred while in this function it would deadlock
      with xhci_irq because that function also grabs the xhci->lock.
      
      Fixing it is trivial by using spin_lock_irqsave instead.
      
      This should be queued to stable kernels as far back as 2.6.33.
      Signed-off-by: NDon Zickus <dzickus@redhat.com>
      Signed-off-by: NSarah Sharp <sarah.a.sharp@linux.intel.com>
      Cc: stable@kernel.org
      f43d6231
  4. 01 11月, 2011 3 次提交
  5. 25 10月, 2011 2 次提交
  6. 20 10月, 2011 1 次提交
  7. 19 10月, 2011 5 次提交
  8. 14 10月, 2011 1 次提交
  9. 27 9月, 2011 17 次提交
  10. 21 9月, 2011 5 次提交
  11. 20 9月, 2011 1 次提交
    • A
      USB: xHCI: prevent infinite loop when processing MSE event · c2d7b49f
      Andiry Xu 提交于
      When a xHC host is unable to handle isochronous transfer in the
      interval, it reports a Missed Service Error event and skips some tds.
      
      Currently xhci driver handles MSE event in the following ways:
      
      1. When encounter a MSE event, set ep->skip flag, update event ring
         dequeue pointer and return.
      
      2. When encounter the next event on this ep, the driver will run the
         do-while loop, fetch td from ep's td_list to find the td
         corresponding to this event.  All tds missed are marked as short
         transfer(-EXDEV).
      
      The do-while loop will end in two ways:
      
      1. If the td pointed by the event trb is found;
      
      2. If the ep ring's td_list is empty.
      
      However, if a buggy HW reports some unpredicted event (for example, an
      overrun event following a MSE event while the ep ring is actually not
      empty), the driver will never find the td, and it will loop until the
      td_list is empty.
      
      Unfortunately, the spinlock is dropped when give back a urb in the
      do-while loop.  During the spinlock released period, the class driver
      may still submit urbs and add tds to the td_list.  This may cause
      disaster, since the td_list will never be empty and the loop never ends,
      and the system hangs.
      
      To fix this, count the number of TDs on the ep ring before skipping TDs,
      and quit the loop when skipped that number of tds.  This guarantees the
      do-while loop will end after certain number of cycles, and driver will
      not be trapped in an infinite loop.
      Signed-off-by: NAndiry Xu <andiry.xu@amd.com>
      Signed-off-by: NSarah Sharp <sarah.a.sharp@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      c2d7b49f