How to force a device to be mounted as Mass Media Storage (MMS) rather than Media Transfer Protocol (MTP)

mountmtp

I use various Sony Walkmans to record a multitude of short audionotes on the go (while running, swimming, or simply walking or taking the bus).

I used to mount each device as a Mass Media Storage (MMS) to /media/$USER/WALKMAN/ under linux, and to move the audionotes (in /media/WALKMAN/Record/Voice) to my hard-drive via a script, which prepares a special order for processing by renaming the folders containing the audionotes.

Since the upgrade to the new linux kernel several months ago, the walkmans are recognized as Media Transfer Protocol (MTP) devices instead of MMS. Not only does this change the mounting point from /media/$USER/WALKMAN/ to something like /run/user/1003/gvfs/mtp:host=%5Busb%3A002%2C007%5D/Storage Media, but scripts (nor shell) can't access this new location: I have been back to moving and renaming the folders of audionotes "by mouse" since then.

Even using known MTP interfaces (e.g. PyMTP in Python, mtpfs) is failing, because the device was already mounted at its insertion. Many other users have complained about MTP for their android device. The move from MMS to MTP is largely justified for Android devices as those are sharing the access to their files with the mounting machine, I don't find it justified for walkman devices. The MMS protocol is simpler and faster in this case (and was the default until the last kernel upgrade).


Notes

  1. If I understand the advantage of mounting the file system of active devices such as cell phones as MTP, I would have assumed that the MMS mode would have been kept for other devices (so I assume that I missed a point?).
  2. I will manage to reprogram my script using the pymtp library: I am asking here in case there is a simpler solution. I would like a simpler solution to exist not only out of laziness, but because it would encourage others to program and personalize their work environment?
  3. Recompiling the kernel could yield a solution link, but I would be surprised if it's the simplest one possible.
  4. Setting up a UDEV rule (with adequate scripts) should have solved the problem according to this and this posts, but it seems that the device is not even mounted when it is recognized as an mtp one (neither gparted nor gnome-disks show it even once visible in the file manager) 🙁
  5. I thought that usbmount would solve my issue, but again I think that the walkman is not detected as a USB key but as an MTP device….
  6. My issue is NOT with the change in the mounting point: I did find the new mounting point in /run/user/1003/gvfs/mtp:host=*/Storage\ Media/. The problem is that a simple cp or mv in a shell from this location to my hard drive does not work: Copying (or moving) the folder or individual files is not supported:

    cp -r /run/user/1003/gvfs/mtp:host=*/Storage\ Media/Record/Voice ~/Unison/Boxes/MyBoxes/AudioNotesToProcess/2014-12-28-09-17
    cp: cannot open ‘/run/user/1003/gvfs/mtp:host=%5Busb%3A002%2C016%5D/Storage Media/Record/Voice/VR0001.WAV’ for reading: Operation not supported
    cp: cannot open ‘/run/user/1003/gvfs/mtp:host=%5Busb%3A002%2C016%5D/Storage Media/Record/Voice/VR0002.WAV’ for reading: Operation not supported
    

    `

  7. The output of dmesg after inserting the device is:

    [  217.097691] usb 2-1: new high-speed USB device number 6 using xhci_hcd
    [  217.114176] usb 2-1: New USB device found, idVendor=054c, idProduct=059a
    [  217.114186] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=8
    [  217.114192] usb 2-1: Product: WALKMAN
    [  217.114197] usb 2-1: Manufacturer: SONY
    [  217.114201] usb 2-1: SerialNumber: 0E4A0C57283357
    [  217.134426] usb-storage 2-1:1.0: USB Mass Storage device detected
    [  217.134471] scsi4 : usb-storage 2-1:1.0
    [  217.134551] usbcore: registered new interface driver usb-storage
    
  8. The output of "mount" does not change between before and after mounting the device. It is as follows:

    mount
    /dev/sda7 on / type ext4 (rw,errors=remount-ro)
    proc on /proc type proc (rw,noexec,nosuid,nodev)
    sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
    none on /sys/fs/cgroup type tmpfs (rw)
    none on /sys/fs/fuse/connections type fusectl (rw)
    none on /sys/kernel/debug type debugfs (rw)
    none on /sys/kernel/security type securityfs (rw)
    udev on /dev type devtmpfs (rw,mode=0755)
    devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
    tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
    none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
    none on /run/shm type tmpfs (rw,nosuid,nodev)
    none on /run/user type tmpfs (rw,noexec,nosuid,nodev,size=104857600,mode=0755)
    none on /sys/fs/pstore type pstore (rw)
    binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev)
    systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd)
    gvfsd-fuse on /run/user/1003/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,user=jbarbay)
    

Best Answer

Haven't found a way to make the changes permanent yet, but at least there's a way to manually change drivers:

For example with my sony walkman:

  • Plug it in and find out its vendor and product id with lsusb:

    # lsusb 
    Bus 001 Device 003: ID 0402:7675 ALi Corp. 
    Bus 001 Device 025: ID 054c:04be Sony Corp. 
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    ...
    

    -> so in this case: 054c 04be.

  • Switch it to usb_storage with:

    # mtp_switch 054c 04be
    

It should get mounted automatically (on ubuntu at least)


mtp_switch script:

#!/bin/bash

usage()
{
    echo "Usage: mtp_switch vendor_id product_id"
    echo "  switch usb device driver from mtp to usb storage."
    exit 1
}

[ $# = "2" ] || usage

vendor="$1"
product="$2"

die()
{
    echo "$@"
    exit 1
}

find_bus_id()
{
    cd /sys/bus/usb/devices/
    for f in *:* ; do
    if grep -qi "^usb:v${vendor}p${product}" "$f/modalias" 2>/dev/null; then
        echo $f
        return
    fi
    done
}

driver()
{
    readlink "/sys/bus/usb/devices/$bus_id/driver"
}

bus_id=`find_bus_id`
[ -n "$bus_id" ]         || die "couldn't find device"
driver | grep -q 'usbfs' || die "device's driver is not mtp"

cd "/sys/bus/usb/drivers"
echo -n "Unbinding mtp driver ..."
while driver | grep -q usbfs; do
    echo -n "$bus_id" > usbfs/unbind
    sleep 0.5
done
echo ""

echo -n "$bus_id" > usb-storage/bind
echo "Done."