#!/usr/bin/perl # # Reads /proc/bus/usb/devices and selectively lists and/or # interprets it. # # Originally written by Randy Dunlap. # $DEVFILENAME = "/proc/bus/usb/devices"; $PROGNAME = $0; if (! open (DEVNUM, "<$DEVFILENAME")) { print "$PROGNAME: cannot open '$DEVFILENAME'\n"; exit 1; } while ($line = ) # read a text line from DEVNUM { # skip all lines except those that begin with "T:", "S:", "D:" or "I:". if (($line !~ "^T:") && ($line !~ "^I:") && ($line !~ "^D:") && ($line !~ "^S:")) { next; # to the next line } chomp $line; # remove line endings # First convert '=' signs to spaces. $line =~ tr/=/ /; # and convert all '(' and ')' to spaces. $line =~ tr/(/ /; $line =~ tr/)/ /; # split the line at spaces. @fields = split / +/, $line; if ($line =~ "^T:") { # split yields: $bus, $level, $parent, $port, $count, $devnum, $speed, $maxchild. $bus = @fields [2]; $level = @fields [4]; $parent = @fields [6]; # parent devnum $port = @fields [8] + 1; # make $port 1-based $count = @fields [10]; $devnum = @fields [12]; $speed = @fields [14]; $maxchild = @fields [16]; $devclass = "?"; $intclass = "?"; $driver = "?"; $ifnum = "?"; $showclass = "?"; # derived from $devclass or $intclass $lastif = "?"; # show only first altsetting $HCtype = "?"; next; } # end T: line elsif ($line =~ "^D:") { # for D: line $devclass = @fields [5]; next; } elsif ( $line =~ "^S:" ) { # for S: line if ( $level == 00 && $line =~ "hcd" ) { $HCtype = @fields [4]; } elsif ( $level == 00 && $line =~ "HCI" ) { $HCtype = @fields [3]; } next; } else { # for I: line $intclass = @fields [9]; $ifnum = @fields [2]; $driver = @fields [15]; } # end I: line if (($devclass eq ">ifc") || ($devclass eq "unk.")) { # then use InterfaceClass, not DeviceClass $showclass = $intclass; $show = "interface"; } else { # use DeviceClass $showclass = $devclass; $show = "device"; } if ($level == 0) { # substitute read driver name if ( $HCtype =~ "UHCI-alt" ) { $HC = "uhci"; } elsif ( $HCtype =~ "UHCI" ) { $HC = "usb-uhci"; } elsif ( $HCtype =~ "OHCI" ) { $HC = "usb-ohci"; } else { $HC = $HCtype; } print sprintf ("/: Bus $bus.Port $port: Dev $devnum, Class=root_hub, Driver=%s/%sp, %sM\n", $HC, $maxchild, $speed ); } elsif ($show eq "device" || $lastif ne $ifnum) { $temp = $level; while ($temp >= 1) { print " "; $temp--; } print sprintf ("|__ Port $port: Dev $devnum, If $ifnum, Class=$showclass, Driver=$driver%s, %sM\n", ($maxchild == 0) ? "" : ("/" . $maxchild . "p"), $speed); $lastif = $ifnum; } } # end while DEVNUM close (DEVNUM); # END.