On Fri, Feb 20, 2009 at 11:32:24PM +0300, Sergei Shtylyov wrote: > The MUSB code either expects TXCSR.DMAReqEnab bit cleared in several places > and then proceeds with clearing the TXCSR.DMAMode bit (but does not bother > with actually clearing DMAReqEnab beforehand) or just clears both bits at > once -- while is the programming guide explicitly forbids to clear DMAMode > before or in the same cycle as DMAReEnab. Fix this and while at it: > > - in musb_gadget::txstate(), stop clearing the AutoSet and DMAReqMode bits for > the CPPI case since they never get set anyway (the former bit is reserved on > DaVinci) but do clear the DMAReqEnab bit on the DMA error path; > > - in musb_host::musb_ep_program(), remove the duplicate DMA controller specific > code code clearing the TXCSR previous state, add the code to clear TXCSR DMA > bits on the Inventra DMA error path, to replace such code (executed late) on > the PIO path; > > - in musbhsdma::dma_channel_abort()/dma_controller_irq(), add/use the 'offset' > variable to avoid MUSB_EP_OFFSET() invocations on every RXCSR/TXCSR access. > > Signed-off-by: Sergei Shtylyov <sshtylyov@xxxxxxxxxxxxx> I ran into the same issue and had to fix similarly, the patch still in my "nokia-only" queue. Good that you're pushing your version out :-) just one comment below > Index: linux-2.6/drivers/usb/musb/musb_gadget.c > =================================================================== > --- linux-2.6.orig/drivers/usb/musb/musb_gadget.c > +++ linux-2.6/drivers/usb/musb/musb_gadget.c > @@ -165,9 +165,19 @@ static void nuke(struct musb_ep *ep, con > if (is_dma_capable() && ep->dma) { > struct dma_controller *c = ep->musb->dma_controller; > int value; > + > if (ep->is_in) { > + u16 txcsr = musb_readw(epio, MUSB_TXCSR); this looks unnecessary, in the end you just wanna keep FLUSHFIFO set so... > + > + /* > + * The programming guide says that we must not clear > + * the DMAReqMode bit before DMAReqEnab, so we only > + * clear it in the second write... > + */ > + txcsr &= MUSB_TXCSR_DMAMODE; > + > musb_writew(epio, MUSB_TXCSR, > - 0 | MUSB_TXCSR_FLUSHFIFO); > + txcsr | MUSB_TXCSR_FLUSHFIFO); musb_writew(epio, MUSB_TXCSR, 0 | MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO); musb_writew(epio, MUSB_TXCSR, 0 | MUSB_TXCSR_FLUSHFIFO); should do it. -- balbi -- 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