[PATCH RFC 6/7] xHCI: isoc bandwidth

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux