summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Hjelm <hjelmn@me.com>2016-09-07 18:47:25 -0600
committerNathan Hjelm <hjelmn@me.com>2016-09-07 18:47:25 -0600
commitaa1d76cd13ae8f8fac696ab2c3204d3f39c77c4c (patch)
tree9f7b2189854652e227fc20d53f50ab4827eb699b
parente5b09f34553df82ebced2c2dce91a50980c2786a (diff)
downloadlibusb-aa1d76cd13ae8f8fac696ab2c3204d3f39c77c4c.tar.gz
darwin: work around devices with buggy endpoint descriptors
This commit adds a workaround for devices that have buggy endpoint descriptors but are otherwise functional. These devices will have endpoints that fail the GetPipeProperties call. Since we only care about the endpoint address we can read it from the descriptor itself. Signed-off-by: Nathan Hjelm <hjelmn@me.com>
-rw-r--r--libusb/os/darwin_usb.c31
-rw-r--r--libusb/version_nano.h2
2 files changed, 25 insertions, 8 deletions
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
index 7912282..ef163ff 100644
--- a/libusb/os/darwin_usb.c
+++ b/libusb/os/darwin_usb.c
@@ -1201,7 +1201,7 @@ static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
u_int8_t numep, direction, number;
u_int8_t dont_care1, dont_care3;
u_int16_t dont_care2;
- int i;
+ int rc;
usbi_dbg ("building table of endpoints.");
@@ -1213,19 +1213,36 @@ static int get_endpoints (struct libusb_device_handle *dev_handle, int iface) {
}
/* iterate through pipe references */
- for (i = 1 ; i <= numep ; i++) {
+ for (int i = 1 ; i <= numep ; i++) {
kresult = (*(cInterface->interface))->GetPipeProperties(cInterface->interface, i, &direction, &number, &dont_care1,
&dont_care2, &dont_care3);
if (kresult != kIOReturnSuccess) {
- usbi_err (HANDLE_CTX (dev_handle), "error getting pipe information for pipe %d: %s", i, darwin_error_str(kresult));
+ /* probably a buggy device. try to get the endpoint address from the descriptors */
+ struct libusb_config_descriptor *config;
+ const struct libusb_endpoint_descriptor *endpoint_desc;
+ UInt8 alt_setting;
- return darwin_to_libusb (kresult);
- }
+ kresult = (*(cInterface->interface))->GetAlternateSetting (cInterface->interface, &alt_setting);
+ if (kresult) {
+ usbi_err (HANDLE_CTX (dev_handle), "can't get alternate setting for interface");
+ return darwin_to_libusb (kresult);
+ }
+
+ rc = libusb_get_active_config_descriptor (dev_handle->dev, &config);
+ if (LIBUSB_SUCCESS != rc) {
+ return rc;
+ }
- usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, direction, number);
+ endpoint_desc = config->interface[iface].altsetting[alt_setting].endpoint + i - 1;
+
+ cInterface->endpoint_addrs[i - 1] = endpoint_desc->bEndpointAddress;
+ } else {
+ cInterface->endpoint_addrs[i - 1] = (((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
+ }
- cInterface->endpoint_addrs[i - 1] = (((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
+ usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
+ cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
}
cInterface->num_endpoints = numep;
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 43ace0c..2074f55 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11140
+#define LIBUSB_NANO 11141