We had another go at it and this is what we have now. Already we can tell that it's much more efficient when we have multiple errors in a row we don't send as much clear requests. Can somebody comment? diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 26bda88..0f5a916 100755 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -307,6 +307,21 @@ start: } } +static void musb_clear_tt_buffer_complete(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + struct musb *musb = hcd_to_musb(hcd); + struct musb_qh *qh = ep->hcpriv; + unsigned long flags; + + if (!qh) + return; + + spin_lock_irqsave(&musb->lock, flags); + qh->clearing_tt = 0; + spin_unlock_irqrestore(&musb->lock, flags); +} + /* Context: caller owns controller lock, IRQs are blocked */ static void musb_giveback(struct musb *musb, struct urb *urb, int status) __releases(musb->lock) @@ -376,6 +391,14 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, break; } + if (urb->dev->tt && + (urb->dev->tt->hub != musb_to_hcd(musb)->self.root_hub) && + (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) && + (status || urb->unlinked) + && !qh->clearing_tt) + if (usb_hub_clear_tt_buffer(urb) == 0) + qh->clearing_tt = 1; + qh->is_ready = 0; musb_giveback(musb, urb, status); qh->is_ready = ready; @@ -2338,4 +2361,6 @@ const struct hc_driver musb_hc_driver = { .bus_resume = musb_bus_resume, /* .start_port_reset = NULL, */ /* .hub_irq_enable = NULL, */ + + .clear_tt_buffer_complete = musb_clear_tt_buffer_complete, }; diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h index 622d09f..1267448 100644 --- a/drivers/usb/musb/musb_host.h +++ b/drivers/usb/musb/musb_host.h @@ -71,6 +71,8 @@ struct musb_qh { u16 maxpacket; u16 frame; /* for periodic schedule */ unsigned iso_idx; /* in urb->iso_frame_desc[] */ + + unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ }; /* map from control or bulk queue head to the first qh on that ring */ François Gervais -- 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