On Fri, 7 Sep 2012, Alan Stern wrote:

> On Fri, 7 Sep 2012, Pavankumar Kondeti wrote:
> 
> > There is a possibility of QH overlay region having reference to a stale
> > qTD pointer during unlink.
> > 
> > Consider an endpoint having two pending qTD before unlink process begins.
> > The endpoint's QH queue looks like this.
> > 
> > qTD1 --> qTD2 --> Dummy
> > 
> > To unlink qTD2, QH is removed from asynchronous list and Asynchronous
> > Advance Doorbell is programmed.  The qTD1's next qTD pointer is set to
> > qTD2'2 next qTD pointer and qTD2 is retired upon controller's doorbell
> > interrupt.  If QH's current qTD pointer points to qTD1, transfer overlay
> > region still have reference to qTD2. But qtD2 is just unlinked and freed.
> > This may cause EHCI system error.  Fix this by updating qTD next pointer
> > in QH overlay region with the qTD next pointer of the current qTD.
> > 
> > Signed-off-by: Pavankumar Kondeti <[email protected]>
> > ---
> >  drivers/usb/host/ehci-q.c |   12 ++++++++++--
> >  1 files changed, 10 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
> > index 9bc39ca..4b66374 100644
> > --- a/drivers/usb/host/ehci-q.c
> > +++ b/drivers/usb/host/ehci-q.c
> > @@ -128,9 +128,17 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
> >     else {
> >             qtd = list_entry (qh->qtd_list.next,
> >                             struct ehci_qtd, qtd_list);
> > -           /* first qtd may already be partially processed */
> > -           if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current)
> > +           /*
> > +            * first qtd may already be partially processed.
> > +            * If we come here during unlink, the QH overlay region
> > +            * might have reference to the just unlinked qtd. The
> > +            * qtd is updated in qh_completions(). Update the QH
> > +            * overlay here.
> > +            */
> > +           if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) {
> > +                   qh->hw->hw_qtd_next = qtd->hw_next;
> >                     qtd = NULL;
> > +           }
> >     }
> >  
> >     if (qtd)
> 
> Acked-by: Alan Stern <[email protected]>

I forgot to mention: This patch should be included in the next 3.6-rc 
release and marked for -stable.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to