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))); /*-------------------------------------------------------------------------*/