Hi Peter,
On Wednesday 03 May 2017 11:10:55 Peter Chen wrote:
> On Tue, May 02, 2017 at 03:07:03PM +0300, Laurent Pinchart wrote:
> > Hello,
> >
> > I ran into an issue with a Xilinx Zynq XC7Z010 system. The system acts as
> > a USB peripheral, using the UVC gadget driver.
> >
> > When transferring high bandwidth data over USB in isochronous mode,
> > complete system freezes are occasionally noticed. The problem was traced
> > to the following code from _hardware_enqueue() in
> > drivers/usb/chipidea/udc.c.
> >
> > wmb();
> > if (hw_read(ci, OP_ENDPTPRIME, BIT(n)))
> > goto done;
> > do {
> > hw_write(ci, OP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
> > tmp_stat = hw_read(ci, OP_ENDPTSTAT, BIT(n));
> > } while (!hw_read(ci, OP_USBCMD, USBCMD_ATDTW));
> > hw_write(ci, OP_USBCMD, USBCMD_ATDTW, 0);
> > if (tmp_stat)
> > goto done;
> >
> > The do ... while loop loops forever, and as the function is called under a
> > spin_lock_irqsave(), the system doesn't appreciate. Adding a maximum
> > number of iterations to exit the loop is easy (I'll try to submit a patch
> > after finding the root cause of the problem). That fixes the system hang,
> > but USB transfers are still broken.
> >
> > I've checked the code and unfortunately it seems to match the procedure
> > documented in the datasheet :-/
> >
> > The MTBF is several hours, but running 'memtester -M100'
> > (http://pyropus.ca/software/memtester/) in parallel to UVC video transfer
> > over USB brings the MTBF to a few minutes. The problem thus seems to be
> > related to memory bus pressure.
> >
> > Has anyone run into this problem before ? Is this a known issue ? I don't
> > mind getting my hands dirty debugging, but as I'm not familiar with the
> > chipidea USB controller pointers to what I should check in priority would
> > be appreciated.
>
> There was no one reported this problem before, but from the description,
> it seems an IC issue which is triggered at high loading memory bus,
> controller may not get time to visit memory at limited time. At
> Xilinx Zynq, its tx buffer is small, and less than 512 bytes (84bc70f94d81,
> "usb: chipidea: add xilinx zynq platform data"), and your throughput
> may be > (512 * 3) bytes/SoF, you can't use non-stream mode by reducing
> max packet size. I think you may observe many under-run at bus analyzer
> during the test.
>
> As a workaround, you may try to do below things:
>
> 1. Link more TDs before the UVC run
> 2. Comment out the code, you are stuck in, it is only useful for protect
> last td status which is handling or will be handled soon by hardware.
> /*
> do {
> hw_write(ci, OP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
> tmp_stat = hw_read(ci, OP_ENDPTSTAT, BIT(n));
> } while (!hw_read(ci, OP_USBCMD, USBCMD_ATDTW));
> hw_write(ci, OP_USBCMD, USBCMD_ATDTW, 0);
> if (tmp_stat)
> goto done;
> */
> 3. If it can let your test run more time, try change code like below:
>
> if (remaining_td_num > 2)
> don't do hardware check;
> else
> do hardware check.
>
>
> Besides, I can try your test if you could show me the detail test steps.
By the way, do you have access to a Xilinx Zynq-based board for testing ? If
you do, what board is that ? And if you don't, what board would you use ?
--
Regards,
Laurent Pinchart
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html