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