3 # Reads /proc/bus/usb/devices and selectively lists and/or
6 # Originally written by Randy Dunlap.
9 $DEVFILENAME = "/proc/bus/usb/devices";
12 if (! open (DEVNUM, "<$DEVFILENAME"))
14 print "$PROGNAME: cannot open '$DEVFILENAME'\n";
20 while ($line = <DEVNUM>) # read a text line from DEVNUM
22 # skip all lines except those we recognize:
23 if (($line !~ "^C:") # Configuration: one is active
24 && ($line !~ "^D:") # Device:
25 && ($line !~ "^I:") # Interface: protocol group
26 && ($line !~ "^S:") # String: used with root hub
27 && ($line !~ "^T:") # Topology: starts each device
30 next; # to the next line
33 chomp $line; # remove line endings
35 # First convert '=' signs to spaces.
38 # and convert all '(' and ')' to spaces.
42 # split the line at spaces.
43 @fields = split / +/, $line;
45 # T: Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 3 Spd=1.5 MxCh= 0
48 # split yields: $bus, $level, $parent, $port, $count, $devnum, $speed, $maxchild.
52 $parent = @fields [6]; # parent devnum
53 $port = @fields [8] + 1; # make $port 1-based
54 $count = @fields [10];
55 $devnum = @fields [12];
56 $speed = @fields [14];
57 $maxchild = @fields [16];
62 $showclass = "?"; # derived from $devclass or $intclass
63 $lastif = "?"; # show only first altsetting
70 # only show the _active_ configuration
71 # C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
72 elsif ( $line =~ "^C:" ) {
73 if ( $line =~ "^C:\\*" ) {
74 $showconfig = @fields[4];
81 # D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
82 elsif ($line =~ "^D:")
84 $devclass = @fields [5];
85 $nconfig = @fields [13];
89 # in case this is a root hub, look at the device strings.
90 # - S: Manufacturer:Linux 2.6.5 ehci_hcd [all 2.6]
91 # - S: Product=USB UHCI Root Hub [all 2.4, 2.2]
92 # - S: Product=OPTi Inc 82C861 [2.6/PCI_NAMES]
93 elsif ( $line =~ "^S:" )
95 if ( $level == 00 && $line =~ "hcd" )
97 $HCtype = @fields [4];
99 elsif ( $level == 00 && $line =~ "HCI" && $HCtype eq "?")
101 $HCtype = @fields [3];
106 # the rest of this code:
107 # - only shows interface descriptors
108 # - for the active configuration
109 # - for the first (prefer: active!) altsetting
110 elsif ( ! ( $line =~ "^I:" )
111 || "$showconfig" eq "no") {
116 # I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=hid
117 $intclass = @fields [9];
118 $ifnum = @fields [2];
119 $driver = @fields [15];
121 if (($devclass eq ">ifc") || ($devclass eq "unk."))
122 { # then use InterfaceClass, not DeviceClass
123 $showclass = $intclass;
127 $showclass = $devclass;
132 # substitute real driver name
133 if ( $HCtype =~ "UHCI-alt" )
137 elsif ( $HCtype =~ "UHCI" )
141 elsif ( $HCtype =~ "OHCI" )
150 print sprintf ("/: Bus $bus.Port $port: Dev $devnum, Class=root_hub, Driver=%s/%sp, %sM\n",
151 $HC, $maxchild, $speed );
153 elsif ($lastif ne $ifnum)
162 if ($nconfig ne "1") {
163 $temp = " Cfg $showconfig/$nconfig";
168 print sprintf ("|__ Port $port: Dev $devnum$temp, If $ifnum, Class=$showclass, Driver=$driver%s, %sM\n",
169 ($maxchild == 0) ? "" : ("/" . $maxchild . "p"),