From 158886cd2cf4599e04f9b7e10cb767f5f39b14f1 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Wed, 30 Nov 2011 16:37:41 +0800 Subject: xHCI: fix bug in xhci_clear_command_ring() When system enters suspend, xHCI driver clears command ring by writing zero to all the TRBs. However, this also writes zero to the Link TRB, and the ring is mangled. This may cause driver accesses wrong memory address and the result is unpredicted. When clear the command ring, keep the last Link TRB intact, only clear its cycle bit. This should fix the "command ring full" issue reported by Oliver Neukum. This should be backported to stable kernels as old as 2.6.37, since the commit 89821320 "xhci: Fix command ring replay after resume" is merged. Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp Reported-by: Oliver Neukum --- drivers/usb/host/xhci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index aa94c0195791..a1afb7c39f7e 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -711,7 +711,10 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) ring = xhci->cmd_ring; seg = ring->deq_seg; do { - memset(seg->trbs, 0, SEGMENT_SIZE); + memset(seg->trbs, 0, + sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1)); + seg->trbs[TRBS_PER_SEGMENT - 1].link.control &= + cpu_to_le32(~TRB_CYCLE); seg = seg->next; } while (seg != ring->deq_seg); -- cgit v1.2.3 From 0de13500ad1d8a66b7dc1e7fa517ea15a2625c9e Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 1 Dec 2011 10:30:16 -0800 Subject: Revert "xHCI: reset-on-resume quirk for NEC uPD720200" This reverts commit df711fc9962b9491af2b92bd0d21ecbfefe4e5fa. The commit added a reset-on-resume quirk because the NEC chipset stopped responding to commands about 30 minutes after a system resume from suspend. We thought it was a chipset issue, but it turns out that the xHCI driver was zeroing out the link TRB after a successful context restore during resume. The host controller would fall off the command ring sometime later, causing it to not respond to new commands. The link TRB issue has been fixed with commit 158886cd2cf4599e04f9b7e10cb767f5f39b14f1 "xHCI: fix bug in xhci_clear_command_ring()", so revert the reset-on-resume quirk, as it's not necessary. Commit df711fc9962b9491af2b92bd0d21ecbfefe4e5fa was marked for stable trees back to 2.6.37, but according to my mail, it has not made it into Linus' tree or the stable trees yet. Signed-off-by: Sarah Sharp Tested-by: Julian Sikorski Cc: Andiry Xu --- drivers/usb/host/xhci-pci.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index d2a7332daca4..ef98b38626fb 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -33,8 +33,6 @@ #define PCI_VENDOR_ID_ETRON 0x1b6f #define PCI_DEVICE_ID_ASROCK_P67 0x7023 -#define PCI_DEVICE_ID_NEC_uPD720200 0x0194 - static const char hcd_name[] = "xhci_hcd"; /* called after powerup, by probe or system-pm "wakeup" */ @@ -76,11 +74,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->revision); } - if (pdev->vendor == PCI_VENDOR_ID_NEC) { + if (pdev->vendor == PCI_VENDOR_ID_NEC) xhci->quirks |= XHCI_NEC_HOST; - if (pdev->device == PCI_DEVICE_ID_NEC_uPD720200) - xhci->quirks |= XHCI_RESET_ON_RESUME; - } if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96) xhci->quirks |= XHCI_AMD_0x96_HOST; -- cgit v1.2.3