diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 06e7023258d0..f5fe1ac301ab 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -759,6 +759,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
759 | msleep(100); | 759 | msleep(100); |
760 | 760 | ||
761 | spin_lock_irq(&xhci->lock); | 761 | spin_lock_irq(&xhci->lock); |
762 | if (xhci->quirks & XHCI_RESET_ON_RESUME) | ||
763 | hibernated = true; | ||
762 | 764 | ||
763 | if (!hibernated) { | 765 | if (!hibernated) { |
764 | /* step 1: restore register */ | 766 | /* step 1: restore register */ |
@@ -1401,6 +1403,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1401 | u32 added_ctxs; | 1403 | u32 added_ctxs; |
1402 | unsigned int last_ctx; | 1404 | unsigned int last_ctx; |
1403 | u32 new_add_flags, new_drop_flags, new_slot_info; | 1405 | u32 new_add_flags, new_drop_flags, new_slot_info; |
1406 | struct xhci_virt_device *virt_dev; | ||
1404 | int ret = 0; | 1407 | int ret = 0; |
1405 | 1408 | ||
1406 | ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); | 1409 | ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); |
@@ -1425,11 +1428,25 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1425 | return 0; | 1428 | return 0; |
1426 | } | 1429 | } |
1427 | 1430 | ||
1428 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; | 1431 | virt_dev = xhci->devs[udev->slot_id]; |
1429 | out_ctx = xhci->devs[udev->slot_id]->out_ctx; | 1432 | in_ctx = virt_dev->in_ctx; |
1433 | out_ctx = virt_dev->out_ctx; | ||
1430 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | 1434 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); |
1431 | ep_index = xhci_get_endpoint_index(&ep->desc); | 1435 | ep_index = xhci_get_endpoint_index(&ep->desc); |
1432 | ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); | 1436 | ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); |
1437 | |||
1438 | /* If this endpoint is already in use, and the upper layers are trying | ||
1439 | * to add it again without dropping it, reject the addition. | ||
1440 | */ | ||
1441 | if (virt_dev->eps[ep_index].ring && | ||
1442 | !(le32_to_cpu(ctrl_ctx->drop_flags) & | ||
1443 | xhci_get_endpoint_flag(&ep->desc))) { | ||
1444 | xhci_warn(xhci, "Trying to add endpoint 0x%x " | ||
1445 | "without dropping it.\n", | ||
1446 | (unsigned int) ep->desc.bEndpointAddress); | ||
1447 | return -EINVAL; | ||
1448 | } | ||
1449 | |||
1433 | /* If the HCD has already noted the endpoint is enabled, | 1450 | /* If the HCD has already noted the endpoint is enabled, |
1434 | * ignore this request. | 1451 | * ignore this request. |
1435 | */ | 1452 | */ |
@@ -1445,8 +1462,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1445 | * process context, not interrupt context (or so documenation | 1462 | * process context, not interrupt context (or so documenation |
1446 | * for usb_set_interface() and usb_set_configuration() claim). | 1463 | * for usb_set_interface() and usb_set_configuration() claim). |
1447 | */ | 1464 | */ |
1448 | if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], | 1465 | 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", | 1466 | dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", |
1451 | __func__, ep->desc.bEndpointAddress); | 1467 | __func__, ep->desc.bEndpointAddress); |
1452 | return -ENOMEM; | 1468 | return -ENOMEM; |
@@ -1537,6 +1553,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, | |||
1537 | "and endpoint is not disabled.\n"); | 1553 | "and endpoint is not disabled.\n"); |
1538 | ret = -EINVAL; | 1554 | ret = -EINVAL; |
1539 | break; | 1555 | break; |
1556 | case COMP_DEV_ERR: | ||
1557 | dev_warn(&udev->dev, "ERROR: Incompatible device for endpoint " | ||
1558 | "configure command.\n"); | ||
1559 | ret = -ENODEV; | ||
1560 | break; | ||
1540 | case COMP_SUCCESS: | 1561 | case COMP_SUCCESS: |
1541 | dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); | 1562 | dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); |
1542 | ret = 0; | 1563 | ret = 0; |
@@ -1571,6 +1592,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, | |||
1571 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); | 1592 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); |
1572 | ret = -EINVAL; | 1593 | ret = -EINVAL; |
1573 | break; | 1594 | break; |
1595 | case COMP_DEV_ERR: | ||
1596 | dev_warn(&udev->dev, "ERROR: Incompatible device for evaluate " | ||
1597 | "context command.\n"); | ||
1598 | ret = -ENODEV; | ||
1599 | break; | ||
1574 | case COMP_MEL_ERR: | 1600 | case COMP_MEL_ERR: |
1575 | /* Max Exit Latency too large error */ | 1601 | /* Max Exit Latency too large error */ |
1576 | dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n"); | 1602 | dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n"); |
@@ -2853,6 +2879,11 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2853 | dev_warn(&udev->dev, "Device not responding to set address.\n"); | 2879 | dev_warn(&udev->dev, "Device not responding to set address.\n"); |
2854 | ret = -EPROTO; | 2880 | ret = -EPROTO; |
2855 | break; | 2881 | break; |
2882 | case COMP_DEV_ERR: | ||
2883 | dev_warn(&udev->dev, "ERROR: Incompatible device for address " | ||
2884 | "device command.\n"); | ||
2885 | ret = -ENODEV; | ||
2886 | break; | ||
2856 | case COMP_SUCCESS: | 2887 | case COMP_SUCCESS: |
2857 | xhci_dbg(xhci, "Successful Address Device command\n"); | 2888 | xhci_dbg(xhci, "Successful Address Device command\n"); |
2858 | break; | 2889 | break; |