Mon, 07 Nov 2005

Dave had one of those nifty front-panel multiple flash card readers
sitting on a shelf, so I borrowed it. It's USB based, fits in a
CD drive bay, and has slots for all the common types of flash memory,
as well as a generic USB socket.

With the device installed, I booted into my usual Ubuntu (hoary)
partition, inserted an SD card and checked dmesg.
Nothing! The four logical units of the device had been seen at boot
time, but nothing new happened when I inserted a card.

Dave muttered darkly about udev and hal and said I should try
it under an older Debian with a normal /dev.
I rebooted my old sid partition, with a kernel I built myself.
I needed a kernel with "Probe all LUNs on each SCSI device", of course.
I still got no messages or hotplug events when inserting the card,
but /dev/sdd1 mounted the SD card.

(For anyone reading this who's not familiar with Linux' handling
of USB storage devices, sd in /dev/sdd1 stands for "SCSI disk" and has
nothing to do with the fact that I was using a "secure digital" media card.
Any USB disk or flash card is supposed to show up under
/dev/sdsomething and the main trick is figuring out the
something. Which is part of what udev and hal are supposed
to help with.)

Then I discovered
that doing an fdisk -l /dev/hdd gave the right answer (one
partition) for the SD card. And as soon as I did that, the /dev/sdd1
device appeared and I was able to mount it normally.

Apparently, when udev sees the logical units at boot time,
with no cards inserted, it decides that there's a /dev/sdd, but it has
no partitions on it so there's no such device as /dev/sdd1. Since
inserting a card later doesn't generate a hotplug event, udev never
re-evaluates this, unless somehow forced to (apparently running fdisk
forces it, though I'm not sure why). Dave was right: udev/hal are the
culprit here, and the kernel was fine.

A helpful person on #ubuntu pointed me to this
tutorial
on writing rules for udev. It mentions the problem with multi USB
card readers not getting additional events when cards are plugged in,
and suggests modifying the NAME key in the rules (which seem
to be in /etc/udev/rules.d/udev.rules to:

Elsewhere in the document, it suggests getting that SYSFS{product}
string by running a command like udevinfo -a -p /sys/block/sdd

Unfortunately, that seems to be completely ignored. udevinfo told me
the string was "CardReader SD ", but plugging that in to
udev.rules did not create any /dev/usbhd* devices.
It also seemed clear that udev is using BUS="scsi" rather than
BUS="usb" for these devices, based on the device names that are
being created (sd* rather than ub*). But making that change didn't
help.

Eventually I found a combination that worked. Ubuntu's current rules
for usb-storage devices are: