Using a USB Card Reader in Linux

I recently got a Compact Flash card reader and set about getting it to work under Linux (x86). I didn't find any instructions that were as straightforward as they should be, so...

First things first... here are some resources:

You should be able to follow the same procedure for other USB storage devices (portable hard drives, other media cards, etc.). With minimal modifications, the setup is the same for USB CD-ROM drives, floppies, etc.

If you have any particular successes or failures using these instructions, let me know. I originally did this on Debian sarge with Linux kernel 2.4.19. It should work with any 2.4.x series kernel. I have also done this with 2.6.x kernels and it all works.

Installing the Drivers

The USB driver serves up your reader as a SCSI device, so you also need to install the SCSI drivers. In the “SCSI Support” section, enable these. The configuration name and the module name are listed:

You need to use the USB mass storage driver to access your reader. In the “USB Support” section of the kernel configuration, enable the following:

Make sure you do not select the “Low Performance USB Block Driver” (BLK_DEV_UB). It will prevent the whole thing from working correctly.

Compile your kernel with these options and reboot (or just load the relevant modules if you've got them). And, plug the thing in, if you haven't already.

Checking it out

If you have a look through the file /proc/bus/usb/devices, you should see a section with an S: line and the name of your reader and an I: line with Driver=usb-storage. If you see that, the kernel is recognizing the USB device.

Install the sg3-utils package if you haven't already (on Debian, apt-get install sg3-utils). To check your SCSI devices, run the command sg_scan -i . You should see something like this:

/dev/sg0: scsi0 channel=0 id=0 lun=0 [em]  type=0
    eUSB      Compact Flash     5.09 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0]

This indicates that the “raw” SCSI device associated with your reader is /dev/sg0. You can also confirm that the driver is working by looking at the file /proc/scsi/scsi .

Now, run the command sg_map to determine the real SCSI device associated with your reader. You'll see output like this:

/dev/sg0  /dev/sda

That's it. Your card reader is /dev/sda. The first (and almost certainly only) partition is /dev/sda1.

Multi Card Readers

If you have an n-in-1 card reader that can deal with multiple cards, the process isn't much different. Make sure that “Probe all LUNs on each SCSI device” (CONFIG_SCSI_MULTI_LUN) is enabled in your kernel. If this isn't compiled in, you can add this line to your /etc/modules.conf:

options scsi_mod max_scsi_luns=8

Or, for a more temporary solution, run this command:

echo 8 > /sys/module/scsi_mod/parameters/max_luns

The device should still appear in your /proc/bus/usb/devices as described above. When you do the sg_scan -i, you should see several devices, like this:

/dev/sg2: scsi2 channel=0 id=0 lun=0 [em]  type=0
    Generic   STORAGE DEVICE    0128 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0]
/dev/sg3: scsi2 channel=0 id=0 lun=1 [em]  type=0
    Generic   STORAGE DEVICE    0128 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0]
/dev/sg4: scsi2 channel=0 id=0 lun=2 [em]  type=0
    Generic   STORAGE DEVICE    0128 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0]
/dev/sg5: scsi2 channel=0 id=0 lun=3 [em]  type=0
    Generic   STORAGE DEVICE    0128 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0]

Notice that the four generics are part of the same physical device, but have different LUNs. The “Probe all LUNs on each SCSI device” option in the kernel must be enabled so it will find these.

If so, then sg_map can do its thing:

/dev/sg2  /dev/sda
/dev/sg3  /dev/sdb
/dev/sg4  /dev/sdc
/dev/sg5  /dev/sdd

On this system, the four slots on the card reader are mapped to SCSI devices /dev/sd[a-d].

If you don't have “Probe all LUNs on each SCSI device” set (as in Knoppix, Libranet, and some other default installs), you're not out of luck. You just have to manually enable the probing. You can either modify /etc/modules.conf, or run the above command on startup.

Now, the question of which slot on the reader corresponds to which device file. I have no real advice here. Some readers give a useful description in sg_scan. If not, put a card in and try to mount it on each one. You will get a “mount: No medium found” for absent cards. When you find the right one, add it to your /etc/fstab as described below and forget about it. Repeat for each kind of card you actually have.

One more note: don't cheap-out on your card reader. The first multi-card reader I bought was a off-brand and would spontaneously disconnent itself after being mounted for a minute or two. I replaced it with a SanDisk 8-in-1 and everything worked beautifully.

Thanks to Susan Macchia for her notes on getting n-in-1 card readers working that got me started with mine. Thanks also to the mailing list posted that I've long since lost that pointed out the “Probe all LUNs” thing. Thanks to Chris Bryant for the info on how to work around when “Probe all LUNs” isn't available, and Neil Gunton and Dale Thacher for even more.

Final Setup

You'll want to add a line to your /etc/fstab so you can easily mount a card. I mount my card at /mnt/flash; you can mount it anywhere you want, just create the mount point first. Add this line to /etc/fstab:

/dev/sda1 /mnt/flash vfat noauto,user 0 0

The user option lets any user mount the card. If you don't want that, remove it.

Now, you should be able to insert a card and mount it with the command mount /mnt/flash . Before you remove the card, unmount it with the command umount /mnt/flash .

Formatting a Card

Since cards are generally formatted as DOS ”disks”, they are formatted just like any other DOS disk. The Unix command mkfs -t vfat /dev/sda1 or mkfs -t msdos /dev/sda1 should do it.


Copyright © , last modified 2010-07-14.