+
+ if (libusb_init(&(slsg->libusb_ctx))) {
+ WLOG("failed to init libusb context, wrong version of libraries?\n");
+ free(sl);
+ free(slsg);
+ return NULL;
+ }
+
+ libusb_set_debug(slsg->libusb_ctx, 3);
+
+ slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID);
+ if (slsg->usb_handle == NULL) {
+ WLOG("Failed to find an stlink v1 by VID:PID\n");
+ libusb_close(slsg->usb_handle);
+ libusb_exit(slsg->libusb_ctx);
+ free(sl);
+ free(slsg);
+ return NULL;
+ }
+
+ // TODO
+ // Could read the interface config descriptor, and assert lots of the assumptions
+
+ // assumption: numInterfaces is always 1...
+ if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) {
+ int r = libusb_detach_kernel_driver(slsg->usb_handle, 0);
+ if (r < 0) {
+ WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r));
+ libusb_close(slsg->usb_handle);
+ libusb_exit(slsg->libusb_ctx);
+ free(sl);
+ free(slsg);
+ return NULL;
+ }
+ DLOG("Kernel driver was successfully detached\n");
+ }
+
+ int config;
+ if (libusb_get_configuration(slsg->usb_handle, &config)) {
+ /* this may fail for a previous configured device */
+ WLOG("libusb_get_configuration()\n");
+ libusb_close(slsg->usb_handle);
+ libusb_exit(slsg->libusb_ctx);
+ free(sl);
+ free(slsg);
+ return NULL;
+
+ }
+
+ // assumption: bConfigurationValue is always 1
+ if (config != 1) {
+ WLOG("Your stlink got into a real weird configuration, trying to fix it!\n");
+ DLOG("setting new configuration (%d -> 1)\n", config);
+ if (libusb_set_configuration(slsg->usb_handle, 1)) {
+ /* this may fail for a previous configured device */
+ WLOG("libusb_set_configuration() failed\n");
+ libusb_close(slsg->usb_handle);
+ libusb_exit(slsg->libusb_ctx);
+ free(sl);
+ free(slsg);
+ return NULL;
+ }
+ }
+
+ if (libusb_claim_interface(slsg->usb_handle, 0)) {
+ WLOG("libusb_claim_interface() failed\n");
+ libusb_close(slsg->usb_handle);
+ libusb_exit(slsg->libusb_ctx);
+ free(sl);
+ free(slsg);
+ return NULL;
+ }
+
+ // assumption: endpoint config is fixed mang. really.
+ slsg->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
+ slsg->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
+
+ DLOG("Successfully opened stlinkv1 by libusb :)\n");
+