udev, hotplug, and firmware, oh my!
My MIDI controller (read keyboard) is an M-Audio Radium 61. I love it. Although it has standard MIDI jacks, I use the USB connection for computer use. It works great in linux, with the hotplug scripts from http://usb-midi-fw.sf.net.
That is, it did work great until udev decided to replace hotplug.
I like udev, I really do. I liked devfs too. I like superior technical
solutions, so although I had no issues with devfs, I welcomed our new dynamic
/dev overlords. But udev seems bent on world domination, and
seemingly has no desire to maintain compatibility with previous configurations
or older kernels. This would only be annoying, except as a Debian user I also
have to deal with Marco d'Itri's attitude if I have a problem. Sigh
udev decided that hotplug was unnecessary and that it should do hotplug's job. That's fine with me, really, but I just wish I had a little more warning and a little bit better instructions on migrating my configuration. There, I've ranted, and the rest of this entry will be technical details on what I did to get my Radium working again.
The problem was simple, if not simple to diagnose: the firmware wasn't getting loaded. The solution was not so simple. There's lots of posts on the web about loading firmware with udev, but most of them give a udev rule that looks like this:
ACTION=="add", SUBSYSTEM=="firmware", RUN+="/sbin/firmware_helper"
There's two assumptions here that will do you no good if you're trying to get
your midisport firmware loaded: udev has no reason to think this device has a
firmware to be loaded, so SUBSYSTEM=="firwmare" will never be matched.
Secondly, /sbin/firmware_helper does not get distributed by Debian (but it
wouldn't do you any good if it did).
Luckily we can rely on the good ol' midisport_fw script that we used before, we just need to make a udev rule for it. Here is the rule for my keyboard:
$ cat /etc/udev/rules.d/013_midisport.rules
ACTION=="add", SYSFS{modalias}=="usb:v0763p1014d0001dcFFdscFFdpFFic*isc*ip*", RUN+="/usr/local/sbin/midisport_fw"
Let's dissect this. ACTION=="add" means match when the device is being added.
SYSFS{modalias} means match when modalias, found in sysfs, matches. This will
likely be unique for your keyboard, or at least for your model of keyboard. You
can do cat /sys/bus/usb/devices/1-1/1-1:1.0/modalias to get this. You will
need to replace 1-1 with the appropriate identifier in your situation: watch
syslog when you plug in the keyboard to discover it. Finally, we
tell udev to run the midisport_fw script.
For the udev smarties reading this: if you use idProduct and idVendor
instead of (or in addition to) modalias, the script will be called thrice,
and only the middle instance is wanted. However, the other two will fail to run
and so the net effect is two more lines in syslog complaining about an unknown
product.
And finally, if your keyboard is recognized by the ALSA sequencer after loading the firmware, but no MIDI is sent, and you see the following in syslog:
kernel: usb_submit_urb: -28
Try using a different USB physical configuration. e.g. unplug other things from the hub, or bypass the hub, etc. I spent hours fighting udev (so I thought) when in reality the problem was an overloaded USB hub. Incidentally, -28 is -ENOSPC (No space left on device), which is why I chased firmware issues with udev for so long.
And finally, here's what a normal, working plug of my keyboard looks like in syslog:
Nov 21 07:15:20 falcon kernel: usb 1-1: new full speed USB device using uhci_hcd and address 2
Nov 21 07:15:20 falcon /usr/local/sbin/midisport_fw: load /lib/firmware/midisport//MidiSportKS.ihx for 763/1014/1 to /proc/bus/usb/001/002
Nov 21 07:15:25 falcon kernel: usb 1-1: USB disconnect, address 2
Nov 21 07:15:26 falcon kernel: usb 1-1: new full speed USB device using uhci_hcd and address 3
Nov 21 07:15:27 falcon kernel: usbcore: registered new driver snd-usb-audio


