>From e888aa36e06a3f3e5b78031d9820f711bbff1ec9 Mon Sep 17 00:00:00 2001 From: Libin Yang <libin.yang@xxxxxxx> Date: Fri, 26 Feb 2010 14:46:24 +0800 Subject: [PATCH 6/7] xHCI: isoc bandwidth This patch add the bandwidth implementation for USB 2 isoc transfer. No other bandwith except isoc is calculated in for bandwith in this patch. Signed-off-by: Libin Yang <libin.yang@xxxxxxx> --- drivers/usb/host/xhci-hcd.c | 4 ++++ drivers/usb/host/xhci-ring.c | 8 ++++++++ drivers/usb/host/xhci.h | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 0 deletions(-) diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c index c318d5a..90d373c 100644 --- a/drivers/usb/host/xhci-hcd.c +++ b/drivers/usb/host/xhci-hcd.c @@ -838,9 +838,13 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) goto done; temp = xhci_readl(xhci, &xhci->op_regs->status); if (temp == 0xffffffff) { + int bandwidth; xhci_dbg(xhci, "HW died, freeing TD.\n"); urb_priv = urb->hcpriv; + bandwidth = xhci_get_bandwidth(urb); + xhci_to_hcd(xhci)->self.bandwidth_allocated -= bandwidth; + usb_hcd_unlink_urb_from_ep(hcd, urb); spin_unlock_irqrestore(&xhci->lock, flags); usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 548cf2e..bcc2dcb 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1326,6 +1326,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, int skip_td; int idx; int len; + int bandwidth; union xhci_trb *cur_trb; struct xhci_segment *cur_seg; handle_isoc: @@ -1420,6 +1421,9 @@ handle_isoc: urb_priv->td_cnt++; } + bandwidth = xhci_get_bandwidth(urb); + xhci_to_hcd(xhci)->self.bandwidth_allocated -= bandwidth; + inc_deq(xhci, xhci->event_ring, true); xhci_set_hc_event_deq(xhci); @@ -2362,6 +2366,7 @@ int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, bool first_trb; int start_cycle; u32 field, length_field; + int bandwidth; int running_total, trb_buff_len, td_len, td_remain_len, ret; u64 start_addr, addr; @@ -2472,6 +2477,9 @@ int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, start_trb->field[3] |= start_cycle; } + bandwidth = xhci_get_bandwidth(urb); + xhci_to_hcd(xhci)->self.bandwidth_allocated += bandwidth; + ring_ep_doorbell(xhci, slot_id, ep_index); return 0; } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e66083c..90e738d 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1339,4 +1339,21 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); +static inline int xhci_get_bandwidth(struct urb *urb) +{ + int is_input, bandwidth; + + is_input = usb_pipein(urb->pipe); + + bandwidth = usb_calc_bus_time(urb->dev->speed, is_input, 1, + le16_to_cpu(urb->ep->desc.wMaxPacketSize)); + if (urb->dev->speed == USB_SPEED_HIGH) + bandwidth /= urb->interval << 3; + else + bandwidth /= urb->interval; + + return bandwidth; + +} + #endif /* __LINUX_XHCI_HCD_H */ -- 1.6.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html