aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2010-07-22 18:23:31 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:41 -0400
commit8e51adccd4c4b9ffcd509d7f2afce0a906139f75 (patch)
treeddd035c4775db7f504878574d3925f5bf4c87ccd /drivers/usb/host/xhci.c
parentd18240db797ed749b511b8dc910c5dcf08be46d6 (diff)
USB: xHCI: Introduce urb_priv structure
Add urb_priv data structure to xHCI driver. This structure allows multiple xhci TDs to be linked to one urb, which is essential for isochronous transfer. For non-isochronous urb, only one TD is needed for one urb; for isochronous urb, the TD number for the urb is equal to urb->number_of_packets. The length field of urb_priv indicates the number of TDs in the urb. The td_cnt field indicates the number of TDs already processed by xHC. When td_cnt matches length, the urb can be given back to usbcore. When an urb is dequeued or cancelled, add all the unprocessed TDs to the endpoint's cancelled_td_list. When process a cancelled TD, increase td_cnt field. When td_cnt equals urb_priv->length, giveback the cancelled urb. Signed-off-by: Andiry Xu <andiry.xu@amd.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r--drivers/usb/host/xhci.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 3106d22ae053..295a0a2063a6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -804,7 +804,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
804 unsigned long flags; 804 unsigned long flags;
805 int ret = 0; 805 int ret = 0;
806 unsigned int slot_id, ep_index; 806 unsigned int slot_id, ep_index;
807 807 struct urb_priv *urb_priv;
808 int size, i;
808 809
809 if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) 810 if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
810 return -EINVAL; 811 return -EINVAL;
@@ -824,6 +825,30 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
824 ret = -ESHUTDOWN; 825 ret = -ESHUTDOWN;
825 goto exit; 826 goto exit;
826 } 827 }
828
829 if (usb_endpoint_xfer_isoc(&urb->ep->desc))
830 size = urb->number_of_packets;
831 else
832 size = 1;
833
834 urb_priv = kzalloc(sizeof(struct urb_priv) +
835 size * sizeof(struct xhci_td *), mem_flags);
836 if (!urb_priv)
837 return -ENOMEM;
838
839 for (i = 0; i < size; i++) {
840 urb_priv->td[i] = kzalloc(sizeof(struct xhci_td), mem_flags);
841 if (!urb_priv->td[i]) {
842 urb_priv->length = i;
843 xhci_urb_free_priv(xhci, urb_priv);
844 return -ENOMEM;
845 }
846 }
847
848 urb_priv->length = size;
849 urb_priv->td_cnt = 0;
850 urb->hcpriv = urb_priv;
851
827 if (usb_endpoint_xfer_control(&urb->ep->desc)) { 852 if (usb_endpoint_xfer_control(&urb->ep->desc)) {
828 /* Check to see if the max packet size for the default control 853 /* Check to see if the max packet size for the default control
829 * endpoint changed during FS device enumeration 854 * endpoint changed during FS device enumeration
@@ -877,6 +902,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
877exit: 902exit:
878 return ret; 903 return ret;
879dying: 904dying:
905 xhci_urb_free_priv(xhci, urb_priv);
906 urb->hcpriv = NULL;
880 xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " 907 xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
881 "non-responsive xHCI host.\n", 908 "non-responsive xHCI host.\n",
882 urb->ep->desc.bEndpointAddress, urb); 909 urb->ep->desc.bEndpointAddress, urb);
@@ -918,9 +945,10 @@ dying:
918int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 945int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
919{ 946{
920 unsigned long flags; 947 unsigned long flags;
921 int ret; 948 int ret, i;
922 u32 temp; 949 u32 temp;
923 struct xhci_hcd *xhci; 950 struct xhci_hcd *xhci;
951 struct urb_priv *urb_priv;
924 struct xhci_td *td; 952 struct xhci_td *td;
925 unsigned int ep_index; 953 unsigned int ep_index;
926 struct xhci_ring *ep_ring; 954 struct xhci_ring *ep_ring;
@@ -935,12 +963,12 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
935 temp = xhci_readl(xhci, &xhci->op_regs->status); 963 temp = xhci_readl(xhci, &xhci->op_regs->status);
936 if (temp == 0xffffffff) { 964 if (temp == 0xffffffff) {
937 xhci_dbg(xhci, "HW died, freeing TD.\n"); 965 xhci_dbg(xhci, "HW died, freeing TD.\n");
938 td = (struct xhci_td *) urb->hcpriv; 966 urb_priv = urb->hcpriv;
939 967
940 usb_hcd_unlink_urb_from_ep(hcd, urb); 968 usb_hcd_unlink_urb_from_ep(hcd, urb);
941 spin_unlock_irqrestore(&xhci->lock, flags); 969 spin_unlock_irqrestore(&xhci->lock, flags);
942 usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); 970 usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN);
943 kfree(td); 971 xhci_urb_free_priv(xhci, urb_priv);
944 return ret; 972 return ret;
945 } 973 }
946 if (xhci->xhc_state & XHCI_STATE_DYING) { 974 if (xhci->xhc_state & XHCI_STATE_DYING) {
@@ -968,9 +996,14 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
968 996
969 xhci_dbg(xhci, "Endpoint ring:\n"); 997 xhci_dbg(xhci, "Endpoint ring:\n");
970 xhci_debug_ring(xhci, ep_ring); 998 xhci_debug_ring(xhci, ep_ring);
971 td = (struct xhci_td *) urb->hcpriv;
972 999
973 list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); 1000 urb_priv = urb->hcpriv;
1001
1002 for (i = urb_priv->td_cnt; i < urb_priv->length; i++) {
1003 td = urb_priv->td[i];
1004 list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list);
1005 }
1006
974 /* Queue a stop endpoint command, but only if this is 1007 /* Queue a stop endpoint command, but only if this is
975 * the first cancellation to be handled. 1008 * the first cancellation to be handled.
976 */ 1009 */