Commit 4e5cd67f authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[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.
parent 5a72e652
...@@ -115,6 +115,7 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe) ...@@ -115,6 +115,7 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
/* ... or C-mask? */ /* ... or C-mask? */
if (q->qh->hw_info2 & cpu_to_le32 (1 << (8 + uframe))) if (q->qh->hw_info2 & cpu_to_le32 (1 << (8 + uframe)))
usecs += q->qh->c_usecs; usecs += q->qh->c_usecs;
hw_p = &q->qh->hw_next;
q = &q->qh->qh_next; q = &q->qh->qh_next;
break; break;
case Q_TYPE_FSTN: case Q_TYPE_FSTN:
...@@ -122,37 +123,35 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe) ...@@ -122,37 +123,35 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
* bandwidth from the previous frame * bandwidth from the previous frame
*/ */
if (q->fstn->hw_prev != EHCI_LIST_END) { 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; q = &q->fstn->fstn_next;
break; break;
case Q_TYPE_ITD: case Q_TYPE_ITD:
usecs += q->itd->usecs [uframe]; usecs += q->itd->usecs [uframe];
hw_p = &q->itd->hw_next;
q = &q->itd->itd_next; q = &q->itd->itd_next;
break; break;
#ifdef have_split_iso #ifdef have_split_iso
case Q_TYPE_SITD: 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) */ /* is it in the S-mask? (count SPLIT, DATA) */
if (q->sitd->hw_uframe & cpu_to_le32 (1 << uframe)) { if (q->sitd->hw_uframe & cpu_to_le32 (1 << uframe)) {
if (temp) if (q->sitd->hw_fullspeed_ep &
usecs += HS_USECS (188); __constant_cpu_to_le32 (1<<31))
else usecs += q->sitd->stream->usecs;
usecs += HS_USECS (1); else /* worst case for OUT start-split */
usecs += HS_USECS_ISO (188);
} }
/* ... C-mask? (count CSPLIT, DATA) */ /* ... C-mask? (count CSPLIT, DATA) */
if (q->sitd->hw_uframe & if (q->sitd->hw_uframe &
cpu_to_le32 (1 << (8 + uframe))) { cpu_to_le32 (1 << (8 + uframe))) {
if (temp) /* worst case for IN complete-split */
usecs += HS_USECS (0); usecs += q->sitd->stream->c_usecs;
else
usecs += HS_USECS (188);
} }
hw_p = &q->sitd->hw_next;
q = &q->sitd->sitd_next; q = &q->sitd->sitd_next;
break; break;
#endif /* have_split_iso */ #endif /* have_split_iso */
...@@ -1302,7 +1301,20 @@ scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs) ...@@ -1302,7 +1301,20 @@ scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs)
break; break;
#ifdef have_split_iso #ifdef have_split_iso
case Q_TYPE_SITD: 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 */ #endif /* have_split_iso */
default: default:
dbg ("corrupt type %d frame %d shadow %p", dbg ("corrupt type %d frame %d shadow %p",
......
...@@ -425,11 +425,11 @@ struct ehci_iso_stream { ...@@ -425,11 +425,11 @@ struct ehci_iso_stream {
int next_uframe; int next_uframe;
/* the rest is derived from the endpoint descriptor, /* 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] * including the extra info for hw_bufp[0..2]
*/ */
u8 interval; u8 interval;
u8 usecs; u8 usecs, c_usecs;
u16 maxp; u16 maxp;
unsigned bandwidth; unsigned bandwidth;
...@@ -492,22 +492,35 @@ struct ehci_sitd { ...@@ -492,22 +492,35 @@ struct ehci_sitd {
/* first part defined by EHCI spec */ /* first part defined by EHCI spec */
u32 hw_next; u32 hw_next;
/* uses bit field macros above - see EHCI 0.95 Table 3-8 */ /* uses bit field macros above - see EHCI 0.95 Table 3-8 */
u32 hw_fullspeed_ep; /* see EHCI table 3-9 */ u32 hw_fullspeed_ep; /* see EHCI table 3-9 */
u32 hw_uframe; /* see EHCI table 3-10 */ u32 hw_uframe; /* see EHCI table 3-10 */
u32 hw_tx_results1; /* see EHCI table 3-11 */ u32 hw_results; /* see EHCI table 3-11 */
u32 hw_tx_results2; /* see EHCI table 3-12 */ #define SITD_IOC (1 << 31) /* interrupt on completion */
u32 hw_tx_results3; /* see EHCI table 3-12 */ #define SITD_PAGE (1 << 30) /* buffer 0/1 */
u32 hw_backpointer; /* see EHCI table 3-13 */ #define SITD_LENGTH(x) (0x3ff & ((x)>>16))
u32 hw_buf_hi [2]; /* Appendix B */ #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 */ /* the rest is HCD-private */
dma_addr_t sitd_dma; dma_addr_t sitd_dma;
union ehci_shadow sitd_next; /* ptr to periodic q entry */ 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 */ struct urb *urb;
unsigned short c_usecs; /* completion bandwidth */ 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))); } __attribute__ ((aligned (32)));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment