These patches are against kernels 2.6.18 through at least 2.6.18-git7.

patch 5: first half of untangling intermixed ehci_iso_sched, itd and
sitd code; moves/groups scattered code into self-contained sections.
Adds kernel-doc entries for functions. This patch should result in no
functional difference.

Signed-off-by: Christopher "Monty" Montgomery <[EMAIL PROTECTED]>

---

diff -X b/Documentation/dontdiff -upr a/drivers/usb/host/ehci-sched.c
b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c     2006-09-26 22:20:51.000000000 -0400
+++ b/drivers/usb/host/ehci-sched.c     2006-09-26 22:21:02.000000000 -0400
@@ -969,9 +969,15 @@ iso_sched_free (struct ehci_iso_stream     *
 }

 /*-------------------------------------------------------------------------*/
+/* ISO stream generic machinery; tracks the ITDs and sITDs associated
+   with an isochronous endpoint */

-/* ehci_iso_stream ops work with both ITD and SITD */
-
+/* iso_stream_alloc - allocate a new iso stream structure; and iso
+ * stream performs a role similar to QHs for ISO endpoints (both ITD
+ * and SITD)
+ *
+ * @mem_flags: flags for memory allocation
+ */
 static struct ehci_iso_stream *
 iso_stream_alloc (gfp_t mem_flags)
 {
@@ -987,6 +993,14 @@ iso_stream_alloc (gfp_t mem_flags)
        return stream;
 }

+/* iso_stream_init - initialize fields of an ehci_iso_stream structure
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @stream: ehci_iso_stream structure to initialize
+ * @dev: endpoint usb device
+ * @pipe: pipe handle
+ * @interval: bInterval of endpoint; frames for FS/LS, uFrames for HS
+ */
 static void
 iso_stream_init (
        struct ehci_hcd         *ehci,
@@ -1082,6 +1096,12 @@ iso_stream_init (
        stream->maxp = maxp;
 }

+/* iso_stream_put - decrement refcount of passed in ehci_iso_stream
+ * structure, reaping it if count has fallen to zero.
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @stream: ehci_iso_stream structure
+ */
 static void
 iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
 {
@@ -1144,6 +1164,11 @@ iso_stream_put(struct ehci_hcd *ehci, st
        }
 }

+/* iso_stream_get - increment refcount of passed in ehci_iso_stream
+ * structure
+ *
+ * @stream: ehci_iso_stream structure
+ */
 static inline struct ehci_iso_stream *
 iso_stream_get (struct ehci_iso_stream *stream)
 {
@@ -1152,6 +1177,14 @@ iso_stream_get (struct ehci_iso_stream *
        return stream;
 }

+/* iso_stream_find - returns ehci_iso_stream structure matching the
+ * passed in urb; if no match is found, a new ehci_iso_stream is
+ * allocated and initialized to match the urb.  This function is thus
+ * used both for looup and lazy alloc.
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @urb: usb request block
+ */
 static struct ehci_iso_stream *
 iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
 {
@@ -1194,114 +1227,6 @@ iso_stream_find (struct ehci_hcd *ehci,
        return stream;
 }

-static inline void
-itd_sched_init (
-       struct ehci_iso_sched   *iso_sched,
-       struct ehci_iso_stream  *stream,
-       struct urb              *urb
-)
-{
-       unsigned        i;
-       dma_addr_t      dma = urb->transfer_dma;
-
-       /* how many uframes are needed for these transfers */
-       iso_sched->span = urb->number_of_packets * stream->interval;
-
-       /* figure out per-uframe itd fields that we'll need later
-        * when we fit new itds into the schedule.
-        */
-       for (i = 0; i < urb->number_of_packets; i++) {
-               struct ehci_iso_packet  *uframe = &iso_sched->packet [i];
-               unsigned                length;
-               dma_addr_t              buf;
-               u32                     trans;
-
-               length = urb->iso_frame_desc [i].length;
-               buf = dma + urb->iso_frame_desc [i].offset;
-
-               trans = EHCI_ISOC_ACTIVE;
-               trans |= buf & 0x0fff;
-               if (unlikely (((i + 1) == urb->number_of_packets))
-                               && !(urb->transfer_flags & URB_NO_INTERRUPT))
-                       trans |= EHCI_ITD_IOC;
-               trans |= length << 16;
-               uframe->transaction = cpu_to_le32 (trans);
-
-               /* might need to cross a buffer page within a uframe */
-               uframe->bufp = (buf & ~(u64)0x0fff);
-               buf += length;
-               if (unlikely ((uframe->bufp != (buf & ~(u64)0x0fff))))
-                       uframe->cross = 1;
-       }
-}
-
-static int
-itd_urb_transaction (
-       struct ehci_iso_stream  *stream,
-       struct ehci_hcd         *ehci,
-       struct urb              *urb,
-       gfp_t                   mem_flags
-)
-{
-       struct ehci_itd         *itd;
-       dma_addr_t              itd_dma;
-       int                     i;
-       unsigned                num_itds;
-       struct ehci_iso_sched   *sched;
-       unsigned long           flags;
-
-       sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
-       if (unlikely (sched == NULL))
-               return -ENOMEM;
-
-       itd_sched_init (sched, stream, urb);
-
-       if (urb->interval < 8)
-               num_itds = 1 + (sched->span + 7) / 8;
-       else
-               num_itds = urb->number_of_packets;
-
-       /* allocate/init ITDs */
-       spin_lock_irqsave (&ehci->lock, flags);
-       for (i = 0; i < num_itds; i++) {
-
-               /* free_list.next might be cache-hot ... but maybe
-                * the HC caches it too. avoid that issue for now.
-                */
-
-               /* prefer previously-allocated itds */
-               if (likely (!list_empty(&stream->free_list))) {
-                       itd = list_entry (stream->free_list.prev,
-                                        struct ehci_itd, itd_list);
-                       list_del (&itd->itd_list);
-                       itd_dma = itd->itd_dma;
-               } else
-                       itd = NULL;
-
-               if (!itd) {
-                       spin_unlock_irqrestore (&ehci->lock, flags);
-                       itd = dma_pool_alloc (ehci->itd_pool, mem_flags,
-                                       &itd_dma);
-                       spin_lock_irqsave (&ehci->lock, flags);
-               }
-
-               if (unlikely (NULL == itd)) {
-                       iso_sched_free (stream, sched);
-                       spin_unlock_irqrestore (&ehci->lock, flags);
-                       return -ENOMEM;
-               }
-               memset (itd, 0, sizeof *itd);
-               itd->itd_dma = itd_dma;
-               list_add (&itd->itd_list, &sched->td_list);
-       }
-       spin_unlock_irqrestore (&ehci->lock, flags);
-
-       /* temporarily store schedule info in hcpriv */
-       urb->hcpriv = sched;
-       urb->error_count = 0;
-       return 0;
-}
-
 /*-------------------------------------------------------------------------*/

 static inline int
@@ -1416,12 +1341,19 @@ sitd_slot_ok (

 #define SCHEDULE_SLOP  10      /* frames */

-static int
-iso_stream_schedule (
+/* iso_stream_schedule - schedules an iso request transaction into the
+ * periodic schedule, budgeting persistent periodic bandwidth for this
+ * stream if that has not yet been done.
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @urb: request
+ * @stream: persistent iso stream
+ */
+static int iso_stream_schedule (
        struct ehci_hcd         *ehci,
        struct urb              *urb,
        struct ehci_iso_stream  *stream
-)
+       )
 {
        u32                     now, start, max, period;
        int                     status;
@@ -1529,6 +1461,139 @@ ready:

 /*-------------------------------------------------------------------------*/

+/* itd_sched_init - ITD-specific initialization of an ehci_iso_sched
+ * structure to hold the specifics of the current requested
+ * transaction during the various steps of budgeting and scheduling.
+ *
+ * @iso_sched: structure to initialize
+ * @stream: iso stream
+ * @urb: current request
+ */
+static inline void
+itd_sched_init (
+       struct ehci_iso_sched   *iso_sched,
+       struct ehci_iso_stream  *stream,
+       struct urb              *urb
+)
+{
+       unsigned        i;
+       dma_addr_t      dma = urb->transfer_dma;
+
+       /* how many uframes are needed for these transfers */
+       iso_sched->span = urb->number_of_packets * stream->interval;
+
+       /* figure out per-uframe itd fields that we'll need later
+        * when we fit new itds into the schedule.
+        */
+       for (i = 0; i < urb->number_of_packets; i++) {
+               struct ehci_iso_packet  *uframe = &iso_sched->packet [i];
+               unsigned                length;
+               dma_addr_t              buf;
+               u32                     trans;
+
+               length = urb->iso_frame_desc [i].length;
+               buf = dma + urb->iso_frame_desc [i].offset;
+
+               trans = EHCI_ISOC_ACTIVE;
+               trans |= buf & 0x0fff;
+               if (unlikely (((i + 1) == urb->number_of_packets))
+                               && !(urb->transfer_flags & URB_NO_INTERRUPT))
+                       trans |= EHCI_ITD_IOC;
+               trans |= length << 16;
+               uframe->transaction = cpu_to_le32 (trans);
+
+               /* might need to cross a buffer page within a uframe */
+               uframe->bufp = (buf & ~(u64)0x0fff);
+               buf += length;
+               if (unlikely ((uframe->bufp != (buf & ~(u64)0x0fff))))
+                       uframe->cross = 1;
+       }
+}
+
+/* itd_urb_transaction - sets up memory and relevant structures to
+ * process current transaction; initializes the iso_sched structure
+ * and preallocates transfer descriptors
+ *
+ * @stream: iso stream
+ * @ehci: pointer to ehci host controller device structure
+ * @urb: current request
+ * mem_flags: flags to use for in-kernel memory allocation
+ */
+static int
+itd_urb_transaction (
+       struct ehci_iso_stream  *stream,
+       struct ehci_hcd         *ehci,
+       struct urb              *urb,
+       gfp_t                   mem_flags
+)
+{
+       struct ehci_itd         *itd;
+       dma_addr_t              itd_dma;
+       int                     i;
+       unsigned                num_itds;
+       struct ehci_iso_sched   *sched;
+       unsigned long           flags;
+
+       sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
+       if (unlikely (sched == NULL))
+               return -ENOMEM;
+
+       itd_sched_init (sched, stream, urb);
+
+       if (urb->interval < 8)
+               num_itds = 1 + (sched->span + 7) / 8;
+       else
+               num_itds = urb->number_of_packets;
+
+       /* allocate/init ITDs */
+       spin_lock_irqsave (&ehci->lock, flags);
+       for (i = 0; i < num_itds; i++) {
+
+               /* free_list.next might be cache-hot ... but maybe
+                * the HC caches it too. avoid that issue for now.
+                */
+
+               /* prefer previously-allocated itds */
+               if (likely (!list_empty(&stream->free_list))) {
+                       itd = list_entry (stream->free_list.prev,
+                                        struct ehci_itd, itd_list);
+                       list_del (&itd->itd_list);
+                       itd_dma = itd->itd_dma;
+               } else
+                       itd = NULL;
+
+               if (!itd) {
+                       spin_unlock_irqrestore (&ehci->lock, flags);
+                       itd = dma_pool_alloc (ehci->itd_pool, mem_flags,
+                                       &itd_dma);
+                       spin_lock_irqsave (&ehci->lock, flags);
+               }
+
+               if (unlikely (NULL == itd)) {
+                       iso_sched_free (stream, sched);
+                       spin_unlock_irqrestore (&ehci->lock, flags);
+                       return -ENOMEM;
+               }
+               memset (itd, 0, sizeof *itd);
+               itd->itd_dma = itd_dma;
+               list_add (&itd->itd_list, &sched->td_list);
+       }
+       spin_unlock_irqrestore (&ehci->lock, flags);
+
+       /* temporarily store schedule info in hcpriv */
+       urb->hcpriv = sched;
+       urb->error_count = 0;
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* itd_init - performs master initilization of the ITD fields that are
+ * drawn from the stream structure.
+ *
+ * @stream: iso stream
+ * @itd: New ITD that is to be added to the shadow/hardware schedule
+ */
 static inline void
 itd_init (struct ehci_iso_stream *stream, struct ehci_itd *itd)
 {
@@ -1546,6 +1611,13 @@ itd_init (struct ehci_iso_stream *stream
        /* All other fields are filled when scheduling */
 }

+/* itd_patch - patches additional transfer descriptors into an existing ITD.
+ *
+ * @itd: New ITD that is to be added to the shadow/hardware schedule
+ * @iso_sched: ehci_iso_sched holding transfer descriptors
+ * @index: packet number to reference within the ehci_iso_sched
+ * @uframe: uframe in which to schedule specified packet
+ */
 static inline void
 itd_patch (
        struct ehci_itd         *itd,
@@ -1576,6 +1648,12 @@ itd_patch (
        }
 }

+/* itd_link - place one completed itd into the shadow/hardware schedule
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @frame: shadow/hardware schedule frame
+ * @itd: ITD to link into schedule
+ */
 static inline void
 itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
 {
@@ -1588,7 +1666,14 @@ itd_link (struct ehci_hcd *ehci, unsigne
        ehci->periodic [frame] = cpu_to_le32 (itd->itd_dma) | Q_TYPE_ITD;
 }

-/* fit urb's itds into the selected schedule slot; activate as needed */
+/* itd_link_urb - link urb's ITDs into the hardware schedule acording
+ * to shadow budget
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @urb: current USB request
+ * @mod: size of periodic hardware schedule [in uFrames]
+ * @stream: stream into which to queue request
+ */
 static int
 itd_link_urb (
        struct ehci_hcd         *ehci,
@@ -1663,6 +1748,15 @@ itd_link_urb (

 #define        ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | 
EHCI_ISOC_XACTERR)

+/* itd_complete - process a single complete ITD that has been removed
+ * from the periodic schedule and handed to us by scan_periodic.  If
+ * this is the last ITD that needed to be completed for a URB, hand
+ * the URB back to the upper level driver.
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @itd: completed ITD
+ * @regs: ptrace registers
+ */
 static unsigned
 itd_complete (
        struct ehci_hcd *ehci,
@@ -1744,8 +1838,13 @@ itd_complete (
        return 1;
 }

-/*-------------------------------------------------------------------------*/
-
+/* itd_submit - top level submission point for a HS isochronous
+ * endpoint request.
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @urb: new USB request
+ * @mem_flags: flags for memory allocation
+ */
 static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
        gfp_t mem_flags)
 {
@@ -1803,12 +1902,17 @@ done:
 #ifdef CONFIG_USB_EHCI_SPLIT_ISO

 /*-------------------------------------------------------------------------*/
+/* Split-ISO transfer machinery; used for FS isoch transfers through the
+ * TTs in USB 2.0 hubs. */

-/*
- * "Split ISO TDs" ... used for USB 1.1 devices going through the
- * TTs in USB 2.0 hubs.  These need microframe scheduling.
+/* sitd_sched_init - sITD-specific initialization of an ehci_iso_sched
+ * structure to hold the specifics of the current requested
+ * transaction during the various steps of budgeting and scheduling.
+ *
+ * @iso_sched: structure to initialize
+ * @stream: iso stream
+ * @urb: current request
  */
-
 static inline void
 sitd_sched_init (
        struct ehci_iso_sched   *iso_sched,
@@ -1857,6 +1961,15 @@ sitd_sched_init (
        }
 }

+/* sitd_urb_transaction - sets up memory and relevant structures to
+ * process current transaction; initializes the iso_sched structure
+ * and preallocates transfer descriptors
+ *
+ * @stream: iso stream
+ * @ehci: pointer to ehci host controller device structure
+ * @urb: current request
+ * @mem_flags: flags to use for in-kernel memory allocation
+ */
 static int
 sitd_urb_transaction (
        struct ehci_iso_stream  *stream,
@@ -1924,8 +2037,15 @@ sitd_urb_transaction (
        return 0;
 }

-/*-------------------------------------------------------------------------*/
-
+/* sitd_patch - finishes filling in the hardware fields of a sITD
+ * schedule prior to it being linked into the hardware/shadow
+ * schedule.
+ *
+ * @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
+ */
 static inline void
 sitd_patch (
        struct ehci_iso_stream  *stream,
@@ -1954,6 +2074,13 @@ sitd_patch (
        sitd->index = index;
 }

+/* sitd_link - fill in and link one sITD into the shadow/hardware
+ * schedule
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @frame: shadow/hardware schedule frame
+ * @sitd: sitd to link
+ */
 static inline void
 sitd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_sitd *sitd)
 {
@@ -1966,7 +2093,14 @@ sitd_link (struct ehci_hcd *ehci, unsign
        ehci->periodic [frame] = cpu_to_le32 (sitd->sitd_dma) | Q_TYPE_SITD;
 }

-/* fit urb's sitds into the selected schedule slot; activate as needed */
+/* sitd_link_urb - link urb's sITDs into the hardware schedule
+ * acording to shadow budget
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @urb: current USB request
+ * @mod: size of periodic hardware schedule [in uFrames]
+ * @stream: stream into which to queue request
+ */
 static int
 sitd_link_urb (
        struct ehci_hcd         *ehci,
@@ -2029,11 +2163,18 @@ sitd_link_urb (
        return 0;
 }

-/*-------------------------------------------------------------------------*/
-
 #define        SITD_ERRS (SITD_STS_ERR | SITD_STS_DBE | SITD_STS_BABBLE \
                                | SITD_STS_XACT | SITD_STS_MMF)

+/* sitd_complete - process a single complete sITD that has been removed
+ * from the periodic schedule and handed to us by scan_periodic.  If
+ * this is the last sITD that needed to be completed for a URB, hand
+ * the URB back to the upper level driver.
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @sitd: completed sITD
+ * @regs: ptrace registers
+ */
 static unsigned
 sitd_complete (
        struct ehci_hcd         *ehci,
@@ -2104,6 +2245,13 @@ sitd_complete (
 }


+/* sitd_submit - top level submission point for a FS split isochronous
+ * endpoint request.
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @urb: new USB request
+ * @mem_flags: flags for memory allocation
+ */
 static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
        gfp_t mem_flags)
 {
@@ -2177,8 +2325,15 @@ sitd_complete (

 #endif /* USB_EHCI_SPLIT_ISO */

-/*-------------------------------------------------------------------------*/
-
+/* scan_periodic - completion worker; called out of interrupt (or
+ * poll) handler to finish processing of transactions that have been
+ * completed by the host controller.  Also now has the responsibility
+ * of halting the hardware periodic schedule after a complete pass
+ * through the schedule with nothing to do.
+ *
+ * @ehci: pointer to ehci host controller device structure
+ * @regs: ptrace registers
+ */
 static void
 scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs)
 {

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to