aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hcd.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-08-07 17:04:43 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:17 -0400
commitf2217e8edd95b0428d8123d426e0097a5e955f9f (patch)
tree2364fb618dcae52cc8b6a947ce75152983dc3a9a /drivers/usb/host/xhci-hcd.c
parent018218d1d9eb06116d24a02dd5e7a390f0353d0f (diff)
USB: xhci: Configure endpoint code refactoring.
Refactor out the code issue, wait for, and parse the event completion code for a configure endpoint command. Modify it to support the evaluate context command, which has a very similar submission process. Add functions to copy parts of the output context into the input context (which will be used in the evaluate context command). Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-hcd.c')
-rw-r--r--drivers/usb/host/xhci-hcd.c169
1 files changed, 117 insertions, 52 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index 994f4c0dda24..ddb1a6a118eb 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -942,6 +942,122 @@ static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *vir
942 } 942 }
943} 943}
944 944
945static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
946 struct usb_device *udev, struct xhci_virt_device *virt_dev)
947{
948 int ret;
949
950 switch (virt_dev->cmd_status) {
951 case COMP_ENOMEM:
952 dev_warn(&udev->dev, "Not enough host controller resources "
953 "for new device state.\n");
954 ret = -ENOMEM;
955 /* FIXME: can we allocate more resources for the HC? */
956 break;
957 case COMP_BW_ERR:
958 dev_warn(&udev->dev, "Not enough bandwidth "
959 "for new device state.\n");
960 ret = -ENOSPC;
961 /* FIXME: can we go back to the old state? */
962 break;
963 case COMP_TRB_ERR:
964 /* the HCD set up something wrong */
965 dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, "
966 "add flag = 1, "
967 "and endpoint is not disabled.\n");
968 ret = -EINVAL;
969 break;
970 case COMP_SUCCESS:
971 dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
972 ret = 0;
973 break;
974 default:
975 xhci_err(xhci, "ERROR: unexpected command completion "
976 "code 0x%x.\n", virt_dev->cmd_status);
977 ret = -EINVAL;
978 break;
979 }
980 return ret;
981}
982
983static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
984 struct usb_device *udev, struct xhci_virt_device *virt_dev)
985{
986 int ret;
987
988 switch (virt_dev->cmd_status) {
989 case COMP_EINVAL:
990 dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate "
991 "context command.\n");
992 ret = -EINVAL;
993 break;
994 case COMP_EBADSLT:
995 dev_warn(&udev->dev, "WARN: slot not enabled for"
996 "evaluate context command.\n");
997 case COMP_CTX_STATE:
998 dev_warn(&udev->dev, "WARN: invalid context state for "
999 "evaluate context command.\n");
1000 xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
1001 ret = -EINVAL;
1002 break;
1003 case COMP_SUCCESS:
1004 dev_dbg(&udev->dev, "Successful evaluate context command\n");
1005 ret = 0;
1006 break;
1007 default:
1008 xhci_err(xhci, "ERROR: unexpected command completion "
1009 "code 0x%x.\n", virt_dev->cmd_status);
1010 ret = -EINVAL;
1011 break;
1012 }
1013 return ret;
1014}
1015
1016/* Issue a configure endpoint command or evaluate context command
1017 * and wait for it to finish.
1018 */
1019static int xhci_configure_endpoint(struct xhci_hcd *xhci,
1020 struct usb_device *udev, struct xhci_virt_device *virt_dev,
1021 bool ctx_change)
1022{
1023 int ret;
1024 int timeleft;
1025 unsigned long flags;
1026
1027 spin_lock_irqsave(&xhci->lock, flags);
1028 if (!ctx_change)
1029 ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma,
1030 udev->slot_id);
1031 else
1032 ret = xhci_queue_evaluate_context(xhci, virt_dev->in_ctx->dma,
1033 udev->slot_id);
1034 if (ret < 0) {
1035 spin_unlock_irqrestore(&xhci->lock, flags);
1036 xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
1037 return -ENOMEM;
1038 }
1039 xhci_ring_cmd_db(xhci);
1040 spin_unlock_irqrestore(&xhci->lock, flags);
1041
1042 /* Wait for the configure endpoint command to complete */
1043 timeleft = wait_for_completion_interruptible_timeout(
1044 &virt_dev->cmd_completion,
1045 USB_CTRL_SET_TIMEOUT);
1046 if (timeleft <= 0) {
1047 xhci_warn(xhci, "%s while waiting for %s command\n",
1048 timeleft == 0 ? "Timeout" : "Signal",
1049 ctx_change == 0 ?
1050 "configure endpoint" :
1051 "evaluate context");
1052 /* FIXME cancel the configure endpoint command */
1053 return -ETIME;
1054 }
1055
1056 if (!ctx_change)
1057 return xhci_configure_endpoint_result(xhci, udev, virt_dev);
1058 return xhci_evaluate_context_result(xhci, udev, virt_dev);
1059}
1060
945/* Called after one or more calls to xhci_add_endpoint() or 1061/* Called after one or more calls to xhci_add_endpoint() or
946 * xhci_drop_endpoint(). If this call fails, the USB core is expected 1062 * xhci_drop_endpoint(). If this call fails, the USB core is expected
947 * to call xhci_reset_bandwidth(). 1063 * to call xhci_reset_bandwidth().
@@ -956,8 +1072,6 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
956{ 1072{
957 int i; 1073 int i;
958 int ret = 0; 1074 int ret = 0;
959 int timeleft;
960 unsigned long flags;
961 struct xhci_hcd *xhci; 1075 struct xhci_hcd *xhci;
962 struct xhci_virt_device *virt_dev; 1076 struct xhci_virt_device *virt_dev;
963 struct xhci_input_control_ctx *ctrl_ctx; 1077 struct xhci_input_control_ctx *ctrl_ctx;
@@ -987,56 +1101,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
987 xhci_dbg_ctx(xhci, virt_dev->in_ctx, 1101 xhci_dbg_ctx(xhci, virt_dev->in_ctx,
988 LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); 1102 LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
989 1103
990 spin_lock_irqsave(&xhci->lock, flags); 1104 ret = xhci_configure_endpoint(xhci, udev, virt_dev, false);
991 ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma,
992 udev->slot_id);
993 if (ret < 0) {
994 spin_unlock_irqrestore(&xhci->lock, flags);
995 xhci_dbg(xhci, "FIXME allocate a new ring segment\n");
996 return -ENOMEM;
997 }
998 xhci_ring_cmd_db(xhci);
999 spin_unlock_irqrestore(&xhci->lock, flags);
1000
1001 /* Wait for the configure endpoint command to complete */
1002 timeleft = wait_for_completion_interruptible_timeout(
1003 &virt_dev->cmd_completion,
1004 USB_CTRL_SET_TIMEOUT);
1005 if (timeleft <= 0) {
1006 xhci_warn(xhci, "%s while waiting for configure endpoint command\n",
1007 timeleft == 0 ? "Timeout" : "Signal");
1008 /* FIXME cancel the configure endpoint command */
1009 return -ETIME;
1010 }
1011
1012 switch (virt_dev->cmd_status) {
1013 case COMP_ENOMEM:
1014 dev_warn(&udev->dev, "Not enough host controller resources "
1015 "for new device state.\n");
1016 ret = -ENOMEM;
1017 /* FIXME: can we allocate more resources for the HC? */
1018 break;
1019 case COMP_BW_ERR:
1020 dev_warn(&udev->dev, "Not enough bandwidth "
1021 "for new device state.\n");
1022 ret = -ENOSPC;
1023 /* FIXME: can we go back to the old state? */
1024 break;
1025 case COMP_TRB_ERR:
1026 /* the HCD set up something wrong */
1027 dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, add flag = 1, "
1028 "and endpoint is not disabled.\n");
1029 ret = -EINVAL;
1030 break;
1031 case COMP_SUCCESS:
1032 dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
1033 break;
1034 default:
1035 xhci_err(xhci, "ERROR: unexpected command completion "
1036 "code 0x%x.\n", virt_dev->cmd_status);
1037 ret = -EINVAL;
1038 break;
1039 }
1040 if (ret) { 1105 if (ret) {
1041 /* Callee should call reset_bandwidth() */ 1106 /* Callee should call reset_bandwidth() */
1042 return ret; 1107 return ret;