ChangeSet 1.1557.49.22, 2004/02/18 13:17:05-08:00, david-b@pacbell.net

[PATCH] USB: ehci-hcd, fullspeed iso data structures (1/3)

[USB] start ehci split transaction support

Updates split ISO transaction descriptor structure, add bitmask #defines;
it's groundwork for full speed ISO support in EHCI.  Updates periodic
schedule scanning, and bandwidth calculations accordingly.

Fixes bandwidth calculation to behave when the periodic schedule has
entries of multiple types ... as will be more common as ISO support
starts to be used here.


 drivers/usb/host/ehci-sched.c |   42 +++++++++++++++++++++++++++---------------
 drivers/usb/host/ehci.h       |   39 ++++++++++++++++++++++++++-------------
 2 files changed, 53 insertions(+), 28 deletions(-)


diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c	Thu Feb 19 17:21:17 2004
+++ b/drivers/usb/host/ehci-sched.c	Thu Feb 19 17:21:17 2004
@@ -115,6 +115,7 @@
 			/* ... or C-mask? */
 			if (q->qh->hw_info2 & cpu_to_le32 (1 << (8 + uframe)))
 				usecs += q->qh->c_usecs;
+			hw_p = &q->qh->hw_next;
 			q = &q->qh->qh_next;
 			break;
 		case Q_TYPE_FSTN:
@@ -122,37 +123,35 @@
 			 * bandwidth from the previous frame
 			 */
 			if (q->fstn->hw_prev != EHCI_LIST_END) {
-				dbg ("not counting FSTN bandwidth yet ...");
+				ehci_dbg (ehci, "ignoring FSTN cost ...\n");
 			}
+			hw_p = &q->fstn->hw_next;
 			q = &q->fstn->fstn_next;
 			break;
 		case Q_TYPE_ITD:
 			usecs += q->itd->usecs [uframe];
+			hw_p = &q->itd->hw_next;
 			q = &q->itd->itd_next;
 			break;
 #ifdef have_split_iso
 		case Q_TYPE_SITD:
-			temp = q->sitd->hw_fullspeed_ep &
-				__constant_cpu_to_le32 (1 << 31);
-
-			// FIXME:  this doesn't count data bytes right...
-
 			/* is it in the S-mask?  (count SPLIT, DATA) */
 			if (q->sitd->hw_uframe & cpu_to_le32 (1 << uframe)) {
-				if (temp)
-					usecs += HS_USECS (188);
-				else
-					usecs += HS_USECS (1);
+				if (q->sitd->hw_fullspeed_ep &
+						__constant_cpu_to_le32 (1<<31))
+					usecs += q->sitd->stream->usecs;
+				else	/* worst case for OUT start-split */
+					usecs += HS_USECS_ISO (188);
 			}
 
 			/* ... C-mask?  (count CSPLIT, DATA) */
 			if (q->sitd->hw_uframe &
 					cpu_to_le32 (1 << (8 + uframe))) {
-				if (temp)
-					usecs += HS_USECS (0);
-				else
-					usecs += HS_USECS (188);
+				/* worst case for IN complete-split */
+				usecs += q->sitd->stream->c_usecs;
 			}
+
+			hw_p = &q->sitd->hw_next;
 			q = &q->sitd->sitd_next;
 			break;
 #endif /* have_split_iso */
@@ -1302,7 +1301,20 @@
 				break;
 #ifdef have_split_iso
 			case Q_TYPE_SITD:
-				// nyet!
+				if (q.sitd->hw_results & SITD_ACTIVE) {
+					q_p = &q.sitd->sitd_next;
+					hw_p = &q.sitd->hw_next;
+					type = Q_NEXT_TYPE (q.sitd->hw_next);
+					q = *q_p;
+					break;
+				}
+				*q_p = q.sitd->sitd_next;
+				*hw_p = q.sitd->hw_next;
+				type = Q_NEXT_TYPE (q.sitd->hw_next);
+				wmb();
+				modified = sitd_complete (ehci, q.sitd, regs);
+				q = *q_p;
+				break;
 #endif /* have_split_iso */
 			default:
 				dbg ("corrupt type %d frame %d shadow %p",
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h	Thu Feb 19 17:21:17 2004
+++ b/drivers/usb/host/ehci.h	Thu Feb 19 17:21:17 2004
@@ -425,11 +425,11 @@
 	int			next_uframe;
 
 	/* the rest is derived from the endpoint descriptor,
-	 * trusting urb->interval == (1 << (epdesc->bInterval - 1)),
+	 * trusting urb->interval == f(epdesc->bInterval) and
 	 * including the extra info for hw_bufp[0..2]
 	 */
 	u8			interval;
-	u8			usecs;		
+	u8			usecs, c_usecs;
 	u16			maxp;
 	unsigned		bandwidth;
 
@@ -492,22 +492,35 @@
 	/* first part defined by EHCI spec */
 	u32			hw_next;
 /* uses bit field macros above - see EHCI 0.95 Table 3-8 */
-	u32			hw_fullspeed_ep;  /* see EHCI table 3-9 */
-	u32                     hw_uframe;        /* see EHCI table 3-10 */
-        u32                     hw_tx_results1;   /* see EHCI table 3-11 */
-	u32                     hw_tx_results2;   /* see EHCI table 3-12 */
-	u32                     hw_tx_results3;   /* see EHCI table 3-12 */
-        u32                     hw_backpointer;   /* see EHCI table 3-13 */
-	u32			hw_buf_hi [2];	  /* Appendix B */
+	u32			hw_fullspeed_ep;	/* see EHCI table 3-9 */
+	u32			hw_uframe;		/* see EHCI table 3-10 */
+	u32			hw_results;		/* see EHCI table 3-11 */
+#define	SITD_IOC	(1 << 31)	/* interrupt on completion */
+#define	SITD_PAGE	(1 << 30)	/* buffer 0/1 */
+#define	SITD_LENGTH(x)	(0x3ff & ((x)>>16))
+#define	SITD_STS_ACTIVE	(1 << 7)	/* HC may execute this */
+#define	SITD_STS_ERR	(1 << 6)	/* error from TT */
+#define	SITD_STS_DBE	(1 << 5)	/* data buffer error (in HC) */
+#define	SITD_STS_BABBLE	(1 << 4)	/* device was babbling */
+#define	SITD_STS_XACT	(1 << 3)	/* illegal IN response */
+#define	SITD_STS_MMF	(1 << 2)	/* incomplete split transaction */
+#define	SITD_STS_STS	(1 << 1)	/* split transaction state */
+
+#define SITD_ACTIVE	__constant_cpu_to_le32(SITD_STS_ACTIVE)
+
+	u32			hw_buf [2];		/* see EHCI table 3-12 */
+	u32			hw_backpointer;		/* see EHCI table 3-13 */
+	u32			hw_buf_hi [2];		/* Appendix B */
 
 	/* the rest is HCD-private */
 	dma_addr_t		sitd_dma;
 	union ehci_shadow	sitd_next;	/* ptr to periodic q entry */
-	struct urb		*urb;
-	dma_addr_t		buf_dma;	/* buffer address */
 
-	unsigned short		usecs;		/* start bandwidth */
-	unsigned short		c_usecs;	/* completion bandwidth */
+	struct urb		*urb;
+	struct ehci_iso_stream	*stream;	/* endpoint's queue */
+	struct list_head	sitd_list;	/* list of stream's sitds */
+	unsigned		frame;
+	unsigned		index;
 } __attribute__ ((aligned (32)));
 
 /*-------------------------------------------------------------------------*/