X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Flibusb1_common.c;h=89f8092719241e780465c90702a9b20aca5a676b;hb=55abb63752196de5a2e79fc4944a6af24e6414f6;hp=a29b2e9105e56eaf51f645cc2ac515d2f204384f;hpb=7568a91c8e2398a113f0b40a2a24a1b91ed12c95;p=openocd.git diff --git a/src/jtag/drivers/libusb1_common.c b/src/jtag/drivers/libusb1_common.c index a29b2e9105..89f8092719 100644 --- a/src/jtag/drivers/libusb1_common.c +++ b/src/jtag/drivers/libusb1_common.c @@ -14,9 +14,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + * along with this program. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -165,49 +163,77 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, int retCode = -99; struct libusb_config_descriptor *config = NULL; + int current_config = -1; - libusb_get_config_descriptor(udev, configuration, &config); - retCode = libusb_set_configuration(devh, config->bConfigurationValue); + retCode = libusb_get_configuration(devh, ¤t_config); + if (retCode != 0) + return retCode; + + retCode = libusb_get_config_descriptor(udev, configuration, &config); + if (retCode != 0 || config == NULL) + return retCode; + + /* Only change the configuration if it is not already set to the + same one. Otherwise this issues a lightweight reset and hangs + LPC-Link2 with JLink firmware. */ + if (current_config != config->bConfigurationValue) + retCode = libusb_set_configuration(devh, config->bConfigurationValue); libusb_free_config_descriptor(config); return retCode; } -int jtag_libusb_get_endpoints(struct jtag_libusb_device *udev, +int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, unsigned int *usb_read_ep, - unsigned int *usb_write_ep) + unsigned int *usb_write_ep, + int bclass, int subclass, int protocol, int trans_type) { + struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); const struct libusb_interface *inter; const struct libusb_interface_descriptor *interdesc; const struct libusb_endpoint_descriptor *epdesc; struct libusb_config_descriptor *config; + *usb_read_ep = *usb_write_ep = 0; + libusb_get_config_descriptor(udev, 0, &config); for (int i = 0; i < (int)config->bNumInterfaces; i++) { inter = &config->interface[i]; - for (int j = 0; j < inter->num_altsetting; j++) { - interdesc = &inter->altsetting[j]; - for (int k = 0; - k < (int)interdesc->bNumEndpoints; k++) { - epdesc = &interdesc->endpoint[k]; - - uint8_t epnum = epdesc->bEndpointAddress; - bool is_input = epnum & 0x80; - LOG_DEBUG("usb ep %s %02x", - is_input ? "in" : "out", epnum); - - if (is_input) - *usb_read_ep = epnum; - else - *usb_write_ep = epnum; + interdesc = &inter->altsetting[0]; + for (int k = 0; + k < (int)interdesc->bNumEndpoints; k++) { + if ((bclass > 0 && interdesc->bInterfaceClass != bclass) || + (subclass > 0 && interdesc->bInterfaceSubClass != subclass) || + (protocol > 0 && interdesc->bInterfaceProtocol != protocol)) + continue; + + epdesc = &interdesc->endpoint[k]; + if (trans_type > 0 && (epdesc->bmAttributes & 0x3) != trans_type) + continue; + + uint8_t epnum = epdesc->bEndpointAddress; + bool is_input = epnum & 0x80; + LOG_DEBUG("usb ep %s %02x", + is_input ? "in" : "out", epnum); + + if (is_input) + *usb_read_ep = epnum; + else + *usb_write_ep = epnum; + + if (*usb_read_ep && *usb_write_ep) { + LOG_DEBUG("Claiming interface %d", (int)interdesc->bInterfaceNumber); + libusb_claim_interface(devh, (int)interdesc->bInterfaceNumber); + libusb_free_config_descriptor(config); + return ERROR_OK; } } } libusb_free_config_descriptor(config); - return 0; + return ERROR_FAIL; } int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid)