Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Unified Diff: patches/13_cherrypick_15d18e31.patch

Issue 11183017: libmtp: Cherrypick upstream commit 15d18e31458be5006eb229df68869df2fff9 to fix device detection for… (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/libmtp/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/libusb-glue.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: patches/13_cherrypick_15d18e31.patch
===================================================================
--- patches/13_cherrypick_15d18e31.patch (revision 0)
+++ patches/13_cherrypick_15d18e31.patch (revision 0)
@@ -0,0 +1,351 @@
+Index: src/libusb-glue.h
+===================================================================
+--- src/libusb-glue.h (revision 162277)
++++ src/libusb-glue.h (working copy)
+@@ -3,7 +3,7 @@
+ * Low-level USB interface glue towards libusb.
+ *
+ * Copyright (C) 2005-2007 Richard A. Low <richard@wentnet.com>
+- * Copyright (C) 2005-2011 Linus Walleij <triad@df.lth.se>
++ * Copyright (C) 2005-2012 Linus Walleij <triad@df.lth.se>
+ * Copyright (C) 2006-2011 Marcus Meissner
+ * Copyright (C) 2007 Ted Bullock
+ * Copyright (C) 2008 Chris Bagwell <chris@cnpbagwell.com>
+@@ -91,7 +91,9 @@
+ #ifdef HAVE_LIBOPENUSB
+ openusb_dev_handle_t* handle;
+ #endif
++ uint8_t config;
+ uint8_t interface;
++ uint8_t altsetting;
+ int inep;
+ int inep_maxpacket;
+ int outep;
+Index: src/libusb1-glue.c
+===================================================================
+--- src/libusb1-glue.c (revision 162277)
++++ src/libusb1-glue.c (working copy)
+@@ -87,7 +87,9 @@
+ static LIBMTP_error_number_t init_usb();
+ static void close_usb(PTP_USB* ptp_usb);
+ static int find_interface_and_endpoints(libusb_device *dev,
++ uint8_t *conf,
+ uint8_t *interface,
++ uint8_t *altsetting,
+ int* inep,
+ int* inep_maxpacket,
+ int* outep,
+@@ -297,6 +299,7 @@
+ && intf->bInterfaceSubClass == 0x01
+ && intf->bInterfaceProtocol == 0x01) {
+ if (dumpfile != NULL) {
++ fprintf(dumpfile, "Configuration %d, interface %d, altsetting %d:\n", i, j, k);
+ fprintf(dumpfile, " Found PTP device, check vendor "
+ "extension...\n");
+ }
+@@ -321,7 +324,7 @@
+ fprintf(dumpfile, " Interface description contains the string \"MTP\"\n");
+ fprintf(dumpfile, " Device recognized as MTP, no further probing.\n");
+ }
+- libusb_free_config_descriptor (config);
++ libusb_free_config_descriptor(config);
+ libusb_close(devh);
+ return 1;
+ }
+@@ -334,13 +337,14 @@
+ if (config->interface[j].altsetting[k].bInterfaceClass !=
+ LIBUSB_CLASS_MASS_STORAGE) {
+ LIBMTP_INFO("avoid probing device using attached kernel interface\n");
+- libusb_free_config_descriptor (config);
++ libusb_free_config_descriptor(config);
+ return 0;
+ }
+ }
+ }
+- }
+- }
++ }
++ libusb_free_config_descriptor(config);
++ }
+
+ /*
+ * Only probe for OS descriptor if the device is vendor specific
+@@ -1623,11 +1627,12 @@
+ return PTP_RC_OK;
+ }
+
+-static int init_ptp_usb (PTPParams* params, PTP_USB* ptp_usb, libusb_device* dev)
++static int init_ptp_usb(PTPParams* params, PTP_USB* ptp_usb, libusb_device* dev)
+ {
+ libusb_device_handle *device_handle;
+ unsigned char buf[255];
+ int ret, usbresult;
++ struct libusb_config_descriptor *config;
+
+ params->sendreq_func=ptp_usb_sendreq;
+ params->senddata_func=ptp_usb_senddata;
+@@ -1646,50 +1651,81 @@
+
+ ret = libusb_open(dev, &device_handle);
+ if (ret != LIBUSB_SUCCESS) {
+- perror("usb_open()");
++ perror("libusb_open() failed!");
+ return -1;
+ }
+ ptp_usb->handle = device_handle;
++
+ /*
+ * If this device is known to be wrongfully claimed by other kernel
+ * drivers (such as mass storage), then try to unload it to make it
+ * accessible from user space.
+ */
+ if (FLAG_UNLOAD_DRIVER(ptp_usb) &&
+- libusb_kernel_driver_active (device_handle, ptp_usb->interface)
++ libusb_kernel_driver_active(device_handle, ptp_usb->interface)
+ ) {
+- if (LIBUSB_SUCCESS != libusb_detach_kernel_driver (device_handle, ptp_usb->interface)) {
+- return -1;
++ if (LIBUSB_SUCCESS != libusb_detach_kernel_driver(device_handle, ptp_usb->interface)) {
++ perror("libusb_detach_kernel_driver() failed, continuing anyway...");
+ }
+ }
+-#ifdef __WIN32__
+- // Only needed on Windows, and cause problems on other platforms.
+- if (libusb_set_configuration(device_handle, dev->config->bConfigurationValue)) {
+- perror("usb_set_configuration()");
++
++ /*
++ * Check if the config is set to something else than what we want
++ * to use. Only set the configuration if we absolutely have to.
++ * Also do not bail out if we fail.
++ */
++ ret = libusb_get_active_config_descriptor(dev, &config);
++ if (ret != LIBUSB_SUCCESS) {
++ perror("libusb_get_active_config_descriptor(1) failed");
+ return -1;
+ }
+-#endif
+- // It seems like on kernel 2.6.31 if we already have it open on another
+- // pthread in our app, we'll get an error if we try to claim it again,
+- // but that error is harmless because our process already claimed the interface
++ if (config->bConfigurationValue != ptp_usb->config) {
++ fprintf(stderr, "desired configuration different from current, trying to set configuration\n");
++ if (libusb_set_configuration(device_handle, ptp_usb->config)) {
++ perror("libusb_set_configuration() failed, continuing anyway...");
++ }
++ /* Re-fetch the config descriptor if we changed */
++ libusb_free_config_descriptor(config);
++ ret = libusb_get_active_config_descriptor(dev, &config);
++ if (ret != LIBUSB_SUCCESS) {
++ perror("libusb_get_active_config_descriptor(2) failed");
++ return -1;
++ }
++ }
++
++ /*
++ * It seems like on kernel 2.6.31 if we already have it open on another
++ * pthread in our app, we'll get an error if we try to claim it again,
++ * but that error is harmless because our process already claimed the interface
++ */
+ usbresult = libusb_claim_interface(device_handle, ptp_usb->interface);
+
+ if (usbresult != 0)
+- fprintf(stderr, "ignoring usb_claim_interface = %d", usbresult);
++ fprintf(stderr, "ignoring libusb_claim_interface() = %d", usbresult);
+
+- // FIXME : Discovered in the Barry project
+- // kernels >= 2.6.28 don't set the interface the same way as
+- // previous versions did, and the Blackberry gets confused
+- // if it isn't explicitly set
+- // See above, same issue with pthreads means that if this fails it is not
+- // fatal
+- // However, this causes problems on Macs so disable here
++ /*
++ * If the altsetting is set to something different than we want, switch
++ * it.
++ *
++ * FIXME: this seems to cause trouble on the Mac:s so disable it. Retry
++ * this on the Mac now that it only sets this when the altsetting differs.
++ */
+ #ifndef __APPLE__
+- usbresult = libusb_set_interface_alt_setting(device_handle, ptp_usb->interface, 0);
+- if (usbresult)
+- fprintf(stderr, "ignoring usb_claim_interface = %d", usbresult);
++#if 0 /* Disable this always, no idea on how to handle it */
++ if (config->interface[].altsetting[].bAlternateSetting !=
++ ptp_usb->altsetting) {
++ fprintf(stderr, "desired altsetting different from current, trying to set altsetting\n");
++ usbresult = libusb_set_interface_alt_setting(device_handle,
++ ptp_usb->interface,
++ ptp_usb->altsetting);
++ if (usbresult != 0)
++ fprintf(stderr, "ignoring libusb_set_interface_alt_setting() = %d\n", usbresult);
++ }
+ #endif
++#endif
+
++ libusb_free_config_descriptor(config);
++
+ if (FLAG_SWITCH_MODE_BLACKBERRY(ptp_usb)) {
+ int ret;
+
+@@ -1823,76 +1859,88 @@
+ * Self-explanatory?
+ */
+ static int find_interface_and_endpoints(libusb_device *dev,
++ uint8_t *conf,
+ uint8_t *interface,
++ uint8_t *altsetting,
+ int* inep,
+ int* inep_maxpacket,
+ int* outep,
+ int *outep_maxpacket,
+ int* intep)
+ {
+- int i, ret;
++ uint8_t i, ret;
+ struct libusb_device_descriptor desc;
+
+- ret = libusb_get_device_descriptor (dev, &desc);
+- if (ret != LIBUSB_SUCCESS) return -1;
++ ret = libusb_get_device_descriptor(dev, &desc);
++ if (ret != LIBUSB_SUCCESS)
++ return -1;
+
+ // Loop over the device configurations
+ for (i = 0; i < desc.bNumConfigurations; i++) {
+ uint8_t j;
+ struct libusb_config_descriptor *config;
+
+- ret = libusb_get_config_descriptor (dev, i, &config);
++ ret = libusb_get_config_descriptor(dev, i, &config);
++ if (ret != 0)
++ continue;
++
++ *conf = config->bConfigurationValue;
++
+ if (ret != LIBUSB_SUCCESS) continue;
+ // Loop over each configurations interfaces
+ for (j = 0; j < config->bNumInterfaces; j++) {
+- uint8_t k;
++ uint8_t k, l;
+ uint8_t no_ep;
+ int found_inep = 0;
+ int found_outep = 0;
+ int found_intep = 0;
+ const struct libusb_endpoint_descriptor *ep;
+
+- // MTP devices shall have 3 endpoints, ignore those interfaces
+- // that haven't.
+- no_ep = config->interface[j].altsetting->bNumEndpoints;
+- if (no_ep != 3)
+- continue;
++ // Inspect the altsettings of this interface...
++ for (k = 0; k < config->interface[j].num_altsetting; k++) {
+
+- *interface = config->interface[j].altsetting->bInterfaceNumber;
+- ep = config->interface[j].altsetting->endpoint;
++ // MTP devices shall have 3 endpoints, ignore those interfaces
++ // that haven't.
++ no_ep = config->interface[j].altsetting[k].bNumEndpoints;
++ if (no_ep != 3)
++ continue;
+
+- // Loop over the three endpoints to locate two bulk and
+- // one interrupt endpoint and FAIL if we cannot, and continue.
+- for (k = 0; k < no_ep; k++) {
+- if (ep[k].bmAttributes == LIBUSB_TRANSFER_TYPE_BULK) {
+- if ((ep[k].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ==
+- LIBUSB_ENDPOINT_DIR_MASK) {
+- *inep = ep[k].bEndpointAddress;
+- *inep_maxpacket = ep[k].wMaxPacketSize;
+- found_inep = 1;
++ *interface = config->interface[j].altsetting[k].bInterfaceNumber;
++ *altsetting = config->interface[j].altsetting[k].bAlternateSetting;
++ ep = config->interface[j].altsetting[k].endpoint;
++
++ // Loop over the three endpoints to locate two bulk and
++ // one interrupt endpoint and FAIL if we cannot, and continue.
++ for (l = 0; l < no_ep; l++) {
++ if (ep[l].bmAttributes == LIBUSB_TRANSFER_TYPE_BULK) {
++ if ((ep[l].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ==
++ LIBUSB_ENDPOINT_DIR_MASK) {
++ *inep = ep[l].bEndpointAddress;
++ *inep_maxpacket = ep[l].wMaxPacketSize;
++ found_inep = 1;
++ }
++ if ((ep[l].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == 0) {
++ *outep = ep[l].bEndpointAddress;
++ *outep_maxpacket = ep[l].wMaxPacketSize;
++ found_outep = 1;
++ }
++ } else if (ep[l].bmAttributes == LIBUSB_TRANSFER_TYPE_INTERRUPT) {
++ if ((ep[l].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ==
++ LIBUSB_ENDPOINT_DIR_MASK) {
++ *intep = ep[l].bEndpointAddress;
++ found_intep = 1;
++ }
+ }
+- if ((ep[k].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == 0) {
+- *outep = ep[k].bEndpointAddress;
+- *outep_maxpacket = ep[k].wMaxPacketSize;
+- found_outep = 1;
+- }
+- } else if (ep[k].bmAttributes == LIBUSB_TRANSFER_TYPE_INTERRUPT) {
+- if ((ep[k].bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ==
+- LIBUSB_ENDPOINT_DIR_MASK) {
+- *intep = ep[k].bEndpointAddress;
+- found_intep = 1;
+- }
+ }
+- }
+- if (found_inep && found_outep && found_intep) {
+- libusb_free_config_descriptor (config);
+- // We assigned the endpoints so return here.
+- return 0;
+- }
+- // Else loop to next interface/config
+- }
+- libusb_free_config_descriptor (config);
+- }
++ if (found_inep && found_outep && found_intep) {
++ libusb_free_config_descriptor(config);
++ // We assigned the endpoints so return here.
++ return 0;
++ }
++ } // Next altsetting
++ } // Next interface
++ libusb_free_config_descriptor(config);
++ } // Next config
+ return -1;
+ }
+
+@@ -1921,14 +1969,14 @@
+ if (init_usb_ret != LIBMTP_ERROR_NONE)
+ return init_usb_ret;
+
+- nrofdevs = libusb_get_device_list (NULL, &devs);
++ nrofdevs = libusb_get_device_list(NULL, &devs);
+ for (i = 0; i < nrofdevs ; i++) {
+- if (libusb_get_bus_number (devs[i]) != device->bus_location)
++ if (libusb_get_bus_number(devs[i]) != device->bus_location)
+ continue;
+- if (libusb_get_device_address (devs[i]) != device->devnum)
++ if (libusb_get_device_address(devs[i]) != device->devnum)
+ continue;
+
+- ret = libusb_get_device_descriptor (devs[i], &desc);
++ ret = libusb_get_device_descriptor(devs[i], &desc);
+ if (ret != LIBUSB_SUCCESS) continue;
+
+ if(desc.idVendor == device->device_entry.vendor_id &&
+@@ -1967,7 +2015,9 @@
+
+ /* Assign interface and endpoints to usbinfo... */
+ err = find_interface_and_endpoints(ldevice,
++ &ptp_usb->config,
+ &ptp_usb->interface,
++ &ptp_usb->altsetting,
+ &ptp_usb->inep,
+ &ptp_usb->inep_maxpacket,
+ &ptp_usb->outep,
« no previous file with comments | « no previous file | src/libusb-glue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698