DWC OTG USB, round 3 (was: hardware driver <-> gadget driver...)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Paul and Alan,
21.01.2012 1:17, Paul Zimmerman:
On Fri, 20 Jan 2012, Alan Stern wrote:

This is a serious problem.  The gadget API does not specify whether
usb_ep_enable and usb_ep_disable should be able to run in interrupt
context.  Consequently we end up with UDC drivers like your DWC thing
in which the routines cannot run in interrupt context, together with
gadget drivers like g_serial which do call them in interrupt context.

It may be that the best solution is for the composite.c driver to
implement Set-Config and Set-Interface requests in a workqueue, so that
the calls could be made in process context.  For now, you can avoid the
problem by not calling dma_alloc_coherent in your endpoint-setup
routine.

g_file_storage doesn't have this problem because it uses its own kernel
thread for handling these requests.

Actually, dma_alloc_coherent() takes a gfp_t parameter, so you should be
able to set GFP_ATOMIC and do the allocation from interrupt context.

The problem comes from dma_free_coherent(). It unconditionally checks for
being called in process context, and gives a warning if not. This check was
added a year or two ago, for something in the ARM architecture IIRC. I keep
expecting that this will get fixed at some point, but so far it hasn't.

Based on your comments I decided to move some preparations to a workqueue and there are no issues with those allocations anymore.

I've now finally got g_serial fully recognised on another side (by host PC) and was even able to open the respective serial device there, but unfortunately for that to succeed I had to also disable (just throw away) all requests for EPs != 0 (I did this in ep_queue in dwc driver, if matters). Without that, controller starts raising "IN Token Received with EP mismatch" instead of normal "Transfer complete" bit. If I understand it correctly, this means that Tx FIFO happened to be filled in some particular order that controller disliked (and refused). I've also found a fragment of code with possibly relevant comment (quoted below). Indeed, apparently this "EP mismatch" event is not handled anywhere in the driver (other than providing a line for dmesg). If it should, then I'd guess it means the driver is just plain unfininshed and I have no idea if it can even be fixed with a reasonable effort. Not sure what was meant exactly by "one endpoint at once" though.. Of course usefull gadget drivers would probably employ > 1 EPs, even g_file_storage does so? Strange thing.

Thank you.
Nikolai

/* Reactive the EP */
dwc_otg_ep_activate(GET_CORE_IF(pcd), &ep->dwc_ep);
if (ep->stopped) {
	ep->stopped = 0;
	/* If there is a request in the EP queue start it */

	/** @todo FIXME: this causes an EP mismatch in DMA mode.
	 * epmismatch not yet implemented. */

	/*
	 * Above fixme is solved by implmenting a tasklet to call the
	 * start_next_request(), outside of interrupt context at some
	 * time after the current time, after a clear-halt setup packet.
	 * Still need to implement ep mismatch in the future if a gadget
	 * ever uses more than one endpoint at once
	 */
	ep->queue_sof = 1;
	tasklet_schedule (pcd->start_xfer_tasklet);
}
/* Start Control Status Phase */
do_setup_in_status_phase(pcd);

--
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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux