aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2014-06-24 10:14:42 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-24 12:31:11 -0400
commitd6759133e9815ef807b17dc752aff8c3771b7444 (patch)
treedd9c703b6f9ee3c0c001d4d86c4a1f02e10b853f /drivers/usb/host/xhci.c
parenta497c3ba1d97fc69c1e78e7b96435ba8c2cb42ee (diff)
usb: xhci: Correct last context entry calculation for Configure Endpoint
The current XHCI driver recalculates the Context Entries field in the Slot Context on every add_endpoint() and drop_endpoint() call. In the case of drop_endpoint(), it seems to assume that the add_flags will always contain every endpoint for the new configuration, which is not necessarily correct if you don't make assumptions about how the USB core uses the add_endpoint/drop_endpoint interface (add_flags only contains endpoints that are new additions in the new configuration). Furthermore, EP0_FLAG is not consistently set in add_flags throughout the lifetime of a device. This means that when all endpoints are dropped, the Context Entries field can be set to 0 (which is invalid and may cause a Parameter Error) or -1 (which is interpreted as 31 and causes the driver to keep using the old, incorrect value). The only surefire way to set this field right is to also take all existing endpoints into account, and to force the value to 1 (meaning only EP0 is active) if no other endpoint is found. This patch implements that as a single step in the final check_bandwidth() call and removes the intermediary calculations from add_endpoint() and drop_endpoint(). Signed-off-by: Julius Werner <jwerner@chromium.org> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r--drivers/usb/host/xhci.c51
1 files changed, 18 insertions, 33 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2b8d9a24af09..013aabb5b379 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1582,12 +1582,10 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1582 struct xhci_hcd *xhci; 1582 struct xhci_hcd *xhci;
1583 struct xhci_container_ctx *in_ctx, *out_ctx; 1583 struct xhci_container_ctx *in_ctx, *out_ctx;
1584 struct xhci_input_control_ctx *ctrl_ctx; 1584 struct xhci_input_control_ctx *ctrl_ctx;
1585 struct xhci_slot_ctx *slot_ctx;
1586 unsigned int last_ctx;
1587 unsigned int ep_index; 1585 unsigned int ep_index;
1588 struct xhci_ep_ctx *ep_ctx; 1586 struct xhci_ep_ctx *ep_ctx;
1589 u32 drop_flag; 1587 u32 drop_flag;
1590 u32 new_add_flags, new_drop_flags, new_slot_info; 1588 u32 new_add_flags, new_drop_flags;
1591 int ret; 1589 int ret;
1592 1590
1593 ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); 1591 ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
@@ -1634,24 +1632,13 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1634 ctrl_ctx->add_flags &= cpu_to_le32(~drop_flag); 1632 ctrl_ctx->add_flags &= cpu_to_le32(~drop_flag);
1635 new_add_flags = le32_to_cpu(ctrl_ctx->add_flags); 1633 new_add_flags = le32_to_cpu(ctrl_ctx->add_flags);
1636 1634
1637 last_ctx = xhci_last_valid_endpoint(le32_to_cpu(ctrl_ctx->add_flags));
1638 slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
1639 /* Update the last valid endpoint context, if we deleted the last one */
1640 if ((le32_to_cpu(slot_ctx->dev_info) & LAST_CTX_MASK) >
1641 LAST_CTX(last_ctx)) {
1642 slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK);
1643 slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(last_ctx));
1644 }
1645 new_slot_info = le32_to_cpu(slot_ctx->dev_info);
1646
1647 xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); 1635 xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
1648 1636
1649 xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", 1637 xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n",
1650 (unsigned int) ep->desc.bEndpointAddress, 1638 (unsigned int) ep->desc.bEndpointAddress,
1651 udev->slot_id, 1639 udev->slot_id,
1652 (unsigned int) new_drop_flags, 1640 (unsigned int) new_drop_flags,
1653 (unsigned int) new_add_flags, 1641 (unsigned int) new_add_flags);
1654 (unsigned int) new_slot_info);
1655 return 0; 1642 return 0;
1656} 1643}
1657 1644
@@ -1674,11 +1661,9 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1674 struct xhci_hcd *xhci; 1661 struct xhci_hcd *xhci;
1675 struct xhci_container_ctx *in_ctx, *out_ctx; 1662 struct xhci_container_ctx *in_ctx, *out_ctx;
1676 unsigned int ep_index; 1663 unsigned int ep_index;
1677 struct xhci_slot_ctx *slot_ctx;
1678 struct xhci_input_control_ctx *ctrl_ctx; 1664 struct xhci_input_control_ctx *ctrl_ctx;
1679 u32 added_ctxs; 1665 u32 added_ctxs;
1680 unsigned int last_ctx; 1666 u32 new_add_flags, new_drop_flags;
1681 u32 new_add_flags, new_drop_flags, new_slot_info;
1682 struct xhci_virt_device *virt_dev; 1667 struct xhci_virt_device *virt_dev;
1683 int ret = 0; 1668 int ret = 0;
1684 1669
@@ -1693,7 +1678,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1693 return -ENODEV; 1678 return -ENODEV;
1694 1679
1695 added_ctxs = xhci_get_endpoint_flag(&ep->desc); 1680 added_ctxs = xhci_get_endpoint_flag(&ep->desc);
1696 last_ctx = xhci_last_valid_endpoint(added_ctxs);
1697 if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { 1681 if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) {
1698 /* FIXME when we have to issue an evaluate endpoint command to 1682 /* FIXME when we have to issue an evaluate endpoint command to
1699 * deal with ep0 max packet size changing once we get the 1683 * deal with ep0 max packet size changing once we get the
@@ -1759,24 +1743,14 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1759 */ 1743 */
1760 new_drop_flags = le32_to_cpu(ctrl_ctx->drop_flags); 1744 new_drop_flags = le32_to_cpu(ctrl_ctx->drop_flags);
1761 1745
1762 slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
1763 /* Update the last valid endpoint context, if we just added one past */
1764 if ((le32_to_cpu(slot_ctx->dev_info) & LAST_CTX_MASK) <
1765 LAST_CTX(last_ctx)) {
1766 slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK);
1767 slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(last_ctx));
1768 }
1769 new_slot_info = le32_to_cpu(slot_ctx->dev_info);
1770
1771 /* Store the usb_device pointer for later use */ 1746 /* Store the usb_device pointer for later use */
1772 ep->hcpriv = udev; 1747 ep->hcpriv = udev;
1773 1748
1774 xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", 1749 xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n",
1775 (unsigned int) ep->desc.bEndpointAddress, 1750 (unsigned int) ep->desc.bEndpointAddress,
1776 udev->slot_id, 1751 udev->slot_id,
1777 (unsigned int) new_drop_flags, 1752 (unsigned int) new_drop_flags,
1778 (unsigned int) new_add_flags, 1753 (unsigned int) new_add_flags);
1779 (unsigned int) new_slot_info);
1780 return 0; 1754 return 0;
1781} 1755}
1782 1756
@@ -2746,8 +2720,19 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
2746 ret = 0; 2720 ret = 0;
2747 goto command_cleanup; 2721 goto command_cleanup;
2748 } 2722 }
2749 xhci_dbg(xhci, "New Input Control Context:\n"); 2723 /* Fix up Context Entries field. Minimum value is EP0 == BIT(1). */
2750 slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); 2724 slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
2725 for (i = 31; i >= 1; i--) {
2726 __le32 le32 = cpu_to_le32(BIT(i));
2727
2728 if ((virt_dev->eps[i-1].ring && !(ctrl_ctx->drop_flags & le32))
2729 || (ctrl_ctx->add_flags & le32) || i == 1) {
2730 slot_ctx->dev_info &= cpu_to_le32(~LAST_CTX_MASK);
2731 slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(i));
2732 break;
2733 }
2734 }
2735 xhci_dbg(xhci, "New Input Control Context:\n");
2751 xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2736 xhci_dbg_ctx(xhci, virt_dev->in_ctx,
2752 LAST_CTX_TO_EP_NUM(le32_to_cpu(slot_ctx->dev_info))); 2737 LAST_CTX_TO_EP_NUM(le32_to_cpu(slot_ctx->dev_info)));
2753 2738