From b3464843dd559dfb33a5e1936cba6b854355cce9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 7 Dec 2010 12:30:27 -0200 Subject: [PATCH] parse_sn9c201.pl: Add a parser for sn9c201 USB dumps Signed-off-by: Mauro Carvalho Chehab --- contrib/sn9c201/parse_sn9c201.pl | 139 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100755 contrib/sn9c201/parse_sn9c201.pl diff --git a/contrib/sn9c201/parse_sn9c201.pl b/contrib/sn9c201/parse_sn9c201.pl new file mode 100755 index 0000000..b402433 --- /dev/null +++ b/contrib/sn9c201/parse_sn9c201.pl @@ -0,0 +1,139 @@ +#!/usr/bin/perl +use strict; + +# Copyright (C) 2010 Mauro Carvalho Chehab +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# This small script parses USB dumps generated by several drivers, +# decoding USB bits. +# +# To use it, do: +# dmesg | ./parse_usb.pl +# +# Also, there are other utilities that produce similar outputs, and it +# is not hard to parse some USB analyzers log into the expected format. +# + +sub i2c_reg($) +{ + my %decode; + my $reg = shift; + + $reg =~ s/\s+.*//; + $reg = hex("$reg"); + + if ($reg & 0x01) { + $decode{"speed"} = "400kbps"; + } else { + $decode{"speed"} = "100kbps"; + } + if ($reg & 0x02) { + $decode{"op"} = "RD"; + } else { + $decode{"op"} = "WR"; + } + $decode{"busy"} = "BUSY" if (($reg & 0x04) == 0); + $decode{"err"} = "ERR" if ($reg & 0x08); + $decode{"size"} = ($reg >> 4) & 7; + $decode{"i2c"} = "3wire" if (($reg & 0x80) == 0); + + return %decode; +} + +sub type_req($) +{ + my $reqtype = shift; + my $s; + + if ($reqtype & 0x80) { + $s = "RD "; + } else { + $s = "WR "; + } + if (($reqtype & 0x60) == 0x20) { + $s .= "CLAS "; + } elsif (($reqtype & 0x60) == 0x40) { + $s .= "VEND "; + } elsif (($reqtype & 0x60) == 0x60) { + $s .= "RSVD "; + } + + if (($reqtype & 0x1f) == 0x00) { + $s .= "DEV "; + } elsif (($reqtype & 0x1f) == 0x01) { + $s .= "INT "; + } elsif (($reqtype & 0x1f) == 0x02) { + $s .= "EP "; + } elsif (($reqtype & 0x1f) == 0x03) { + $s .= "OTHER "; + } elsif (($reqtype & 0x1f) == 0x04) { + $s .= "PORT "; + } elsif (($reqtype & 0x1f) == 0x05) { + $s .= "RPIPE "; + } else { + $s .= sprintf "RECIP 0x%02x ", $reqtype & 0x1f; + } + + $s =~ s/\s+$//; + return $s; +} + +my %i2c; +my $i2c_id; +while (<>) { + tr/A-F/a-f/; + if (m/([0-9a-f].) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].) ([0-9a-f].)[\<\>\s]+(.*)/) { + my $reqtype = hex($1); + my $req = hex($2); + my $wvalue = hex("$4$3"); + my $windex = hex("$6$5"); + my $wlen = hex("$8$7"); + my $payload = $9; + my $fullpayload = $9; + + %i2c = i2c_reg($payload) if ($wvalue == 0x10c0); + + if (($wvalue >= 0x10c0) && ($wvalue <= 0x10c2)) { + my $reg = $wvalue; + if ($reg == 0x10c0) { + $payload =~ s/^([0-9a-f].)//; + $payload =~ s/^\s+//; + $reg++; + } + if ($reg == 0x10c1 && $payload ne "") { + $i2c_id = $payload; + $i2c_id =~ s/\s+.*//; + $i2c_id = "addr=0x$i2c_id, "; + $payload =~ s/^([0-9a-f].)//; + $payload =~ s/^\s+//; + $reg++; + } + +# my $data = $payload; +# $payload =~ + + my $s = sprintf "%s %s %s %s %s size=%d", + $i2c{"op"}, $i2c{"speed"}, $i2c{"busy"}, $i2c{"err"}, $i2c{"i2c"}, $i2c{"size"}; + $s =~ s/\s+/ /g; + + if ($reqtype & 0x80) { + printf "Read I2C: $s $i2c_id$payload\n"; + } else { + printf "I2C $s $i2c_id$payload\n"; + } + printf("\t%s, Req %3d, wValue: 0x%04x, wIndex 0x%04x, wlen %d: %s\n", + type_req($reqtype), $req, $wvalue, $windex, $wlen, $fullpayload); + } else { + printf("%s, Req %3d, wValue: 0x%04x, wIndex 0x%04x, wlen %d: %s\n", + type_req($reqtype), $req, $wvalue, $windex, $wlen, $payload); + } + } +} -- 2.7.4