Libusb Port (Pencils Down)

Blog post by akshay1994 on Mon, 2014-08-18 06:47

As you would know, my project was porting libusb to Haiku.
Initially I planned to use USBKit for the Haiku backend, as that was what was used by Pulkomandy in his port of libusbx (and my work thus was to hunt down bugs in this and complete this).

I started tracking the bugs one by one, starting with the Segment Violation on running a Mass Storage test. A null pointer was being accessed. Added a check, which libusb guys mentioned was a wrong way to do things. (I left this as is for a few weeks, completing other functionalities meanwhile. The bug was due to an int function returning no value.)
Next, the program hung while fetching string descriptors. A quick control transfer using USBKit told this behaviour was independent of libusb.
Dive into the lower layers!! (usb_raw -> bus_manager -> busses[EHCI,UHCI])
The problem was with Short Packet transfers. Our usb stack used a trick to avoid this problem: First get the string descriptor length, then query the exact amount. This wouldn’t work with libusb.
I was able to fix this for EHCI and Pulkomandy also tested my patch for UHCI.

At this point I decided to use usb_raw instead of USBKit for the port. Next few weeks were spent on writing the backend, fixing issues (a lot more issues popped up as the work progressed), etc.

Post mid-term, I decided to work on the XHCI driver. I list down some of the fixes to the XHCI HC:

  • Add support for hubs in AllocateDevice().
  • Prevent page fault in FinishTransfers().
  • Set fCapabilityLength
  • Correction in BIOS ownership code
  • Fix context errors in _InsertEndpointForPipe().
  • Update constants according to latest Specification (v1.1)
  • Fix SMI code (reference http://lkml.iu.edu/hypermail/linux/kernel/1204.2/02460.html).
  • Fix Memory/Device-Slot leaks.
  • Fix area allocation for TRBs.
  • Fix for Intel Lynx Point and Panther Point chipsets. Also move init of xhci before ehci, to switch USB 2.0 ports before the ehci module discovers them.
  • Fix device speed identification.
  • Fix Max Packet Size for Full-Speed devices.
  • Fix IRQ rate.
  • Update slot context for LS/FS devices connected to non-root HS hub.
  • Fix Endpoint Context Initialisation (Refer xHCI v1.1 - 6.2.3)
  • Fix Interval Calculation (Refer xHCI v1.1 - 6.2.3.6 , USB 2.0 - 9.6.6 page 271)
  • Fix MaxBurst, MaxPacketSize Calculation (Refer xHCI v1.1 - 6.2.3.5, USB 2.0 - 9.6.6 page 271)
  • Fix MaxESITPayload Calculation (Refer xHCI v1.1 - 4.14.2)
  • Remove Link TRBs as they were never being used
  • Increase Number of TRBs per endpoint (to utilise the whole area allocated for Device TRBs)
  • Fix usage of XHCI_MAX_ENDPOINTS (most of the checks were failing at corner cases)
I was able to boot from a USB3.0 port, and mass storage devices work (with the logs enabled).

At this point I turned back to the libusb port, giving the port finishing touches.
I’m now waiting for libusb moderators to merge my work.
Pulkomandy tested the port with AVRDude, which works (except for some issues with UHCI). I myself tested this with a PS3 controller, and dfu-programmer (the recipe for which has been added to HaikuPorts), to dump the firmware of an Arduino UNO.

Ending this, I would like to thank everyone for allowing we to work on such an amazing project, and everyone who helped me out, on IRC, on the mailing lists, and everywhere else. :)

Thanks a lot.


Akshay Jaggi

[1] https://github.com/akshay1994/libusb
[2] https://cgit.haiku-os.org/haiku/log/?qt=author&q=akshay1994
[3] https://dev.haiku-os.org/ticket/8954
[4] https://dev.haiku-os.org/ticket/10867
[5] https://dev.haiku-os.org/ticket/10915
[6] http://www.google-melange.com/gsoc/proposal/public/google/gsoc2014/akshay1994/5629499534213120