mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-17 19:18:38 +07:00
xhci: isoc, Intel xHCI, and suspend races.
Hi Greg, Here's some xHCI fixes that should be queued for 3.5. The first patch builds on Alan Stern's 3.4 patch to close the suspend and port event race conditions. It's marked for 3.4 stable, since that's where Alan's patch landed. The second patch fixes an incorrect error code that the xHCI driver would return when an isochronous transfer error occurred. The third and fourth patches fix issues seen on Intel xHCI host controllers. The third patch fixes a dead port issue that was seen on the Panther Point EHCI/xHCI host when CONFIG_USB_XHCI_HCD was turned off. The ports were being switched over to xHCI, even though the xHCI driver was never even built. The fourth patch adds support for the EHCI to xHCI port switchover for the upcoming Intel Lynx Point chipset. As I said, there's nothing here that's terribly urgent, and these patches can wait a couple weeks for the 3.5 merge window. Thanks, Sarah Sharp -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJPounlAAoJEBMGWMLi1Gc55twQAJm/cOCW4NI3aLfW44nsc3UM WFSXpu8MgaNXqQJrdaFjLAlrSWob2t2uAlI+Rr178ltpu7tOFUCBgmYp8P2eQwEF K6wM/464SaQYIPQjxAekTRWwxAKM9eSI6CahFHn+M6nAQY8TJkUqDuE4I/EAIHgQ R71OYPLvEP2w5vMi+ObkGdy6PFcIbSpDQM+trgCj3MUuaX1m0kWQjIIvgCByvdxU twhxOL/P6WheYCyttbr0H/PsX57jRkpV4Sjr0UJ6TdDI6aB7ZWa977+IWyf3TmUc mvtMBU2Kv4jts8Bkzzulz0uCKbFYQ30MihXua8nwXP/sph6dnIhwr+dYhb/HPp3a DrEzBiqcH1ASgBX/kvZ52UjTf4aP0vuK6nS/VsQYH7a23pO4Qd3aX41lJy/bFnt+ u/GHeFlEQ3BmxNwMMSGHQibqAK194zvGSDs2XyPnK6PQqBiMnm77DAhzOqPP1L2f Z3do/dOeNRTeGknJXrgc8Eq/C4HVQ+S5MsTv3GZp/PlSTe+aGAgontH9Rj11bvs3 FJng2S/zee/IBhuWkK9wdqud5gqZbBFw7MU3cfrGH5KzdOPsRJ6+XFfuCqLzo110 inLhytN+urvvuZspr/gCCeW+PLDaYbYK/pw1ge0UUxWrRy0IE2spjW/Q3cdq5vL1 brPKwwF7PsPZ6IiTY5RR =WrEx -----END PGP SIGNATURE----- Merge tag 'for-usb-next-2012-05-03' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-next xhci: isoc, Intel xHCI, and suspend races. Hi Greg, Here's some xHCI fixes that should be queued for 3.5. The first patch builds on Alan Stern's 3.4 patch to close the suspend and port event race conditions. It's marked for 3.4 stable, since that's where Alan's patch landed. The second patch fixes an incorrect error code that the xHCI driver would return when an isochronous transfer error occurred. The third and fourth patches fix issues seen on Intel xHCI host controllers. The third patch fixes a dead port issue that was seen on the Panther Point EHCI/xHCI host when CONFIG_USB_XHCI_HCD was turned off. The ports were being switched over to xHCI, even though the xHCI driver was never even built. The fourth patch adds support for the EHCI to xHCI port switchover for the upcoming Intel Lynx Point chipset. As I said, there's nothing here that's terribly urgent, and these patches can wait a couple weeks for the 3.5 merge window. Thanks, Sarah Sharp
This commit is contained in:
commit
cbad67e33d
@ -360,7 +360,9 @@ static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev)
|
||||
{
|
||||
return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
|
||||
pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
pdev->device == 0x1E26;
|
||||
(pdev->device == 0x1E26 ||
|
||||
pdev->device == 0x8C2D ||
|
||||
pdev->device == 0x8C26);
|
||||
}
|
||||
|
||||
static void ehci_enable_xhci_companion(void)
|
||||
|
@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
@ -712,12 +713,28 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done,
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
|
||||
#define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI 0x8C31
|
||||
|
||||
bool usb_is_intel_ppt_switchable_xhci(struct pci_dev *pdev)
|
||||
{
|
||||
return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
|
||||
pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI;
|
||||
}
|
||||
|
||||
/* The Intel Lynx Point chipset also has switchable ports. */
|
||||
bool usb_is_intel_lpt_switchable_xhci(struct pci_dev *pdev)
|
||||
{
|
||||
return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
|
||||
pdev->vendor == PCI_VENDOR_ID_INTEL &&
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI;
|
||||
}
|
||||
|
||||
bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
|
||||
{
|
||||
return usb_is_intel_ppt_switchable_xhci(pdev) ||
|
||||
usb_is_intel_lpt_switchable_xhci(pdev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci);
|
||||
|
||||
/*
|
||||
@ -742,6 +759,19 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
|
||||
{
|
||||
u32 ports_available;
|
||||
|
||||
/* Don't switchover the ports if the user hasn't compiled the xHCI
|
||||
* driver. Otherwise they will see "dead" USB ports that don't power
|
||||
* the devices.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_USB_XHCI_HCD)) {
|
||||
dev_warn(&xhci_pdev->dev,
|
||||
"CONFIG_USB_XHCI_HCD is turned off, "
|
||||
"defaulting to EHCI.\n");
|
||||
dev_warn(&xhci_pdev->dev,
|
||||
"USB 3.0 devices will work at USB 2.0 speeds.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ports_available = 0xffffffff;
|
||||
/* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable
|
||||
* Register, to turn on SuperSpeed terminations for all
|
||||
|
@ -558,6 +558,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
xhci_dbg(xhci, "Resume USB2 port %d\n",
|
||||
wIndex + 1);
|
||||
bus_state->resume_done[wIndex] = 0;
|
||||
clear_bit(wIndex, &bus_state->resuming_ports);
|
||||
xhci_set_link_state(xhci, port_array, wIndex,
|
||||
XDEV_U0);
|
||||
xhci_dbg(xhci, "set port %d resume\n",
|
||||
@ -845,7 +846,12 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
|
||||
/* Initial status is no changes */
|
||||
retval = (max_ports + 8) / 8;
|
||||
memset(buf, 0, retval);
|
||||
status = 0;
|
||||
|
||||
/*
|
||||
* Inform the usbcore about resume-in-progress by returning
|
||||
* a non-zero value even if there are no status changes.
|
||||
*/
|
||||
status = bus_state->resuming_ports;
|
||||
|
||||
mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC;
|
||||
|
||||
@ -885,15 +891,11 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
|
||||
if (hcd->self.root_hub->do_remote_wakeup) {
|
||||
port_index = max_ports;
|
||||
while (port_index--) {
|
||||
if (bus_state->resume_done[port_index] != 0) {
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
xhci_dbg(xhci, "suspend failed because "
|
||||
"port %d is resuming\n",
|
||||
port_index + 1);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (bus_state->resuming_ports) {
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
xhci_dbg(xhci, "suspend failed because "
|
||||
"a port is resuming\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1377,6 +1377,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
|
||||
xhci_dbg(xhci, "resume HS port %d\n", port_id);
|
||||
bus_state->resume_done[faked_port_index] = jiffies +
|
||||
msecs_to_jiffies(20);
|
||||
set_bit(faked_port_index, &bus_state->resuming_ports);
|
||||
mod_timer(&hcd->rh_timer,
|
||||
bus_state->resume_done[faked_port_index]);
|
||||
/* Do the rest in GetPortStatus */
|
||||
@ -1803,6 +1804,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||
break;
|
||||
case COMP_DEV_ERR:
|
||||
case COMP_STALL:
|
||||
case COMP_TX_ERR:
|
||||
frame->status = -EPROTO;
|
||||
skip_td = true;
|
||||
break;
|
||||
|
@ -152,7 +152,7 @@ int xhci_reset(struct xhci_hcd *xhci)
|
||||
{
|
||||
u32 command;
|
||||
u32 state;
|
||||
int ret;
|
||||
int ret, i;
|
||||
|
||||
state = xhci_readl(xhci, &xhci->op_regs->status);
|
||||
if ((state & STS_HALT) == 0) {
|
||||
@ -175,7 +175,15 @@ int xhci_reset(struct xhci_hcd *xhci)
|
||||
* xHCI cannot write to any doorbells or operational registers other
|
||||
* than status until the "Controller Not Ready" flag is cleared.
|
||||
*/
|
||||
return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000);
|
||||
ret = handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000);
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
xhci->bus_state[i].port_c_suspend = 0;
|
||||
xhci->bus_state[i].suspended_ports = 0;
|
||||
xhci->bus_state[i].resuming_ports = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
@ -1362,6 +1362,8 @@ struct xhci_bus_state {
|
||||
u32 suspended_ports;
|
||||
u32 port_remote_wakeup;
|
||||
unsigned long resume_done[USB_MAXCHILDREN];
|
||||
/* which ports have started to resume */
|
||||
unsigned long resuming_ports;
|
||||
};
|
||||
|
||||
static inline unsigned int hcd_index(struct usb_hcd *hcd)
|
||||
|
Loading…
Reference in New Issue
Block a user