Dear Alan I'm facing an issue on isoc sitd dma recycling. I'm using an omap3 (beableboard xM) board and after a while I don't have anymore the possibity to allocate dma sitd from the pool (128Kb, 1M, 4M, it is a matter of time). I'm playing flac music from usb disk and send on a dac connected to another usb port of the same controller. Right now I'm experimenting this patch (not for any submission) and it seems that it masks/fixes the problem. diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index b476daf..183d4ec 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1166,7 +1166,8 @@ itd_urb_transaction ( gfp_t mem_flags ) { - struct ehci_itd *itd; + struct ehci_itd *itd = NULL; + bool found; dma_addr_t itd_dma; int i; unsigned num_itds; @@ -1187,18 +1188,24 @@ itd_urb_transaction ( /* allocate/init ITDs */ spin_lock_irqsave (&ehci->lock, flags); for (i = 0; i < num_itds; i++) { + found = false; /* * Use iTDs from the free list, but not iTDs that may * still be in use by the hardware. */ if (likely(!list_empty(&stream->free_list))) { - itd = list_first_entry(&stream->free_list, - struct ehci_itd, itd_list); - if (itd->frame == ehci->now_frame) + list_for_each_entry(itd, &stream->free_list, + itd_list) { + if (itd->frame != ehci->now_frame) { + list_del(&itd->itd_list); + itd_dma = itd->itd_dma; + found = true; + break; + } + } + if (found == false) goto alloc_itd; - list_del (&itd->itd_list); - itd_dma = itd->itd_dma; } else { alloc_itd: spin_unlock_irqrestore (&ehci->lock, flags); @@ -1868,7 +1875,8 @@ sitd_urb_transaction ( gfp_t mem_flags ) { - struct ehci_sitd *sitd; + struct ehci_sitd *sitd = NULL; + bool found = false; dma_addr_t sitd_dma; int i; struct ehci_iso_sched *iso_sched; @@ -1894,12 +1902,17 @@ sitd_urb_transaction ( * still be in use by the hardware. */ if (likely(!list_empty(&stream->free_list))) { - sitd = list_first_entry(&stream->free_list, - struct ehci_sitd, sitd_list); - if (sitd->frame == ehci->now_frame) + list_for_each_entry(sitd, &stream->free_list, + sitd_list) { + if (sitd->frame != ehci->now_frame) { + list_del(&sitd->sitd_list); + sitd_dma = sitd->sitd_dma; + found = true; + break; + } + } + if (found == false) goto alloc_sitd; - list_del (&sitd->sitd_list); - sitd_dma = sitd->sitd_dma; } else { alloc_sitd: spin_unlock_irqrestore (&ehci->lock, flags); What do you think? Michael -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html