mirror of
https://github.com/mvp/uhubctl.git
synced 2026-05-17 00:16:13 +03:00
Add --sysdev/-y option for direct device node access (#600)
* Add --sysdev/-u option for direct device node access Only the device specified by the given device path will be accessed, instead of scanning the USB bus. Most useful if you use udev rules to create stable device node aliases for hubs, independent of bus topology. For instance, if your matching udev rules include SYMLINK+="MYSMARTHUB1" you can call uhubctl with --sysdev /dev/MYSMARTHUB1 instead of using -l and a non-stable bus location to specify it. Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
This commit is contained in:
63
uhubctl.c
63
uhubctl.c
@@ -223,6 +223,9 @@ static int opt_force = 0; /* force operation even on unsupported hubs */
|
||||
static int opt_nodesc = 0; /* skip querying device description */
|
||||
#if defined(__gnu_linux__) || defined(__linux__)
|
||||
static int opt_nosysfs = 0; /* don't use the Linux sysfs port disable interface, even if available */
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000107)
|
||||
static const char *opt_sysdev;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* For Raspberry Pi detection and workarounds: */
|
||||
@@ -232,8 +235,12 @@ static int is_rpi_5 = 0;
|
||||
static const char short_options[] =
|
||||
"l:L:n:a:p:d:r:w:s:hvefRN"
|
||||
#if defined(__gnu_linux__) || defined(__linux__)
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000107)
|
||||
"Sy:"
|
||||
#else
|
||||
"S"
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
|
||||
static const struct option long_options[] = {
|
||||
@@ -251,6 +258,9 @@ static const struct option long_options[] = {
|
||||
{ "nodesc", no_argument, NULL, 'N' },
|
||||
#if defined(__gnu_linux__) || defined(__linux__)
|
||||
{ "nosysfs", no_argument, NULL, 'S' },
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000107)
|
||||
{ "sysdev", required_argument, NULL, 'y' },
|
||||
#endif
|
||||
#endif
|
||||
{ "reset", no_argument, NULL, 'R' },
|
||||
{ "version", no_argument, NULL, 'v' },
|
||||
@@ -280,6 +290,9 @@ static int print_usage(void)
|
||||
"--nodesc, -N - do not query device description (helpful for unresponsive devices).\n"
|
||||
#if defined(__gnu_linux__) || defined(__linux__)
|
||||
"--nosysfs, -S - do not use the Linux sysfs port disable interface.\n"
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000107)
|
||||
"--sysdev, -y - open system device node instead of scanning.\n"
|
||||
#endif
|
||||
#endif
|
||||
"--reset, -R - reset hub after each power-on action, causing all devices to reassociate.\n"
|
||||
"--wait, -w - wait before repeat power off [%d ms].\n"
|
||||
@@ -1099,6 +1112,11 @@ int main(int argc, char *argv[])
|
||||
int rc;
|
||||
int c = 0;
|
||||
int option_index = 0;
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000107) && \
|
||||
(defined(__gnu_linux__) || defined(__linux__))
|
||||
int sys_fd;
|
||||
libusb_device_handle *sys_devh = NULL;
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
c = getopt_long(argc, argv, short_options, long_options, &option_index);
|
||||
@@ -1167,6 +1185,11 @@ int main(int argc, char *argv[])
|
||||
case 'S':
|
||||
opt_nosysfs = 1;
|
||||
break;
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000107)
|
||||
case 'y':
|
||||
opt_sysdev = optarg;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
case 'e':
|
||||
opt_exact = 1;
|
||||
@@ -1209,7 +1232,36 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000107) && \
|
||||
(defined(__gnu_linux__) || defined(__linux__))
|
||||
if (opt_sysdev) {
|
||||
sys_fd = open(opt_sysdev, O_RDWR);
|
||||
if (sys_fd < 0) {
|
||||
fprintf(stderr, "Cannot open system node!\n");
|
||||
rc = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
rc = libusb_wrap_sys_device(NULL, sys_fd, &sys_devh);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr,
|
||||
"Cannot use %s as USB hub device, failed to wrap system node!\n",
|
||||
opt_sysdev);
|
||||
rc = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
usb_devs = calloc(2, sizeof *usb_devs);
|
||||
if (!usb_devs) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
rc = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
usb_devs[0] = libusb_get_device(sys_devh);
|
||||
} else {
|
||||
rc = libusb_get_device_list(NULL, &usb_devs);
|
||||
}
|
||||
#else
|
||||
rc = libusb_get_device_list(NULL, &usb_devs);
|
||||
#endif
|
||||
if (rc < 0) {
|
||||
fprintf(stderr,
|
||||
"Cannot enumerate USB devices!\n"
|
||||
@@ -1315,8 +1367,19 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
rc = 0;
|
||||
cleanup:
|
||||
#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000107) && \
|
||||
(defined(__gnu_linux__) || defined(__linux__))
|
||||
if (opt_sysdev && sys_fd >= 0) {
|
||||
if (sys_devh)
|
||||
libusb_close(sys_devh);
|
||||
close(sys_fd);
|
||||
free(usb_devs);
|
||||
} else if (usb_devs)
|
||||
libusb_free_device_list(usb_devs, 1);
|
||||
#else
|
||||
if (usb_devs)
|
||||
libusb_free_device_list(usb_devs, 1);
|
||||
#endif
|
||||
usb_devs = NULL;
|
||||
libusb_exit(NULL);
|
||||
return rc;
|
||||
|
||||
Reference in New Issue
Block a user