summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Makefile3
-rw-r--r--scripts/bootgraph.pl16
-rwxr-xr-xscripts/checkpatch.pl172
-rwxr-xr-xscripts/config150
-rw-r--r--scripts/ihex2fw.c268
-rw-r--r--scripts/markup_oops.pl162
-rwxr-xr-xscripts/tags.sh18
8 files changed, 736 insertions, 54 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore
index b939fbd01195..09e2406f3b78 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,6 +1,7 @@
#
# Generated files
#
+ihex2fw
conmakehash
kallsyms
pnmtologo
diff --git a/scripts/Makefile b/scripts/Makefile
index aafdf064feef..035182e16afb 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -2,11 +2,12 @@
# scripts contains sources for various helper programs used throughout
# the kernel for the build process.
# ---------------------------------------------------------------------------
+# ihex2fw: Parser/loader for IHEX formatted data
# kallsyms: Find all symbols in vmlinux
# pnmttologo: Convert pnm files to logo files
-# conmakehash: Create chartable
# conmakehash: Create arrays for initializing the kernel console tables
+hostprogs-y := ihex2fw
hostprogs-$(CONFIG_KALLSYMS) += kallsyms
hostprogs-$(CONFIG_LOGO) += pnmtologo
hostprogs-$(CONFIG_VT) += conmakehash
diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
index f0af9aa9b243..0a498e33b30b 100644
--- a/scripts/bootgraph.pl
+++ b/scripts/bootgraph.pl
@@ -88,7 +88,7 @@ END
}
print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
-print "<svg width=\"1000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
+print "<svg width=\"2000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
my @styles;
@@ -105,8 +105,9 @@ $styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0
$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-my $mult = 950.0 / ($maxtime - $firsttime);
-my $threshold = ($maxtime - $firsttime) / 60.0;
+my $mult = 1950.0 / ($maxtime - $firsttime);
+my $threshold2 = ($maxtime - $firsttime) / 120.0;
+my $threshold = $threshold2/10;
my $stylecounter = 0;
my %rows;
my $rowscount = 1;
@@ -116,7 +117,7 @@ foreach my $key (@initcalls) {
my $duration = $end{$key} - $start{$key};
if ($duration >= $threshold) {
- my ($s, $s2, $e, $w, $y, $y2, $style);
+ my ($s, $s2, $s3, $e, $w, $y, $y2, $style);
my $pid = $pids{$key};
if (!defined($rows{$pid})) {
@@ -125,6 +126,7 @@ foreach my $key (@initcalls) {
}
$s = ($start{$key} - $firsttime) * $mult;
$s2 = $s + 6;
+ $s3 = $s + 1;
$e = ($end{$key} - $firsttime) * $mult;
$w = $e - $s;
@@ -138,7 +140,11 @@ foreach my $key (@initcalls) {
};
print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n";
- print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n";
+ if ($duration >= $threshold2) {
+ print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n";
+ } else {
+ print "<text transform=\"translate($s3,$y2) rotate(90)\" font-size=\"3pt\">$key</text>\n";
+ }
}
}
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index f88bb3e21cda..7bed4ed2c519 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1,7 +1,8 @@
#!/usr/bin/perl -w
# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit)
# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
-# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc)
+# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
+# (c) 2008, Andy Whitcroft <apw@canonical.com>
# Licensed under the terms of the GNU GPL License version 2
use strict;
@@ -9,7 +10,7 @@ use strict;
my $P = $0;
$P =~ s@.*/@@g;
-my $V = '0.24';
+my $V = '0.26';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -68,7 +69,9 @@ my $dbg_possible = 0;
my $dbg_type = 0;
my $dbg_attr = 0;
for my $key (keys %debug) {
- eval "\${dbg_$key} = '$debug{$key}';"
+ ## no critic
+ eval "\${dbg_$key} = '$debug{$key}';";
+ die "$@" if ($@);
}
if ($terse) {
@@ -116,7 +119,8 @@ our $Attribute = qr{
__(?:mem|cpu|dev|)(?:initdata|init)|
____cacheline_aligned|
____cacheline_aligned_in_smp|
- ____cacheline_internodealigned_in_smp
+ ____cacheline_internodealigned_in_smp|
+ __weak
}x;
our $Modifier;
our $Inline = qr{inline|__always_inline|noinline};
@@ -125,6 +129,7 @@ our $Lval = qr{$Ident(?:$Member)*};
our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
+our $Compare = qr{<=|>=|==|!=|<|>};
our $Operators = qr{
<=|>=|==|!=|
=>|->|<<|>>|<|>|!|~|
@@ -190,7 +195,7 @@ sub build_types {
}x;
$Type = qr{
$NonptrType
- (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
+ (?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)?
(?:\s+$Inline|\s+$Modifier)*
}x;
$Declare = qr{(?:$Storage\s+)?$Type};
@@ -203,9 +208,9 @@ my @dep_includes = ();
my @dep_functions = ();
my $removal = "Documentation/feature-removal-schedule.txt";
if ($tree && -f "$root/$removal") {
- open(REMOVE, "<$root/$removal") ||
+ open(my $REMOVE, '<', "$root/$removal") ||
die "$P: $removal: open failed - $!\n";
- while (<REMOVE>) {
+ while (<$REMOVE>) {
if (/^Check:\s+(.*\S)/) {
for my $entry (split(/[, ]+/, $1)) {
if ($entry =~ m@include/(.*)@) {
@@ -217,17 +222,21 @@ if ($tree && -f "$root/$removal") {
}
}
}
+ close($REMOVE);
}
my @rawlines = ();
my @lines = ();
my $vname;
for my $filename (@ARGV) {
+ my $FILE;
if ($file) {
- open(FILE, "diff -u /dev/null $filename|") ||
+ open($FILE, '-|', "diff -u /dev/null $filename") ||
die "$P: $filename: diff failed - $!\n";
+ } elsif ($filename eq '-') {
+ open($FILE, '<&STDIN');
} else {
- open(FILE, "<$filename") ||
+ open($FILE, '<', "$filename") ||
die "$P: $filename: open failed - $!\n";
}
if ($filename eq '-') {
@@ -235,11 +244,11 @@ for my $filename (@ARGV) {
} else {
$vname = $filename;
}
- while (<FILE>) {
+ while (<$FILE>) {
chomp;
push(@rawlines, $_);
}
- close(FILE);
+ close($FILE);
if (!process($filename)) {
$exit = 1;
}
@@ -366,7 +375,7 @@ sub sanitise_line {
}
}
- #print "SQ:$sanitise_quote\n";
+ #print "c<$c> SQ<$sanitise_quote>\n";
if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
substr($res, $off, 1, $;);
} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
@@ -402,6 +411,7 @@ sub ctx_statement_block {
my $type = '';
my $level = 0;
+ my @stack = ([$type, $level]);
my $p;
my $c;
my $len = 0;
@@ -433,6 +443,16 @@ sub ctx_statement_block {
$remainder = substr($blk, $off);
#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
+
+ # Handle nested #if/#else.
+ if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
+ push(@stack, [ $type, $level ]);
+ } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
+ ($type, $level) = @{$stack[$#stack - 1]};
+ } elsif ($remainder =~ /^#\s*endif\b/) {
+ ($type, $level) = @{pop(@stack)};
+ }
+
# Statement ends at the ';' or a close '}' at the
# outermost level.
if ($level == 0 && $c eq ';') {
@@ -579,11 +599,22 @@ sub ctx_block_get {
my @res = ();
my $level = 0;
+ my @stack = ($level);
for ($line = $start; $remain > 0; $line++) {
next if ($rawlines[$line] =~ /^-/);
$remain--;
$blk .= $rawlines[$line];
+
+ # Handle nested #if/#else.
+ if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
+ push(@stack, $level);
+ } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
+ $level = $stack[$#stack - 1];
+ } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) {
+ $level = pop(@stack);
+ }
+
foreach my $c (split(//, $rawlines[$line])) {
##print "C<$c>L<$level><$open$close>O<$off>\n";
if ($off > 0) {
@@ -843,11 +874,11 @@ sub annotate_values {
$type = 'V';
$av_pending = 'V';
- } elsif ($cur =~ /^($Ident\s*):/) {
- if ($type eq 'E') {
- $av_pend_colon = 'L';
- } elsif ($type eq 'T') {
+ } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
+ if (defined $2 && $type eq 'C' || $type eq 'T') {
$av_pend_colon = 'B';
+ } elsif ($type eq 'E') {
+ $av_pend_colon = 'L';
}
print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
$type = 'V';
@@ -865,6 +896,10 @@ sub annotate_values {
$type = 'E';
$av_pend_colon = 'O';
+ } elsif ($cur =~/^(,)/) {
+ print "COMMA($1)\n" if ($dbg_values > 1);
+ $type = 'C';
+
} elsif ($cur =~ /^(\?)/o) {
print "QUESTION($1)\n" if ($dbg_values > 1);
$type = 'N';
@@ -880,7 +915,7 @@ sub annotate_values {
}
$av_pend_colon = 'O';
- } elsif ($cur =~ /^(;|\[)/o) {
+ } elsif ($cur =~ /^(\[)/o) {
print "CLOSE($1)\n" if ($dbg_values > 1);
$type = 'N';
@@ -1051,6 +1086,7 @@ sub process {
my $in_comment = 0;
my $comment_edge = 0;
my $first_line = 0;
+ my $p1_prefix = '';
my $prev_values = 'E';
@@ -1097,9 +1133,12 @@ sub process {
$rawlines[$ln - 1] =~ /^-/);
$cnt--;
#print "RAW<$rawlines[$ln - 1]>\n";
- ($edge) = (defined $rawlines[$ln - 1] &&
- $rawlines[$ln - 1] =~ m@(/\*|\*/)@);
- last if (defined $edge);
+ last if (!defined $rawlines[$ln - 1]);
+ if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
+ $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
+ ($edge) = $1;
+ last;
+ }
}
if (defined $edge && $edge eq '*/') {
$in_comment = 1;
@@ -1109,7 +1148,7 @@ sub process {
# is the start of a diff block and this line starts
# ' *' then it is very likely a comment.
if (!defined $edge &&
- $rawlines[$linenr] =~ m@^.\s* \*(?:\s|$)@)
+ $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
{
$in_comment = 1;
}
@@ -1196,7 +1235,12 @@ sub process {
# extract the filename as it passes
if ($line=~/^\+\+\+\s+(\S+)/) {
$realfile = $1;
- $realfile =~ s@^[^/]*/@@;
+ $realfile =~ s@^([^/]*)/@@;
+
+ $p1_prefix = $1;
+ if ($tree && $p1_prefix ne '' && -e "$root/$p1_prefix") {
+ WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
+ }
if ($realfile =~ m@^include/asm/@) {
ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
@@ -1336,7 +1380,7 @@ sub process {
}
# any (foo ... *) is a pointer cast, and foo is a type
- while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/sg) {
+ while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
possible($1, "C:" . $s);
}
@@ -1594,7 +1638,7 @@ sub process {
$herecurr);
}
# check for static initialisers.
- if ($line =~ /\s*static\s.*=\s*(0|NULL|false)\s*;/) {
+ if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
ERROR("do not initialise statics to 0 or NULL\n" .
$herecurr);
}
@@ -1602,7 +1646,7 @@ sub process {
# check for new typedefs, only function parameters and sparse annotations
# make sense.
if ($line =~ /\btypedef\s/ &&
- $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ &&
+ $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
$line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
$line !~ /\b$typeTypedefs\b/ &&
$line !~ /\b__bitwise(?:__|)\b/) {
@@ -1610,21 +1654,39 @@ sub process {
}
# * goes on variable not on type
- if ($line =~ m{\($NonptrType(\*+)(?:\s+const)?\)}) {
- ERROR("\"(foo$1)\" should be \"(foo $1)\"\n" .
- $herecurr);
+ # (char*[ const])
+ if ($line =~ m{\($NonptrType(\s*\*[\s\*]*(?:$Modifier\s*)*)\)}) {
+ my ($from, $to) = ($1, $1);
- } elsif ($line =~ m{\($NonptrType\s+(\*+)(?!\s+const)\s+\)}) {
- ERROR("\"(foo $1 )\" should be \"(foo $1)\"\n" .
- $herecurr);
+ # Should start with a space.
+ $to =~ s/^(\S)/ $1/;
+ # Should not end with a space.
+ $to =~ s/\s+$//;
+ # '*'s should not have spaces between.
+ while ($to =~ s/(.)\s\*/$1\*/) {
+ }
- } elsif ($line =~ m{\b$NonptrType(\*+)(?:\s+(?:$Attribute|$Sparse))?\s+[A-Za-z\d_]+}) {
- ERROR("\"foo$1 bar\" should be \"foo $1bar\"\n" .
- $herecurr);
+ #print "from<$from> to<$to>\n";
+ if ($from ne $to) {
+ ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr);
+ }
+ } elsif ($line =~ m{\b$NonptrType(\s*\*[\s\*]*(?:$Modifier\s*)?)($Ident)}) {
+ my ($from, $to, $ident) = ($1, $1, $2);
- } elsif ($line =~ m{\b$NonptrType\s+(\*+)(?!\s+(?:$Attribute|$Sparse))\s+[A-Za-z\d_]+}) {
- ERROR("\"foo $1 bar\" should be \"foo $1bar\"\n" .
- $herecurr);
+ # Should start with a space.
+ $to =~ s/^(\S)/ $1/;
+ # Should not end with a space.
+ $to =~ s/\s+$//;
+ # '*'s should not have spaces between.
+ while ($to =~ s/(.)\s\*/$1\*/) {
+ }
+ # Modifiers should have spaces.
+ $to =~ s/(\b$Modifier$)/$1 /;
+
+ #print "from<$from> to<$to>\n";
+ if ($from ne $to) {
+ ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr);
+ }
}
# # no BUG() or BUG_ON()
@@ -1759,7 +1821,7 @@ sub process {
$c = 'C' if ($elements[$n + 2] =~ /^$;/);
$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
$c = 'O' if ($elements[$n + 2] eq '');
- $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/);
+ $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
} else {
$c = 'E';
}
@@ -1950,9 +2012,9 @@ sub process {
my $spacing = $1;
my $value = $2;
- # Flatten any parentheses and braces
+ # Flatten any parentheses
$value =~ s/\)\(/\) \(/g;
- while ($value =~ s/\([^\(\)]*\)/1/) {
+ while ($value !~ /(?:$Ident|-?$Constant)\s*$Compare\s*(?:$Ident|-?$Constant)/ && $value =~ s/\([^\(\)]*\)/1/) {
}
if ($value =~ /^(?:$Ident|-?$Constant)$/) {
@@ -1992,7 +2054,7 @@ sub process {
$line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
my ($s, $c) = ($stat, $cond);
- if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) {
+ if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
ERROR("do not use assignment in if condition\n" . $herecurr);
}
@@ -2167,9 +2229,10 @@ sub process {
MODULE_PARAM_DESC|
DECLARE_PER_CPU|
DEFINE_PER_CPU|
- __typeof__\(
+ __typeof__\(|
+ \.$Ident\s*=\s*
}x;
- #print "REST<$rest>\n";
+ #print "REST<$rest> dstat<$dstat>\n";
if ($rest ne '') {
if ($rest !~ /while\s*\(/ &&
$dstat !~ /$exceptions/)
@@ -2189,6 +2252,15 @@ sub process {
}
}
+# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
+# all assignments may have only one of the following with an assignment:
+# .
+# ALIGN(...)
+# VMLINUX_SYMBOL(...)
+ if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
+ WARN("vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
+ }
+
# check for redundant bracing round if etc
if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
my ($level, $endln, @chunks) =
@@ -2443,6 +2515,11 @@ sub process {
if ($line =~ /^.\s*__initcall\s*\(/) {
WARN("please use device_initcall() instead of __initcall()\n" . $herecurr);
}
+# check for struct file_operations, ensure they are const.
+ if ($line =~ /\bstruct\s+file_operations\b/ &&
+ $line !~ /\bconst\b/) {
+ WARN("struct file_operations should normally be const\n" . $herecurr);
+ }
# use of NR_CPUS is usually wrong
# ignore definitions of NR_CPUS and usage to define arrays as likely right
@@ -2466,6 +2543,15 @@ sub process {
last;
}
}
+
+# whine mightly about in_atomic
+ if ($line =~ /\bin_atomic\s*\(/) {
+ if ($realfile =~ m@^drivers/@) {
+ ERROR("do not use in_atomic in drivers\n" . $herecurr);
+ } else {
+ WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
+ }
+ }
}
# If we have no input at all, then there is nothing to report on
diff --git a/scripts/config b/scripts/config
new file mode 100755
index 000000000000..68b9761cdc38
--- /dev/null
+++ b/scripts/config
@@ -0,0 +1,150 @@
+#!/bin/bash
+# Manipulate options in a .config file from the command line
+
+usage() {
+ cat >&2 <<EOL
+Manipulate options in a .config file from the command line.
+Usage:
+config options command ...
+commands:
+ --enable|-e option Enable option
+ --disable|-d option Disable option
+ --module|-m option Turn option into a module
+ --state|-s option Print state of option (n,y,m,undef)
+
+ --enable-after|-E beforeopt option
+ Enable option directly after other option
+ --disable-after|-D beforeopt option
+ Disable option directly after other option
+ --module-after|-M beforeopt option
+ Turn option into module directly after other option
+
+ commands can be repeated multiple times
+
+options:
+ --file .config file to change (default .config)
+
+config doesn't check the validity of the .config file. This is done at next
+ make time.
+The options need to be already in the file before they can be changed,
+but sometimes you can cheat with the --*-after options.
+EOL
+ exit 1
+}
+
+checkarg() {
+ ARG="$1"
+ if [ "$ARG" = "" ] ; then
+ usage
+ fi
+ case "$ARG" in
+ CONFIG_*)
+ ARG="${ARG/CONFIG_/}"
+ ;;
+ esac
+ ARG="`echo $ARG | tr a-z A-Z`"
+}
+
+replace() {
+ sed -i -e "$@" $FN
+}
+
+if [ "$1" = "--file" ]; then
+ FN="$2"
+ if [ "$FN" = "" ] ; then
+ usage
+ fi
+ shift
+ shift
+else
+ FN=.config
+fi
+
+while [ "$1" != "" ] ; do
+ CMD="$1"
+ shift
+ case "$CMD" in
+ --enable|-e)
+ checkarg "$1"
+ replace "s/# CONFIG_$ARG is not set/CONFIG_$ARG=y/"
+ shift
+ ;;
+
+ --disable|-d)
+ checkarg "$1"
+ replace "s/CONFIG_$ARG=[my]/# CONFIG_$ARG is not set/"
+ shift
+ ;;
+
+ --module|-m)
+ checkarg "$1"
+ replace "s/CONFIG_$ARG=y/CONFIG_$ARG=m/" \
+ -e "s/# CONFIG_$ARG is not set/CONFIG_$ARG=m/"
+ shift
+ ;;
+
+ --state|-s)
+ checkarg "$1"
+ if grep -q "# CONFIG_$ARG is not set" $FN ; then
+ echo n
+ else
+ V="$(grep "^CONFIG_$ARG=" $FN)"
+ if [ $? != 0 ] ; then
+ echo undef
+ else
+ V="${V/CONFIG_$ARG=/}"
+ V="${V/\"/}"
+ echo "$V"
+ fi
+ fi
+ shift
+ ;;
+
+ --enable-after|-E)
+ checkarg "$1"
+ A=$ARG
+ checkarg "$2"
+ B=$ARG
+ replace "/CONFIG_$A=[my]/aCONFIG_$B=y" \
+ -e "/# CONFIG_$ARG is not set/a/CONFIG_$ARG=y" \
+ -e "s/# CONFIG_$ARG is not set/CONFIG_$ARG=y/"
+ shift
+ shift
+ ;;
+
+ --disable-after|-D)
+ checkarg "$1"
+ A=$ARG
+ checkarg "$2"
+ B=$ARG
+ replace "/CONFIG_$A=[my]/a# CONFIG_$B is not set" \
+ -e "/# CONFIG_$ARG is not set/a/# CONFIG_$ARG is not set" \
+ -e "s/CONFIG_$ARG=[my]/# CONFIG_$ARG is not set/"
+ shift
+ shift
+ ;;
+
+ --module-after|-M)
+ checkarg "$1"
+ A=$ARG
+ checkarg "$2"
+ B=$ARG
+ replace "/CONFIG_$A=[my]/aCONFIG_$B=m" \
+ -e "/# CONFIG_$ARG is not set/a/CONFIG_$ARG=m" \
+ -e "s/CONFIG_$ARG=y/CONFIG_$ARG=m/" \
+ -e "s/# CONFIG_$ARG is not set/CONFIG_$ARG=m/"
+ shift
+ shift
+ ;;
+
+ # undocumented because it ignores --file (fixme)
+ --refresh)
+ yes "" | make oldconfig
+ ;;
+
+ *)
+ usage
+ ;;
+ esac
+done
+
diff --git a/scripts/ihex2fw.c b/scripts/ihex2fw.c
new file mode 100644
index 000000000000..8f7fdaa9e010
--- /dev/null
+++ b/scripts/ihex2fw.c
@@ -0,0 +1,268 @@
+/*
+ * Parser/loader for IHEX formatted data.
+ *
+ * Copyright © 2008 David Woodhouse <dwmw2@infradead.org>
+ * Copyright © 2005 Jan Harkes <jaharkes@cs.cmu.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#define _GNU_SOURCE
+#include <getopt.h>
+
+
+struct ihex_binrec {
+ struct ihex_binrec *next; /* not part of the real data structure */
+ uint32_t addr;
+ uint16_t len;
+ uint8_t data[];
+};
+
+/**
+ * nybble/hex are little helpers to parse hexadecimal numbers to a byte value
+ **/
+static uint8_t nybble(const uint8_t n)
+{
+ if (n >= '0' && n <= '9') return n - '0';
+ else if (n >= 'A' && n <= 'F') return n - ('A' - 10);
+ else if (n >= 'a' && n <= 'f') return n - ('a' - 10);
+ return 0;
+}
+
+static uint8_t hex(const uint8_t *data, uint8_t *crc)
+{
+ uint8_t val = (nybble(data[0]) << 4) | nybble(data[1]);
+ *crc += val;
+ return val;
+}
+
+static int process_ihex(uint8_t *data, ssize_t size);
+static void file_record(struct ihex_binrec *record);
+static int output_records(int outfd);
+
+static int sort_records = 0;
+static int wide_records = 0;
+
+int usage(void)
+{
+ fprintf(stderr, "ihex2fw: Convert ihex files into binary "
+ "representation for use by Linux kernel\n");
+ fprintf(stderr, "usage: ihex2fw [<options>] <src.HEX> <dst.fw>\n");
+ fprintf(stderr, " -w: wide records (16-bit length)\n");
+ fprintf(stderr, " -s: sort records by address\n");
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ int infd, outfd;
+ struct stat st;
+ uint8_t *data;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "ws")) != -1) {
+ switch (opt) {
+ case 'w':
+ wide_records = 1;
+ break;
+ case 's':
+ sort_records = 1;
+ break;
+ default:
+ return usage();
+ }
+ }
+
+ if (optind + 2 != argc)
+ return usage();
+
+ if (!strcmp(argv[optind], "-"))
+ infd = 0;
+ else
+ infd = open(argv[optind], O_RDONLY);
+ if (infd == -1) {
+ fprintf(stderr, "Failed to open source file: %s",
+ strerror(errno));
+ return usage();
+ }
+ if (fstat(infd, &st)) {
+ perror("stat");
+ return 1;
+ }
+ data = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, infd, 0);
+ if (data == MAP_FAILED) {
+ perror("mmap");
+ return 1;
+ }
+
+ if (!strcmp(argv[optind+1], "-"))
+ outfd = 1;
+ else
+ outfd = open(argv[optind+1], O_TRUNC|O_CREAT|O_WRONLY, 0644);
+ if (outfd == -1) {
+ fprintf(stderr, "Failed to open destination file: %s",
+ strerror(errno));
+ return usage();
+ }
+ if (process_ihex(data, st.st_size))
+ return 1;
+
+ output_records(outfd);
+ return 0;
+}
+
+static int process_ihex(uint8_t *data, ssize_t size)
+{
+ struct ihex_binrec *record;
+ uint32_t offset = 0;
+ uint8_t type, crc = 0, crcbyte = 0;
+ int i, j;
+ int line = 1;
+ int len;
+
+ i = 0;
+next_record:
+ /* search for the start of record character */
+ while (i < size) {
+ if (data[i] == '\n') line++;
+ if (data[i++] == ':') break;
+ }
+
+ /* Minimum record length would be about 10 characters */
+ if (i + 10 > size) {
+ fprintf(stderr, "Can't find valid record at line %d\n", line);
+ return -EINVAL;
+ }
+
+ len = hex(data + i, &crc); i += 2;
+ if (wide_records) {
+ len <<= 8;
+ len += hex(data + i, &crc); i += 2;
+ }
+ record = malloc((sizeof (*record) + len + 3) & ~3);
+ if (!record) {
+ fprintf(stderr, "out of memory for records\n");
+ return -ENOMEM;
+ }
+ memset(record, 0, (sizeof(*record) + len + 3) & ~3);
+ record->len = len;
+
+ /* now check if we have enough data to read everything */
+ if (i + 8 + (record->len * 2) > size) {
+ fprintf(stderr, "Not enough data to read complete record at line %d\n",
+ line);
+ return -EINVAL;
+ }
+
+ record->addr = hex(data + i, &crc) << 8; i += 2;
+ record->addr |= hex(data + i, &crc); i += 2;
+ type = hex(data + i, &crc); i += 2;
+
+ for (j = 0; j < record->len; j++, i += 2)
+ record->data[j] = hex(data + i, &crc);
+
+ /* check CRC */
+ crcbyte = hex(data + i, &crc); i += 2;
+ if (crc != 0) {
+ fprintf(stderr, "CRC failure at line %d: got 0x%X, expected 0x%X\n",
+ line, crcbyte, (unsigned char)(crcbyte-crc));
+ return -EINVAL;
+ }
+
+ /* Done reading the record */
+ switch (type) {
+ case 0:
+ /* old style EOF record? */
+ if (!record->len)
+ break;
+
+ record->addr += offset;
+ file_record(record);
+ goto next_record;
+
+ case 1: /* End-Of-File Record */
+ if (record->addr || record->len) {
+ fprintf(stderr, "Bad EOF record (type 01) format at line %d",
+ line);
+ return -EINVAL;
+ }
+ break;
+
+ case 2: /* Extended Segment Address Record (HEX86) */
+ case 4: /* Extended Linear Address Record (HEX386) */
+ if (record->addr || record->len != 2) {
+ fprintf(stderr, "Bad HEX86/HEX386 record (type %02X) at line %d\n",
+ type, line);
+ return -EINVAL;
+ }
+
+ /* We shouldn't really be using the offset for HEX86 because
+ * the wraparound case is specified quite differently. */
+ offset = record->data[0] << 8 | record->data[1];
+ offset <<= (type == 2 ? 4 : 16);
+ goto next_record;
+
+ case 3: /* Start Segment Address Record */
+ case 5: /* Start Linear Address Record */
+ if (record->addr || record->len != 4) {
+ fprintf(stderr, "Bad Start Address record (type %02X) at line %d\n",
+ type, line);
+ return -EINVAL;
+ }
+
+ /* These records contain the CS/IP or EIP where execution
+ * starts. Don't really know what to do with them. */
+ goto next_record;
+
+ default:
+ fprintf(stderr, "Unknown record (type %02X)\n", type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct ihex_binrec *records;
+
+static void file_record(struct ihex_binrec *record)
+{
+ struct ihex_binrec **p = &records;
+
+ while ((*p) && (!sort_records || (*p)->addr < record->addr))
+ p = &((*p)->next);
+
+ record->next = *p;
+ *p = record;
+}
+
+static int output_records(int outfd)
+{
+ unsigned char zeroes[6] = {0, 0, 0, 0, 0, 0};
+ struct ihex_binrec *p = records;
+
+ while (p) {
+ uint16_t writelen = (p->len + 9) & ~3;
+
+ p->addr = htonl(p->addr);
+ p->len = htons(p->len);
+ write(outfd, &p->addr, writelen);
+ p = p->next;
+ }
+ /* EOF record is zero length, since we don't bother to represent
+ the type field in the binary version */
+ write(outfd, zeroes, 6);
+ return 0;
+}
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
new file mode 100644
index 000000000000..700a7a654a3f
--- /dev/null
+++ b/scripts/markup_oops.pl
@@ -0,0 +1,162 @@
+#!/usr/bin/perl -w
+
+# Copyright 2008, Intel Corporation
+#
+# This file is part of the Linux kernel
+#
+# This program file 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.
+#
+# Authors:
+# Arjan van de Ven <arjan@linux.intel.com>
+
+
+my $vmlinux_name = $ARGV[0];
+
+#
+# Step 1: Parse the oops to find the EIP value
+#
+
+my $target = "0";
+while (<STDIN>) {
+ if ($_ =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
+ $target = $1;
+ }
+}
+
+if ($target =~ /^f8/) {
+ print "This script does not work on modules ... \n";
+ exit;
+}
+
+if ($target eq "0") {
+ print "No oops found!\n";
+ print "Usage: \n";
+ print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
+ exit;
+}
+
+my $counter = 0;
+my $state = 0;
+my $center = 0;
+my @lines;
+
+sub InRange {
+ my ($address, $target) = @_;
+ my $ad = "0x".$address;
+ my $ta = "0x".$target;
+ my $delta = hex($ad) - hex($ta);
+
+ if (($delta > -4096) && ($delta < 4096)) {
+ return 1;
+ }
+ return 0;
+}
+
+
+
+# first, parse the input into the lines array, but to keep size down,
+# we only do this for 4Kb around the sweet spot
+
+my $filename;
+
+open(FILE, "objdump -dS $vmlinux_name |") || die "Cannot start objdump";
+
+while (<FILE>) {
+ my $line = $_;
+ chomp($line);
+ if ($state == 0) {
+ if ($line =~ /^([a-f0-9]+)\:/) {
+ if (InRange($1, $target)) {
+ $state = 1;
+ }
+ }
+ } else {
+ if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) {
+ my $val = $1;
+ if (!InRange($val, $target)) {
+ last;
+ }
+ if ($val eq $target) {
+ $center = $counter;
+ }
+ }
+ $lines[$counter] = $line;
+
+ $counter = $counter + 1;
+ }
+}
+
+close(FILE);
+
+if ($counter == 0) {
+ print "No matching code found \n";
+ exit;
+}
+
+if ($center == 0) {
+ print "No matching code found \n";
+ exit;
+}
+
+my $start;
+my $finish;
+my $codelines = 0;
+my $binarylines = 0;
+# now we go up and down in the array to find how much we want to print
+
+$start = $center;
+
+while ($start > 1) {
+ $start = $start - 1;
+ my $line = $lines[$start];
+ if ($line =~ /^([a-f0-9]+)\:/) {
+ $binarylines = $binarylines + 1;
+ } else {
+ $codelines = $codelines + 1;
+ }
+ if ($codelines > 10) {
+ last;
+ }
+ if ($binarylines > 20) {
+ last;
+ }
+}
+
+
+$finish = $center;
+$codelines = 0;
+$binarylines = 0;
+while ($finish < $counter) {
+ $finish = $finish + 1;
+ my $line = $lines[$finish];
+ if ($line =~ /^([a-f0-9]+)\:/) {
+ $binarylines = $binarylines + 1;
+ } else {
+ $codelines = $codelines + 1;
+ }
+ if ($codelines > 10) {
+ last;
+ }
+ if ($binarylines > 20) {
+ last;
+ }
+}
+
+
+my $i;
+
+my $fulltext = "";
+$i = $start;
+while ($i < $finish) {
+ if ($i == $center) {
+ $fulltext = $fulltext . "*$lines[$i] <----- faulting instruction\n";
+ } else {
+ $fulltext = $fulltext . " $lines[$i]\n";
+ }
+ $i = $i +1;
+}
+
+print $fulltext;
+
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 9e3451d2c3a1..fdbe78bb5e2b 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -24,6 +24,11 @@ else
tree=${srctree}/
fi
+# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
+if [ "${ALLSOURCE_ARCHS}" = "" ]; then
+ ALLSOURCE_ARCHS=${SRCARCH}
+fi
+
# find sources in arch/$ARCH
find_arch_sources()
{
@@ -54,26 +59,29 @@ find_other_sources()
find_sources()
{
find_arch_sources $1 "$2"
- find_include_sources "$2"
- find_other_sources "$2"
}
all_sources()
{
- find_sources $SRCARCH '*.[chS]'
+ for arch in $ALLSOURCE_ARCHS
+ do
+ find_sources $arch '*.[chS]'
+ done
if [ ! -z "$archinclude" ]; then
find_arch_include_sources $archinclude '*.[chS]'
fi
+ find_include_sources '*.[chS]'
+ find_other_sources '*.[chS]'
}
all_kconfigs()
{
- find_sources $SRCARCH 'Kconfig*'
+ find_sources $ALLSOURCE_ARCHS 'Kconfig*'
}
all_defconfigs()
{
- find_sources $SRCARCH "defconfig"
+ find_sources $ALLSOURCE_ARCHS "defconfig"
}
docscope()