razer-bw-te-ctl: adjust code style
And import the newer find_device() from elksmart-comm.
This commit is contained in:
parent
e46eee0a7f
commit
3219d87bc4
@ -34,71 +34,60 @@
|
||||
|
||||
// --- Utilities ---------------------------------------------------------------
|
||||
|
||||
/** Search for a device with given vendor and product ID. */
|
||||
/// Search for a device with given vendor and product ID.
|
||||
/// This is quite similar to libusb_open_device_with_vid_pid().
|
||||
static libusb_device_handle *
|
||||
find_device (int vendor, int product, int *error)
|
||||
find_device(int vendor, int product, int *error)
|
||||
{
|
||||
libusb_device **list;
|
||||
libusb_device *found = NULL;
|
||||
libusb_device **list = NULL;
|
||||
libusb_device_handle *handle = NULL;
|
||||
int err = 0;
|
||||
int result = 0;
|
||||
|
||||
ssize_t cnt = libusb_get_device_list (NULL, &list);
|
||||
if (cnt < 0)
|
||||
ssize_t len = libusb_get_device_list(NULL, &list);
|
||||
if (len < 0) {
|
||||
result = len;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ssize_t i = 0;
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
for (ssize_t i = 0; i < len; i++) {
|
||||
libusb_device *device = list[i];
|
||||
|
||||
struct libusb_device_descriptor desc;
|
||||
if (libusb_get_device_descriptor (device, &desc))
|
||||
struct libusb_device_descriptor desc = {};
|
||||
if ((result = libusb_get_device_descriptor(device, &desc)))
|
||||
(void) libusb_strerror(result);
|
||||
else if (desc.idVendor != vendor || desc.idProduct != product)
|
||||
continue;
|
||||
|
||||
if (desc.idVendor == vendor && desc.idProduct == product)
|
||||
{
|
||||
found = device;
|
||||
else if (!(result = libusb_open(device, &handle)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
err = libusb_open (found, &handle);
|
||||
if (err)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
out_free:
|
||||
libusb_free_device_list(list, 1);
|
||||
libusb_free_device_list(list, true);
|
||||
out:
|
||||
if (error != NULL && err != 0)
|
||||
*error = err;
|
||||
if (error != NULL && result != 0)
|
||||
*error = result;
|
||||
return handle;
|
||||
}
|
||||
|
||||
// --- Device configuration ----------------------------------------------------
|
||||
|
||||
#define USB_VENDOR_RAZER 0x1532
|
||||
#define USB_PRODUCT_RAZER_BW_TE 0x011c
|
||||
enum {
|
||||
USB_VENDOR_RAZER = 0x1532,
|
||||
USB_PRODUCT_RAZER_BW_TE = 0x011c,
|
||||
|
||||
#define USB_GET_REPORT 0x01
|
||||
#define USB_SET_REPORT 0x09
|
||||
USB_GET_REPORT = 0x01,
|
||||
USB_SET_REPORT = 0x09,
|
||||
|
||||
#define BW_CTL_IFACE 0
|
||||
BW_CTL_IFACE = 0,
|
||||
};
|
||||
|
||||
/** Razer logo backlight mode. */
|
||||
enum bw_led_mode
|
||||
{
|
||||
/// Razer logo backlight mode.
|
||||
enum bw_led_mode {
|
||||
LED_BRIGHTNESS = 0,
|
||||
LED_BLINK,
|
||||
LED_PULSATE
|
||||
};
|
||||
|
||||
/** Overall device configuration. */
|
||||
struct bw_config
|
||||
{
|
||||
/// Overall device configuration.
|
||||
struct bw_config {
|
||||
enum bw_led_mode led_mode;
|
||||
unsigned led_brightness;
|
||||
unsigned macro_led_on : 1;
|
||||
@ -106,71 +95,70 @@ struct bw_config
|
||||
unsigned gaming_mode : 1;
|
||||
};
|
||||
|
||||
/** Send a command to the mouse via SET_REPORT. */
|
||||
/// Send a command to the mouse via SET_REPORT.
|
||||
static int
|
||||
bw_send_command (libusb_device_handle *device,
|
||||
unsigned char *data, uint16_t length)
|
||||
bw_send_command(
|
||||
libusb_device_handle *device, unsigned char *data, uint16_t length)
|
||||
{
|
||||
unsigned char packet[90] = { 0x00 };
|
||||
assert (length <= sizeof packet - 5);
|
||||
memcpy (packet + 5, data, length);
|
||||
unsigned char packet[90] = {0x00};
|
||||
assert(length <= sizeof packet - 5);
|
||||
memcpy(packet + 5, data, length);
|
||||
|
||||
unsigned char checksum = 0;
|
||||
while (length--)
|
||||
checksum ^= data[length];
|
||||
packet[sizeof packet - 2] = checksum;
|
||||
|
||||
// XXX wIndex should actually be 0x0002 but that doesn't work
|
||||
int result = libusb_control_transfer (device, LIBUSB_ENDPOINT_OUT
|
||||
| LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
// XXX: wIndex should actually be 0x0002 but that doesn't work.
|
||||
int result = libusb_control_transfer(device, LIBUSB_ENDPOINT_OUT |
|
||||
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||
USB_SET_REPORT, 0x0300, 0x0000, packet, sizeof packet, 0);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
|
||||
/** Set Razer logo backlight mode. */
|
||||
/// Set Razer logo backlight mode.
|
||||
static int
|
||||
bw_set_led_mode (libusb_device_handle *device, enum bw_led_mode mode)
|
||||
bw_set_led_mode(libusb_device_handle *device, enum bw_led_mode mode)
|
||||
{
|
||||
unsigned char cmd[] = { 0x03, 0x03, 0x02, 0x01, 0x04, mode };
|
||||
return bw_send_command (device, cmd, sizeof cmd);
|
||||
unsigned char cmd[] = {0x03, 0x03, 0x02, 0x01, 0x04, mode};
|
||||
return bw_send_command(device, cmd, sizeof cmd);
|
||||
}
|
||||
|
||||
/** Set Razer logo backlight brightness. */
|
||||
/// Set Razer logo backlight brightness.
|
||||
static int
|
||||
bw_set_led_brightness (libusb_device_handle *device, unsigned char brightness)
|
||||
bw_set_led_brightness(libusb_device_handle *device, unsigned char brightness)
|
||||
{
|
||||
unsigned char cmd[] = { 0x03, 0x03, 0x03, 0x01, 0x04, brightness };
|
||||
return bw_send_command (device, cmd, sizeof cmd);
|
||||
unsigned char cmd[] = {0x03, 0x03, 0x03, 0x01, 0x04, brightness};
|
||||
return bw_send_command(device, cmd, sizeof cmd);
|
||||
}
|
||||
|
||||
/** Set the on/off state of the macro LED. */
|
||||
/// Set the on/off state of the macro LED.
|
||||
static int
|
||||
bw_set_macro_led (libusb_device_handle *device, bool on)
|
||||
bw_set_macro_led(libusb_device_handle *device, bool on)
|
||||
{
|
||||
unsigned char cmd[] = { 0x03, 0x03, 0x00, 0x00, 0x07, on };
|
||||
return bw_send_command (device, cmd, sizeof cmd);
|
||||
unsigned char cmd[] = {0x03, 0x03, 0x00, 0x00, 0x07, on};
|
||||
return bw_send_command(device, cmd, sizeof cmd);
|
||||
}
|
||||
|
||||
/** Set whether the macro LED should blink. */
|
||||
/// Set whether the macro LED should blink.
|
||||
static int
|
||||
bw_set_macro_led_blinking (libusb_device_handle *device, bool blinking)
|
||||
bw_set_macro_led_blinking(libusb_device_handle *device, bool blinking)
|
||||
{
|
||||
unsigned char cmd[] = { 0x03, 0x03, 0x02, 0x00, 0x07, blinking };
|
||||
return bw_send_command (device, cmd, sizeof cmd);
|
||||
unsigned char cmd[] = {0x03, 0x03, 0x02, 0x00, 0x07, blinking};
|
||||
return bw_send_command(device, cmd, sizeof cmd);
|
||||
}
|
||||
|
||||
/** Set the gaming mode (whether the Windows key should be ignored). */
|
||||
/// Set the gaming mode (whether the Windows key should be ignored).
|
||||
static int
|
||||
bw_set_gaming_mode (libusb_device_handle *device, bool on)
|
||||
bw_set_gaming_mode(libusb_device_handle *device, bool on)
|
||||
{
|
||||
unsigned char cmd[] = { 0x03, 0x03, 0x00, 0x01, 0x08, on };
|
||||
return bw_send_command (device, cmd, sizeof cmd);
|
||||
unsigned char cmd[] = {0x03, 0x03, 0x00, 0x01, 0x08, on};
|
||||
return bw_send_command(device, cmd, sizeof cmd);
|
||||
}
|
||||
|
||||
// --- Control utility ---------------------------------------------------------
|
||||
|
||||
struct options
|
||||
{
|
||||
struct options {
|
||||
unsigned set_led_mode : 1;
|
||||
unsigned set_led_brightness : 1;
|
||||
unsigned set_macro_led_on : 1;
|
||||
@ -179,249 +167,217 @@ struct options
|
||||
};
|
||||
|
||||
static void
|
||||
show_usage (const char *program_name)
|
||||
show_usage(const char *program_name)
|
||||
{
|
||||
printf ("Usage: %s [OPTION]...\n", program_name);
|
||||
printf ("Configure Razer BlackWidow Tournament Edition devices.\n\n");
|
||||
printf (" -h, --help Show this help\n");
|
||||
printf (" --version Show program version and exit\n");
|
||||
printf (" --led-mode X Set the mode of the Razer logo LED"
|
||||
" (can be 'normal', 'blink' or 'pulsate')\n");
|
||||
printf (" --led-brightness X Set Razer logo LED brightness"
|
||||
" (from 0 to 255)\n");
|
||||
printf (" --macro-led X Set the macro LED mode"
|
||||
" ('off', 'on' or 'blink')\n");
|
||||
printf (" --gaming-mode BOOL Set whether the Windows key is ignored\n");
|
||||
printf ("\n");
|
||||
printf("Usage: %s [OPTION]...\n", program_name);
|
||||
printf("Configure Razer BlackWidow Tournament Edition devices.\n\n");
|
||||
printf(" -h, --help Show this help\n");
|
||||
printf(" --version Show program version and exit\n");
|
||||
printf(" --led-mode X Set the mode of the Razer logo LED"
|
||||
" (can be 'normal', 'blink' or 'pulsate')\n");
|
||||
printf(" --led-brightness X Set Razer logo LED brightness"
|
||||
" (from 0 to 255)\n");
|
||||
printf(" --macro-led X Set the macro LED mode"
|
||||
" ('off', 'on' or 'blink')\n");
|
||||
printf(" --gaming-mode BOOL Set whether the Windows key is ignored\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
parse_options (int argc, char *argv[],
|
||||
parse_options(int argc, char *argv[],
|
||||
struct options *options, struct bw_config *new_config)
|
||||
{
|
||||
static struct option long_opts[] =
|
||||
{
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "version", no_argument, 0, 'V' },
|
||||
{ "led-mode", required_argument, 0, 'l' },
|
||||
{ "led-brightness", required_argument, 0, 'L' },
|
||||
{ "macro-led", required_argument, 0, 'm' },
|
||||
{ "gaming-mode", required_argument, 0, 'g' },
|
||||
{ 0, 0, 0, 0 }
|
||||
static struct option long_opts[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"led-mode", required_argument, 0, 'l'},
|
||||
{"led-brightness", required_argument, 0, 'L'},
|
||||
{"macro-led", required_argument, 0, 'm'},
|
||||
{"gaming-mode", required_argument, 0, 'g'},
|
||||
{0}
|
||||
};
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
if (argc == 1) {
|
||||
show_usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int c;
|
||||
while ((c = getopt_long (argc, argv, "h", long_opts, NULL)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
while ((c = getopt_long(argc, argv, "h", long_opts, NULL)) != -1)
|
||||
switch (c) {
|
||||
case 'h':
|
||||
show_usage (argv[0]);
|
||||
exit (EXIT_SUCCESS);
|
||||
show_usage(argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'V':
|
||||
printf (PROGRAM_NAME " " PROGRAM_VERSION "\n");
|
||||
exit (EXIT_SUCCESS);
|
||||
printf(PROGRAM_NAME " " PROGRAM_VERSION "\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'l':
|
||||
if (!strcasecmp (optarg, "normal"))
|
||||
if (!strcasecmp(optarg, "normal")) {
|
||||
new_config->led_mode = LED_BRIGHTNESS;
|
||||
else if (!strcasecmp (optarg, "blink"))
|
||||
} else if (!strcasecmp(optarg, "blink")) {
|
||||
new_config->led_mode = LED_BLINK;
|
||||
else if (!strcasecmp (optarg, "pulsate"))
|
||||
} else if (!strcasecmp(optarg, "pulsate")) {
|
||||
new_config->led_mode = LED_PULSATE;
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "Error: invalid LED mode: %s\n", optarg);
|
||||
exit (EXIT_FAILURE);
|
||||
} else {
|
||||
fprintf(stderr, "Error: invalid LED mode: %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
options->set_led_mode = true;
|
||||
break;
|
||||
case 'L':
|
||||
{
|
||||
case 'L': {
|
||||
char *end;
|
||||
long bri = strtol (optarg, &end, 10);
|
||||
if (!*optarg || *end || bri < 0 || bri > 255)
|
||||
{
|
||||
fprintf (stderr, "Error: invalid LED brightness value\n");
|
||||
exit (EXIT_FAILURE);
|
||||
long bri = strtol(optarg, &end, 10);
|
||||
if (!*optarg || *end || bri < 0 || bri > 255) {
|
||||
fprintf(stderr, "Error: invalid LED brightness value\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
options->set_led_brightness = true;
|
||||
break;
|
||||
}
|
||||
case 'm':
|
||||
if (!strcasecmp (optarg, "off"))
|
||||
{
|
||||
if (!strcasecmp(optarg, "off")) {
|
||||
new_config->macro_led_on = false;
|
||||
new_config->macro_led_blinking = false;
|
||||
}
|
||||
else if (!strcasecmp (optarg, "blink"))
|
||||
{
|
||||
} else if (!strcasecmp(optarg, "blink")) {
|
||||
new_config->macro_led_on = true;
|
||||
new_config->macro_led_blinking = true;
|
||||
}
|
||||
else if (!strcasecmp (optarg, "on"))
|
||||
{
|
||||
} else if (!strcasecmp(optarg, "on")) {
|
||||
new_config->macro_led_on = true;
|
||||
new_config->macro_led_blinking = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "Error: invalid macro LED mode: %s\n", optarg);
|
||||
exit (EXIT_FAILURE);
|
||||
} else {
|
||||
fprintf(stderr, "Error: invalid macro LED mode: %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
options->set_macro_led_blinking = true;
|
||||
options->set_macro_led_on = true;
|
||||
break;
|
||||
case 'g':
|
||||
if (!strcasecmp (optarg, "true")
|
||||
|| !strcasecmp (optarg, "on")
|
||||
|| !strcasecmp (optarg, "yes"))
|
||||
if (!strcasecmp(optarg, "true") ||
|
||||
!strcasecmp(optarg, "on") ||
|
||||
!strcasecmp(optarg, "yes")) {
|
||||
new_config->gaming_mode = true;
|
||||
else if (!strcasecmp (optarg, "false")
|
||||
|| !strcasecmp (optarg, "off")
|
||||
|| !strcasecmp (optarg, "no"))
|
||||
} else if (!strcasecmp (optarg, "false") ||
|
||||
!strcasecmp(optarg, "off") ||
|
||||
!strcasecmp(optarg, "no")) {
|
||||
new_config->gaming_mode = false;
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "Error: invalid gaming mode"
|
||||
} else {
|
||||
fprintf(stderr, "Error: invalid gaming mode"
|
||||
" setting: %s\n", optarg);
|
||||
exit (EXIT_FAILURE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
options->set_gaming_mode = true;
|
||||
break;
|
||||
case '?':
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
fprintf (stderr, "Error: extra parameters\n");
|
||||
exit (EXIT_FAILURE);
|
||||
if (optind < argc) {
|
||||
fprintf(stderr, "Error: extra parameters\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
apply_options (libusb_device_handle *device,
|
||||
apply_options(libusb_device_handle *device,
|
||||
struct options *options, struct bw_config *new_config)
|
||||
{
|
||||
int result;
|
||||
int result = 0;
|
||||
|
||||
if (options->set_led_mode)
|
||||
if ((result = bw_set_led_mode
|
||||
(device, new_config->led_mode)))
|
||||
if ((result = bw_set_led_mode(
|
||||
device, new_config->led_mode)))
|
||||
return result;
|
||||
if (options->set_led_brightness)
|
||||
if ((result = bw_set_led_brightness
|
||||
(device, new_config->led_brightness)))
|
||||
if ((result = bw_set_led_brightness(
|
||||
device, new_config->led_brightness)))
|
||||
return result;
|
||||
|
||||
if (options->set_macro_led_on)
|
||||
if ((result = bw_set_macro_led
|
||||
(device, new_config->macro_led_on)))
|
||||
if ((result = bw_set_macro_led(
|
||||
device, new_config->macro_led_on)))
|
||||
return result;
|
||||
if (options->set_macro_led_blinking)
|
||||
if ((result = bw_set_macro_led_blinking
|
||||
(device, new_config->macro_led_blinking)))
|
||||
if ((result = bw_set_macro_led_blinking(
|
||||
device, new_config->macro_led_blinking)))
|
||||
return result;
|
||||
|
||||
if (options->set_gaming_mode)
|
||||
if ((result = bw_set_gaming_mode
|
||||
(device, new_config->gaming_mode)))
|
||||
if ((result = bw_set_gaming_mode(
|
||||
device, new_config->gaming_mode)))
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ERROR(label, ...) \
|
||||
do { \
|
||||
fprintf (stderr, "Error: " __VA_ARGS__); \
|
||||
status = 1; \
|
||||
goto label; \
|
||||
#define ERROR(label, ...) \
|
||||
do { \
|
||||
fprintf(stderr, "Error: " __VA_ARGS__); \
|
||||
status = 1; \
|
||||
goto label; \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct options options = { 0 };
|
||||
struct bw_config new_config = { 0 };
|
||||
struct options options = {0};
|
||||
struct bw_config new_config = {0};
|
||||
|
||||
parse_options (argc, argv, &options, &new_config);
|
||||
parse_options(argc, argv, &options, &new_config);
|
||||
|
||||
int result, status = 0;
|
||||
|
||||
result = libusb_init (NULL);
|
||||
if (result)
|
||||
ERROR (error_0, "libusb initialisation failed: %s\n",
|
||||
libusb_error_name (result));
|
||||
if ((result = libusb_init(NULL)))
|
||||
ERROR(error_0, "libusb initialisation failed: %s\n",
|
||||
libusb_error_name(result));
|
||||
|
||||
result = 0;
|
||||
libusb_device_handle *device = find_device
|
||||
(USB_VENDOR_RAZER, USB_PRODUCT_RAZER_BW_TE, &result);
|
||||
if (!device)
|
||||
{
|
||||
libusb_device_handle *device =
|
||||
find_device(USB_VENDOR_RAZER, USB_PRODUCT_RAZER_BW_TE, &result);
|
||||
if (!device) {
|
||||
if (result)
|
||||
ERROR (error_1, "couldn't open device: %s\n",
|
||||
libusb_error_name (result));
|
||||
ERROR(error_1, "couldn't open device: %s\n",
|
||||
libusb_error_name(result));
|
||||
else
|
||||
ERROR (error_1, "no suitable device found\n");
|
||||
ERROR(error_1, "no suitable device found\n");
|
||||
}
|
||||
|
||||
bool reattach_driver = false;
|
||||
|
||||
result = libusb_kernel_driver_active (device, BW_CTL_IFACE);
|
||||
switch (result)
|
||||
{
|
||||
switch ((result = libusb_kernel_driver_active(device, BW_CTL_IFACE))) {
|
||||
case 0:
|
||||
case LIBUSB_ERROR_NOT_SUPPORTED:
|
||||
break;
|
||||
case 1:
|
||||
reattach_driver = true;
|
||||
result = libusb_detach_kernel_driver (device, BW_CTL_IFACE);
|
||||
if (result)
|
||||
ERROR (error_2, "couldn't detach kernel driver: %s\n",
|
||||
libusb_error_name (result));
|
||||
if ((result = libusb_detach_kernel_driver(device, BW_CTL_IFACE)))
|
||||
ERROR(error_2, "couldn't detach kernel driver: %s\n",
|
||||
libusb_error_name(result));
|
||||
break;
|
||||
default:
|
||||
ERROR (error_2, "coudn't detect kernel driver presence: %s\n",
|
||||
libusb_error_name (result));
|
||||
ERROR(error_2, "coudn't detect kernel driver presence: %s\n",
|
||||
libusb_error_name(result));
|
||||
}
|
||||
|
||||
result = libusb_claim_interface (device, BW_CTL_IFACE);
|
||||
if (result)
|
||||
ERROR (error_3, "couldn't claim interface: %s\n",
|
||||
libusb_error_name (result));
|
||||
if ((result = libusb_claim_interface(device, BW_CTL_IFACE)))
|
||||
ERROR(error_3, "couldn't claim interface: %s\n",
|
||||
libusb_error_name(result));
|
||||
|
||||
result = apply_options (device, &options, &new_config);
|
||||
if (result)
|
||||
ERROR (error_4, "operation failed: %s\n",
|
||||
if ((result = apply_options(device, &options, &new_config)))
|
||||
ERROR(error_4, "operation failed: %s\n",
|
||||
libusb_error_name (result));
|
||||
|
||||
error_4:
|
||||
result = libusb_release_interface (device, BW_CTL_IFACE);
|
||||
if (result)
|
||||
ERROR (error_3, "couldn't release interface: %s\n",
|
||||
libusb_error_name (result));
|
||||
|
||||
if ((result = libusb_release_interface(device, BW_CTL_IFACE)))
|
||||
ERROR(error_3, "couldn't release interface: %s\n",
|
||||
libusb_error_name(result));
|
||||
error_3:
|
||||
if (reattach_driver)
|
||||
{
|
||||
result = libusb_attach_kernel_driver (device, BW_CTL_IFACE);
|
||||
if (result)
|
||||
ERROR (error_2, "couldn't reattach kernel driver: %s\n",
|
||||
libusb_error_name (result));
|
||||
if (reattach_driver) {
|
||||
if ((result = libusb_attach_kernel_driver(device, BW_CTL_IFACE)))
|
||||
ERROR(error_2, "couldn't reattach kernel driver: %s\n",
|
||||
libusb_error_name(result));
|
||||
}
|
||||
|
||||
error_2:
|
||||
libusb_close (device);
|
||||
libusb_close(device);
|
||||
error_1:
|
||||
libusb_exit (NULL);
|
||||
libusb_exit(NULL);
|
||||
error_0:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user