embedded-linuxusb-driveintel-edisonhotswapusb-mass-storage

How do I hot-swap a mass storage LUN backing file in the Linux composite USB gadget?


Cutting to the Chase

Does the Linux composite USB gadget mass storage function support hot swapping of its LUN media backing files? If so, has anyone gotten it to work?

Background

The Linux USB composite gadget includes a Mass Storage function which can support multiple logical units, each of which maps to a drive image file (like FAT or ISO). From what I can tell, the Mass Storage function appears to inherit some or all of it's configuration interface from the previous standalone g_mass_storage gadget

The documentation implies that you can mount a storage image as a mass storage LUN, and then, at a later time, unmount it and remount a new storage image, in a manner similar to how a physical CD/DVD drive would work. It is this functionality that I am trying to access.

What I Have Tried

I am using insmod/modprobe and rmmod to mount and unmount a single LUN mapped to an ISO image. The modprobe parameters are modified version of the stock Edison config, which it uses to expose its "firmware update" drive image.

The USB slave is an Intel Edison board running a slightly modified Yocto build, the host is OS X 10.10.2:

# Step 1: mount an ISO
modprobe g_multi file=/home/root/first_image.iso removable=1 ro=1 stall=0 idVendor=0x8087 idProduct=0x0A9E iProduct=Edison iManufacturer=Intel

# at this point, the ISO appears on the host (I'm testing with OS X)

# Step 2, at some later time
rmmod g_multi

# The storage disappears from the OS X desktop. 
# It does not seem to complain unless you had files open on the media

# Step 3: mount a different ISO
modprobe g_multi file=/home/root/second_image.iso removable=1 ro=1 stall=0 idVendor=0x8087 idProduct=0x0A9E iProduct=Edison iManufacturer=Intel

# The operation appears to work on the device side, 
# but the new media does not appear in OS X.
# You can usually get it to work by unplugging the USB cable,
# which presumably resets the port somehow.

I have tried to find a way to reset the OTG device port under software control. That may be the ultimate solution.

I have not (yet) tried using the configfs interface to build and configure the device. That may also be an option, but I'm still working through the docs on that.

Thanks!


Solution

  • At least on:

    $ uname -r
    4.9.87
    

    I've found this:

    $ find /sys -type f -a -name file
    /sys/devices/soc0/soc/2100000.aips-bus/2184000.usb/ci_hdrc.0/gadget/lun0/file
    /sys/module/g_multi/parameters/file
    

    The prefix will be heavily dependent on your hardware, but the gadget/lun0/file one is writable. You'd then:

    echo "/where/is/your/file" >.../lun0/file
    

    and voila. Of course, you need the removable=1 passed go g_file as the OP implied.

    To "eject" the device, you simply do the following:

    echo >.../lun0/file
    

    This last one may fail if the filesystem is still mounted on the host.