This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

OMAP L138 [musb/gadgetfs] control out transfers get lost

I would like to implement a usb device using gadgetfs and a usermode driver. The processor is a OMAP L138 on an logicpd experimenter kit.

 

Kernel 2.6.37 (from DaVinci-PSP-SDK-03.21.00.04) is configured to supply the gadgetfs module. A simple userspace application (derived from usb.c - http://www.lrr.in.tum.de/Par/arch/usb/linux-usb/gadget/usb.c) implements a control out transfer with 7 bytes in the data stage. 

 

When i send the command once, everything is fine, i see the musb debug output "musb_read_setup 616: SETUP req40.cb v0000 i0000 l7" in the kernel logs, my userspace application handles the request and receives the data.

 

Sending the control out request 500 times in a loop gives 500 times the musb log message in the kernel log but the userspace application sees the request about 450 times (varies slightly from run to run). It seems that each request is handled correctly by the kernel driver but the userspace part misses some of them. 

From the host computers point of view the 500 control out transfers finish as expected.

 

Is anyone facing the same problem? Is it generally a bad idea to use gadgetfs, should i write a separate gadget driver? Are more details (kernelconfig, code, ..) needed to answer my questions?

Any help would be appreciated.

 

Thanks,

Michael

  • Michael

    I assume this problem you observe in DMA mode enabled, have you tried with PIO mode, whether the gadgetfs working in PIO mode?

    Regards

    Ravi B

     

     

  • I've never used GadgetFS. My project needed low-level control and I eventually had to write my own Gadget. Some speculation on my part.

    From an inspection of the GadgetFS code, I don't think GadgetFS buffers messages. A new message will overwrite the previous message. You should get an errno of EIDRM on read() and POLLHUP on poll().

    I believe a new control message would not normally arrive until the current message is dealt with and acked. The host may timeout on the device and send another message. I would guess that your process is swapped out longer than the host timeout period and the host decides to send another message. I guess you could try elevating your process priority and test again.

  • Ravi B

    You are right, musb-hdrc was compiled in DMA mode (Kernel options "CONFIG_USB_CPPI41_DMA_HW = y" and "CONFIG_USB_TI_CPPI41_DMA=y"). 

    After recompiling the kernel with "CONFIG_MUSB_PIO_ONLY=y" the behaviour did not change, my userspace program still misses control transfers. So i suppose dma is not the reason for my problem, anyway - thans for the fast reply.

    Regards,

    Michael

  • Norman Wong said:

    I've never used GadgetFS. My project needed low-level control and I eventually had to write my own Gadget. Some speculation on my part.

    From an inspection of the GadgetFS code, I don't think GadgetFS buffers messages. A new message will overwrite the previous message. You should get an errno of EIDRM on read() and POLLHUP on poll().

    Yes, read() fails with EIDRM (sorry - i forgot to mention that, i tried a lot of things because i thought the problem was my userspace application before i realized that gadgetfs does not behave as i expect).

    Norman Wong said:

    I believe a new control message would not normally arrive until the current message is dealt with and acked. The host may timeout on the device and send another message. I would guess that your process is swapped out longer than the host timeout period and the host decides to send another message. I guess you could try elevating your process priority and test again.

    I am confused because transfers seem to get ACKed by gadgetfs before the userspace application even "sees" them. In my opinion it would be ok if a transfer fails because the device is not ready and the host is aware of this situation. 

    Elevating the process priority and inserting a small delay between the control transfers (on the host side) improved the situation. 

    Regards

    Michael

     

     

  • The GadgetFS appears to allow the user space app to stall the endpoint. The app does this by doing the opposite of what is expected, ie read when it should write and write when it should read. Pseudo code for a control message with data:

    read(ctrl_msg) - setup phase, auto acked
    read(data) - data phase, no status sent back.
    if my device supports this message
      write(0) - status phase, ack
    else
      read(0) - status phase, stall

    All speculation on my part.  I know that in my Gadget driver, I do stall the endpoint on certain set messages that I don't support. The HW is capable of it.

    On the host side, you should get some sort of error that the transmission has timed out. Hardware USB sniffers are really nice for this sort of thing.

    Unfortunately, I don't see any way to guarantee that a process is not swapped out in the midst of a control transaction. Not sure if there are any Linux APIs to establish a critical section to avoid swap out. You might want to try the Serial Gadget for streaming data.