reset device before every connection

We reset a usb device before issuing LIBMTP_Open_Raw_Device_Uncached(), so we do not timeout, when libmtp can't properly open the usb device.
This commit is contained in:
Peter Hatina 2014-02-09 19:13:18 +01:00
parent a5499dea4f
commit 5535446a7a
3 changed files with 56 additions and 5 deletions

View File

@ -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<void*>(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);

View File

@ -37,6 +37,7 @@ extern "C" {
# include <libusb.h>
}
#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<uint32_t>(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)

View File

@ -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