Merge "usb: host: xhci: Change L1 timeout default to 128us"

This commit is contained in:
qctecmdr 2019-12-14 13:45:02 -08:00 • committed by Gerrit - the friendly Code Review server
commit 68ab595cfd
5 changed files with 345 additions and 28 deletions

View file

@ -8,7 +8,7 @@
* Some code borrowed from the Linux EHCI driver.
*/
#include <linux/gfp.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
@ -1065,6 +1065,151 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
return status;
}
static void xhci_single_step_completion(struct urb *urb)
{
struct completion *done = urb->context;
complete(done);
}
/*
* Allocate a URB and initialize the various fields of it.
* This API is used by the single_step_set_feature test of
* EHSET where IN packet of the GetDescriptor request is
* sent 15secs after the SETUP packet.
* Return NULL if failed.
*/
static struct urb *xhci_request_single_step_set_feature_urb(
struct usb_device *udev,
void *dr,
void *buf,
struct completion *done)
{
struct urb *urb;
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
struct usb_host_endpoint *ep;
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return NULL;
urb->pipe = usb_rcvctrlpipe(udev, 0);
ep = udev->ep_in[usb_pipeendpoint(urb->pipe)];
if (!ep) {
usb_free_urb(urb);
return NULL;
}
/*
* Initialize the various URB fields as these are used by the HCD
* driver to queue it and as well as when completion happens.
*/
urb->ep = ep;
urb->dev = udev;
urb->setup_packet = dr;
urb->transfer_buffer = buf;
urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
urb->complete = xhci_single_step_completion;
urb->status = -EINPROGRESS;
urb->actual_length = 0;
urb->transfer_flags = URB_DIR_IN;
usb_get_urb(urb);
atomic_inc(&urb->use_count);
atomic_inc(&urb->dev->urbnum);
usb_hcd_map_urb_for_dma(hcd, urb, GFP_KERNEL);
urb->context = done;
return urb;
}
/*
* This function implements the USB_PORT_FEAT_TEST handling of the
* SINGLE_STEP_SET_FEATURE test mode as defined in the Embedded
* High-Speed Electrical Test (EHSET) specification. This simply
* issues a GetDescriptor control transfer, with an inserted 15-second
* delay after the end of the SETUP stage and before the IN token of
* the DATA stage is set. The idea is that this gives the test operator
* enough time to configure the oscilloscope to perform a measurement
* of the response time between the DATA and ACK packets that follow.
*/
static int xhci_ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
{
int retval;
struct usb_ctrlrequest *dr;
struct urb *urb;
struct usb_device *udev;
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct usb_device_descriptor *buf;
unsigned long flags;
DECLARE_COMPLETION_ONSTACK(done);
/* Obtain udev of the rhub's child port */
udev = usb_hub_find_child(hcd->self.root_hub, port);
if (!udev) {
xhci_err(xhci, "No device attached to the RootHub\n");
return -ENODEV;
}
buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
if (!dr) {
kfree(buf);
return -ENOMEM;
}
/* Fill Setup packet for GetDescriptor */
dr->bRequestType = USB_DIR_IN;
dr->bRequest = USB_REQ_GET_DESCRIPTOR;
dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8);
dr->wIndex = 0;
dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE);
urb = xhci_request_single_step_set_feature_urb(udev, dr, buf, &done);
if (!urb) {
retval = -ENOMEM;
goto cleanup;
}
/* Now complete just the SETUP stage */
spin_lock_irqsave(&xhci->lock, flags);
retval = xhci_submit_single_step_set_feature(hcd, urb, 1);
spin_unlock_irqrestore(&xhci->lock, flags);
if (retval)
goto out1;
if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) {
usb_kill_urb(urb);
retval = -ETIMEDOUT;
xhci_err(xhci, "%s SETUP stage timed out on ep0\n", __func__);
goto out1;
}
/* Sleep for 15 seconds; HC will send SOFs during this period */
msleep(15 * 1000);
/* Complete remaining DATA and status stages. Re-use same URB */
urb->status = -EINPROGRESS;
usb_get_urb(urb);
atomic_inc(&urb->use_count);
atomic_inc(&urb->dev->urbnum);
spin_lock_irqsave(&xhci->lock, flags);
retval = xhci_submit_single_step_set_feature(hcd, urb, 0);
spin_unlock_irqrestore(&xhci->lock, flags);
if (!retval && !wait_for_completion_timeout(&done,
msecs_to_jiffies(2000))) {
usb_kill_urb(urb);
retval = -ETIMEDOUT;
xhci_err(xhci, "%s IN stage timed out on ep0\n", __func__);
}
out1:
usb_free_urb(urb);
cleanup:
kfree(dr);
kfree(buf);
return retval;
}
int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
u16 wIndex, char *buf, u16 wLength)
{
@ -1359,6 +1504,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
/* 4.19.6 Port Test Modes (USB2 Test Mode) */
if (hcd->speed != HCD_USB2)
goto error;
if (test_mode == 6) { /* TEST_SINGLE_STEP_SET_FEATURE */
spin_unlock_irqrestore(&xhci->lock, flags);
retval = xhci_ehset_single_step_set_feature(hcd,
wIndex);
spin_lock_irqsave(&xhci->lock, flags);
break;
}
if (test_mode > TEST_FORCE_EN || test_mode < TEST_J)
goto error;
retval = xhci_enter_test_mode(xhci, test_mode, wIndex,

View file

@ -193,6 +193,14 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (!sysdev)
sysdev = &pdev->dev;
/*
* If sysdev dev is having parent i.e. "linux,sysdev_is_parent" is true,
* then use sysdev->parent device.
*/
if (sysdev->parent && sysdev->parent->of_node &&
device_property_read_bool(sysdev, "linux,sysdev_is_parent"))
sysdev = sysdev->parent;
/* Try to set 64-bit DMA first */
if (WARN_ON(!sysdev->dma_mask))
/* Platform did not initialize dma_mask */
@ -382,33 +390,21 @@ static int xhci_plat_remove(struct platform_device *dev)
return 0;
}
static int __maybe_unused xhci_plat_suspend(struct device *dev)
static int __maybe_unused xhci_plat_runtime_idle(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
/*
* xhci_suspend() needs `do_wakeup` to know whether host is allowed
* to do wakeup during suspend. Since xhci_plat_suspend is currently
* only designed for system suspend, device_may_wakeup() is enough
* to dertermine whether host is allowed to do wakeup. Need to
* reconsider this when xhci_plat_suspend enlarges its scope, e.g.,
* also applies to runtime suspend.
* When pm_runtime_put_autosuspend() is called on this device,
* after this idle callback returns the PM core will schedule the
* autosuspend if there is any remaining time until expiry. However,
* when reaching this point because the child_count becomes 0, the
* core does not honor autosuspend in that case and results in
* idle/suspend happening immediately. In order to have a delay
* before suspend we have to call pm_runtime_autosuspend() manually.
*/
return xhci_suspend(xhci, device_may_wakeup(dev));
}
static int __maybe_unused xhci_plat_resume(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int ret;
ret = xhci_priv_resume_quirk(hcd);
if (ret)
return ret;
return xhci_resume(xhci, 0);
pm_runtime_mark_last_busy(dev);
pm_runtime_autosuspend(dev);
return -EBUSY;
}
static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev)
@ -423,12 +419,25 @@ static int __maybe_unused xhci_plat_runtime_resume(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int ret;
return xhci_resume(xhci, 0);
if (!xhci)
return 0;
dev_dbg(dev, "xhci-plat runtime resume\n");
ret = xhci_priv_resume_quirk(hcd);
if (ret)
return ret;
ret = xhci_resume(xhci, false);
pm_runtime_mark_last_busy(dev);
return ret;
}
static const struct dev_pm_ops xhci_plat_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume)
SET_SYSTEM_SLEEP_PM_OPS(NULL, NULL)
SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend,
xhci_plat_runtime_resume,

View file

@ -3519,6 +3519,150 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
return 0;
}
/*
* Variant of xhci_queue_ctrl_tx() used to implement EHSET
* SINGLE_STEP_SET_FEATURE test mode. It differs in that the control
* transfer is broken up so that the SETUP stage can happen and call
* the URB's completion handler before the DATA/STATUS stages are
* executed by the xHC hardware. This assumes the control transfer is a
* GetDescriptor, with a DATA stage in the IN direction, and an OUT
* STATUS stage.
*
* This function is called twice, usually with a 15-second delay in between.
* - with is_setup==true, the SETUP stage for the control request
* (GetDescriptor) is queued in the TRB ring and sent to HW immediately
* - with is_setup==false, the DATA and STATUS TRBs are queued and exceuted
*
* Caller must have locked xhci->lock
*/
int xhci_submit_single_step_set_feature(struct usb_hcd *hcd, struct urb *urb,
int is_setup)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_ring *ep_ring;
int num_trbs;
int ret;
unsigned int slot_id, ep_index;
struct usb_ctrlrequest *setup;
struct xhci_generic_trb *start_trb;
int start_cycle;
u32 field, length_field, remainder;
struct urb_priv *urb_priv;
struct xhci_td *td;
ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
if (!ep_ring)
return -EINVAL;
/* Need buffer for data stage */
if (urb->transfer_buffer_length <= 0)
return -EINVAL;
/*
* Need to copy setup packet into setup TRB, so we can't use the setup
* DMA address.
*/
if (!urb->setup_packet)
return -EINVAL;
setup = (struct usb_ctrlrequest *) urb->setup_packet;
slot_id = urb->dev->slot_id;
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
urb_priv = kzalloc(sizeof(struct urb_priv) +
sizeof(struct xhci_td *), GFP_ATOMIC);
if (!urb_priv)
return -ENOMEM;
td = &urb_priv->td[0];
urb_priv->num_tds = 1;
urb_priv->num_tds_done = 0;
urb->hcpriv = urb_priv;
num_trbs = is_setup ? 1 : 2;
ret = prepare_transfer(xhci, xhci->devs[slot_id],
ep_index, urb->stream_id,
num_trbs, urb, 0, GFP_ATOMIC);
if (ret < 0) {
kfree(urb_priv);
return ret;
}
/*
* Don't give the first TRB to the hardware (by toggling the cycle bit)
* until we've finished creating all the other TRBs. The ring's cycle
* state may change as we enqueue the other TRBs, so save it too.
*/
start_trb = &ep_ring->enqueue->generic;
start_cycle = ep_ring->cycle_state;
if (is_setup) {
/* Queue only the setup TRB */
field = TRB_IDT | TRB_IOC | TRB_TYPE(TRB_SETUP);
if (start_cycle == 0)
field |= 0x1;
/* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */
if (xhci->hci_version >= 0x100) {
if (setup->bRequestType & USB_DIR_IN)
field |= TRB_TX_TYPE(TRB_DATA_IN);
else
field |= TRB_TX_TYPE(TRB_DATA_OUT);
}
/* Save the DMA address of the last TRB in the TD */
td->last_trb = ep_ring->enqueue;
queue_trb(xhci, ep_ring, false,
setup->bRequestType | setup->bRequest << 8 |
le16_to_cpu(setup->wValue) << 16,
le16_to_cpu(setup->wIndex) |
le16_to_cpu(setup->wLength) << 16,
TRB_LEN(8) | TRB_INTR_TARGET(0),
field);
} else {
/* Queue data TRB */
field = TRB_ISP | TRB_TYPE(TRB_DATA);
if (start_cycle == 0)
field |= 0x1;
if (setup->bRequestType & USB_DIR_IN)
field |= TRB_DIR_IN;
remainder = xhci_td_remainder(xhci, 0,
urb->transfer_buffer_length,
urb->transfer_buffer_length,
urb, 1);
length_field = TRB_LEN(urb->transfer_buffer_length) |
TRB_TD_SIZE(remainder) |
TRB_INTR_TARGET(0);
queue_trb(xhci, ep_ring, true,
lower_32_bits(urb->transfer_dma),
upper_32_bits(urb->transfer_dma),
length_field,
field);
/* Save the DMA address of the last TRB in the TD */
td->last_trb = ep_ring->enqueue;
/* Queue status TRB */
field = TRB_IOC | TRB_TYPE(TRB_STATUS);
if (!(setup->bRequestType & USB_DIR_IN))
field |= TRB_DIR_IN;
queue_trb(xhci, ep_ring, false,
0,
0,
TRB_INTR_TARGET(0),
field | ep_ring->cycle_state);
}
giveback_first_trb(xhci, slot_id, ep_index, 0, start_cycle, start_trb);
return 0;
}
/*
* The transfer burst count field of the isochronous TRB defines the number of
* bursts that are required to move all packets in this TD. Only SuperSpeed

View file

@ -132,7 +132,13 @@ int xhci_start(struct xhci_hcd *xhci)
{
u32 temp;
int ret;
struct usb_hcd *hcd = xhci_to_hcd(xhci);
/*
* disable irq to avoid xhci_irq flooding due to unhandeled port
* change event in halt state, as soon as xhci_start clears halt bit
*/
disable_irq(hcd->irq);
temp = readl(&xhci->op_regs->command);
temp |= (CMD_RUN);
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Turn on HC, cmd = 0x%x.",
@ -153,6 +159,8 @@ int xhci_start(struct xhci_hcd *xhci)
/* clear state flags. Including dying, halted or removing */
xhci->xhc_state = 0;
enable_irq(hcd->irq);
return ret;
}

View file

@ -437,8 +437,8 @@ struct xhci_op_regs {
#define PORT_L1_TIMEOUT(p)(((p) & 0xff) << 2)
#define PORT_BESLD(p)(((p) & 0xf) << 10)
/* use 512 microseconds as USB2 LPM L1 default timeout. */
#define XHCI_L1_TIMEOUT 512
/* use 128 microseconds as USB2 LPM L1 default timeout. */
#define XHCI_L1_TIMEOUT 128
/* Set default HIRD/BESL value to 4 (350/400us) for USB2 L1 LPM resume latency.
* Safe to use with mixed HIRD and BESL systems (host and device) and is used
@ -2674,4 +2674,8 @@ static inline const char *xhci_decode_ep_context(u32 info, u32 info2, u64 deq,
return str;
}
/* EHSET */
int xhci_submit_single_step_set_feature(struct usb_hcd *hcd, struct urb *urb,
int is_setup);
#endif /* __LINUX_XHCI_HCD_H */