Sunday 27 June 2010

Weekly report - Week 5

Status:
  • Managed to fix the throughput issue with my USB flash device. I now get 19.11 MB/sec, close to the maximum throughput when the USB device is directly connected to the host.
    In my previous version, I used only one urb/request pair per endpoint: when data came from the device (through an urb), it was forwarded to the host (as a request), and the driver would only resubmit the urb when the data was properly sent to the host.

    • I fixed this by having 8 urb/requests submitted to the USB controller driver, to make sure that there is always some buffer available to write incoming data to. This alone improved the performance to 12.79 MB/sec.
    • The second thing I did is to have a larger buffer per urb/request: instead of allocating 512 bytes (i.e. wMaxPacketSize) per urb/request, I allocated 4096 bytes. I guess that this reduces the number of interrupts (and the number of times my handlers are called), giving an extra performance gain. This should also be transparent to the host/device, as transfers larger than wMaxPacketSize are split into smaller packets of size wMaxPacketSize (except the last one). Since our buffer size is a multiple of wMaxPacketSize, this should not cause problems.

  • SET_INTERFACE command works (this is a prerequisite for isochronous transfers). This was a bit tricky, as disabling endpoints cannot be done in interrupt context, so I submit a work_struct to do that in process context.
  • I started working on isochronous transfers. I got clean audio coming from the microphone integrated in a webcam. The video still does not work, but I am working on it.
Plans:
  • Fix isochronous transfers, as the urb buffer is filled in a special way in these cases (I'll write about that next week), my code works by chance with the audio from the webcam.
  • Code cleanup, again. Some parts are unstable again, causing oopses and warning, after some of my recent updates.
  • Maybe, collect statistics on urb/request usage, to see how many urb/requests are needed for maximum performance.
Risks:
  • From what I see in MUSB, the driver does not support high-bandwidth endpoints (i.e. isochronous transfers with maxPacketSize > 1024 bytes), that are used by High-Speed device. The driver may need to be updated.
  • Bandwidth allocation: with this proxy model, there is nothing much with can do if bandwidth allocation fails on the BeagleBoard. If the host believes enough bandwidth is available, it will use high-throughput interfaces, and there is nothing that can be done on the BeagleBoard to prevent that, in case there is not enough bandwidth available on the EHCI controller of the BeagleBoard. This causes problems with the video on the USB webcam, but the configuration option CONFIG_USB_EHCI_TT_NEWSCHED seems to help, though.