In EHCI, each ITD's member index[8] stores the offset in its urb's
iso_frame_desc[] for status updates while in itd_scan().  This can be
simplified by storing only the first unfinished microframe's index,
updating it when scanning the completed ITD to save 7*4 = 28 bytes.
(Based on a patch from Karsten Wiese.)

This lets each 4K page allocate three (x86_64) or four (x86_32) more
ISO descriptors than before, when combined with a previous patch that
saves another eight bytes per ITD.

Signed-off-by: David Brownell <[EMAIL PROTECTED]>
---
NOTE:  depends textually on the previous save-space patch, but
there's no technical interdependency.  This merits testing from
someone that uses high speed ISO, just for paranoia's sake.

 drivers/usb/host/ehci-dbg.c   |    5 +----
 drivers/usb/host/ehci-sched.c |   25 +++++++++++++++----------
 drivers/usb/host/ehci.h       |    2 +-
 3 files changed, 17 insertions(+), 15 deletions(-)

--- g26.orig/drivers/usb/host/ehci-dbg.c        2007-12-31 00:02:30.000000000 
-0800
+++ g26/drivers/usb/host/ehci-dbg.c     2007-12-31 00:02:59.000000000 -0800
@@ -165,10 +165,7 @@ dbg_itd (const char *label, struct ehci_
                hc32_to_cpu(ehci, itd->hw_bufp[4]),
                hc32_to_cpu(ehci, itd->hw_bufp[5]),
                hc32_to_cpu(ehci, itd->hw_bufp[6]));
-       ehci_dbg (ehci, "  index: %d %d %d %d %d %d %d %d\n",
-               itd->index[0], itd->index[1], itd->index[2],
-               itd->index[3], itd->index[4], itd->index[5],
-               itd->index[6], itd->index[7]);
+       ehci_dbg (ehci, "  index: %d\n", itd->index);
 }
 
 static void __maybe_unused
--- g26.orig/drivers/usb/host/ehci-sched.c      2007-12-31 00:00:03.000000000 
-0800
+++ g26/drivers/usb/host/ehci-sched.c   2007-12-31 09:48:09.000000000 -0800
@@ -1431,17 +1431,12 @@ static inline void
 itd_init(struct ehci_hcd *ehci, struct ehci_iso_stream *stream,
                struct ehci_itd *itd)
 {
-       int i;
-
        /* it's been recently zeroed */
        itd->hw_next = EHCI_LIST_END(ehci);
        itd->hw_bufp [0] = stream->buf0;
        itd->hw_bufp [1] = stream->buf1;
        itd->hw_bufp [2] = stream->buf2;
 
-       for (i = 0; i < 8; i++)
-               itd->index[i] = -1;
-
        /* All other fields are filled when scheduling */
 }
 
@@ -1460,7 +1455,6 @@ itd_patch(
        // BUG_ON (pg == 6 && uf->cross);
 
        uframe &= 0x07;
-       itd->index [uframe] = index;
 
        itd->hw_transaction[uframe] = uf->transaction;
        itd->hw_transaction[uframe] |= cpu_to_hc32(ehci, pg << 12);
@@ -1532,6 +1526,7 @@ itd_link_urb (
                        itd->stream = iso_stream_get (stream);
                        itd->urb = usb_get_urb (urb);
                        itd_init (ehci, stream, itd);
+                       itd->index = packet;
                }
 
                uframe = next_uframe & 0x07;
@@ -1574,16 +1569,20 @@ itd_complete (
        struct usb_iso_packet_descriptor        *desc;
        u32                                     t;
        unsigned                                uframe;
-       int                                     urb_index = -1;
+       unsigned                                urb_index = itd->index;
        struct ehci_iso_stream                  *stream = itd->stream;
        struct usb_device                       *dev;
 
+       /* Caller guarantees this ITD is inactive.  We always
+        * report something for each transfer it defines.
+        */
+       desc = &urb->iso_frame_desc[urb_index];
+
        /* for each uframe with a packet */
        for (uframe = 0; uframe < 8; uframe++) {
-               if (likely (itd->index[uframe] == -1))
+               t = hc32_to_cpup(ehci, &itd->hw_bufp[uframe]);
+               if ((t >> 12) == 0)
                        continue;
-               urb_index = itd->index[uframe];
-               desc = &urb->iso_frame_desc [urb_index];
 
                t = hc32_to_cpup(ehci, &itd->hw_transaction [uframe]);
                itd->hw_transaction [uframe] = 0;
@@ -1607,7 +1606,13 @@ itd_complete (
                } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
                        desc->status = 0;
                        desc->actual_length = EHCI_ITD_LENGTH (t);
+               } else {
+                       /* "should not happen" unless HC shut down */
+                       desc->status = -EIO;
                }
+
+               desc++;
+               urb_index++;
        }
 
        usb_put_urb (urb);
--- g26.orig/drivers/usb/host/ehci.h    2007-12-31 00:00:03.000000000 -0800
+++ g26/drivers/usb/host/ehci.h 2007-12-31 00:01:25.000000000 -0800
@@ -593,7 +593,7 @@ struct ehci_itd {
        /* any/all hw_transactions here may be used by that urb */
        unsigned                frame;          /* where scheduled */
        unsigned                pg;
-       unsigned                index[8];       /* in urb->iso_frame_desc */
+       unsigned                index;          /* first urb->iso_frame_desc */
 } __attribute__ ((aligned (32)));
 
 /*-------------------------------------------------------------------------*/
-
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to