1. 29 1月, 2021 16 次提交
  2. 16 1月, 2021 1 次提交
    • M
      xhci: make sure TRB is fully written before giving it to the controller · 576667ba
      Mathias Nyman 提交于
      Once the command ring doorbell is rung the xHC controller will parse all
      command TRBs on the command ring that have the cycle bit set properly.
      
      If the driver just started writing the next command TRB to the ring when
      hardware finished the previous TRB, then HW might fetch an incomplete TRB
      as long as its cycle bit set correctly.
      
      A command TRB is 16 bytes (128 bits) long.
      Driver writes the command TRB in four 32 bit chunks, with the chunk
      containing the cycle bit last. This does however not guarantee that
      chunks actually get written in that order.
      
      This was detected in stress testing when canceling URBs with several
      connected USB devices.
      Two consecutive "Set TR Dequeue pointer" commands got queued right
      after each other, and the second one was only partially written when
      the controller parsed it, causing the dequeue pointer to be set
      to bogus values. This was seen as error messages:
      
      "Mismatch between completed Set TR Deq Ptr command & xHCI internal state"
      
      Solution is to add a write memory barrier before writing the cycle bit.
      
      Cc: <stable@vger.kernel.org>
      Tested-by: NRoss Zwisler <zwisler@google.com>
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Link: https://lore.kernel.org/r/20210115161907.2875631-2-mathias.nyman@linux.intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      576667ba
  3. 09 12月, 2020 1 次提交
    • T
      usb: xhci: Use temporary buffer to consolidate SG · 2017a1e5
      Tejas Joglekar 提交于
      The Synopsys xHC has an internal TRB cache of size TRB_CACHE_SIZE for
      each endpoint. The default value for TRB_CACHE_SIZE is 16 for SS and 8
      for HS. The controller loads and updates the TRB cache from the transfer
      ring in system memory whenever the driver issues a start transfer or
      update transfer command.
      
      For chained TRBs, the Synopsys xHC requires that the total amount of
      bytes for all TRBs loaded in the TRB cache be greater than or equal to 1
      MPS. Or the chain ends within the TRB cache (with a last TRB).
      
      If this requirement is not met, the controller will not be able to send
      or receive a packet and it will hang causing a driver timeout and error.
      
      This can be a problem if a class driver queues SG requests with many
      small-buffer entries. The XHCI driver will create a chained TRB for each
      entry which may trigger this issue.
      
      This patch adds logic to the XHCI driver to detect and prevent this from
      happening.
      
      For every (TRB_CACHE_SIZE - 2), we check the total buffer size of
      the SG list and if the last window of (TRB_CACHE_SIZE - 2) SG list length
      and we don't make up at least 1 MPS, we create a temporary buffer to
      consolidate full SG list into the buffer.
      
      We check at (TRB_CACHE_SIZE - 2) window because it is possible that there
      would be a link and/or event data TRB that take up to 2 of the cache
      entries.
      
      We discovered this issue with devices on other platforms but have not
      yet come across any device that triggers this on Linux. But it could be
      a real problem now or in the future. All it takes is N number of small
      chained TRBs. And other instances of the Synopsys IP may have smaller
      values for the TRB_CACHE_SIZE which would exacerbate the problem.
      Signed-off-by: NTejas Joglekar <joglekar@synopsys.com>
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Link: https://lore.kernel.org/r/20201208092912.1773650-3-mathias.nyman@linux.intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2017a1e5
  4. 13 11月, 2020 1 次提交
  5. 20 9月, 2020 1 次提交
    • M
      xhci: Tune interrupt blocking for isochronous transfers · edc649a8
      Mathias Nyman 提交于
      controllers with XHCI_AVOID_BEI quirk cause too frequent interrupts
      and affect power management.
      
      To avoid interrupting on every isochronous interval the BEI (Block
      Event Interrupt) flag is set for all except the last Isoch TRB in a URB.
      This lead to event ring filling up in case several isoc URB were
      queued and cancelled rapidly, which some controllers didn't
      handle well, and thus the XHCI_AVOID_BEI quirk was introduced.
      see commit 227a4fd8 ("usb: xhci: apply XHCI_AVOID_BEI quirk to all
      Intel xHCI controllers")
      
      With the XHCI_AVOID_BEI quirk each Isoch TRB will trigger an interrupt.
      This can cause up to 8000 interrupts per second for isochronous transfers
      with HD USB3 cameras, affecting power saving.
      
      The event ring fits 256 events, instead of interrupting on every
      isochronous TRB if XHCI_AVOID_BEI is set we make sure at least every
      8th Isochronous TRB asserts an interrupt, clearing the event ring.
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Link: https://lore.kernel.org/r/20200918131752.16488-9-mathias.nyman@linux.intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      edc649a8
  6. 24 8月, 2020 1 次提交
  7. 14 5月, 2020 1 次提交
    • S
      usb: xhci: Fix NULL pointer dereference when enqueuing trbs from urb sg list · 3c6f8cb9
      Sriharsha Allenki 提交于
      On platforms with IOMMU enabled, multiple SGs can be coalesced into one
      by the IOMMU driver. In that case the SG list processing as part of the
      completion of a urb on a bulk endpoint can result into a NULL pointer
      dereference with the below stack dump.
      
      <6> Unable to handle kernel NULL pointer dereference at virtual address 0000000c
      <6> pgd = c0004000
      <6> [0000000c] *pgd=00000000
      <6> Internal error: Oops: 5 [#1] PREEMPT SMP ARM
      <2> PC is at xhci_queue_bulk_tx+0x454/0x80c
      <2> LR is at xhci_queue_bulk_tx+0x44c/0x80c
      <2> pc : [<c08907c4>]    lr : [<c08907bc>]    psr: 000000d3
      <2> sp : ca337c80  ip : 00000000  fp : ffffffff
      <2> r10: 00000000  r9 : 50037000  r8 : 00004000
      <2> r7 : 00000000  r6 : 00004000  r5 : 00000000  r4 : 00000000
      <2> r3 : 00000000  r2 : 00000082  r1 : c2c1a200  r0 : 00000000
      <2> Flags: nzcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
      <2> Control: 10c0383d  Table: b412c06a  DAC: 00000051
      <6> Process usb-storage (pid: 5961, stack limit = 0xca336210)
      <snip>
      <2> [<c08907c4>] (xhci_queue_bulk_tx)
      <2> [<c0881b3c>] (xhci_urb_enqueue)
      <2> [<c0831068>] (usb_hcd_submit_urb)
      <2> [<c08350b4>] (usb_sg_wait)
      <2> [<c089f384>] (usb_stor_bulk_transfer_sglist)
      <2> [<c089f2c0>] (usb_stor_bulk_srb)
      <2> [<c089fe38>] (usb_stor_Bulk_transport)
      <2> [<c089f468>] (usb_stor_invoke_transport)
      <2> [<c08a11b4>] (usb_stor_control_thread)
      <2> [<c014a534>] (kthread)
      
      The above NULL pointer dereference is the result of block_len and the
      sent_len set to zero after the first SG of the list when IOMMU driver
      is enabled. Because of this the loop of processing the SGs has run
      more than num_sgs which resulted in a sg_next on the last SG of the
      list which has SG_END set.
      
      Fix this by check for the sg before any attributes of the sg are
      accessed.
      
      [modified reason for null pointer dereference in commit message subject -Mathias]
      Fixes: f9c589e1 ("xhci: TD-fragment, align the unsplittable case with a bounce buffer")
      Cc: stable@vger.kernel.org
      Signed-off-by: NSriharsha Allenki <sallenki@codeaurora.org>
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Link: https://lore.kernel.org/r/20200514110432.25564-2-mathias.nyman@linux.intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      3c6f8cb9
  8. 21 4月, 2020 2 次提交
  9. 13 3月, 2020 3 次提交
  10. 11 12月, 2019 2 次提交
  11. 16 11月, 2019 3 次提交
  12. 29 10月, 2019 1 次提交
  13. 04 10月, 2019 1 次提交
  14. 19 6月, 2019 1 次提交
    • M
      usb: xhci: Don't try to recover an endpoint if port is in error state. · b8c3b718
      Mathias Nyman 提交于
      A USB3 device needs to be reset and re-enumarated if the port it
      connects to goes to a error state, with link state inactive.
      
      There is no use in trying to recover failed transactions by resetting
      endpoints at this stage. Tests show that in rare cases, after multiple
      endpoint resets of a roothub port the whole host controller might stop
      completely.
      
      Several retries to recover from transaction error can happen as
      it can take a long time before the hub thread discovers the USB3
      port error and inactive link.
      
      We can't reliably detect the port error from slot or endpoint context
      due to a limitation in xhci, see xhci specs section 4.8.3:
      "There are several cases where the EP State field in the Output
      Endpoint Context may not reflect the current state of an endpoint"
      and
      "Software should maintain an accurate value for EP State, by tracking it
      with an internal variable that is driven by Events and Doorbell accesses"
      
      Same appears to be true for slot state.
      
      set a flag to the corresponding slot if a USB3 roothub port link goes
      inactive to prevent both queueing new URBs and resetting endpoints.
      Reported-by: NRapolu Chiranjeevi <chiranjeevi.rapolu@intel.com>
      Tested-by: NRapolu Chiranjeevi <chiranjeevi.rapolu@intel.com>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b8c3b718
  15. 05 6月, 2019 1 次提交
    • J
      usb: xhci: Add Clear_TT_Buffer · ef513be0
      Jim Lin 提交于
      USB 2.0 specification chapter 11.17.5 says "as part of endpoint halt
      processing for full-/low-speed endpoints connected via a TT, the host
      software must use the Clear_TT_Buffer request to the TT to ensure
      that the buffer is not in the busy state".
      
      In our case, a full-speed speaker (ConferenceCam) is behind a high-
      speed hub (ConferenceCam Connect), sometimes once we get STALL on a
      request we may continue to get STALL with the folllowing requests,
      like Set_Interface.
      
      Here we invoke usb_hub_clear_tt_buffer() to send Clear_TT_Buffer
      request to the hub of the device for the following Set_Interface
      requests to the device to get ACK successfully.
      Signed-off-by: NJim Lin <jilin@nvidia.com>
      Acked-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ef513be0
  16. 23 5月, 2019 1 次提交
  17. 22 5月, 2019 2 次提交
  18. 27 4月, 2019 1 次提交