usb-serial-cp210x-add-id-for-imst-im871a-usb.patch
usb-dwc3-host-set-xhci_sg_trb_cache_size_quirk.patch
usb-host-xhci-plat-add-support-for-xhci_sg_trb_cache_size_quirk.patch
-xhci-process-isoc-td-properly-when-there-was-a-transaction-error-mid-td.patch
-xhci-handle-isoc-babble-and-buffer-overrun-events-properly.patch
hrtimer-report-offline-hrtimer-enqueue.patch
input-i8042-fix-strange-behavior-of-touchpad-on-clevo-ns70pu.patch
input-atkbd-skip-atkbd_cmd_setleds-when-skipping-atkbd_cmd_getid.patch
+++ /dev/null
-From 7c4650ded49e5b88929ecbbb631efb8b0838e811 Mon Sep 17 00:00:00 2001
-From: Michal Pecio <michal.pecio@gmail.com>
-Date: Thu, 25 Jan 2024 17:27:37 +0200
-Subject: xhci: handle isoc Babble and Buffer Overrun events properly
-
-From: Michal Pecio <michal.pecio@gmail.com>
-
-commit 7c4650ded49e5b88929ecbbb631efb8b0838e811 upstream.
-
-xHCI 4.9 explicitly forbids assuming that the xHC has released its
-ownership of a multi-TRB TD when it reports an error on one of the
-early TRBs. Yet the driver makes such assumption and releases the TD,
-allowing the remaining TRBs to be freed or overwritten by new TDs.
-
-The xHC should also report completion of the final TRB due to its IOC
-flag being set by us, regardless of prior errors. This event cannot
-be recognized if the TD has already been freed earlier, resulting in
-"Transfer event TRB DMA ptr not part of current TD" error message.
-
-Fix this by reusing the logic for processing isoc Transaction Errors.
-This also handles hosts which fail to report the final completion.
-
-Fix transfer length reporting on Babble errors. They may be caused by
-device malfunction, no guarantee that the buffer has been filled.
-
-Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
-Cc: stable@vger.kernel.org
-Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
-Link: https://lore.kernel.org/r/20240125152737.2983959-5-mathias.nyman@linux.intel.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/usb/host/xhci-ring.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/usb/host/xhci-ring.c
-+++ b/drivers/usb/host/xhci-ring.c
-@@ -2447,9 +2447,13 @@ static int process_isoc_td(struct xhci_h
- case COMP_BANDWIDTH_OVERRUN_ERROR:
- frame->status = -ECOMM;
- break;
-- case COMP_ISOCH_BUFFER_OVERRUN:
- case COMP_BABBLE_DETECTED_ERROR:
-+ sum_trbs_for_length = true;
-+ fallthrough;
-+ case COMP_ISOCH_BUFFER_OVERRUN:
- frame->status = -EOVERFLOW;
-+ if (ep_trb != td->last_trb)
-+ td->error_mid_td = true;
- break;
- case COMP_INCOMPATIBLE_DEVICE_ERROR:
- case COMP_STALL_ERROR:
+++ /dev/null
-From 5372c65e1311a16351ef03dd096ff576e6477674 Mon Sep 17 00:00:00 2001
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-Date: Thu, 25 Jan 2024 17:27:36 +0200
-Subject: xhci: process isoc TD properly when there was a transaction error mid TD.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-
-commit 5372c65e1311a16351ef03dd096ff576e6477674 upstream.
-
-The last TRB of a isoc TD might not trigger an event if there was
-an error event for a TRB mid TD. This is seen on a NEC Corporation
-uPD720200 USB 3.0 Host
-
-After an error mid a multi-TRB TD the xHC should according to xhci 4.9.1
-generate events for passed TRBs with IOC flag set if it proceeds to the
-next TD. This event is either a copy of the original error, or a
-"success" transfer event.
-
-If that event is missing then the driver and xHC host get out of sync as
-the driver is still expecting a transfer event for that first TD, while
-xHC host is already sending events for the next TD in the list.
-This leads to
-"Transfer event TRB DMA ptr not part of current TD" messages.
-
-As a solution we tag the isoc TDs that get error events mid TD.
-If an event doesn't match the first TD, then check if the tag is
-set, and event points to the next TD.
-In that case give back the fist TD and process the next TD normally
-
-Make sure TD status and transferred length stay valid in both cases
-with and without final TD completion event.
-
-Reported-by: Michał Pecio <michal.pecio@gmail.com>
-Closes: https://lore.kernel.org/linux-usb/20240112235205.1259f60c@foxbook/
-Tested-by: Michał Pecio <michal.pecio@gmail.com>
-Cc: stable@vger.kernel.org
-Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
-Link: https://lore.kernel.org/r/20240125152737.2983959-4-mathias.nyman@linux.intel.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/usb/host/xhci-ring.c | 74 ++++++++++++++++++++++++++++++++++---------
- drivers/usb/host/xhci.h | 1
- 2 files changed, 61 insertions(+), 14 deletions(-)
-
---- a/drivers/usb/host/xhci-ring.c
-+++ b/drivers/usb/host/xhci-ring.c
-@@ -2429,6 +2429,9 @@ static int process_isoc_td(struct xhci_h
- /* handle completion code */
- switch (trb_comp_code) {
- case COMP_SUCCESS:
-+ /* Don't overwrite status if TD had an error, see xHCI 4.9.1 */
-+ if (td->error_mid_td)
-+ break;
- if (remaining) {
- frame->status = short_framestatus;
- if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
-@@ -2454,8 +2457,9 @@ static int process_isoc_td(struct xhci_h
- break;
- case COMP_USB_TRANSACTION_ERROR:
- frame->status = -EPROTO;
-+ sum_trbs_for_length = true;
- if (ep_trb != td->last_trb)
-- return 0;
-+ td->error_mid_td = true;
- break;
- case COMP_STOPPED:
- sum_trbs_for_length = true;
-@@ -2475,6 +2479,9 @@ static int process_isoc_td(struct xhci_h
- break;
- }
-
-+ if (td->urb_length_set)
-+ goto finish_td;
-+
- if (sum_trbs_for_length)
- frame->actual_length = sum_trb_lengths(xhci, ep->ring, ep_trb) +
- ep_trb_len - remaining;
-@@ -2483,6 +2490,14 @@ static int process_isoc_td(struct xhci_h
-
- td->urb->actual_length += frame->actual_length;
-
-+finish_td:
-+ /* Don't give back TD yet if we encountered an error mid TD */
-+ if (td->error_mid_td && ep_trb != td->last_trb) {
-+ xhci_dbg(xhci, "Error mid isoc TD, wait for final completion event\n");
-+ td->urb_length_set = true;
-+ return 0;
-+ }
-+
- return finish_td(xhci, ep, ep_ring, td, trb_comp_code);
- }
-
-@@ -2867,17 +2882,51 @@ static int handle_tx_event(struct xhci_h
- }
-
- if (!ep_seg) {
-- if (!ep->skip ||
-- !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
-- /* Some host controllers give a spurious
-- * successful event after a short transfer.
-- * Ignore it.
-- */
-- if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&
-- ep_ring->last_td_was_short) {
-- ep_ring->last_td_was_short = false;
-- goto cleanup;
-+
-+ if (ep->skip && usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
-+ skip_isoc_td(xhci, td, ep, status);
-+ goto cleanup;
-+ }
-+
-+ /*
-+ * Some hosts give a spurious success event after a short
-+ * transfer. Ignore it.
-+ */
-+ if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&
-+ ep_ring->last_td_was_short) {
-+ ep_ring->last_td_was_short = false;
-+ goto cleanup;
-+ }
-+
-+ /*
-+ * xhci 4.10.2 states isoc endpoints should continue
-+ * processing the next TD if there was an error mid TD.
-+ * So host like NEC don't generate an event for the last
-+ * isoc TRB even if the IOC flag is set.
-+ * xhci 4.9.1 states that if there are errors in mult-TRB
-+ * TDs xHC should generate an error for that TRB, and if xHC
-+ * proceeds to the next TD it should genete an event for
-+ * any TRB with IOC flag on the way. Other host follow this.
-+ * So this event might be for the next TD.
-+ */
-+ if (td->error_mid_td &&
-+ !list_is_last(&td->td_list, &ep_ring->td_list)) {
-+ struct xhci_td *td_next = list_next_entry(td, td_list);
-+
-+ ep_seg = trb_in_td(xhci, td_next->start_seg, td_next->first_trb,
-+ td_next->last_trb, ep_trb_dma, false);
-+ if (ep_seg) {
-+ /* give back previous TD, start handling new */
-+ xhci_dbg(xhci, "Missing TD completion event after mid TD error\n");
-+ ep_ring->dequeue = td->last_trb;
-+ ep_ring->deq_seg = td->last_trb_seg;
-+ inc_deq(xhci, ep_ring);
-+ xhci_td_cleanup(xhci, td, ep_ring, td->status);
-+ td = td_next;
- }
-+ }
-+
-+ if (!ep_seg) {
- /* HC is busted, give up! */
- xhci_err(xhci,
- "ERROR Transfer event TRB DMA ptr not "
-@@ -2889,9 +2938,6 @@ static int handle_tx_event(struct xhci_h
- ep_trb_dma, true);
- return -ESHUTDOWN;
- }
--
-- skip_isoc_td(xhci, td, ep, status);
-- goto cleanup;
- }
- if (trb_comp_code == COMP_SHORT_PACKET)
- ep_ring->last_td_was_short = true;
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -1572,6 +1572,7 @@ struct xhci_td {
- struct xhci_segment *bounce_seg;
- /* actual_length of the URB has already been set */
- bool urb_length_set;
-+ bool error_mid_td;
- unsigned int num_trbs;
- };
-
usb-serial-cp210x-add-id-for-imst-im871a-usb.patch
usb-dwc3-host-set-xhci_sg_trb_cache_size_quirk.patch
usb-host-xhci-plat-add-support-for-xhci_sg_trb_cache_size_quirk.patch
-xhci-process-isoc-td-properly-when-there-was-a-transaction-error-mid-td.patch
-xhci-handle-isoc-babble-and-buffer-overrun-events-properly.patch
hrtimer-report-offline-hrtimer-enqueue.patch
input-i8042-fix-strange-behavior-of-touchpad-on-clevo-ns70pu.patch
input-atkbd-skip-atkbd_cmd_setleds-when-skipping-atkbd_cmd_getid.patch
+++ /dev/null
-From 7c4650ded49e5b88929ecbbb631efb8b0838e811 Mon Sep 17 00:00:00 2001
-From: Michal Pecio <michal.pecio@gmail.com>
-Date: Thu, 25 Jan 2024 17:27:37 +0200
-Subject: xhci: handle isoc Babble and Buffer Overrun events properly
-
-From: Michal Pecio <michal.pecio@gmail.com>
-
-commit 7c4650ded49e5b88929ecbbb631efb8b0838e811 upstream.
-
-xHCI 4.9 explicitly forbids assuming that the xHC has released its
-ownership of a multi-TRB TD when it reports an error on one of the
-early TRBs. Yet the driver makes such assumption and releases the TD,
-allowing the remaining TRBs to be freed or overwritten by new TDs.
-
-The xHC should also report completion of the final TRB due to its IOC
-flag being set by us, regardless of prior errors. This event cannot
-be recognized if the TD has already been freed earlier, resulting in
-"Transfer event TRB DMA ptr not part of current TD" error message.
-
-Fix this by reusing the logic for processing isoc Transaction Errors.
-This also handles hosts which fail to report the final completion.
-
-Fix transfer length reporting on Babble errors. They may be caused by
-device malfunction, no guarantee that the buffer has been filled.
-
-Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
-Cc: stable@vger.kernel.org
-Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
-Link: https://lore.kernel.org/r/20240125152737.2983959-5-mathias.nyman@linux.intel.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/usb/host/xhci-ring.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/usb/host/xhci-ring.c
-+++ b/drivers/usb/host/xhci-ring.c
-@@ -2381,9 +2381,13 @@ static int process_isoc_td(struct xhci_h
- case COMP_BANDWIDTH_OVERRUN_ERROR:
- frame->status = -ECOMM;
- break;
-- case COMP_ISOCH_BUFFER_OVERRUN:
- case COMP_BABBLE_DETECTED_ERROR:
-+ sum_trbs_for_length = true;
-+ fallthrough;
-+ case COMP_ISOCH_BUFFER_OVERRUN:
- frame->status = -EOVERFLOW;
-+ if (ep_trb != td->last_trb)
-+ td->error_mid_td = true;
- break;
- case COMP_INCOMPATIBLE_DEVICE_ERROR:
- case COMP_STALL_ERROR:
+++ /dev/null
-From 5372c65e1311a16351ef03dd096ff576e6477674 Mon Sep 17 00:00:00 2001
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-Date: Thu, 25 Jan 2024 17:27:36 +0200
-Subject: xhci: process isoc TD properly when there was a transaction error mid TD.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Mathias Nyman <mathias.nyman@linux.intel.com>
-
-commit 5372c65e1311a16351ef03dd096ff576e6477674 upstream.
-
-The last TRB of a isoc TD might not trigger an event if there was
-an error event for a TRB mid TD. This is seen on a NEC Corporation
-uPD720200 USB 3.0 Host
-
-After an error mid a multi-TRB TD the xHC should according to xhci 4.9.1
-generate events for passed TRBs with IOC flag set if it proceeds to the
-next TD. This event is either a copy of the original error, or a
-"success" transfer event.
-
-If that event is missing then the driver and xHC host get out of sync as
-the driver is still expecting a transfer event for that first TD, while
-xHC host is already sending events for the next TD in the list.
-This leads to
-"Transfer event TRB DMA ptr not part of current TD" messages.
-
-As a solution we tag the isoc TDs that get error events mid TD.
-If an event doesn't match the first TD, then check if the tag is
-set, and event points to the next TD.
-In that case give back the fist TD and process the next TD normally
-
-Make sure TD status and transferred length stay valid in both cases
-with and without final TD completion event.
-
-Reported-by: Michał Pecio <michal.pecio@gmail.com>
-Closes: https://lore.kernel.org/linux-usb/20240112235205.1259f60c@foxbook/
-Tested-by: Michał Pecio <michal.pecio@gmail.com>
-Cc: stable@vger.kernel.org
-Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
-Link: https://lore.kernel.org/r/20240125152737.2983959-4-mathias.nyman@linux.intel.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/usb/host/xhci-ring.c | 74 ++++++++++++++++++++++++++++++++++---------
- drivers/usb/host/xhci.h | 1
- 2 files changed, 61 insertions(+), 14 deletions(-)
-
---- a/drivers/usb/host/xhci-ring.c
-+++ b/drivers/usb/host/xhci-ring.c
-@@ -2363,6 +2363,9 @@ static int process_isoc_td(struct xhci_h
- /* handle completion code */
- switch (trb_comp_code) {
- case COMP_SUCCESS:
-+ /* Don't overwrite status if TD had an error, see xHCI 4.9.1 */
-+ if (td->error_mid_td)
-+ break;
- if (remaining) {
- frame->status = short_framestatus;
- if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
-@@ -2388,8 +2391,9 @@ static int process_isoc_td(struct xhci_h
- break;
- case COMP_USB_TRANSACTION_ERROR:
- frame->status = -EPROTO;
-+ sum_trbs_for_length = true;
- if (ep_trb != td->last_trb)
-- return 0;
-+ td->error_mid_td = true;
- break;
- case COMP_STOPPED:
- sum_trbs_for_length = true;
-@@ -2409,6 +2413,9 @@ static int process_isoc_td(struct xhci_h
- break;
- }
-
-+ if (td->urb_length_set)
-+ goto finish_td;
-+
- if (sum_trbs_for_length)
- frame->actual_length = sum_trb_lengths(xhci, ep->ring, ep_trb) +
- ep_trb_len - remaining;
-@@ -2417,6 +2424,14 @@ static int process_isoc_td(struct xhci_h
-
- td->urb->actual_length += frame->actual_length;
-
-+finish_td:
-+ /* Don't give back TD yet if we encountered an error mid TD */
-+ if (td->error_mid_td && ep_trb != td->last_trb) {
-+ xhci_dbg(xhci, "Error mid isoc TD, wait for final completion event\n");
-+ td->urb_length_set = true;
-+ return 0;
-+ }
-+
- return finish_td(xhci, ep, ep_ring, td, trb_comp_code);
- }
-
-@@ -2801,17 +2816,51 @@ static int handle_tx_event(struct xhci_h
- }
-
- if (!ep_seg) {
-- if (!ep->skip ||
-- !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
-- /* Some host controllers give a spurious
-- * successful event after a short transfer.
-- * Ignore it.
-- */
-- if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&
-- ep_ring->last_td_was_short) {
-- ep_ring->last_td_was_short = false;
-- goto cleanup;
-+
-+ if (ep->skip && usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
-+ skip_isoc_td(xhci, td, ep, status);
-+ goto cleanup;
-+ }
-+
-+ /*
-+ * Some hosts give a spurious success event after a short
-+ * transfer. Ignore it.
-+ */
-+ if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&
-+ ep_ring->last_td_was_short) {
-+ ep_ring->last_td_was_short = false;
-+ goto cleanup;
-+ }
-+
-+ /*
-+ * xhci 4.10.2 states isoc endpoints should continue
-+ * processing the next TD if there was an error mid TD.
-+ * So host like NEC don't generate an event for the last
-+ * isoc TRB even if the IOC flag is set.
-+ * xhci 4.9.1 states that if there are errors in mult-TRB
-+ * TDs xHC should generate an error for that TRB, and if xHC
-+ * proceeds to the next TD it should genete an event for
-+ * any TRB with IOC flag on the way. Other host follow this.
-+ * So this event might be for the next TD.
-+ */
-+ if (td->error_mid_td &&
-+ !list_is_last(&td->td_list, &ep_ring->td_list)) {
-+ struct xhci_td *td_next = list_next_entry(td, td_list);
-+
-+ ep_seg = trb_in_td(xhci, td_next->start_seg, td_next->first_trb,
-+ td_next->last_trb, ep_trb_dma, false);
-+ if (ep_seg) {
-+ /* give back previous TD, start handling new */
-+ xhci_dbg(xhci, "Missing TD completion event after mid TD error\n");
-+ ep_ring->dequeue = td->last_trb;
-+ ep_ring->deq_seg = td->last_trb_seg;
-+ inc_deq(xhci, ep_ring);
-+ xhci_td_cleanup(xhci, td, ep_ring, td->status);
-+ td = td_next;
- }
-+ }
-+
-+ if (!ep_seg) {
- /* HC is busted, give up! */
- xhci_err(xhci,
- "ERROR Transfer event TRB DMA ptr not "
-@@ -2823,9 +2872,6 @@ static int handle_tx_event(struct xhci_h
- ep_trb_dma, true);
- return -ESHUTDOWN;
- }
--
-- skip_isoc_td(xhci, td, ep, status);
-- goto cleanup;
- }
- if (trb_comp_code == COMP_SHORT_PACKET)
- ep_ring->last_td_was_short = true;
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -1570,6 +1570,7 @@ struct xhci_td {
- struct xhci_segment *bounce_seg;
- /* actual_length of the URB has already been set */
- bool urb_length_set;
-+ bool error_mid_td;
- unsigned int num_trbs;
- };
-