All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/3] xhci: don't finish a TD if we get a short transfer event mid TD
       [not found] <1444638613-10189-1-git-send-email-mathias.nyman@linux.intel.com>
@ 2015-10-12  8:30 ` Mathias Nyman
  2015-10-12  8:30 ` [PATCH v2 2/3] xhci: handle no ping response error properly Mathias Nyman
  2015-10-12  8:30 ` [PATCH v2 3/3] Add spurious wakeup quirk for LynxPoint-LP controllers Mathias Nyman
  2 siblings, 0 replies; 3+ messages in thread
From: Mathias Nyman @ 2015-10-12  8:30 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, pauldzim, Mathias Nyman, stable

If the difference is big enough between the bytes asked and received
in a bulk transfer we can get a short transfer event pointing to a TRB in
the middle of the TD. We don't want to handle the TD yet as we will anyway
receive a new event for the last TRB in the TD.

Hold off from finishing the TD and removing it from the list until we
receive an event for the last TRB in the TD

Cc: stable <stable@vger.kernel.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-ring.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 43291f9..79e89e6 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2191,6 +2191,10 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
 		}
 	/* Fast path - was this the last TRB in the TD for this URB? */
 	} else if (event_trb == td->last_trb) {
+		if (td->urb_length_set && trb_comp_code == COMP_SHORT_TX)
+			return finish_td(xhci, td, event_trb, event, ep,
+					 status, false);
+
 		if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
 			td->urb->actual_length =
 				td->urb->transfer_buffer_length -
@@ -2242,6 +2246,12 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
 			td->urb->actual_length +=
 				TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
 				EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
+
+		if (trb_comp_code == COMP_SHORT_TX) {
+			xhci_dbg(xhci, "mid bulk/intr SP, wait for last TRB event\n");
+			td->urb_length_set = true;
+			return 0;
+		}
 	}
 
 	return finish_td(xhci, td, event_trb, event, ep, status, false);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 2/3] xhci: handle no ping response error properly
       [not found] <1444638613-10189-1-git-send-email-mathias.nyman@linux.intel.com>
  2015-10-12  8:30 ` [PATCH v2 1/3] xhci: don't finish a TD if we get a short transfer event mid TD Mathias Nyman
@ 2015-10-12  8:30 ` Mathias Nyman
  2015-10-12  8:30 ` [PATCH v2 3/3] Add spurious wakeup quirk for LynxPoint-LP controllers Mathias Nyman
  2 siblings, 0 replies; 3+ messages in thread
From: Mathias Nyman @ 2015-10-12  8:30 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, pauldzim, Mathias Nyman, stable

If a host fails to wake up a isochronous SuperSpeed device from U1/U2
in time for a isoch transfer it will generate a "No ping response error"
Host will then move to the next transfer descriptor.

Handle this case in the same way as missed service errors, tag the
current TD as skipped and handle it on the next transfer event.

Cc: stable <stable@vger.kernel.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-ring.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 79e89e6..97ffe39 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2284,6 +2284,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 	u32 trb_comp_code;
 	int ret = 0;
 	int td_num = 0;
+	bool handling_skipped_tds = false;
 
 	slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
 	xdev = xhci->devs[slot_id];
@@ -2420,6 +2421,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 		ep->skip = true;
 		xhci_dbg(xhci, "Miss service interval error, set skip flag\n");
 		goto cleanup;
+	case COMP_PING_ERR:
+		ep->skip = true;
+		xhci_dbg(xhci, "No Ping response error, Skip one Isoc TD\n");
+		goto cleanup;
 	default:
 		if (xhci_is_vendor_info_code(xhci, trb_comp_code)) {
 			status = 0;
@@ -2556,13 +2561,18 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 						 ep, &status);
 
 cleanup:
+
+
+		handling_skipped_tds = ep->skip &&
+			trb_comp_code != COMP_MISSED_INT &&
+			trb_comp_code != COMP_PING_ERR;
+
 		/*
-		 * Do not update event ring dequeue pointer if ep->skip is set.
-		 * Will roll back to continue process missed tds.
+		 * Do not update event ring dequeue pointer if we're in a loop
+		 * processing missed tds.
 		 */
-		if (trb_comp_code == COMP_MISSED_INT || !ep->skip) {
+		if (!handling_skipped_tds)
 			inc_deq(xhci, xhci->event_ring);
-		}
 
 		if (ret) {
 			urb = td->urb;
@@ -2597,7 +2607,7 @@ cleanup:
 	 * Process them as short transfer until reach the td pointed by
 	 * the event.
 	 */
-	} while (ep->skip && trb_comp_code != COMP_MISSED_INT);
+	} while (handling_skipped_tds);
 
 	return 0;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2 3/3] Add spurious wakeup quirk for LynxPoint-LP controllers
       [not found] <1444638613-10189-1-git-send-email-mathias.nyman@linux.intel.com>
  2015-10-12  8:30 ` [PATCH v2 1/3] xhci: don't finish a TD if we get a short transfer event mid TD Mathias Nyman
  2015-10-12  8:30 ` [PATCH v2 2/3] xhci: handle no ping response error properly Mathias Nyman
@ 2015-10-12  8:30 ` Mathias Nyman
  2 siblings, 0 replies; 3+ messages in thread
From: Mathias Nyman @ 2015-10-12  8:30 UTC (permalink / raw)
  To: gregkh
  Cc: linux-usb, pauldzim, Laura Abbott, Takashi Iwai, Oliver Neukum,
	stable, Mathias Nyman

From: Laura Abbott <labbott@fedoraproject.org>

We received several reports of systems rebooting and powering on
after an attempted shutdown. Testing showed that setting
XHCI_SPURIOUS_WAKEUP quirk in addition to the XHCI_SPURIOUS_REBOOT
quirk allowed the system to shutdown as expected for LynxPoint-LP
xHCI controllers. Set the quirk back.

Note that the quirk was originally introduced for LynxPoint and
LynxPoint-LP just for this same reason. See:

commit 638298dc66ea ("xhci: Fix spurious wakeups after S5 on Haswell")

It was later limited to only concern HP machines as it caused
regression on some machines, see both bug and commit:

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=66171
commit 6962d914f317 ("xhci: Limit the spurious wakeup fix only to HP machines")

Later it was discovered that the powering on after shutdown
was limited to LynxPoint-LP (Haswell-ULT) and that some non-LP HP
machine suffered from spontaneous resume from S3 (which should
not be related to the SPURIOUS_WAKEUP quirk at all). An attempt
to fix this then removed the SPURIOUS_WAKEUP flag usage completely.

commit b45abacde3d5 ("xhci: no switching back on non-ULT Haswell")

Current understanding is that LynxPoint-LP (Haswell ULT) machines
need the SPURIOUS_WAKEUP quirk, otherwise they will restart, and
plain Lynxpoint (Haswell) machines may _not_ have the quirk
set otherwise they again will restart.

Signed-off-by: Laura Abbott <labbott@fedoraproject.org>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Oliver Neukum <oneukum@suse.com>
[Added more history to commit message -Mathias]
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index c79d336..c47d3e4 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -147,6 +147,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
 		pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
 		xhci->quirks |= XHCI_SPURIOUS_REBOOT;
+		xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
 	}
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
 		(pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-10-12  8:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1444638613-10189-1-git-send-email-mathias.nyman@linux.intel.com>
2015-10-12  8:30 ` [PATCH v2 1/3] xhci: don't finish a TD if we get a short transfer event mid TD Mathias Nyman
2015-10-12  8:30 ` [PATCH v2 2/3] xhci: handle no ping response error properly Mathias Nyman
2015-10-12  8:30 ` [PATCH v2 3/3] Add spurious wakeup quirk for LynxPoint-LP controllers Mathias Nyman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.