diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 78 |
1 files changed, 26 insertions, 52 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 64c1ba353856..2b8d9a24af09 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -1820,6 +1820,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, | |||
1820 | int ret; | 1820 | int ret; |
1821 | 1821 | ||
1822 | switch (*cmd_status) { | 1822 | switch (*cmd_status) { |
1823 | case COMP_CMD_ABORT: | ||
1824 | case COMP_CMD_STOP: | ||
1825 | xhci_warn(xhci, "Timeout while waiting for configure endpoint command\n"); | ||
1826 | ret = -ETIME; | ||
1827 | break; | ||
1823 | case COMP_ENOMEM: | 1828 | case COMP_ENOMEM: |
1824 | dev_warn(&udev->dev, "Not enough host controller resources " | 1829 | dev_warn(&udev->dev, "Not enough host controller resources " |
1825 | "for new device state.\n"); | 1830 | "for new device state.\n"); |
@@ -1866,6 +1871,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, | |||
1866 | struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; | 1871 | struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; |
1867 | 1872 | ||
1868 | switch (*cmd_status) { | 1873 | switch (*cmd_status) { |
1874 | case COMP_CMD_ABORT: | ||
1875 | case COMP_CMD_STOP: | ||
1876 | xhci_warn(xhci, "Timeout while waiting for evaluate context command\n"); | ||
1877 | ret = -ETIME; | ||
1878 | break; | ||
1869 | case COMP_EINVAL: | 1879 | case COMP_EINVAL: |
1870 | dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " | 1880 | dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " |
1871 | "context command.\n"); | 1881 | "context command.\n"); |
@@ -2590,7 +2600,6 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2590 | bool ctx_change, bool must_succeed) | 2600 | bool ctx_change, bool must_succeed) |
2591 | { | 2601 | { |
2592 | int ret; | 2602 | int ret; |
2593 | int timeleft; | ||
2594 | unsigned long flags; | 2603 | unsigned long flags; |
2595 | struct xhci_input_control_ctx *ctrl_ctx; | 2604 | struct xhci_input_control_ctx *ctrl_ctx; |
2596 | struct xhci_virt_device *virt_dev; | 2605 | struct xhci_virt_device *virt_dev; |
@@ -2646,21 +2655,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2646 | spin_unlock_irqrestore(&xhci->lock, flags); | 2655 | spin_unlock_irqrestore(&xhci->lock, flags); |
2647 | 2656 | ||
2648 | /* Wait for the configure endpoint command to complete */ | 2657 | /* Wait for the configure endpoint command to complete */ |
2649 | timeleft = wait_for_completion_interruptible_timeout( | 2658 | wait_for_completion(command->completion); |
2650 | command->completion, | ||
2651 | XHCI_CMD_DEFAULT_TIMEOUT); | ||
2652 | if (timeleft <= 0) { | ||
2653 | xhci_warn(xhci, "%s while waiting for %s command\n", | ||
2654 | timeleft == 0 ? "Timeout" : "Signal", | ||
2655 | ctx_change == 0 ? | ||
2656 | "configure endpoint" : | ||
2657 | "evaluate context"); | ||
2658 | /* cancel the configure endpoint command */ | ||
2659 | ret = xhci_cancel_cmd(xhci, command, command->command_trb); | ||
2660 | if (ret < 0) | ||
2661 | return ret; | ||
2662 | return -ETIME; | ||
2663 | } | ||
2664 | 2659 | ||
2665 | if (!ctx_change) | 2660 | if (!ctx_change) |
2666 | ret = xhci_configure_endpoint_result(xhci, udev, | 2661 | ret = xhci_configure_endpoint_result(xhci, udev, |
@@ -3438,7 +3433,6 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3438 | unsigned int slot_id; | 3433 | unsigned int slot_id; |
3439 | struct xhci_virt_device *virt_dev; | 3434 | struct xhci_virt_device *virt_dev; |
3440 | struct xhci_command *reset_device_cmd; | 3435 | struct xhci_command *reset_device_cmd; |
3441 | int timeleft; | ||
3442 | int last_freed_endpoint; | 3436 | int last_freed_endpoint; |
3443 | struct xhci_slot_ctx *slot_ctx; | 3437 | struct xhci_slot_ctx *slot_ctx; |
3444 | int old_active_eps = 0; | 3438 | int old_active_eps = 0; |
@@ -3506,15 +3500,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3506 | spin_unlock_irqrestore(&xhci->lock, flags); | 3500 | spin_unlock_irqrestore(&xhci->lock, flags); |
3507 | 3501 | ||
3508 | /* Wait for the Reset Device command to finish */ | 3502 | /* Wait for the Reset Device command to finish */ |
3509 | timeleft = wait_for_completion_interruptible_timeout( | 3503 | wait_for_completion(reset_device_cmd->completion); |
3510 | reset_device_cmd->completion, | ||
3511 | XHCI_CMD_DEFAULT_TIMEOUT); | ||
3512 | if (timeleft <= 0) { | ||
3513 | xhci_warn(xhci, "%s while waiting for reset device command\n", | ||
3514 | timeleft == 0 ? "Timeout" : "Signal"); | ||
3515 | ret = -ETIME; | ||
3516 | goto command_cleanup; | ||
3517 | } | ||
3518 | 3504 | ||
3519 | /* The Reset Device command can't fail, according to the 0.95/0.96 spec, | 3505 | /* The Reset Device command can't fail, according to the 0.95/0.96 spec, |
3520 | * unless we tried to reset a slot ID that wasn't enabled, | 3506 | * unless we tried to reset a slot ID that wasn't enabled, |
@@ -3522,6 +3508,11 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3522 | */ | 3508 | */ |
3523 | ret = reset_device_cmd->status; | 3509 | ret = reset_device_cmd->status; |
3524 | switch (ret) { | 3510 | switch (ret) { |
3511 | case COMP_CMD_ABORT: | ||
3512 | case COMP_CMD_STOP: | ||
3513 | xhci_warn(xhci, "Timeout waiting for reset device command\n"); | ||
3514 | ret = -ETIME; | ||
3515 | goto command_cleanup; | ||
3525 | case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */ | 3516 | case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */ |
3526 | case COMP_CTX_STATE: /* 0.96 completion code for same thing */ | 3517 | case COMP_CTX_STATE: /* 0.96 completion code for same thing */ |
3527 | xhci_dbg(xhci, "Can't reset device (slot ID %u) in %s state\n", | 3518 | xhci_dbg(xhci, "Can't reset device (slot ID %u) in %s state\n", |
@@ -3691,7 +3682,6 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
3691 | { | 3682 | { |
3692 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 3683 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
3693 | unsigned long flags; | 3684 | unsigned long flags; |
3694 | int timeleft; | ||
3695 | int ret; | 3685 | int ret; |
3696 | struct xhci_command *command; | 3686 | struct xhci_command *command; |
3697 | 3687 | ||
@@ -3711,19 +3701,9 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
3711 | xhci_ring_cmd_db(xhci); | 3701 | xhci_ring_cmd_db(xhci); |
3712 | spin_unlock_irqrestore(&xhci->lock, flags); | 3702 | spin_unlock_irqrestore(&xhci->lock, flags); |
3713 | 3703 | ||
3714 | /* XXX: how much time for xHC slot assignment? */ | 3704 | wait_for_completion(command->completion); |
3715 | timeleft = wait_for_completion_interruptible_timeout( | ||
3716 | command->completion, | ||
3717 | XHCI_CMD_DEFAULT_TIMEOUT); | ||
3718 | if (timeleft <= 0) { | ||
3719 | xhci_warn(xhci, "%s while waiting for a slot\n", | ||
3720 | timeleft == 0 ? "Timeout" : "Signal"); | ||
3721 | /* cancel the enable slot request */ | ||
3722 | ret = xhci_cancel_cmd(xhci, NULL, command->command_trb); | ||
3723 | return ret; | ||
3724 | } | ||
3725 | 3705 | ||
3726 | if (!xhci->slot_id) { | 3706 | if (!xhci->slot_id || command->status != COMP_SUCCESS) { |
3727 | xhci_err(xhci, "Error while assigning device slot ID\n"); | 3707 | xhci_err(xhci, "Error while assigning device slot ID\n"); |
3728 | xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n", | 3708 | xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n", |
3729 | HCS_MAX_SLOTS( | 3709 | HCS_MAX_SLOTS( |
@@ -3792,7 +3772,6 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3792 | { | 3772 | { |
3793 | const char *act = setup == SETUP_CONTEXT_ONLY ? "context" : "address"; | 3773 | const char *act = setup == SETUP_CONTEXT_ONLY ? "context" : "address"; |
3794 | unsigned long flags; | 3774 | unsigned long flags; |
3795 | int timeleft; | ||
3796 | struct xhci_virt_device *virt_dev; | 3775 | struct xhci_virt_device *virt_dev; |
3797 | int ret = 0; | 3776 | int ret = 0; |
3798 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 3777 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
@@ -3867,23 +3846,18 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3867 | spin_unlock_irqrestore(&xhci->lock, flags); | 3846 | spin_unlock_irqrestore(&xhci->lock, flags); |
3868 | 3847 | ||
3869 | /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ | 3848 | /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ |
3870 | timeleft = wait_for_completion_interruptible_timeout( | 3849 | wait_for_completion(command->completion); |
3871 | command->completion, XHCI_CMD_DEFAULT_TIMEOUT); | 3850 | |
3872 | /* FIXME: From section 4.3.4: "Software shall be responsible for timing | 3851 | /* FIXME: From section 4.3.4: "Software shall be responsible for timing |
3873 | * the SetAddress() "recovery interval" required by USB and aborting the | 3852 | * the SetAddress() "recovery interval" required by USB and aborting the |
3874 | * command on a timeout. | 3853 | * command on a timeout. |
3875 | */ | 3854 | */ |
3876 | if (timeleft <= 0) { | ||
3877 | xhci_warn(xhci, "%s while waiting for setup %s command\n", | ||
3878 | timeleft == 0 ? "Timeout" : "Signal", act); | ||
3879 | /* cancel the address device command */ | ||
3880 | ret = xhci_cancel_cmd(xhci, NULL, command->command_trb); | ||
3881 | if (ret < 0) | ||
3882 | return ret; | ||
3883 | return -ETIME; | ||
3884 | } | ||
3885 | |||
3886 | switch (command->status) { | 3855 | switch (command->status) { |
3856 | case COMP_CMD_ABORT: | ||
3857 | case COMP_CMD_STOP: | ||
3858 | xhci_warn(xhci, "Timeout while waiting for setup device command\n"); | ||
3859 | ret = -ETIME; | ||
3860 | break; | ||
3887 | case COMP_CTX_STATE: | 3861 | case COMP_CTX_STATE: |
3888 | case COMP_EBADSLT: | 3862 | case COMP_EBADSLT: |
3889 | xhci_err(xhci, "Setup ERROR: setup %s command for slot %d.\n", | 3863 | xhci_err(xhci, "Setup ERROR: setup %s command for slot %d.\n", |