Hello community,

here is the log from the commit of package go-go-mtpfs for openSUSE:Factory 
checked in at 2014-09-23 10:42:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/go-go-mtpfs (Old)
 and      /work/SRC/openSUSE:Factory/.go-go-mtpfs.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "go-go-mtpfs"

Changes:
--------
--- /work/SRC/openSUSE:Factory/go-go-mtpfs/go-go-mtpfs.changes  2013-11-13 
10:03:06.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.go-go-mtpfs.new/go-go-mtpfs.changes     
2014-09-23 10:42:49.000000000 +0200
@@ -1,0 +2,5 @@
+Fri Sep 19 17:35:48 UTC 2014 - i...@marguerite.su
+
+- update version 0.0.0+git20140903.689b5b4
+
+-------------------------------------------------------------------

Old:
----
  go-mtpfs-0.0.0+git20131015.bb3f0c2.tar.bz2

New:
----
  go-mtpfs-0.0.0+git20140903.689b5b4.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ go-go-mtpfs.spec ++++++
--- /var/tmp/diff_new_pack.dBXNbb/_old  2014-09-23 10:42:51.000000000 +0200
+++ /var/tmp/diff_new_pack.dBXNbb/_new  2014-09-23 10:42:51.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package go-go-mtpfs
 #
-# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,26 +17,28 @@
 
 
 Name:           go-go-mtpfs
-Version:        0.0.0+git20131015.bb3f0c2
+Version:        0.0.0+git20140903.689b5b4
 Release:        0
 Summary:        Mount MTP devices over FUSE
-Group:          Productivity/Multimedia/Sound/Players
 License:        BSD-3-Clause
+Group:          Productivity/Multimedia/Sound/Players
 Url:            https://github.com/hanwen/go-mtpfs
 Source:         go-mtpfs-%{version}.tar.bz2
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  go-devel
 BuildRequires:  go-go-fuse
-BuildRequires:  pkgconfig
+BuildRequires:  go-hanwen-usb
+BuildRequires:  pkg-config
 BuildRequires:  pkgconfig(libmtp)
-BuildRequires:  pkgconfig(libusb-1.0)
-%if 0%{?suse_version} >= 1100
-Recommends:     %{name}-doc
-%endif
+Requires:       go-go-fuse
+Requires:       go-hanwen-usb
+Requires:       pkg-config
+Requires:       pkgconfig(libmtp)
 Provides:       go-mtpfs = 0.0+git6b55d1f9
 Obsoletes:      go-mtpfs < 0.0+git6b55d1f9
 %{go_requires}
 %{go_provides}
+%{go_recommends}
 
 %description
 Go-mtpfs is a simple FUSE filesystem for mounting Android devices as a
@@ -51,13 +53,7 @@
 Nexus 7).  As of Jan. 2013, it uses a pure Go implementation of MTP,
 which is based on libusb.
 
-%package doc
-Summary:        API documenation
-Group:          Documentation/Other
-Requires:       %{name} = %{version}
-
-%description doc
-API, examples and documentation.
+%godoc_package
 
 %prep
 %setup -q -n go-mtpfs-%{version}

++++++ go-mtpfs-0.0.0+git20131015.bb3f0c2.tar.bz2 -> 
go-mtpfs-0.0.0+git20140903.689b5b4.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/all.bash 
new/go-mtpfs-0.0.0+git20140903.689b5b4/all.bash
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/all.bash     2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/all.bash     2014-09-19 
19:29:28.000000000 +0200
@@ -3,8 +3,6 @@
 # Script to exercise everything.
 set -eux
 
-# mtp-detect still does a better job at resetting device to a sane state.
-mtp-detect
 for x in fs mtp
 do
     go build github.com/hanwen/go-mtpfs/$x
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/fs/android.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/fs/android.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/fs/android.go        2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/fs/android.go        2014-09-19 
19:29:28.000000000 +0200
@@ -93,7 +93,7 @@
 }
 
 func (f *androidFile) Read(dest []byte, off int64) (fuse.ReadResult, 
fuse.Status) {
-       if off >= f.node.Size {
+       if off > f.node.Size {
                // ENXIO = no such address.
                return nil, fuse.Status(int(syscall.ENXIO))
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/fs/classic.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/fs/classic.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/fs/classic.go        2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/fs/classic.go        2014-09-19 
19:29:28.000000000 +0200
@@ -281,7 +281,7 @@
 
 ////////////////////////////////////////////////////////////////
 
-func (fs *DeviceFs) trimUnused(todo int64, node *nodefs.Inode) (done int64) {
+func (fs *deviceFS) trimUnused(todo int64, node *nodefs.Inode) (done int64) {
        for _, ch := range node.Children() {
                if done > todo {
                        break
@@ -296,7 +296,7 @@
        return
 }
 
-func (fs *DeviceFs) freeBacking() (int64, error) {
+func (fs *deviceFS) freeBacking() (int64, error) {
        t := syscall.Statfs_t{}
        err := syscall.Statfs(fs.options.Dir, &t)
        if err != nil {
@@ -306,7 +306,7 @@
        return int64(t.Bfree * uint64(t.Bsize)), nil
 }
 
-func (fs *DeviceFs) ensureFreeSpace(want int64) error {
+func (fs *deviceFS) ensureFreeSpace(want int64) error {
        free, err := fs.freeBacking()
        if err != nil {
                return err
@@ -329,7 +329,7 @@
        return fmt.Errorf("not enough space in %s. Have %d, want %d", 
fs.options.Dir, free, want)
 }
 
-func (fs *DeviceFs) setupClassic() error {
+func (fs *deviceFS) setupClassic() error {
        if fs.options.Dir == "" {
                var err error
                fs.options.Dir, err = ioutil.TempDir(os.TempDir(), "go-mtpfs")
@@ -344,19 +344,13 @@
        return nil
 }
 
-func (fs *DeviceFs) OnUnmount() {
-       if fs.delBackingDir {
-               os.RemoveAll(fs.options.Dir)
-       }
-}
-
-func (fs *DeviceFs) createClassicFile(obj mtp.ObjectInfo) (file nodefs.File, 
node nodefs.Node, err error) {
+func (fs *deviceFS) createClassicFile(obj mtp.ObjectInfo) (file nodefs.File, 
node nodefs.Node, err error) {
        backingFile, err := ioutil.TempFile(fs.options.Dir, "")
        cl := &classicNode{
                mtpNodeImpl: mtpNodeImpl{
-                       Node:   nodefs.NewDefaultNode(),
-                       obj: &obj,
-                       fs:  fs,
+                       Node: nodefs.NewDefaultNode(),
+                       obj:  &obj,
+                       fs:   fs,
                },
                dirty:   true,
                backing: backingFile.Name(),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/fs/device_test.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/fs/device_test.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/fs/device_test.go    2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/fs/device_test.go    2014-09-19 
19:29:28.000000000 +0200
@@ -3,7 +3,10 @@
 // This test requires an unlocked android MTP device plugged in.
 
 import (
+       "bytes"
+       "flag"
        "fmt"
+       "io"
        "io/ioutil"
        "math/rand"
        "os"
@@ -16,11 +19,17 @@
        "github.com/hanwen/go-mtpfs/mtp"
 )
 
+// VerboseTest returns true if the testing framework is run with -v.
+func VerboseTest() bool {
+       flag := flag.Lookup("test.v")
+       return flag != nil && flag.Value.String() == "true"
+}
+
 func init() {
        rand.Seed(time.Now().UnixNano())
 }
 
-func startFs(t *testing.T, useAndroid bool) (root string, cleanup func()) {
+func startFs(t *testing.T, useAndroid bool) (storageRoot string, cleanup 
func()) {
        dev, err := mtp.SelectDevice("")
        if err != nil {
                t.Fatalf("SelectDevice failed: %v", err)
@@ -49,40 +58,40 @@
        opts := DeviceFsOptions{
                Android: useAndroid,
        }
-       fs, err := NewDeviceFs(dev, sids, opts)
+       root, err := NewDeviceFSRoot(dev, sids, opts)
        if err != nil {
                t.Fatal("NewDeviceFs failed:", err)
        }
-       conn := nodefs.NewFileSystemConnector(fs, nodefs.NewOptions())
+       conn := nodefs.NewFileSystemConnector(root, nodefs.NewOptions())
        rawFs := fuse.NewLockingRawFileSystem(conn.RawFS())
        mount, err := fuse.NewServer(rawFs, tempdir, nil)
        if err != nil {
                t.Fatalf("mount failed: %v", err)
        }
 
-       mount.SetDebug(fuse.VerboseTest())
-       dev.MTPDebug = fuse.VerboseTest()
-       dev.USBDebug = fuse.VerboseTest()
-       dev.DataDebug = fuse.VerboseTest()
+       mount.SetDebug(VerboseTest())
+       dev.MTPDebug = VerboseTest()
+       dev.USBDebug = VerboseTest()
+       dev.DataDebug = VerboseTest()
        go mount.Serve()
 
        for i := 0; i < 10; i++ {
                fis, err := ioutil.ReadDir(tempdir)
                if err == nil && len(fis) > 0 {
-                       root = filepath.Join(tempdir, fis[0].Name())
+                       storageRoot = filepath.Join(tempdir, fis[0].Name())
                        break
                }
                time.Sleep(1)
        }
 
-       if root == "" {
+       if storageRoot == "" {
                mount.Unmount()
                t.Fatal("could not find entries in mount point.")
        }
 
        d := dev
        dev = nil
-       return root, func() {
+       return storageRoot, func() {
                mount.Unmount()
                d.Close()
        }
@@ -173,6 +182,46 @@
        }
 }
 
+func testReadBlockBoundary(t *testing.T, android bool) {
+       root, cleanup := startFs(t, android)
+       defer cleanup()
+
+       name := filepath.Join(root, fmt.Sprintf("mtpfs-test-%x", rand.Int31()))
+
+       page := 4096
+       buf := bytes.Repeat([]byte("a"), 32*page)
+       if err := ioutil.WriteFile(name, buf, 0644); err != nil {
+               t.Fatalf("WriteFile: %v", err)
+       }
+
+       f, err := os.Open(name)
+       if err != nil {
+               t.Fatalf("Open: %v", name)
+       }
+
+       total := 0
+       for {
+               b := make([]byte, page)
+               n, err := f.Read(b)
+               total += n
+               if n == 0 && err == io.EOF {
+                       break
+               }
+               if n != 4096 || err != nil {
+                       t.Fatalf("Read: %v (%d bytes)", err, n)
+               }
+       }
+       f.Close()
+}
+
+func TestReadBlockBoundaryAndroid(t *testing.T) {
+       testReadBlockBoundary(t, true)
+}
+
+func TestReadBlockBoundaryNormal(t *testing.T) {
+       testReadBlockBoundary(t, false)
+}
+
 func TestAndroid(t *testing.T) {
        testDevice(t, true)
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/fs/fs.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/fs/fs.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/fs/fs.go     2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/fs/fs.go     2014-09-19 
19:29:28.000000000 +0200
@@ -8,6 +8,7 @@
        "bytes"
        "fmt"
        "log"
+       "os"
        "strings"
        "time"
 
@@ -30,9 +31,7 @@
 
 // DeviceFS implements a fuse.NodeFileSystem that mounts multiple
 // storages.
-type DeviceFs struct {
-       nodefs.FileSystem
-
+type deviceFS struct {
        backingDir    string
        delBackingDir bool
        root          *rootNode
@@ -49,19 +48,18 @@
 // threadsafe.  The file system assumes the device does not touch the
 // storage.  Arguments are the opened mtp device and a directory for the
 // backing store.
-func NewDeviceFs(d *mtp.Device, storages []uint32, options DeviceFsOptions) 
(*DeviceFs, error) {
+func NewDeviceFSRoot(d *mtp.Device, storages []uint32, options 
DeviceFsOptions) (nodefs.Node, error) {
        root := rootNode{Node: nodefs.NewDefaultNode()}
-       fs := &DeviceFs{
-               FileSystem: nodefs.NewDefaultFileSystem(),
-               root:       &root,
-               dev:        d,
-               options:    &options,
+       fs := &deviceFS{
+               root:    &root,
+               dev:     d,
+               options: &options,
        }
        root.fs = fs
        fs.storages = storages
        err := d.GetDeviceInfo(&fs.devInfo)
        if err != nil {
-               return fs, nil
+               return nil, err
        }
 
        if !strings.Contains(fs.devInfo.MTPExtension, "android.com") {
@@ -85,21 +83,39 @@
                fs.mungeVfat[sid] = info.IsRemovable() && 
fs.options.RemovableVFat
        }
 
-       return fs, nil
+       return fs.Root(), nil
 }
 
-func (fs *DeviceFs) Root() nodefs.Node {
+func (fs *deviceFS) Root() nodefs.Node {
        return fs.root
 }
 
-func (fs *DeviceFs) String() string {
-       return fmt.Sprintf("DeviceFs(%s)", fs.devInfo.Model)
+func (fs *deviceFS) String() string {
+       return fmt.Sprintf("deviceFS(%s)", fs.devInfo.Model)
+}
+
+func (fs *deviceFS) onMount() {
+       for _, sid := range fs.storages {
+               var info mtp.StorageInfo
+               if err := fs.dev.GetStorageInfo(sid, &info); err != nil {
+                       log.Printf("GetStorageInfo %x: %v", sid, err)
+                       continue
+               }
+
+               obj := mtp.ObjectInfo{
+                       ParentObject: NOPARENT_ID,
+                       StorageID:    sid,
+                       Filename:     info.StorageDescription,
+               }
+               folder := fs.newFolder(obj, NOPARENT_ID)
+               fs.root.Inode().NewChild(info.StorageDescription, true, folder)
+       }
 }
 
 // TODO - this should be per storage and return just the free space in
 // the storage.
 
-func (fs *DeviceFs) newFile(obj mtp.ObjectInfo, size int64, id uint32) (node 
nodefs.Node) {
+func (fs *deviceFS) newFile(obj mtp.ObjectInfo, size int64, id uint32) (node 
nodefs.Node) {
        if obj.CompressedSize != 0xFFFFFFFF {
                size = int64(obj.CompressedSize)
        }
@@ -125,27 +141,19 @@
 
 type rootNode struct {
        nodefs.Node
-       fs *DeviceFs
+       fs *deviceFS
 }
 
 const NOPARENT_ID = 0xFFFFFFFF
 
-func (fs *DeviceFs) OnMount(conn *nodefs.FileSystemConnector) {
-       for _, sid := range fs.storages {
-               var info mtp.StorageInfo
-               if err := fs.dev.GetStorageInfo(sid, &info); err != nil {
-                       log.Printf("GetStorageInfo %x: %v", sid, err)
-                       continue
-               }
+func (n *rootNode) OnMount(conn *nodefs.FileSystemConnector) {
+       n.fs.onMount()
+}
 
-               obj := mtp.ObjectInfo{
-                       ParentObject: NOPARENT_ID,
-                       StorageID:    sid,
-                       Filename:     info.StorageDescription,
-               }
-               folder := fs.newFolder(obj, NOPARENT_ID)
-               inode := fs.root.Inode().New(true, folder)
-               fs.root.Inode().AddChild(info.StorageDescription, inode)
+func (n *rootNode) OnUnmount() {
+       if n.fs.delBackingDir {
+               os.RemoveAll(n.fs.options.Dir)
+               n.fs.delBackingDir = false
        }
 }
 
@@ -202,7 +210,7 @@
 
        obj *mtp.ObjectInfo
 
-       fs *DeviceFs
+       fs *deviceFS
 
        // This is needed because obj.CompressedSize only goes to
        // 0xFFFFFFFF
@@ -288,7 +296,7 @@
        fetched bool
 }
 
-func (fs *DeviceFs) newFolder(obj mtp.ObjectInfo, h uint32) *folderNode {
+func (fs *deviceFS) newFolder(obj mtp.ObjectInfo, h uint32) *folderNode {
        obj.AssociationType = mtp.OFC_Association
        return &folderNode{
                mtpNodeImpl: mtpNodeImpl{
@@ -359,7 +367,7 @@
                        node = n.fs.newFile(*info, sz, handle)
                }
 
-               n.Inode().AddChild(info.Filename, n.Inode().New(isdir, node))
+               n.Inode().NewChild(info.Filename, isdir, node)
        }
        n.fetched = true
        return true
@@ -428,7 +436,7 @@
        return fuse.OK
 }
 
-func (n *folderNode) Lookup(out *fuse.Attr, name string, context 
*fuse.Context) (node nodefs.Node, code fuse.Status) {
+func (n *folderNode) Lookup(out *fuse.Attr, name string, context 
*fuse.Context) (node *nodefs.Inode, code fuse.Status) {
        if !n.fetch() {
                return nil, fuse.EIO
        }
@@ -437,11 +445,10 @@
                return nil, fuse.ENOENT
        }
 
-       s := ch.Node().GetAttr(out, nil, context)
-       return ch.Node(), s
+       return ch, ch.Node().GetAttr(out, nil, context)
 }
 
-func (n *folderNode) Mkdir(name string, mode uint32, context *fuse.Context) 
(nodefs.Node, fuse.Status) {
+func (n *folderNode) Mkdir(name string, mode uint32, context *fuse.Context) 
(*nodefs.Inode, fuse.Status) {
        if !n.fetch() {
                return nil, fuse.EIO
        }
@@ -460,8 +467,7 @@
        }
 
        f := n.fs.newFolder(obj, newId)
-       n.Inode().AddChild(name, n.Inode().New(true, f))
-       return f, fuse.OK
+       return n.Inode().NewChild(name, true, f), fuse.OK
 }
 
 func (n *folderNode) Unlink(name string, c *fuse.Context) fuse.Status {
@@ -492,7 +498,7 @@
        return n.Unlink(name, c)
 }
 
-func (n *folderNode) Create(name string, flags uint32, mode uint32, context 
*fuse.Context) (file nodefs.File, node nodefs.Node, code fuse.Status) {
+func (n *folderNode) Create(name string, flags uint32, mode uint32, context 
*fuse.Context) (nodefs.File, *nodefs.Inode, fuse.Status) {
        if !n.fetch() {
                return nil, nil, fuse.EIO
        }
@@ -506,6 +512,8 @@
                CompressedSize:   0,
        }
 
+       var file nodefs.File
+       var fsNode nodefs.Node
        if n.fs.options.Android {
                _, _, handle, err := n.fs.dev.SendObjectInfo(n.StorageID(), 
n.Handle(), &obj)
                if err != nil {
@@ -535,14 +543,13 @@
                        File: nodefs.NewDefaultFile(),
                        node: aNode,
                }
-               node = aNode
+               fsNode = aNode
        } else {
                var err error
-               file, node, err = n.fs.createClassicFile(obj)
+               file, fsNode, err = n.fs.createClassicFile(obj)
                if err != nil {
                        return nil, nil, fuse.ToStatus(err)
                }
        }
-       n.Inode().AddChild(name, n.Inode().New(false, node))
-       return file, node, fuse.OK
+       return file, n.Inode().NewChild(name, false, fsNode), fuse.OK
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/main.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/main.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/main.go      2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/main.go      2014-09-19 
19:29:28.000000000 +0200
@@ -9,6 +9,7 @@
        "log"
        "os"
        "strings"
+       "sync"
 
        "github.com/hanwen/go-fuse/fuse"
        "github.com/hanwen/go-fuse/fuse/nodefs"
@@ -22,8 +23,8 @@
        vfat := flag.Bool("vfat", true, "assume removable RAM media uses VFAT, 
and rewrite names.")
        other := flag.Bool("allow-other", false, "allow other users to access 
mounted fuse. Default: false.")
        deviceFilter := flag.String("dev", "",
-               "regular expression to filter device IDs, " +
-               "which are composed of manufacturer/product/serial.")
+               "regular expression to filter device IDs, "+
+                       "which are composed of manufacturer/product/serial.")
        storageFilter := flag.String("storage", "", "regular expression to 
filter storage areas.")
        android := flag.Bool("android", true, "use android extensions if 
available")
        flag.Parse()
@@ -59,11 +60,11 @@
                RemovableVFat: *vfat,
                Android:       *android,
        }
-       fs, err := fs.NewDeviceFs(dev, sids, opts)
+       root, err := fs.NewDeviceFSRoot(dev, sids, opts)
        if err != nil {
                log.Fatalf("NewDeviceFs failed: %v", err)
        }
-       conn := nodefs.NewFileSystemConnector(fs, nodefs.NewOptions())
+       conn := nodefs.NewFileSystemConnector(root, nodefs.NewOptions())
        rawFs := fuse.NewLockingRawFileSystem(conn.RawFS())
 
        mOpts := &fuse.MountOptions{
@@ -76,7 +77,14 @@
 
        conn.SetDebug(debugs["fuse"] || debugs["fs"])
        mount.SetDebug(debugs["fuse"] || debugs["fs"])
-       log.Printf("starting FUSE.")
-       mount.Serve()
-       fs.OnUnmount()
+       var wg sync.WaitGroup
+       wg.Add(1)
+       go func() {
+               mount.Serve()
+               wg.Done()
+       }()
+       mount.WaitMount()
+       log.Printf("FUSE mounted")
+       wg.Wait()
+       root.OnUnmount()
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/mtp/encoding.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/mtp/encoding.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/mtp/encoding.go      2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/mtp/encoding.go      2014-09-19 
19:29:28.000000000 +0200
@@ -45,27 +45,28 @@
 }
 
 func encodeStr(buf []byte, s string) ([]byte, error) {
-       if len(s) > 254 {
-               return nil, fmt.Errorf("range")
-       }
-
        if s == "" {
                buf[0] = 0
                return buf[:1], nil
        }
 
-       i := 0
-       buf[i] = byte(len(s) + 1)
-       i++
+       codepoints := 0
+       buf = append(buf[:0], 0)
+
+       var rune [2]byte
        for _, r := range s {
-               byteOrder.PutUint16(buf[i:], uint16(r))
-               i += 2
+               byteOrder.PutUint16(rune[:], uint16(r))
+               buf = append(buf, rune[0], rune[1])
+               codepoints++
        }
-       buf[i] = 0
-       i++
-       buf[i] = 0
-       i++
-       return buf[:i], nil
+       buf = append(buf, 0, 0)
+       codepoints++
+       if codepoints > 254 {
+               return nil, fmt.Errorf("string too long")
+       }
+
+       buf[0] = byte(codepoints)
+       return buf, nil
 }
 
 func encodeStrField(w io.Writer, f reflect.Value) error {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/go-mtpfs-0.0.0+git20131015.bb3f0c2/mtp/encoding_test.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/mtp/encoding_test.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/mtp/encoding_test.go 2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/mtp/encoding_test.go 2014-09-19 
19:29:28.000000000 +0200
@@ -240,3 +240,31 @@
                        dp, back)
        }
 }
+
+func TestDecodeStr(t *testing.T) {
+       enc := make([]byte, 100)
+       test := "ö"
+       out, err := encodeStr(enc, test)
+       if err != nil {
+               t.Fatalf("encodeStr: %v", err)
+       }
+       buf := bytes.NewBuffer(out)
+       roundtrip, err := decodeStr(buf)
+       if err != nil {
+               t.Fatalf("encodeStr: %v", err)
+       }
+       if roundtrip != test {
+               t.Fatalf("got %q, want %q", roundtrip, test)
+       }
+}
+
+func TestEncodeStr(t *testing.T) {
+       mtpStr := []byte("\x02\xe4\x00\x00\x00")
+       str := "ä"
+
+       if out, err := encodeStr(nil, str); err != nil {
+               t.Fatalf("encodeStr: %v", err)
+       } else if bytes.Compare(out, mtpStr) != 0 {
+               t.Fatalf("got %q, want %q", out, mtpStr)
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/mtp/mtp.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/mtp/mtp.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/mtp/mtp.go   2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/mtp/mtp.go   2014-09-19 
19:29:28.000000000 +0200
@@ -10,7 +10,7 @@
        "strings"
        "time"
 
-       "github.com/hanwen/go-mtpfs/usb"
+       "github.com/hanwen/usb"
 )
 
 // An MTP device.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/mtp/select.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/mtp/select.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/mtp/select.go        2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/mtp/select.go        2014-09-19 
19:29:28.000000000 +0200
@@ -5,7 +5,7 @@
        "regexp"
        "strings"
 
-       "github.com/hanwen/go-mtpfs/usb"
+       "github.com/hanwen/usb"
 )
 
 func candidateFromDeviceDescriptor(d *usb.Device) *Device {
@@ -107,15 +107,15 @@
                }
        }
 
-       if len(cands) == 0 {
+       if len(found) == 0 {
                return nil, fmt.Errorf("no device matched")
        }
-       
-       if len(cands) > 1 {
+
+       if len(found) > 1 {
                return nil, fmt.Errorf("mtp: more than 1 device: %s", 
strings.Join(ids, ","))
        }
-       
-       cand := cands[0]
+
+       cand := found[0]
        config, err := cand.h.GetConfiguration()
        if err != nil {
                return nil, fmt.Errorf("could not get configuration of %v: %v",
@@ -128,7 +128,7 @@
                                ids[0], err)
                }
        }
-       return cands[0], nil
+       return found[0], nil
 }
 
 // Return opened MTP device that matches given pattern.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/usb/print.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/usb/print.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/usb/print.go 2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/usb/print.go 1970-01-01 
01:00:00.000000000 +0100
@@ -1,118 +0,0 @@
-package usb
-
-func ClassToStr(c byte) string {
-       switch c {
-       case CLASS_PER_INTERFACE:
-               return "PER_INTERFACE"
-       case CLASS_AUDIO:
-               return "AUDIO"
-       case CLASS_COMM:
-               return "COMM"
-       case CLASS_HID:
-               return "HID"
-       case CLASS_PHYSICAL:
-               return "PHYSICAL"
-       case CLASS_PRINTER:
-               return "PRINTER"
-       case CLASS_IMAGE:
-               return "IMAGE"
-       case CLASS_MASS_STORAGE:
-               return "MASS_STORAGE"
-       case CLASS_HUB:
-               return "HUB"
-       case CLASS_DATA:
-               return "DATA"
-       case CLASS_SMART_CARD:
-               return "SMART_CARD"
-       case CLASS_CONTENT_SECURITY:
-               return "CONTENT_SECURITY"
-       case CLASS_VIDEO:
-               return "VIDEO"
-       case CLASS_PERSONAL_HEALTHCARE:
-               return "PERSONAL_HEALTHCARE"
-       case CLASS_DIAGNOSTIC_DEVICE:
-               return "DIAGNOSTIC_DEVICE"
-       case CLASS_WIRELESS:
-               return "WIRELESS"
-       case CLASS_APPLICATION:
-               return "APPLICATION"
-       case CLASS_VENDOR_SPEC:
-               return "VENDOR_SPEC"
-       }
-       return "other"
-}
-
-func dtToStr(c int) string {
-       switch c {
-       case DT_DEVICE:
-               return "DEVICE"
-       case DT_CONFIG:
-               return "CONFIG"
-       case DT_STRING:
-               return "STRING"
-       case DT_INTERFACE:
-               return "INTERFACE"
-       case DT_ENDPOINT:
-               return "ENDPOINT"
-       case DT_HID:
-               return "HID"
-       case DT_REPORT:
-               return "REPORT"
-       case DT_PHYSICAL:
-               return "PHYSICAL"
-       case DT_HUB:
-               return "HUB"
-       }
-       return "other"
-}
-
-func requestToStr(c int) string {
-       switch c {
-       case REQUEST_GET_STATUS:
-               return "GET_STATUS"
-       case REQUEST_CLEAR_FEATURE:
-               return "CLEAR_FEATURE"
-               /** Set or enable a specific feature */
-       case REQUEST_SET_FEATURE:
-               return "SET_FEATURE"
-               /** Set device address for all future accesses */
-       case REQUEST_SET_ADDRESS:
-               return "SET_ADDRESS"
-               /** Get the specified descriptor */
-       case REQUEST_GET_DESCRIPTOR:
-               return "GET_DESCRIPTOR"
-               /** Used to update existing descriptors or add new descriptors 
*/
-       case REQUEST_SET_DESCRIPTOR:
-               return "SET_DESCRIPTOR"
-               /** Get the current device configuration value */
-       case REQUEST_GET_CONFIGURATION:
-               return "GET_CONFIGURATION"
-               /** Set device configuration */
-       case REQUEST_SET_CONFIGURATION:
-               return "SET_CONFIGURATION"
-               /** Return the selected alternate setting for the specified 
interface */
-       case REQUEST_GET_INTERFACE:
-               return "GET_INTERFACE"
-               /** Select an alternate interface for the specified interface */
-       case REQUEST_SET_INTERFACE:
-               return "SET_INTERFACE"
-               /** Set then report an endpoint's synchronization frame */
-       case REQUEST_SYNCH_FRAME:
-               return "SYNCH_FRAME"
-       }
-       return "other"
-}
-
-func transferTypeString(t byte) string {
-       switch t {
-       case TRANSFER_TYPE_CONTROL:
-               return "control"
-       case TRANSFER_TYPE_ISOCHRONOUS:
-               return "iso"
-       case TRANSFER_TYPE_BULK:
-               return "bulk"
-       case TRANSFER_TYPE_INTERRUPT:
-               return "int"
-       }
-       panic("unknown")
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/usb/usb.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/usb/usb.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/usb/usb.go   2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/usb/usb.go   1970-01-01 
01:00:00.000000000 +0100
@@ -1,720 +0,0 @@
-// The usb package is a straighforward cgo wrapping of the libusb 1.0
-// API. It only supports the synchronous API, since Goroutines can be
-// used for asynchronous use-cases.
-
-package usb
-
-// #cgo pkg-config: libusb-1.0
-// #include <libusb.h>
-import "C"
-import (
-       "fmt"
-       "reflect"
-       "unsafe"
-)
-
-const SPEED_UNKNOWN = C.LIBUSB_SPEED_UNKNOWN
-const SPEED_LOW = C.LIBUSB_SPEED_LOW
-const SPEED_FULL = C.LIBUSB_SPEED_FULL
-const SPEED_HIGH = C.LIBUSB_SPEED_HIGH
-const SPEED_SUPER = C.LIBUSB_SPEED_SUPER
-
-var SPEED_names = map[byte]string{
-       byte(C.LIBUSB_SPEED_UNKNOWN): "UNKNOWN",
-       byte(C.LIBUSB_SPEED_LOW):     "LOW",
-       byte(C.LIBUSB_SPEED_FULL):    "FULL",
-       byte(C.LIBUSB_SPEED_HIGH):    "HIGH",
-       byte(C.LIBUSB_SPEED_SUPER):   "SUPER",
-}
-
-type ControlSetup C.struct_libusb_control_setup
-type Transfer C.struct_libusb_transfer
-
-// Device and/or interface class codes.
-const CLASS_PER_INTERFACE = 0
-const CLASS_AUDIO = 1
-const CLASS_COMM = 2
-const CLASS_HID = 3
-const CLASS_PHYSICAL = 5
-const CLASS_PRINTER = 7
-const CLASS_IMAGE = 6
-const CLASS_MASS_STORAGE = 8
-const CLASS_HUB = 9
-const CLASS_DATA = 10
-const CLASS_SMART_CARD = 0x0b
-const CLASS_CONTENT_SECURITY = 0x0d
-const CLASS_VIDEO = 0x0e
-const CLASS_PERSONAL_HEALTHCARE = 0x0f
-const CLASS_DIAGNOSTIC_DEVICE = 0xdc
-const CLASS_WIRELESS = 0xe0
-const CLASS_APPLICATION = 0xfe
-const CLASS_VENDOR_SPEC = 0xff
-
-// Device and/or interface class codes.
-var CLASS_names = map[byte]string{
-       0:    "PER_INTERFACE",
-       1:    "AUDIO",
-       2:    "COMM",
-       3:    "HID",
-       5:    "PHYSICAL",
-       7:    "PRINTER",
-       6:    "IMAGE",
-       8:    "MASS_STORAGE",
-       9:    "HUB",
-       10:   "DATA",
-       0x0b: "SMART_CARD",
-       0x0d: "CONTENT_SECURITY",
-       0x0e: "VIDEO",
-       0x0f: "PERSONAL_HEALTHCARE",
-       0xdc: "DIAGNOSTIC_DEVICE",
-       0xe0: "WIRELESS",
-       0xfe: "APPLICATION",
-       0xff: "VENDOR_SPEC",
-}
-
-// Descriptor types as defined by the USB specification.
-const DT_DEVICE = 0x01
-const DT_CONFIG = 0x02
-const DT_STRING = 0x03
-const DT_INTERFACE = 0x04
-const DT_ENDPOINT = 0x05
-const DT_HID = 0x21
-const DT_REPORT = 0x22
-const DT_PHYSICAL = 0x23
-const DT_HUB = 0x29
-
-// Standard request types, as defined in table 9-3 of the USB2 specifications
-const REQUEST_GET_STATUS = 0x00
-const REQUEST_CLEAR_FEATURE = 0x01
-
-// Set or enable a specific feature
-const REQUEST_SET_FEATURE = 0x03
-
-// Set device address for all future accesses
-const REQUEST_SET_ADDRESS = 0x05
-
-// Get the specified descriptor
-const REQUEST_GET_DESCRIPTOR = 0x06
-
-// Used to update existing descriptors or add new descriptors
-const REQUEST_SET_DESCRIPTOR = 0x07
-
-// Get the current device configuration value
-const REQUEST_GET_CONFIGURATION = 0x08
-
-// Set device configuration
-const REQUEST_SET_CONFIGURATION = 0x09
-
-// Return the selected alternate setting for the specified interface.
-const REQUEST_GET_INTERFACE = 0x0A
-
-// Select an alternate interface for the specified interface
-const REQUEST_SET_INTERFACE = 0x0B
-
-// Set then report an endpoint's synchronization frame
-const REQUEST_SYNCH_FRAME = 0x0C
-
-// The error codes returned by libusb.
-type Error int
-
-func (e Error) Error() string {
-       return C.GoString(C.libusb_error_name(C.int(e)))
-}
-
-func toErr(e C.int) error {
-       if e < 0 {
-               return Error(e)
-       }
-       return nil
-}
-
-const SUCCESS = Error(0)
-const ERROR_IO = Error(-1)
-const ERROR_INVALID_PARAM = Error(-2)
-const ERROR_ACCESS = Error(-3)
-const ERROR_NO_DEVICE = Error(-4)
-const ERROR_NOT_FOUND = Error(-5)
-const ERROR_BUSY = Error(-6)
-const ERROR_TIMEOUT = Error(-7)
-const ERROR_OVERFLOW = Error(-8)
-const ERROR_PIPE = Error(-9)
-const ERROR_INTERRUPTED = Error(-10)
-const ERROR_NO_MEM = Error(-11)
-const ERROR_NOT_SUPPORTED = Error(-12)
-const ERROR_OTHER = Error(-99)
-
-const TRANSFER_COMPLETED = 0
-const TRANSFER_ERROR = 1
-const TRANSFER_TIMED_OUT = 2
-const TRANSFER_CANCELLED = 3
-const TRANSFER_STALL = 4
-const TRANSFER_NO_DEVICE = 5
-const TRANSFER_OVERFLOW = 6
-
-const TRANSFER_SHORT_NOT_OK = 1 << 0
-const TRANSFER_FREE_BUFFER = 1 << 1
-const TRANSFER_FREE_TRANSFER = 1 << 2
-
-// Request types to use in ControlTransfer().
-const REQUEST_TYPE_STANDARD = (0x00 << 5)
-const REQUEST_TYPE_CLASS = (0x01 << 5)
-const REQUEST_TYPE_VENDOR = (0x02 << 5)
-const REQUEST_TYPE_RESERVED = (0x03 << 5)
-
-// Recipient bits for the reqType of ControlTransfer(). Values 4 - 31
-// are reserved.
-const RECIPIENT_DEVICE = 0x00
-const RECIPIENT_INTERFACE = 0x01
-const RECIPIENT_ENDPOINT = 0x02
-const RECIPIENT_OTHER = 0x03
-
-// Synchronization types for isochronous endpoints, used in
-// EndpointDescriptor.Attributes, bits 2:3.
-const ISO_SYNC_TYPE_NONE = 0
-const ISO_SYNC_TYPE_ASYNC = 1
-const ISO_SYNC_TYPE_ADAPTIVE = 2
-const ISO_SYNC_TYPE_SYNC = 3
-
-// Usage types used in EndpointDescriptor.Attributes, bits 4:5.
-const ISO_USAGE_TYPE_DATA = 0
-const ISO_USAGE_TYPE_FEEDBACK = 1
-const ISO_USAGE_TYPE_IMPLICIT = 2
-
-// DeviceDescriptor is the standard USB device descriptor as
-// documented in section 9.6.1 of the USB 2.0 specification.
-type DeviceDescriptor struct {
-       // Size of this descriptor (in bytes)
-       Length byte
-       // Descriptor type.
-       DescriptorType byte
-       // USB specification release number in binary-coded decimal.
-       USBRelease uint16
-
-       // USB-IF class code for the device.
-       DeviceClass byte
-       // USB-IF subclass code for the device, qualified by the
-       // DeviceClass value.
-       DeviceSubClass byte
-       // USB-IF protocol code for the device, qualified by the
-       // DeviceClass and DeviceSubClass values.
-       DeviceProtocol byte
-       // Maximum packet size for endpoint 0.
-       MaxPacketSize0 byte
-       // USB-IF vendor ID.
-       IdVendor uint16
-       // USB-IF product ID.
-       IdProduct uint16
-       // Device release number in binary-coded decimal.
-       Device uint16
-
-       // Index of string descriptor describing manufacturer.
-       Manufacturer byte
-       // Index of string descriptor describing product.
-       Product byte
-       // Index of string descriptor containing device serial number.
-       SerialNumber byte
-
-       // Number of possible configurations.
-       NumConfigurations byte
-}
-
-// A collection of alternate settings for a USB interface.
-type Interface struct {
-       AltSetting []InterfaceDescriptor
-}
-
-func (f *Interface) fromC(c *C.struct_libusb_interface) {
-       f.AltSetting = make([]InterfaceDescriptor, c.num_altsetting)
-
-       ds := []C.struct_libusb_interface_descriptor{}
-       cSlice(unsafe.Pointer(&ds), unsafe.Pointer(c.altsetting), 
c.num_altsetting)
-       for i, s := range ds {
-               f.AltSetting[i].fromC(&s)
-       }
-}
-
-// EndpointDescriptor represents the standard USB endpoint
-// descriptor. This descriptor is documented in section 9.6.3 of the
-// USB 2.0 specification.
-type EndpointDescriptor struct {
-       // Size of this descriptor (in bytes)
-       Length byte
-
-       // Descriptor type. Will have value LIBUSB_DT_ENDPOINT in this
-       // context.
-       DescriptorType byte
-
-       // The address of the endpoint described by this descriptor. Bits 0:3 
are
-       // the endpoint number. Bits 4:6 are reserved. Bit 7 indicates 
direction.
-       EndpointAddress byte
-
-       // Attributes which apply to the endpoint when it is configured using
-       // the ConfigurationValue. Bits 0:1 determine the transfer type and
-       // correspond to libusb_transfer_type. Bits 2:3 are only used for
-       // isochronous endpoints and correspond to libusb_iso_sync_type.
-       // Bits 4:5 are also only used for isochronous endpoints and correspond 
to
-       // libusb_iso_usage_type. Bits 6:7 are reserved.
-       Attributes byte
-
-       // Maximum packet size this endpoint is capable of sending/receiving.
-       MaxPacketSize uint16
-
-       // Interval for polling endpoint for data transfers.
-       Interval byte
-
-       // For audio devices only: the rate at which synchronization feedback
-       // is provided.
-       Refresh byte
-
-       // For audio devices only: the address if the synch endpoint
-       SynchAddress byte
-
-       // Extra descriptors. If libusb encounters unknown endpoint
-       // descriptors, it will store them here, should you wish to
-       // parse them.
-       Extra []byte
-}
-
-// Endpoint transfer types, for bits 0:1 of
-// EndpointDescriptor.Attributes
-const TRANSFER_TYPE_CONTROL = 0
-const TRANSFER_TYPE_ISOCHRONOUS = 1
-const TRANSFER_TYPE_BULK = 2
-const TRANSFER_TYPE_INTERRUPT = 3
-
-// in: device-to-host
-const ENDPOINT_IN = 0x80
-
-// out: host-to-device
-const ENDPOINT_OUT = 0x00
-
-func (e *EndpointDescriptor) TransferType() byte {
-       return e.Attributes & 0x3
-}
-
-func (e *EndpointDescriptor) Direction() byte {
-       return e.EndpointAddress & ENDPOINT_IN
-}
-
-func (e *EndpointDescriptor) Number() byte {
-       return e.EndpointAddress & 0x0f
-}
-
-func (e *EndpointDescriptor) String() string {
-       tDir := "out"
-       if e.EndpointAddress&ENDPOINT_IN != 0 {
-               tDir = "in"
-       }
-
-       // TODO - print isochronous data too.
-       s := fmt.Sprintf("ep num %x dir %s ttype %s maxpacket %d",
-               e.Number(), tDir, transferTypeString(e.TransferType()),
-               e.MaxPacketSize)
-
-       return s
-}
-
-func byteArrToSlice(a *C.uchar, n C.int) []byte {
-       var g []C.uchar
-
-       b := make([]byte, int(n))
-       for i, c := range g {
-               b[i] = byte(c)
-       }
-       return b
-}
-
-func cSlice(slice unsafe.Pointer, arr unsafe.Pointer, n C.int) {
-       h := (*reflect.SliceHeader)(slice)
-       h.Cap = int(n)
-       h.Len = int(n)
-       h.Data = uintptr(unsafe.Pointer(arr))
-}
-
-func (d *EndpointDescriptor) fromC(c *C.struct_libusb_endpoint_descriptor) {
-       d.Length = byte(c.bLength)
-       d.DescriptorType = byte(c.bDescriptorType)
-       d.EndpointAddress = byte(c.bEndpointAddress)
-       d.Attributes = byte(c.bmAttributes)
-       d.MaxPacketSize = uint16(c.wMaxPacketSize)
-       d.Interval = byte(c.bInterval)
-       d.Refresh = byte(c.bRefresh)
-       d.SynchAddress = byte(c.bSynchAddress)
-
-       d.Extra = byteArrToSlice(c.extra, c.extra_length)
-}
-
-// InterfaceDescriptor contains the standard USB interface descriptor,
-// according to section 9.6.5 of the USB 2.0 specification.
-type InterfaceDescriptor struct {
-       // Size of this descriptor (in bytes)
-       Length byte
-
-       // Descriptor type. Will have value DT_INTERFACE
-       // LIBUSB_DT_INTERFACE in this context.
-       DescriptorType byte
-
-       // Number of this interface
-       InterfaceNumber byte
-
-       // Value used to select this alternate setting for this interface
-       AlternateSetting byte
-
-       // USB-IF class code for this interface.
-       InterfaceClass byte
-
-       // USB-IF subclass code for this interface, qualified by the
-       // InterfaceClass value
-       InterfaceSubClass byte
-
-       // USB-IF protocol code for this interface, qualified by the
-       // InterfaceClass and InterfaceSubClass values
-       InterfaceProtocol byte
-
-       // Index of string descriptor describing this interface
-       InterfaceStringIndex byte
-
-       // Array of endpoint descriptors.
-       EndPoints []EndpointDescriptor
-
-       // Extra descriptors. If libusb encounters unknown interface
-       // descriptors, it will store them here, should you wish to
-       // parse them.
-       Extra []byte
-}
-
-func (d *InterfaceDescriptor) fromC(c *C.struct_libusb_interface_descriptor) {
-       d.Length = byte(c.bLength)
-       d.DescriptorType = byte(c.bDescriptorType)
-       d.InterfaceNumber = byte(c.bInterfaceNumber)
-       d.AlternateSetting = byte(c.bAlternateSetting)
-       d.InterfaceClass = byte(c.bInterfaceClass)
-       d.InterfaceSubClass = byte(c.bInterfaceSubClass)
-       d.InterfaceProtocol = byte(c.bInterfaceProtocol)
-       d.InterfaceStringIndex = byte(c.iInterface)
-       d.EndPoints = make([]EndpointDescriptor, c.bNumEndpoints)
-
-       cs := []C.struct_libusb_endpoint_descriptor{}
-       cSlice(unsafe.Pointer(&cs), unsafe.Pointer(c.endpoint), 
C.int(c.bNumEndpoints))
-       for i, s := range cs {
-               d.EndPoints[i].fromC(&s)
-       }
-
-       d.Extra = byteArrToSlice(c.extra, c.extra_length)
-}
-
-type IsoPacketDescriptor struct {
-       // Length of data to request in this packet
-       Length uint
-
-       // Amount of data that was actually transferred
-       ActualLength uint
-
-       // Status code for this packet
-       Status int
-}
-
-type ConfigDescriptor struct {
-       // Size of this descriptor (in bytes)
-       Length byte
-
-       // Descriptor type. Will have value DT_CONFIG LIBUSB_DT_CONFIG
-       // in this context.
-       DescriptorType byte
-
-       // Total length of data returned for this configuration
-       TotalLength uint16
-
-       // Identifier value for this configuration
-       ConfigurationValue byte
-
-       // Index of string descriptor describing this configuration
-       ConfigurationIndex byte
-
-       // Configuration characteristics
-       Attributes byte
-
-       // Maximum power consumption of the USB device from this bus in this
-       // configuration when the device is fully opreation. Expressed in units
-       // of 2 mA.
-       MaxPower byte
-
-       // Array of interfaces supported by this configuration.
-       Interfaces []Interface
-
-       // Extra descriptors. If libusb encounters unknown configuration
-       // descriptors, it will store them here, should you wish to parse them.
-       Extra []byte
-}
-
-func (d *ConfigDescriptor) fromC(c *C.struct_libusb_config_descriptor) {
-       d.Length = byte(c.bLength)
-       d.DescriptorType = byte(c.bDescriptorType)
-       d.TotalLength = uint16(c.wTotalLength)
-       d.ConfigurationValue = byte(c.bConfigurationValue)
-       d.ConfigurationIndex = byte(c.iConfiguration)
-       d.Attributes = byte(c.bmAttributes)
-       d.MaxPower = byte(c.MaxPower)
-
-       d.Interfaces = make([]Interface, c.bNumInterfaces)
-
-       cis := []C.struct_libusb_interface{}
-       cSlice(unsafe.Pointer(&cis), unsafe.Pointer(c._interface), 
C.int(c.bNumInterfaces))
-       for i, iface := range cis {
-               d.Interfaces[i].fromC(&iface)
-       }
-       d.Extra = byteArrToSlice(c.extra, c.extra_length)
-}
-
-type Context C.struct_libusb_context
-type Device C.struct_libusb_device
-type DeviceHandle C.struct_libusb_device_handle
-
-func NewContext() *Context {
-       var r *C.struct_libusb_context
-       C.libusb_init(&r)
-       return (*Context)(r)
-}
-
-func (c *Context) me() *C.struct_libusb_context {
-       return (*C.struct_libusb_context)(c)
-}
-
-func (c *Context) SetDebug(level int) {
-       C.libusb_set_debug(c.me(), C.int(level))
-}
-
-func (c *Context) Exit() {
-       C.libusb_exit(c.me())
-}
-
-type DeviceList []*Device
-
-func (d DeviceList) Done() {
-       C.libusb_free_device_list((**C.libusb_device)(unsafe.Pointer((&d[0]))), 
1)
-}
-
-func (c *Context) GetDeviceList() (DeviceList, error) {
-       var devs **C.libusb_device
-       count := C.libusb_get_device_list(c.me(), &devs)
-       if count < 0 {
-               return nil, Error(count)
-       }
-       slice := &reflect.SliceHeader{uintptr(unsafe.Pointer(devs)), 
int(count), int(count)}
-       rdevs := *(*[]*Device)(unsafe.Pointer(slice))
-       return DeviceList(rdevs), nil
-}
-
-func (d *Device) me() *C.libusb_device {
-       return (*C.libusb_device)(d)
-}
-
-// Get the number of the bus that a device is connected to.
-func (d *Device) GetBusNumber() uint8 {
-       return uint8(C.libusb_get_bus_number(d.me()))
-}
-
-// Get the address of the device on the bus it is connected to.
-func (d *Device) GetDeviceAddress() uint8 {
-       return uint8(C.libusb_get_device_address(d.me()))
-}
-
-// Get the negotiated connection speed for a device.
-func (d *Device) GetDeviceSpeed() int {
-       return int(C.libusb_get_device_speed(d.me()))
-}
-
-// Convenience function to retrieve the MaxPacketSize value for a particular 
endpoint in the active device configuration.
-func (d *Device) GetMaxPacketSize(endpoint byte) int {
-       return int(C.libusb_get_max_packet_size(d.me(), C.uchar(endpoint)))
-}
-
-// Calculate the maximum packet size which a specific endpoint is capable is 
sending or receiving in the duration of 1 microframe.
-func (d *Device) GetMaxIsoPacketSize(endpoint byte) int {
-       return int(C.libusb_get_max_iso_packet_size(d.me(), C.uchar(endpoint)))
-}
-
-func (d *Device) Ref() *Device {
-       return (*Device)(C.libusb_ref_device((*C.libusb_device)(d.me())))
-}
-
-// Decrement the reference count of a device.
-func (d *Device) Unref() {
-       C.libusb_unref_device((*C.libusb_device)(d.me()))
-}
-
-func (d *Device) GetDeviceDescriptor() (*DeviceDescriptor, error) {
-       // this relies on struct packing being equal.
-       var dd DeviceDescriptor
-       r := C.libusb_get_device_descriptor(d.me(), 
(*C.struct_libusb_device_descriptor)(unsafe.Pointer(&dd)))
-       return &dd, toErr(r)
-}
-
-func (d *Device) GetActiveConfigDescriptor() (*ConfigDescriptor, error) {
-       var desc *C.struct_libusb_config_descriptor
-       r := C.libusb_get_active_config_descriptor(d.me(), &desc)
-       if r < 0 {
-               return nil, toErr(r)
-       }
-
-       var cd ConfigDescriptor
-       cd.fromC(desc)
-       C.libusb_free_config_descriptor(desc)
-       return &cd, nil
-}
-
-func (d *Device) GetConfigDescriptor(config byte) (*ConfigDescriptor, error) {
-       var desc *C.struct_libusb_config_descriptor
-       r := C.libusb_get_config_descriptor(d.me(), C.uint8_t(config), &desc)
-       if r < 0 {
-               return nil, toErr(r)
-       }
-
-       var cd ConfigDescriptor
-       cd.fromC(desc)
-       C.libusb_free_config_descriptor(desc)
-       return &cd, nil
-}
-
-func (d *Device) GetConfigDescriptorByValue(value byte) (*ConfigDescriptor, 
error) {
-       var desc *C.struct_libusb_config_descriptor
-       r := C.libusb_get_config_descriptor_by_value(d.me(), C.uint8_t(value), 
&desc)
-       if r < 0 {
-               return nil, toErr(r)
-       }
-
-       var cd ConfigDescriptor
-       cd.fromC(desc)
-       C.libusb_free_config_descriptor(desc)
-       return &cd, nil
-}
-
-// Determine the ConfigurationValue of the currently active configuration.
-func (h *DeviceHandle) GetConfiguration() (byte, error) {
-       var r C.int
-       err := C.libusb_get_configuration(h.me(), &r)
-       return byte(r), toErr(err)
-}
-
-// Set the active configuration for a device. The argument should be
-// a ConfigurationValue, as given in the ConfigDescriptor.
-func (h *DeviceHandle) SetConfiguration(c byte) error {
-       err := C.libusb_set_configuration(h.me(), C.int(c))
-       return toErr(err)
-}
-
-// Open a device and obtain a device handle.
-func (d *Device) Open() (*DeviceHandle, error) {
-       var h *C.libusb_device_handle
-       r := C.libusb_open(d.me(), &h)
-       return (*DeviceHandle)(h), toErr(r)
-}
-
-func (h *DeviceHandle) me() *C.libusb_device_handle {
-       return (*C.libusb_device_handle)(h)
-}
-
-// Close a device handle.
-func (h *DeviceHandle) Close() error {
-       C.libusb_close(h.me())
-       return nil
-}
-
-// Get the underlying device for a handle.
-func (h *DeviceHandle) Device() *Device {
-       return (*Device)(C.libusb_get_device(h.me()))
-}
-
-// Claim an interface on a given device handle.
-func (h *DeviceHandle) ClaimInterface(num byte) error {
-       return toErr(C.libusb_claim_interface(h.me(), C.int(num)))
-}
-
-// Release an interface previously claimed with libusb_claim_interface().
-func (h *DeviceHandle) ReleaseInterface(num byte) error {
-       return toErr(C.libusb_release_interface(h.me(), C.int(num)))
-}
-
-// Activate an alternate setting for an interface.
-func (h *DeviceHandle) SetInterfaceAltSetting(num int, alternate int) error {
-       return toErr(C.libusb_set_interface_alt_setting(h.me(), C.int(num), 
C.int(alternate)))
-}
-
-func (h *DeviceHandle) GetStringDescriptorASCII(descIndex byte) (string, 
error) {
-       data := make([]byte, 1024)
-       start := (*C.uchar)(unsafe.Pointer(&data[0]))
-       r := C.libusb_get_string_descriptor_ascii(h.me(),
-               C.uint8_t(descIndex), start, C.int(len(data)))
-       return C.GoString((*C.char)(unsafe.Pointer(&data[0]))), toErr(r)
-}
-
-func (h *DeviceHandle) ControlTransfer(reqType, req byte, value, index uint16,
-       data []byte, timeout int) error {
-       var ptr *byte
-       if len(data) > 0 {
-               ptr = &data[0]
-       }
-       if len(data) > 0xffff {
-               return fmt.Errorf("overflow")
-       }
-       err := C.libusb_control_transfer(h.me(),
-               C.uint8_t(reqType), C.uint8_t(req), C.uint16_t(value), 
C.uint16_t(index),
-               (*C.uchar)(ptr), C.uint16_t(len(data)), C.uint(timeout))
-       return toErr(err)
-}
-
-func (h *DeviceHandle) BulkTransfer(endpoint byte, data []byte, timeout int) 
(actual int, err error) {
-       var ptr *byte
-       if len(data) > 0 {
-               ptr = &data[0]
-       }
-
-       var n C.int
-       e := C.libusb_bulk_transfer(h.me(), C.uchar(endpoint), (*C.uchar)(ptr),
-               C.int(len(data)), &n, C.uint(timeout))
-       return int(n), toErr(e)
-}
-
-func (h *DeviceHandle) InterruptTransfer(endpoint byte, data []byte, timeout 
int) (actual int, err error) {
-       var ptr *byte
-       if len(data) > 0 {
-               ptr = &data[0]
-       }
-
-       var n C.int
-       e := C.libusb_bulk_transfer(h.me(), C.uchar(endpoint), (*C.uchar)(ptr),
-               C.int(len(data)), &n, C.uint(timeout))
-       return int(n), toErr(e)
-}
-
-// Perform a USB port reset to reinitialize a device.
-func (h *DeviceHandle) Reset() error {
-       return toErr(C.libusb_reset_device(h.me()))
-}
-
-// Clear an halt/stall for a endpoint.
-func (h *DeviceHandle) ClearHalt(endpoint byte) error {
-       return toErr(C.libusb_clear_halt(h.me(), C.uchar(endpoint)))
-}
-
-// Determine if a kernel driver is active on an interface.
-func (h *DeviceHandle) KernelDriverActive(ifaceNum byte) (bool, error) {
-       ret := C.libusb_kernel_driver_active(h.me(), C.int(ifaceNum))
-       if ret == 0 {
-               return false, nil
-       }
-       if ret == 1 {
-               return true, nil
-       }
-       return false, toErr(ret)
-}
-
-// Detach a kernel driver from an interface.
-func (h *DeviceHandle) DetachKernelDriver(ifaceNum byte) error {
-       return toErr(C.libusb_detach_kernel_driver(h.me(), C.int(ifaceNum)))
-}
-
-// Re-attach an interface's kernel driver, which was previously detached using 
libusb_detach_kernel_driver().
-func (h *DeviceHandle) AttachKernelDriver(ifaceNum byte) error {
-       return toErr(C.libusb_attach_kernel_driver(h.me(), C.int(ifaceNum)))
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-mtpfs-0.0.0+git20131015.bb3f0c2/usb/usb_test.go 
new/go-mtpfs-0.0.0+git20140903.689b5b4/usb/usb_test.go
--- old/go-mtpfs-0.0.0+git20131015.bb3f0c2/usb/usb_test.go      2013-11-11 
11:27:55.000000000 +0100
+++ new/go-mtpfs-0.0.0+git20140903.689b5b4/usb/usb_test.go      1970-01-01 
01:00:00.000000000 +0100
@@ -1,69 +0,0 @@
-package usb
-
-import (
-       "testing"
-)
-
-func TestDevice(t *testing.T) {
-       c := NewContext()
-       defer c.Exit()
-       l, err := c.GetDeviceList()
-       if err != nil {
-               t.Fatal("GetDeviceList failed:", err)
-       }
-
-       for _, dev := range l {
-               t.Logf("bus 0x%x addr 0x%x speed 0x%x\n",
-                       dev.GetBusNumber(), dev.GetDeviceAddress(), 
dev.GetDeviceSpeed())
-               dd, err := dev.GetDeviceDescriptor()
-               if err != nil {
-                       t.Logf("GetDeviceDescriptor failed: %v", err)
-                       continue
-               }
-
-               t.Logf("Vendor/Product %x:%x Class/subclass/protocol %x:%x:%x: 
%s\n",
-                       dd.IdVendor, dd.IdProduct, dd.DeviceClass, 
dd.DeviceSubClass, dd.DeviceProtocol, CLASS_names[dd.DeviceClass])
-
-               stringDescs := []byte{
-                       dd.Manufacturer, dd.Product, dd.SerialNumber,
-               }
-
-               for i := 0; i < int(dd.NumConfigurations); i++ {
-                       cd, err := dev.GetConfigDescriptor(byte(i))
-                       if err != nil {
-                               t.Logf("GetConfigDescriptor failed: %v", err)
-                               continue
-                       }
-                       stringDescs = append(stringDescs, cd.ConfigurationIndex)
-                       t.Logf(" config value %x, attributes %x power %d\n", 
cd.ConfigurationValue,
-                               cd.Attributes, cd.MaxPower)
-                       for idx, iface := range cd.Interfaces {
-                               t.Logf("  iface %d\n", idx)
-                               for _, alt := range iface.AltSetting {
-                                       t.Logf("   num %d 
class/subclass/protocol %x/%x/%x\n",
-                                               alt.InterfaceNumber, 
alt.InterfaceClass, alt.InterfaceSubClass, alt.InterfaceProtocol)
-                                       for _, ep := range alt.EndPoints {
-                                               t.Logf("    %v", &ep)
-                                       }
-                                       stringDescs = append(stringDescs, 
alt.InterfaceStringIndex)
-                               }
-                       }
-               }
-
-               dh, err := dev.Open()
-               if err != nil {
-                       t.Logf("can't open: %v", err)
-                       continue
-               }
-
-               for _, c := range stringDescs {
-                       str, err := dh.GetStringDescriptorASCII(c)
-                       if err != nil {
-                               t.Logf("GetStringDescriptorASCII %d failed: 
%v", c, err)
-                               continue
-                       }
-                       t.Logf(" desc %d: %s", c, str)
-               }
-               dh.Close()
-       }
-}

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to