+
+int ezusb_upload_firmware(libusb_device *dev, int configuration,
+ const char *filename)
+{
+ struct libusb_device_handle *hdl;
+ int err;
+
+ sr_info("uploading firmware to device on %d.%d",
+ libusb_get_bus_number(dev), libusb_get_device_address(dev));
+
+ if ((err = libusb_open(dev, &hdl)) < 0) {
+ sr_warn("failed to open device: %d", err);
+ return SR_ERR;
+ }
+
+ if (libusb_kernel_driver_active(hdl, 0)) {
+ if ((err = libusb_detach_kernel_driver(hdl, 0)) < 0) {
+ sr_warn("failed to detach kernel driver: %d", err);
+ return SR_ERR;
+ }
+ }
+
+ if ((err = libusb_set_configuration(hdl, configuration)) < 0) {
+ sr_warn("Unable to set configuration: %d", err);
+ return SR_ERR;
+ }
+
+ if ((ezusb_reset(hdl, 1)) < 0)
+ return SR_ERR;
+
+ if (ezusb_install_firmware(hdl, filename) < 0)
+ return SR_ERR;
+
+ if ((ezusb_reset(hdl, 0)) < 0)
+ return SR_ERR;
+
+ libusb_close(hdl);
+
+ return SR_OK;
+}