[PATCH 2/6] [C67x00] Fix calculation of frame bandwidth

Grant Likely grant.likely at secretlab.ca
Wed Jun 13 09:02:17 EST 2007


Use the correct formulas and values for calculating the bittime within
a frame.
Signed-off-by: Grant Likely <grant.likely at secretlab.ca>
---
 drivers/usb/c67x00/c67x00-hcd.h   |   10 ++++++--
 drivers/usb/c67x00/c67x00-sched.c |   42 +++++++++++++++++++++++++++++++++---
 2 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/c67x00/c67x00-hcd.h b/drivers/usb/c67x00/c67x00-hcd.h
index 8f8eff1..94ce7ec 100644
--- a/drivers/usb/c67x00/c67x00-hcd.h
+++ b/drivers/usb/c67x00/c67x00-hcd.h
@@ -46,12 +46,16 @@
  * The current implementation switches between _STD (default) and _ISO (when
  * isochronous transfers are scheduled), in order to optimize the throughput
  * in normal cicrumstances, but also provide good isochronous behaviour.
+ *
+ * Bandwidth is described in bit time so with a 12MHz USB clock and 1ms
+ * frames; there are 12000 bit times per frame.
  */
 
-#define MAX_FRAME_BW_STD	4000
-#define MAX_FRAME_BW_ISO	2400
+#define TOTAL_FRAME_BW		12000
+#define DEFAULT_EOT		2250
 
-#define DEFAULT_EOT		6500
+#define MAX_FRAME_BW_STD	(TOTAL_FRAME_BW - DEFAULT_EOT)
+#define MAX_FRAME_BW_ISO	2400
 
 /*
  * Periodic transfers may only use 90% of the full frame, but as
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
index 952bdab..0d08af7 100644
--- a/drivers/usb/c67x00/c67x00-sched.c
+++ b/drivers/usb/c67x00/c67x00-sched.c
@@ -520,11 +520,45 @@ static inline void giveback_urb(struct c67x00_hcd *c67x00, struct urb *urb,
 
 /* -------------------------------------------------------------------------- */
 
-static int claim_frame_bw(struct c67x00_hcd *c67x00, int len, int periodic)
+static int claim_frame_bw(struct c67x00_hcd *c67x00, struct urb *urb,
+			  int len, int periodic)
 {
-	int bit_time = len * 8;
+	struct urb_priv *urbp = urb->hcpriv;
+	int bit_time;
+
+	/* According to the C67x00 BIOS user manual, page 3-18,19, the
+	 * following calculations provide the full speed bit times for
+	 * a transaction.
+	 *
+	 * FS(in)	= 112.5 +  9.36*BC + HOST_DELAY
+	 * FS(in,iso)	=  90.5 +  9.36*BC + HOST_DELAY
+	 * FS(out)	= 112.5 +  9.36*BC + HOST_DELAY
+	 * FS(out,iso)	=  78.4 +  9.36*BC + HOST_DELAY
+	 * LS(in)	= 802.4 + 75.78*BC + HOST_DELAY
+	 * LS(out)	= 802.6 + 74.67*BC + HOST_DELAY
+	 *
+	 * HOST_DELAY == 106 for the c67200 and c67300.
+	 */
+
+	/* make calculations in 1/100 bit times to maintain resolution */
+	if (urbp->ep_data->dev->speed == USB_SPEED_LOW) {
+		/* Low speed pipe */
+		if (usb_pipein(urb->pipe))
+			bit_time = 80240 + 7578*len;
+		else
+			bit_time = 80260 + 7467*len;
+	} else {
+		/* FS pipes */
+		if (usb_pipeisoc(urb->pipe))
+			bit_time = usb_pipein(urb->pipe) ? 9050 : 7840;
+		else
+			bit_time = 11250;
+		bit_time += 936*len;
+	}
 
-	/* TODO don't we need to take low speed into regards? */
+	/* Scale back down to integer bit times.  Use a host delay of 106.
+	 * (this is the only place it is used) */
+	bit_time = ((bit_time+50) / 100) + 106;
 
 	if (unlikely(bit_time + c67x00->bandwidth_allocated >=
 		     c67x00->max_frame_bw))
@@ -565,7 +599,7 @@ static int create_td(struct c67x00_hcd *c67x00,
 	__u8 cmd = 0;
 	int tt = 0;
 
-	if (claim_frame_bw(c67x00, len,
+	if (claim_frame_bw(c67x00, urb, len,
 			   usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)))
 		return -EMSGSIZE;	/* Not really an error, but expected */
 
-- 
1.4.4.2




More information about the Linuxppc-embedded mailing list