MUSB issue

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

 



Hello Felipe,

We have discovered an issue in MUSB gadget when receiving control OUT
transfers. I have specifically observed it very frequently on the second
SET_CUR UVC request when trying to stream video with yavta from a UVC
gadget.

What happens is that in the DATA phase, the controller copies the
incoming data to FIFO which generates an interrupt (as per the docs),
then the interrupt handler (actually ep0_rxstate) sends a stall because
there is no usb_request to put the data into.

Currently this usb_request is supposed to come from userspace by ioctl
UVCIOC_SEND_RESPONSE, which means that (more often than not) if the
interrupt corresponding to the DATA phase comes before userspace has a
chance to call the ioctl (or before the ioctl handler has a chance to
finish), then it will send a stall (usbmon ends with EPIPE).


I found this in ep0_rxstate:
/* read packet and ack; or stall because of gadget driver bug:
 * should have provided the rx buffer before setup() returned.
 */
Which I suppose correctly describes the observed behavior. However,
what we have now is that setup(), which is composite_setup ->
uvc_function_setup, queues a UVC event to userspace so that userspace
can do stuff or validation on the usb_request. This means that the rx
buffer cannot be provided before setup() returns. So, is this a
requrement of the USB gadget stack, or of MUSB?

We have also considered enqueuing a usb_request synchronously in the
setup handler (only for OUT transfer), instead of having userspace queue
it via ioctl. The problem is that there doesn't seem to be any way for
the gadget to signal errors from the DATA phase. This means that all
parameter validations would have to be done in the SETUP phase, and if the
usb_requst has to be queued synchronously then, then the checks can't
be performed by userspace. This is a problem since in our case, only
userspace has enough information to perform validation.

===

Log (reordered into threads of execution; timestamps are preserved):

(irq for SETUP phase of SET_CUR (21 01))
[  954.976318] in musb_g_ep0_irq: csr 0001, count 8, ep0stage out/status
[  954.976318] in musb_read_setup: ------ setting musb stage to rx (out)
[  954.983154] in musb_g_ep0_irq: ------ handled 0, csr 0001, ep0stage out
[  954.983154] in uvc_function_setup: setup request 21 01 value 0100 index 0001 001a
[  954.983184] in musb_g_ep0_irq: ------ after, handled = 0, state = out

(irq for DATA phase)
[  954.983245] in musb_g_ep0_irq: csr 0001, count 0, ep0stage out
[  954.998504] in ep0_rxstate: -------- sending stall

(irq after SENTSTALL)
[  954.998565] in musb_g_ep0_irq: csr 0004, count 0, ep0stage out
[  955.005462] in musb_g_ep0_irq: ---- setting idle state coz need to ack stall
[  955.005462] in musb_g_ep0_irq: ---- new csr = 0
[  955.012420] in musb_g_ep0_irq: ------ setting musb stage to setup

(ioctl handler for UVCIOC_SEND_RESPONSE)
[  954.983245] in uvc_v4l2_ioctl_default: handling ioctl
[  955.005462] in uvc_v4l2_ioctl_default: --- sending response
[  955.020385] in uvc_send_response: --- queueing usb ep
[  955.075744] in musb_g_ep0_queue: --- ep0 request queued in state setup
[  955.088134] in musb_g_ep0_queue: ret status from musb_g_ep0_queue is -22

Thanks,

Paul

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