@@ -223,6 +223,9 @@ static int opt_force = 0; /* force operation even on unsupported hubs */
223223static int opt_nodesc = 0 ; /* skip querying device description */
224224#if defined(__gnu_linux__ ) || defined(__linux__ )
225225static int opt_nosysfs = 0 ; /* don't use the Linux sysfs port disable interface, even if available */
226+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000107 )
227+ static const char * opt_sysdev ;
228+ #endif
226229#endif
227230
228231/* For Raspberry Pi detection and workarounds: */
@@ -232,8 +235,12 @@ static int is_rpi_5 = 0;
232235static const char short_options [] =
233236 "l:L:n:a:p:d:r:w:s:hvefRN"
234237#if defined(__gnu_linux__ ) || defined(__linux__ )
238+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000107 )
239+ "Sy:"
240+ #else
235241 "S"
236242#endif
243+ #endif
237244;
238245
239246static const struct option long_options [] = {
@@ -251,6 +258,9 @@ static const struct option long_options[] = {
251258 { "nodesc" , no_argument , NULL , 'N' },
252259#if defined(__gnu_linux__ ) || defined (__linux__ )
253260 { "nosysfs" , no_argument , NULL , 'S' },
261+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000107 )
262+ { "sysdev" , required_argument , NULL , 'y' },
263+ #endif
254264#endif
255265 { "reset" , no_argument , NULL , 'R' },
256266 { "version" , no_argument , NULL , 'v' },
@@ -280,6 +290,9 @@ static int print_usage(void)
280290 "--nodesc, -N - do not query device description (helpful for unresponsive devices).\n"
281291#if defined(__gnu_linux__ ) || defined (__linux__ )
282292 "--nosysfs, -S - do not use the Linux sysfs port disable interface.\n"
293+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000107 )
294+ "--sysdev, -y - open system device node instead of scanning.\n"
295+ #endif
283296#endif
284297 "--reset, -R - reset hub after each power-on action, causing all devices to reassociate.\n"
285298 "--wait, -w - wait before repeat power off [%d ms].\n"
@@ -1099,6 +1112,11 @@ int main(int argc, char *argv[])
10991112 int rc ;
11001113 int c = 0 ;
11011114 int option_index = 0 ;
1115+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000107 ) && \
1116+ (defined(__gnu_linux__ ) || defined(__linux__ ))
1117+ int sys_fd ;
1118+ libusb_device_handle * sys_devh = NULL ;
1119+ #endif
11021120
11031121 for (;;) {
11041122 c = getopt_long (argc , argv , short_options , long_options , & option_index );
@@ -1167,6 +1185,11 @@ int main(int argc, char *argv[])
11671185 case 'S' :
11681186 opt_nosysfs = 1 ;
11691187 break ;
1188+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000107 )
1189+ case 'y' :
1190+ opt_sysdev = optarg ;
1191+ break ;
1192+ #endif
11701193#endif
11711194 case 'e' :
11721195 opt_exact = 1 ;
@@ -1209,7 +1232,36 @@ int main(int argc, char *argv[])
12091232 exit (1 );
12101233 }
12111234
1235+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000107 ) && \
1236+ (defined(__gnu_linux__ ) || defined(__linux__ ))
1237+ if (opt_sysdev ) {
1238+ sys_fd = open (opt_sysdev , O_RDWR );
1239+ if (sys_fd < 0 ) {
1240+ fprintf (stderr , "Cannot open system node!\n" );
1241+ rc = 1 ;
1242+ goto cleanup ;
1243+ }
1244+ rc = libusb_wrap_sys_device (NULL , sys_fd , & sys_devh );
1245+ if (rc != 0 ) {
1246+ fprintf (stderr ,
1247+ "Cannot use %s as USB hub device, failed to wrap system node!\n" ,
1248+ opt_sysdev );
1249+ rc = 1 ;
1250+ goto cleanup ;
1251+ }
1252+ usb_devs = calloc (2 , sizeof * usb_devs );
1253+ if (!usb_devs ) {
1254+ fprintf (stderr , "Out of memory\n" );
1255+ rc = 1 ;
1256+ goto cleanup ;
1257+ }
1258+ usb_devs [0 ] = libusb_get_device (sys_devh );
1259+ } else {
1260+ rc = libusb_get_device_list (NULL , & usb_devs );
1261+ }
1262+ #else
12121263 rc = libusb_get_device_list (NULL , & usb_devs );
1264+ #endif
12131265 if (rc < 0 ) {
12141266 fprintf (stderr ,
12151267 "Cannot enumerate USB devices!\n"
@@ -1315,8 +1367,19 @@ int main(int argc, char *argv[])
13151367 }
13161368 rc = 0 ;
13171369cleanup :
1370+ #if defined(LIBUSB_API_VERSION ) && (LIBUSB_API_VERSION >= 0x01000107 ) && \
1371+ (defined(__gnu_linux__ ) || defined(__linux__ ))
1372+ if (opt_sysdev && sys_fd >= 0 ) {
1373+ if (sys_devh )
1374+ libusb_close (sys_devh );
1375+ close (sys_fd );
1376+ free (usb_devs );
1377+ } else if (usb_devs )
1378+ libusb_free_device_list (usb_devs , 1 );
1379+ #else
13181380 if (usb_devs )
13191381 libusb_free_device_list (usb_devs , 1 );
1382+ #endif
13201383 usb_devs = NULL ;
13211384 libusb_exit (NULL );
13221385 return rc ;
0 commit comments