aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 06e7023258d0..e5a01713f937 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1401,6 +1401,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1401 u32 added_ctxs; 1401 u32 added_ctxs;
1402 unsigned int last_ctx; 1402 unsigned int last_ctx;
1403 u32 new_add_flags, new_drop_flags, new_slot_info; 1403 u32 new_add_flags, new_drop_flags, new_slot_info;
1404 struct xhci_virt_device *virt_dev;
1404 int ret = 0; 1405 int ret = 0;
1405 1406
1406 ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); 1407 ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
@@ -1425,11 +1426,25 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1425 return 0; 1426 return 0;
1426 } 1427 }
1427 1428
1428 in_ctx = xhci->devs[udev->slot_id]->in_ctx; 1429 virt_dev = xhci->devs[udev->slot_id];
1429 out_ctx = xhci->devs[udev->slot_id]->out_ctx; 1430 in_ctx = virt_dev->in_ctx;
1431 out_ctx = virt_dev->out_ctx;
1430 ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); 1432 ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
1431 ep_index = xhci_get_endpoint_index(&ep->desc); 1433 ep_index = xhci_get_endpoint_index(&ep->desc);
1432 ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); 1434 ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
1435
1436 /* If this endpoint is already in use, and the upper layers are trying
1437 * to add it again without dropping it, reject the addition.
1438 */
1439 if (virt_dev->eps[ep_index].ring &&
1440 !(le32_to_cpu(ctrl_ctx->drop_flags) &
1441 xhci_get_endpoint_flag(&ep->desc))) {
1442 xhci_warn(xhci, "Trying to add endpoint 0x%x "
1443 "without dropping it.\n",
1444 (unsigned int) ep->desc.bEndpointAddress);
1445 return -EINVAL;
1446 }
1447
1433 /* If the HCD has already noted the endpoint is enabled, 1448 /* If the HCD has already noted the endpoint is enabled,
1434 * ignore this request. 1449 * ignore this request.
1435 */ 1450 */
@@ -1445,8 +1460,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
1445 * process context, not interrupt context (or so documenation 1460 * process context, not interrupt context (or so documenation
1446 * for usb_set_interface() and usb_set_configuration() claim). 1461 * for usb_set_interface() and usb_set_configuration() claim).
1447 */ 1462 */
1448 if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], 1463 if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) {
1449 udev, ep, GFP_NOIO) < 0) {
1450 dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", 1464 dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
1451 __func__, ep->desc.bEndpointAddress); 1465 __func__, ep->desc.bEndpointAddress);
1452 return -ENOMEM; 1466 return -ENOMEM;