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