| #!/bin/bash |
| |
| # Copyright: 2009 Greg Kroah-Hartman <greg@kroah.com> |
| # 2009 Randy Dunlap <rdunlap@xenotime.net> |
| # 2009 Frans Pop <elendil@planet.nl> |
| # |
| # This software may be used and distributed according to the terms of |
| # the GNU General Public License (GPL), version 2, or at your option |
| # any later version. |
| |
| print_string() { |
| file=$1 |
| name=$2 |
| if [ -f $file ]; then |
| echo "S: $name=`cat $file`" |
| fi |
| } |
| |
| class_decode() { |
| local class=$1 # v4: in hex |
| |
| case $class in |
| "00") echo ">ifc " ;; |
| "01") echo "audio" ;; |
| "02") echo "commc" ;; |
| "03") echo "HID " ;; |
| "05") echo "PID " ;; |
| "06") echo "still" ;; |
| "07") echo "print" ;; |
| "08") echo "stor." ;; |
| "09") echo "hub " ;; |
| "0a") echo "data " ;; |
| "0b") echo "scard" ;; |
| "0d") echo "c-sec" ;; |
| "0e") echo "video" ;; |
| "0f") echo "perhc" ;; |
| "dc") echo "diagd" ;; |
| "e0") echo "wlcon" ;; |
| "ef") echo "misc " ;; |
| "fe") echo "app. " ;; |
| "ff") echo "vend." ;; |
| "*") echo "unk. " ;; |
| esac |
| } |
| |
| print_endpoint() { |
| local eppath=$1 |
| |
| addr=`cat $eppath/bEndpointAddress` |
| attr=`cat $eppath/bmAttributes` |
| dir=`cat $eppath/direction` |
| eptype=`cat $eppath/type` |
| maxps_hex="0x`cat $eppath/wMaxPacketSize`" |
| # Extract MaxPS size (bits 0-10) and multiplicity values (bits 11-12) |
| maxps=`printf "%4i*%s\n" $(($maxps_hex & 0x7ff)) \ |
| $((1 + (($maxps_hex >> 11) & 0x3)))` |
| interval=`cat $eppath/interval` |
| |
| printf "E: Ad=%s(%s) Atr=%s(%s) MxPS=%s Ivl=%s\n" \ |
| $addr $dir $attr $eptype "$maxps" $interval |
| } |
| |
| print_interface() { |
| local ifpath=$1 |
| |
| ifnum=`cat $ifpath/bInterfaceNumber` |
| altset=`cat $ifpath/bAlternateSetting` |
| numeps=`cat $ifpath/bNumEndpoints` |
| class=`cat $ifpath/bInterfaceClass` |
| subclass=`cat $ifpath/bInterfaceSubClass` |
| protocol=`cat $ifpath/bInterfaceProtocol` |
| if [ -L $ifpath/driver ]; then # v4: allow for no driver |
| driver=`readlink $ifpath/driver` |
| driver=`basename $driver` |
| else |
| driver="(none)" |
| fi |
| classname=`class_decode $class` |
| printf "I: If#=%2i Alt=%2i #EPs=%2i Cls=%s(%s) Sub=%s Prot=%s Driver=%s\n" \ |
| $ifnum $altset $numeps $class "$classname" $subclass \ |
| $protocol $driver |
| |
| for endpoint in $ifpath/ep_?? |
| do |
| if [ -L $endpoint ]; then # v4: verify endpoint exists |
| print_endpoint $endpoint |
| fi |
| done |
| } |
| |
| print_device() { |
| local devpath=$1 |
| local parent=$2 |
| local level=$3 |
| local count=$4 |
| |
| [ -d $devpath ] || return |
| cd $devpath |
| |
| local busnum=`cat busnum` |
| local devnum=`cat devnum` |
| |
| if [ $level -gt 0 ]; then |
| port=$((${devpath##*[-.]} - 1)) |
| else |
| port=0 |
| fi |
| speed=`cat speed` |
| maxchild=`cat maxchild` |
| printf "\nT: Bus=%02i Lev=%02i Prnt=%02i Port=%02i Cnt=%02i Dev#=%3i Spd=%-3s MxCh=%2i\n" \ |
| $busnum $level $parent $port $count $devnum $speed $maxchild |
| |
| ver=`cat version` |
| devclass=`cat bDeviceClass` |
| devsubclass=`cat bDeviceSubClass` |
| devprotocol=`cat bDeviceProtocol` |
| maxps0=`cat bMaxPacketSize0` |
| numconfigs=`cat bNumConfigurations` |
| classname=`class_decode $devclass` |
| printf "D: Ver=%5s Cls=%s(%s) Sub=%s Prot=%s MxPS=%2i #Cfgs=%3i\n" \ |
| $ver $devclass "$classname" $devsubclass $devprotocol \ |
| $maxps0 $numconfigs |
| |
| vendid=`cat idVendor` |
| prodid=`cat idProduct` |
| revmajor=`cat bcdDevice | cut -c 1-2` |
| revminor=`cat bcdDevice | cut -c 3-4` |
| printf "P: Vendor=%s ProdID=%s Rev=%s.%s\n" \ |
| $vendid $prodid $revmajor $revminor |
| |
| print_string manufacturer "Manufacturer" |
| print_string product Product |
| print_string serial SerialNumber |
| |
| numifs=`cat bNumInterfaces` |
| cfgnum=`cat bConfigurationValue` |
| attr=`cat bmAttributes` |
| maxpower=`cat bMaxPower` |
| printf "C: #Ifs=%2i Cfg#=%2i Atr=%s MxPwr=%s\n" \ |
| $numifs $cfgnum $attr $maxpower |
| |
| # There's not really any useful info in endpoint 00 |
| #print_endpoint $devpath/ep_00 |
| |
| for interface in $busnum-*:?.* |
| do |
| print_interface $devpath/$interface |
| done |
| |
| local devcount=0 |
| for subdev in $busnum-* |
| do |
| echo "$subdev" | grep -Eq "^$busnum-[0-9]+(\.[0-9]+)*$" \ |
| || continue |
| |
| devcount=$(($devcount + 1)) |
| if [ -d $devpath/$subdev ]; then |
| print_device $devpath/$subdev \ |
| $devnum $(($level +1)) $devcount |
| fi |
| done |
| } |
| |
| if [ ! -d /sys/bus ]; then |
| echo "Error: directory /sys/bus does not exist; is sysfs mounted?" >&2 |
| exit 1 |
| fi |
| |
| for device in /sys/bus/usb/devices/usb* |
| do |
| print_device $device 0 0 0 |
| done |