From xiphmont@gmail.com Thu Sep 28 00:13:42 2006 Message-ID: <806dafc20609280013l6eace4c7vee4b9545d2b08c0f@mail.gmail.com> Date: Thu, 28 Sep 2006 03:13:40 -0400 From: "Christopher \"Monty\" Montgomery" To: linux-usb-devel@lists.sourceforge.net Subject: [PATCH 7/15] USB: ehci-hcd: refactor sitd link/patch code for easier frame spanning Cc: greg@kroah.com, david-b@pacbell.net, xiphmont@gmail.com Content-Disposition: inline patch 7: slightly rearrange sitd patching and linking code flow to simplify addition of sITD backpointer support later. This should result in no functional difference. Signed-off-by: Christopher "Monty" Montgomery Cc: David Brownell Signed-off-by: Greg Kroah-Hartman --- --- drivers/usb/host/ehci-sched.c | 75 +++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 40 deletions(-) --- gregkh-2.6.orig/drivers/usb/host/ehci-sched.c +++ gregkh-2.6/drivers/usb/host/ehci-sched.c @@ -2029,18 +2029,15 @@ sitd_urb_transaction ( * * @stream: stream into which this request will be queued * @sitd: New sITD that is to be added to the shadow/hardware schedule - * @iso_sched: ehci_iso_sched holding transfer descriptors - * @index: packet number + * @uf: iso stream packet */ static inline void sitd_patch ( struct ehci_iso_stream *stream, struct ehci_sitd *sitd, - struct ehci_iso_sched *iso_sched, - unsigned index -) + struct ehci_iso_packet *uf + ) { - struct ehci_iso_packet *uf = &iso_sched->packet [index]; u64 bufp = uf->bufp; sitd->hw_next = EHCI_LIST_END; @@ -2049,7 +2046,6 @@ sitd_patch ( sitd->hw_results = uf->transaction; sitd->hw_backpointer = EHCI_LIST_END; - bufp = uf->bufp; sitd->hw_buf [0] = cpu_to_le32 (bufp); sitd->hw_buf_hi [0] = cpu_to_le32 (bufp >> 32); @@ -2057,26 +2053,47 @@ sitd_patch ( if (uf->cross) bufp += 4096; sitd->hw_buf_hi [1] = cpu_to_le32 (bufp >> 32); - sitd->index = index; } /* sitd_link - fill in and link one sITD into the shadow/hardware * schedule * * @ehci: pointer to ehci host controller device structure + * @urb: new USB request * @frame: shadow/hardware schedule frame - * @sitd: sitd to link + * @stream: stream to which ITD belongs + * @sched: ehci_iso_sched structure holding packets + * @index: index of packet to use from sched */ -static inline void -sitd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_sitd *sitd) +static inline void sitd_link (struct ehci_hcd *ehci, + struct urb *urb, + unsigned frame, + struct ehci_iso_stream *stream, + struct ehci_iso_sched *sched, + int index) { + struct ehci_sitd *sitd; + + /* get SITD from already allocated list */ + BUG_ON (list_empty (&sched->td_list)); + sitd = list_entry (sched->td_list.next, + struct ehci_sitd, sitd_list); + list_move_tail (&sitd->sitd_list, &stream->td_list); + sitd->stream = iso_stream_get (stream); + sitd->urb = usb_get_urb (urb); + + /* set the sitd fields */ + sitd_patch (stream, sitd, &sched->packet [index]); + /* note: sitd ordering could matter (CSPLIT then SSPLIT) */ + sitd->frame = frame; + sitd->index = index; sitd->sitd_next = ehci->pshadow [frame]; sitd->hw_next = ehci->periodic [frame]; ehci->pshadow [frame].sitd = sitd; - sitd->frame = frame; wmb (); ehci->periodic [frame] = cpu_to_le32 (sitd->sitd_dma) | Q_TYPE_SITD; + } /* sitd_link_urb - link urb's sITDs into the hardware schedule @@ -2093,12 +2110,11 @@ sitd_link_urb ( struct urb *urb, unsigned mod, struct ehci_iso_stream *stream -) + ) { int packet; unsigned next_uframe; struct ehci_iso_sched *sched = urb->hcpriv; - struct ehci_sitd *sitd; next_uframe = stream->next_uframe; @@ -2106,42 +2122,21 @@ sitd_link_urb ( /* usbfs ignores TT bandwidth */ ehci_to_hcd(ehci)->self.bandwidth_allocated += stream->bandwidth; - ehci_vdbg (ehci, - "sched devp %s ep%d%s-iso [%d] %dms/%04x\n", - urb->dev->devpath, stream->bEndpointAddress & 0x0f, - (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out", - (next_uframe >> 3) % ehci->periodic_size, - stream->interval, le32_to_cpu (stream->splits)); - stream->start = jiffies; } ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; /* fill sITDs frame by frame */ - for (packet = 0, sitd = NULL; - packet < urb->number_of_packets; - packet++) { - - /* ASSERT: we have all necessary sitds */ - BUG_ON (list_empty (&sched->td_list)); - - /* ASSERT: no itds for this endpoint in this frame */ - - sitd = list_entry (sched->td_list.next, - struct ehci_sitd, sitd_list); - list_move_tail (&sitd->sitd_list, &stream->td_list); - sitd->stream = iso_stream_get (stream); - sitd->urb = usb_get_urb (urb); - - sitd_patch (stream, sitd, sched, packet); - sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, - sitd); - + for (packet = 0; packet < urb->number_of_packets; packet++) { + sitd_link (ehci, urb, ((next_uframe & (mod-1)) >> 3), + stream, sched, packet); next_uframe += stream->interval << 3; stream->depth += stream->interval << 3; } + stream->next_uframe = next_uframe % mod; /* don't need that schedule data any more */ + /* also releases unused sITDs that weren't needed for spanning */ iso_sched_free (stream, sched); urb->hcpriv = NULL;