diff --git a/src/simple-mtpfs-mtp-device.cpp b/src/simple-mtpfs-mtp-device.cpp index e773dc9..a68bea5 100644 --- a/src/simple-mtpfs-mtp-device.cpp +++ b/src/simple-mtpfs-mtp-device.cpp @@ -94,9 +94,18 @@ bool MTPDevice::connect(int dev_no) return false; } + LIBMTP_raw_device_t *raw_device = &raw_devices[dev_no]; + +#ifdef HAVE_LIBUSB1 + // Try to reset USB device, so we don't wait until LIBMTP times out. + // We do this every time we are about to mount a device, but better + // connect on first try, than wait for 60s timeout. + smtpfs_reset_device(raw_device); +#endif // HAVE_LIBUSB1 + // Do not output LIBMTP debug stuff StreamHelper::off(); - m_device = LIBMTP_Open_Raw_Device_Uncached(&raw_devices[dev_no]); + m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device); StreamHelper::on(); free(static_cast(raw_devices)); @@ -120,17 +129,24 @@ bool MTPDevice::connect(const std::string &dev_file) return true; } - LIBMTP_raw_device_t *device = smtpfs_raw_device_new(dev_file); - if (!device) { + LIBMTP_raw_device_t *raw_device = smtpfs_raw_device_new(dev_file); + if (!raw_device) { logerr("Can not open such device '", dev_file, "'.\n"); return false; } +#ifdef HAVE_LIBUSB1 + // Try to reset USB device, so we don't wait until LIBMTP times out. + // We do this every time we are about to mount a device, but better + // connect on first try, than wait for 60s timeout. + smtpfs_reset_device(raw_device); +#endif // HAVE_LIBUSB1 + // Do not output LIBMTP debug stuff StreamHelper::off(); - m_device = LIBMTP_Open_Raw_Device_Uncached(device); + m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device); StreamHelper::on(); - smtpfs_raw_device_free(device); + smtpfs_raw_device_free(raw_device); if (!m_device) { LIBMTP_Dump_Errorstack(m_device); diff --git a/src/simple-mtpfs-util.cpp b/src/simple-mtpfs-util.cpp index 04d268b..8a957f9 100644 --- a/src/simple-mtpfs-util.cpp +++ b/src/simple-mtpfs-util.cpp @@ -37,6 +37,7 @@ extern "C" { # include } #endif // HAVE_LIBUSB1 +#include "simple-mtpfs-log.h" #include "simple-mtpfs-util.h" const std::string devnull = "/dev/null"; @@ -227,6 +228,39 @@ LIBMTP_raw_device_t *smtpfs_raw_device_new(const std::string &path) return raw_device; } +bool smtpfs_reset_device(LIBMTP_raw_device_t *device) +{ + if (libusb_init(NULL) != 0) + return false; + + libusb_device **dev_list; + ssize_t num_devs = libusb_get_device_list(NULL, &dev_list); + if (!num_devs) { + libusb_exit(NULL); + return false; + } + + libusb_device_handle *dev_handle = nullptr; + for (auto i = 0; i < num_devs; ++i) { + uint8_t bnum = libusb_get_bus_number(dev_list[i]); + uint8_t dnum = libusb_get_device_address(dev_list[i]); + + if (static_cast(bnum) == device->bus_location && + dnum == device->devnum) + { + libusb_open(dev_list[i], &dev_handle); + libusb_reset_device(dev_handle); + libusb_close(dev_handle); + break; + } + } + + libusb_free_device_list(dev_list, 0); + libusb_exit(NULL); + + return true; +} + void smtpfs_raw_device_free(LIBMTP_raw_device_t *device) { if (!device) diff --git a/src/simple-mtpfs-util.h b/src/simple-mtpfs-util.h index ac7f4ee..21523fb 100644 --- a/src/simple-mtpfs-util.h +++ b/src/simple-mtpfs-util.h @@ -51,6 +51,7 @@ bool smtpfs_check_dir(const std::string &path); #ifdef HAVE_LIBUSB1 LIBMTP_raw_device_t *smtpfs_raw_device_new(const std::string &path); void smtpfs_raw_device_free(LIBMTP_raw_device_t *device); +bool smtpfs_reset_device(LIBMTP_raw_device_t *device); #endif // HAVE_LIBUSB1 #endif // SIMPLE_MTPFS_UTIL