diff options
author | Andiry Xu <andiry.xu@amd.com> | 2010-07-23 00:23:31 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-10 23:35:41 +0200 |
commit | 8e51adccd4c4b9ffcd509d7f2afce0a906139f75 (patch) | |
tree | ddd035c4775db7f504878574d3925f5bf4c87ccd /drivers/usb/host/xhci-mem.c | |
parent | USB: xHCI: Missed Service Error Event process (diff) | |
download | linux-8e51adccd4c4b9ffcd509d7f2afce0a906139f75.tar.xz linux-8e51adccd4c4b9ffcd509d7f2afce0a906139f75.zip |
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-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 64d036804715..44eeaa016f1b 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1390,6 +1390,22 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, return command; } +void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv) +{ + int last; + + if (!urb_priv) + return; + + last = urb_priv->length - 1; + if (last >= 0) { + int i; + for (i = 0; i <= last; i++) + kfree(urb_priv->td[i]); + } + kfree(urb_priv); +} + void xhci_free_command(struct xhci_hcd *xhci, struct xhci_command *command) { |