Notes about writing usb slave drivers

I passionately hate USB.

Maybe I'm just dumb, but I think USB is horribly complex.  I once
mentioned this to a friend, who's a hardware (chip) guy, and he was
surprised me saying so.  The thing is that the hardware side of usb is
actually quite simple, and that's why it's cheap.

The software layers on top of it however are simply horrible.  A
marvelous example of design-by-committee[1], where an overly complex
spec leads to to misunderstanding by developers that design devices,
which leads to bugs that stick because the existence of workarounds on
the host side -- introduced by a first generation of buggy devices --
never encourages developers to actually follow the specs since "it
works, anyway". (Postel's law gone bad [2]).

The big irony of USB is that it contains a lot of device classes that
are supposed to be universal: one host driver handles them all.
However, if you look at the host driver in in Linux, it still needs to
identify the devices by their vendor:device ID in order to perform
workarounds, because in reality many of these devices contain bugs.

The dream does does seem to work in general for printers, disks,
keyboards and mice.  And audio and midi devices.  So I'm going to
assume I'm just dumb and will now go out to slay that dragon.

EDIT 8/2013: After getting my hands dirty on some more real world
protocols, I'm inclined to think that getting *something* to work when
a lot of people are involved in designing a protocol is a victory in
itself.  Elegance in procols seems to only work when they never have
to be extended.  The pain comes from not being able to design or
maintain a minimal interface over time due to backwards compatibility
issues or simply lack of overview or agreement.  I tend to relate
protocol elegance to the ease at wich parsing state machines can be
built in a particular style (see some other post on protocol-oriented
programming).  More specifically: how much buffering is needed, and
how many branch points does the code contain?

EDIT 7/2014: I'll leave the social commentary in, but hey I got some
things to work.  USB is not that bad once it becomes clear that most
of the horror can be ignored.  It's just buffered streams, really.

[1] http://en.wikipedia.org/wiki/Design_by_committee
[2] http://en.wikipedia.org/wiki/Robustness_principle

20140709 Staapl drivers
20130914 CDC SETUP requests
ACM descriptor
20130908 Distinguishing a bag of USB serial adapters
20130901 USB ACM
20130831 Staapl USB ACM serial driver
20130809 USB control OUT
USB linux
Sending raw control transfers
USB: device / configuration / interface
20120523 Got a USB sniffer
20110408 USB low-level
PK2 done
20110329 libusb, Racket FFI and PK2
20110314 libusb talk
20110307 Staapl code on PIC18
20110306 USB docs
Linux KVM workbench