On 05/23/2014 03:18 PM, George Cherian wrote: > On 5/23/2014 3:01 PM, Daniel Mack wrote: >> Before accessing any of an endpoint's CSR registers, make sure the >> correct endpoint is selected. Otherwise, data read from or written to >> the registers is likely to affect the wrong endpoint as long as the >> connected device has more than one endpoint. >> >> This, of course, leads to all sorts of strange effects such as stream >> starvation and driver internal state machine confusion due to spurious >> interrupts. >> >> Signed-off-by: Daniel Mack <zonque@xxxxxxxxx> >> --- >> drivers/usb/musb/musb_cppi41.c | 17 ++++++++++++++--- >> 1 file changed, 14 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c >> index a11bbb6..db497dd 100644 >> --- a/drivers/usb/musb/musb_cppi41.c >> +++ b/drivers/usb/musb/musb_cppi41.c >> @@ -58,14 +58,17 @@ struct cppi41_dma_controller { >> >> static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel) >> { >> + struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; >> + struct musb *musb = hw_ep->musb; >> u16 csr; >> u8 toggle; >> >> if (cppi41_channel->is_tx) >> return; >> - if (!is_host_active(cppi41_channel->controller->musb)) >> + if (!is_host_active(musb)) >> return; >> >> + musb_ep_select(musb->mregs, hw_ep->epnum); > > save_rx_toggle is called from cppi41_configure_channel as part of > channel_program() from musb_host_rx() > and musb_ep_program(). Both these functions call musb_ep_select() before > calling channel_program(). > > Both musb_ep_program() and musb_host_rx() are called with IRQ's disabled. > Still do we need this musb_ep_select() in save_rx_toggle? Or am I confused? No, you're right. It seems not necessary here. >> @@ -173,6 +180,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) >> dma_async_issue_pending(dc); >> >> if (!cppi41_channel->is_tx) { >> + musb_ep_select(musb->mregs, hw_ep->epnum); > Since in update_rx_toggle () we did musb_epe_select(), do we really it > again here? I'd say so, because cppi41_trans_done() may be called from a work tasklet or hrtimer callback. In such cases, another endpoint might have been selected. >> @@ -565,6 +574,8 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel) >> if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE) >> return 0; >> > musb_ep_select is done before calling channel_abort. Right, thanks for spotting this. I'll drop it in v3. Thanks, Daniel -- 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