diff --git a/[refs] b/[refs]
index 6773d0bba14b..2eca439bf8db 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 611a15afcdaacec6efba984c7eb089b853564bdf
+refs/heads/master: 4e6d816e51728d5006c53e78e079ac62b902f8aa
diff --git a/trunk/.gitignore b/trunk/.gitignore
index b1f5b9df2ae1..e1d5c17c12c2 100644
--- a/trunk/.gitignore
+++ b/trunk/.gitignore
@@ -12,6 +12,9 @@
*.ko
*.so
*.mod.c
+*.i
+*.lst
+*.symtypes
#
# Top-level generic files
diff --git a/trunk/CREDITS b/trunk/CREDITS
index 0fe904ebb7c7..cc3453a55fb9 100644
--- a/trunk/CREDITS
+++ b/trunk/CREDITS
@@ -2384,6 +2384,13 @@ N: Thomas Molina
E: tmolina@cablespeed.com
D: bug fixes, documentation, minor hackery
+N: Paul Moore
+E: paul.moore@hp.com
+D: NetLabel author
+S: Hewlett-Packard
+S: 110 Spit Brook Road
+S: Nashua, NH 03062
+
N: James Morris
E: jmorris@namei.org
W: http://namei.org/
diff --git a/trunk/Documentation/00-INDEX b/trunk/Documentation/00-INDEX
index 5f7f7d7f77d2..02457ec9c94f 100644
--- a/trunk/Documentation/00-INDEX
+++ b/trunk/Documentation/00-INDEX
@@ -184,6 +184,8 @@ mtrr.txt
- how to use PPro Memory Type Range Registers to increase performance.
nbd.txt
- info on a TCP implementation of a network block device.
+netlabel/
+ - directory with information on the NetLabel subsystem.
networking/
- directory with info on various aspects of networking with Linux.
nfsroot.txt
diff --git a/trunk/Documentation/Changes b/trunk/Documentation/Changes
index 488272074c36..abee7f58c1ed 100644
--- a/trunk/Documentation/Changes
+++ b/trunk/Documentation/Changes
@@ -37,15 +37,14 @@ o e2fsprogs 1.29 # tune2fs
o jfsutils 1.1.3 # fsck.jfs -V
o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs
o xfsprogs 2.6.0 # xfs_db -V
-o pcmciautils 004
-o pcmcia-cs 3.1.21 # cardmgr -V
+o pcmciautils 004 # pccardctl -V
o quota-tools 3.09 # quota -V
o PPP 2.4.0 # pppd --version
o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
o nfs-utils 1.0.5 # showmount --version
o procps 3.2.0 # ps --version
o oprofile 0.9 # oprofiled --version
-o udev 071 # udevinfo -V
+o udev 081 # udevinfo -V
Kernel compilation
==================
@@ -268,7 +267,7 @@ active clients.
To enable this new functionality, you need to:
- mount -t nfsd nfsd /proc/fs/nfs
+ mount -t nfsd nfsd /proc/fs/nfsd
before running exportfs or mountd. It is recommended that all NFS
services be protected from the internet-at-large by a firewall where
diff --git a/trunk/Documentation/DocBook/libata.tmpl b/trunk/Documentation/DocBook/libata.tmpl
index e97c32314541..065e8dc23e3a 100644
--- a/trunk/Documentation/DocBook/libata.tmpl
+++ b/trunk/Documentation/DocBook/libata.tmpl
@@ -868,18 +868,18 @@ and other resources, etc.
libata Library
-!Edrivers/scsi/libata-core.c
+!Edrivers/ata/libata-core.c
libata Core Internals
-!Idrivers/scsi/libata-core.c
+!Idrivers/ata/libata-core.c
libata SCSI translation/emulation
-!Edrivers/scsi/libata-scsi.c
-!Idrivers/scsi/libata-scsi.c
+!Edrivers/ata/libata-scsi.c
+!Idrivers/ata/libata-scsi.c
@@ -1600,12 +1600,12 @@ and other resources, etc.
ata_piix Internals
-!Idrivers/scsi/ata_piix.c
+!Idrivers/ata/ata_piix.c
sata_sil Internals
-!Idrivers/scsi/sata_sil.c
+!Idrivers/ata/sata_sil.c
diff --git a/trunk/Documentation/crypto/api-intro.txt b/trunk/Documentation/crypto/api-intro.txt
index 74dffc68ff9f..5a03a2801d67 100644
--- a/trunk/Documentation/crypto/api-intro.txt
+++ b/trunk/Documentation/crypto/api-intro.txt
@@ -19,15 +19,14 @@ At the lowest level are algorithms, which register dynamically with the
API.
'Transforms' are user-instantiated objects, which maintain state, handle all
-of the implementation logic (e.g. manipulating page vectors), provide an
-abstraction to the underlying algorithms, and handle common logical
-operations (e.g. cipher modes, HMAC for digests). However, at the user
+of the implementation logic (e.g. manipulating page vectors) and provide an
+abstraction to the underlying algorithms. However, at the user
level they are very simple.
Conceptually, the API layering looks like this:
[transform api] (user interface)
- [transform ops] (per-type logic glue e.g. cipher.c, digest.c)
+ [transform ops] (per-type logic glue e.g. cipher.c, compress.c)
[algorithm api] (for registering algorithms)
The idea is to make the user interface and algorithm registration API
@@ -44,22 +43,27 @@ under development.
Here's an example of how to use the API:
#include
+ #include
+ #include
struct scatterlist sg[2];
char result[128];
- struct crypto_tfm *tfm;
+ struct crypto_hash *tfm;
+ struct hash_desc desc;
- tfm = crypto_alloc_tfm("md5", 0);
- if (tfm == NULL)
+ tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm))
fail();
/* ... set up the scatterlists ... */
+
+ desc.tfm = tfm;
+ desc.flags = 0;
- crypto_digest_init(tfm);
- crypto_digest_update(tfm, &sg, 2);
- crypto_digest_final(tfm, result);
+ if (crypto_hash_digest(&desc, &sg, 2, result))
+ fail();
- crypto_free_tfm(tfm);
+ crypto_free_hash(tfm);
Many real examples are available in the regression test module (tcrypt.c).
@@ -126,7 +130,7 @@ might already be working on.
BUGS
Send bug reports to:
-James Morris
+Herbert Xu
Cc: David S. Miller
@@ -134,13 +138,14 @@ FURTHER INFORMATION
For further patches and various updates, including the current TODO
list, see:
-http://samba.org/~jamesm/crypto/
+http://gondor.apana.org.au/~herbert/crypto/
AUTHORS
James Morris
David S. Miller
+Herbert Xu
CREDITS
@@ -238,8 +243,11 @@ Anubis algorithm contributors:
Tiger algorithm contributors:
Aaron Grothe
+VIA PadLock contributors:
+ Michal Ludvig
+
Generic scatterwalk code by Adam J. Richter
Please send any credits updates or corrections to:
-James Morris
+Herbert Xu
diff --git a/trunk/Documentation/dontdiff b/trunk/Documentation/dontdiff
index 24adfe9af3ca..63c2d0c55aa2 100644
--- a/trunk/Documentation/dontdiff
+++ b/trunk/Documentation/dontdiff
@@ -135,6 +135,7 @@ tags
times.h*
tkparse
trix_boot.h
+utsrelease.h*
version.h*
vmlinux
vmlinux-*
diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt
index d1cd5f93e028..552507fe9a7e 100644
--- a/trunk/Documentation/feature-removal-schedule.txt
+++ b/trunk/Documentation/feature-removal-schedule.txt
@@ -281,3 +281,16 @@ Why: The deferred output hooks are a layering violation causing unusual
Who: Patrick McHardy
---------------------------
+
+What: frame diverter
+When: November 2006
+Why: The frame diverter is included in most distribution kernels, but is
+ broken. It does not correctly handle many things:
+ - IPV6
+ - non-linear skb's
+ - network device RCU on removal
+ - input frames not correctly checked for protocol errors
+ It also adds allocation overhead even if not enabled.
+ It is not clear if anyone is still using it.
+Who: Stephen Hemminger
+
diff --git a/trunk/Documentation/kbuild/kconfig-language.txt b/trunk/Documentation/kbuild/kconfig-language.txt
index ca1967f36423..003fccc14d24 100644
--- a/trunk/Documentation/kbuild/kconfig-language.txt
+++ b/trunk/Documentation/kbuild/kconfig-language.txt
@@ -67,19 +67,19 @@ applicable everywhere (see syntax).
- default value: "default" ["if" ]
A config option can have any number of default values. If multiple
default values are visible, only the first defined one is active.
- Default values are not limited to the menu entry, where they are
- defined, this means the default can be defined somewhere else or be
+ Default values are not limited to the menu entry where they are
+ defined. This means the default can be defined somewhere else or be
overridden by an earlier definition.
The default value is only assigned to the config symbol if no other
value was set by the user (via the input prompt above). If an input
prompt is visible the default value is presented to the user and can
be overridden by him.
- Optionally dependencies only for this default value can be added with
+ Optionally, dependencies only for this default value can be added with
"if".
- dependencies: "depends on"/"requires"
This defines a dependency for this menu entry. If multiple
- dependencies are defined they are connected with '&&'. Dependencies
+ dependencies are defined, they are connected with '&&'. Dependencies
are applied to all other options within this menu entry (which also
accept an "if" expression), so these two examples are equivalent:
@@ -153,7 +153,7 @@ Nonconstant symbols are the most common ones and are defined with the
'config' statement. Nonconstant symbols consist entirely of alphanumeric
characters or underscores.
Constant symbols are only part of expressions. Constant symbols are
-always surrounded by single or double quotes. Within the quote any
+always surrounded by single or double quotes. Within the quote, any
other character is allowed and the quotes can be escaped using '\'.
Menu structure
@@ -237,7 +237,7 @@ choices:
"endchoice"
-This defines a choice group and accepts any of above attributes as
+This defines a choice group and accepts any of the above attributes as
options. A choice can only be of type bool or tristate, while a boolean
choice only allows a single config entry to be selected, a tristate
choice also allows any number of config entries to be set to 'm'. This
diff --git a/trunk/Documentation/kbuild/makefiles.txt b/trunk/Documentation/kbuild/makefiles.txt
index 0706699c9da9..b7d6abb501a6 100644
--- a/trunk/Documentation/kbuild/makefiles.txt
+++ b/trunk/Documentation/kbuild/makefiles.txt
@@ -22,7 +22,7 @@ This document describes the Linux kernel Makefiles.
=== 4 Host Program support
--- 4.1 Simple Host Program
--- 4.2 Composite Host Programs
- --- 4.3 Defining shared libraries
+ --- 4.3 Defining shared libraries
--- 4.4 Using C++ for host programs
--- 4.5 Controlling compiler options for host programs
--- 4.6 When host programs are actually built
@@ -69,7 +69,7 @@ architecture-specific information to the top Makefile.
Each subdirectory has a kbuild Makefile which carries out the commands
passed down from above. The kbuild Makefile uses information from the
-.config file to construct various file lists used by kbuild to build
+.config file to construct various file lists used by kbuild to build
any built-in or modular targets.
scripts/Makefile.* contains all the definitions/rules etc. that
@@ -86,7 +86,7 @@ any kernel Makefiles (or any other source files).
*Normal developers* are people who work on features such as device
drivers, file systems, and network protocols. These people need to
-maintain the kbuild Makefiles for the subsystem that they are
+maintain the kbuild Makefiles for the subsystem they are
working on. In order to do this effectively, they need some overall
knowledge about the kernel Makefiles, plus detailed knowledge about the
public interface for kbuild.
@@ -104,10 +104,10 @@ This document is aimed towards normal developers and arch developers.
=== 3 The kbuild files
Most Makefiles within the kernel are kbuild Makefiles that use the
-kbuild infrastructure. This chapter introduce the syntax used in the
+kbuild infrastructure. This chapter introduces the syntax used in the
kbuild makefiles.
The preferred name for the kbuild files are 'Makefile' but 'Kbuild' can
-be used and if both a 'Makefile' and a 'Kbuild' file exists then the 'Kbuild'
+be used and if both a 'Makefile' and a 'Kbuild' file exists, then the 'Kbuild'
file will be used.
Section 3.1 "Goal definitions" is a quick intro, further chapters provide
@@ -124,7 +124,7 @@ more details, with real examples.
Example:
obj-y += foo.o
- This tell kbuild that there is one object in that directory named
+ This tell kbuild that there is one object in that directory, named
foo.o. foo.o will be built from foo.c or foo.S.
If foo.o shall be built as a module, the variable obj-m is used.
@@ -140,7 +140,7 @@ more details, with real examples.
--- 3.2 Built-in object goals - obj-y
The kbuild Makefile specifies object files for vmlinux
- in the lists $(obj-y). These lists depend on the kernel
+ in the $(obj-y) lists. These lists depend on the kernel
configuration.
Kbuild compiles all the $(obj-y) files. It then calls
@@ -154,8 +154,8 @@ more details, with real examples.
Link order is significant, because certain functions
(module_init() / __initcall) will be called during boot in the
order they appear. So keep in mind that changing the link
- order may e.g. change the order in which your SCSI
- controllers are detected, and thus you disks are renumbered.
+ order may e.g. change the order in which your SCSI
+ controllers are detected, and thus your disks are renumbered.
Example:
#drivers/isdn/i4l/Makefile
@@ -203,11 +203,11 @@ more details, with real examples.
Example:
#fs/ext2/Makefile
obj-$(CONFIG_EXT2_FS) += ext2.o
- ext2-y := balloc.o bitmap.o
+ ext2-y := balloc.o bitmap.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
-
- In this example xattr.o is only part of the composite object
- ext2.o, if $(CONFIG_EXT2_FS_XATTR) evaluates to 'y'.
+
+ In this example, xattr.o is only part of the composite object
+ ext2.o if $(CONFIG_EXT2_FS_XATTR) evaluates to 'y'.
Note: Of course, when you are building objects into the kernel,
the syntax above will also work. So, if you have CONFIG_EXT2_FS=y,
@@ -221,16 +221,16 @@ more details, with real examples.
--- 3.5 Library file goals - lib-y
- Objects listed with obj-* are used for modules or
+ Objects listed with obj-* are used for modules, or
combined in a built-in.o for that specific directory.
There is also the possibility to list objects that will
be included in a library, lib.a.
All objects listed with lib-y are combined in a single
library for that directory.
- Objects that are listed in obj-y and additional listed in
+ Objects that are listed in obj-y and additionaly listed in
lib-y will not be included in the library, since they will anyway
be accessible.
- For consistency objects listed in lib-m will be included in lib.a.
+ For consistency, objects listed in lib-m will be included in lib.a.
Note that the same kbuild makefile may list files to be built-in
and to be part of a library. Therefore the same directory
@@ -241,11 +241,11 @@ more details, with real examples.
lib-y := checksum.o delay.o
This will create a library lib.a based on checksum.o and delay.o.
- For kbuild to actually recognize that there is a lib.a being build
+ For kbuild to actually recognize that there is a lib.a being built,
the directory shall be listed in libs-y.
See also "6.3 List directories to visit when descending".
-
- Usage of lib-y is normally restricted to lib/ and arch/*/lib.
+
+ Use of lib-y is normally restricted to lib/ and arch/*/lib.
--- 3.6 Descending down in directories
@@ -255,7 +255,7 @@ more details, with real examples.
invoke make recursively in subdirectories, provided you let it know of
them.
- To do so obj-y and obj-m are used.
+ To do so, obj-y and obj-m are used.
ext2 lives in a separate directory, and the Makefile present in fs/
tells kbuild to descend down using the following assignment.
@@ -353,8 +353,8 @@ more details, with real examples.
Special rules are used when the kbuild infrastructure does
not provide the required support. A typical example is
header files generated during the build process.
- Another example is the architecture specific Makefiles which
- needs special rules to prepare boot images etc.
+ Another example are the architecture specific Makefiles which
+ need special rules to prepare boot images etc.
Special rules are written as normal Make rules.
Kbuild is not executing in the directory where the Makefile is
@@ -387,28 +387,28 @@ more details, with real examples.
--- 3.11 $(CC) support functions
- The kernel may be build with several different versions of
+ The kernel may be built with several different versions of
$(CC), each supporting a unique set of features and options.
kbuild provide basic support to check for valid options for $(CC).
$(CC) is useally the gcc compiler, but other alternatives are
available.
as-option
- as-option is used to check if $(CC) when used to compile
- assembler (*.S) files supports the given option. An optional
- second option may be specified if first option are not supported.
+ as-option is used to check if $(CC) -- when used to compile
+ assembler (*.S) files -- supports the given option. An optional
+ second option may be specified if the first option is not supported.
Example:
#arch/sh/Makefile
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
- In the above example cflags-y will be assinged the the option
+ In the above example, cflags-y will be assigned the option
-Wa$(comma)-isa=$(isa-y) if it is supported by $(CC).
The second argument is optional, and if supplied will be used
if first argument is not supported.
ld-option
- ld-option is used to check if $(CC) when used to link object files
+ ld-option is used to check if $(CC) when used to link object files
supports the given option. An optional second option may be
specified if first option are not supported.
@@ -422,7 +422,7 @@ more details, with real examples.
if first argument is not supported.
cc-option
- cc-option is used to check if $(CC) support a given option, and not
+ cc-option is used to check if $(CC) supports a given option, and not
supported to use an optional second option.
Example:
@@ -430,12 +430,12 @@ more details, with real examples.
cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
In the above example cflags-y will be assigned the option
- -march=pentium-mmx if supported by $(CC), otherwise -march-i586.
- The second argument to cc-option is optional, and if omitted
+ -march=pentium-mmx if supported by $(CC), otherwise -march=i586.
+ The second argument to cc-option is optional, and if omitted,
cflags-y will be assigned no value if first option is not supported.
cc-option-yn
- cc-option-yn is used to check if gcc supports a given option
+ cc-option-yn is used to check if gcc supports a given option
and return 'y' if supported, otherwise 'n'.
Example:
@@ -443,32 +443,33 @@ more details, with real examples.
biarch := $(call cc-option-yn, -m32)
aflags-$(biarch) += -a32
cflags-$(biarch) += -m32
-
- In the above example $(biarch) is set to y if $(CC) supports the -m32
- option. When $(biarch) equals to y the expanded variables $(aflags-y)
- and $(cflags-y) will be assigned the values -a32 and -m32.
+
+ In the above example, $(biarch) is set to y if $(CC) supports the -m32
+ option. When $(biarch) equals 'y', the expanded variables $(aflags-y)
+ and $(cflags-y) will be assigned the values -a32 and -m32,
+ respectively.
cc-option-align
- gcc version >= 3.0 shifted type of options used to speify
- alignment of functions, loops etc. $(cc-option-align) whrn used
- as prefix to the align options will select the right prefix:
+ gcc versions >= 3.0 changed the type of options used to specify
+ alignment of functions, loops etc. $(cc-option-align), when used
+ as prefix to the align options, will select the right prefix:
gcc < 3.00
cc-option-align = -malign
gcc >= 3.00
cc-option-align = -falign
-
+
Example:
CFLAGS += $(cc-option-align)-functions=4
- In the above example the option -falign-functions=4 is used for
- gcc >= 3.00. For gcc < 3.00 -malign-functions=4 is used.
-
+ In the above example, the option -falign-functions=4 is used for
+ gcc >= 3.00. For gcc < 3.00, -malign-functions=4 is used.
+
cc-version
- cc-version return a numerical version of the $(CC) compiler version.
+ cc-version returns a numerical version of the $(CC) compiler version.
The format is where both are two digits. So for example
gcc 3.41 would return 0341.
cc-version is useful when a specific $(CC) version is faulty in one
- area, for example the -mregparm=3 were broken in some gcc version
+ area, for example -mregparm=3 was broken in some gcc versions
even though the option was accepted by gcc.
Example:
@@ -477,20 +478,20 @@ more details, with real examples.
if [ $(call cc-version) -ge 0300 ] ; then \
echo "-mregparm=3"; fi ;)
- In the above example -mregparm=3 is only used for gcc version greater
+ In the above example, -mregparm=3 is only used for gcc version greater
than or equal to gcc 3.0.
cc-ifversion
- cc-ifversion test the version of $(CC) and equals last argument if
+ cc-ifversion tests the version of $(CC) and equals last argument if
version expression is true.
Example:
#fs/reiserfs/Makefile
EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0402, -O1)
- In this example EXTRA_CFLAGS will be assigned the value -O1 if the
+ In this example, EXTRA_CFLAGS will be assigned the value -O1 if the
$(CC) version is less than 4.2.
- cc-ifversion takes all the shell operators:
+ cc-ifversion takes all the shell operators:
-eq, -ne, -lt, -le, -gt, and -ge
The third parameter may be a text as in this example, but it may also
be an expanded variable or a macro.
@@ -506,7 +507,7 @@ The first step is to tell kbuild that a host program exists. This is
done utilising the variable hostprogs-y.
The second step is to add an explicit dependency to the executable.
-This can be done in two ways. Either add the dependency in a rule,
+This can be done in two ways. Either add the dependency in a rule,
or utilise the variable $(always).
Both possibilities are described in the following.
@@ -523,28 +524,28 @@ Both possibilities are described in the following.
Kbuild assumes in the above example that bin2hex is made from a single
c-source file named bin2hex.c located in the same directory as
the Makefile.
-
+
--- 4.2 Composite Host Programs
Host programs can be made up based on composite objects.
The syntax used to define composite objects for host programs is
similar to the syntax used for kernel objects.
- $(-objs) list all objects used to link the final
+ $(-objs) lists all objects used to link the final
executable.
Example:
#scripts/lxdialog/Makefile
- hostprogs-y := lxdialog
+ hostprogs-y := lxdialog
lxdialog-objs := checklist.o lxdialog.o
Objects with extension .o are compiled from the corresponding .c
- files. In the above example checklist.c is compiled to checklist.o
+ files. In the above example, checklist.c is compiled to checklist.o
and lxdialog.c is compiled to lxdialog.o.
- Finally the two .o files are linked to the executable, lxdialog.
+ Finally, the two .o files are linked to the executable, lxdialog.
Note: The syntax -y is not permitted for host-programs.
---- 4.3 Defining shared libraries
-
+--- 4.3 Defining shared libraries
+
Objects with extension .so are considered shared libraries, and
will be compiled as position independent objects.
Kbuild provides support for shared libraries, but the usage
@@ -557,7 +558,7 @@ Both possibilities are described in the following.
hostprogs-y := conf
conf-objs := conf.o libkconfig.so
libkconfig-objs := expr.o type.o
-
+
Shared libraries always require a corresponding -objs line, and
in the example above the shared library libkconfig is composed by
the two objects expr.o and type.o.
@@ -578,7 +579,7 @@ Both possibilities are described in the following.
In the example above the executable is composed of the C++ file
qconf.cc - identified by $(qconf-cxxobjs).
-
+
If qconf is composed by a mixture of .c and .cc files, then an
additional line can be used to identify this.
@@ -587,34 +588,35 @@ Both possibilities are described in the following.
hostprogs-y := qconf
qconf-cxxobjs := qconf.o
qconf-objs := check.o
-
+
--- 4.5 Controlling compiler options for host programs
When compiling host programs, it is possible to set specific flags.
The programs will always be compiled utilising $(HOSTCC) passed
the options specified in $(HOSTCFLAGS).
To set flags that will take effect for all host programs created
- in that Makefile use the variable HOST_EXTRACFLAGS.
+ in that Makefile, use the variable HOST_EXTRACFLAGS.
Example:
#scripts/lxdialog/Makefile
HOST_EXTRACFLAGS += -I/usr/include/ncurses
-
+
To set specific flags for a single file the following construction
is used:
Example:
#arch/ppc64/boot/Makefile
HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE)
-
+
It is also possible to specify additional options to the linker.
-
+
Example:
#scripts/kconfig/Makefile
HOSTLOADLIBES_qconf := -L$(QTDIR)/lib
- When linking qconf it will be passed the extra option "-L$(QTDIR)/lib".
-
+ When linking qconf, it will be passed the extra option
+ "-L$(QTDIR)/lib".
+
--- 4.6 When host programs are actually built
Kbuild will only build host-programs when they are referenced
@@ -629,7 +631,7 @@ Both possibilities are described in the following.
$(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist
( cd $(obj); ./gen-devlist ) < $<
- The target $(obj)/devlist.h will not be built before
+ The target $(obj)/devlist.h will not be built before
$(obj)/gen-devlist is updated. Note that references to
the host programs in special rules must be prefixed with $(obj).
@@ -648,7 +650,7 @@ Both possibilities are described in the following.
--- 4.7 Using hostprogs-$(CONFIG_FOO)
- A typcal pattern in a Kbuild file lok like this:
+ A typical pattern in a Kbuild file looks like this:
Example:
#scripts/Makefile
@@ -656,13 +658,13 @@ Both possibilities are described in the following.
Kbuild knows about both 'y' for built-in and 'm' for module.
So if a config symbol evaluate to 'm', kbuild will still build
- the binary. In other words Kbuild handle hostprogs-m exactly
- like hostprogs-y. But only hostprogs-y is recommend used
- when no CONFIG symbol are involved.
+ the binary. In other words, Kbuild handles hostprogs-m exactly
+ like hostprogs-y. But only hostprogs-y is recommended to be used
+ when no CONFIG symbols are involved.
=== 5 Kbuild clean infrastructure
-"make clean" deletes most generated files in the src tree where the kernel
+"make clean" deletes most generated files in the obj tree where the kernel
is compiled. This includes generated files such as host programs.
Kbuild knows targets listed in $(hostprogs-y), $(hostprogs-m), $(always),
$(extra-y) and $(targets). They are all deleted during "make clean".
@@ -680,7 +682,8 @@ When executing "make clean", the two files "devlist.h classlist.h" will
be deleted. Kbuild will assume files to be in same relative directory as the
Makefile except if an absolute path is specified (path starting with '/').
-To delete a directory hirachy use:
+To delete a directory hierarchy use:
+
Example:
#scripts/package/Makefile
clean-dirs := $(objtree)/debian/
@@ -723,29 +726,29 @@ be visited during "make clean".
The top level Makefile sets up the environment and does the preparation,
before starting to descend down in the individual directories.
-The top level makefile contains the generic part, whereas the
-arch/$(ARCH)/Makefile contains what is required to set-up kbuild
-to the said architecture.
-To do so arch/$(ARCH)/Makefile sets a number of variables, and defines
+The top level makefile contains the generic part, whereas
+arch/$(ARCH)/Makefile contains what is required to set up kbuild
+for said architecture.
+To do so, arch/$(ARCH)/Makefile sets up a number of variables and defines
a few targets.
-When kbuild executes the following steps are followed (roughly):
-1) Configuration of the kernel => produced .config
+When kbuild executes, the following steps are followed (roughly):
+1) Configuration of the kernel => produce .config
2) Store kernel version in include/linux/version.h
3) Symlink include/asm to include/asm-$(ARCH)
4) Updating all other prerequisites to the target prepare:
- Additional prerequisites are specified in arch/$(ARCH)/Makefile
5) Recursively descend down in all directories listed in
init-* core* drivers-* net-* libs-* and build all targets.
- - The value of the above variables are extended in arch/$(ARCH)/Makefile.
-6) All object files are then linked and the resulting file vmlinux is
- located at the root of the src tree.
+ - The values of the above variables are expanded in arch/$(ARCH)/Makefile.
+6) All object files are then linked and the resulting file vmlinux is
+ located at the root of the obj tree.
The very first objects linked are listed in head-y, assigned by
arch/$(ARCH)/Makefile.
-7) Finally the architecture specific part does any required post processing
+7) Finally, the architecture specific part does any required post processing
and builds the final bootimage.
- This includes building boot records
- - Preparing initrd images and the like
+ - Preparing initrd images and thelike
--- 6.1 Set variables to tweak the build to the architecture
@@ -760,7 +763,7 @@ When kbuild executes the following steps are followed (roughly):
LDFLAGS := -m elf_s390
Note: EXTRA_LDFLAGS and LDFLAGS_$@ can be used to further customise
the flags used. See chapter 7.
-
+
LDFLAGS_MODULE Options for $(LD) when linking modules
LDFLAGS_MODULE is used to set specific flags for $(LD) when
@@ -770,7 +773,7 @@ When kbuild executes the following steps are followed (roughly):
LDFLAGS_vmlinux Options for $(LD) when linking vmlinux
LDFLAGS_vmlinux is used to specify additional flags to pass to
- the linker when linking the final vmlinux.
+ the linker when linking the final vmlinux image.
LDFLAGS_vmlinux uses the LDFLAGS_$@ support.
Example:
@@ -780,7 +783,7 @@ When kbuild executes the following steps are followed (roughly):
OBJCOPYFLAGS objcopy flags
When $(call if_changed,objcopy) is used to translate a .o file,
- then the flags specified in OBJCOPYFLAGS will be used.
+ the flags specified in OBJCOPYFLAGS will be used.
$(call if_changed,objcopy) is often used to generate raw binaries on
vmlinux.
@@ -792,7 +795,7 @@ When kbuild executes the following steps are followed (roughly):
$(obj)/image: vmlinux FORCE
$(call if_changed,objcopy)
- In this example the binary $(obj)/image is a binary version of
+ In this example, the binary $(obj)/image is a binary version of
vmlinux. The usage of $(call if_changed,xxx) will be described later.
AFLAGS $(AS) assembler flags
@@ -809,7 +812,7 @@ When kbuild executes the following steps are followed (roughly):
Default value - see top level Makefile
Append or modify as required per architecture.
- Often the CFLAGS variable depends on the configuration.
+ Often, the CFLAGS variable depends on the configuration.
Example:
#arch/i386/Makefile
@@ -830,7 +833,7 @@ When kbuild executes the following steps are followed (roughly):
...
- The first examples utilises the trick that a config option expands
+ The first example utilises the trick that a config option expands
to 'y' when selected.
CFLAGS_KERNEL $(CC) options specific for built-in
@@ -843,18 +846,18 @@ When kbuild executes the following steps are followed (roughly):
$(CFLAGS_MODULE) contains extra C compiler flags used to compile code
for loadable kernel modules.
-
+
--- 6.2 Add prerequisites to archprepare:
- The archprepare: rule is used to list prerequisites that needs to be
+ The archprepare: rule is used to list prerequisites that need to be
built before starting to descend down in the subdirectories.
- This is usual header files containing assembler constants.
+ This is usually used for header files containing assembler constants.
Example:
#arch/arm/Makefile
archprepare: maketools
- In this example the file target maketools will be processed
+ In this example, the file target maketools will be processed
before descending down in the subdirectories.
See also chapter XXX-TODO that describe how kbuild supports
generating offset header files.
@@ -867,18 +870,19 @@ When kbuild executes the following steps are followed (roughly):
corresponding arch-specific section for modules; the module-building
machinery is all architecture-independent.
-
+
head-y, init-y, core-y, libs-y, drivers-y, net-y
- $(head-y) list objects to be linked first in vmlinux.
- $(libs-y) list directories where a lib.a archive can be located.
- The rest list directories where a built-in.o object file can be located.
+ $(head-y) lists objects to be linked first in vmlinux.
+ $(libs-y) lists directories where a lib.a archive can be located.
+ The rest lists directories where a built-in.o object file can be
+ located.
$(init-y) objects will be located after $(head-y).
Then the rest follows in this order:
$(core-y), $(libs-y), $(drivers-y) and $(net-y).
- The top level Makefile define values for all generic directories,
+ The top level Makefile defines values for all generic directories,
and arch/$(ARCH)/Makefile only adds architecture specific directories.
Example:
@@ -915,27 +919,27 @@ When kbuild executes the following steps are followed (roughly):
"$(Q)$(MAKE) $(build)=" is the recommended way to invoke
make in a subdirectory.
- There are no rules for naming of the architecture specific targets,
+ There are no rules for naming architecture specific targets,
but executing "make help" will list all relevant targets.
- To support this $(archhelp) must be defined.
+ To support this, $(archhelp) must be defined.
Example:
#arch/i386/Makefile
define archhelp
echo '* bzImage - Image (arch/$(ARCH)/boot/bzImage)'
- endef
+ endif
When make is executed without arguments, the first goal encountered
will be built. In the top level Makefile the first goal present
is all:.
- An architecture shall always per default build a bootable image.
- In "make help" the default goal is highlighted with a '*'.
+ An architecture shall always, per default, build a bootable image.
+ In "make help", the default goal is highlighted with a '*'.
Add a new prerequisite to all: to select a default goal different
from vmlinux.
Example:
#arch/i386/Makefile
- all: bzImage
+ all: bzImage
When "make" is executed without arguments, bzImage will be built.
@@ -955,10 +959,10 @@ When kbuild executes the following steps are followed (roughly):
#arch/i386/kernel/Makefile
extra-y := head.o init_task.o
- In this example extra-y is used to list object files that
+ In this example, extra-y is used to list object files that
shall be built, but shall not be linked as part of built-in.o.
-
+
--- 6.6 Commands useful for building a boot image
Kbuild provides a few macros that are useful when building a
@@ -972,8 +976,8 @@ When kbuild executes the following steps are followed (roughly):
target: source(s) FORCE
$(call if_changed,ld/objcopy/gzip)
- When the rule is evaluated it is checked to see if any files
- needs an update, or the commandline has changed since last
+ When the rule is evaluated, it is checked to see if any files
+ needs an update, or the command line has changed since the last
invocation. The latter will force a rebuild if any options
to the executable have changed.
Any target that utilises if_changed must be listed in $(targets),
@@ -991,8 +995,8 @@ When kbuild executes the following steps are followed (roughly):
#WRONG!# $(call if_changed, ld/objcopy/gzip)
ld
- Link target. Often LDFLAGS_$@ is used to set specific options to ld.
-
+ Link target. Often, LDFLAGS_$@ is used to set specific options to ld.
+
objcopy
Copy binary. Uses OBJCOPYFLAGS usually specified in
arch/$(ARCH)/Makefile.
@@ -1010,10 +1014,10 @@ When kbuild executes the following steps are followed (roughly):
$(obj)/setup $(obj)/bootsect: %: %.o FORCE
$(call if_changed,ld)
- In this example there are two possible targets, requiring different
- options to the linker. the linker options are specified using the
+ In this example, there are two possible targets, requiring different
+ options to the linker. The linker options are specified using the
LDFLAGS_$@ syntax - one for each potential target.
- $(targets) are assinged all potential targets, herby kbuild knows
+ $(targets) are assinged all potential targets, by which kbuild knows
the targets and will:
1) check for commandline changes
2) delete target during make clean
@@ -1027,7 +1031,7 @@ When kbuild executes the following steps are followed (roughly):
--- 6.7 Custom kbuild commands
- When kbuild is executing with KBUILD_VERBOSE=0 then only a shorthand
+ When kbuild is executing with KBUILD_VERBOSE=0, then only a shorthand
of a command is normally displayed.
To enable this behaviour for custom commands kbuild requires
two variables to be set:
@@ -1045,34 +1049,34 @@ When kbuild executes the following steps are followed (roughly):
$(call if_changed,image)
@echo 'Kernel: $@ is ready'
- When updating the $(obj)/bzImage target the line:
+ When updating the $(obj)/bzImage target, the line
BUILD arch/i386/boot/bzImage
will be displayed with "make KBUILD_VERBOSE=0".
-
+
--- 6.8 Preprocessing linker scripts
- When the vmlinux image is build the linker script:
+ When the vmlinux image is built, the linker script
arch/$(ARCH)/kernel/vmlinux.lds is used.
The script is a preprocessed variant of the file vmlinux.lds.S
located in the same directory.
- kbuild knows .lds file and includes a rule *lds.S -> *lds.
-
+ kbuild knows .lds files and includes a rule *lds.S -> *lds.
+
Example:
#arch/i386/kernel/Makefile
always := vmlinux.lds
-
+
#Makefile
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
-
- The assigment to $(always) is used to tell kbuild to build the
- target: vmlinux.lds.
- The assignment to $(CPPFLAGS_vmlinux.lds) tell kbuild to use the
+
+ The assignment to $(always) is used to tell kbuild to build the
+ target vmlinux.lds.
+ The assignment to $(CPPFLAGS_vmlinux.lds) tells kbuild to use the
specified options when building the target vmlinux.lds.
-
- When building the *.lds target kbuild used the variakles:
+
+ When building the *.lds target, kbuild uses the variables:
CPPFLAGS : Set in top-level Makefile
EXTRA_CPPFLAGS : May be set in the kbuild makefile
CPPFLAGS_$(@F) : Target specific flags.
@@ -1147,7 +1151,7 @@ The top Makefile exports the following variables:
=== 8 Makefile language
-The kernel Makefiles are designed to run with GNU Make. The Makefiles
+The kernel Makefiles are designed to be run with GNU Make. The Makefiles
use only the documented features of GNU Make, but they do use many
GNU extensions.
@@ -1169,10 +1173,13 @@ is the right choice.
Original version made by Michael Elizabeth Chastain,
Updates by Kai Germaschewski
Updates by Sam Ravnborg
+Language QA by Jan Engelhardt
=== 10 TODO
-- Describe how kbuild support shipped files with _shipped.
+- Describe how kbuild supports shipped files with _shipped.
- Generating offset header files.
- Add more variables to section 7?
+
+
diff --git a/trunk/Documentation/kbuild/modules.txt b/trunk/Documentation/kbuild/modules.txt
index 61fc079eb966..2e7702e94a78 100644
--- a/trunk/Documentation/kbuild/modules.txt
+++ b/trunk/Documentation/kbuild/modules.txt
@@ -1,7 +1,7 @@
In this document you will find information about:
- how to build external modules
-- how to make your module use kbuild infrastructure
+- how to make your module use the kbuild infrastructure
- how kbuild will install a kernel
- how to install modules in a non-standard location
@@ -24,7 +24,7 @@ In this document you will find information about:
--- 6.1 INSTALL_MOD_PATH
--- 6.2 INSTALL_MOD_DIR
=== 7. Module versioning & Module.symvers
- --- 7.1 Symbols fron the kernel (vmlinux + modules)
+ --- 7.1 Symbols from the kernel (vmlinux + modules)
--- 7.2 Symbols and external modules
--- 7.3 Symbols from another external module
=== 8. Tips & Tricks
@@ -36,13 +36,13 @@ In this document you will find information about:
kbuild includes functionality for building modules both
within the kernel source tree and outside the kernel source tree.
-The latter is usually referred to as external modules and is used
-both during development and for modules that are not planned to be
-included in the kernel tree.
+The latter is usually referred to as external or "out-of-tree"
+modules and is used both during development and for modules that
+are not planned to be included in the kernel tree.
What is covered within this file is mainly information to authors
-of modules. The author of an external modules should supply
-a makefile that hides most of the complexity so one only has to type
+of modules. The author of an external module should supply
+a makefile that hides most of the complexity, so one only has to type
'make' to build the module. A complete example will be present in
chapter 4, "Creating a kbuild file for an external module".
@@ -63,14 +63,15 @@ when building an external module.
For the running kernel use:
make -C /lib/modules/`uname -r`/build M=`pwd`
- For the above command to succeed the kernel must have been built with
- modules enabled.
+ For the above command to succeed, the kernel must have been
+ built with modules enabled.
To install the modules that were just built:
make -C M=`pwd` modules_install
- More complex examples later, the above should get you going.
+ More complex examples will be shown later, the above should
+ be enough to get you started.
--- 2.2 Available targets
@@ -89,13 +90,13 @@ when building an external module.
Same functionality as if no target was specified.
See description above.
- make -C $KDIR M=$PWD modules_install
+ make -C $KDIR M=`pwd` modules_install
Install the external module(s).
Installation default is in /lib/modules//extra,
but may be prefixed with INSTALL_MOD_PATH - see separate
chapter.
- make -C $KDIR M=$PWD clean
+ make -C $KDIR M=`pwd` clean
Remove all generated files for the module - the kernel
source directory is not modified.
@@ -129,29 +130,28 @@ when building an external module.
To make sure the kernel contains the information required to
build external modules the target 'modules_prepare' must be used.
- 'module_prepare' solely exists as a simple way to prepare
- a kernel for building external modules.
+ 'module_prepare' exists solely as a simple way to prepare
+ a kernel source tree for building external modules.
Note: modules_prepare will not build Module.symvers even if
- CONFIG_MODULEVERSIONING is set.
- Therefore a full kernel build needs to be executed to make
- module versioning work.
+ CONFIG_MODULEVERSIONING is set. Therefore a full kernel build
+ needs to be executed to make module versioning work.
--- 2.5 Building separate files for a module
- It is possible to build single files which is part of a module.
- This works equal for the kernel, a module and even for external
- modules.
+ It is possible to build single files which are part of a module.
+ This works equally well for the kernel, a module and even for
+ external modules.
Examples (module foo.ko, consist of bar.o, baz.o):
make -C $KDIR M=`pwd` bar.lst
make -C $KDIR M=`pwd` bar.o
make -C $KDIR M=`pwd` foo.ko
make -C $KDIR M=`pwd` /
-
+
=== 3. Example commands
This example shows the actual commands to be executed when building
an external module for the currently running kernel.
-In the example below the distribution is supposed to use the
+In the example below, the distribution is supposed to use the
facility to locate output files for a kernel compile in a different
directory than the kernel source - but the examples will also work
when the source and the output files are mixed in the same directory.
@@ -170,14 +170,14 @@ the following commands to build the module:
O=/lib/modules/`uname-r`/build \
M=`pwd`
-Then to install the module use the following command:
+Then, to install the module use the following command:
make -C /usr/src/`uname -r`/source \
O=/lib/modules/`uname-r`/build \
M=`pwd` \
modules_install
-If one looks closely you will see that this is the same commands as
+If you look closely you will see that this is the same command as
listed before - with the directories spelled out.
The above are rather long commands, and the following chapter
@@ -230,7 +230,7 @@ following files:
endif
- In example 1 the check for KERNELRELEASE is used to separate
+ In example 1, the check for KERNELRELEASE is used to separate
the two parts of the Makefile. kbuild will only see the two
assignments whereas make will see everything except the two
kbuild assignments.
@@ -255,7 +255,7 @@ following files:
echo "X" > 8123_bin_shipped
- In example 2 we are down to two fairly simple files and for simple
+ In example 2, we are down to two fairly simple files and for simple
files as used in this example the split is questionable. But some
external modules use Makefiles of several hundred lines and here it
really pays off to separate the kbuild part from the rest.
@@ -282,9 +282,9 @@ following files:
endif
- The trick here is to include the Kbuild file from Makefile so
- if an older version of kbuild picks up the Makefile the Kbuild
- file will be included.
+ The trick here is to include the Kbuild file from Makefile, so
+ if an older version of kbuild picks up the Makefile, the Kbuild
+ file will be included.
--- 4.2 Binary blobs included in a module
@@ -301,18 +301,19 @@ following files:
obj-m := 8123.o
8123-y := 8123_if.o 8123_pci.o 8123_bin.o
- In example 4 there is no distinction between the ordinary .c/.h files
+ In example 4, there is no distinction between the ordinary .c/.h files
and the binary file. But kbuild will pick up different rules to create
the .o file.
=== 5. Include files
-Include files are a necessity when a .c file uses something from another .c
-files (not strictly in the sense of .c but if good programming practice is
-used). Any module that consist of more than one .c file will have a .h file
-for one of the .c files.
-- If the .h file only describes a module internal interface then the .h file
+Include files are a necessity when a .c file uses something from other .c
+files (not strictly in the sense of C, but if good programming practice is
+used). Any module that consists of more than one .c file will have a .h file
+for one of the .c files.
+
+- If the .h file only describes a module internal interface, then the .h file
shall be placed in the same directory as the .c files.
- If the .h files describe an interface used by other parts of the kernel
located in different directories, the .h files shall be located in
@@ -323,11 +324,11 @@ under include/ such as include/scsi. Another exception is arch-specific
.h files which are located under include/asm-$(ARCH)/*.
External modules have a tendency to locate include files in a separate include/
-directory and therefore needs to deal with this in their kbuild file.
+directory and therefore need to deal with this in their kbuild file.
--- 5.1 How to include files from the kernel include dir
- When a module needs to include a file from include/linux/ then one
+ When a module needs to include a file from include/linux/, then one
just uses:
#include
@@ -348,7 +349,7 @@ directory and therefore needs to deal with this in their kbuild file.
The trick here is to use either EXTRA_CFLAGS (take effect for all .c
files) or CFLAGS_$F.o (take effect only for a single file).
- In our example if we move 8123_if.h to a subdirectory named include/
+ In our example, if we move 8123_if.h to a subdirectory named include/
the resulting Kbuild file would look like:
--> filename: Kbuild
@@ -362,19 +363,19 @@ directory and therefore needs to deal with this in their kbuild file.
--- 5.3 External modules using several directories
- If an external module does not follow the usual kernel style but
- decide to spread files over several directories then kbuild can
- support this too.
+ If an external module does not follow the usual kernel style, but
+ decides to spread files over several directories, then kbuild can
+ handle this too.
Consider the following example:
-
+
|
+- src/complex_main.c
| +- hal/hardwareif.c
| +- hal/include/hardwareif.h
+- include/complex.h
-
- To build a single module named complex.ko we then need the following
+
+ To build a single module named complex.ko, we then need the following
kbuild file:
Kbuild:
@@ -387,12 +388,12 @@ directory and therefore needs to deal with this in their kbuild file.
kbuild knows how to handle .o files located in another directory -
- although this is NOT reccommended practice. The syntax is to specify
+ although this is NOT recommended practice. The syntax is to specify
the directory relative to the directory where the Kbuild file is
located.
- To find the .h files we have to explicitly tell kbuild where to look
- for the .h files. When kbuild executes current directory is always
+ To find the .h files, we have to explicitly tell kbuild where to look
+ for the .h files. When kbuild executes, the current directory is always
the root of the kernel tree (argument to -C) and therefore we have to
tell kbuild how to find the .h files using absolute paths.
$(src) will specify the absolute path to the directory where the
@@ -412,7 +413,7 @@ External modules are installed in the directory:
--- 6.1 INSTALL_MOD_PATH
- Above are the default directories, but as always some level of
+ Above are the default directories, but as always, some level of
customization is possible. One can prefix the path using the variable
INSTALL_MOD_PATH:
@@ -420,17 +421,17 @@ External modules are installed in the directory:
=> Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the
- example above be specified on the command line when calling make.
+ example above, can be specified on the command line when calling make.
INSTALL_MOD_PATH has effect both when installing modules included in
the kernel as well as when installing external modules.
--- 6.2 INSTALL_MOD_DIR
- When installing external modules they are default installed in a
+ When installing external modules they are by default installed to a
directory under /lib/modules/$(KERNELRELEASE)/extra, but one may wish
to locate modules for a specific functionality in a separate
- directory. For this purpose one can use INSTALL_MOD_DIR to specify an
- alternative name than 'extra'.
+ directory. For this purpose, one can use INSTALL_MOD_DIR to specify an
+ alternative name to 'extra'.
$ make INSTALL_MOD_DIR=gandalf -C KERNELDIR \
M=`pwd` modules_install
@@ -444,16 +445,16 @@ Module versioning is enabled by the CONFIG_MODVERSIONS tag.
Module versioning is used as a simple ABI consistency check. The Module
versioning creates a CRC value of the full prototype for an exported symbol and
when a module is loaded/used then the CRC values contained in the kernel are
-compared with similar values in the module. If they are not equal then the
+compared with similar values in the module. If they are not equal, then the
kernel refuses to load the module.
Module.symvers contains a list of all exported symbols from a kernel build.
--- 7.1 Symbols fron the kernel (vmlinux + modules)
- During a kernel build a file named Module.symvers will be generated.
+ During a kernel build, a file named Module.symvers will be generated.
Module.symvers contains all exported symbols from the kernel and
- compiled modules. For each symbols the corresponding CRC value
+ compiled modules. For each symbols, the corresponding CRC value
is stored too.
The syntax of the Module.symvers file is:
@@ -461,27 +462,27 @@ Module.symvers contains a list of all exported symbols from a kernel build.
Sample:
0x2d036834 scsi_remove_host drivers/scsi/scsi_mod
- For a kernel build without CONFIG_MODVERSIONING enabled the crc
+ For a kernel build without CONFIG_MODVERSIONS enabled, the crc
would read: 0x00000000
- Module.symvers serve two purposes.
- 1) It list all exported symbols both from vmlinux and all modules
- 2) It list CRC if CONFIG_MODVERSION is enabled
+ Module.symvers serves two purposes:
+ 1) It lists all exported symbols both from vmlinux and all modules
+ 2) It lists the CRC if CONFIG_MODVERSIONS is enabled
--- 7.2 Symbols and external modules
- When building an external module the build system needs access to
+ When building an external module, the build system needs access to
the symbols from the kernel to check if all external symbols are
defined. This is done in the MODPOST step and to obtain all
- symbols modpost reads Module.symvers from the kernel.
+ symbols, modpost reads Module.symvers from the kernel.
If a Module.symvers file is present in the directory where
- the external module is being build this file will be read too.
- During the MODPOST step a new Module.symvers file will be written
- containing all exported symbols that was not defined in the kernel.
-
+ the external module is being built, this file will be read too.
+ During the MODPOST step, a new Module.symvers file will be written
+ containing all exported symbols that were not defined in the kernel.
+
--- 7.3 Symbols from another external module
- Sometimes one external module uses exported symbols from another
+ Sometimes, an external module uses exported symbols from another
external module. Kbuild needs to have full knowledge on all symbols
to avoid spitting out warnings about undefined symbols.
Two solutions exist to let kbuild know all symbols of more than
@@ -490,15 +491,15 @@ Module.symvers contains a list of all exported symbols from a kernel build.
impractical in certain situations.
Use a top-level Kbuild file
- If you have two modules: 'foo', 'bar' and 'foo' needs symbols
- from 'bar' then one can use a common top-level kbuild file so
- both modules are compiled in same build.
+ If you have two modules: 'foo' and 'bar', and 'foo' needs
+ symbols from 'bar', then one can use a common top-level kbuild
+ file so both modules are compiled in same build.
Consider following directory layout:
./foo/ <= contains the foo module
./bar/ <= contains the bar module
The top-level Kbuild file would then look like:
-
+
#./Kbuild: (this file may also be named Makefile)
obj-y := foo/ bar/
@@ -509,23 +510,23 @@ Module.symvers contains a list of all exported symbols from a kernel build.
knowledge on symbols from both modules.
Use an extra Module.symvers file
- When an external module is build a Module.symvers file is
+ When an external module is built, a Module.symvers file is
generated containing all exported symbols which are not
defined in the kernel.
- To get access to symbols from module 'bar' one can copy the
+ To get access to symbols from module 'bar', one can copy the
Module.symvers file from the compilation of the 'bar' module
- to the directory where the 'foo' module is build.
- During the module build kbuild will read the Module.symvers
+ to the directory where the 'foo' module is built.
+ During the module build, kbuild will read the Module.symvers
file in the directory of the external module and when the
- build is finished a new Module.symvers file is created
+ build is finished, a new Module.symvers file is created
containing the sum of all symbols defined and not part of the
kernel.
-
+
=== 8. Tips & Tricks
--- 8.1 Testing for CONFIG_FOO_BAR
- Modules often needs to check for certain CONFIG_ options to decide if
+ Modules often need to check for certain CONFIG_ options to decide if
a specific feature shall be included in the module. When kbuild is used
this is done by referencing the CONFIG_ variable directly.
@@ -537,7 +538,7 @@ Module.symvers contains a list of all exported symbols from a kernel build.
External modules have traditionally used grep to check for specific
CONFIG_ settings directly in .config. This usage is broken.
- As introduced before external modules shall use kbuild when building
- and therefore can use the same methods as in-kernel modules when testing
- for CONFIG_ definitions.
+ As introduced before, external modules shall use kbuild when building
+ and therefore can use the same methods as in-kernel modules when
+ testing for CONFIG_ definitions.
diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt
index 7947cede8712..71d05f481727 100644
--- a/trunk/Documentation/kernel-parameters.txt
+++ b/trunk/Documentation/kernel-parameters.txt
@@ -697,6 +697,12 @@ running once the system is up.
ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
See header of drivers/scsi/ips.c.
+ ports= [IP_VS_FTP] IPVS ftp helper module
+ Default is 21.
+ Up to 8 (IP_VS_APP_MAX_PORTS) ports
+ may be specified.
+ Format: ,....
+
irqfixup [HW]
When an interrupt is not handled search all handlers
for it. Intended to get systems with badly broken
@@ -1183,8 +1189,6 @@ running once the system is up.
Mechanism 2.
nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI
Configuration
- mmconf [IA-32,X86_64] Force MMCONFIG. This is useful
- to override the builtin blacklist.
nomsi [MSI] If the PCI_MSI kernel config parameter is
enabled, this kernel boot option can be used to
disable the use of MSI interrupts system-wide.
diff --git a/trunk/Documentation/netlabel/00-INDEX b/trunk/Documentation/netlabel/00-INDEX
new file mode 100644
index 000000000000..837bf35990e2
--- /dev/null
+++ b/trunk/Documentation/netlabel/00-INDEX
@@ -0,0 +1,10 @@
+00-INDEX
+ - this file.
+cipso_ipv4.txt
+ - documentation on the IPv4 CIPSO protocol engine.
+draft-ietf-cipso-ipsecurity-01.txt
+ - IETF draft of the CIPSO protocol, dated 16 July 1992.
+introduction.txt
+ - NetLabel introduction, READ THIS FIRST.
+lsm_interface.txt
+ - documentation on the NetLabel kernel security module API.
diff --git a/trunk/Documentation/netlabel/cipso_ipv4.txt b/trunk/Documentation/netlabel/cipso_ipv4.txt
new file mode 100644
index 000000000000..93dacb132c3c
--- /dev/null
+++ b/trunk/Documentation/netlabel/cipso_ipv4.txt
@@ -0,0 +1,48 @@
+NetLabel CIPSO/IPv4 Protocol Engine
+==============================================================================
+Paul Moore, paul.moore@hp.com
+
+May 17, 2006
+
+ * Overview
+
+The NetLabel CIPSO/IPv4 protocol engine is based on the IETF Commercial IP
+Security Option (CIPSO) draft from July 16, 1992. A copy of this draft can be
+found in this directory, consult '00-INDEX' for the filename. While the IETF
+draft never made it to an RFC standard it has become a de-facto standard for
+labeled networking and is used in many trusted operating systems.
+
+ * Outbound Packet Processing
+
+The CIPSO/IPv4 protocol engine applies the CIPSO IP option to packets by
+adding the CIPSO label to the socket. This causes all packets leaving the
+system through the socket to have the CIPSO IP option applied. The socket's
+CIPSO label can be changed at any point in time, however, it is recommended
+that it is set upon the socket's creation. The LSM can set the socket's CIPSO
+label by using the NetLabel security module API; if the NetLabel "domain" is
+configured to use CIPSO for packet labeling then a CIPSO IP option will be
+generated and attached to the socket.
+
+ * Inbound Packet Processing
+
+The CIPSO/IPv4 protocol engine validates every CIPSO IP option it finds at the
+IP layer without any special handling required by the LSM. However, in order
+to decode and translate the CIPSO label on the packet the LSM must use the
+NetLabel security module API to extract the security attributes of the packet.
+This is typically done at the socket layer using the 'socket_sock_rcv_skb()'
+LSM hook.
+
+ * Label Translation
+
+The CIPSO/IPv4 protocol engine contains a mechanism to translate CIPSO security
+attributes such as sensitivity level and category to values which are
+appropriate for the host. These mappings are defined as part of a CIPSO
+Domain Of Interpretation (DOI) definition and are configured through the
+NetLabel user space communication layer. Each DOI definition can have a
+different security attribute mapping table.
+
+ * Label Translation Cache
+
+The NetLabel system provides a framework for caching security attribute
+mappings from the network labels to the corresponding LSM identifiers. The
+CIPSO/IPv4 protocol engine supports this caching mechanism.
diff --git a/trunk/Documentation/netlabel/draft-ietf-cipso-ipsecurity-01.txt b/trunk/Documentation/netlabel/draft-ietf-cipso-ipsecurity-01.txt
new file mode 100644
index 000000000000..256c2c9d4f50
--- /dev/null
+++ b/trunk/Documentation/netlabel/draft-ietf-cipso-ipsecurity-01.txt
@@ -0,0 +1,791 @@
+IETF CIPSO Working Group
+16 July, 1992
+
+
+
+ COMMERCIAL IP SECURITY OPTION (CIPSO 2.2)
+
+
+
+1. Status
+
+This Internet Draft provides the high level specification for a Commercial
+IP Security Option (CIPSO). This draft reflects the version as approved by
+the CIPSO IETF Working Group. Distribution of this memo is unlimited.
+
+This document is an Internet Draft. Internet Drafts are working documents
+of the Internet Engineering Task Force (IETF), its Areas, and its Working
+Groups. Note that other groups may also distribute working documents as
+Internet Drafts.
+
+Internet Drafts are draft documents valid for a maximum of six months.
+Internet Drafts may be updated, replaced, or obsoleted by other documents
+at any time. It is not appropriate to use Internet Drafts as reference
+material or to cite them other than as a "working draft" or "work in
+progress."
+
+Please check the I-D abstract listing contained in each Internet Draft
+directory to learn the current status of this or any other Internet Draft.
+
+
+
+
+2. Background
+
+Currently the Internet Protocol includes two security options. One of
+these options is the DoD Basic Security Option (BSO) (Type 130) which allows
+IP datagrams to be labeled with security classifications. This option
+provides sixteen security classifications and a variable number of handling
+restrictions. To handle additional security information, such as security
+categories or compartments, another security option (Type 133) exists and
+is referred to as the DoD Extended Security Option (ESO). The values for
+the fixed fields within these two options are administered by the Defense
+Information Systems Agency (DISA).
+
+Computer vendors are now building commercial operating systems with
+mandatory access controls and multi-level security. These systems are
+no longer built specifically for a particular group in the defense or
+intelligence communities. They are generally available commercial systems
+for use in a variety of government and civil sector environments.
+
+The small number of ESO format codes can not support all the possible
+applications of a commercial security option. The BSO and ESO were
+designed to only support the United States DoD. CIPSO has been designed
+to support multiple security policies. This Internet Draft provides the
+format and procedures required to support a Mandatory Access Control
+security policy. Support for additional security policies shall be
+defined in future RFCs.
+
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 1]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+
+3. CIPSO Format
+
+Option type: 134 (Class 0, Number 6, Copy on Fragmentation)
+Option length: Variable
+
+This option permits security related information to be passed between
+systems within a single Domain of Interpretation (DOI). A DOI is a
+collection of systems which agree on the meaning of particular values
+in the security option. An authority that has been assigned a DOI
+identifier will define a mapping between appropriate CIPSO field values
+and their human readable equivalent. This authority will distribute that
+mapping to hosts within the authority's domain. These mappings may be
+sensitive, therefore a DOI authority is not required to make these
+mappings available to anyone other than the systems that are included in
+the DOI.
+
+This option MUST be copied on fragmentation. This option appears at most
+once in a datagram. All multi-octet fields in the option are defined to be
+transmitted in network byte order. The format of this option is as follows:
+
++----------+----------+------//------+-----------//---------+
+| 10000110 | LLLLLLLL | DDDDDDDDDDDD | TTTTTTTTTTTTTTTTTTTT |
++----------+----------+------//------+-----------//---------+
+
+ TYPE=134 OPTION DOMAIN OF TAGS
+ LENGTH INTERPRETATION
+
+
+ Figure 1. CIPSO Format
+
+
+3.1 Type
+
+This field is 1 octet in length. Its value is 134.
+
+
+3.2 Length
+
+This field is 1 octet in length. It is the total length of the option
+including the type and length fields. With the current IP header length
+restriction of 40 octets the value of this field MUST not exceed 40.
+
+
+3.3 Domain of Interpretation Identifier
+
+This field is an unsigned 32 bit integer. The value 0 is reserved and MUST
+not appear as the DOI identifier in any CIPSO option. Implementations
+should assume that the DOI identifier field is not aligned on any particular
+byte boundary.
+
+To conserve space in the protocol, security levels and categories are
+represented by numbers rather than their ASCII equivalent. This requires
+a mapping table within CIPSO hosts to map these numbers to their
+corresponding ASCII representations. Non-related groups of systems may
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 2]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+have their own unique mappings. For example, one group of systems may
+use the number 5 to represent Unclassified while another group may use the
+number 1 to represent that same security level. The DOI identifier is used
+to identify which mapping was used for the values within the option.
+
+
+3.4 Tag Types
+
+A common format for passing security related information is necessary
+for interoperability. CIPSO uses sets of "tags" to contain the security
+information relevant to the data in the IP packet. Each tag begins with
+a tag type identifier followed by the length of the tag and ends with the
+actual security information to be passed. All multi-octet fields in a tag
+are defined to be transmitted in network byte order. Like the DOI
+identifier field in the CIPSO header, implementations should assume that
+all tags, as well as fields within a tag, are not aligned on any particular
+octet boundary. The tag types defined in this document contain alignment
+bytes to assist alignment of some information, however alignment can not
+be guaranteed if CIPSO is not the first IP option.
+
+CIPSO tag types 0 through 127 are reserved for defining standard tag
+formats. Their definitions will be published in RFCs. Tag types whose
+identifiers are greater than 127 are defined by the DOI authority and may
+only be meaningful in certain Domains of Interpretation. For these tag
+types, implementations will require the DOI identifier as well as the tag
+number to determine the security policy and the format associated with the
+tag. Use of tag types above 127 are restricted to closed networks where
+interoperability with other networks will not be an issue. Implementations
+that support a tag type greater than 127 MUST support at least one DOI that
+requires only tag types 1 to 127.
+
+Tag type 0 is reserved. Tag types 1, 2, and 5 are defined in this
+Internet Draft. Types 3 and 4 are reserved for work in progress.
+The standard format for all current and future CIPSO tags is shown below:
+
++----------+----------+--------//--------+
+| TTTTTTTT | LLLLLLLL | IIIIIIIIIIIIIIII |
++----------+----------+--------//--------+
+ TAG TAG TAG
+ TYPE LENGTH INFORMATION
+
+ Figure 2: Standard Tag Format
+
+In the three tag types described in this document, the length and count
+restrictions are based on the current IP limitation of 40 octets for all
+IP options. If the IP header is later expanded, then the length and count
+restrictions specified in this document may increase to use the full area
+provided for IP options.
+
+
+3.4.1 Tag Type Classes
+
+Tag classes consist of tag types that have common processing requirements
+and support the same security policy. The three tags defined in this
+Internet Draft belong to the Mandatory Access Control (MAC) Sensitivity
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 3]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+class and support the MAC Sensitivity security policy.
+
+
+3.4.2 Tag Type 1
+
+This is referred to as the "bit-mapped" tag type. Tag type 1 is included
+in the MAC Sensitivity tag type class. The format of this tag type is as
+follows:
+
++----------+----------+----------+----------+--------//---------+
+| 00000001 | LLLLLLLL | 00000000 | LLLLLLLL | CCCCCCCCCCCCCCCCC |
++----------+----------+----------+----------+--------//---------+
+
+ TAG TAG ALIGNMENT SENSITIVITY BIT MAP OF
+ TYPE LENGTH OCTET LEVEL CATEGORIES
+
+ Figure 3. Tag Type 1 Format
+
+
+3.4.2.1 Tag Type
+
+This field is 1 octet in length and has a value of 1.
+
+
+3.4.2.2 Tag Length
+
+This field is 1 octet in length. It is the total length of the tag type
+including the type and length fields. With the current IP header length
+restriction of 40 bytes the value within this field is between 4 and 34.
+
+
+3.4.2.3 Alignment Octet
+
+This field is 1 octet in length and always has the value of 0. Its purpose
+is to align the category bitmap field on an even octet boundary. This will
+speed many implementations including router implementations.
+
+
+3.4.2.4 Sensitivity Level
+
+This field is 1 octet in length. Its value is from 0 to 255. The values
+are ordered with 0 being the minimum value and 255 representing the maximum
+value.
+
+
+3.4.2.5 Bit Map of Categories
+
+The length of this field is variable and ranges from 0 to 30 octets. This
+provides representation of categories 0 to 239. The ordering of the bits
+is left to right or MSB to LSB. For example category 0 is represented by
+the most significant bit of the first byte and category 15 is represented
+by the least significant bit of the second byte. Figure 4 graphically
+shows this ordering. Bit N is binary 1 if category N is part of the label
+for the datagram, and bit N is binary 0 if category N is not part of the
+label. Except for the optimized tag 1 format described in the next section,
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 4]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+minimal encoding SHOULD be used resulting in no trailing zero octets in the
+category bitmap.
+
+ octet 0 octet 1 octet 2 octet 3 octet 4 octet 5
+ XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX . . .
+bit 01234567 89111111 11112222 22222233 33333333 44444444
+number 012345 67890123 45678901 23456789 01234567
+
+ Figure 4. Ordering of Bits in Tag 1 Bit Map
+
+
+3.4.2.6 Optimized Tag 1 Format
+
+Routers work most efficiently when processing fixed length fields. To
+support these routers there is an optimized form of tag type 1. The format
+does not change. The only change is to the category bitmap which is set to
+a constant length of 10 octets. Trailing octets required to fill out the 10
+octets are zero filled. Ten octets, allowing for 80 categories, was chosen
+because it makes the total length of the CIPSO option 20 octets. If CIPSO
+is the only option then the option will be full word aligned and additional
+filler octets will not be required.
+
+
+3.4.3 Tag Type 2
+
+This is referred to as the "enumerated" tag type. It is used to describe
+large but sparsely populated sets of categories. Tag type 2 is in the MAC
+Sensitivity tag type class. The format of this tag type is as follows:
+
++----------+----------+----------+----------+-------------//-------------+
+| 00000010 | LLLLLLLL | 00000000 | LLLLLLLL | CCCCCCCCCCCCCCCCCCCCCCCCCC |
++----------+----------+----------+----------+-------------//-------------+
+
+ TAG TAG ALIGNMENT SENSITIVITY ENUMERATED
+ TYPE LENGTH OCTET LEVEL CATEGORIES
+
+ Figure 5. Tag Type 2 Format
+
+
+3.4.3.1 Tag Type
+
+This field is one octet in length and has a value of 2.
+
+
+3.4.3.2 Tag Length
+
+This field is 1 octet in length. It is the total length of the tag type
+including the type and length fields. With the current IP header length
+restriction of 40 bytes the value within this field is between 4 and 34.
+
+
+3.4.3.3 Alignment Octet
+
+This field is 1 octet in length and always has the value of 0. Its purpose
+is to align the category field on an even octet boundary. This will
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 5]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+speed many implementations including router implementations.
+
+
+3.4.3.4 Sensitivity Level
+
+This field is 1 octet in length. Its value is from 0 to 255. The values
+are ordered with 0 being the minimum value and 255 representing the
+maximum value.
+
+
+3.4.3.5 Enumerated Categories
+
+In this tag, categories are represented by their actual value rather than
+by their position within a bit field. The length of each category is 2
+octets. Up to 15 categories may be represented by this tag. Valid values
+for categories are 0 to 65534. Category 65535 is not a valid category
+value. The categories MUST be listed in ascending order within the tag.
+
+
+3.4.4 Tag Type 5
+
+This is referred to as the "range" tag type. It is used to represent
+labels where all categories in a range, or set of ranges, are included
+in the sensitivity label. Tag type 5 is in the MAC Sensitivity tag type
+class. The format of this tag type is as follows:
+
++----------+----------+----------+----------+------------//-------------+
+| 00000101 | LLLLLLLL | 00000000 | LLLLLLLL | Top/Bottom | Top/Bottom |
++----------+----------+----------+----------+------------//-------------+
+
+ TAG TAG ALIGNMENT SENSITIVITY CATEGORY RANGES
+ TYPE LENGTH OCTET LEVEL
+
+ Figure 6. Tag Type 5 Format
+
+
+3.4.4.1 Tag Type
+
+This field is one octet in length and has a value of 5.
+
+
+3.4.4.2 Tag Length
+
+This field is 1 octet in length. It is the total length of the tag type
+including the type and length fields. With the current IP header length
+restriction of 40 bytes the value within this field is between 4 and 34.
+
+
+3.4.4.3 Alignment Octet
+
+This field is 1 octet in length and always has the value of 0. Its purpose
+is to align the category range field on an even octet boundary. This will
+speed many implementations including router implementations.
+
+
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 6]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+3.4.4.4 Sensitivity Level
+
+This field is 1 octet in length. Its value is from 0 to 255. The values
+are ordered with 0 being the minimum value and 255 representing the maximum
+value.
+
+
+3.4.4.5 Category Ranges
+
+A category range is a 4 octet field comprised of the 2 octet index of the
+highest numbered category followed by the 2 octet index of the lowest
+numbered category. These range endpoints are inclusive within the range of
+categories. All categories within a range are included in the sensitivity
+label. This tag may contain a maximum of 7 category pairs. The bottom
+category endpoint for the last pair in the tag MAY be omitted and SHOULD be
+assumed to be 0. The ranges MUST be non-overlapping and be listed in
+descending order. Valid values for categories are 0 to 65534. Category
+65535 is not a valid category value.
+
+
+3.4.5 Minimum Requirements
+
+A CIPSO implementation MUST be capable of generating at least tag type 1 in
+the non-optimized form. In addition, a CIPSO implementation MUST be able
+to receive any valid tag type 1 even those using the optimized tag type 1
+format.
+
+
+4. Configuration Parameters
+
+The configuration parameters defined below are required for all CIPSO hosts,
+gateways, and routers that support multiple sensitivity labels. A CIPSO
+host is defined to be the origination or destination system for an IP
+datagram. A CIPSO gateway provides IP routing services between two or more
+IP networks and may be required to perform label translations between
+networks. A CIPSO gateway may be an enhanced CIPSO host or it may just
+provide gateway services with no end system CIPSO capabilities. A CIPSO
+router is a dedicated IP router that routes IP datagrams between two or more
+IP networks.
+
+An implementation of CIPSO on a host MUST have the capability to reject a
+datagram for reasons that the information contained can not be adequately
+protected by the receiving host or if acceptance may result in violation of
+the host or network security policy. In addition, a CIPSO gateway or router
+MUST be able to reject datagrams going to networks that can not provide
+adequate protection or may violate the network's security policy. To
+provide this capability the following minimal set of configuration
+parameters are required for CIPSO implementations:
+
+HOST_LABEL_MAX - This parameter contains the maximum sensitivity label that
+a CIPSO host is authorized to handle. All datagrams that have a label
+greater than this maximum MUST be rejected by the CIPSO host. This
+parameter does not apply to CIPSO gateways or routers. This parameter need
+not be defined explicitly as it can be implicitly derived from the
+PORT_LABEL_MAX parameters for the associated interfaces.
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 7]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+
+HOST_LABEL_MIN - This parameter contains the minimum sensitivity label that
+a CIPSO host is authorized to handle. All datagrams that have a label less
+than this minimum MUST be rejected by the CIPSO host. This parameter does
+not apply to CIPSO gateways or routers. This parameter need not be defined
+explicitly as it can be implicitly derived from the PORT_LABEL_MIN
+parameters for the associated interfaces.
+
+PORT_LABEL_MAX - This parameter contains the maximum sensitivity label for
+all datagrams that may exit a particular network interface port. All
+outgoing datagrams that have a label greater than this maximum MUST be
+rejected by the CIPSO system. The label within this parameter MUST be
+less than or equal to the label within the HOST_LABEL_MAX parameter. This
+parameter does not apply to CIPSO hosts that support only one network port.
+
+PORT_LABEL_MIN - This parameter contains the minimum sensitivity label for
+all datagrams that may exit a particular network interface port. All
+outgoing datagrams that have a label less than this minimum MUST be
+rejected by the CIPSO system. The label within this parameter MUST be
+greater than or equal to the label within the HOST_LABEL_MIN parameter.
+This parameter does not apply to CIPSO hosts that support only one network
+port.
+
+PORT_DOI - This parameter is used to assign a DOI identifier value to a
+particular network interface port. All CIPSO labels within datagrams
+going out this port MUST use the specified DOI identifier. All CIPSO
+hosts and gateways MUST support either this parameter, the NET_DOI
+parameter, or the HOST_DOI parameter.
+
+NET_DOI - This parameter is used to assign a DOI identifier value to a
+particular IP network address. All CIPSO labels within datagrams destined
+for the particular IP network MUST use the specified DOI identifier. All
+CIPSO hosts and gateways MUST support either this parameter, the PORT_DOI
+parameter, or the HOST_DOI parameter.
+
+HOST_DOI - This parameter is used to assign a DOI identifier value to a
+particular IP host address. All CIPSO labels within datagrams destined for
+the particular IP host will use the specified DOI identifier. All CIPSO
+hosts and gateways MUST support either this parameter, the PORT_DOI
+parameter, or the NET_DOI parameter.
+
+This list represents the minimal set of configuration parameters required
+to be compliant. Implementors are encouraged to add to this list to
+provide enhanced functionality and control. For example, many security
+policies may require both incoming and outgoing datagrams be checked against
+the port and host label ranges.
+
+
+4.1 Port Range Parameters
+
+The labels represented by the PORT_LABEL_MAX and PORT_LABEL_MIN parameters
+MAY be in CIPSO or local format. Some CIPSO systems, such as routers, may
+want to have the range parameters expressed in CIPSO format so that incoming
+labels do not have to be converted to a local format before being compared
+against the range. If multiple DOIs are supported by one of these CIPSO
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 8]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+systems then multiple port range parameters would be needed, one set for
+each DOI supported on a particular port.
+
+The port range will usually represent the total set of labels that may
+exist on the logical network accessed through the corresponding network
+interface. It may, however, represent a subset of these labels that are
+allowed to enter the CIPSO system.
+
+
+4.2 Single Label CIPSO Hosts
+
+CIPSO implementations that support only one label are not required to
+support the parameters described above. These limited implementations are
+only required to support a NET_LABEL parameter. This parameter contains
+the CIPSO label that may be inserted in datagrams that exit the host. In
+addition, the host MUST reject any incoming datagram that has a label which
+is not equivalent to the NET_LABEL parameter.
+
+
+5. Handling Procedures
+
+This section describes the processing requirements for incoming and
+outgoing IP datagrams. Just providing the correct CIPSO label format
+is not enough. Assumptions will be made by one system on how a
+receiving system will handle the CIPSO label. Wrong assumptions may
+lead to non-interoperability or even a security incident. The
+requirements described below represent the minimal set needed for
+interoperability and that provide users some level of confidence.
+Many other requirements could be added to increase user confidence,
+however at the risk of restricting creativity and limiting vendor
+participation.
+
+
+5.1 Input Procedures
+
+All datagrams received through a network port MUST have a security label
+associated with them, either contained in the datagram or assigned to the
+receiving port. Without this label the host, gateway, or router will not
+have the information it needs to make security decisions. This security
+label will be obtained from the CIPSO if the option is present in the
+datagram. See section 4.1.2 for handling procedures for unlabeled
+datagrams. This label will be compared against the PORT (if appropriate)
+and HOST configuration parameters defined in section 3.
+
+If any field within the CIPSO option, such as the DOI identifier, is not
+recognized the IP datagram is discarded and an ICMP "parameter problem"
+(type 12) is generated and returned. The ICMP code field is set to "bad
+parameter" (code 0) and the pointer is set to the start of the CIPSO field
+that is unrecognized.
+
+If the contents of the CIPSO are valid but the security label is
+outside of the configured host or port label range, the datagram is
+discarded and an ICMP "destination unreachable" (type 3) is generated
+and returned. The code field of the ICMP is set to "communication with
+destination network administratively prohibited" (code 9) or to
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 9]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+"communication with destination host administratively prohibited"
+(code 10). The value of the code field used is dependent upon whether
+the originator of the ICMP message is acting as a CIPSO host or a CIPSO
+gateway. The recipient of the ICMP message MUST be able to handle either
+value. The same procedure is performed if a CIPSO can not be added to an
+IP packet because it is too large to fit in the IP options area.
+
+If the error is triggered by receipt of an ICMP message, the message
+is discarded and no response is permitted (consistent with general ICMP
+processing rules).
+
+
+5.1.1 Unrecognized tag types
+
+The default condition for any CIPSO implementation is that an
+unrecognized tag type MUST be treated as a "parameter problem" and
+handled as described in section 4.1. A CIPSO implementation MAY allow
+the system administrator to identify tag types that may safely be
+ignored. This capability is an allowable enhancement, not a
+requirement.
+
+
+5.1.2 Unlabeled Packets
+
+A network port may be configured to not require a CIPSO label for all
+incoming datagrams. For this configuration a CIPSO label must be
+assigned to that network port and associated with all unlabeled IP
+datagrams. This capability might be used for single level networks or
+networks that have CIPSO and non-CIPSO hosts and the non-CIPSO hosts
+all operate at the same label.
+
+If a CIPSO option is required and none is found, the datagram is
+discarded and an ICMP "parameter problem" (type 12) is generated and
+returned to the originator of the datagram. The code field of the ICMP
+is set to "option missing" (code 1) and the ICMP pointer is set to 134
+(the value of the option type for the missing CIPSO option).
+
+
+5.2 Output Procedures
+
+A CIPSO option MUST appear only once in a datagram. Only one tag type
+from the MAC Sensitivity class MAY be included in a CIPSO option. Given
+the current set of defined tag types, this means that CIPSO labels at
+first will contain only one tag.
+
+All datagrams leaving a CIPSO system MUST meet the following condition:
+
+ PORT_LABEL_MIN <= CIPSO label <= PORT_LABEL_MAX
+
+If this condition is not satisfied the datagram MUST be discarded.
+If the CIPSO system only supports one port, the HOST_LABEL_MIN and the
+HOST_LABEL_MAX parameters MAY be substituted for the PORT parameters in
+the above condition.
+
+The DOI identifier to be used for all outgoing datagrams is configured by
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 10]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+the administrator. If port level DOI identifier assignment is used, then
+the PORT_DOI configuration parameter MUST contain the DOI identifier to
+use. If network level DOI assignment is used, then the NET_DOI parameter
+MUST contain the DOI identifier to use. And if host level DOI assignment
+is employed, then the HOST_DOI parameter MUST contain the DOI identifier
+to use. A CIPSO implementation need only support one level of DOI
+assignment.
+
+
+5.3 DOI Processing Requirements
+
+A CIPSO implementation MUST support at least one DOI and SHOULD support
+multiple DOIs. System and network administrators are cautioned to
+ensure that at least one DOI is common within an IP network to allow for
+broadcasting of IP datagrams.
+
+CIPSO gateways MUST be capable of translating a CIPSO option from one
+DOI to another when forwarding datagrams between networks. For
+efficiency purposes this capability is only a desired feature for CIPSO
+routers.
+
+
+5.4 Label of ICMP Messages
+
+The CIPSO label to be used on all outgoing ICMP messages MUST be equivalent
+to the label of the datagram that caused the ICMP message. If the ICMP was
+generated due to a problem associated with the original CIPSO label then the
+following responses are allowed:
+
+ a. Use the CIPSO label of the original IP datagram
+ b. Drop the original datagram with no return message generated
+
+In most cases these options will have the same effect. If you can not
+interpret the label or if it is outside the label range of your host or
+interface then an ICMP message with the same label will probably not be
+able to exit the system.
+
+
+6. Assignment of DOI Identifier Numbers =
+
+Requests for assignment of a DOI identifier number should be addressed to
+the Internet Assigned Numbers Authority (IANA).
+
+
+7. Acknowledgements
+
+Much of the material in this RFC is based on (and copied from) work
+done by Gary Winiger of Sun Microsystems and published as Commercial
+IP Security Option at the INTEROP 89, Commercial IPSO Workshop.
+
+
+8. Author's Address
+
+To submit mail for distribution to members of the IETF CIPSO Working
+Group, send mail to: cipso@wdl1.wdl.loral.com.
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 11]
+
+
+
+CIPSO INTERNET DRAFT 16 July, 1992
+
+
+
+
+To be added to or deleted from this distribution, send mail to:
+cipso-request@wdl1.wdl.loral.com.
+
+
+9. References
+
+RFC 1038, "Draft Revised IP Security Option", M. St. Johns, IETF, January
+1988.
+
+RFC 1108, "U.S. Department of Defense Security Options
+for the Internet Protocol", Stephen Kent, IAB, 1 March, 1991.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Internet Draft, Expires 15 Jan 93 [PAGE 12]
+
+
+
diff --git a/trunk/Documentation/netlabel/introduction.txt b/trunk/Documentation/netlabel/introduction.txt
new file mode 100644
index 000000000000..a4ffba1694c8
--- /dev/null
+++ b/trunk/Documentation/netlabel/introduction.txt
@@ -0,0 +1,46 @@
+NetLabel Introduction
+==============================================================================
+Paul Moore, paul.moore@hp.com
+
+August 2, 2006
+
+ * Overview
+
+NetLabel is a mechanism which can be used by kernel security modules to attach
+security attributes to outgoing network packets generated from user space
+applications and read security attributes from incoming network packets. It
+is composed of three main components, the protocol engines, the communication
+layer, and the kernel security module API.
+
+ * Protocol Engines
+
+The protocol engines are responsible for both applying and retrieving the
+network packet's security attributes. If any translation between the network
+security attributes and those on the host are required then the protocol
+engine will handle those tasks as well. Other kernel subsystems should
+refrain from calling the protocol engines directly, instead they should use
+the NetLabel kernel security module API described below.
+
+Detailed information about each NetLabel protocol engine can be found in this
+directory, consult '00-INDEX' for filenames.
+
+ * Communication Layer
+
+The communication layer exists to allow NetLabel configuration and monitoring
+from user space. The NetLabel communication layer uses a message based
+protocol built on top of the Generic NETLINK transport mechanism. The exact
+formatting of these NetLabel messages as well as the Generic NETLINK family
+names can be found in the the 'net/netlabel/' directory as comments in the
+header files as well as in 'include/net/netlabel.h'.
+
+ * Security Module API
+
+The purpose of the NetLabel security module API is to provide a protocol
+independent interface to the underlying NetLabel protocol engines. In addition
+to protocol independence, the security module API is designed to be completely
+LSM independent which should allow multiple LSMs to leverage the same code
+base.
+
+Detailed information about the NetLabel security module API can be found in the
+'include/net/netlabel.h' header file as well as the 'lsm_interface.txt' file
+found in this directory.
diff --git a/trunk/Documentation/netlabel/lsm_interface.txt b/trunk/Documentation/netlabel/lsm_interface.txt
new file mode 100644
index 000000000000..98dd9f7430f2
--- /dev/null
+++ b/trunk/Documentation/netlabel/lsm_interface.txt
@@ -0,0 +1,47 @@
+NetLabel Linux Security Module Interface
+==============================================================================
+Paul Moore, paul.moore@hp.com
+
+May 17, 2006
+
+ * Overview
+
+NetLabel is a mechanism which can set and retrieve security attributes from
+network packets. It is intended to be used by LSM developers who want to make
+use of a common code base for several different packet labeling protocols.
+The NetLabel security module API is defined in 'include/net/netlabel.h' but a
+brief overview is given below.
+
+ * NetLabel Security Attributes
+
+Since NetLabel supports multiple different packet labeling protocols and LSMs
+it uses the concept of security attributes to refer to the packet's security
+labels. The NetLabel security attributes are defined by the
+'netlbl_lsm_secattr' structure in the NetLabel header file. Internally the
+NetLabel subsystem converts the security attributes to and from the correct
+low-level packet label depending on the NetLabel build time and run time
+configuration. It is up to the LSM developer to translate the NetLabel
+security attributes into whatever security identifiers are in use for their
+particular LSM.
+
+ * NetLabel LSM Protocol Operations
+
+These are the functions which allow the LSM developer to manipulate the labels
+on outgoing packets as well as read the labels on incoming packets. Functions
+exist to operate both on sockets as well as the sk_buffs directly. These high
+level functions are translated into low level protocol operations based on how
+the administrator has configured the NetLabel subsystem.
+
+ * NetLabel Label Mapping Cache Operations
+
+Depending on the exact configuration, translation between the network packet
+label and the internal LSM security identifier can be time consuming. The
+NetLabel label mapping cache is a caching mechanism which can be used to
+sidestep much of this overhead once a mapping has been established. Once the
+LSM has received a packet, used NetLabel to decode it's security attributes,
+and translated the security attributes into a LSM internal identifier the LSM
+can use the NetLabel caching functions to associate the LSM internal
+identifier with the network packet's label. This means that in the future
+when a incoming packet matches a cached value not only are the internal
+NetLabel translation mechanisms bypassed but the LSM translation mechanisms are
+bypassed as well which should result in a significant reduction in overhead.
diff --git a/trunk/Documentation/networking/LICENSE.qla3xxx b/trunk/Documentation/networking/LICENSE.qla3xxx
new file mode 100644
index 000000000000..2f2077e34d81
--- /dev/null
+++ b/trunk/Documentation/networking/LICENSE.qla3xxx
@@ -0,0 +1,46 @@
+Copyright (c) 2003-2006 QLogic Corporation
+QLogic Linux Networking HBA Driver
+
+This program includes a device driver for Linux 2.6 that may be
+distributed with QLogic hardware specific firmware binary file.
+You may modify and redistribute the device driver code under the
+GNU General Public License as published by the Free Software
+Foundation (version 2 or a later version).
+
+You may redistribute the hardware specific firmware binary file
+under the following terms:
+
+ 1. Redistribution of source code (only if applicable),
+ must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ 2. Redistribution in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ 3. The name of QLogic Corporation may not be used to
+ endorse or promote products derived from this software
+ without specific prior written permission
+
+REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE,
+THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT
+CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR
+OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT,
+TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
+ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
+COMBINATION WITH THIS PROGRAM.
+
diff --git a/trunk/Documentation/networking/dccp.txt b/trunk/Documentation/networking/dccp.txt
index c45daabd3bfe..74563b38ffd9 100644
--- a/trunk/Documentation/networking/dccp.txt
+++ b/trunk/Documentation/networking/dccp.txt
@@ -1,7 +1,6 @@
DCCP protocol
============
-Last updated: 10 November 2005
Contents
========
@@ -42,8 +41,11 @@ Socket options
DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for
calculations.
-DCCP_SOCKOPT_SERVICE sets the service. This is compulsory as per the
-specification. If you don't set it you will get EPROTO.
+DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of
+service codes (RFC 4340, sec. 8.1.2); if this socket option is not set,
+the socket will fall back to 0 (which means that no meaningful service code
+is present). Connecting sockets set at most one service option; for
+listening sockets, multiple service codes can be specified.
Notes
=====
diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt
index 3e0c017e7877..935e298f674a 100644
--- a/trunk/Documentation/networking/ip-sysctl.txt
+++ b/trunk/Documentation/networking/ip-sysctl.txt
@@ -102,9 +102,15 @@ inet_peer_gc_maxtime - INTEGER
TCP variables:
tcp_abc - INTEGER
- Controls Appropriate Byte Count defined in RFC3465. If set to
- 0 then does congestion avoid once per ack. 1 is conservative
- value, and 2 is more agressive.
+ Controls Appropriate Byte Count (ABC) defined in RFC3465.
+ ABC is a way of increasing congestion window (cwnd) more slowly
+ in response to partial acknowledgments.
+ Possible values are:
+ 0 increase cwnd once per acknowledgment (no ABC)
+ 1 increase cwnd once per acknowledgment of full sized segment
+ 2 allow increase cwnd by two if acknowledgment is
+ of two segments to compensate for delayed acknowledgments.
+ Default: 0 (off)
tcp_syn_retries - INTEGER
Number of times initial SYNs for an active TCP connection attempt
@@ -369,6 +375,41 @@ tcp_slow_start_after_idle - BOOLEAN
be timed out after an idle period.
Default: 1
+CIPSOv4 Variables:
+
+cipso_cache_enable - BOOLEAN
+ If set, enable additions to and lookups from the CIPSO label mapping
+ cache. If unset, additions are ignored and lookups always result in a
+ miss. However, regardless of the setting the cache is still
+ invalidated when required when means you can safely toggle this on and
+ off and the cache will always be "safe".
+ Default: 1
+
+cipso_cache_bucket_size - INTEGER
+ The CIPSO label cache consists of a fixed size hash table with each
+ hash bucket containing a number of cache entries. This variable limits
+ the number of entries in each hash bucket; the larger the value the
+ more CIPSO label mappings that can be cached. When the number of
+ entries in a given hash bucket reaches this limit adding new entries
+ causes the oldest entry in the bucket to be removed to make room.
+ Default: 10
+
+cipso_rbm_optfmt - BOOLEAN
+ Enable the "Optimized Tag 1 Format" as defined in section 3.4.2.6 of
+ the CIPSO draft specification (see Documentation/netlabel for details).
+ This means that when set the CIPSO tag will be padded with empty
+ categories in order to make the packet data 32-bit aligned.
+ Default: 0
+
+cipso_rbm_structvalid - BOOLEAN
+ If set, do a very strict check of the CIPSO option when
+ ip_options_compile() is called. If unset, relax the checks done during
+ ip_options_compile(). Either way is "safe" as errors are caught else
+ where in the CIPSO processing code but setting this to 0 (False) should
+ result in less work (i.e. it should be faster) but could cause problems
+ with other implementations that require strict checking.
+ Default: 0
+
IP Variables:
ip_local_port_range - 2 INTEGERS
@@ -724,6 +765,9 @@ conf/all/forwarding - BOOLEAN
This referred to as global forwarding.
+proxy_ndp - BOOLEAN
+ Do proxy ndp.
+
conf/interface/*:
Change special settings per interface.
diff --git a/trunk/Documentation/networking/secid.txt b/trunk/Documentation/networking/secid.txt
new file mode 100644
index 000000000000..95ea06784333
--- /dev/null
+++ b/trunk/Documentation/networking/secid.txt
@@ -0,0 +1,14 @@
+flowi structure:
+
+The secid member in the flow structure is used in LSMs (e.g. SELinux) to indicate
+the label of the flow. This label of the flow is currently used in selecting
+matching labeled xfrm(s).
+
+If this is an outbound flow, the label is derived from the socket, if any, or
+the incoming packet this flow is being generated as a response to (e.g. tcp
+resets, timewait ack, etc.). It is also conceivable that the label could be
+derived from other sources such as process context, device, etc., in special
+cases, as may be appropriate.
+
+If this is an inbound flow, the label is derived from the IPSec security
+associations, if any, used by the packet.
diff --git a/trunk/Documentation/scsi/ChangeLog.arcmsr b/trunk/Documentation/scsi/ChangeLog.arcmsr
new file mode 100644
index 000000000000..162c47fdf45f
--- /dev/null
+++ b/trunk/Documentation/scsi/ChangeLog.arcmsr
@@ -0,0 +1,56 @@
+**************************************************************************
+** History
+**
+** REV# DATE NAME DESCRIPTION
+** 1.00.00.00 3/31/2004 Erich Chen First release
+** 1.10.00.04 7/28/2004 Erich Chen modify for ioctl
+** 1.10.00.06 8/28/2004 Erich Chen modify for 2.6.x
+** 1.10.00.08 9/28/2004 Erich Chen modify for x86_64
+** 1.10.00.10 10/10/2004 Erich Chen bug fix for SMP & ioctl
+** 1.20.00.00 11/29/2004 Erich Chen bug fix with arcmsr_bus_reset when PHY error
+** 1.20.00.02 12/09/2004 Erich Chen bug fix with over 2T bytes RAID Volume
+** 1.20.00.04 1/09/2005 Erich Chen fits for Debian linux kernel version 2.2.xx
+** 1.20.00.05 2/20/2005 Erich Chen cleanly as look like a Linux driver at 2.6.x
+** thanks for peoples kindness comment
+** Kornel Wieliczek
+** Christoph Hellwig
+** Adrian Bunk
+** Andrew Morton
+** Christoph Hellwig
+** James Bottomley
+** Arjan van de Ven
+** 1.20.00.06 3/12/2005 Erich Chen fix with arcmsr_pci_unmap_dma "unsigned long" cast,
+** modify PCCB POOL allocated by "dma_alloc_coherent"
+** (Kornel Wieliczek's comment)
+** 1.20.00.07 3/23/2005 Erich Chen bug fix with arcmsr_scsi_host_template_init
+** occur segmentation fault,
+** if RAID adapter does not on PCI slot
+** and modprobe/rmmod this driver twice.
+** bug fix enormous stack usage (Adrian Bunk's comment)
+** 1.20.00.08 6/23/2005 Erich Chen bug fix with abort command,
+** in case of heavy loading when sata cable
+** working on low quality connection
+** 1.20.00.09 9/12/2005 Erich Chen bug fix with abort command handling, firmware version check
+** and firmware update notify for hardware bug fix
+** 1.20.00.10 9/23/2005 Erich Chen enhance sysfs function for change driver's max tag Q number.
+** add DMA_64BIT_MASK for backward compatible with all 2.6.x
+** add some useful message for abort command
+** add ioctl code 'ARCMSR_IOCTL_FLUSH_ADAPTER_CACHE'
+** customer can send this command for sync raid volume data
+** 1.20.00.11 9/29/2005 Erich Chen by comment of Arjan van de Ven fix incorrect msleep redefine
+** cast off sizeof(dma_addr_t) condition for 64bit pci_set_dma_mask
+** 1.20.00.12 9/30/2005 Erich Chen bug fix with 64bit platform's ccbs using if over 4G system memory
+** change 64bit pci_set_consistent_dma_mask into 32bit
+** increcct adapter count if adapter initialize fail.
+** miss edit at arcmsr_build_ccb....
+** psge += sizeof(struct _SG64ENTRY *) =>
+** psge += sizeof(struct _SG64ENTRY)
+** 64 bits sg entry would be incorrectly calculated
+** thanks Kornel Wieliczek give me kindly notify
+** and detail description
+** 1.20.00.13 11/15/2005 Erich Chen scheduling pending ccb with FIFO
+** change the architecture of arcmsr command queue list
+** for linux standard list
+** enable usage of pci message signal interrupt
+** follow Randy.Danlup kindness suggestion cleanup this code
+**************************************************************************
\ No newline at end of file
diff --git a/trunk/Documentation/scsi/aacraid.txt b/trunk/Documentation/scsi/aacraid.txt
index be55670851a4..ee03678c8029 100644
--- a/trunk/Documentation/scsi/aacraid.txt
+++ b/trunk/Documentation/scsi/aacraid.txt
@@ -11,38 +11,43 @@ the original).
Supported Cards/Chipsets
-------------------------
PCI ID (pci.ids) OEM Product
- 9005:0285:9005:028a Adaptec 2020ZCR (Skyhawk)
- 9005:0285:9005:028e Adaptec 2020SA (Skyhawk)
- 9005:0285:9005:028b Adaptec 2025ZCR (Terminator)
- 9005:0285:9005:028f Adaptec 2025SA (Terminator)
- 9005:0285:9005:0286 Adaptec 2120S (Crusader)
- 9005:0286:9005:028d Adaptec 2130S (Lancer)
+ 9005:0283:9005:0283 Adaptec Catapult (3210S with arc firmware)
+ 9005:0284:9005:0284 Adaptec Tomcat (3410S with arc firmware)
9005:0285:9005:0285 Adaptec 2200S (Vulcan)
+ 9005:0285:9005:0286 Adaptec 2120S (Crusader)
9005:0285:9005:0287 Adaptec 2200S (Vulcan-2m)
+ 9005:0285:9005:0288 Adaptec 3230S (Harrier)
+ 9005:0285:9005:0289 Adaptec 3240S (Tornado)
+ 9005:0285:9005:028a Adaptec 2020ZCR (Skyhawk)
+ 9005:0285:9005:028b Adaptec 2025ZCR (Terminator)
9005:0286:9005:028c Adaptec 2230S (Lancer)
9005:0286:9005:028c Adaptec 2230SLP (Lancer)
- 9005:0285:9005:0296 Adaptec 2240S (SabreExpress)
+ 9005:0286:9005:028d Adaptec 2130S (Lancer)
+ 9005:0285:9005:028e Adaptec 2020SA (Skyhawk)
+ 9005:0285:9005:028f Adaptec 2025SA (Terminator)
9005:0285:9005:0290 Adaptec 2410SA (Jaguar)
- 9005:0285:9005:0293 Adaptec 21610SA (Corsair-16)
9005:0285:103c:3227 Adaptec 2610SA (Bearcat HP release)
+ 9005:0285:9005:0293 Adaptec 21610SA (Corsair-16)
+ 9005:0285:9005:0296 Adaptec 2240S (SabreExpress)
9005:0285:9005:0292 Adaptec 2810SA (Corsair-8)
9005:0285:9005:0294 Adaptec Prowler
- 9005:0286:9005:029d Adaptec 2420SA (Intruder HP release)
- 9005:0286:9005:029c Adaptec 2620SA (Intruder)
- 9005:0286:9005:029b Adaptec 2820SA (Intruder)
- 9005:0286:9005:02a7 Adaptec 2830SA (Skyray)
- 9005:0286:9005:02a8 Adaptec 2430SA (Skyray)
- 9005:0285:9005:0288 Adaptec 3230S (Harrier)
- 9005:0285:9005:0289 Adaptec 3240S (Tornado)
- 9005:0285:9005:0298 Adaptec 4000SAS (BlackBird)
9005:0285:9005:0297 Adaptec 4005SAS (AvonPark)
+ 9005:0285:9005:0298 Adaptec 4000SAS (BlackBird)
9005:0285:9005:0299 Adaptec 4800SAS (Marauder-X)
9005:0285:9005:029a Adaptec 4805SAS (Marauder-E)
+ 9005:0286:9005:029b Adaptec 2820SA (Intruder)
+ 9005:0286:9005:029c Adaptec 2620SA (Intruder)
+ 9005:0286:9005:029d Adaptec 2420SA (Intruder HP release)
9005:0286:9005:02a2 Adaptec 3800SAS (Hurricane44)
+ 9005:0286:9005:02a7 Adaptec 3805SAS (Hurricane80)
+ 9005:0286:9005:02a8 Adaptec 3400SAS (Hurricane40)
+ 9005:0286:9005:02ac Adaptec 1800SAS (Typhoon44)
+ 9005:0286:9005:02b3 Adaptec 2400SAS (Hurricane40lm)
+ 9005:0285:9005:02b5 Adaptec ASR5800 (Voodoo44)
+ 9005:0285:9005:02b6 Adaptec ASR5805 (Voodoo80)
+ 9005:0285:9005:02b7 Adaptec ASR5808 (Voodoo08)
1011:0046:9005:0364 Adaptec 5400S (Mustang)
1011:0046:9005:0365 Adaptec 5400S (Mustang)
- 9005:0283:9005:0283 Adaptec Catapult (3210S with arc firmware)
- 9005:0284:9005:0284 Adaptec Tomcat (3410S with arc firmware)
9005:0287:9005:0800 Adaptec Themisto (Jupiter)
9005:0200:9005:0200 Adaptec Themisto (Jupiter)
9005:0286:9005:0800 Adaptec Callisto (Jupiter)
@@ -64,18 +69,20 @@ Supported Cards/Chipsets
9005:0285:9005:0290 IBM ServeRAID 7t (Jaguar)
9005:0285:1014:02F2 IBM ServeRAID 8i (AvonPark)
9005:0285:1014:0312 IBM ServeRAID 8i (AvonParkLite)
- 9005:0286:1014:9580 IBM ServeRAID 8k/8k-l8 (Aurora)
9005:0286:1014:9540 IBM ServeRAID 8k/8k-l4 (AuroraLite)
- 9005:0286:9005:029f ICP ICP9014R0 (Lancer)
+ 9005:0286:1014:9580 IBM ServeRAID 8k/8k-l8 (Aurora)
+ 9005:0286:1014:034d IBM ServeRAID 8s (Hurricane)
9005:0286:9005:029e ICP ICP9024R0 (Lancer)
+ 9005:0286:9005:029f ICP ICP9014R0 (Lancer)
9005:0286:9005:02a0 ICP ICP9047MA (Lancer)
9005:0286:9005:02a1 ICP ICP9087MA (Lancer)
+ 9005:0286:9005:02a3 ICP ICP5445AU (Hurricane44)
9005:0286:9005:02a4 ICP ICP9085LI (Marauder-X)
9005:0286:9005:02a5 ICP ICP5085BR (Marauder-E)
- 9005:0286:9005:02a3 ICP ICP5445AU (Hurricane44)
9005:0286:9005:02a6 ICP ICP9067MA (Intruder-6)
- 9005:0286:9005:02a9 ICP ICP5087AU (Skyray)
- 9005:0286:9005:02aa ICP ICP5047AU (Skyray)
+ 9005:0286:9005:02a9 ICP ICP5085AU (Hurricane80)
+ 9005:0286:9005:02aa ICP ICP5045AU (Hurricane40)
+ 9005:0286:9005:02b4 ICP ICP5045AL (Hurricane40lm)
People
-------------------------
diff --git a/trunk/Documentation/scsi/arcmsr_spec.txt b/trunk/Documentation/scsi/arcmsr_spec.txt
new file mode 100644
index 000000000000..5e0042340fd3
--- /dev/null
+++ b/trunk/Documentation/scsi/arcmsr_spec.txt
@@ -0,0 +1,574 @@
+*******************************************************************************
+** ARECA FIRMWARE SPEC
+*******************************************************************************
+** Usage of IOP331 adapter
+** (All In/Out is in IOP331's view)
+** 1. Message 0 --> InitThread message and retrun code
+** 2. Doorbell is used for RS-232 emulation
+** inDoorBell : bit0 -- data in ready
+** (DRIVER DATA WRITE OK)
+** bit1 -- data out has been read
+** (DRIVER DATA READ OK)
+** outDooeBell: bit0 -- data out ready
+** (IOP331 DATA WRITE OK)
+** bit1 -- data in has been read
+** (IOP331 DATA READ OK)
+** 3. Index Memory Usage
+** offset 0xf00 : for RS232 out (request buffer)
+** offset 0xe00 : for RS232 in (scratch buffer)
+** offset 0xa00 : for inbound message code message_rwbuffer
+** (driver send to IOP331)
+** offset 0xa00 : for outbound message code message_rwbuffer
+** (IOP331 send to driver)
+** 4. RS-232 emulation
+** Currently 128 byte buffer is used
+** 1st uint32_t : Data length (1--124)
+** Byte 4--127 : Max 124 bytes of data
+** 5. PostQ
+** All SCSI Command must be sent through postQ:
+** (inbound queue port) Request frame must be 32 bytes aligned
+** #bit27--bit31 => flag for post ccb
+** #bit0--bit26 => real address (bit27--bit31) of post arcmsr_cdb
+** bit31 :
+** 0 : 256 bytes frame
+** 1 : 512 bytes frame
+** bit30 :
+** 0 : normal request
+** 1 : BIOS request
+** bit29 : reserved
+** bit28 : reserved
+** bit27 : reserved
+** ---------------------------------------------------------------------------
+** (outbount queue port) Request reply
+** #bit27--bit31
+** => flag for reply
+** #bit0--bit26
+** => real address (bit27--bit31) of reply arcmsr_cdb
+** bit31 : must be 0 (for this type of reply)
+** bit30 : reserved for BIOS handshake
+** bit29 : reserved
+** bit28 :
+** 0 : no error, ignore AdapStatus/DevStatus/SenseData
+** 1 : Error, error code in AdapStatus/DevStatus/SenseData
+** bit27 : reserved
+** 6. BIOS request
+** All BIOS request is the same with request from PostQ
+** Except :
+** Request frame is sent from configuration space
+** offset: 0x78 : Request Frame (bit30 == 1)
+** offset: 0x18 : writeonly to generate
+** IRQ to IOP331
+** Completion of request:
+** (bit30 == 0, bit28==err flag)
+** 7. Definition of SGL entry (structure)
+** 8. Message1 Out - Diag Status Code (????)
+** 9. Message0 message code :
+** 0x00 : NOP
+** 0x01 : Get Config
+** ->offset 0xa00 :for outbound message code message_rwbuffer
+** (IOP331 send to driver)
+** Signature 0x87974060(4)
+** Request len 0x00000200(4)
+** numbers of queue 0x00000100(4)
+** SDRAM Size 0x00000100(4)-->256 MB
+** IDE Channels 0x00000008(4)
+** vendor 40 bytes char
+** model 8 bytes char
+** FirmVer 16 bytes char
+** Device Map 16 bytes char
+** FirmwareVersion DWORD <== Added for checking of
+** new firmware capability
+** 0x02 : Set Config
+** ->offset 0xa00 :for inbound message code message_rwbuffer
+** (driver send to IOP331)
+** Signature 0x87974063(4)
+** UPPER32 of Request Frame (4)-->Driver Only
+** 0x03 : Reset (Abort all queued Command)
+** 0x04 : Stop Background Activity
+** 0x05 : Flush Cache
+** 0x06 : Start Background Activity
+** (re-start if background is halted)
+** 0x07 : Check If Host Command Pending
+** (Novell May Need This Function)
+** 0x08 : Set controller time
+** ->offset 0xa00 : for inbound message code message_rwbuffer
+** (driver to IOP331)
+** byte 0 : 0xaa <-- signature
+** byte 1 : 0x55 <-- signature
+** byte 2 : year (04)
+** byte 3 : month (1..12)
+** byte 4 : date (1..31)
+** byte 5 : hour (0..23)
+** byte 6 : minute (0..59)
+** byte 7 : second (0..59)
+*******************************************************************************
+*******************************************************************************
+** RS-232 Interface for Areca Raid Controller
+** The low level command interface is exclusive with VT100 terminal
+** --------------------------------------------------------------------
+** 1. Sequence of command execution
+** --------------------------------------------------------------------
+** (A) Header : 3 bytes sequence (0x5E, 0x01, 0x61)
+** (B) Command block : variable length of data including length,
+** command code, data and checksum byte
+** (C) Return data : variable length of data
+** --------------------------------------------------------------------
+** 2. Command block
+** --------------------------------------------------------------------
+** (A) 1st byte : command block length (low byte)
+** (B) 2nd byte : command block length (high byte)
+** note ..command block length shouldn't > 2040 bytes,
+** length excludes these two bytes
+** (C) 3rd byte : command code
+** (D) 4th and following bytes : variable length data bytes
+** depends on command code
+** (E) last byte : checksum byte (sum of 1st byte until last data byte)
+** --------------------------------------------------------------------
+** 3. Command code and associated data
+** --------------------------------------------------------------------
+** The following are command code defined in raid controller Command
+** code 0x10--0x1? are used for system level management,
+** no password checking is needed and should be implemented in separate
+** well controlled utility and not for end user access.
+** Command code 0x20--0x?? always check the password,
+** password must be entered to enable these command.
+** enum
+** {
+** GUI_SET_SERIAL=0x10,
+** GUI_SET_VENDOR,
+** GUI_SET_MODEL,
+** GUI_IDENTIFY,
+** GUI_CHECK_PASSWORD,
+** GUI_LOGOUT,
+** GUI_HTTP,
+** GUI_SET_ETHERNET_ADDR,
+** GUI_SET_LOGO,
+** GUI_POLL_EVENT,
+** GUI_GET_EVENT,
+** GUI_GET_HW_MONITOR,
+** // GUI_QUICK_CREATE=0x20, (function removed)
+** GUI_GET_INFO_R=0x20,
+** GUI_GET_INFO_V,
+** GUI_GET_INFO_P,
+** GUI_GET_INFO_S,
+** GUI_CLEAR_EVENT,
+** GUI_MUTE_BEEPER=0x30,
+** GUI_BEEPER_SETTING,
+** GUI_SET_PASSWORD,
+** GUI_HOST_INTERFACE_MODE,
+** GUI_REBUILD_PRIORITY,
+** GUI_MAX_ATA_MODE,
+** GUI_RESET_CONTROLLER,
+** GUI_COM_PORT_SETTING,
+** GUI_NO_OPERATION,
+** GUI_DHCP_IP,
+** GUI_CREATE_PASS_THROUGH=0x40,
+** GUI_MODIFY_PASS_THROUGH,
+** GUI_DELETE_PASS_THROUGH,
+** GUI_IDENTIFY_DEVICE,
+** GUI_CREATE_RAIDSET=0x50,
+** GUI_DELETE_RAIDSET,
+** GUI_EXPAND_RAIDSET,
+** GUI_ACTIVATE_RAIDSET,
+** GUI_CREATE_HOT_SPARE,
+** GUI_DELETE_HOT_SPARE,
+** GUI_CREATE_VOLUME=0x60,
+** GUI_MODIFY_VOLUME,
+** GUI_DELETE_VOLUME,
+** GUI_START_CHECK_VOLUME,
+** GUI_STOP_CHECK_VOLUME
+** };
+** Command description :
+** GUI_SET_SERIAL : Set the controller serial#
+** byte 0,1 : length
+** byte 2 : command code 0x10
+** byte 3 : password length (should be 0x0f)
+** byte 4-0x13 : should be "ArEcATecHnoLogY"
+** byte 0x14--0x23 : Serial number string (must be 16 bytes)
+** GUI_SET_VENDOR : Set vendor string for the controller
+** byte 0,1 : length
+** byte 2 : command code 0x11
+** byte 3 : password length (should be 0x08)
+** byte 4-0x13 : should be "ArEcAvAr"
+** byte 0x14--0x3B : vendor string (must be 40 bytes)
+** GUI_SET_MODEL : Set the model name of the controller
+** byte 0,1 : length
+** byte 2 : command code 0x12
+** byte 3 : password length (should be 0x08)
+** byte 4-0x13 : should be "ArEcAvAr"
+** byte 0x14--0x1B : model string (must be 8 bytes)
+** GUI_IDENTIFY : Identify device
+** byte 0,1 : length
+** byte 2 : command code 0x13
+** return "Areca RAID Subsystem "
+** GUI_CHECK_PASSWORD : Verify password
+** byte 0,1 : length
+** byte 2 : command code 0x14
+** byte 3 : password length
+** byte 4-0x?? : user password to be checked
+** GUI_LOGOUT : Logout GUI (force password checking on next command)
+** byte 0,1 : length
+** byte 2 : command code 0x15
+** GUI_HTTP : HTTP interface (reserved for Http proxy service)(0x16)
+**
+** GUI_SET_ETHERNET_ADDR : Set the ethernet MAC address
+** byte 0,1 : length
+** byte 2 : command code 0x17
+** byte 3 : password length (should be 0x08)
+** byte 4-0x13 : should be "ArEcAvAr"
+** byte 0x14--0x19 : Ethernet MAC address (must be 6 bytes)
+** GUI_SET_LOGO : Set logo in HTTP
+** byte 0,1 : length
+** byte 2 : command code 0x18
+** byte 3 : Page# (0/1/2/3) (0xff --> clear OEM logo)
+** byte 4/5/6/7 : 0x55/0xaa/0xa5/0x5a
+** byte 8 : TITLE.JPG data (each page must be 2000 bytes)
+** note page0 1st 2 byte must be
+** actual length of the JPG file
+** GUI_POLL_EVENT : Poll If Event Log Changed
+** byte 0,1 : length
+** byte 2 : command code 0x19
+** GUI_GET_EVENT : Read Event
+** byte 0,1 : length
+** byte 2 : command code 0x1a
+** byte 3 : Event Page (0:1st page/1/2/3:last page)
+** GUI_GET_HW_MONITOR : Get HW monitor data
+** byte 0,1 : length
+** byte 2 : command code 0x1b
+** byte 3 : # of FANs(example 2)
+** byte 4 : # of Voltage sensor(example 3)
+** byte 5 : # of temperature sensor(example 2)
+** byte 6 : # of power
+** byte 7/8 : Fan#0 (RPM)
+** byte 9/10 : Fan#1
+** byte 11/12 : Voltage#0 original value in *1000
+** byte 13/14 : Voltage#0 value
+** byte 15/16 : Voltage#1 org
+** byte 17/18 : Voltage#1
+** byte 19/20 : Voltage#2 org
+** byte 21/22 : Voltage#2
+** byte 23 : Temp#0
+** byte 24 : Temp#1
+** byte 25 : Power indicator (bit0 : power#0,
+** bit1 : power#1)
+** byte 26 : UPS indicator
+** GUI_QUICK_CREATE : Quick create raid/volume set
+** byte 0,1 : length
+** byte 2 : command code 0x20
+** byte 3/4/5/6 : raw capacity
+** byte 7 : raid level
+** byte 8 : stripe size
+** byte 9 : spare
+** byte 10/11/12/13: device mask (the devices to create raid/volume)
+** This function is removed, application like
+** to implement quick create function
+** need to use GUI_CREATE_RAIDSET and GUI_CREATE_VOLUMESET function.
+** GUI_GET_INFO_R : Get Raid Set Information
+** byte 0,1 : length
+** byte 2 : command code 0x20
+** byte 3 : raidset#
+** typedef struct sGUI_RAIDSET
+** {
+** BYTE grsRaidSetName[16];
+** DWORD grsCapacity;
+** DWORD grsCapacityX;
+** DWORD grsFailMask;
+** BYTE grsDevArray[32];
+** BYTE grsMemberDevices;
+** BYTE grsNewMemberDevices;
+** BYTE grsRaidState;
+** BYTE grsVolumes;
+** BYTE grsVolumeList[16];
+** BYTE grsRes1;
+** BYTE grsRes2;
+** BYTE grsRes3;
+** BYTE grsFreeSegments;
+** DWORD grsRawStripes[8];
+** DWORD grsRes4;
+** DWORD grsRes5; // Total to 128 bytes
+** DWORD grsRes6; // Total to 128 bytes
+** } sGUI_RAIDSET, *pGUI_RAIDSET;
+** GUI_GET_INFO_V : Get Volume Set Information
+** byte 0,1 : length
+** byte 2 : command code 0x21
+** byte 3 : volumeset#
+** typedef struct sGUI_VOLUMESET
+** {
+** BYTE gvsVolumeName[16]; // 16
+** DWORD gvsCapacity;
+** DWORD gvsCapacityX;
+** DWORD gvsFailMask;
+** DWORD gvsStripeSize;
+** DWORD gvsNewFailMask;
+** DWORD gvsNewStripeSize;
+** DWORD gvsVolumeStatus;
+** DWORD gvsProgress; // 32
+** sSCSI_ATTR gvsScsi;
+** BYTE gvsMemberDisks;
+** BYTE gvsRaidLevel; // 8
+** BYTE gvsNewMemberDisks;
+** BYTE gvsNewRaidLevel;
+** BYTE gvsRaidSetNumber;
+** BYTE gvsRes0; // 4
+** BYTE gvsRes1[4]; // 64 bytes
+** } sGUI_VOLUMESET, *pGUI_VOLUMESET;
+** GUI_GET_INFO_P : Get Physical Drive Information
+** byte 0,1 : length
+** byte 2 : command code 0x22
+** byte 3 : drive # (from 0 to max-channels - 1)
+** typedef struct sGUI_PHY_DRV
+** {
+** BYTE gpdModelName[40];
+** BYTE gpdSerialNumber[20];
+** BYTE gpdFirmRev[8];
+** DWORD gpdCapacity;
+** DWORD gpdCapacityX; // Reserved for expansion
+** BYTE gpdDeviceState;
+** BYTE gpdPioMode;
+** BYTE gpdCurrentUdmaMode;
+** BYTE gpdUdmaMode;
+** BYTE gpdDriveSelect;
+** BYTE gpdRaidNumber; // 0xff if not belongs to a raid set
+** sSCSI_ATTR gpdScsi;
+** BYTE gpdReserved[40]; // Total to 128 bytes
+** } sGUI_PHY_DRV, *pGUI_PHY_DRV;
+** GUI_GET_INFO_S : Get System Information
+** byte 0,1 : length
+** byte 2 : command code 0x23
+** typedef struct sCOM_ATTR
+** {
+** BYTE comBaudRate;
+** BYTE comDataBits;
+** BYTE comStopBits;
+** BYTE comParity;
+** BYTE comFlowControl;
+** } sCOM_ATTR, *pCOM_ATTR;
+** typedef struct sSYSTEM_INFO
+** {
+** BYTE gsiVendorName[40];
+** BYTE gsiSerialNumber[16];
+** BYTE gsiFirmVersion[16];
+** BYTE gsiBootVersion[16];
+** BYTE gsiMbVersion[16];
+** BYTE gsiModelName[8];
+** BYTE gsiLocalIp[4];
+** BYTE gsiCurrentIp[4];
+** DWORD gsiTimeTick;
+** DWORD gsiCpuSpeed;
+** DWORD gsiICache;
+** DWORD gsiDCache;
+** DWORD gsiScache;
+** DWORD gsiMemorySize;
+** DWORD gsiMemorySpeed;
+** DWORD gsiEvents;
+** BYTE gsiMacAddress[6];
+** BYTE gsiDhcp;
+** BYTE gsiBeeper;
+** BYTE gsiChannelUsage;
+** BYTE gsiMaxAtaMode;
+** BYTE gsiSdramEcc; // 1:if ECC enabled
+** BYTE gsiRebuildPriority;
+** sCOM_ATTR gsiComA; // 5 bytes
+** sCOM_ATTR gsiComB; // 5 bytes
+** BYTE gsiIdeChannels;
+** BYTE gsiScsiHostChannels;
+** BYTE gsiIdeHostChannels;
+** BYTE gsiMaxVolumeSet;
+** BYTE gsiMaxRaidSet;
+** BYTE gsiEtherPort; // 1:if ether net port supported
+** BYTE gsiRaid6Engine; // 1:Raid6 engine supported
+** BYTE gsiRes[75];
+** } sSYSTEM_INFO, *pSYSTEM_INFO;
+** GUI_CLEAR_EVENT : Clear System Event
+** byte 0,1 : length
+** byte 2 : command code 0x24
+** GUI_MUTE_BEEPER : Mute current beeper
+** byte 0,1 : length
+** byte 2 : command code 0x30
+** GUI_BEEPER_SETTING : Disable beeper
+** byte 0,1 : length
+** byte 2 : command code 0x31
+** byte 3 : 0->disable, 1->enable
+** GUI_SET_PASSWORD : Change password
+** byte 0,1 : length
+** byte 2 : command code 0x32
+** byte 3 : pass word length ( must <= 15 )
+** byte 4 : password (must be alpha-numerical)
+** GUI_HOST_INTERFACE_MODE : Set host interface mode
+** byte 0,1 : length
+** byte 2 : command code 0x33
+** byte 3 : 0->Independent, 1->cluster
+** GUI_REBUILD_PRIORITY : Set rebuild priority
+** byte 0,1 : length
+** byte 2 : command code 0x34
+** byte 3 : 0/1/2/3 (low->high)
+** GUI_MAX_ATA_MODE : Set maximum ATA mode to be used
+** byte 0,1 : length
+** byte 2 : command code 0x35
+** byte 3 : 0/1/2/3 (133/100/66/33)
+** GUI_RESET_CONTROLLER : Reset Controller
+** byte 0,1 : length
+** byte 2 : command code 0x36
+** *Response with VT100 screen (discard it)
+** GUI_COM_PORT_SETTING : COM port setting
+** byte 0,1 : length
+** byte 2 : command code 0x37
+** byte 3 : 0->COMA (term port),
+** 1->COMB (debug port)
+** byte 4 : 0/1/2/3/4/5/6/7
+** (1200/2400/4800/9600/19200/38400/57600/115200)
+** byte 5 : data bit
+** (0:7 bit, 1:8 bit : must be 8 bit)
+** byte 6 : stop bit (0:1, 1:2 stop bits)
+** byte 7 : parity (0:none, 1:off, 2:even)
+** byte 8 : flow control
+** (0:none, 1:xon/xoff, 2:hardware => must use none)
+** GUI_NO_OPERATION : No operation
+** byte 0,1 : length
+** byte 2 : command code 0x38
+** GUI_DHCP_IP : Set DHCP option and local IP address
+** byte 0,1 : length
+** byte 2 : command code 0x39
+** byte 3 : 0:dhcp disabled, 1:dhcp enabled
+** byte 4/5/6/7 : IP address
+** GUI_CREATE_PASS_THROUGH : Create pass through disk
+** byte 0,1 : length
+** byte 2 : command code 0x40
+** byte 3 : device #
+** byte 4 : scsi channel (0/1)
+** byte 5 : scsi id (0-->15)
+** byte 6 : scsi lun (0-->7)
+** byte 7 : tagged queue (1 : enabled)
+** byte 8 : cache mode (1 : enabled)
+** byte 9 : max speed (0/1/2/3/4,
+** async/20/40/80/160 for scsi)
+** (0/1/2/3/4, 33/66/100/133/150 for ide )
+** GUI_MODIFY_PASS_THROUGH : Modify pass through disk
+** byte 0,1 : length
+** byte 2 : command code 0x41
+** byte 3 : device #
+** byte 4 : scsi channel (0/1)
+** byte 5 : scsi id (0-->15)
+** byte 6 : scsi lun (0-->7)
+** byte 7 : tagged queue (1 : enabled)
+** byte 8 : cache mode (1 : enabled)
+** byte 9 : max speed (0/1/2/3/4,
+** async/20/40/80/160 for scsi)
+** (0/1/2/3/4, 33/66/100/133/150 for ide )
+** GUI_DELETE_PASS_THROUGH : Delete pass through disk
+** byte 0,1 : length
+** byte 2 : command code 0x42
+** byte 3 : device# to be deleted
+** GUI_IDENTIFY_DEVICE : Identify Device
+** byte 0,1 : length
+** byte 2 : command code 0x43
+** byte 3 : Flash Method
+** (0:flash selected, 1:flash not selected)
+** byte 4/5/6/7 : IDE device mask to be flashed
+** note .... no response data available
+** GUI_CREATE_RAIDSET : Create Raid Set
+** byte 0,1 : length
+** byte 2 : command code 0x50
+** byte 3/4/5/6 : device mask
+** byte 7-22 : raidset name (if byte 7 == 0:use default)
+** GUI_DELETE_RAIDSET : Delete Raid Set
+** byte 0,1 : length
+** byte 2 : command code 0x51
+** byte 3 : raidset#
+** GUI_EXPAND_RAIDSET : Expand Raid Set
+** byte 0,1 : length
+** byte 2 : command code 0x52
+** byte 3 : raidset#
+** byte 4/5/6/7 : device mask for expansion
+** byte 8/9/10 : (8:0 no change, 1 change, 0xff:terminate,
+** 9:new raid level,
+** 10:new stripe size
+** 0/1/2/3/4/5->4/8/16/32/64/128K )
+** byte 11/12/13 : repeat for each volume in the raidset
+** GUI_ACTIVATE_RAIDSET : Activate incomplete raid set
+** byte 0,1 : length
+** byte 2 : command code 0x53
+** byte 3 : raidset#
+** GUI_CREATE_HOT_SPARE : Create hot spare disk
+** byte 0,1 : length
+** byte 2 : command code 0x54
+** byte 3/4/5/6 : device mask for hot spare creation
+** GUI_DELETE_HOT_SPARE : Delete hot spare disk
+** byte 0,1 : length
+** byte 2 : command code 0x55
+** byte 3/4/5/6 : device mask for hot spare deletion
+** GUI_CREATE_VOLUME : Create volume set
+** byte 0,1 : length
+** byte 2 : command code 0x60
+** byte 3 : raidset#
+** byte 4-19 : volume set name
+** (if byte4 == 0, use default)
+** byte 20-27 : volume capacity (blocks)
+** byte 28 : raid level
+** byte 29 : stripe size
+** (0/1/2/3/4/5->4/8/16/32/64/128K)
+** byte 30 : channel
+** byte 31 : ID
+** byte 32 : LUN
+** byte 33 : 1 enable tag
+** byte 34 : 1 enable cache
+** byte 35 : speed
+** (0/1/2/3/4->async/20/40/80/160 for scsi)
+** (0/1/2/3/4->33/66/100/133/150 for IDE )
+** byte 36 : 1 to select quick init
+**
+** GUI_MODIFY_VOLUME : Modify volume Set
+** byte 0,1 : length
+** byte 2 : command code 0x61
+** byte 3 : volumeset#
+** byte 4-19 : new volume set name
+** (if byte4 == 0, not change)
+** byte 20-27 : new volume capacity (reserved)
+** byte 28 : new raid level
+** byte 29 : new stripe size
+** (0/1/2/3/4/5->4/8/16/32/64/128K)
+** byte 30 : new channel
+** byte 31 : new ID
+** byte 32 : new LUN
+** byte 33 : 1 enable tag
+** byte 34 : 1 enable cache
+** byte 35 : speed
+** (0/1/2/3/4->async/20/40/80/160 for scsi)
+** (0/1/2/3/4->33/66/100/133/150 for IDE )
+** GUI_DELETE_VOLUME : Delete volume set
+** byte 0,1 : length
+** byte 2 : command code 0x62
+** byte 3 : volumeset#
+** GUI_START_CHECK_VOLUME : Start volume consistency check
+** byte 0,1 : length
+** byte 2 : command code 0x63
+** byte 3 : volumeset#
+** GUI_STOP_CHECK_VOLUME : Stop volume consistency check
+** byte 0,1 : length
+** byte 2 : command code 0x64
+** ---------------------------------------------------------------------
+** 4. Returned data
+** ---------------------------------------------------------------------
+** (A) Header : 3 bytes sequence (0x5E, 0x01, 0x61)
+** (B) Length : 2 bytes
+** (low byte 1st, excludes length and checksum byte)
+** (C) status or data :
+** <1> If length == 1 ==> 1 byte status code
+** #define GUI_OK 0x41
+** #define GUI_RAIDSET_NOT_NORMAL 0x42
+** #define GUI_VOLUMESET_NOT_NORMAL 0x43
+** #define GUI_NO_RAIDSET 0x44
+** #define GUI_NO_VOLUMESET 0x45
+** #define GUI_NO_PHYSICAL_DRIVE 0x46
+** #define GUI_PARAMETER_ERROR 0x47
+** #define GUI_UNSUPPORTED_COMMAND 0x48
+** #define GUI_DISK_CONFIG_CHANGED 0x49
+** #define GUI_INVALID_PASSWORD 0x4a
+** #define GUI_NO_DISK_SPACE 0x4b
+** #define GUI_CHECKSUM_ERROR 0x4c
+** #define GUI_PASSWORD_REQUIRED 0x4d
+** <2> If length > 1 ==>
+** data block returned from controller
+** and the contents depends on the command code
+** (E) Checksum : checksum of length and status or data byte
+**************************************************************************
diff --git a/trunk/Documentation/scsi/libsas.txt b/trunk/Documentation/scsi/libsas.txt
new file mode 100644
index 000000000000..9e2078b2a615
--- /dev/null
+++ b/trunk/Documentation/scsi/libsas.txt
@@ -0,0 +1,484 @@
+SAS Layer
+---------
+
+The SAS Layer is a management infrastructure which manages
+SAS LLDDs. It sits between SCSI Core and SAS LLDDs. The
+layout is as follows: while SCSI Core is concerned with
+SAM/SPC issues, and a SAS LLDD+sequencer is concerned with
+phy/OOB/link management, the SAS layer is concerned with:
+
+ * SAS Phy/Port/HA event management (LLDD generates,
+ SAS Layer processes),
+ * SAS Port management (creation/destruction),
+ * SAS Domain discovery and revalidation,
+ * SAS Domain device management,
+ * SCSI Host registration/unregistration,
+ * Device registration with SCSI Core (SAS) or libata
+ (SATA), and
+ * Expander management and exporting expander control
+ to user space.
+
+A SAS LLDD is a PCI device driver. It is concerned with
+phy/OOB management, and vendor specific tasks and generates
+events to the SAS layer.
+
+The SAS Layer does most SAS tasks as outlined in the SAS 1.1
+spec.
+
+The sas_ha_struct describes the SAS LLDD to the SAS layer.
+Most of it is used by the SAS Layer but a few fields need to
+be initialized by the LLDDs.
+
+After initializing your hardware, from the probe() function
+you call sas_register_ha(). It will register your LLDD with
+the SCSI subsystem, creating a SCSI host and it will
+register your SAS driver with the sysfs SAS tree it creates.
+It will then return. Then you enable your phys to actually
+start OOB (at which point your driver will start calling the
+notify_* event callbacks).
+
+Structure descriptions:
+
+struct sas_phy --------------------
+Normally this is statically embedded to your driver's
+phy structure:
+ struct my_phy {
+ blah;
+ struct sas_phy sas_phy;
+ bleh;
+ };
+And then all the phys are an array of my_phy in your HA
+struct (shown below).
+
+Then as you go along and initialize your phys you also
+initialize the sas_phy struct, along with your own
+phy structure.
+
+In general, the phys are managed by the LLDD and the ports
+are managed by the SAS layer. So the phys are initialized
+and updated by the LLDD and the ports are initialized and
+updated by the SAS layer.
+
+There is a scheme where the LLDD can RW certain fields,
+and the SAS layer can only read such ones, and vice versa.
+The idea is to avoid unnecessary locking.
+
+enabled -- must be set (0/1)
+id -- must be set [0,MAX_PHYS)
+class, proto, type, role, oob_mode, linkrate -- must be set
+oob_mode -- you set this when OOB has finished and then notify
+the SAS Layer.
+
+sas_addr -- this normally points to an array holding the sas
+address of the phy, possibly somewhere in your my_phy
+struct.
+
+attached_sas_addr -- set this when you (LLDD) receive an
+IDENTIFY frame or a FIS frame, _before_ notifying the SAS
+layer. The idea is that sometimes the LLDD may want to fake
+or provide a different SAS address on that phy/port and this
+allows it to do this. At best you should copy the sas
+address from the IDENTIFY frame or maybe generate a SAS
+address for SATA directly attached devices. The Discover
+process may later change this.
+
+frame_rcvd -- this is where you copy the IDENTIFY/FIS frame
+when you get it; you lock, copy, set frame_rcvd_size and
+unlock the lock, and then call the event. It is a pointer
+since there's no way to know your hw frame size _exactly_,
+so you define the actual array in your phy struct and let
+this pointer point to it. You copy the frame from your
+DMAable memory to that area holding the lock.
+
+sas_prim -- this is where primitives go when they're
+received. See sas.h. Grab the lock, set the primitive,
+release the lock, notify.
+
+port -- this points to the sas_port if the phy belongs
+to a port -- the LLDD only reads this. It points to the
+sas_port this phy is part of. Set by the SAS Layer.
+
+ha -- may be set; the SAS layer sets it anyway.
+
+lldd_phy -- you should set this to point to your phy so you
+can find your way around faster when the SAS layer calls one
+of your callbacks and passes you a phy. If the sas_phy is
+embedded you can also use container_of -- whatever you
+prefer.
+
+
+struct sas_port --------------------
+The LLDD doesn't set any fields of this struct -- it only
+reads them. They should be self explanatory.
+
+phy_mask is 32 bit, this should be enough for now, as I
+haven't heard of a HA having more than 8 phys.
+
+lldd_port -- I haven't found use for that -- maybe other
+LLDD who wish to have internal port representation can make
+use of this.
+
+
+struct sas_ha_struct --------------------
+It normally is statically declared in your own LLDD
+structure describing your adapter:
+struct my_sas_ha {
+ blah;
+ struct sas_ha_struct sas_ha;
+ struct my_phy phys[MAX_PHYS];
+ struct sas_port sas_ports[MAX_PHYS]; /* (1) */
+ bleh;
+};
+
+(1) If your LLDD doesn't have its own port representation.
+
+What needs to be initialized (sample function given below).
+
+pcidev
+sas_addr -- since the SAS layer doesn't want to mess with
+ memory allocation, etc, this points to statically
+ allocated array somewhere (say in your host adapter
+ structure) and holds the SAS address of the host
+ adapter as given by you or the manufacturer, etc.
+sas_port
+sas_phy -- an array of pointers to structures. (see
+ note above on sas_addr).
+ These must be set. See more notes below.
+num_phys -- the number of phys present in the sas_phy array,
+ and the number of ports present in the sas_port
+ array. There can be a maximum num_phys ports (one per
+ port) so we drop the num_ports, and only use
+ num_phys.
+
+The event interface:
+
+ /* LLDD calls these to notify the class of an event. */
+ void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
+ void (*notify_port_event)(struct sas_phy *, enum port_event);
+ void (*notify_phy_event)(struct sas_phy *, enum phy_event);
+
+When sas_register_ha() returns, those are set and can be
+called by the LLDD to notify the SAS layer of such events
+the SAS layer.
+
+The port notification:
+
+ /* The class calls these to notify the LLDD of an event. */
+ void (*lldd_port_formed)(struct sas_phy *);
+ void (*lldd_port_deformed)(struct sas_phy *);
+
+If the LLDD wants notification when a port has been formed
+or deformed it sets those to a function satisfying the type.
+
+A SAS LLDD should also implement at least one of the Task
+Management Functions (TMFs) described in SAM:
+
+ /* Task Management Functions. Must be called from process context. */
+ int (*lldd_abort_task)(struct sas_task *);
+ int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
+ int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
+ int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
+ int (*lldd_I_T_nexus_reset)(struct domain_device *);
+ int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
+ int (*lldd_query_task)(struct sas_task *);
+
+For more information please read SAM from T10.org.
+
+Port and Adapter management:
+
+ /* Port and Adapter management */
+ int (*lldd_clear_nexus_port)(struct sas_port *);
+ int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);
+
+A SAS LLDD should implement at least one of those.
+
+Phy management:
+
+ /* Phy management */
+ int (*lldd_control_phy)(struct sas_phy *, enum phy_func);
+
+lldd_ha -- set this to point to your HA struct. You can also
+use container_of if you embedded it as shown above.
+
+A sample initialization and registration function
+can look like this (called last thing from probe())
+*but* before you enable the phys to do OOB:
+
+static int register_sas_ha(struct my_sas_ha *my_ha)
+{
+ int i;
+ static struct sas_phy *sas_phys[MAX_PHYS];
+ static struct sas_port *sas_ports[MAX_PHYS];
+
+ my_ha->sas_ha.sas_addr = &my_ha->sas_addr[0];
+
+ for (i = 0; i < MAX_PHYS; i++) {
+ sas_phys[i] = &my_ha->phys[i].sas_phy;
+ sas_ports[i] = &my_ha->sas_ports[i];
+ }
+
+ my_ha->sas_ha.sas_phy = sas_phys;
+ my_ha->sas_ha.sas_port = sas_ports;
+ my_ha->sas_ha.num_phys = MAX_PHYS;
+
+ my_ha->sas_ha.lldd_port_formed = my_port_formed;
+
+ my_ha->sas_ha.lldd_dev_found = my_dev_found;
+ my_ha->sas_ha.lldd_dev_gone = my_dev_gone;
+
+ my_ha->sas_ha.lldd_max_execute_num = lldd_max_execute_num; (1)
+
+ my_ha->sas_ha.lldd_queue_size = ha_can_queue;
+ my_ha->sas_ha.lldd_execute_task = my_execute_task;
+
+ my_ha->sas_ha.lldd_abort_task = my_abort_task;
+ my_ha->sas_ha.lldd_abort_task_set = my_abort_task_set;
+ my_ha->sas_ha.lldd_clear_aca = my_clear_aca;
+ my_ha->sas_ha.lldd_clear_task_set = my_clear_task_set;
+ my_ha->sas_ha.lldd_I_T_nexus_reset= NULL; (2)
+ my_ha->sas_ha.lldd_lu_reset = my_lu_reset;
+ my_ha->sas_ha.lldd_query_task = my_query_task;
+
+ my_ha->sas_ha.lldd_clear_nexus_port = my_clear_nexus_port;
+ my_ha->sas_ha.lldd_clear_nexus_ha = my_clear_nexus_ha;
+
+ my_ha->sas_ha.lldd_control_phy = my_control_phy;
+
+ return sas_register_ha(&my_ha->sas_ha);
+}
+
+(1) This is normally a LLDD parameter, something of the
+lines of a task collector. What it tells the SAS Layer is
+whether the SAS layer should run in Direct Mode (default:
+value 0 or 1) or Task Collector Mode (value greater than 1).
+
+In Direct Mode, the SAS Layer calls Execute Task as soon as
+it has a command to send to the SDS, _and_ this is a single
+command, i.e. not linked.
+
+Some hardware (e.g. aic94xx) has the capability to DMA more
+than one task at a time (interrupt) from host memory. Task
+Collector Mode is an optional feature for HAs which support
+this in their hardware. (Again, it is completely optional
+even if your hardware supports it.)
+
+In Task Collector Mode, the SAS Layer would do _natural_
+coalescing of tasks and at the appropriate moment it would
+call your driver to DMA more than one task in a single HA
+interrupt. DMBS may want to use this by insmod/modprobe
+setting the lldd_max_execute_num to something greater than
+1.
+
+(2) SAS 1.1 does not define I_T Nexus Reset TMF.
+
+Events
+------
+
+Events are _the only way_ a SAS LLDD notifies the SAS layer
+of anything. There is no other method or way a LLDD to tell
+the SAS layer of anything happening internally or in the SAS
+domain.
+
+Phy events:
+ PHYE_LOSS_OF_SIGNAL, (C)
+ PHYE_OOB_DONE,
+ PHYE_OOB_ERROR, (C)
+ PHYE_SPINUP_HOLD.
+
+Port events, passed on a _phy_:
+ PORTE_BYTES_DMAED, (M)
+ PORTE_BROADCAST_RCVD, (E)
+ PORTE_LINK_RESET_ERR, (C)
+ PORTE_TIMER_EVENT, (C)
+ PORTE_HARD_RESET.
+
+Host Adapter event:
+ HAE_RESET
+
+A SAS LLDD should be able to generate
+ - at least one event from group C (choice),
+ - events marked M (mandatory) are mandatory (only one),
+ - events marked E (expander) if it wants the SAS layer
+ to handle domain revalidation (only one such).
+ - Unmarked events are optional.
+
+Meaning:
+
+HAE_RESET -- when your HA got internal error and was reset.
+
+PORTE_BYTES_DMAED -- on receiving an IDENTIFY/FIS frame
+PORTE_BROADCAST_RCVD -- on receiving a primitive
+PORTE_LINK_RESET_ERR -- timer expired, loss of signal, loss
+of DWS, etc. (*)
+PORTE_TIMER_EVENT -- DWS reset timeout timer expired (*)
+PORTE_HARD_RESET -- Hard Reset primitive received.
+
+PHYE_LOSS_OF_SIGNAL -- the device is gone (*)
+PHYE_OOB_DONE -- OOB went fine and oob_mode is valid
+PHYE_OOB_ERROR -- Error while doing OOB, the device probably
+got disconnected. (*)
+PHYE_SPINUP_HOLD -- SATA is present, COMWAKE not sent.
+
+(*) should set/clear the appropriate fields in the phy,
+ or alternatively call the inlined sas_phy_disconnected()
+ which is just a helper, from their tasklet.
+
+The Execute Command SCSI RPC:
+
+ int (*lldd_execute_task)(struct sas_task *, int num,
+ unsigned long gfp_flags);
+
+Used to queue a task to the SAS LLDD. @task is the tasks to
+be executed. @num should be the number of tasks being
+queued at this function call (they are linked listed via
+task::list), @gfp_mask should be the gfp_mask defining the
+context of the caller.
+
+This function should implement the Execute Command SCSI RPC,
+or if you're sending a SCSI Task as linked commands, you
+should also use this function.
+
+That is, when lldd_execute_task() is called, the command(s)
+go out on the transport *immediately*. There is *no*
+queuing of any sort and at any level in a SAS LLDD.
+
+The use of task::list is two-fold, one for linked commands,
+the other discussed below.
+
+It is possible to queue up more than one task at a time, by
+initializing the list element of struct sas_task, and
+passing the number of tasks enlisted in this manner in num.
+
+Returns: -SAS_QUEUE_FULL, -ENOMEM, nothing was queued;
+ 0, the task(s) were queued.
+
+If you want to pass num > 1, then either
+A) you're the only caller of this function and keep track
+ of what you've queued to the LLDD, or
+B) you know what you're doing and have a strategy of
+ retrying.
+
+As opposed to queuing one task at a time (function call),
+batch queuing of tasks, by having num > 1, greatly
+simplifies LLDD code, sequencer code, and _hardware design_,
+and has some performance advantages in certain situations
+(DBMS).
+
+The LLDD advertises if it can take more than one command at
+a time at lldd_execute_task(), by setting the
+lldd_max_execute_num parameter (controlled by "collector"
+module parameter in aic94xx SAS LLDD).
+
+You should leave this to the default 1, unless you know what
+you're doing.
+
+This is a function of the LLDD, to which the SAS layer can
+cater to.
+
+int lldd_queue_size
+ The host adapter's queue size. This is the maximum
+number of commands the lldd can have pending to domain
+devices on behalf of all upper layers submitting through
+lldd_execute_task().
+
+You really want to set this to something (much) larger than
+1.
+
+This _really_ has absolutely nothing to do with queuing.
+There is no queuing in SAS LLDDs.
+
+struct sas_task {
+ dev -- the device this task is destined to
+ list -- must be initialized (INIT_LIST_HEAD)
+ task_proto -- _one_ of enum sas_proto
+ scatter -- pointer to scatter gather list array
+ num_scatter -- number of elements in scatter
+ total_xfer_len -- total number of bytes expected to be transfered
+ data_dir -- PCI_DMA_...
+ task_done -- callback when the task has finished execution
+};
+
+When an external entity, entity other than the LLDD or the
+SAS Layer, wants to work with a struct domain_device, it
+_must_ call kobject_get() when getting a handle on the
+device and kobject_put() when it is done with the device.
+
+This does two things:
+ A) implements proper kfree() for the device;
+ B) increments/decrements the kref for all players:
+ domain_device
+ all domain_device's ... (if past an expander)
+ port
+ host adapter
+ pci device
+ and up the ladder, etc.
+
+DISCOVERY
+---------
+
+The sysfs tree has the following purposes:
+ a) It shows you the physical layout of the SAS domain at
+ the current time, i.e. how the domain looks in the
+ physical world right now.
+ b) Shows some device parameters _at_discovery_time_.
+
+This is a link to the tree(1) program, very useful in
+viewing the SAS domain:
+ftp://mama.indstate.edu/linux/tree/
+I expect user space applications to actually create a
+graphical interface of this.
+
+That is, the sysfs domain tree doesn't show or keep state if
+you e.g., change the meaning of the READY LED MEANING
+setting, but it does show you the current connection status
+of the domain device.
+
+Keeping internal device state changes is responsibility of
+upper layers (Command set drivers) and user space.
+
+When a device or devices are unplugged from the domain, this
+is reflected in the sysfs tree immediately, and the device(s)
+removed from the system.
+
+The structure domain_device describes any device in the SAS
+domain. It is completely managed by the SAS layer. A task
+points to a domain device, this is how the SAS LLDD knows
+where to send the task(s) to. A SAS LLDD only reads the
+contents of the domain_device structure, but it never creates
+or destroys one.
+
+Expander management from User Space
+-----------------------------------
+
+In each expander directory in sysfs, there is a file called
+"smp_portal". It is a binary sysfs attribute file, which
+implements an SMP portal (Note: this is *NOT* an SMP port),
+to which user space applications can send SMP requests and
+receive SMP responses.
+
+Functionality is deceptively simple:
+
+1. Build the SMP frame you want to send. The format and layout
+ is described in the SAS spec. Leave the CRC field equal 0.
+open(2)
+2. Open the expander's SMP portal sysfs file in RW mode.
+write(2)
+3. Write the frame you built in 1.
+read(2)
+4. Read the amount of data you expect to receive for the frame you built.
+ If you receive different amount of data you expected to receive,
+ then there was some kind of error.
+close(2)
+All this process is shown in detail in the function do_smp_func()
+and its callers, in the file "expander_conf.c".
+
+The kernel functionality is implemented in the file
+"sas_expander.c".
+
+The program "expander_conf.c" implements this. It takes one
+argument, the sysfs file name of the SMP portal to the
+expander, and gives expander information, including routing
+tables.
+
+The SMP portal gives you complete control of the expander,
+so please be careful.
diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt
index f61af23dd85d..e6b57dd46a4f 100644
--- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -758,6 +758,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
single_cmd - Use single immediate commands to communicate with
codecs (for debugging only)
+ disable_msi - Disable Message Signaled Interrupt (MSI)
This module supports one card and autoprobe.
@@ -778,11 +779,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
6stack-digout 6-jack with a SPDIF out
w810 3-jack
z71v 3-jack (HP shared SPDIF)
- asus 3-jack
+ asus 3-jack (ASUS Mobo)
+ asus-w1v ASUS W1V
+ asus-dig ASUS with SPDIF out
+ asus-dig2 ASUS with SPDIF out (using GPIO2)
uniwill 3-jack
F1734 2-jack
lg LG laptop (m1 express dual)
- lg-lw LG LW20 laptop
+ lg-lw LG LW20/LW25 laptop
+ tcl TCL S700
+ clevo Clevo laptops (m520G, m665n)
test for testing/debugging purpose, almost all controls can be
adjusted. Appearing only when compiled with
$CONFIG_SND_DEBUG=y
@@ -790,6 +796,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ALC260
hp HP machines
+ hp-3013 HP machines (3013-variant)
fujitsu Fujitsu S7020
acer Acer TravelMate
basic fixed pin assignment (old default model)
@@ -797,24 +804,32 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ALC262
fujitsu Fujitsu Laptop
+ hp-bpc HP xw4400/6400/8400/9400 laptops
+ benq Benq ED8
basic fixed pin assignment w/o SPDIF
auto auto-config reading BIOS (default)
ALC882/885
3stack-dig 3-jack with SPDIF I/O
6stck-dig 6-jack digital with SPDIF I/O
+ arima Arima W820Di1
auto auto-config reading BIOS (default)
ALC883/888
3stack-dig 3-jack with SPDIF I/O
6stack-dig 6-jack digital with SPDIF I/O
- 6stack-dig-demo 6-stack digital for Intel demo board
+ 3stack-6ch 3-jack 6-channel
+ 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
+ 6stack-dig-demo 6-jack digital for Intel demo board
+ acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
auto auto-config reading BIOS (default)
ALC861/660
3stack 3-jack
3stack-dig 3-jack with SPDIF I/O
6stack-dig 6-jack with SPDIF I/O
+ 3stack-660 3-jack (for ALC660)
+ uniwill-m31 Uniwill M31 laptop
auto auto-config reading BIOS (default)
CMI9880
@@ -843,10 +858,21 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
3stack-dig ditto with SPDIF
laptop 3-jack with hp-jack automute
laptop-dig ditto with SPDIF
- auto auto-confgi reading BIOS (default)
+ auto auto-config reading BIOS (default)
+
+ STAC9200/9205/9220/9221/9254
+ ref Reference board
+ 3stack D945 3stack
+ 5stack D945 5stack + SPDIF
- STAC7661(?)
+ STAC9227/9228/9229/927x
+ ref Reference board
+ 3stack D965 3stack
+ 5stack D965 5stack + SPDIF
+
+ STAC9872
vaio Setup for VAIO FE550G/SZ110
+ vaio-ar Setup for VAIO AR
If the default configuration doesn't work and one of the above
matches with your device, report it together with the PCI
@@ -1213,6 +1239,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module supports only 1 card. This module has no enable option.
+ Module snd-mts64
+ ----------------
+
+ Module for Ego Systems (ESI) Miditerminal 4140
+
+ This module supports multiple devices.
+ Requires parport (CONFIG_PARPORT).
+
Module snd-nm256
----------------
diff --git a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index b8dc51ca776c..4807ef79a94d 100644
--- a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -1054,9 +1054,8 @@
For a device which allows hotplugging, you can use
- snd_card_free_in_thread. This one will
- postpone the destruction and wait in a kernel-thread until all
- devices are closed.
+ snd_card_free_when_closed. This one will
+ postpone the destruction until all devices are closed.
diff --git a/trunk/Documentation/sparse.txt b/trunk/Documentation/sparse.txt
index 5a311c38dd1a..f9c99c9a54f9 100644
--- a/trunk/Documentation/sparse.txt
+++ b/trunk/Documentation/sparse.txt
@@ -69,10 +69,10 @@ recompiled, or use "make C=2" to run sparse on the files whether they need to
be recompiled or not. The latter is a fast way to check the whole tree if you
have already built it.
-The optional make variable CF can be used to pass arguments to sparse. The
-build system passes -Wbitwise to sparse automatically. To perform endianness
-checks, you may define __CHECK_ENDIAN__:
+The optional make variable CHECKFLAGS can be used to pass arguments to sparse.
+The build system passes -Wbitwise to sparse automatically. To perform
+endianness checks, you may define __CHECK_ENDIAN__:
- make C=2 CF="-D__CHECK_ENDIAN__"
+ make C=2 CHECKFLAGS="-D__CHECK_ENDIAN__"
These checks are disabled by default as they generate a host of warnings.
diff --git a/trunk/Kbuild b/trunk/Kbuild
index 2d4f95e4b89f..0451f69353ba 100644
--- a/trunk/Kbuild
+++ b/trunk/Kbuild
@@ -28,7 +28,7 @@ define cmd_offsets
echo "/*"; \
echo " * DO NOT MODIFY."; \
echo " *"; \
- echo " * This file was generated by $(srctree)/Kbuild"; \
+ echo " * This file was generated by Kbuild"; \
echo " *"; \
echo " */"; \
echo ""; \
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 7e86286ddf1e..23348c0d37bc 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -298,6 +298,14 @@ L: info-linux@geode.amd.com
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
S: Supported
+AMSO1100 RNIC DRIVER
+P: Tom Tucker
+M: tom@opengridcomputing.com
+P: Steve Wise
+M: swise@opengridcomputing.com
+L: openib-general@openib.org
+S: Maintained
+
AOA (Apple Onboard Audio) ALSA DRIVER
P: Johannes Berg
M: johannes@sipsolutions.net
@@ -416,7 +424,7 @@ S: Supported
ATM
P: Chas Williams
M: chas@cmf.nrl.navy.mil
-L: linux-atm-general@lists.sourceforge.net
+L: linux-atm-general@lists.sourceforge.net (subscribers-only)
W: http://linux-atm.sourceforge.net
S: Maintained
@@ -449,9 +457,9 @@ L: linux-hams@vger.kernel.org
W: http://www.baycom.org/~tom/ham/ham.html
S: Maintained
-BCM43XX WIRELESS DRIVER
-P: Michael Buesch
-M: mb@bu3sch.de
+BCM43XX WIRELESS DRIVER (SOFTMAC BASED VERSION)
+P: Larry Finger
+M: Larry.Finger@lwfinger.net
P: Stefano Brivio
M: st3@riseup.net
W: http://bcm43xx.berlios.de/
@@ -991,6 +999,14 @@ EFS FILESYSTEM
W: http://aeschi.ch.eu.org/efs/
S: Orphan
+EHCA (IBM GX bus InfiniBand adapter) DRIVER:
+P: Hoang-Nam Nguyen
+M: hnguyen@de.ibm.com
+P: Christoph Raisch
+M: raisch@de.ibm.com
+L: openib-general@openib.org
+S: Supported
+
EMU10K1 SOUND DRIVER
P: James Courtier-Dutton
M: James@superbug.demon.co.uk
@@ -2015,6 +2031,13 @@ L: netfilter@lists.netfilter.org
L: netfilter-devel@lists.netfilter.org
S: Supported
+NETLABEL
+P: Paul Moore
+M: paul.moore@hp.com
+W: http://netlabel.sf.net
+L: netdev@vger.kernel.org
+S: Supported
+
NETROM NETWORK LAYER
P: Ralf Baechle
M: ralf@linux-mips.org
@@ -2373,6 +2396,12 @@ M: linux-driver@qlogic.com
L: linux-scsi@vger.kernel.org
S: Supported
+QLOGIC QLA3XXX NETWORK DRIVER
+P: Ron Mercer
+M: linux-driver@qlogic.com
+L: netdev@vger.kernel.org
+S: Supported
+
QNX4 FILESYSTEM
P: Anders Larsen
M: al@alarsen.net
@@ -2452,6 +2481,8 @@ S: Maintained
S390
P: Martin Schwidefsky
M: schwidefsky@de.ibm.com
+P: Heiko Carstens
+M: heiko.carstens@de.ibm.com
M: linux390@de.ibm.com
L: linux-390@vm.marist.edu
W: http://www.ibm.com/developerworks/linux/linux390/
@@ -2466,8 +2497,8 @@ W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
S390 ZFCP DRIVER
-P: Andreas Herrmann
-M: aherrman@de.ibm.com
+P: Swen Schillig
+M: swen@vnet.ibm.com
M: linux390@de.ibm.com
L: linux-390@vm.marist.edu
W: http://www.ibm.com/developerworks/linux/linux390/
@@ -2623,6 +2654,18 @@ P: Nicolas Pitre
M: nico@cam.org
S: Maintained
+SOFTMAC LAYER (IEEE 802.11)
+P: Johannes Berg
+M: johannes@sipsolutions.net
+P: Joe Jezak
+M: josejx@gentoo.org
+P: Daniel Drake
+M: dsd@gentoo.org
+W: http://softmac.sipsolutions.net/
+L: softmac-dev@sipsolutions.net
+L: netdev@vger.kernel.org
+S: Maintained
+
SOFTWARE RAID (Multiple Disks) SUPPORT
P: Ingo Molnar
M: mingo@redhat.com
@@ -2817,6 +2860,14 @@ M: hadi@cyberus.ca
L: netdev@vger.kernel.org
S: Maintained
+TCP LOW PRIORITY MODULE
+P: Wong Hoi Sing, Edison
+M: hswong3i@gmail.com
+P: Hung Hing Lun, Mike
+M: hlhung3i@gmail.com
+W: http://tcp-lp-mod.sourceforge.net/
+S: Maintained
+
TI OMAP RANDOM NUMBER GENERATOR SUPPORT
P: Deepak Saxena
M: dsaxena@plexity.net
@@ -2896,8 +2947,8 @@ W: http://www.auk.cx/tms380tr/
S: Maintained
TULIP NETWORK DRIVER
-P: Jeff Garzik
-M: jgarzik@pobox.com
+P: Valerie Henson
+M: val_henson@linux.intel.com
L: tulip-users@lists.sourceforge.net
W: http://sourceforge.net/projects/tulip/
S: Maintained
@@ -3348,6 +3399,15 @@ W: http://www.qsl.net/dl1bke/
L: linux-hams@vger.kernel.org
S: Maintained
+ZD1211RW WIRELESS DRIVER
+P: Daniel Drake
+M: dsd@gentoo.org
+P: Ulrich Kunitz
+M: kune@deine-taler.de
+W: http://zd1211.ath.cx/wiki/DriverRewrite
+L: zd1211-devs@lists.sourceforge.net (subscribers-only)
+S: Maintained
+
ZF MACHZ WATCHDOG
P: Fernando Fuganti
M: fuganti@netbank.com.br
diff --git a/trunk/Makefile b/trunk/Makefile
index eab5a8c2ee49..80dac0245d66 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1,8 +1,8 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 18
-EXTRAVERSION = -rc7
-NAME=Crazed Snow-Weasel
+EXTRAVERSION =
+NAME=Avast! A bilge rat!
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
@@ -41,9 +41,15 @@ ifndef KBUILD_VERBOSE
KBUILD_VERBOSE = 0
endif
-# Call checker as part of compilation of C files
-# Use 'make C=1' to enable checking (sparse, by default)
-# Override with 'make C=1 CHECK=checker_executable CHECKFLAGS=....'
+# Call a source code checker (by default, "sparse") as part of the
+# C compilation.
+#
+# Use 'make C=1' to enable checking of only re-compiled files.
+# Use 'make C=2' to enable checking of *all* source files, regardless
+# of whether they are re-compiled or not.
+#
+# See the file "Documentation/sparse.txt" for more details, including
+# where to get the "sparse" utility.
ifdef C
ifeq ("$(origin C)", "command line")
@@ -639,12 +645,12 @@ define rule_vmlinux__
$(call cmd,vmlinux__)
$(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
- $(Q)$(if $($(quiet)cmd_sysmap), \
- echo ' $($(quiet)cmd_sysmap) System.map' &&) \
- $(cmd_sysmap) $@ System.map; \
- if [ $$? -ne 0 ]; then \
- rm -f $@; \
- /bin/false; \
+ $(Q)$(if $($(quiet)cmd_sysmap), \
+ echo ' $($(quiet)cmd_sysmap) System.map' &&) \
+ $(cmd_sysmap) $@ System.map; \
+ if [ $$? -ne 0 ]; then \
+ rm -f $@; \
+ /bin/false; \
fi;
$(verify_kallsyms)
endef
@@ -677,12 +683,12 @@ endif
kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
define verify_kallsyms
- $(Q)$(if $($(quiet)cmd_sysmap), \
- echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \
+ $(Q)$(if $($(quiet)cmd_sysmap), \
+ echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \
$(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map
- $(Q)cmp -s System.map .tmp_System.map || \
- (echo Inconsistent kallsyms data; \
- echo Try setting CONFIG_KALLSYMS_EXTRA_PASS; \
+ $(Q)cmp -s System.map .tmp_System.map || \
+ (echo Inconsistent kallsyms data; \
+ echo Try setting CONFIG_KALLSYMS_EXTRA_PASS; \
rm .tmp_kallsyms* ; /bin/false )
endef
@@ -736,6 +742,7 @@ endif # ifdef CONFIG_KALLSYMS
# vmlinux image - including updated kernel symbols
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
$(call if_changed_rule,vmlinux__)
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
$(Q)rm -f .old_version
# The actual objects are generated when descending,
@@ -753,12 +760,34 @@ $(vmlinux-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@
# Build the kernel release string
-# The KERNELRELEASE is stored in a file named include/config/kernel.release
-# to be used when executing for example make install or make modules_install
#
-# Take the contents of any files called localversion* and the config
-# variable CONFIG_LOCALVERSION and append them to KERNELRELEASE.
-# LOCALVERSION from the command line override all of this
+# The KERNELRELEASE value built here is stored in the file
+# include/config/kernel.release, and is used when executing several
+# make targets, such as "make install" or "make modules_install."
+#
+# The eventual kernel release string consists of the following fields,
+# shown in a hierarchical format to show how smaller parts are concatenated
+# to form the larger and final value, with values coming from places like
+# the Makefile, kernel config options, make command line options and/or
+# SCM tag information.
+#
+# $(KERNELVERSION)
+# $(VERSION) eg, 2
+# $(PATCHLEVEL) eg, 6
+# $(SUBLEVEL) eg, 18
+# $(EXTRAVERSION) eg, -rc6
+# $(localver-full)
+# $(localver)
+# localversion* (all localversion* files)
+# $(CONFIG_LOCALVERSION) (from kernel config setting)
+# $(localver-auto) (only if CONFIG_LOCALVERSION_AUTO is set)
+# ./scripts/setlocalversion (SCM tag, if one exists)
+# $(LOCALVERSION) (from make command line if provided)
+#
+# Note how the final $(localver-auto) string is included *only* if the
+# kernel config option CONFIG_LOCALVERSION_AUTO is selected. Also, at the
+# moment, only git is supported but other SCMs can edit the script
+# scripts/setlocalversion and add the appropriate checks as needed.
nullstring :=
space := $(nullstring) # end of line
@@ -889,18 +918,29 @@ depend dep:
# ---------------------------------------------------------------------------
# Kernel headers
-INSTALL_HDR_PATH=$(MODLIB)/abi
+INSTALL_HDR_PATH=$(objtree)/usr
export INSTALL_HDR_PATH
+HDRARCHES=$(filter-out generic,$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
+
+PHONY += headers_install_all
+headers_install_all: include/linux/version.h scripts_basic FORCE
+ $(Q)$(MAKE) $(build)=scripts scripts/unifdef
+ $(Q)for arch in $(HDRARCHES); do \
+ $(MAKE) ARCH=$$arch -f $(srctree)/scripts/Makefile.headersinst obj=include BIASMDIR=-bi-$$arch ;\
+ done
+
PHONY += headers_install
-headers_install: include/linux/version.h
- $(Q)unifdef -Ux /dev/null
- $(Q)rm -rf $(INSTALL_HDR_PATH)/include
- $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.headersinst obj=include
+headers_install: include/linux/version.h scripts_basic FORCE
+ @if [ ! -r include/asm-$(ARCH)/Kbuild ]; then \
+ echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \
+ exit 1 ; fi
+ $(Q)$(MAKE) $(build)=scripts scripts/unifdef
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include
PHONY += headers_check
headers_check: headers_install
- $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.headersinst obj=include HDRCHECK=1
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include HDRCHECK=1
# ---------------------------------------------------------------------------
# Modules
@@ -916,7 +956,7 @@ all: modules
PHONY += modules
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
@echo ' Building modules, stage 2.';
- $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
# Target to prepare building external modules
@@ -942,7 +982,7 @@ _modinst_:
rm -f $(MODLIB)/build ; \
ln -s $(objtree) $(MODLIB)/build ; \
fi
- $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
# If System.map exists, run depmod. This deliberately does not have a
# dependency on System.map since that would run the dependency tree on
@@ -986,7 +1026,7 @@ CLEAN_FILES += vmlinux System.map \
.tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map
# Directories & files removed with 'make mrproper'
-MRPROPER_DIRS += include/config include2
+MRPROPER_DIRS += include/config include2 usr/include
MRPROPER_FILES += .config .config.old include/asm .version .old_version \
include/linux/autoconf.h include/linux/version.h \
include/linux/utsrelease.h \
@@ -1057,8 +1097,10 @@ boards := $(notdir $(boards))
help:
@echo 'Cleaning targets:'
- @echo ' clean - remove most generated files but keep the config'
+ @echo ' clean - remove most generated files but keep the config and'
+ @echo ' enough build support to build external modules'
@echo ' mrproper - remove all generated files + config + various backup files'
+ @echo ' distclean - mrproper + remove editor backup and patch files'
@echo ''
@echo 'Configuration targets:'
@$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
@@ -1076,12 +1118,17 @@ help:
@echo ' cscope - Generate cscope index'
@echo ' kernelrelease - Output the release version string'
@echo ' kernelversion - Output the version stored in Makefile'
- @echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'
- @echo ' (default: /lib/modules/$$VERSION/abi)'
+ @if [ -r include/asm-$(ARCH)/Kbuild ]; then \
+ echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
+ fi
+ @echo ' (default: $(INSTALL_HDR_PATH))'
@echo ''
@echo 'Static analysers'
@echo ' checkstack - Generate a list of stack hogs'
@echo ' namespacecheck - Name space analysis on compiled kernel'
+ @if [ -r include/asm-$(ARCH)/Kbuild ]; then \
+ echo ' headers_check - Sanity check on exported headers'; \
+ fi
@echo ''
@echo 'Kernel packaging:'
@$(MAKE) $(build)=$(package-dir) help
@@ -1099,6 +1146,7 @@ help:
echo '')
@echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
+ @echo ' make V=2 [targets] 2 => give reason for rebuild of target'
@echo ' make O=dir [targets] Locate all output files in "dir", including .config'
@echo ' make C=1 [targets] Check all c source with $$CHECK (sparse by default)'
@echo ' make C=2 [targets] Force check of all c source with $$CHECK'
@@ -1153,7 +1201,7 @@ $(module-dirs): crmodverdir $(objtree)/Module.symvers
modules: $(module-dirs)
@echo ' Building modules, stage 2.';
- $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
PHONY += modules_install
modules_install: _emodinst_ _emodinst_post
@@ -1162,7 +1210,7 @@ install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra)
PHONY += _emodinst_
_emodinst_:
$(Q)mkdir -p $(MODLIB)/$(install-dir)
- $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
# Run depmod only is we have System.map and depmod is executable
quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
@@ -1263,6 +1311,31 @@ define all-defconfigs
$(call find-sources,'defconfig')
endef
+define xtags
+ if $1 --version 2>&1 | grep -iq exuberant; then \
+ $(all-sources) | xargs $1 -a \
+ -I __initdata,__exitdata,__acquires,__releases \
+ -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
+ --extra=+f --c-kinds=+px; \
+ $(all-kconfigs) | xargs $1 -a \
+ --langdef=kconfig \
+ --language-force=kconfig \
+ --regex-kconfig='/^[[:blank:]]*config[[:blank:]]+([[:alnum:]_]+)/\1/'; \
+ $(all-defconfigs) | xargs $1 -a \
+ --langdef=dotconfig \
+ --language-force=dotconfig \
+ --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'; \
+ elif $1 --version 2>&1 | grep -iq emacs; then \
+ $(all-sources) | xargs $1 -a; \
+ $(all-kconfigs) | xargs $1 -a \
+ --regex='/^[ \t]*config[ \t]+\([a-zA-Z0-9_]+\)/\1/'; \
+ $(all-defconfigs) | xargs $1 -a \
+ --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \
+ else \
+ $(all-sources) | xargs $1 -a; \
+ fi
+endef
+
quiet_cmd_cscope-file = FILELST cscope.files
cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files
@@ -1276,31 +1349,16 @@ cscope: FORCE
quiet_cmd_TAGS = MAKE $@
define cmd_TAGS
rm -f $@; \
- ETAGSF=`etags --version | grep -i exuberant >/dev/null && \
- echo "-I __initdata,__exitdata,__acquires,__releases \
- -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
- --extra=+f --c-kinds=+px"`; \
- $(all-sources) | xargs etags $$ETAGSF -a; \
- if test "x$$ETAGSF" = x; then \
- $(all-kconfigs) | xargs etags -a \
- --regex='/^config[ \t]+\([a-zA-Z0-9_]+\)/\1/'; \
- $(all-defconfigs) | xargs etags -a \
- --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \
- fi
+ $(call xtags,etags)
endef
TAGS: FORCE
$(call cmd,TAGS)
-
quiet_cmd_tags = MAKE $@
define cmd_tags
rm -f $@; \
- CTAGSF=`ctags --version | grep -i exuberant >/dev/null && \
- echo "-I __initdata,__exitdata,__acquires,__releases \
- -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
- --extra=+f --c-kinds=+px"`; \
- $(all-sources) | xargs ctags $$CTAGSF -a
+ $(call xtags,ctags)
endef
tags: FORCE
@@ -1378,7 +1436,7 @@ endif
%.ko: prepare scripts FORCE
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir) $(@:.ko=.o)
- $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
# FIXME Should go into a make.lib or something
# ===========================================================================
diff --git a/trunk/arch/arm/configs/pnx4008_defconfig b/trunk/arch/arm/configs/pnx4008_defconfig
index 8a078d479d57..a4989f44baaa 100644
--- a/trunk/arch/arm/configs/pnx4008_defconfig
+++ b/trunk/arch/arm/configs/pnx4008_defconfig
@@ -1,14 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17-rc1
-# Thu Apr 6 17:05:58 2006
+# Linux kernel version: 2.6.18-rc6
+# Mon Sep 11 13:59:24 2006
#
CONFIG_ARM=y
CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
@@ -28,6 +32,7 @@ CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
CONFIG_SYSCTL=y
CONFIG_AUDIT=y
# CONFIG_IKCONFIG is not set
@@ -44,14 +49,15 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
+CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
-CONFIG_OBSOLETE_INTERMODULE=m
#
# Loadable module support
@@ -84,18 +90,26 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
#
# System Type
#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_IOP3XX is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
# CONFIG_ARCH_L7200 is not set
+CONFIG_ARCH_PNX4008=y
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
@@ -103,13 +117,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_AT91RM9200 is not set
-CONFIG_ARCH_PNX4008=y
#
# Processor Type
@@ -138,15 +145,7 @@ CONFIG_ARM_THUMB=y
#
# PCCARD (PCMCIA/CardBus) support
#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
-CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
-
-#
-# PC-card bridges
-#
+# CONFIG_PCCARD is not set
#
# Kernel Features
@@ -164,13 +163,14 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
CONFIG_ALIGNMENT_TRAP=y
#
# Boot options
#
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="mem=64M console=ttyS0,115200"
# CONFIG_XIP_KERNEL is not set
@@ -181,7 +181,8 @@ CONFIG_CMDLINE="mem=64M console=ttyS0,115200"
#
# At least one emulation must be selected
#
-# CONFIG_FPE_NWFPE is not set
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
# CONFIG_FPE_FASTFPE is not set
# CONFIG_VFP is not set
@@ -199,7 +200,7 @@ CONFIG_BINFMT_MISC=m
CONFIG_PM=y
CONFIG_PM_LEGACY=y
# CONFIG_PM_DEBUG is not set
-CONFIG_APM=m
+# CONFIG_APM is not set
#
# Networking
@@ -210,12 +211,12 @@ CONFIG_NET=y
# Networking options
#
# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=m
+CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=m
+CONFIG_UNIX=y
CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
@@ -227,10 +228,12 @@ CONFIG_IP_ROUTE_FWMARK=y
CONFIG_IP_ROUTE_MULTIPATH=y
# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
CONFIG_IP_ROUTE_VERBOSE=y
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
@@ -241,6 +244,8 @@ CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_XFRM_TUNNEL=m
CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
@@ -287,7 +292,10 @@ CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_IPV6_TUNNEL=m
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
@@ -313,6 +321,7 @@ CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
# CONFIG_IP_NF_PPTP is not set
# CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
CONFIG_IP_NF_QUEUE=m
#
@@ -384,7 +393,7 @@ CONFIG_LLC2=m
CONFIG_IPX=m
# CONFIG_IPX_INTERN is not set
CONFIG_ATALK=m
-CONFIG_DEV_APPLETALK=y
+CONFIG_DEV_APPLETALK=m
CONFIG_IPDDP=m
CONFIG_IPDDP_ENCAP=y
CONFIG_IPDDP_DECAP=y
@@ -445,110 +454,9 @@ CONFIG_NET_ESTIMATOR=y
# Network testing
#
CONFIG_NET_PKTGEN=m
-CONFIG_HAMRADIO=y
-
-#
-# Packet Radio protocols
-#
-CONFIG_AX25=m
-# CONFIG_AX25_DAMA_SLAVE is not set
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-
-#
-# AX.25 network device drivers
-#
-CONFIG_MKISS=m
-CONFIG_6PACK=m
-CONFIG_BPQETHER=m
-CONFIG_BAYCOM_SER_FDX=m
-CONFIG_BAYCOM_SER_HDX=m
-CONFIG_BAYCOM_PAR=m
-CONFIG_BAYCOM_EPP=m
-CONFIG_YAM=m
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-
-#
-# Dongle support
-#
-CONFIG_DONGLE=y
-CONFIG_ESI_DONGLE=m
-CONFIG_ACTISYS_DONGLE=m
-CONFIG_TEKRAM_DONGLE=m
-# CONFIG_TOIM3232_DONGLE is not set
-CONFIG_LITELINK_DONGLE=m
-CONFIG_MA600_DONGLE=m
-CONFIG_GIRBIL_DONGLE=m
-CONFIG_MCP2120_DONGLE=m
-CONFIG_OLD_BELKIN_DONGLE=m
-CONFIG_ACT200L_DONGLE=m
-
-#
-# Old SIR device drivers
-#
-CONFIG_IRPORT_SIR=m
-
-#
-# Old Serial dongle support
-#
-# CONFIG_DONGLE_OLD is not set
-
-#
-# FIR device drivers
-#
-CONFIG_USB_IRDA=m
-CONFIG_SIGMATEL_FIR=m
-CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_CMTP=m
-CONFIG_BT_HIDP=m
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIUSB=m
-CONFIG_BT_HCIUSB_SCO=y
-CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIBCM203X=m
-# CONFIG_BT_HCIBPA10X is not set
-CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
-CONFIG_BT_HCIBTUART=m
-CONFIG_BT_HCIVHCI=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_IEEE80211=m
# CONFIG_IEEE80211_DEBUG is not set
# CONFIG_IEEE80211_CRYPT_WEP is not set
@@ -566,8 +474,9 @@ CONFIG_WIRELESS_EXT=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
@@ -577,11 +486,11 @@ CONFIG_FW_LOADER=m
#
# Memory Technology Devices (MTD)
#
-CONFIG_MTD=m
+CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_CONCAT=m
+CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
@@ -591,22 +500,18 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
#
# User Modules And Translation Layers
#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_BLOCK_RO=m
-CONFIG_FTL=m
-CONFIG_NFTL=m
-CONFIG_NFTL_RW=y
-CONFIG_INFTL=m
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
#
# RAM/ROM/Flash chip drivers
#
-CONFIG_MTD_CFI=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=m
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -617,36 +522,27 @@ CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=m
-CONFIG_MTD_CFI_AMDSTD=m
-CONFIG_MTD_CFI_STAA=m
-CONFIG_MTD_CFI_UTIL=m
-CONFIG_MTD_RAM=m
-CONFIG_MTD_ROM=m
-CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
#
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=m
-CONFIG_MTD_PHYSMAP_START=0x8000000
-CONFIG_MTD_PHYSMAP_LEN=0x4000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
CONFIG_MTD_SLRAM=m
CONFIG_MTD_PHRAM=m
CONFIG_MTD_MTDRAM=m
CONFIG_MTDRAM_TOTAL_SIZE=4096
CONFIG_MTDRAM_ERASE_SIZE=128
-CONFIG_MTD_BLKMTD=m
# CONFIG_MTD_BLOCK2MTD is not set
#
@@ -663,14 +559,12 @@ CONFIG_MTD_DOCPROBE_ADDRESS=0
#
# NAND Flash Device Drivers
#
-CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-CONFIG_MTD_NAND_IDS=m
-CONFIG_MTD_NAND_DISKONCHIP=m
-# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
-CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
-# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_NANDSIM=m
#
# OneNAND Flash Device Drivers
@@ -680,15 +574,7 @@ CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
#
# Parallel port support
#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_FIFO=y
-# CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_PC_PCMCIA=m
-CONFIG_PARPORT_NOT_PC=y
-# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_GSC is not set
-CONFIG_PARPORT_1284=y
+# CONFIG_PARPORT is not set
#
# Plug and Play support
@@ -697,79 +583,21 @@ CONFIG_PARPORT_1284=y
#
# Block devices
#
-CONFIG_PARIDE=m
-CONFIG_PARIDE_PARPORT=m
-
-#
-# Parallel IDE high-level drivers
-#
-CONFIG_PARIDE_PD=m
-CONFIG_PARIDE_PCD=m
-CONFIG_PARIDE_PF=m
-CONFIG_PARIDE_PT=m
-CONFIG_PARIDE_PG=m
-
-#
-# Parallel IDE protocol modules
-#
-CONFIG_PARIDE_ATEN=m
-CONFIG_PARIDE_BPCK=m
-CONFIG_PARIDE_BPCK6=m
-CONFIG_PARIDE_COMM=m
-CONFIG_PARIDE_DSTR=m
-CONFIG_PARIDE_FIT2=m
-CONFIG_PARIDE_FIT3=m
-CONFIG_PARIDE_EPAT=m
-# CONFIG_PARIDE_EPATC8 is not set
-CONFIG_PARIDE_EPIA=m
-CONFIG_PARIDE_FRIQ=m
-CONFIG_PARIDE_FRPW=m
-CONFIG_PARIDE_KBIC=m
-CONFIG_PARIDE_KTTI=m
-CONFIG_PARIDE_ON20=m
-CONFIG_PARIDE_ON26=m
# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
# CONFIG_ATA_OVER_ETH is not set
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-CONFIG_BLK_DEV_IDESCSI=m
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=m
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
#
# SCSI device support
#
@@ -808,41 +636,12 @@ CONFIG_SCSI_FC_ATTRS=m
#
# CONFIG_ISCSI_TCP is not set
CONFIG_SCSI_SATA=m
-CONFIG_SCSI_PPA=m
-CONFIG_SCSI_IMM=m
-# CONFIG_SCSI_IZIP_EPP16 is not set
-# CONFIG_SCSI_IZIP_SLOW_CTR is not set
CONFIG_SCSI_DEBUG=m
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_PCMCIA_AHA152X=m
-CONFIG_PCMCIA_FDOMAIN=m
-CONFIG_PCMCIA_NINJA_SCSI=m
-CONFIG_PCMCIA_QLOGIC=m
-CONFIG_PCMCIA_SYM53C500=m
-
#
# Multi-device support (RAID and LVM)
#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID5=m
-# CONFIG_MD_RAID5_RESHAPE is not set
-CONFIG_MD_RAID6=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-# CONFIG_DM_MULTIPATH is not set
+# CONFIG_MD is not set
#
# Fusion MPT device support
@@ -878,9 +677,6 @@ CONFIG_NET_ETHERNET=y
CONFIG_MII=m
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
-CONFIG_NET_POCKET=y
-CONFIG_DE600=m
-CONFIG_DE620=m
#
# Ethernet (1000 Mbit)
@@ -904,49 +700,13 @@ CONFIG_NET_RADIO=y
# Obsolete Wireless cards support (pre-802.11)
#
CONFIG_STRIP=m
-CONFIG_PCMCIA_WAVELAN=m
-CONFIG_PCMCIA_NETWAVE=m
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-CONFIG_PCMCIA_RAYCS=m
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-CONFIG_ATMEL=m
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-# CONFIG_PCMCIA_SPECTRUM is not set
-CONFIG_AIRO_CS=m
-CONFIG_PCMCIA_ATMEL=m
-CONFIG_PCMCIA_WL3501=m
+# CONFIG_USB_ZD1201 is not set
# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
#
# Wan interfaces
#
CONFIG_WAN=y
-CONFIG_SYNCLINK_SYNCPPP=m
CONFIG_HDLC=m
CONFIG_HDLC_RAW=y
CONFIG_HDLC_RAW_ETH=y
@@ -966,7 +726,6 @@ CONFIG_X25_ASY=m
#
# CONFIG_ATM_DUMMY is not set
CONFIG_ATM_TCP=m
-CONFIG_PLIP=m
CONFIG_PPP=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPP_FILTER=y
@@ -991,114 +750,7 @@ CONFIG_NET_POLL_CONTROLLER=y
#
# ISDN subsystem
#
-CONFIG_ISDN=m
-
-#
-# Old ISDN4Linux
-#
-CONFIG_ISDN_I4L=m
-CONFIG_ISDN_PPP=y
-CONFIG_ISDN_PPP_VJ=y
-CONFIG_ISDN_MPP=y
-CONFIG_IPPP_FILTER=y
-CONFIG_ISDN_PPP_BSDCOMP=m
-CONFIG_ISDN_AUDIO=y
-CONFIG_ISDN_TTY_FAX=y
-CONFIG_ISDN_X25=y
-
-#
-# ISDN feature submodules
-#
-CONFIG_ISDN_DRV_LOOP=m
-CONFIG_ISDN_DIVERSION=m
-
-#
-# ISDN4Linux hardware drivers
-#
-
-#
-# Passive cards
-#
-CONFIG_ISDN_DRV_HISAX=m
-
-#
-# D-channel protocol features
-#
-CONFIG_HISAX_EURO=y
-CONFIG_DE_AOC=y
-# CONFIG_HISAX_NO_SENDCOMPLETE is not set
-# CONFIG_HISAX_NO_LLC is not set
-# CONFIG_HISAX_NO_KEYPAD is not set
-CONFIG_HISAX_1TR6=y
-CONFIG_HISAX_NI1=y
-CONFIG_HISAX_MAX_CARDS=8
-
-#
-# HiSax supported cards
-#
-CONFIG_HISAX_16_3=y
-CONFIG_HISAX_S0BOX=y
-CONFIG_HISAX_FRITZPCI=y
-CONFIG_HISAX_AVM_A1_PCMCIA=y
-CONFIG_HISAX_ELSA=y
-CONFIG_HISAX_DIEHLDIVA=y
-CONFIG_HISAX_SEDLBAUER=y
-CONFIG_HISAX_NICCY=y
-CONFIG_HISAX_GAZEL=y
-CONFIG_HISAX_HFC_SX=y
-# CONFIG_HISAX_DEBUG is not set
-
-#
-# HiSax PCMCIA card service modules
-#
-CONFIG_HISAX_SEDLBAUER_CS=m
-CONFIG_HISAX_ELSA_CS=m
-CONFIG_HISAX_AVM_A1_CS=m
-CONFIG_HISAX_TELES_CS=m
-
-#
-# HiSax sub driver modules
-#
-CONFIG_HISAX_ST5481=m
-CONFIG_HISAX_HFCUSB=m
-# CONFIG_HISAX_HFC4S8S is not set
-CONFIG_HISAX_HDLC=y
-
-#
-# Active cards
-#
-
-#
-# Siemens Gigaset
-#
-# CONFIG_ISDN_DRV_GIGASET is not set
-
-#
-# CAPI subsystem
-#
-CONFIG_ISDN_CAPI=m
-CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
-CONFIG_ISDN_CAPI_MIDDLEWARE=y
-CONFIG_ISDN_CAPI_CAPI20=m
-CONFIG_ISDN_CAPI_CAPIFS_BOOL=y
-CONFIG_ISDN_CAPI_CAPIFS=m
-CONFIG_ISDN_CAPI_CAPIDRV=m
-
-#
-# CAPI hardware drivers
-#
-
-#
-# Active AVM cards
-#
-CONFIG_CAPI_AVM=y
-CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
-CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
-
-#
-# Active Eicon DIVA Server cards
-#
-CONFIG_CAPI_EICON=y
+# CONFIG_ISDN is not set
#
# Input device support
@@ -1108,10 +760,7 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_JOYDEV=m
CONFIG_INPUT_TSDEV=m
CONFIG_INPUT_TSDEV_SCREEN_X=240
@@ -1153,11 +802,9 @@ CONFIG_JOYSTICK_SPACEORB=m
CONFIG_JOYSTICK_SPACEBALL=m
CONFIG_JOYSTICK_STINGER=m
# CONFIG_JOYSTICK_TWIDJOY is not set
-CONFIG_JOYSTICK_DB9=m
-CONFIG_JOYSTICK_GAMECON=m
-CONFIG_JOYSTICK_TURBOGRAFX=m
CONFIG_JOYSTICK_JOYDUMP=m
CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
CONFIG_TOUCHSCREEN_GUNZE=m
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
@@ -1170,7 +817,6 @@ CONFIG_INPUT_UINPUT=m
#
CONFIG_SERIO=y
CONFIG_SERIO_SERPORT=m
-CONFIG_SERIO_PARKBD=m
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=m
CONFIG_GAMEPORT=m
@@ -1183,32 +829,14 @@ CONFIG_GAMEPORT_L4=m
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
-CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_COMPUTONE=m
-CONFIG_ROCKETPORT=m
-CONFIG_CYCLADES=m
-# CONFIG_CYZ_INTR is not set
-CONFIG_DIGIEPCA=m
-CONFIG_MOXA_INTELLIO=m
-CONFIG_MOXA_SMARTIO=m
-# CONFIG_ISI is not set
-CONFIG_SYNCLINKMP=m
-CONFIG_N_HDLC=m
-# CONFIG_RISCOM8 is not set
-# CONFIG_SPECIALIX is not set
-CONFIG_SX=m
-CONFIG_RIO=m
-CONFIG_RIO_OLDPCI=y
-CONFIG_STALDRV=y
-CONFIG_STALLION=m
-CONFIG_ISTALLION=m
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
@@ -1225,20 +853,11 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-CONFIG_PRINTER=m
-# CONFIG_LP_CONSOLE is not set
-CONFIG_PPDEV=m
-CONFIG_TIPAR=m
#
# IPMI
#
-CONFIG_IPMI_HANDLER=m
-# CONFIG_IPMI_PANIC_EVENT is not set
-CONFIG_IPMI_DEVICE_INTERFACE=m
-CONFIG_IPMI_SI=m
-CONFIG_IPMI_WATCHDOG=m
-CONFIG_IPMI_POWEROFF=m
+# CONFIG_IPMI_HANDLER is not set
#
# Watchdog Cards
@@ -1255,22 +874,15 @@ CONFIG_SOFT_WATCHDOG=m
# USB-based Watchdog Cards
#
CONFIG_USBPCWATCHDOG=m
-CONFIG_NVRAM=m
-CONFIG_DTLK=m
-CONFIG_R3964=m
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
-
-#
-# PCMCIA character devices
-#
-CONFIG_SYNCLINK_CS=m
-# CONFIG_CARDMAN_4000 is not set
-# CONFIG_CARDMAN_4040 is not set
-CONFIG_RAW_DRIVER=m
-CONFIG_MAX_RAW_DEVS=256
+# CONFIG_RAW_DRIVER is not set
#
# TPM devices
@@ -1281,8 +893,8 @@ CONFIG_MAX_RAW_DEVS=256
#
# I2C support
#
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
#
# I2C Algorithms
@@ -1294,11 +906,10 @@ CONFIG_I2C_ALGOPCA=m
#
# I2C Hardware Bus support
#
-CONFIG_I2C_ISA=m
-CONFIG_I2C_PARPORT=m
-CONFIG_I2C_PARPORT_LIGHT=m
-CONFIG_I2C_STUB=m
-CONFIG_I2C_PCA_ISA=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
#
# Miscellaneous I2C Chip support
@@ -1318,66 +929,28 @@ CONFIG_SENSORS_PCF8591=m
#
# SPI support
#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
#
-# Dallas's 1-wire bus
+# SPI Master Controller Drivers
#
-CONFIG_W1=m
+CONFIG_SPI_BITBANG=y
#
-# 1-wire Bus Masters
+# SPI Protocol Masters
#
-# CONFIG_W1_MASTER_DS9490 is not set
-# CONFIG_W1_MASTER_DS2482 is not set
#
-# 1-wire Slaves
+# Dallas's 1-wire bus
#
-# CONFIG_W1_SLAVE_THERM is not set
-# CONFIG_W1_SLAVE_SMEM is not set
-# CONFIG_W1_SLAVE_DS2433 is not set
#
# Hardware Monitoring support
#
-CONFIG_HWMON=y
-CONFIG_HWMON_VID=m
-CONFIG_SENSORS_ADM1021=m
-CONFIG_SENSORS_ADM1025=m
-CONFIG_SENSORS_ADM1026=m
-CONFIG_SENSORS_ADM1031=m
-# CONFIG_SENSORS_ADM9240 is not set
-CONFIG_SENSORS_ASB100=m
-# CONFIG_SENSORS_ATXP1 is not set
-CONFIG_SENSORS_DS1621=m
-# CONFIG_SENSORS_F71805F is not set
-CONFIG_SENSORS_FSCHER=m
-# CONFIG_SENSORS_FSCPOS is not set
-CONFIG_SENSORS_GL518SM=m
-# CONFIG_SENSORS_GL520SM is not set
-CONFIG_SENSORS_IT87=m
-CONFIG_SENSORS_LM63=m
-CONFIG_SENSORS_LM75=m
-CONFIG_SENSORS_LM77=m
-CONFIG_SENSORS_LM78=m
-CONFIG_SENSORS_LM80=m
-CONFIG_SENSORS_LM83=m
-CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_LM87=m
-CONFIG_SENSORS_LM90=m
-# CONFIG_SENSORS_LM92 is not set
-CONFIG_SENSORS_MAX1619=m
-CONFIG_SENSORS_PC87360=m
-CONFIG_SENSORS_SMSC47M1=m
-# CONFIG_SENSORS_SMSC47B397 is not set
-CONFIG_SENSORS_W83781D=m
-# CONFIG_SENSORS_W83792D is not set
-CONFIG_SENSORS_W83L785TS=m
-CONFIG_SENSORS_W83627HF=m
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
#
# Misc devices
@@ -1388,10 +961,19 @@ CONFIG_SENSORS_W83627HF=m
#
# CONFIG_NEW_LEDS is not set
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -1460,18 +1042,25 @@ CONFIG_DVB_TDA10021=m
CONFIG_DVB_STV0297=m
#
-# ATSC (North American/Korean Terresterial DTV) frontends
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
#
# CONFIG_DVB_NXT200X is not set
# CONFIG_DVB_OR51211 is not set
# CONFIG_DVB_OR51132 is not set
# CONFIG_DVB_BCM3510 is not set
# CONFIG_DVB_LGDT330X is not set
+
+#
+# Miscellaneous devices
+#
+CONFIG_DVB_LNBP21=m
+# CONFIG_DVB_ISL6421 is not set
# CONFIG_USB_DABUSB is not set
#
# Graphics support
#
+CONFIG_FIRMWARE_EDID=y
# CONFIG_FB is not set
#
@@ -1479,6 +1068,7 @@ CONFIG_DVB_STV0297=m
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -1525,18 +1115,13 @@ CONFIG_SND_MPU401=m
#
CONFIG_SND_USB_AUDIO=m
-#
-# PCMCIA devices
-#
-
#
# Open Sound System
#
CONFIG_SOUND_PRIME=m
-# CONFIG_OBSOLETE_OSS_DRIVER is not set
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
-CONFIG_SOUND_TVMIXER=m
#
# USB support
@@ -1544,7 +1129,7 @@ CONFIG_SOUND_TVMIXER=m
CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
# CONFIG_USB_ARCH_HAS_EHCI is not set
-CONFIG_USB=m
+CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
#
@@ -1561,7 +1146,6 @@ CONFIG_USB_BANDWIDTH=y
#
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_SL811_HCD=m
-# CONFIG_USB_SL811_CS is not set
#
# USB Device Class drivers
@@ -1580,7 +1164,6 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_DPCM=y
CONFIG_USB_STORAGE_USBAT=y
CONFIG_USB_STORAGE_SDDR09=y
@@ -1608,9 +1191,7 @@ CONFIG_USB_WACOM=m
# CONFIG_USB_ACECAD is not set
CONFIG_USB_KBTAB=m
CONFIG_USB_POWERMATE=m
-CONFIG_USB_MTOUCH=m
-# CONFIG_USB_ITMTOUCH is not set
-CONFIG_USB_EGALAX=m
+# CONFIG_USB_TOUCHSCREEN is not set
# CONFIG_USB_YEALINK is not set
CONFIG_USB_XPAD=m
CONFIG_USB_ATI_REMOTE=m
@@ -1640,13 +1221,11 @@ CONFIG_USB_NET_NET1080=m
# CONFIG_USB_NET_RNDIS_HOST is not set
# CONFIG_USB_NET_CDC_SUBSET is not set
CONFIG_USB_NET_ZAURUS=m
-# CONFIG_USB_ZD1201 is not set
CONFIG_USB_MON=y
#
# USB port drivers
#
-CONFIG_USB_USS720=m
#
# USB Serial Converter support
@@ -1654,7 +1233,7 @@ CONFIG_USB_USS720=m
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
# CONFIG_USB_SERIAL_AIRPRIME is not set
-# CONFIG_USB_SERIAL_ANYDATA is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
@@ -1662,6 +1241,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
@@ -1691,9 +1271,11 @@ CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_SERIAL_HP4X is not set
CONFIG_USB_SERIAL_SAFE=m
# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
# CONFIG_USB_SERIAL_TI is not set
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_XIRCOM=m
+# CONFIG_USB_SERIAL_OPTION is not set
CONFIG_USB_SERIAL_OMNINET=m
CONFIG_USB_EZUSB=y
@@ -1707,10 +1289,12 @@ CONFIG_USB_RIO500=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
CONFIG_USB_CYTHERM=m
CONFIG_USB_PHIDGETKIT=m
CONFIG_USB_PHIDGETSERVO=m
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_LD is not set
CONFIG_USB_TEST=m
@@ -1787,7 +1371,6 @@ CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_STATISTICS=y
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
CONFIG_XFS_QUOTA=y
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
@@ -1796,6 +1379,7 @@ CONFIG_XFS_RT=y
CONFIG_MINIX_FS=m
CONFIG_ROMFS_FS=m
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
CONFIG_QUOTA=y
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m
@@ -1856,6 +1440,7 @@ CONFIG_JFFS2_FS=m
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@@ -1866,11 +1451,13 @@ CONFIG_HPFS_FS=m
CONFIG_QNX4FS_FS=m
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
#
# Network File Systems
#
-CONFIG_NFS_FS=m
+CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
@@ -1880,19 +1467,22 @@ CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=m
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
CONFIG_RPCSEC_GSS_SPKM3=m
CONFIG_SMB_FS=m
# CONFIG_SMB_NLS_DEFAULT is not set
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_EXPERIMENTAL is not set
CONFIG_NCP_FS=m
CONFIG_NCPFS_PACKET_SIGNING=y
@@ -1940,7 +1530,7 @@ CONFIG_SUN_PARTITION=y
#
# Native Language Support
#
-CONFIG_NLS=y
+CONFIG_NLS=m
CONFIG_NLS_DEFAULT="cp437"
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
@@ -1984,26 +1574,29 @@ CONFIG_NLS_UTF8=m
#
# Profiling support
#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+# CONFIG_PROFILING is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
CONFIG_FRAME_POINTER=y
@@ -2013,8 +1606,7 @@ CONFIG_FORCED_INLINING=y
# CONFIG_DEBUG_USER is not set
# CONFIG_DEBUG_WAITQ is not set
# CONFIG_DEBUG_ERRORS is not set
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_LL is not set
#
# Security options
@@ -2039,7 +1631,7 @@ CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
# CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_SERPENT=m
@@ -2068,5 +1660,6 @@ CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
-CONFIG_REED_SOLOMON=m
-CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_PLIST=y
diff --git a/trunk/arch/arm/mach-s3c2410/Kconfig b/trunk/arch/arm/mach-s3c2410/Kconfig
index b4171dd43df0..bbd138be6a70 100644
--- a/trunk/arch/arm/mach-s3c2410/Kconfig
+++ b/trunk/arch/arm/mach-s3c2410/Kconfig
@@ -81,9 +81,17 @@ config SMDK2440_CPU2442
depends on ARCH_S3C2440
select CPU_S3C2442
+config MACH_S3C2413
+ bool
+ help
+ Internal node for S3C2413 verison of SMDK2413, so that
+ machine_is_s3c2413() will work when MACH_SMDK2413 is
+ selected
+
config MACH_SMDK2413
bool "SMDK2413"
select CPU_S3C2412
+ select MACH_S3C2413
select MACH_SMDK
help
Say Y here if you are using an SMDK2413
diff --git a/trunk/arch/arm/mach-s3c2410/irq.h b/trunk/arch/arm/mach-s3c2410/irq.h
index f7cc4c983de5..842a9f42c97b 100644
--- a/trunk/arch/arm/mach-s3c2410/irq.h
+++ b/trunk/arch/arm/mach-s3c2410/irq.h
@@ -100,5 +100,10 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
/* exported for use in arch/arm/mach-s3c2410 */
+#ifdef CONFIG_PM
extern int s3c_irq_wake(unsigned int irqno, unsigned int state);
+#else
+#define s3c_irq_wake NULL
+#endif
+
extern int s3c_irqext_type(unsigned int irq, unsigned int type);
diff --git a/trunk/arch/arm/mach-s3c2410/s3c2412.c b/trunk/arch/arm/mach-s3c2410/s3c2412.c
index e24ffd5e478b..2d163f7600be 100644
--- a/trunk/arch/arm/mach-s3c2410/s3c2412.c
+++ b/trunk/arch/arm/mach-s3c2410/s3c2412.c
@@ -35,11 +35,15 @@
#include
#include
+#include
#include
#include
+#include
+
#include
#include
+#include
#include
#include
#include
@@ -75,6 +79,27 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
s3c_device_nand.name = "s3c2412-nand";
}
+/* s3c2412_idle
+ *
+ * use the standard idle call by ensuring the idle mode
+ * in power config, then issuing the idle co-processor
+ * instruction
+*/
+
+static void s3c2412_idle(void)
+{
+ unsigned long tmp;
+
+ /* ensure our idle mode is to go to idle */
+
+ tmp = __raw_readl(S3C2412_PWRCFG);
+ tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+ tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
+ __raw_writel(tmp, S3C2412_PWRCFG);
+
+ cpu_do_idle();
+}
+
/* s3c2412_map_io
*
* register the standard cpu IO areas, and any passed in from the
@@ -87,6 +112,10 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
+ /* set our idle function */
+
+ s3c24xx_idle = s3c2412_idle;
+
/* register our io-tables */
iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
diff --git a/trunk/arch/arm/mm/proc-xscale.S b/trunk/arch/arm/mm/proc-xscale.S
index 561bff73a036..3ca0c92e98a2 100644
--- a/trunk/arch/arm/mm/proc-xscale.S
+++ b/trunk/arch/arm/mm/proc-xscale.S
@@ -644,7 +644,7 @@ __80219_proc_info:
.type __8032x_proc_info,#object
__8032x_proc_info:
.long 0x69052420
- .long 0xffffffe0
+ .long 0xfffff7e0
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
diff --git a/trunk/arch/frv/Makefile b/trunk/arch/frv/Makefile
index d163747d17c0..038e3a8457e0 100644
--- a/trunk/arch/frv/Makefile
+++ b/trunk/arch/frv/Makefile
@@ -108,11 +108,8 @@ Image: vmlinux
bootstrap:
$(Q)$(MAKEBOOT) bootstrap
-archmrproper:
- $(Q)$(MAKE) $(build)=arch/frv/boot mrproper
-
archclean:
- $(Q)$(MAKE) $(build)=arch/frv/boot clean
+ $(Q)$(MAKE) $(clean)=arch/frv/boot
archdep: scripts/mkdep symlinks
$(Q)$(MAKE) $(build)=arch/frv/boot dep
diff --git a/trunk/arch/frv/boot/Makefile b/trunk/arch/frv/boot/Makefile
index 5dfc93fd945a..dc6f03824423 100644
--- a/trunk/arch/frv/boot/Makefile
+++ b/trunk/arch/frv/boot/Makefile
@@ -8,6 +8,8 @@
# Copyright (C) 1995-2000 Russell King
#
+targets := Image zImage bootpImage
+
SYSTEM =$(TOPDIR)/$(LINUX)
ZTEXTADDR = 0x02080000
@@ -66,7 +68,6 @@ zinstall: $(CONFIGURE) zImage
# miscellany
#
mrproper clean:
- $(RM) Image zImage bootpImage
# @$(MAKE) -C compressed clean
# @$(MAKE) -C bootp clean
diff --git a/trunk/arch/i386/crypto/Makefile b/trunk/arch/i386/crypto/Makefile
index 103c353d0a63..3fd19af18e34 100644
--- a/trunk/arch/i386/crypto/Makefile
+++ b/trunk/arch/i386/crypto/Makefile
@@ -5,5 +5,8 @@
#
obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
+obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
aes-i586-y := aes-i586-asm.o aes.o
+twofish-i586-y := twofish-i586-asm.o twofish.o
+
diff --git a/trunk/arch/i386/crypto/aes.c b/trunk/arch/i386/crypto/aes.c
index d3806daa3de3..49aad9397f10 100644
--- a/trunk/arch/i386/crypto/aes.c
+++ b/trunk/arch/i386/crypto/aes.c
@@ -379,12 +379,13 @@ static void gen_tabs(void)
}
static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
- unsigned int key_len, u32 *flags)
+ unsigned int key_len)
{
int i;
u32 ss[8];
struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
const __le32 *key = (const __le32 *)in_key;
+ u32 *flags = &tfm->crt_flags;
/* encryption schedule */
diff --git a/trunk/arch/i386/crypto/twofish-i586-asm.S b/trunk/arch/i386/crypto/twofish-i586-asm.S
new file mode 100644
index 000000000000..39b98ed2c1b9
--- /dev/null
+++ b/trunk/arch/i386/crypto/twofish-i586-asm.S
@@ -0,0 +1,335 @@
+/***************************************************************************
+* Copyright (C) 2006 by Joachim Fritschi, *
+* *
+* 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; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* 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. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+***************************************************************************/
+
+.file "twofish-i586-asm.S"
+.text
+
+#include
+
+/* return adress at 0 */
+
+#define in_blk 12 /* input byte array address parameter*/
+#define out_blk 8 /* output byte array address parameter*/
+#define tfm 4 /* Twofish context structure */
+
+#define a_offset 0
+#define b_offset 4
+#define c_offset 8
+#define d_offset 12
+
+/* Structure of the crypto context struct*/
+
+#define s0 0 /* S0 Array 256 Words each */
+#define s1 1024 /* S1 Array */
+#define s2 2048 /* S2 Array */
+#define s3 3072 /* S3 Array */
+#define w 4096 /* 8 whitening keys (word) */
+#define k 4128 /* key 1-32 ( word ) */
+
+/* define a few register aliases to allow macro substitution */
+
+#define R0D %eax
+#define R0B %al
+#define R0H %ah
+
+#define R1D %ebx
+#define R1B %bl
+#define R1H %bh
+
+#define R2D %ecx
+#define R2B %cl
+#define R2H %ch
+
+#define R3D %edx
+#define R3B %dl
+#define R3H %dh
+
+
+/* performs input whitening */
+#define input_whitening(src,context,offset)\
+ xor w+offset(context), src;
+
+/* performs input whitening */
+#define output_whitening(src,context,offset)\
+ xor w+16+offset(context), src;
+
+/*
+ * a input register containing a (rotated 16)
+ * b input register containing b
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ */
+#define encrypt_round(a,b,c,d,round)\
+ push d ## D;\
+ movzx b ## B, %edi;\
+ mov s1(%ebp,%edi,4),d ## D;\
+ movzx a ## B, %edi;\
+ mov s2(%ebp,%edi,4),%esi;\
+ movzx b ## H, %edi;\
+ ror $16, b ## D;\
+ xor s2(%ebp,%edi,4),d ## D;\
+ movzx a ## H, %edi;\
+ ror $16, a ## D;\
+ xor s3(%ebp,%edi,4),%esi;\
+ movzx b ## B, %edi;\
+ xor s3(%ebp,%edi,4),d ## D;\
+ movzx a ## B, %edi;\
+ xor (%ebp,%edi,4), %esi;\
+ movzx b ## H, %edi;\
+ ror $15, b ## D;\
+ xor (%ebp,%edi,4), d ## D;\
+ movzx a ## H, %edi;\
+ xor s1(%ebp,%edi,4),%esi;\
+ pop %edi;\
+ add d ## D, %esi;\
+ add %esi, d ## D;\
+ add k+round(%ebp), %esi;\
+ xor %esi, c ## D;\
+ rol $15, c ## D;\
+ add k+4+round(%ebp),d ## D;\
+ xor %edi, d ## D;
+
+/*
+ * a input register containing a (rotated 16)
+ * b input register containing b
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ * last round has different rotations for the output preparation
+ */
+#define encrypt_last_round(a,b,c,d,round)\
+ push d ## D;\
+ movzx b ## B, %edi;\
+ mov s1(%ebp,%edi,4),d ## D;\
+ movzx a ## B, %edi;\
+ mov s2(%ebp,%edi,4),%esi;\
+ movzx b ## H, %edi;\
+ ror $16, b ## D;\
+ xor s2(%ebp,%edi,4),d ## D;\
+ movzx a ## H, %edi;\
+ ror $16, a ## D;\
+ xor s3(%ebp,%edi,4),%esi;\
+ movzx b ## B, %edi;\
+ xor s3(%ebp,%edi,4),d ## D;\
+ movzx a ## B, %edi;\
+ xor (%ebp,%edi,4), %esi;\
+ movzx b ## H, %edi;\
+ ror $16, b ## D;\
+ xor (%ebp,%edi,4), d ## D;\
+ movzx a ## H, %edi;\
+ xor s1(%ebp,%edi,4),%esi;\
+ pop %edi;\
+ add d ## D, %esi;\
+ add %esi, d ## D;\
+ add k+round(%ebp), %esi;\
+ xor %esi, c ## D;\
+ ror $1, c ## D;\
+ add k+4+round(%ebp),d ## D;\
+ xor %edi, d ## D;
+
+/*
+ * a input register containing a
+ * b input register containing b (rotated 16)
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ */
+#define decrypt_round(a,b,c,d,round)\
+ push c ## D;\
+ movzx a ## B, %edi;\
+ mov (%ebp,%edi,4), c ## D;\
+ movzx b ## B, %edi;\
+ mov s3(%ebp,%edi,4),%esi;\
+ movzx a ## H, %edi;\
+ ror $16, a ## D;\
+ xor s1(%ebp,%edi,4),c ## D;\
+ movzx b ## H, %edi;\
+ ror $16, b ## D;\
+ xor (%ebp,%edi,4), %esi;\
+ movzx a ## B, %edi;\
+ xor s2(%ebp,%edi,4),c ## D;\
+ movzx b ## B, %edi;\
+ xor s1(%ebp,%edi,4),%esi;\
+ movzx a ## H, %edi;\
+ ror $15, a ## D;\
+ xor s3(%ebp,%edi,4),c ## D;\
+ movzx b ## H, %edi;\
+ xor s2(%ebp,%edi,4),%esi;\
+ pop %edi;\
+ add %esi, c ## D;\
+ add c ## D, %esi;\
+ add k+round(%ebp), c ## D;\
+ xor %edi, c ## D;\
+ add k+4+round(%ebp),%esi;\
+ xor %esi, d ## D;\
+ rol $15, d ## D;
+
+/*
+ * a input register containing a
+ * b input register containing b (rotated 16)
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ * last round has different rotations for the output preparation
+ */
+#define decrypt_last_round(a,b,c,d,round)\
+ push c ## D;\
+ movzx a ## B, %edi;\
+ mov (%ebp,%edi,4), c ## D;\
+ movzx b ## B, %edi;\
+ mov s3(%ebp,%edi,4),%esi;\
+ movzx a ## H, %edi;\
+ ror $16, a ## D;\
+ xor s1(%ebp,%edi,4),c ## D;\
+ movzx b ## H, %edi;\
+ ror $16, b ## D;\
+ xor (%ebp,%edi,4), %esi;\
+ movzx a ## B, %edi;\
+ xor s2(%ebp,%edi,4),c ## D;\
+ movzx b ## B, %edi;\
+ xor s1(%ebp,%edi,4),%esi;\
+ movzx a ## H, %edi;\
+ ror $16, a ## D;\
+ xor s3(%ebp,%edi,4),c ## D;\
+ movzx b ## H, %edi;\
+ xor s2(%ebp,%edi,4),%esi;\
+ pop %edi;\
+ add %esi, c ## D;\
+ add c ## D, %esi;\
+ add k+round(%ebp), c ## D;\
+ xor %edi, c ## D;\
+ add k+4+round(%ebp),%esi;\
+ xor %esi, d ## D;\
+ ror $1, d ## D;
+
+.align 4
+.global twofish_enc_blk
+.global twofish_dec_blk
+
+twofish_enc_blk:
+ push %ebp /* save registers according to calling convention*/
+ push %ebx
+ push %esi
+ push %edi
+
+ mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
+ add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
+ mov in_blk+16(%esp),%edi /* input adress in edi */
+
+ mov (%edi), %eax
+ mov b_offset(%edi), %ebx
+ mov c_offset(%edi), %ecx
+ mov d_offset(%edi), %edx
+ input_whitening(%eax,%ebp,a_offset)
+ ror $16, %eax
+ input_whitening(%ebx,%ebp,b_offset)
+ input_whitening(%ecx,%ebp,c_offset)
+ input_whitening(%edx,%ebp,d_offset)
+ rol $1, %edx
+
+ encrypt_round(R0,R1,R2,R3,0);
+ encrypt_round(R2,R3,R0,R1,8);
+ encrypt_round(R0,R1,R2,R3,2*8);
+ encrypt_round(R2,R3,R0,R1,3*8);
+ encrypt_round(R0,R1,R2,R3,4*8);
+ encrypt_round(R2,R3,R0,R1,5*8);
+ encrypt_round(R0,R1,R2,R3,6*8);
+ encrypt_round(R2,R3,R0,R1,7*8);
+ encrypt_round(R0,R1,R2,R3,8*8);
+ encrypt_round(R2,R3,R0,R1,9*8);
+ encrypt_round(R0,R1,R2,R3,10*8);
+ encrypt_round(R2,R3,R0,R1,11*8);
+ encrypt_round(R0,R1,R2,R3,12*8);
+ encrypt_round(R2,R3,R0,R1,13*8);
+ encrypt_round(R0,R1,R2,R3,14*8);
+ encrypt_last_round(R2,R3,R0,R1,15*8);
+
+ output_whitening(%eax,%ebp,c_offset)
+ output_whitening(%ebx,%ebp,d_offset)
+ output_whitening(%ecx,%ebp,a_offset)
+ output_whitening(%edx,%ebp,b_offset)
+ mov out_blk+16(%esp),%edi;
+ mov %eax, c_offset(%edi)
+ mov %ebx, d_offset(%edi)
+ mov %ecx, (%edi)
+ mov %edx, b_offset(%edi)
+
+ pop %edi
+ pop %esi
+ pop %ebx
+ pop %ebp
+ mov $1, %eax
+ ret
+
+twofish_dec_blk:
+ push %ebp /* save registers according to calling convention*/
+ push %ebx
+ push %esi
+ push %edi
+
+
+ mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
+ add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
+ mov in_blk+16(%esp),%edi /* input adress in edi */
+
+ mov (%edi), %eax
+ mov b_offset(%edi), %ebx
+ mov c_offset(%edi), %ecx
+ mov d_offset(%edi), %edx
+ output_whitening(%eax,%ebp,a_offset)
+ output_whitening(%ebx,%ebp,b_offset)
+ ror $16, %ebx
+ output_whitening(%ecx,%ebp,c_offset)
+ output_whitening(%edx,%ebp,d_offset)
+ rol $1, %ecx
+
+ decrypt_round(R0,R1,R2,R3,15*8);
+ decrypt_round(R2,R3,R0,R1,14*8);
+ decrypt_round(R0,R1,R2,R3,13*8);
+ decrypt_round(R2,R3,R0,R1,12*8);
+ decrypt_round(R0,R1,R2,R3,11*8);
+ decrypt_round(R2,R3,R0,R1,10*8);
+ decrypt_round(R0,R1,R2,R3,9*8);
+ decrypt_round(R2,R3,R0,R1,8*8);
+ decrypt_round(R0,R1,R2,R3,7*8);
+ decrypt_round(R2,R3,R0,R1,6*8);
+ decrypt_round(R0,R1,R2,R3,5*8);
+ decrypt_round(R2,R3,R0,R1,4*8);
+ decrypt_round(R0,R1,R2,R3,3*8);
+ decrypt_round(R2,R3,R0,R1,2*8);
+ decrypt_round(R0,R1,R2,R3,1*8);
+ decrypt_last_round(R2,R3,R0,R1,0);
+
+ input_whitening(%eax,%ebp,c_offset)
+ input_whitening(%ebx,%ebp,d_offset)
+ input_whitening(%ecx,%ebp,a_offset)
+ input_whitening(%edx,%ebp,b_offset)
+ mov out_blk+16(%esp),%edi;
+ mov %eax, c_offset(%edi)
+ mov %ebx, d_offset(%edi)
+ mov %ecx, (%edi)
+ mov %edx, b_offset(%edi)
+
+ pop %edi
+ pop %esi
+ pop %ebx
+ pop %ebp
+ mov $1, %eax
+ ret
diff --git a/trunk/arch/i386/crypto/twofish.c b/trunk/arch/i386/crypto/twofish.c
new file mode 100644
index 000000000000..e3004dfe9c7a
--- /dev/null
+++ b/trunk/arch/i386/crypto/twofish.c
@@ -0,0 +1,97 @@
+/*
+ * Glue Code for optimized 586 assembler version of TWOFISH
+ *
+ * Originally Twofish for GPG
+ * By Matthew Skala , July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ * Ported to the kerneli patch by Marc Mutz
+ * Ported to CryptoAPI by Colin Slater
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus put it in the public domain. The subsequent authors
+ * have put this under the GNU General Public License.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+
+asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
+asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
+
+static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ twofish_enc_blk(tfm, dst, src);
+}
+
+static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ twofish_dec_blk(tfm, dst, src);
+}
+
+static struct crypto_alg alg = {
+ .cra_name = "twofish",
+ .cra_driver_name = "twofish-i586",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = TF_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct twofish_ctx),
+ .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = TF_MIN_KEY_SIZE,
+ .cia_max_keysize = TF_MAX_KEY_SIZE,
+ .cia_setkey = twofish_setkey,
+ .cia_encrypt = twofish_encrypt,
+ .cia_decrypt = twofish_decrypt
+ }
+ }
+};
+
+static int __init init(void)
+{
+ return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+ crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION ("Twofish Cipher Algorithm, i586 asm optimized");
+MODULE_ALIAS("twofish");
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index e6ea00edcb54..ea19d091fd41 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -32,6 +32,7 @@
#include
#include
#include /* current */
+#include
#include
#include
#include
@@ -387,6 +388,33 @@ static int acpi_cpufreq_early_init_acpi(void)
return acpi_processor_preregister_performance(acpi_perf_data);
}
+/*
+ * Some BIOSes do SW_ANY coordination internally, either set it up in hw
+ * or do it in BIOS firmware and won't inform about it to OS. If not
+ * detected, this has a side effect of making CPU run at a different speed
+ * than OS intended it to run at. Detect it and handle it cleanly.
+ */
+static int bios_with_sw_any_bug;
+
+static int __init sw_any_bug_found(struct dmi_system_id *d)
+{
+ bios_with_sw_any_bug = 1;
+ return 0;
+}
+
+static struct dmi_system_id __initdata sw_any_bug_dmi_table[] = {
+ {
+ .callback = sw_any_bug_found,
+ .ident = "Supermicro Server X6DLP",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
+ DMI_MATCH(DMI_BIOS_VERSION, "080010"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
+ },
+ },
+ { }
+};
+
static int
acpi_cpufreq_cpu_init (
struct cpufreq_policy *policy)
@@ -422,8 +450,17 @@ acpi_cpufreq_cpu_init (
* coordination is required.
*/
if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
- policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+ policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
policy->cpus = perf->shared_cpu_map;
+ }
+
+#ifdef CONFIG_SMP
+ dmi_check_system(sw_any_bug_dmi_table);
+ if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+ policy->cpus = cpu_core_map[cpu];
+ }
+#endif
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c
index 4f2c3aeef724..f5cc9f5c9bab 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
#include
#include
@@ -52,18 +53,26 @@
#define CPU_NEHEMIAH 5
static int cpu_model;
-static unsigned int numscales=16, numvscales;
+static unsigned int numscales=16;
static unsigned int fsb;
-static int minvid, maxvid;
+
+static struct mV_pos *vrm_mV_table;
+static unsigned char *mV_vrm_table;
+struct f_msr {
+ unsigned char vrm;
+};
+static struct f_msr f_msr_table[32];
+
+static unsigned int highest_speed, lowest_speed; /* kHz */
static unsigned int minmult, maxmult;
static int can_scale_voltage;
-static int vrmrev;
static struct acpi_processor *pr = NULL;
static struct acpi_processor_cx *cx = NULL;
+static int port22_en;
/* Module parameters */
-static int dont_scale_voltage;
-
+static int scale_voltage;
+static int ignore_latency;
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
@@ -71,7 +80,6 @@ static int dont_scale_voltage;
/* Clock ratios multiplied by 10 */
static int clock_ratio[32];
static int eblcr_table[32];
-static int voltage_table[32];
static unsigned int highest_speed, lowest_speed; /* kHz */
static int longhaul_version;
static struct cpufreq_frequency_table *longhaul_table;
@@ -124,10 +132,9 @@ static int longhaul_get_cpu_mult(void)
/* For processor with BCR2 MSR */
-static void do_longhaul1(int cx_address, unsigned int clock_ratio_index)
+static void do_longhaul1(unsigned int clock_ratio_index)
{
union msr_bcr2 bcr2;
- u32 t;
rdmsrl(MSR_VIA_BCR2, bcr2.val);
/* Enable software clock multiplier */
@@ -136,13 +143,11 @@ static void do_longhaul1(int cx_address, unsigned int clock_ratio_index)
/* Sync to timer tick */
safe_halt();
- ACPI_FLUSH_CPU_CACHE();
/* Change frequency on next halt or sleep */
wrmsrl(MSR_VIA_BCR2, bcr2.val);
- /* Invoke C3 */
- inb(cx_address);
- /* Dummy op - must do something useless after P_LVL3 read */
- t = inl(acpi_fadt.xpm_tmr_blk.address);
+ /* Invoke transition */
+ ACPI_FLUSH_CPU_CACHE();
+ halt();
/* Disable software clock multiplier */
local_irq_disable();
@@ -164,11 +169,16 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
longhaul.bits.EnableSoftBusRatio = 1;
+ if (can_scale_voltage) {
+ longhaul.bits.SoftVID = f_msr_table[clock_ratio_index].vrm;
+ longhaul.bits.EnableSoftVID = 1;
+ }
+
/* Sync to timer tick */
safe_halt();
- ACPI_FLUSH_CPU_CACHE();
/* Change frequency on next halt or sleep */
wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+ ACPI_FLUSH_CPU_CACHE();
/* Invoke C3 */
inb(cx_address);
/* Dummy op - must do something useless after P_LVL3 read */
@@ -227,10 +237,13 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
outb(0xFF,0xA1); /* Overkill */
outb(0xFE,0x21); /* TMR0 only */
- /* Disable bus master arbitration */
- if (pr->flags.bm_check) {
+ if (pr->flags.bm_control) {
+ /* Disable bus master arbitration */
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
ACPI_MTX_DO_NOT_LOCK);
+ } else if (port22_en) {
+ /* Disable AGP and PCI arbiters */
+ outb(3, 0x22);
}
switch (longhaul_version) {
@@ -244,7 +257,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
*/
case TYPE_LONGHAUL_V1:
case TYPE_LONGHAUL_V2:
- do_longhaul1(cx->address, clock_ratio_index);
+ do_longhaul1(clock_ratio_index);
break;
/*
@@ -259,14 +272,20 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
* to work in practice.
*/
case TYPE_POWERSAVER:
+ /* Don't allow wakeup */
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0,
+ ACPI_MTX_DO_NOT_LOCK);
do_powersaver(cx->address, clock_ratio_index);
break;
}
- /* Enable bus master arbitration */
- if (pr->flags.bm_check) {
+ if (pr->flags.bm_control) {
+ /* Enable bus master arbitration */
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,
ACPI_MTX_DO_NOT_LOCK);
+ } else if (port22_en) {
+ /* Enable arbiters */
+ outb(0, 0x22);
}
outb(pic2_mask,0xA1); /* restore mask */
@@ -446,53 +465,57 @@ static int __init longhaul_get_ranges(void)
static void __init longhaul_setup_voltagescaling(void)
{
union msr_longhaul longhaul;
+ struct mV_pos minvid, maxvid;
+ unsigned int j, speed, pos, kHz_step, numvscales;
- rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
-
- if (!(longhaul.bits.RevisionID & 1))
+ rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+ if (!(longhaul.bits.RevisionID & 1)) {
+ printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n");
return;
+ }
+
+ if (!longhaul.bits.VRMRev) {
+ printk (KERN_INFO PFX "VRM 8.5\n");
+ vrm_mV_table = &vrm85_mV[0];
+ mV_vrm_table = &mV_vrm85[0];
+ } else {
+ printk (KERN_INFO PFX "Mobile VRM\n");
+ vrm_mV_table = &mobilevrm_mV[0];
+ mV_vrm_table = &mV_mobilevrm[0];
+ }
- minvid = longhaul.bits.MinimumVID;
- maxvid = longhaul.bits.MaximumVID;
- vrmrev = longhaul.bits.VRMRev;
+ minvid = vrm_mV_table[longhaul.bits.MinimumVID];
+ maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
+ numvscales = maxvid.pos - minvid.pos + 1;
+ kHz_step = (highest_speed - lowest_speed) / numvscales;
- if (minvid == 0 || maxvid == 0) {
+ if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
"Voltage scaling disabled.\n",
- minvid/1000, minvid%1000, maxvid/1000, maxvid%1000);
+ minvid.mV/1000, minvid.mV%1000, maxvid.mV/1000, maxvid.mV%1000);
return;
}
- if (minvid == maxvid) {
+ if (minvid.mV == maxvid.mV) {
printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are "
"both %d.%03d. Voltage scaling disabled\n",
- maxvid/1000, maxvid%1000);
+ maxvid.mV/1000, maxvid.mV%1000);
return;
}
- if (vrmrev==0) {
- dprintk ("VRM 8.5\n");
- memcpy (voltage_table, vrm85scales, sizeof(voltage_table));
- numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25;
- } else {
- dprintk ("Mobile VRM\n");
- memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table));
- numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5;
+ printk(KERN_INFO PFX "Max VID=%d.%03d Min VID=%d.%03d, %d possible voltage scales\n",
+ maxvid.mV/1000, maxvid.mV%1000,
+ minvid.mV/1000, minvid.mV%1000,
+ numvscales);
+
+ j = 0;
+ while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
+ speed = longhaul_table[j].frequency;
+ pos = (speed - lowest_speed) / kHz_step + minvid.pos;
+ f_msr_table[longhaul_table[j].index].vrm = mV_vrm_table[pos];
+ j++;
}
- /* Current voltage isn't readable at first, so we need to
- set it to a known value. The spec says to use maxvid */
- longhaul.bits.RevisionKey = longhaul.bits.RevisionID; /* FIXME: This is bad. */
- longhaul.bits.EnableSoftVID = 1;
- longhaul.bits.SoftVID = maxvid;
- wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
-
- minvid = voltage_table[minvid];
- maxvid = voltage_table[maxvid];
-
- dprintk ("Min VID=%d.%03d Max VID=%d.%03d, %d possible voltage scales\n",
- maxvid/1000, maxvid%1000, minvid/1000, minvid%1000, numvscales);
-
can_scale_voltage = 1;
}
@@ -540,21 +563,33 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
return 1;
}
+/* VIA don't support PM2 reg, but have something similar */
+static int enable_arbiter_disable(void)
+{
+ struct pci_dev *dev;
+ u8 pci_cmd;
+
+ /* Find PLE133 host bridge */
+ dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL);
+ if (dev != NULL) {
+ /* Enable access to port 0x22 */
+ pci_read_config_byte(dev, 0x78, &pci_cmd);
+ if ( !(pci_cmd & 1<<7) ) {
+ pci_cmd |= 1<<7;
+ pci_write_config_byte(dev, 0x78, pci_cmd);
+ }
+ return 1;
+ }
+ return 0;
+}
+
static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *c = cpu_data;
char *cpuname=NULL;
int ret;
- /* Check ACPI support for C3 state */
- acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
- &longhaul_walk_callback, NULL, (void *)&pr);
- if (pr == NULL) goto err_acpi;
-
- cx = &pr->power.states[ACPI_STATE_C3];
- if (cx->address == 0 || cx->latency > 1000) goto err_acpi;
-
- /* Now check what we have on this motherboard */
+ /* Check what we have on this motherboard */
switch (c->x86_model) {
case 6:
cpu_model = CPU_SAMUEL;
@@ -636,12 +671,36 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
break;
};
+ /* Find ACPI data for processor */
+ acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ &longhaul_walk_callback, NULL, (void *)&pr);
+ if (pr == NULL)
+ goto err_acpi;
+
+ if (longhaul_version == TYPE_POWERSAVER) {
+ /* Check ACPI support for C3 state */
+ cx = &pr->power.states[ACPI_STATE_C3];
+ if (cx->address == 0 ||
+ (cx->latency > 1000 && ignore_latency == 0) )
+ goto err_acpi;
+
+ } else {
+ /* Check ACPI support for bus master arbiter disable */
+ if (!pr->flags.bm_control) {
+ if (!enable_arbiter_disable()) {
+ printk(KERN_ERR PFX "No ACPI support. No VT8601 host bridge. Aborting.\n");
+ return -ENODEV;
+ } else
+ port22_en = 1;
+ }
+ }
+
ret = longhaul_get_ranges();
if (ret != 0)
return ret;
if ((longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) &&
- (dont_scale_voltage==0))
+ (scale_voltage != 0))
longhaul_setup_voltagescaling();
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
@@ -729,8 +788,10 @@ static void __exit longhaul_exit(void)
kfree(longhaul_table);
}
-module_param (dont_scale_voltage, int, 0644);
-MODULE_PARM_DESC(dont_scale_voltage, "Don't scale voltage of processor");
+module_param (scale_voltage, int, 0644);
+MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
+module_param(ignore_latency, int, 0644);
+MODULE_PARM_DESC(ignore_latency, "Skip ACPI C3 latency test");
MODULE_AUTHOR ("Dave Jones ");
MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
@@ -738,4 +799,3 @@ MODULE_LICENSE ("GPL");
late_initcall(longhaul_init);
module_exit(longhaul_exit);
-
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.h b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.h
index d3a95d77ee85..bc4682aad69b 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.h
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.h
@@ -450,17 +450,45 @@ static int __initdata nehemiah_c_eblcr[32] = {
* Voltage scales. Div/Mod by 1000 to get actual voltage.
* Which scale to use depends on the VRM type in use.
*/
-static int __initdata vrm85scales[32] = {
- 1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700,
- 1650, 1600, 1550, 1500, 1450, 1400, 1350, 1300,
- 1275, 1225, 1175, 1125, 1075, 1825, 1775, 1725,
- 1675, 1625, 1575, 1525, 1475, 1425, 1375, 1325,
+
+struct mV_pos {
+ unsigned short mV;
+ unsigned short pos;
+};
+
+static struct mV_pos __initdata vrm85_mV[32] = {
+ {1250, 8}, {1200, 6}, {1150, 4}, {1100, 2},
+ {1050, 0}, {1800, 30}, {1750, 28}, {1700, 26},
+ {1650, 24}, {1600, 22}, {1550, 20}, {1500, 18},
+ {1450, 16}, {1400, 14}, {1350, 12}, {1300, 10},
+ {1275, 9}, {1225, 7}, {1175, 5}, {1125, 3},
+ {1075, 1}, {1825, 31}, {1775, 29}, {1725, 27},
+ {1675, 25}, {1625, 23}, {1575, 21}, {1525, 19},
+ {1475, 17}, {1425, 15}, {1375, 13}, {1325, 11}
+};
+
+static unsigned char __initdata mV_vrm85[32] = {
+ 0x04, 0x14, 0x03, 0x13, 0x02, 0x12, 0x01, 0x11,
+ 0x00, 0x10, 0x0f, 0x1f, 0x0e, 0x1e, 0x0d, 0x1d,
+ 0x0c, 0x1c, 0x0b, 0x1b, 0x0a, 0x1a, 0x09, 0x19,
+ 0x08, 0x18, 0x07, 0x17, 0x06, 0x16, 0x05, 0x15
+};
+
+static struct mV_pos __initdata mobilevrm_mV[32] = {
+ {1750, 31}, {1700, 30}, {1650, 29}, {1600, 28},
+ {1550, 27}, {1500, 26}, {1450, 25}, {1400, 24},
+ {1350, 23}, {1300, 22}, {1250, 21}, {1200, 20},
+ {1150, 19}, {1100, 18}, {1050, 17}, {1000, 16},
+ {975, 15}, {950, 14}, {925, 13}, {900, 12},
+ {875, 11}, {850, 10}, {825, 9}, {800, 8},
+ {775, 7}, {750, 6}, {725, 5}, {700, 4},
+ {675, 3}, {650, 2}, {625, 1}, {600, 0}
};
-static int __initdata mobilevrmscales[32] = {
- 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
- 1600, 1550, 1500, 1450, 1500, 1350, 1300, -1,
- 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
- 1075, 1050, 1025, 1000, 975, 950, 925, -1,
+static unsigned char __initdata mV_mobilevrm[32] = {
+ 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
+ 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
};
diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index b77f1358bd79..7a9325349e94 100644
--- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -23,6 +23,7 @@
#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
#include
+#include
#include
#endif
@@ -377,6 +378,35 @@ static int centrino_cpu_early_init_acpi(void)
return 0;
}
+
+/*
+ * Some BIOSes do SW_ANY coordination internally, either set it up in hw
+ * or do it in BIOS firmware and won't inform about it to OS. If not
+ * detected, this has a side effect of making CPU run at a different speed
+ * than OS intended it to run at. Detect it and handle it cleanly.
+ */
+static int bios_with_sw_any_bug;
+static int __init sw_any_bug_found(struct dmi_system_id *d)
+{
+ bios_with_sw_any_bug = 1;
+ return 0;
+}
+
+
+static struct dmi_system_id sw_any_bug_dmi_table[] = {
+ {
+ .callback = sw_any_bug_found,
+ .ident = "Supermicro Server X6DLP",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
+ DMI_MATCH(DMI_BIOS_VERSION, "080010"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
+ },
+ },
+ { }
+};
+
+
/*
* centrino_cpu_init_acpi - register with ACPI P-States library
*
@@ -398,14 +428,24 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
dprintk(PFX "obtaining ACPI data failed\n");
return -EIO;
}
+
policy->shared_type = p->shared_type;
/*
* Will let policy->cpus know about dependency only when software
* coordination is required.
*/
if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
- policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+ policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
policy->cpus = p->shared_cpu_map;
+ }
+
+#ifdef CONFIG_SMP
+ dmi_check_system(sw_any_bug_dmi_table);
+ if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+ policy->cpus = cpu_core_map[cpu];
+ }
+#endif
/* verify the acpi_data */
if (p->state_count <= 1) {
diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S
index 37a7d2eaf4a0..87f9f60b803b 100644
--- a/trunk/arch/i386/kernel/entry.S
+++ b/trunk/arch/i386/kernel/entry.S
@@ -209,6 +209,10 @@ ENTRY(ret_from_fork)
GET_THREAD_INFO(%ebp)
popl %eax
CFI_ADJUST_CFA_OFFSET -4
+ pushl $0x0202 # Reset kernel eflags
+ CFI_ADJUST_CFA_OFFSET 4
+ popfl
+ CFI_ADJUST_CFA_OFFSET -4
jmp syscall_exit
CFI_ENDPROC
diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c
index 345ffb7d904d..f1682206d304 100644
--- a/trunk/arch/i386/kernel/setup.c
+++ b/trunk/arch/i386/kernel/setup.c
@@ -956,6 +956,38 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
return 0;
}
+ /*
+ * This function checks if the entire range is mapped with type.
+ *
+ * Note: this function only works correct if the e820 table is sorted and
+ * not-overlapping, which is the case
+ */
+int __init
+e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
+{
+ u64 start = s;
+ u64 end = e;
+ int i;
+ for (i = 0; i < e820.nr_map; i++) {
+ struct e820entry *ei = &e820.map[i];
+ if (type && ei->type != type)
+ continue;
+ /* is the region (part) in overlap with the current region ?*/
+ if (ei->addr >= end || ei->addr + ei->size <= start)
+ continue;
+ /* if the region is at the beginning of we move
+ * start to the end of the region since it's ok until there
+ */
+ if (ei->addr <= start)
+ start = ei->addr + ei->size;
+ /* if start is now at or beyond end, we're done, full
+ * coverage */
+ if (start >= end)
+ return 1; /* we're done */
+ }
+ return 0;
+}
+
/*
* Find the highest page frame number we have available
*/
diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c
index f948419c888a..efe07990e7fc 100644
--- a/trunk/arch/i386/kernel/smpboot.c
+++ b/trunk/arch/i386/kernel/smpboot.c
@@ -642,9 +642,13 @@ static void map_cpu_to_logical_apicid(void)
{
int cpu = smp_processor_id();
int apicid = logical_smp_processor_id();
+ int node = apicid_to_node(apicid);
+
+ if (!node_online(node))
+ node = first_online_node;
cpu_2_logical_apicid[cpu] = apicid;
- map_cpu_to_node(cpu, apicid_to_node(apicid));
+ map_cpu_to_node(cpu, node);
}
static void unmap_cpu_to_logical_apicid(int cpu)
diff --git a/trunk/arch/i386/mm/boot_ioremap.c b/trunk/arch/i386/mm/boot_ioremap.c
index 5d44f4f5ff59..4de11f508c3a 100644
--- a/trunk/arch/i386/mm/boot_ioremap.c
+++ b/trunk/arch/i386/mm/boot_ioremap.c
@@ -29,8 +29,11 @@
*/
#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
-#define boot_pte_index(address) \
- (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
+
+static unsigned long boot_pte_index(unsigned long vaddr)
+{
+ return __pa(vaddr) >> PAGE_SHIFT;
+}
static inline boot_pte_t* boot_vaddr_to_pte(void *address)
{
diff --git a/trunk/arch/i386/oprofile/nmi_int.c b/trunk/arch/i386/oprofile/nmi_int.c
index c8c1df8ff2b4..5f8dc8a21bd7 100644
--- a/trunk/arch/i386/oprofile/nmi_int.c
+++ b/trunk/arch/i386/oprofile/nmi_int.c
@@ -337,6 +337,8 @@ static int __init ppro_init(char ** cpu_type)
if (cpu_model == 14)
*cpu_type = "i386/core";
+ else if (cpu_model == 15)
+ *cpu_type = "i386/core_2";
else if (cpu_model > 0xd)
return 0;
else if (cpu_model == 9) {
diff --git a/trunk/arch/i386/pci/common.c b/trunk/arch/i386/pci/common.c
index 1220dd828ce3..0a362e3aeac5 100644
--- a/trunk/arch/i386/pci/common.c
+++ b/trunk/arch/i386/pci/common.c
@@ -237,11 +237,6 @@ char * __devinit pcibios_setup(char *str)
pci_probe &= ~PCI_PROBE_MMCONF;
return NULL;
}
- /* override DMI blacklist */
- else if (!strcmp(str, "mmconf")) {
- pci_probe |= PCI_PROBE_MMCONF_FORCE;
- return NULL;
- }
#endif
else if (!strcmp(str, "noacpi")) {
acpi_noirq_set();
diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c
index ef5a2faa7d82..972180f738d9 100644
--- a/trunk/arch/i386/pci/mmconfig.c
+++ b/trunk/arch/i386/pci/mmconfig.c
@@ -12,7 +12,6 @@
#include
#include
#include
-#include
#include
#include "pci.h"
@@ -188,31 +187,9 @@ static __init void unreachable_devices(void)
}
}
-static int disable_mcfg(struct dmi_system_id *d)
-{
- printk("PCI: %s detected. Disabling MCFG.\n", d->ident);
- pci_probe &= ~PCI_PROBE_MMCONF;
- return 0;
-}
-
-static struct dmi_system_id __initdata dmi_bad_mcfg[] = {
- /* Has broken MCFG table that makes the system hang when used */
- {
- .callback = disable_mcfg,
- .ident = "Intel D3C5105 SDV",
- .matches = {
- DMI_MATCH(DMI_BIOS_VENDOR, "Intel"),
- DMI_MATCH(DMI_BOARD_NAME, "D26928"),
- },
- },
- {}
-};
-
void __init pci_mmcfg_init(void)
{
- dmi_check_system(dmi_bad_mcfg);
-
- if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0)
+ if ((pci_probe & PCI_PROBE_MMCONF) == 0)
return;
acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
@@ -221,6 +198,15 @@ void __init pci_mmcfg_init(void)
(pci_mmcfg_config[0].base_address == 0))
return;
+ if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
+ pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
+ E820_RESERVED)) {
+ printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
+ pci_mmcfg_config[0].base_address);
+ printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
+ return;
+ }
+
printk(KERN_INFO "PCI: Using MMCONFIG\n");
raw_pci_ops = &pci_mmcfg;
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
diff --git a/trunk/arch/i386/pci/pci.h b/trunk/arch/i386/pci/pci.h
index 49a849b3a241..bf4e79335388 100644
--- a/trunk/arch/i386/pci/pci.h
+++ b/trunk/arch/i386/pci/pci.h
@@ -16,8 +16,7 @@
#define PCI_PROBE_CONF1 0x0002
#define PCI_PROBE_CONF2 0x0004
#define PCI_PROBE_MMCONF 0x0008
-#define PCI_PROBE_MMCONF_FORCE 0x0010
-#define PCI_PROBE_MASK 0x00ff
+#define PCI_PROBE_MASK 0x000f
#define PCI_NO_SORT 0x0100
#define PCI_BIOS_SORT 0x0200
diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c
index 0176556aeecc..32c3abededc6 100644
--- a/trunk/arch/ia64/kernel/acpi.c
+++ b/trunk/arch/ia64/kernel/acpi.c
@@ -771,16 +771,19 @@ int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid)
{
#ifdef CONFIG_ACPI_NUMA
int pxm_id;
+ int nid;
pxm_id = acpi_get_pxm(handle);
-
/*
- * Assuming that the container driver would have set the proximity
- * domain and would have initialized pxm_to_node(pxm_id) && pxm_flag
+ * We don't have cpu-only-node hotadd. But if the system equips
+ * SRAT table, pxm is already found and node is ready.
+ * So, just pxm_to_nid(pxm) is OK.
+ * This code here is for the system which doesn't have full SRAT
+ * table for possible cpus.
*/
- node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_node(pxm_id);
-
+ nid = acpi_map_pxm_to_node(pxm_id);
node_cpuid[cpu].phys_id = physid;
+ node_cpuid[cpu].nid = nid;
#endif
return (0);
}
diff --git a/trunk/arch/ia64/kernel/numa.c b/trunk/arch/ia64/kernel/numa.c
index 1cc360c83e7a..20340631179f 100644
--- a/trunk/arch/ia64/kernel/numa.c
+++ b/trunk/arch/ia64/kernel/numa.c
@@ -29,6 +29,36 @@ EXPORT_SYMBOL(cpu_to_node_map);
cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+void __cpuinit map_cpu_to_node(int cpu, int nid)
+{
+ int oldnid;
+ if (nid < 0) { /* just initialize by zero */
+ cpu_to_node_map[cpu] = 0;
+ return;
+ }
+ /* sanity check first */
+ oldnid = cpu_to_node_map[cpu];
+ if (cpu_isset(cpu, node_to_cpu_mask[oldnid])) {
+ return; /* nothing to do */
+ }
+ /* we don't have cpu-driven node hot add yet...
+ In usual case, node is created from SRAT at boot time. */
+ if (!node_online(nid))
+ nid = first_online_node;
+ cpu_to_node_map[cpu] = nid;
+ cpu_set(cpu, node_to_cpu_mask[nid]);
+ return;
+}
+
+void __cpuinit unmap_cpu_from_node(int cpu, int nid)
+{
+ WARN_ON(!cpu_isset(cpu, node_to_cpu_mask[nid]));
+ WARN_ON(cpu_to_node_map[cpu] != nid);
+ cpu_to_node_map[cpu] = 0;
+ cpu_clear(cpu, node_to_cpu_mask[nid]);
+}
+
+
/**
* build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
*
@@ -49,8 +79,6 @@ void __init build_cpu_to_node_map(void)
node = node_cpuid[i].nid;
break;
}
- cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
- if (node >= 0)
- cpu_set(cpu, node_to_cpu_mask[node]);
+ map_cpu_to_node(cpu, node);
}
}
diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c
index f648c610b10c..05bdf7affb43 100644
--- a/trunk/arch/ia64/kernel/topology.c
+++ b/trunk/arch/ia64/kernel/topology.c
@@ -36,6 +36,9 @@ int arch_register_cpu(int num)
*/
if (!can_cpei_retarget() && is_cpu_cpei_target(num))
sysfs_cpus[num].cpu.no_control = 1;
+#ifdef CONFIG_NUMA
+ map_cpu_to_node(num, node_cpuid[num].nid);
+#endif
#endif
return register_cpu(&sysfs_cpus[num].cpu, num);
@@ -45,7 +48,8 @@ int arch_register_cpu(int num)
void arch_unregister_cpu(int num)
{
- return unregister_cpu(&sysfs_cpus[num].cpu);
+ unregister_cpu(&sysfs_cpus[num].cpu);
+ unmap_cpu_from_node(num, cpu_to_node(num));
}
EXPORT_SYMBOL(arch_register_cpu);
EXPORT_SYMBOL(arch_unregister_cpu);
diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile
index afc776f821e5..e73774136b55 100644
--- a/trunk/arch/powerpc/boot/Makefile
+++ b/trunk/arch/powerpc/boot/Makefile
@@ -36,7 +36,8 @@ zliblinuxheader := zlib.h zconf.h zutil.h
$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
-src-boot := crt0.S string.S prom.c stdio.c main.c div64.S
+src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c
+src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y)
src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
diff --git a/trunk/arch/powerpc/boot/flatdevtree.h b/trunk/arch/powerpc/boot/flatdevtree.h
new file mode 100644
index 000000000000..761c8dc84008
--- /dev/null
+++ b/trunk/arch/powerpc/boot/flatdevtree.h
@@ -0,0 +1,46 @@
+/*
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FLATDEVTREE_H
+#define FLATDEVTREE_H
+
+#include "types.h"
+
+/* Definitions used by the flattened device tree */
+#define OF_DT_HEADER 0xd00dfeed /* marker */
+#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
+#define OF_DT_END_NODE 0x2 /* End node */
+#define OF_DT_PROP 0x3 /* Property: name off, size, content */
+#define OF_DT_NOP 0x4 /* nop */
+#define OF_DT_END 0x9
+
+#define OF_DT_VERSION 0x10
+
+struct boot_param_header {
+ u32 magic; /* magic word OF_DT_HEADER */
+ u32 totalsize; /* total size of DT block */
+ u32 off_dt_struct; /* offset to structure */
+ u32 off_dt_strings; /* offset to strings */
+ u32 off_mem_rsvmap; /* offset to memory reserve map */
+ u32 version; /* format version */
+ u32 last_comp_version; /* last compatible version */
+ /* version 2 fields below */
+ u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
+ /* version 3 fields below */
+ u32 dt_strings_size; /* size of the DT strings block */
+};
+
+#endif /* FLATDEVTREE_H */
diff --git a/trunk/arch/powerpc/boot/main.c b/trunk/arch/powerpc/boot/main.c
index b66634c9ea34..d719bb9333d1 100644
--- a/trunk/arch/powerpc/boot/main.c
+++ b/trunk/arch/powerpc/boot/main.c
@@ -14,17 +14,12 @@
#include "page.h"
#include "string.h"
#include "stdio.h"
-#include "prom.h"
#include "zlib.h"
+#include "ops.h"
+#include "flatdevtree.h"
extern void flush_cache(void *, unsigned long);
-
-/* Value picked to match that used by yaboot */
-#define PROG_START 0x01400000 /* only used on 64-bit systems */
-#define RAM_END (512<<20) /* Fixme: use OF */
-#define ONE_MB 0x100000
-
extern char _start[];
extern char __bss_start[];
extern char _end[];
@@ -33,14 +28,6 @@ extern char _vmlinux_end[];
extern char _initrd_start[];
extern char _initrd_end[];
-/* A buffer that may be edited by tools operating on a zImage binary so as to
- * edit the command line passed to vmlinux (by setting /chosen/bootargs).
- * The buffer is put in it's own section so that tools may locate it easier.
- */
-static char builtin_cmdline[512]
- __attribute__((section("__builtin_cmdline")));
-
-
struct addr_range {
unsigned long addr;
unsigned long size;
@@ -51,21 +38,16 @@ static struct addr_range vmlinuz;
static struct addr_range initrd;
static unsigned long elfoffset;
+static int is_64bit;
-static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */
+/* scratch space for gunzip; 46912 is from zlib_inflate_workspacesize() */
+static char scratch[46912];
static char elfheader[256];
-
-typedef void (*kernel_entry_t)( unsigned long,
- unsigned long,
- void *,
- void *);
-
+typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *);
#undef DEBUG
-static unsigned long claim_base;
-
#define HEAD_CRC 2
#define EXTRA_FIELD 4
#define ORIG_NAME 8
@@ -123,24 +105,6 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
zlib_inflateEnd(&s);
}
-static unsigned long try_claim(unsigned long size)
-{
- unsigned long addr = 0;
-
- for(; claim_base < RAM_END; claim_base += ONE_MB) {
-#ifdef DEBUG
- printf(" trying: 0x%08lx\n\r", claim_base);
-#endif
- addr = (unsigned long)claim(claim_base, size, 0);
- if ((void *)addr != (void *)-1)
- break;
- }
- if (addr == 0)
- return 0;
- claim_base = PAGE_ALIGN(claim_base + size);
- return addr;
-}
-
static int is_elf64(void *hdr)
{
Elf64_Ehdr *elf64 = hdr;
@@ -169,16 +133,7 @@ static int is_elf64(void *hdr)
vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
-#if defined(PROG_START)
- /*
- * Maintain a "magic" minimum address. This keeps some older
- * firmware platforms running.
- */
-
- if (claim_base < PROG_START)
- claim_base = PROG_START;
-#endif
-
+ is_64bit = 1;
return 1;
}
@@ -212,47 +167,9 @@ static int is_elf32(void *hdr)
return 1;
}
-void export_cmdline(void* chosen_handle)
-{
- int len;
- char cmdline[2] = { 0, 0 };
-
- if (builtin_cmdline[0] == 0)
- return;
-
- len = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline));
- if (len > 0 && cmdline[0] != 0)
- return;
-
- setprop(chosen_handle, "bootargs", builtin_cmdline,
- strlen(builtin_cmdline) + 1);
-}
-
-
-void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
+static void prep_kernel(unsigned long *a1, unsigned long *a2)
{
int len;
- kernel_entry_t kernel_entry;
-
- memset(__bss_start, 0, _end - __bss_start);
-
- prom = (int (*)(void *)) promptr;
- chosen_handle = finddevice("/chosen");
- if (chosen_handle == (void *) -1)
- exit();
- if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
- exit();
-
- printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
-
- /*
- * The first available claim_base must be above the end of the
- * the loaded kernel wrapper file (_start to _end includes the
- * initrd image if it is present) and rounded up to a nice
- * 1 MB boundary for good measure.
- */
-
- claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
vmlinuz.addr = (unsigned long)_vmlinux_start;
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
@@ -263,43 +180,51 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
gunzip(elfheader, sizeof(elfheader),
(unsigned char *)vmlinuz.addr, &len);
} else
- memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
+ memcpy(elfheader, (const void *)vmlinuz.addr,
+ sizeof(elfheader));
if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
exit();
}
+ if (platform_ops.image_hdr)
+ platform_ops.image_hdr(elfheader);
- /* We need to claim the memsize plus the file offset since gzip
+ /* We need to alloc the memsize plus the file offset since gzip
* will expand the header (file offset), then the kernel, then
* possible rubbish we don't care about. But the kernel bss must
* be claimed (it will be zero'd by the kernel itself)
*/
printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
- vmlinux.addr = try_claim(vmlinux.memsize);
+ vmlinux.addr = (unsigned long)malloc(vmlinux.memsize);
if (vmlinux.addr == 0) {
printf("Can't allocate memory for kernel image !\n\r");
exit();
}
/*
- * Now we try to claim memory for the initrd (and copy it there)
+ * Now we try to alloc memory for the initrd (and copy it there)
*/
initrd.size = (unsigned long)(_initrd_end - _initrd_start);
initrd.memsize = initrd.size;
if ( initrd.size > 0 ) {
- printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size);
- initrd.addr = try_claim(initrd.size);
+ printf("Allocating 0x%lx bytes for initrd ...\n\r",
+ initrd.size);
+ initrd.addr = (unsigned long)malloc((u32)initrd.size);
if (initrd.addr == 0) {
- printf("Can't allocate memory for initial ramdisk !\n\r");
+ printf("Can't allocate memory for initial "
+ "ramdisk !\n\r");
exit();
}
- a1 = initrd.addr;
- a2 = initrd.size;
- printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r",
- initrd.addr, (unsigned long)_initrd_start, initrd.size);
- memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size);
- printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr));
+ *a1 = initrd.addr;
+ *a2 = initrd.size;
+ printf("initial ramdisk moving 0x%lx <- 0x%lx "
+ "(0x%lx bytes)\n\r", initrd.addr,
+ (unsigned long)_initrd_start, initrd.size);
+ memmove((void *)initrd.addr, (void *)_initrd_start,
+ initrd.size);
+ printf("initrd head: 0x%lx\n\r",
+ *((unsigned long *)initrd.addr));
}
/* Eventually gunzip the kernel */
@@ -311,11 +236,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
(unsigned char *)vmlinuz.addr, &len);
printf("done 0x%lx bytes\n\r", len);
} else {
- memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
+ memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,
+ vmlinuz.size);
}
- export_cmdline(chosen_handle);
-
/* Skip over the ELF header */
#ifdef DEBUG
printf("... skipping 0x%lx bytes of ELF header\n\r",
@@ -324,23 +248,107 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
vmlinux.addr += elfoffset;
flush_cache((void *)vmlinux.addr, vmlinux.size);
+}
- kernel_entry = (kernel_entry_t)vmlinux.addr;
-#ifdef DEBUG
- printf( "kernel:\n\r"
- " entry addr = 0x%lx\n\r"
- " a1 = 0x%lx,\n\r"
- " a2 = 0x%lx,\n\r"
- " prom = 0x%lx,\n\r"
- " bi_recs = 0x%lx,\n\r",
- (unsigned long)kernel_entry, a1, a2,
- (unsigned long)prom, NULL);
-#endif
+void __attribute__ ((weak)) ft_init(void *dt_blob)
+{
+}
- kernel_entry(a1, a2, prom, NULL);
+/* A buffer that may be edited by tools operating on a zImage binary so as to
+ * edit the command line passed to vmlinux (by setting /chosen/bootargs).
+ * The buffer is put in it's own section so that tools may locate it easier.
+ */
+static char builtin_cmdline[COMMAND_LINE_SIZE]
+ __attribute__((__section__("__builtin_cmdline")));
- printf("Error: Linux kernel returned to zImage bootloader!\n\r");
+static void get_cmdline(char *buf, int size)
+{
+ void *devp;
+ int len = strlen(builtin_cmdline);
- exit();
+ buf[0] = '\0';
+
+ if (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */
+ len = min(len, size-1);
+ strncpy(buf, builtin_cmdline, len);
+ buf[len] = '\0';
+ }
+ else if ((devp = finddevice("/chosen")))
+ getprop(devp, "bootargs", buf, size);
+}
+
+static void set_cmdline(char *buf)
+{
+ void *devp;
+
+ if ((devp = finddevice("/chosen")))
+ setprop(devp, "bootargs", buf, strlen(buf) + 1);
}
+/* Section where ft can be tacked on after zImage is built */
+union blobspace {
+ struct boot_param_header hdr;
+ char space[8*1024];
+} dt_blob __attribute__((__section__("__builtin_ft")));
+
+struct platform_ops platform_ops;
+struct dt_ops dt_ops;
+struct console_ops console_ops;
+
+void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
+{
+ int have_dt = 0;
+ kernel_entry_t kentry;
+ char cmdline[COMMAND_LINE_SIZE];
+
+ memset(__bss_start, 0, _end - __bss_start);
+ memset(&platform_ops, 0, sizeof(platform_ops));
+ memset(&dt_ops, 0, sizeof(dt_ops));
+ memset(&console_ops, 0, sizeof(console_ops));
+
+ /* Override the dt_ops and device tree if there was an flat dev
+ * tree attached to the zImage.
+ */
+ if (dt_blob.hdr.magic == OF_DT_HEADER) {
+ have_dt = 1;
+ ft_init(&dt_blob);
+ }
+
+ if (platform_init(promptr))
+ exit();
+ if (console_ops.open && (console_ops.open() < 0))
+ exit();
+ if (platform_ops.fixups)
+ platform_ops.fixups();
+
+ printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
+ _start, sp);
+
+ prep_kernel(&a1, &a2);
+
+ /* If cmdline came from zimage wrapper or if we can edit the one
+ * in the dt, print it out and edit it, if possible.
+ */
+ if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) {
+ get_cmdline(cmdline, COMMAND_LINE_SIZE);
+ printf("\n\rLinux/PowerPC load: %s", cmdline);
+ if (console_ops.edit_cmdline)
+ console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
+ printf("\n\r");
+ set_cmdline(cmdline);
+ }
+
+ if (console_ops.close)
+ console_ops.close();
+
+ kentry = (kernel_entry_t) vmlinux.addr;
+ if (have_dt)
+ kentry(dt_ops.ft_addr(), 0, NULL);
+ else
+ /* XXX initrd addr/size should be passed in properties */
+ kentry(a1, a2, promptr);
+
+ /* console closed so printf below may not work */
+ printf("Error: Linux kernel returned to zImage boot wrapper!\n\r");
+ exit();
+}
diff --git a/trunk/arch/powerpc/boot/prom.c b/trunk/arch/powerpc/boot/of.c
similarity index 54%
rename from trunk/arch/powerpc/boot/prom.c
rename to trunk/arch/powerpc/boot/of.c
index fa0057736f6b..fd99f789a37b 100644
--- a/trunk/arch/powerpc/boot/prom.c
+++ b/trunk/arch/powerpc/boot/of.c
@@ -8,15 +8,29 @@
*/
#include
#include
+#include "types.h"
+#include "elf.h"
#include "string.h"
#include "stdio.h"
-#include "prom.h"
+#include "page.h"
+#include "ops.h"
-int (*prom)(void *);
-phandle chosen_handle;
-ihandle stdout;
+typedef void *ihandle;
+typedef void *phandle;
-int call_prom(const char *service, int nargs, int nret, ...)
+extern char _end[];
+
+/* Value picked to match that used by yaboot */
+#define PROG_START 0x01400000 /* only used on 64-bit systems */
+#define RAM_END (512<<20) /* Fixme: use OF */
+#define ONE_MB 0x100000
+
+int (*prom) (void *);
+
+
+static unsigned long claim_base;
+
+static int call_prom(const char *service, int nargs, int nret, ...)
{
int i;
struct prom_args {
@@ -45,7 +59,7 @@ int call_prom(const char *service, int nargs, int nret, ...)
return (nret > 0)? args.args[nargs]: 0;
}
-int call_prom_ret(const char *service, int nargs, int nret,
+static int call_prom_ret(const char *service, int nargs, int nret,
unsigned int *rets, ...)
{
int i;
@@ -79,11 +93,6 @@ int call_prom_ret(const char *service, int nargs, int nret,
return (nret > 0)? args.args[nargs]: 0;
}
-int write(void *handle, void *ptr, int nb)
-{
- return call_prom("write", 3, 1, handle, ptr, nb);
-}
-
/*
* Older OF's require that when claiming a specific range of addresses,
* we claim the physical space in the /memory node and the virtual
@@ -142,7 +151,7 @@ static int check_of_version(void)
return 1;
}
-void *claim(unsigned long virt, unsigned long size, unsigned long align)
+static void *claim(unsigned long virt, unsigned long size, unsigned long align)
{
int ret;
unsigned int result;
@@ -151,7 +160,7 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align)
need_map = check_of_version();
if (align || !need_map)
return (void *) call_prom("claim", 3, 1, virt, size, align);
-
+
ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
align, size, virt);
if (ret != 0 || result == -1)
@@ -163,3 +172,112 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align)
0x12, size, virt, virt);
return (void *) virt;
}
+
+static void *of_try_claim(u32 size)
+{
+ unsigned long addr = 0;
+ static u8 first_time = 1;
+
+ if (first_time) {
+ claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
+ first_time = 0;
+ }
+
+ for(; claim_base < RAM_END; claim_base += ONE_MB) {
+#ifdef DEBUG
+ printf(" trying: 0x%08lx\n\r", claim_base);
+#endif
+ addr = (unsigned long)claim(claim_base, size, 0);
+ if ((void *)addr != (void *)-1)
+ break;
+ }
+ if (addr == 0)
+ return NULL;
+ claim_base = PAGE_ALIGN(claim_base + size);
+ return (void *)addr;
+}
+
+static void of_image_hdr(const void *hdr)
+{
+ const Elf64_Ehdr *elf64 = hdr;
+
+ if (elf64->e_ident[EI_CLASS] == ELFCLASS64) {
+ /*
+ * Maintain a "magic" minimum address. This keeps some older
+ * firmware platforms running.
+ */
+ if (claim_base < PROG_START)
+ claim_base = PROG_START;
+ }
+}
+
+static void of_exit(void)
+{
+ call_prom("exit", 0, 0);
+}
+
+/*
+ * OF device tree routines
+ */
+static void *of_finddevice(const char *name)
+{
+ return (phandle) call_prom("finddevice", 1, 1, name);
+}
+
+static int of_getprop(const void *phandle, const char *name, void *buf,
+ const int buflen)
+{
+ return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
+}
+
+static int of_setprop(const void *phandle, const char *name, const void *buf,
+ const int buflen)
+{
+ return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
+}
+
+/*
+ * OF console routines
+ */
+static void *of_stdout_handle;
+
+static int of_console_open(void)
+{
+ void *devp;
+
+ if (((devp = finddevice("/chosen")) != NULL)
+ && (getprop(devp, "stdout", &of_stdout_handle,
+ sizeof(of_stdout_handle))
+ == sizeof(of_stdout_handle)))
+ return 0;
+
+ return -1;
+}
+
+static void of_console_write(char *buf, int len)
+{
+ call_prom("write", 3, 1, of_stdout_handle, buf, len);
+}
+
+int platform_init(void *promptr)
+{
+ platform_ops.fixups = NULL;
+ platform_ops.image_hdr = of_image_hdr;
+ platform_ops.malloc = of_try_claim;
+ platform_ops.free = NULL;
+ platform_ops.exit = of_exit;
+
+ dt_ops.finddevice = of_finddevice;
+ dt_ops.getprop = of_getprop;
+ dt_ops.setprop = of_setprop;
+ dt_ops.translate_addr = NULL;
+
+ console_ops.open = of_console_open;
+ console_ops.write = of_console_write;
+ console_ops.edit_cmdline = NULL;
+ console_ops.close = NULL;
+ console_ops.data = NULL;
+
+ prom = (int (*)(void *))promptr;
+ return 0;
+}
diff --git a/trunk/arch/powerpc/boot/ops.h b/trunk/arch/powerpc/boot/ops.h
new file mode 100644
index 000000000000..135eb4bb03b4
--- /dev/null
+++ b/trunk/arch/powerpc/boot/ops.h
@@ -0,0 +1,100 @@
+/*
+ * Global definition of all the bootwrapper operations.
+ *
+ * Author: Mark A. Greer
+ *
+ * 2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef _PPC_BOOT_OPS_H_
+#define _PPC_BOOT_OPS_H_
+
+#include "types.h"
+
+#define COMMAND_LINE_SIZE 512
+#define MAX_PATH_LEN 256
+#define MAX_PROP_LEN 256 /* What should this be? */
+
+/* Platform specific operations */
+struct platform_ops {
+ void (*fixups)(void);
+ void (*image_hdr)(const void *);
+ void * (*malloc)(u32 size);
+ void (*free)(void *ptr, u32 size);
+ void (*exit)(void);
+};
+extern struct platform_ops platform_ops;
+
+/* Device Tree operations */
+struct dt_ops {
+ void * (*finddevice)(const char *name);
+ int (*getprop)(const void *node, const char *name, void *buf,
+ const int buflen);
+ int (*setprop)(const void *node, const char *name,
+ const void *buf, const int buflen);
+ u64 (*translate_addr)(const char *path, const u32 *in_addr,
+ const u32 addr_len);
+ unsigned long (*ft_addr)(void);
+};
+extern struct dt_ops dt_ops;
+
+/* Console operations */
+struct console_ops {
+ int (*open)(void);
+ void (*write)(char *buf, int len);
+ void (*edit_cmdline)(char *buf, int len);
+ void (*close)(void);
+ void *data;
+};
+extern struct console_ops console_ops;
+
+/* Serial console operations */
+struct serial_console_data {
+ int (*open)(void);
+ void (*putc)(unsigned char c);
+ unsigned char (*getc)(void);
+ u8 (*tstc)(void);
+ void (*close)(void);
+};
+
+extern int platform_init(void *promptr);
+extern void simple_alloc_init(void);
+extern void ft_init(void *dt_blob);
+extern int serial_console_init(void);
+
+static inline void *finddevice(const char *name)
+{
+ return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL;
+}
+
+static inline int getprop(void *devp, const char *name, void *buf, int buflen)
+{
+ return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1;
+}
+
+static inline int setprop(void *devp, const char *name, void *buf, int buflen)
+{
+ return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1;
+}
+
+static inline void *malloc(u32 size)
+{
+ return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
+}
+
+static inline void free(void *ptr, u32 size)
+{
+ if (platform_ops.free)
+ platform_ops.free(ptr, size);
+}
+
+static inline void exit(void)
+{
+ if (platform_ops.exit)
+ platform_ops.exit();
+ for(;;);
+}
+
+#endif /* _PPC_BOOT_OPS_H_ */
diff --git a/trunk/arch/powerpc/boot/prom.h b/trunk/arch/powerpc/boot/prom.h
deleted file mode 100644
index a57b184c564f..000000000000
--- a/trunk/arch/powerpc/boot/prom.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _PPC_BOOT_PROM_H_
-#define _PPC_BOOT_PROM_H_
-
-typedef void *phandle;
-typedef void *ihandle;
-
-extern int (*prom) (void *);
-extern phandle chosen_handle;
-extern ihandle stdout;
-
-int call_prom(const char *service, int nargs, int nret, ...);
-int call_prom_ret(const char *service, int nargs, int nret,
- unsigned int *rets, ...);
-
-extern int write(void *handle, void *ptr, int nb);
-extern void *claim(unsigned long virt, unsigned long size, unsigned long aln);
-
-static inline void exit(void)
-{
- call_prom("exit", 0, 0);
-}
-
-static inline phandle finddevice(const char *name)
-{
- return (phandle) call_prom("finddevice", 1, 1, name);
-}
-
-static inline int getprop(void *phandle, const char *name,
- void *buf, int buflen)
-{
- return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
-}
-
-
-static inline int setprop(void *phandle, const char *name,
- void *buf, int buflen)
-{
- return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
-}
-
-#endif /* _PPC_BOOT_PROM_H_ */
diff --git a/trunk/arch/powerpc/boot/stdio.c b/trunk/arch/powerpc/boot/stdio.c
index b5aa522f8b77..6d5f6382e1ce 100644
--- a/trunk/arch/powerpc/boot/stdio.c
+++ b/trunk/arch/powerpc/boot/stdio.c
@@ -10,7 +10,7 @@
#include
#include "string.h"
#include "stdio.h"
-#include "prom.h"
+#include "ops.h"
size_t strnlen(const char * s, size_t count)
{
@@ -320,6 +320,6 @@ printf(const char *fmt, ...)
va_start(args, fmt);
n = vsprintf(sprint_buf, fmt, args);
va_end(args);
- write(stdout, sprint_buf, n);
+ console_ops.write(sprint_buf, n);
return n;
}
diff --git a/trunk/arch/powerpc/boot/stdio.h b/trunk/arch/powerpc/boot/stdio.h
index eb9e16c87aef..73b8a91bfb34 100644
--- a/trunk/arch/powerpc/boot/stdio.h
+++ b/trunk/arch/powerpc/boot/stdio.h
@@ -1,8 +1,16 @@
#ifndef _PPC_BOOT_STDIO_H_
#define _PPC_BOOT_STDIO_H_
+#include
+
+#define ENOMEM 12 /* Out of Memory */
+#define EINVAL 22 /* Invalid argument */
+#define ENOSPC 28 /* No space left on device */
+
extern int printf(const char *fmt, ...);
+#define fprintf(fmt, args...) printf(args)
+
extern int sprintf(char *buf, const char *fmt, ...);
extern int vsprintf(char *buf, const char *fmt, va_list args);
diff --git a/trunk/arch/powerpc/boot/types.h b/trunk/arch/powerpc/boot/types.h
new file mode 100644
index 000000000000..79d26e708677
--- /dev/null
+++ b/trunk/arch/powerpc/boot/types.h
@@ -0,0 +1,23 @@
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+
+#define min(x,y) ({ \
+ typeof(x) _x = (x); \
+ typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x < _y ? _x : _y; })
+
+#define max(x,y) ({ \
+ typeof(x) _x = (x); \
+ typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x > _y ? _x : _y; })
+
+#endif /* _TYPES_H_ */
diff --git a/trunk/arch/powerpc/configs/chrp32_defconfig b/trunk/arch/powerpc/configs/chrp32_defconfig
index bbf2b5f8a8cb..fee72f8a2fb7 100644
--- a/trunk/arch/powerpc/configs/chrp32_defconfig
+++ b/trunk/arch/powerpc/configs/chrp32_defconfig
@@ -492,7 +492,7 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
diff --git a/trunk/arch/powerpc/configs/g5_defconfig b/trunk/arch/powerpc/configs/g5_defconfig
index 4b9c2ed925f5..92d0a9dd0b8f 100644
--- a/trunk/arch/powerpc/configs/g5_defconfig
+++ b/trunk/arch/powerpc/configs/g5_defconfig
@@ -490,23 +490,23 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-CONFIG_SCSI_SATA_SVW=y
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SVW=y
# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
# CONFIG_SCSI_PDC_ADMA is not set
# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
diff --git a/trunk/arch/powerpc/configs/iseries_defconfig b/trunk/arch/powerpc/configs/iseries_defconfig
index eb0885ea0731..d58f82f836f8 100644
--- a/trunk/arch/powerpc/configs/iseries_defconfig
+++ b/trunk/arch/powerpc/configs/iseries_defconfig
@@ -475,7 +475,7 @@ CONFIG_SCSI_FC_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
diff --git a/trunk/arch/powerpc/configs/mpc7448_hpc2_defconfig b/trunk/arch/powerpc/configs/mpc7448_hpc2_defconfig
index 719fba4eb421..d1811e754518 100644
--- a/trunk/arch/powerpc/configs/mpc7448_hpc2_defconfig
+++ b/trunk/arch/powerpc/configs/mpc7448_hpc2_defconfig
@@ -413,23 +413,23 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
# CONFIG_SCSI_ATA_PIIX is not set
-CONFIG_SCSI_SATA_MV=y
-# CONFIG_SCSI_SATA_NV is not set
+CONFIG_SATA_MV=y
+# CONFIG_SATA_NV is not set
# CONFIG_SCSI_PDC_ADMA is not set
# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
diff --git a/trunk/arch/powerpc/configs/mpc834x_itx_defconfig b/trunk/arch/powerpc/configs/mpc834x_itx_defconfig
index 8da6a47f0339..cd3535e1a095 100644
--- a/trunk/arch/powerpc/configs/mpc834x_itx_defconfig
+++ b/trunk/arch/powerpc/configs/mpc834x_itx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc6
-# Sun Sep 10 10:28:05 2006
+# Linux kernel version: 2.6.18
+# Mon Sep 25 19:41:14 2006
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -21,6 +21,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_PPC_OF=y
CONFIG_PPC_UDBG_16550=y
# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
CONFIG_DEFAULT_UIMAGE=y
#
@@ -61,25 +62,25 @@ CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EMBEDDED=y
+CONFIG_SYSCTL=y
# CONFIG_KALLSYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -259,7 +260,6 @@ CONFIG_TCP_CONG_BIC=y
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -313,6 +313,7 @@ CONFIG_MTD_CHAR=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
@@ -464,23 +465,23 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
# CONFIG_SCSI_PDC_ADMA is not set
# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-CONFIG_SCSI_SATA_SIL=y
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
@@ -1277,11 +1278,11 @@ CONFIG_PLIST=y
#
# Kernel hacking
#
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=17
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
@@ -1293,15 +1294,15 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_DEBUGGER is not set
# CONFIG_BDI_SWITCH is not set
-CONFIG_BOOTX_TEXT=y
-CONFIG_SERIAL_TEXT_DEBUG=y
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
# CONFIG_PPC_EARLY_DEBUG is not set
#
@@ -1314,6 +1315,8 @@ CONFIG_SERIAL_TEXT_DEBUG=y
# Cryptographic options
#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
@@ -1323,6 +1326,8 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_CBC is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
diff --git a/trunk/arch/powerpc/configs/pmac32_defconfig b/trunk/arch/powerpc/configs/pmac32_defconfig
index 6861dde7d77b..765c8bb90ddd 100644
--- a/trunk/arch/powerpc/configs/pmac32_defconfig
+++ b/trunk/arch/powerpc/configs/pmac32_defconfig
@@ -682,7 +682,7 @@ CONFIG_SCSI_AIC7XXX_OLD=m
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
@@ -1826,7 +1826,7 @@ CONFIG_OPROFILE=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
diff --git a/trunk/arch/powerpc/configs/ppc64_defconfig b/trunk/arch/powerpc/configs/ppc64_defconfig
index 7517d0c5303f..be11df7c11aa 100644
--- a/trunk/arch/powerpc/configs/ppc64_defconfig
+++ b/trunk/arch/powerpc/configs/ppc64_defconfig
@@ -520,23 +520,23 @@ CONFIG_SCSI_ISCSI_ATTRS=m
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-CONFIG_SCSI_SATA_SVW=y
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SVW=y
# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
# CONFIG_SCSI_PDC_ADMA is not set
# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
diff --git a/trunk/arch/powerpc/configs/pseries_defconfig b/trunk/arch/powerpc/configs/pseries_defconfig
index a8cdf312e1b0..44175fb7adec 100644
--- a/trunk/arch/powerpc/configs/pseries_defconfig
+++ b/trunk/arch/powerpc/configs/pseries_defconfig
@@ -506,7 +506,7 @@ CONFIG_SCSI_SAS_ATTRS=m
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_ATA is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile
index 8b3f4faf5768..8b133afbdc20 100644
--- a/trunk/arch/powerpc/kernel/Makefile
+++ b/trunk/arch/powerpc/kernel/Makefile
@@ -51,7 +51,7 @@ extra-$(CONFIG_8xx) := head_8xx.o
extra-y += vmlinux.lds
obj-y += time.o prom.o traps.o setup-common.o \
- udbg.o misc.o
+ udbg.o misc.o io.o
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o
obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c
index db65c9f6559a..190a57e20765 100644
--- a/trunk/arch/powerpc/kernel/cputable.c
+++ b/trunk/arch/powerpc/kernel/cputable.c
@@ -949,6 +949,7 @@ struct cpu_spec cpu_specs[] = {
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
.icache_bsize = 32,
.dcache_bsize = 32,
+ .platform = "ppc405",
},
{ /* 405EP */
.pvr_mask = 0xffff0000,
diff --git a/trunk/arch/powerpc/kernel/io.c b/trunk/arch/powerpc/kernel/io.c
new file mode 100644
index 000000000000..e98180686b35
--- /dev/null
+++ b/trunk/arch/powerpc/kernel/io.c
@@ -0,0 +1,131 @@
+/*
+ * I/O string operations
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ * Copyright (C) 2006 IBM Corporation
+ *
+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras.
+ *
+ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
+ *
+ * Rewritten in C by Stephen Rothwell.
+ *
+ * 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; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+void _insb(volatile u8 __iomem *port, void *buf, long count)
+{
+ u8 *tbuf = buf;
+ u8 tmp;
+
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ if (unlikely(count <= 0))
+ return;
+ asm volatile("sync");
+ do {
+ tmp = *port;
+ asm volatile("eieio");
+ *tbuf++ = tmp;
+ } while (--count != 0);
+ asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
+}
+EXPORT_SYMBOL(_insb);
+
+void _outsb(volatile u8 __iomem *port, const void *buf, long count)
+{
+ const u8 *tbuf = buf;
+
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ if (unlikely(count <= 0))
+ return;
+ asm volatile("sync");
+ do {
+ *port = *tbuf++;
+ } while (--count != 0);
+ asm volatile("sync");
+}
+EXPORT_SYMBOL(_outsb);
+
+void _insw_ns(volatile u16 __iomem *port, void *buf, long count)
+{
+ u16 *tbuf = buf;
+ u16 tmp;
+
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ if (unlikely(count <= 0))
+ return;
+ asm volatile("sync");
+ do {
+ tmp = *port;
+ asm volatile("eieio");
+ *tbuf++ = tmp;
+ } while (--count != 0);
+ asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
+}
+EXPORT_SYMBOL(_insw_ns);
+
+void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
+{
+ const u16 *tbuf = buf;
+
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ if (unlikely(count <= 0))
+ return;
+ asm volatile("sync");
+ do {
+ *port = *tbuf++;
+ } while (--count != 0);
+ asm volatile("sync");
+}
+EXPORT_SYMBOL(_outsw_ns);
+
+void _insl_ns(volatile u32 __iomem *port, void *buf, long count)
+{
+ u32 *tbuf = buf;
+ u32 tmp;
+
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ if (unlikely(count <= 0))
+ return;
+ asm volatile("sync");
+ do {
+ tmp = *port;
+ asm volatile("eieio");
+ *tbuf++ = tmp;
+ } while (--count != 0);
+ asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
+}
+EXPORT_SYMBOL(_insl_ns);
+
+void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
+{
+ const u32 *tbuf = buf;
+
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ if (unlikely(count <= 0))
+ return;
+ asm volatile("sync");
+ do {
+ *port = *tbuf++;
+ } while (--count != 0);
+ asm volatile("sync");
+}
+EXPORT_SYMBOL(_outsl_ns);
diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c
index b4432332341f..c3f58f2f9f52 100644
--- a/trunk/arch/powerpc/kernel/irq.c
+++ b/trunk/arch/powerpc/kernel/irq.c
@@ -777,7 +777,6 @@ unsigned int irq_alloc_virt(struct irq_host *host,
{
unsigned long flags;
unsigned int i, j, found = NO_IRQ;
- unsigned int limit = irq_virq_count - count;
if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
return NO_IRQ;
@@ -794,14 +793,16 @@ unsigned int irq_alloc_virt(struct irq_host *host,
/* Look for count consecutive numbers in the allocatable
* (non-legacy) space
*/
- for (i = NUM_ISA_INTERRUPTS; i <= limit; ) {
- for (j = i; j < (i + count); j++)
- if (irq_map[j].host != NULL) {
- i = j + 1;
- continue;
- }
- found = i;
- break;
+ for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
+ if (irq_map[i].host != NULL)
+ j = 0;
+ else
+ j++;
+
+ if (j == count) {
+ found = i - count + 1;
+ break;
+ }
}
if (found == NO_IRQ) {
spin_unlock_irqrestore(&irq_big_lock, flags);
diff --git a/trunk/arch/powerpc/kernel/misc.S b/trunk/arch/powerpc/kernel/misc.S
index f770805f1215..330c9dc7db86 100644
--- a/trunk/arch/powerpc/kernel/misc.S
+++ b/trunk/arch/powerpc/kernel/misc.S
@@ -43,162 +43,3 @@ _GLOBAL(add_reloc_offset)
add r3,r3,r5
mtlr r0
blr
-
-/*
- * I/O string operations
- *
- * insb(port, buf, len)
- * outsb(port, buf, len)
- * insw(port, buf, len)
- * outsw(port, buf, len)
- * insl(port, buf, len)
- * outsl(port, buf, len)
- * insw_ns(port, buf, len)
- * outsw_ns(port, buf, len)
- * insl_ns(port, buf, len)
- * outsl_ns(port, buf, len)
- *
- * The *_ns versions don't do byte-swapping.
- */
-_GLOBAL(_insb)
- sync
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,1
- blelr-
-00: lbz r5,0(r3)
- eieio
- stbu r5,1(r4)
- bdnz 00b
- twi 0,r5,0
- isync
- blr
-
-_GLOBAL(_outsb)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,1
- blelr-
- sync
-00: lbzu r5,1(r4)
- stb r5,0(r3)
- bdnz 00b
- sync
- blr
-
-_GLOBAL(_insw)
- sync
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,2
- blelr-
-00: lhbrx r5,0,r3
- eieio
- sthu r5,2(r4)
- bdnz 00b
- twi 0,r5,0
- isync
- blr
-
-_GLOBAL(_outsw)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,2
- blelr-
- sync
-00: lhzu r5,2(r4)
- sthbrx r5,0,r3
- bdnz 00b
- sync
- blr
-
-_GLOBAL(_insl)
- sync
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,4
- blelr-
-00: lwbrx r5,0,r3
- eieio
- stwu r5,4(r4)
- bdnz 00b
- twi 0,r5,0
- isync
- blr
-
-_GLOBAL(_outsl)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,4
- blelr-
- sync
-00: lwzu r5,4(r4)
- stwbrx r5,0,r3
- bdnz 00b
- sync
- blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_insw)
-#endif
-_GLOBAL(_insw_ns)
- sync
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,2
- blelr-
-00: lhz r5,0(r3)
- eieio
- sthu r5,2(r4)
- bdnz 00b
- twi 0,r5,0
- isync
- blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_outsw)
-#endif
-_GLOBAL(_outsw_ns)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,2
- blelr-
- sync
-00: lhzu r5,2(r4)
- sth r5,0(r3)
- bdnz 00b
- sync
- blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_insl)
-#endif
-_GLOBAL(_insl_ns)
- sync
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,4
- blelr-
-00: lwz r5,0(r3)
- eieio
- stwu r5,4(r4)
- bdnz 00b
- twi 0,r5,0
- isync
- blr
-
-#ifdef CONFIG_PPC32
-_GLOBAL(__ide_mm_outsl)
-#endif
-_GLOBAL(_outsl_ns)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,4
- blelr-
- sync
-00: lwzu r5,4(r4)
- stw r5,0(r3)
- bdnz 00b
- sync
- blr
-
diff --git a/trunk/arch/powerpc/kernel/ppc_ksyms.c b/trunk/arch/powerpc/kernel/ppc_ksyms.c
index b2edac8ddf0a..807193a3c784 100644
--- a/trunk/arch/powerpc/kernel/ppc_ksyms.c
+++ b/trunk/arch/powerpc/kernel/ppc_ksyms.c
@@ -95,24 +95,6 @@ EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(copy_4K_page);
#endif
-#ifndef __powerpc64__
-EXPORT_SYMBOL(__ide_mm_insl);
-EXPORT_SYMBOL(__ide_mm_outsw);
-EXPORT_SYMBOL(__ide_mm_insw);
-EXPORT_SYMBOL(__ide_mm_outsl);
-#endif
-
-EXPORT_SYMBOL(_insb);
-EXPORT_SYMBOL(_outsb);
-EXPORT_SYMBOL(_insw);
-EXPORT_SYMBOL(_outsw);
-EXPORT_SYMBOL(_insl);
-EXPORT_SYMBOL(_outsl);
-EXPORT_SYMBOL(_insw_ns);
-EXPORT_SYMBOL(_outsw_ns);
-EXPORT_SYMBOL(_insl_ns);
-EXPORT_SYMBOL(_outsl_ns);
-
#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
EXPORT_SYMBOL(ppc_ide_md);
#endif
diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c
index bf2005b2feb6..eb913f80bfb1 100644
--- a/trunk/arch/powerpc/kernel/prom.c
+++ b/trunk/arch/powerpc/kernel/prom.c
@@ -757,24 +757,9 @@ static int __init early_init_dt_scan_root(unsigned long node,
static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
{
cell_t *p = *cellp;
- unsigned long r;
- /* Ignore more than 2 cells */
- while (s > sizeof(unsigned long) / 4) {
- p++;
- s--;
- }
- r = *p++;
-#ifdef CONFIG_PPC64
- if (s > 1) {
- r <<= 32;
- r |= *(p++);
- s--;
- }
-#endif
-
- *cellp = p;
- return r;
+ *cellp = p + s;
+ return of_read_ulong(p, s);
}
diff --git a/trunk/arch/powerpc/kernel/ptrace.c b/trunk/arch/powerpc/kernel/ptrace.c
index dea75d73f983..975102a020d9 100644
--- a/trunk/arch/powerpc/kernel/ptrace.c
+++ b/trunk/arch/powerpc/kernel/ptrace.c
@@ -526,9 +526,7 @@ static void do_syscall_trace(void)
void do_syscall_trace_enter(struct pt_regs *regs)
{
-#ifdef CONFIG_PPC64
secure_computing(regs->gpr[0]);
-#endif
if (test_thread_flag(TIF_SYSCALL_TRACE)
&& (current->ptrace & PT_PTRACED))
@@ -548,12 +546,8 @@ void do_syscall_trace_enter(struct pt_regs *regs)
void do_syscall_trace_leave(struct pt_regs *regs)
{
-#ifdef CONFIG_PPC32
- secure_computing(regs->gpr[0]);
-#endif
-
if (unlikely(current->audit_context))
- audit_syscall_exit((regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+ audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
regs->result);
if ((test_thread_flag(TIF_SYSCALL_TRACE)
@@ -561,8 +555,3 @@ void do_syscall_trace_leave(struct pt_regs *regs)
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
}
-
-#ifdef CONFIG_PPC32
-EXPORT_SYMBOL(do_syscall_trace_enter);
-EXPORT_SYMBOL(do_syscall_trace_leave);
-#endif
diff --git a/trunk/arch/powerpc/kernel/setup-common.c b/trunk/arch/powerpc/kernel/setup-common.c
index 465e7435efbc..0af3fc1bdcc9 100644
--- a/trunk/arch/powerpc/kernel/setup-common.c
+++ b/trunk/arch/powerpc/kernel/setup-common.c
@@ -304,18 +304,21 @@ struct seq_operations cpuinfo_op = {
void __init check_for_initrd(void)
{
#ifdef CONFIG_BLK_DEV_INITRD
- const unsigned long *prop;
+ const unsigned int *prop;
+ int len;
DBG(" -> check_for_initrd()\n");
if (of_chosen) {
- prop = get_property(of_chosen, "linux,initrd-start", NULL);
+ prop = get_property(of_chosen, "linux,initrd-start", &len);
if (prop != NULL) {
- initrd_start = (unsigned long)__va(*prop);
+ initrd_start = (unsigned long)
+ __va(of_read_ulong(prop, len / 4));
prop = get_property(of_chosen,
- "linux,initrd-end", NULL);
+ "linux,initrd-end", &len);
if (prop != NULL) {
- initrd_end = (unsigned long)__va(*prop);
+ initrd_end = (unsigned long)
+ __va(of_read_ulong(prop, len / 4));
initrd_below_start_ok = 1;
} else
initrd_start = 0;
diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c
index 406f308ddead..d45a168bdaca 100644
--- a/trunk/arch/powerpc/kernel/sysfs.c
+++ b/trunk/arch/powerpc/kernel/sysfs.c
@@ -25,8 +25,8 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
/* SMT stuff */
#ifdef CONFIG_PPC_MULTIPLATFORM
-/* default to snooze disabled */
-DEFINE_PER_CPU(unsigned long, smt_snooze_delay);
+/* Time in microseconds we delay before sleeping in the idle loop */
+DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 };
static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
size_t count)
diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c
index b9a2061cfdb7..7a3c3f791ade 100644
--- a/trunk/arch/powerpc/kernel/time.c
+++ b/trunk/arch/powerpc/kernel/time.c
@@ -870,9 +870,7 @@ static int __init get_freq(char *name, int cells, unsigned long *val)
fp = get_property(cpu, name, NULL);
if (fp) {
found = 1;
- *val = 0;
- while (cells--)
- *val = (*val << 32) | *fp++;
+ *val = of_read_ulong(fp, cells);
}
of_node_put(cpu);
diff --git a/trunk/arch/powerpc/lib/locks.c b/trunk/arch/powerpc/lib/locks.c
index 077bed7dc52b..80b482ca30df 100644
--- a/trunk/arch/powerpc/lib/locks.c
+++ b/trunk/arch/powerpc/lib/locks.c
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
void __spin_yield(raw_spinlock_t *lock)
{
@@ -39,13 +40,12 @@ void __spin_yield(raw_spinlock_t *lock)
rmb();
if (lock->slock != lock_value)
return; /* something has changed */
-#ifdef CONFIG_PPC_ISERIES
- HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
- ((u64)holder_cpu << 32) | yield_count);
-#else
- plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
- yield_count);
-#endif
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
+ ((u64)holder_cpu << 32) | yield_count);
+ else
+ plpar_hcall_norets(H_CONFER,
+ get_hard_smp_processor_id(holder_cpu), yield_count);
}
/*
@@ -69,13 +69,12 @@ void __rw_yield(raw_rwlock_t *rw)
rmb();
if (rw->lock != lock_value)
return; /* something has changed */
-#ifdef CONFIG_PPC_ISERIES
- HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
- ((u64)holder_cpu << 32) | yield_count);
-#else
- plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
- yield_count);
-#endif
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
+ ((u64)holder_cpu << 32) | yield_count);
+ else
+ plpar_hcall_norets(H_CONFER,
+ get_hard_smp_processor_id(holder_cpu), yield_count);
}
#endif
diff --git a/trunk/arch/powerpc/math-emu/Makefile b/trunk/arch/powerpc/math-emu/Makefile
index 754143e8936b..29bc9126241b 100644
--- a/trunk/arch/powerpc/math-emu/Makefile
+++ b/trunk/arch/powerpc/math-emu/Makefile
@@ -11,3 +11,6 @@ obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
mtfsf.o mtfsfi.o stfiwx.o stfs.o \
udivmodti4.o
+
+CFLAGS_fabs.o = -fno-builtin-fabs
+CFLAGS_math.o = -fno-builtin-fabs
diff --git a/trunk/arch/powerpc/oprofile/backtrace.c b/trunk/arch/powerpc/oprofile/backtrace.c
index 75f57bc96b40..b4278cfd1f80 100644
--- a/trunk/arch/powerpc/oprofile/backtrace.c
+++ b/trunk/arch/powerpc/oprofile/backtrace.c
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#define STACK_SP(STACK) *(STACK)
@@ -26,8 +27,9 @@
static unsigned int user_getsp32(unsigned int sp, int is_first)
{
unsigned int stack_frame[2];
+ void __user *p = compat_ptr(sp);
- if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+ if (!access_ok(VERIFY_READ, p, sizeof(stack_frame)))
return 0;
/*
@@ -35,8 +37,7 @@ static unsigned int user_getsp32(unsigned int sp, int is_first)
* which means that we've done all that we can do from
* interrupt context.
*/
- if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp,
- sizeof(stack_frame)))
+ if (__copy_from_user_inatomic(stack_frame, p, sizeof(stack_frame)))
return 0;
if (!is_first)
@@ -54,10 +55,10 @@ static unsigned long user_getsp64(unsigned long sp, int is_first)
{
unsigned long stack_frame[3];
- if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+ if (!access_ok(VERIFY_READ, (void __user *)sp, sizeof(stack_frame)))
return 0;
- if (__copy_from_user_inatomic(stack_frame, (void *)sp,
+ if (__copy_from_user_inatomic(stack_frame, (void __user *)sp,
sizeof(stack_frame)))
return 0;
diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c
index 3bd36d46ab4a..0f5c8ebc7fc3 100644
--- a/trunk/arch/powerpc/platforms/cell/spu_base.c
+++ b/trunk/arch/powerpc/platforms/cell/spu_base.c
@@ -538,7 +538,7 @@ static void __iomem * __init map_spe_prop(struct spu *spu,
const void *p;
int proplen;
- void* ret = NULL;
+ void __iomem *ret = NULL;
int err = 0;
p = get_property(n, name, &proplen);
@@ -562,7 +562,7 @@ static void spu_unmap(struct spu *spu)
iounmap(spu->priv2);
iounmap(spu->priv1);
iounmap(spu->problem);
- iounmap((u8 __iomem *)spu->local_store);
+ iounmap((__force u8 __iomem *)spu->local_store);
}
/* This function shall be abstracted for HV platforms */
diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c
index 58e794f9da1b..51fd197ab5dd 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/file.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c
@@ -1342,7 +1342,7 @@ static u64 spufs_id_get(void *data)
return num;
}
-DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, 0, "0x%llx\n")
+DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
struct tree_descr spufs_dir_contents[] = {
{ "mem", &spufs_mem_fops, 0666, },
diff --git a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c
index c8670f519734..efc452e71ab0 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -234,7 +234,7 @@ static void spu_hw_runcntl_stop(struct spu_context *ctx)
static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode)
{
- struct spu_problem *prob = ctx->spu->problem;
+ struct spu_problem __iomem *prob = ctx->spu->problem;
int ret;
spin_lock_irq(&ctx->spu->register_lock);
@@ -263,7 +263,7 @@ static int spu_hw_send_mfc_command(struct spu_context *ctx,
struct mfc_dma_command *cmd)
{
u32 status;
- struct spu_problem *prob = ctx->spu->problem;
+ struct spu_problem __iomem *prob = ctx->spu->problem;
spin_lock_irq(&ctx->spu->register_lock);
out_be32(&prob->mfc_lsa_W, cmd->lsa);
diff --git a/trunk/arch/powerpc/platforms/iseries/pci.c b/trunk/arch/powerpc/platforms/iseries/pci.c
index f4d427a7bb2d..3eb12065df23 100644
--- a/trunk/arch/powerpc/platforms/iseries/pci.c
+++ b/trunk/arch/powerpc/platforms/iseries/pci.c
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include
#include
@@ -269,46 +270,6 @@ void pcibios_fixup_resources(struct pci_dev *pdev)
{
}
-/*
- * I/0 Memory copy MUST use mmio commands on iSeries
- * To do; For performance, include the hv call directly
- */
-void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
-{
- u8 ByteValue = c;
- long NumberOfBytes = Count;
-
- while (NumberOfBytes > 0) {
- iSeries_Write_Byte(ByteValue, dest++);
- -- NumberOfBytes;
- }
-}
-EXPORT_SYMBOL(iSeries_memset_io);
-
-void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
-{
- char *src = source;
- long NumberOfBytes = count;
-
- while (NumberOfBytes > 0) {
- iSeries_Write_Byte(*src++, dest++);
- -- NumberOfBytes;
- }
-}
-EXPORT_SYMBOL(iSeries_memcpy_toio);
-
-void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
-{
- char *dst = dest;
- long NumberOfBytes = count;
-
- while (NumberOfBytes > 0) {
- *dst++ = iSeries_Read_Byte(src++);
- -- NumberOfBytes;
- }
-}
-EXPORT_SYMBOL(iSeries_memcpy_fromio);
-
/*
* Look down the chain to find the matching Device Device
*/
@@ -491,7 +452,7 @@ static inline struct device_node *xlate_iomm_address(
* iSeries_Read_Word = Read Word (16 bit)
* iSeries_Read_Long = Read Long (32 bit)
*/
-u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
+static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -518,9 +479,8 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
return (u8)ret.value;
}
-EXPORT_SYMBOL(iSeries_Read_Byte);
-u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
+static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -548,9 +508,8 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
return swab16((u16)ret.value);
}
-EXPORT_SYMBOL(iSeries_Read_Word);
-u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
+static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -578,7 +537,6 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
return swab32((u32)ret.value);
}
-EXPORT_SYMBOL(iSeries_Read_Long);
/*
* Write MM I/O Instructions for the iSeries
@@ -587,7 +545,7 @@ EXPORT_SYMBOL(iSeries_Read_Long);
* iSeries_Write_Word = Write Word(16 bit)
* iSeries_Write_Long = Write Long(32 bit)
*/
-void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
+static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -612,9 +570,8 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
}
-EXPORT_SYMBOL(iSeries_Write_Byte);
-void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
+static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -639,9 +596,8 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
}
-EXPORT_SYMBOL(iSeries_Write_Word);
-void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
+static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -666,4 +622,224 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
}
-EXPORT_SYMBOL(iSeries_Write_Long);
+
+extern unsigned char __raw_readb(const volatile void __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ return *(volatile unsigned char __force *)addr;
+}
+EXPORT_SYMBOL(__raw_readb);
+
+extern unsigned short __raw_readw(const volatile void __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ return *(volatile unsigned short __force *)addr;
+}
+EXPORT_SYMBOL(__raw_readw);
+
+extern unsigned int __raw_readl(const volatile void __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ return *(volatile unsigned int __force *)addr;
+}
+EXPORT_SYMBOL(__raw_readl);
+
+extern unsigned long __raw_readq(const volatile void __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ return *(volatile unsigned long __force *)addr;
+}
+EXPORT_SYMBOL(__raw_readq);
+
+extern void __raw_writeb(unsigned char v, volatile void __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ *(volatile unsigned char __force *)addr = v;
+}
+EXPORT_SYMBOL(__raw_writeb);
+
+extern void __raw_writew(unsigned short v, volatile void __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ *(volatile unsigned short __force *)addr = v;
+}
+EXPORT_SYMBOL(__raw_writew);
+
+extern void __raw_writel(unsigned int v, volatile void __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ *(volatile unsigned int __force *)addr = v;
+}
+EXPORT_SYMBOL(__raw_writel);
+
+extern void __raw_writeq(unsigned long v, volatile void __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ *(volatile unsigned long __force *)addr = v;
+}
+EXPORT_SYMBOL(__raw_writeq);
+
+int in_8(const volatile unsigned char __iomem *addr)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ return iSeries_Read_Byte(addr);
+ return __in_8(addr);
+}
+EXPORT_SYMBOL(in_8);
+
+void out_8(volatile unsigned char __iomem *addr, int val)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ iSeries_Write_Byte(val, addr);
+ else
+ __out_8(addr, val);
+}
+EXPORT_SYMBOL(out_8);
+
+int in_le16(const volatile unsigned short __iomem *addr)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ return iSeries_Read_Word(addr);
+ return __in_le16(addr);
+}
+EXPORT_SYMBOL(in_le16);
+
+int in_be16(const volatile unsigned short __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ return __in_be16(addr);
+}
+EXPORT_SYMBOL(in_be16);
+
+void out_le16(volatile unsigned short __iomem *addr, int val)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ iSeries_Write_Word(val, addr);
+ else
+ __out_le16(addr, val);
+}
+EXPORT_SYMBOL(out_le16);
+
+void out_be16(volatile unsigned short __iomem *addr, int val)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ __out_be16(addr, val);
+}
+EXPORT_SYMBOL(out_be16);
+
+unsigned in_le32(const volatile unsigned __iomem *addr)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ return iSeries_Read_Long(addr);
+ return __in_le32(addr);
+}
+EXPORT_SYMBOL(in_le32);
+
+unsigned in_be32(const volatile unsigned __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ return __in_be32(addr);
+}
+EXPORT_SYMBOL(in_be32);
+
+void out_le32(volatile unsigned __iomem *addr, int val)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ iSeries_Write_Long(val, addr);
+ else
+ __out_le32(addr, val);
+}
+EXPORT_SYMBOL(out_le32);
+
+void out_be32(volatile unsigned __iomem *addr, int val)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ __out_be32(addr, val);
+}
+EXPORT_SYMBOL(out_be32);
+
+unsigned long in_le64(const volatile unsigned long __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ return __in_le64(addr);
+}
+EXPORT_SYMBOL(in_le64);
+
+unsigned long in_be64(const volatile unsigned long __iomem *addr)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ return __in_be64(addr);
+}
+EXPORT_SYMBOL(in_be64);
+
+void out_le64(volatile unsigned long __iomem *addr, unsigned long val)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ __out_le64(addr, val);
+}
+EXPORT_SYMBOL(out_le64);
+
+void out_be64(volatile unsigned long __iomem *addr, unsigned long val)
+{
+ BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+
+ __out_be64(addr, val);
+}
+EXPORT_SYMBOL(out_be64);
+
+void memset_io(volatile void __iomem *addr, int c, unsigned long n)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+ volatile char __iomem *d = addr;
+
+ while (n-- > 0) {
+ iSeries_Write_Byte(c, d++);
+ }
+ } else
+ eeh_memset_io(addr, c, n);
+}
+EXPORT_SYMBOL(memset_io);
+
+void memcpy_fromio(void *dest, const volatile void __iomem *src,
+ unsigned long n)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+ char *d = dest;
+ const volatile char __iomem *s = src;
+
+ while (n-- > 0) {
+ *d++ = iSeries_Read_Byte(s++);
+ }
+ } else
+ eeh_memcpy_fromio(dest, src, n);
+}
+EXPORT_SYMBOL(memcpy_fromio);
+
+void memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+ const char *s = src;
+ volatile char __iomem *d = dest;
+
+ while (n-- > 0) {
+ iSeries_Write_Byte(*s++, d++);
+ }
+ } else
+ eeh_memcpy_toio(dest, src, n);
+}
+EXPORT_SYMBOL(memcpy_toio);
diff --git a/trunk/arch/powerpc/platforms/maple/pci.c b/trunk/arch/powerpc/platforms/maple/pci.c
index dc05af5156a9..1b827618e05f 100644
--- a/trunk/arch/powerpc/platforms/maple/pci.c
+++ b/trunk/arch/powerpc/platforms/maple/pci.c
@@ -81,28 +81,32 @@ static void __init fixup_bus_range(struct device_node *bridge)
}
-#define U3_AGP_CFA0(devfn, off) \
- ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
- | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
- | (((unsigned long)(off)) & 0xFCUL))
-
-#define U3_AGP_CFA1(bus, devfn, off) \
- ((((unsigned long)(bus)) << 16) \
- |(((unsigned long)(devfn)) << 8) \
- |(((unsigned long)(off)) & 0xFCUL) \
- |1UL)
-
-static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
+static unsigned long u3_agp_cfa0(u8 devfn, u8 off)
+{
+ return (1 << (unsigned long)PCI_SLOT(devfn)) |
+ ((unsigned long)PCI_FUNC(devfn) << 8) |
+ ((unsigned long)off & 0xFCUL);
+}
+
+static unsigned long u3_agp_cfa1(u8 bus, u8 devfn, u8 off)
+{
+ return ((unsigned long)bus << 16) |
+ ((unsigned long)devfn << 8) |
+ ((unsigned long)off & 0xFCUL) |
+ 1UL;
+}
+
+static volatile void __iomem *u3_agp_cfg_access(struct pci_controller* hose,
u8 bus, u8 dev_fn, u8 offset)
{
unsigned int caddr;
if (bus == hose->first_busno) {
if (dev_fn < (11 << 3))
- return 0;
- caddr = U3_AGP_CFA0(dev_fn, offset);
+ return NULL;
+ caddr = u3_agp_cfa0(dev_fn, offset);
} else
- caddr = U3_AGP_CFA1(bus, dev_fn, offset);
+ caddr = u3_agp_cfa1(bus, dev_fn, offset);
/* Uninorth will return garbage if we don't read back the value ! */
do {
@@ -110,14 +114,14 @@ static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
} while (in_le32(hose->cfg_addr) != caddr);
offset &= 0x07;
- return ((unsigned long)hose->cfg_data) + offset;
+ return hose->cfg_data + offset;
}
static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 *val)
{
struct pci_controller *hose;
- unsigned long addr;
+ volatile void __iomem *addr;
hose = pci_bus_to_host(bus);
if (hose == NULL)
@@ -132,13 +136,13 @@ static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
*/
switch (len) {
case 1:
- *val = in_8((u8 *)addr);
+ *val = in_8(addr);
break;
case 2:
- *val = in_le16((u16 *)addr);
+ *val = in_le16(addr);
break;
default:
- *val = in_le32((u32 *)addr);
+ *val = in_le32(addr);
break;
}
return PCIBIOS_SUCCESSFUL;
@@ -148,7 +152,7 @@ static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 val)
{
struct pci_controller *hose;
- unsigned long addr;
+ volatile void __iomem *addr;
hose = pci_bus_to_host(bus);
if (hose == NULL)
@@ -163,16 +167,16 @@ static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
*/
switch (len) {
case 1:
- out_8((u8 *)addr, val);
- (void) in_8((u8 *)addr);
+ out_8(addr, val);
+ (void) in_8(addr);
break;
case 2:
- out_le16((u16 *)addr, val);
- (void) in_le16((u16 *)addr);
+ out_le16(addr, val);
+ (void) in_le16(addr);
break;
default:
- out_le32((u32 *)addr, val);
- (void) in_le32((u32 *)addr);
+ out_le32(addr, val);
+ (void) in_le32(addr);
break;
}
return PCIBIOS_SUCCESSFUL;
@@ -184,35 +188,40 @@ static struct pci_ops u3_agp_pci_ops =
u3_agp_write_config
};
+static unsigned long u3_ht_cfa0(u8 devfn, u8 off)
+{
+ return (devfn << 8) | off;
+}
-#define U3_HT_CFA0(devfn, off) \
- ((((unsigned long)devfn) << 8) | offset)
-#define U3_HT_CFA1(bus, devfn, off) \
- (U3_HT_CFA0(devfn, off) \
- + (((unsigned long)bus) << 16) \
- + 0x01000000UL)
+static unsigned long u3_ht_cfa1(u8 bus, u8 devfn, u8 off)
+{
+ return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL;
+}
-static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose,
u8 bus, u8 devfn, u8 offset)
{
if (bus == hose->first_busno) {
if (PCI_SLOT(devfn) == 0)
- return 0;
- return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
+ return NULL;
+ return hose->cfg_data + u3_ht_cfa0(devfn, offset);
} else
- return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
+ return hose->cfg_data + u3_ht_cfa1(bus, devfn, offset);
}
static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 *val)
{
struct pci_controller *hose;
- unsigned long addr;
+ volatile void __iomem *addr;
hose = pci_bus_to_host(bus);
if (hose == NULL)
return PCIBIOS_DEVICE_NOT_FOUND;
+ if (offset > 0xff)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
if (!addr)
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -223,13 +232,13 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
*/
switch (len) {
case 1:
- *val = in_8((u8 *)addr);
+ *val = in_8(addr);
break;
case 2:
- *val = in_le16((u16 *)addr);
+ *val = in_le16(addr);
break;
default:
- *val = in_le32((u32 *)addr);
+ *val = in_le32(addr);
break;
}
return PCIBIOS_SUCCESSFUL;
@@ -239,12 +248,15 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 val)
{
struct pci_controller *hose;
- unsigned long addr;
+ volatile void __iomem *addr;
hose = pci_bus_to_host(bus);
if (hose == NULL)
return PCIBIOS_DEVICE_NOT_FOUND;
+ if (offset > 0xff)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
if (!addr)
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -254,16 +266,16 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
*/
switch (len) {
case 1:
- out_8((u8 *)addr, val);
- (void) in_8((u8 *)addr);
+ out_8(addr, val);
+ (void) in_8(addr);
break;
case 2:
- out_le16((u16 *)addr, val);
- (void) in_le16((u16 *)addr);
+ out_le16(addr, val);
+ (void) in_le16(addr);
break;
default:
- out_le32((u32 *)addr, val);
- (void) in_le32((u32 *)addr);
+ out_le32(addr, val);
+ (void) in_le32(addr);
break;
}
return PCIBIOS_SUCCESSFUL;
@@ -303,7 +315,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
* the reg address cell, we shall fix that by killing struct
* reg_property and using some accessor functions instead
*/
- hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+ hose->cfg_data = ioremap(0xf2000000, 0x02000000);
hose->first_busno = 0;
hose->last_busno = 0xef;
diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c
index 167cd3ce8a13..d30466d74194 100644
--- a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -89,7 +89,7 @@ static DEFINE_MUTEX(g5_switch_mutex);
#ifdef CONFIG_PMAC_SMU
-static u32 *g5_pmode_data;
+static const u32 *g5_pmode_data;
static int g5_pmode_max;
static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
diff --git a/trunk/arch/powerpc/platforms/powermac/feature.c b/trunk/arch/powerpc/platforms/powermac/feature.c
index 13fcaf5b1796..e49621be6640 100644
--- a/trunk/arch/powerpc/platforms/powermac/feature.c
+++ b/trunk/arch/powerpc/platforms/powermac/feature.c
@@ -1058,8 +1058,8 @@ core99_reset_cpu(struct device_node *node, long param, long value)
if (np == NULL)
return -ENODEV;
for (np = np->child; np != NULL; np = np->sibling) {
- u32 *num = get_property(np, "reg", NULL);
- u32 *rst = get_property(np, "soft-reset", NULL);
+ const u32 *num = get_property(np, "reg", NULL);
+ const u32 *rst = get_property(np, "soft-reset", NULL);
if (num == NULL || rst == NULL)
continue;
if (param == *num) {
diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c
index 653eeb64d1e2..1949b657b092 100644
--- a/trunk/arch/powerpc/platforms/powermac/smp.c
+++ b/trunk/arch/powerpc/platforms/powermac/smp.c
@@ -702,7 +702,7 @@ static void __init smp_core99_setup(int ncpus)
/* GPIO based HW sync on ppc32 Core99 */
if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) {
struct device_node *cpu;
- u32 *tbprop = NULL;
+ const u32 *tbprop = NULL;
core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */
cpu = of_find_node_by_type(NULL, "cpu");
diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c
index 5a23ce5e16ff..3c2d63ebf787 100644
--- a/trunk/arch/powerpc/platforms/pseries/eeh.c
+++ b/trunk/arch/powerpc/platforms/pseries/eeh.c
@@ -225,6 +225,7 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
void eeh_mark_slot (struct device_node *dn, int mode_flag)
{
+ struct pci_dev *dev;
dn = find_device_pe (dn);
/* Back up one, since config addrs might be shared */
@@ -232,6 +233,12 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
dn = dn->parent;
PCI_DN(dn)->eeh_mode |= mode_flag;
+
+ /* Mark the pci device too */
+ dev = PCI_DN(dn)->pcidev;
+ if (dev)
+ dev->error_state = pci_channel_io_frozen;
+
__eeh_mark_slot (dn->child, mode_flag);
}
@@ -449,7 +456,11 @@ EXPORT_SYMBOL(eeh_check_failure);
/* ------------------------------------------------------------- */
/* The code below deals with error recovery */
-/** Return negative value if a permanent error, else return
+/**
+ * eeh_slot_availability - returns error status of slot
+ * @pdn pci device node
+ *
+ * Return negative value if a permanent error, else return
* a number of milliseconds to wait until the PCI slot is
* ready to be used.
*/
@@ -474,11 +485,42 @@ eeh_slot_availability(struct pci_dn *pdn)
printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n",
rc, rets[0], rets[1], rets[2]);
- return -1;
+ return -2;
}
-/** rtas_pci_slot_reset raises/lowers the pci #RST line
- * state: 1/0 to raise/lower the #RST
+/**
+ * rtas_pci_enable - enable MMIO or DMA transfers for this slot
+ * @pdn pci device node
+ */
+
+int
+rtas_pci_enable(struct pci_dn *pdn, int function)
+{
+ int config_addr;
+ int rc;
+
+ /* Use PE configuration address, if present */
+ config_addr = pdn->eeh_config_addr;
+ if (pdn->eeh_pe_config_addr)
+ config_addr = pdn->eeh_pe_config_addr;
+
+ rc = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
+ config_addr,
+ BUID_HI(pdn->phb->buid),
+ BUID_LO(pdn->phb->buid),
+ function);
+
+ if (rc)
+ printk(KERN_WARNING "EEH: Cannot enable function %d, err=%d dn=%s\n",
+ function, rc, pdn->node->full_name);
+
+ return rc;
+}
+
+/**
+ * rtas_pci_slot_reset - raises/lowers the pci #RST line
+ * @pdn pci device node
+ * @state: 1/0 to raise/lower the #RST
*
* Clear the EEH-frozen condition on a slot. This routine
* asserts the PCI #RST line if the 'state' argument is '1',
@@ -511,24 +553,21 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state)
BUID_HI(pdn->phb->buid),
BUID_LO(pdn->phb->buid),
state);
- if (rc) {
- printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n",
+ if (rc)
+ printk (KERN_WARNING "EEH: Unable to reset the failed slot,"
+ " (%d) #RST=%d dn=%s\n",
rc, state, pdn->node->full_name);
- return;
- }
}
-/** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
- * dn -- device node to be reset.
+/**
+ * rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
+ * @pdn: pci device node to be reset.
*
* Return 0 if success, else a non-zero value.
*/
-int
-rtas_set_slot_reset(struct pci_dn *pdn)
+static void __rtas_set_slot_reset(struct pci_dn *pdn)
{
- int i, rc;
-
rtas_pci_slot_reset (pdn, 1);
/* The PCI bus requires that the reset be held high for at least
@@ -549,17 +588,33 @@ rtas_set_slot_reset(struct pci_dn *pdn)
* up traffic. */
#define PCI_BUS_SETTLE_TIME_MSEC 1800
msleep (PCI_BUS_SETTLE_TIME_MSEC);
+}
+
+int rtas_set_slot_reset(struct pci_dn *pdn)
+{
+ int i, rc;
+
+ __rtas_set_slot_reset(pdn);
/* Now double check with the firmware to make sure the device is
* ready to be used; if not, wait for recovery. */
for (i=0; i<10; i++) {
rc = eeh_slot_availability (pdn);
- if (rc < 0)
- printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", rc, pdn->node->full_name);
if (rc == 0)
return 0;
- if (rc < 0)
+
+ if (rc == -2) {
+ printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n",
+ i, pdn->node->full_name);
+ __rtas_set_slot_reset(pdn);
+ continue;
+ }
+
+ if (rc < 0) {
+ printk (KERN_ERR "EEH: unrecoverable slot failure %s\n",
+ pdn->node->full_name);
return -1;
+ }
msleep (rc+100);
}
@@ -582,6 +637,8 @@ rtas_set_slot_reset(struct pci_dn *pdn)
/**
* __restore_bars - Restore the Base Address Registers
+ * @pdn: pci device node
+ *
* Loads the PCI configuration space base address registers,
* the expansion ROM base address, the latency timer, and etc.
* from the saved values in the device node.
diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_cache.c b/trunk/arch/powerpc/platforms/pseries/eeh_cache.c
index c37a8497c60f..b6b462d3c604 100644
--- a/trunk/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/trunk/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -157,6 +157,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
if (!piar)
return NULL;
+ pci_dev_get(dev);
piar->addr_lo = alo;
piar->addr_hi = ahi;
piar->pcidev = dev;
@@ -178,7 +179,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
struct device_node *dn;
struct pci_dn *pdn;
int i;
- int inserted = 0;
dn = pci_device_to_OF_node(dev);
if (!dn) {
@@ -197,9 +197,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
return;
}
- /* The cache holds a reference to the device... */
- pci_dev_get(dev);
-
/* Walk resources on this device, poke them into the tree */
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
unsigned long start = pci_resource_start(dev,i);
@@ -212,12 +209,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
continue;
pci_addr_cache_insert(dev, start, end, flags);
- inserted = 1;
}
-
- /* If there was nothing to add, the cache has no reference... */
- if (!inserted)
- pci_dev_put(dev);
}
/**
@@ -240,7 +232,6 @@ void pci_addr_cache_insert_device(struct pci_dev *dev)
static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
{
struct rb_node *n;
- int removed = 0;
restart:
n = rb_first(&pci_io_addr_cache_root.rb_root);
@@ -250,16 +241,12 @@ static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
if (piar->pcidev == dev) {
rb_erase(n, &pci_io_addr_cache_root.rb_root);
- removed = 1;
+ pci_dev_put(piar->pcidev);
kfree(piar);
goto restart;
}
n = rb_next(n);
}
-
- /* The cache no longer holds its reference to this device... */
- if (removed)
- pci_dev_put(dev);
}
/**
diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c
index 3269d2cd428b..c2bc9904f1cb 100644
--- a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -77,8 +77,12 @@ static int irq_in_use(unsigned int irq)
}
/* ------------------------------------------------------- */
-/** eeh_report_error - report an EEH error to each device,
- * collect up and merge the device responses.
+/**
+ * eeh_report_error - report pci error to each device driver
+ *
+ * Report an EEH error to each device driver, collect up and
+ * merge the device driver responses. Cumulative response
+ * passed back in "userdata".
*/
static void eeh_report_error(struct pci_dev *dev, void *userdata)
@@ -96,24 +100,49 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
disable_irq_nosync(dev->irq);
}
- if (!driver->err_handler)
- return;
- if (!driver->err_handler->error_detected)
+ if (!driver->err_handler ||
+ !driver->err_handler->error_detected)
return;
rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
if (*res == PCI_ERS_RESULT_NONE) *res = rc;
- if (*res == PCI_ERS_RESULT_NEED_RESET) return;
if (*res == PCI_ERS_RESULT_DISCONNECT &&
rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
}
-/** eeh_report_reset -- tell this device that the pci slot
- * has been reset.
+/**
+ * eeh_report_mmio_enabled - tell drivers that MMIO has been enabled
+ *
+ * Report an EEH error to each device driver, collect up and
+ * merge the device driver responses. Cumulative response
+ * passed back in "userdata".
+ */
+
+static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
+{
+ enum pci_ers_result rc, *res = userdata;
+ struct pci_driver *driver = dev->driver;
+
+ // dev->error_state = pci_channel_mmio_enabled;
+
+ if (!driver ||
+ !driver->err_handler ||
+ !driver->err_handler->mmio_enabled)
+ return;
+
+ rc = driver->err_handler->mmio_enabled (dev);
+ if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+ if (*res == PCI_ERS_RESULT_DISCONNECT &&
+ rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
+}
+
+/**
+ * eeh_report_reset - tell device that slot has been reset
*/
static void eeh_report_reset(struct pci_dev *dev, void *userdata)
{
+ enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver = dev->driver;
struct device_node *dn = pci_device_to_OF_node(dev);
@@ -124,14 +153,20 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata)
PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
enable_irq(dev->irq);
}
- if (!driver->err_handler)
- return;
- if (!driver->err_handler->slot_reset)
+ if (!driver->err_handler ||
+ !driver->err_handler->slot_reset)
return;
- driver->err_handler->slot_reset(dev);
+ rc = driver->err_handler->slot_reset(dev);
+ if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+ if (*res == PCI_ERS_RESULT_DISCONNECT &&
+ rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
}
+/**
+ * eeh_report_resume - tell device to resume normal operations
+ */
+
static void eeh_report_resume(struct pci_dev *dev, void *userdata)
{
struct pci_driver *driver = dev->driver;
@@ -148,6 +183,13 @@ static void eeh_report_resume(struct pci_dev *dev, void *userdata)
driver->err_handler->resume(dev);
}
+/**
+ * eeh_report_failure - tell device driver that device is dead.
+ *
+ * This informs the device driver that the device is permanently
+ * dead, and that no further recovery attempts will be made on it.
+ */
+
static void eeh_report_failure(struct pci_dev *dev, void *userdata)
{
struct pci_driver *driver = dev->driver;
@@ -190,11 +232,11 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata)
/**
* eeh_reset_device() -- perform actual reset of a pci slot
- * Args: bus: pointer to the pci bus structure corresponding
+ * @bus: pointer to the pci bus structure corresponding
* to the isolated slot. A non-null value will
* cause all devices under the bus to be removed
* and then re-added.
- * pe_dn: pointer to a "Partionable Endpoint" device node.
+ * @pe_dn: pointer to a "Partionable Endpoint" device node.
* This is the top-level structure on which pci
* bus resets can be performed.
*/
@@ -347,23 +389,43 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
goto hard_fail;
}
- /* If any device called out for a reset, then reset the slot */
- if (result == PCI_ERS_RESULT_NEED_RESET) {
- rc = eeh_reset_device(frozen_pdn, NULL);
- if (rc)
- goto hard_fail;
- pci_walk_bus(frozen_bus, eeh_report_reset, NULL);
+ /* If all devices reported they can proceed, then re-enable MMIO */
+ if (result == PCI_ERS_RESULT_CAN_RECOVER) {
+ rc = rtas_pci_enable(frozen_pdn, EEH_THAW_MMIO);
+
+ if (rc) {
+ result = PCI_ERS_RESULT_NEED_RESET;
+ } else {
+ result = PCI_ERS_RESULT_NONE;
+ pci_walk_bus(frozen_bus, eeh_report_mmio_enabled, &result);
+ }
}
- /* If all devices reported they can proceed, the re-enable PIO */
+ /* If all devices reported they can proceed, then re-enable DMA */
if (result == PCI_ERS_RESULT_CAN_RECOVER) {
- /* XXX Not supported; we brute-force reset the device */
+ rc = rtas_pci_enable(frozen_pdn, EEH_THAW_DMA);
+
+ if (rc)
+ result = PCI_ERS_RESULT_NEED_RESET;
+ }
+
+ /* If any device has a hard failure, then shut off everything. */
+ if (result == PCI_ERS_RESULT_DISCONNECT)
+ goto hard_fail;
+
+ /* If any device called out for a reset, then reset the slot */
+ if (result == PCI_ERS_RESULT_NEED_RESET) {
rc = eeh_reset_device(frozen_pdn, NULL);
if (rc)
goto hard_fail;
- pci_walk_bus(frozen_bus, eeh_report_reset, NULL);
+ result = PCI_ERS_RESULT_NONE;
+ pci_walk_bus(frozen_bus, eeh_report_reset, &result);
}
+ /* All devices should claim they have recovered by now. */
+ if (result != PCI_ERS_RESULT_RECOVERED)
+ goto hard_fail;
+
/* Tell all device drivers that they can resume operations */
pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c
index a6398fbe530d..2551da46b2a6 100644
--- a/trunk/arch/powerpc/platforms/pseries/setup.c
+++ b/trunk/arch/powerpc/platforms/pseries/setup.c
@@ -477,7 +477,6 @@ static void pseries_dedicated_idle_sleep(void)
{
unsigned int cpu = smp_processor_id();
unsigned long start_snooze;
- unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
/*
* Indicate to the HV that we are idle. Now would be
@@ -490,9 +489,9 @@ static void pseries_dedicated_idle_sleep(void)
* has been checked recently. If we should poll for a little
* while, do so.
*/
- if (*smt_snooze_delay) {
+ if (__get_cpu_var(smt_snooze_delay)) {
start_snooze = get_tb() +
- *smt_snooze_delay * tb_ticks_per_usec;
+ __get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec;
local_irq_enable();
set_thread_flag(TIF_POLLING_NRFLAG);
@@ -512,24 +511,7 @@ static void pseries_dedicated_idle_sleep(void)
goto out;
}
- /*
- * If not SMT, cede processor. If CPU is running SMT
- * cede if the other thread is not idle, so that it can
- * go single-threaded. If the other thread is idle,
- * we ask the hypervisor if it has pending work it
- * wants to do and cede if it does. Otherwise we keep
- * polling in order to reduce interrupt latency.
- *
- * Doing the cede when the other thread is active will
- * result in this thread going dormant, meaning the other
- * thread gets to run in single-threaded (ST) mode, which
- * is slightly faster than SMT mode with this thread at
- * very low priority. The cede enables interrupts, which
- * doesn't matter here.
- */
- if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle
- || poll_pending() == H_PENDING)
- cede_processor();
+ cede_processor();
out:
HMT_medium();
diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.h b/trunk/arch/powerpc/sysdev/fsl_soc.h
index 25230ceffbcf..04e145b5fc32 100644
--- a/trunk/arch/powerpc/sysdev/fsl_soc.h
+++ b/trunk/arch/powerpc/sysdev/fsl_soc.h
@@ -2,6 +2,8 @@
#define __PPC_FSL_SOC_H
#ifdef __KERNEL__
+#include
+
extern phys_addr_t get_immrbase(void);
extern u32 get_brgfreq(void);
extern u32 get_baudrate(void);
diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/powerpc/sysdev/ipic.c
index 70e707785d49..0251b7c68d0e 100644
--- a/trunk/arch/powerpc/sysdev/ipic.c
+++ b/trunk/arch/powerpc/sysdev/ipic.c
@@ -210,7 +210,7 @@ static struct ipic_info ipic_info[] = {
.prio_mask = 4,
},
[64] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = IPIC_SMPRR_A,
.force = IPIC_SIFCR_L,
@@ -218,7 +218,7 @@ static struct ipic_info ipic_info[] = {
.prio_mask = 0,
},
[65] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = IPIC_SMPRR_A,
.force = IPIC_SIFCR_L,
@@ -226,7 +226,7 @@ static struct ipic_info ipic_info[] = {
.prio_mask = 1,
},
[66] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = IPIC_SMPRR_A,
.force = IPIC_SIFCR_L,
@@ -234,7 +234,7 @@ static struct ipic_info ipic_info[] = {
.prio_mask = 2,
},
[67] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = IPIC_SMPRR_A,
.force = IPIC_SIFCR_L,
@@ -242,7 +242,7 @@ static struct ipic_info ipic_info[] = {
.prio_mask = 3,
},
[68] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = IPIC_SMPRR_B,
.force = IPIC_SIFCR_L,
@@ -250,7 +250,7 @@ static struct ipic_info ipic_info[] = {
.prio_mask = 0,
},
[69] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = IPIC_SMPRR_B,
.force = IPIC_SIFCR_L,
@@ -258,7 +258,7 @@ static struct ipic_info ipic_info[] = {
.prio_mask = 1,
},
[70] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = IPIC_SMPRR_B,
.force = IPIC_SIFCR_L,
@@ -266,7 +266,7 @@ static struct ipic_info ipic_info[] = {
.prio_mask = 2,
},
[71] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = IPIC_SMPRR_B,
.force = IPIC_SIFCR_L,
@@ -274,91 +274,91 @@ static struct ipic_info ipic_info[] = {
.prio_mask = 3,
},
[72] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 8,
},
[73] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 9,
},
[74] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 10,
},
[75] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 11,
},
[76] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 12,
},
[77] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 13,
},
[78] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 14,
},
[79] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 15,
},
[80] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 16,
},
[84] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 20,
},
[85] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 21,
},
[90] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
.bit = 26,
},
[91] = {
- .pend = IPIC_SIPNR_H,
+ .pend = IPIC_SIPNR_L,
.mask = IPIC_SIMSR_L,
.prio = 0,
.force = IPIC_SIFCR_L,
diff --git a/trunk/arch/ppc/boot/utils/mkbugboot.c b/trunk/arch/ppc/boot/utils/mkbugboot.c
index 29115e01f60a..1640c4199ca6 100644
--- a/trunk/arch/ppc/boot/utils/mkbugboot.c
+++ b/trunk/arch/ppc/boot/utils/mkbugboot.c
@@ -19,36 +19,13 @@
#include
#include
#include
+#include
#ifdef __sun__
#include
#else
#include
#endif
-#ifdef __i386__
-#define cpu_to_be32(x) le32_to_cpu(x)
-#define cpu_to_be16(x) le16_to_cpu(x)
-#else
-#define cpu_to_be32(x) (x)
-#define cpu_to_be16(x) (x)
-#endif
-
-#define cpu_to_le32(x) le32_to_cpu((x))
-unsigned long le32_to_cpu(unsigned long x)
-{
- return (((x & 0x000000ffU) << 24) |
- ((x & 0x0000ff00U) << 8) |
- ((x & 0x00ff0000U) >> 8) |
- ((x & 0xff000000U) >> 24));
-}
-
-#define cpu_to_le16(x) le16_to_cpu((x))
-unsigned short le16_to_cpu(unsigned short x)
-{
- return (((x & 0x00ff) << 8) |
- ((x & 0xff00) >> 8));
-}
-
/* size of read buffer */
#define SIZE 0x1000
@@ -62,124 +39,109 @@ typedef struct bug_boot_header {
#define HEADER_SIZE sizeof(bug_boot_header_t)
-uint32_t copy_image(int32_t in_fd, int32_t out_fd)
+void update_checksum(void *buf, size_t size, uint16_t *sum)
{
- uint8_t buf[SIZE];
- int n;
- uint32_t image_size = 0;
- uint8_t zero = 0;
-
- lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
-
- /* Copy an image while recording its size */
- while ( (n = read(in_fd, buf, SIZE)) > 0 )
- {
- image_size = image_size + n;
- write(out_fd, buf, n);
- }
-
- /* BUG romboot requires that our size is divisible by 2 */
- /* align image to 2 byte boundary */
- if (image_size % 2)
- {
- image_size++;
- write(out_fd, &zero, 1);
- }
-
- return image_size;
+ uint32_t csum = *sum;
+
+ while (size) {
+ csum += *(uint16_t *)buf;
+ if (csum > 0xffff)
+ csum -= 0xffff;
+ buf = (uint16_t *)buf + 1;
+ size -= 2;
+ }
+ *sum = csum;
}
-void write_bugboot_header(int32_t out_fd, uint32_t boot_size)
+uint32_t copy_image(int in_fd, int out_fd, uint16_t *sum)
{
- uint8_t header_block[HEADER_SIZE];
- bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0];
-
- memset(header_block, 0, HEADER_SIZE);
-
- /* Fill in the PPCBUG ROM boot header */
- strncpy(bbh->magic_word, "BOOT", 4); /* PPCBUG magic word */
- bbh->entry_offset = cpu_to_be32(HEADER_SIZE); /* Entry address */
- bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2); /* Routine length */
- strncpy(bbh->routine_name, "LINUXROM", 8); /* Routine name */
-
- /* Output the header and bootloader to the file */
- write(out_fd, header_block, HEADER_SIZE);
+ uint8_t buf[SIZE];
+ int offset = 0;
+ int n;
+ uint32_t image_size = 0;
+
+ lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
+
+ /* Copy an image while recording its size */
+ while ( (n = read(in_fd, buf + offset, SIZE - offset)) > 0 ) {
+ n += offset;
+ offset = n & 1;
+ n -= offset;
+ image_size = image_size + n;
+ /* who's going to deal with short writes? */
+ write(out_fd, buf, n);
+ update_checksum(buf, n, sum);
+ if (offset)
+ buf[0] = buf[n];
+ }
+
+ /* BUG romboot requires that our size is divisible by 2 */
+ /* align image to 2 byte boundary */
+ if (offset) {
+ image_size += 2;
+ buf[1] = '\0';
+ write(out_fd, buf, 2);
+ update_checksum(buf, 2, sum);
+ }
+ return image_size;
}
-uint16_t calc_checksum(int32_t bug_fd)
+void write_bugboot_header(int out_fd, uint32_t boot_size, uint16_t *sum)
{
- uint32_t checksum_var = 0;
- uint8_t buf[2];
- int n;
-
- /* Checksum loop */
- while ( (n = read(bug_fd, buf, 2) ) )
- {
- checksum_var = checksum_var + *(uint16_t *)buf;
-
- /* If we carry out, mask it and add one to the checksum */
- if (checksum_var >> 16)
- checksum_var = (checksum_var & 0x0000ffff) + 1;
- }
-
- return checksum_var;
+ static bug_boot_header_t bbh = {
+ .magic_word = "BOOT",
+ .routine_name = "LINUXROM"
+ };
+
+ /* Fill in the PPCBUG ROM boot header */
+ bbh.entry_offset = htonl(HEADER_SIZE); /* Entry address */
+ bbh.routine_length= htonl(HEADER_SIZE+boot_size+2); /* Routine length */
+
+ /* Output the header and bootloader to the file */
+ write(out_fd, &bbh, sizeof(bug_boot_header_t));
+ update_checksum(&bbh, sizeof(bug_boot_header_t), sum);
}
int main(int argc, char *argv[])
{
- int32_t image_fd, bugboot_fd;
- int argptr = 1;
- uint32_t kernel_size = 0;
- uint16_t checksum = 0;
- uint8_t bugbootname[256];
-
- if ( (argc != 3) )
- {
- fprintf(stderr, "usage: %s \n",argv[0]);
- exit(-1);
- }
-
- /* Get file args */
-
- /* kernel image file */
- if ((image_fd = open( argv[argptr] , 0)) < 0)
- exit(-1);
- argptr++;
+ int image_fd, bugboot_fd;
+ uint32_t kernel_size = 0;
+ uint16_t checksum = 0;
- /* bugboot file */
- if ( !strcmp( argv[argptr], "-" ) )
- bugboot_fd = 1; /* stdout */
- else
- if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0)
- exit(-1);
- else
- strcpy(bugbootname, argv[argptr]);
- argptr++;
+ if (argc != 3) {
+ fprintf(stderr, "usage: %s \n",argv[0]);
+ exit(-1);
+ }
- /* Set file position after ROM header block where zImage will be written */
- lseek(bugboot_fd, HEADER_SIZE, SEEK_SET);
+ /* Get file args */
- /* Copy kernel image into bugboot image */
- kernel_size = copy_image(image_fd, bugboot_fd);
- close(image_fd);
+ /* kernel image file */
+ if ((image_fd = open(argv[1] , 0)) < 0)
+ exit(-1);
- /* Set file position to beginning where header/romboot will be written */
- lseek(bugboot_fd, 0, SEEK_SET);
+ /* bugboot file */
+ if (!strcmp(argv[2], "-"))
+ bugboot_fd = 1; /* stdout */
+ else if ((bugboot_fd = creat(argv[2] , 0755)) < 0)
+ exit(-1);
- /* Write out BUG header/romboot */
- write_bugboot_header(bugboot_fd, kernel_size);
+ /* Set file position after ROM header block where zImage will be written */
+ lseek(bugboot_fd, HEADER_SIZE, SEEK_SET);
- /* Close bugboot file */
- close(bugboot_fd);
+ /* Copy kernel image into bugboot image */
+ kernel_size = copy_image(image_fd, bugboot_fd, &checksum);
- /* Reopen it as read/write */
- bugboot_fd = open(bugbootname, O_RDWR);
+ /* Set file position to beginning where header/romboot will be written */
+ lseek(bugboot_fd, 0, SEEK_SET);
- /* Calculate checksum */
- checksum = calc_checksum(bugboot_fd);
+ /* Write out BUG header/romboot */
+ write_bugboot_header(bugboot_fd, kernel_size, &checksum);
- /* Write out the calculated checksum */
- write(bugboot_fd, &checksum, 2);
+ /* Write out the calculated checksum */
+ lseek(bugboot_fd, 0, SEEK_END);
+ write(bugboot_fd, &checksum, 2);
- return 0;
+ /* Close bugboot file */
+ close(bugboot_fd);
+ return 0;
}
diff --git a/trunk/arch/ppc/boot/utils/mkprep.c b/trunk/arch/ppc/boot/utils/mkprep.c
index f6d5a2f2fcf6..192bb397126f 100644
--- a/trunk/arch/ppc/boot/utils/mkprep.c
+++ b/trunk/arch/ppc/boot/utils/mkprep.c
@@ -15,279 +15,227 @@
* Modified for Sparc hosted builds by Peter Wahl
*/
-#include
#include
-#include
#include
-#include
-#include
-#include
-
-#define cpu_to_le32(x) le32_to_cpu((x))
-unsigned long le32_to_cpu(unsigned long x)
-{
- return (((x & 0x000000ffU) << 24) |
- ((x & 0x0000ff00U) << 8) |
- ((x & 0x00ff0000U) >> 8) |
- ((x & 0xff000000U) >> 24));
-}
-
-
-#define cpu_to_le16(x) le16_to_cpu((x))
-unsigned short le16_to_cpu(unsigned short x)
-{
- return (((x & 0x00ff) << 8) |
- ((x & 0xff00) >> 8));
-}
-
-#define cpu_to_be32(x) (x)
-#define be32_to_cpu(x) (x)
-#define cpu_to_be16(x) (x)
-#define be16_to_cpu(x) (x)
+#include
/* size of read buffer */
#define SIZE 0x1000
-
-typedef unsigned long dword_t;
-typedef unsigned short word_t;
-typedef unsigned char byte_t;
-typedef byte_t block_t[512];
-typedef byte_t page_t[4096];
-
-
/*
* Partition table entry
* - from the PReP spec
*/
typedef struct partition_entry {
- byte_t boot_indicator;
- byte_t starting_head;
- byte_t starting_sector;
- byte_t starting_cylinder;
-
- byte_t system_indicator;
- byte_t ending_head;
- byte_t ending_sector;
- byte_t ending_cylinder;
-
- dword_t beginning_sector;
- dword_t number_of_sectors;
+ unsigned char boot_indicator;
+ unsigned char starting_head;
+ unsigned char starting_sector;
+ unsigned char starting_cylinder;
+
+ unsigned char system_indicator;
+ unsigned char ending_head;
+ unsigned char ending_sector;
+ unsigned char ending_cylinder;
+
+ unsigned char beginning_sector[4];
+ unsigned char number_of_sectors[4];
} partition_entry_t;
#define BootActive 0x80
#define SystemPrep 0x41
-void copy_image(int , int);
-void write_prep_partition(int , int );
-void write_asm_data( int in, int out );
+void copy_image(FILE *, FILE *);
+void write_prep_partition(FILE *, FILE *);
+void write_asm_data(FILE *, FILE *);
unsigned int elfhdr_size = 65536;
int main(int argc, char *argv[])
{
- int in_fd, out_fd;
- int argptr = 1;
- unsigned int prep = 0;
- unsigned int asmoutput = 0;
-
- if ( (argc < 3) || (argc > 4) )
- {
- fprintf(stderr, "usage: %s [-pbp] [-asm] \n",argv[0]);
- exit(-1);
- }
-
- /* needs to handle args more elegantly -- but this is a small/simple program */
-
- /* check for -pbp */
- if ( !strcmp( argv[argptr], "-pbp" ) )
- {
- prep = 1;
- argptr++;
- }
-
- /* check for -asm */
- if ( !strcmp( argv[argptr], "-asm" ) )
- {
- asmoutput = 1;
- argptr++;
- }
-
- /* input file */
- if ( !strcmp( argv[argptr], "-" ) )
- in_fd = 0; /* stdin */
- else
- if ((in_fd = open( argv[argptr] , 0)) < 0)
- exit(-1);
- argptr++;
-
- /* output file */
- if ( !strcmp( argv[argptr], "-" ) )
- out_fd = 1; /* stdout */
- else
- if ((out_fd = creat( argv[argptr] , 0755)) < 0)
- exit(-1);
- argptr++;
-
- /* skip elf header in input file */
- /*if ( !prep )*/
- lseek(in_fd, elfhdr_size, SEEK_SET);
-
- /* write prep partition if necessary */
- if ( prep )
- write_prep_partition( in_fd, out_fd );
-
- /* write input image to bootimage */
- if ( asmoutput )
- write_asm_data( in_fd, out_fd );
- else
- copy_image(in_fd, out_fd);
-
- return 0;
+ FILE *in, *out;
+ int argptr = 1;
+ int prep = 0;
+ int asmoutput = 0;
+
+ if (argc < 3 || argc > 4) {
+ fprintf(stderr, "usage: %s [-pbp] [-asm] \n",
+ argv[0]);
+ exit(-1);
+ }
+
+/* needs to handle args more elegantly -- but this is a small/simple program */
+
+ /* check for -pbp */
+ if (!strcmp(argv[argptr], "-pbp")) {
+ prep = 1;
+ argptr++;
+ }
+
+ /* check for -asm */
+ if (!strcmp(argv[argptr], "-asm")) {
+ asmoutput = 1;
+ argptr++;
+ }
+
+ /* input file */
+ if (!strcmp(argv[argptr], "-"))
+ in = stdin;
+ else if (!(in = fopen(argv[argptr], "r")))
+ exit(-1);
+ argptr++;
+
+ /* output file */
+ if (!strcmp(argv[argptr], "-"))
+ out = stdout;
+ else if (!(out = fopen(argv[argptr], "w")))
+ exit(-1);
+ argptr++;
+
+ /* skip elf header in input file */
+ /*if ( !prep )*/
+ fseek(in, elfhdr_size, SEEK_SET);
+
+ /* write prep partition if necessary */
+ if (prep)
+ write_prep_partition(in, out);
+
+ /* write input image to bootimage */
+ if (asmoutput)
+ write_asm_data(in, out);
+ else
+ copy_image(in, out);
+
+ return 0;
}
-void write_prep_partition(int in, int out)
+void store_le32(unsigned int v, unsigned char *p)
{
- unsigned char block[512];
- partition_entry_t pe;
- dword_t *entry = (dword_t *)&block[0];
- dword_t *length = (dword_t *)&block[sizeof(long)];
- struct stat info;
-
- if (fstat(in, &info) < 0)
- {
- fprintf(stderr,"info failed\n");
- exit(-1);
- }
-
- bzero( block, sizeof block );
-
- /* set entry point and boot image size skipping over elf header */
-#ifdef __i386__
- *entry = 0x400/*+65536*/;
- *length = info.st_size-elfhdr_size+0x400;
-#else
- *entry = cpu_to_le32(0x400/*+65536*/);
- *length = cpu_to_le32(info.st_size-elfhdr_size+0x400);
-#endif /* __i386__ */
-
- /* sets magic number for msdos partition (used by linux) */
- block[510] = 0x55;
- block[511] = 0xAA;
-
- /*
- * Build a "PReP" partition table entry in the boot record
- * - "PReP" may only look at the system_indicator
- */
- pe.boot_indicator = BootActive;
- pe.system_indicator = SystemPrep;
- /*
- * The first block of the diskette is used by this "boot record" which
- * actually contains the partition table. (The first block of the
- * partition contains the boot image, but I digress...) We'll set up
- * one partition on the diskette and it shall contain the rest of the
- * diskette.
- */
- pe.starting_head = 0; /* zero-based */
- pe.starting_sector = 2; /* one-based */
- pe.starting_cylinder = 0; /* zero-based */
- pe.ending_head = 1; /* assumes two heads */
- pe.ending_sector = 18; /* assumes 18 sectors/track */
- pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */
-
- /*
- * The "PReP" software ignores the above fields and just looks at
- * the next two.
- * - size of the diskette is (assumed to be)
- * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
- * - unlike the above sector numbers, the beginning sector is zero-based!
- */
+ p[0] = v;
+ p[1] = v >>= 8;
+ p[2] = v >>= 8;
+ p[3] = v >> 8;
+}
+
+void write_prep_partition(FILE *in, FILE *out)
+{
+ unsigned char block[512];
+ partition_entry_t pe;
+ unsigned char *entry = block;
+ unsigned char *length = block + 4;
+ long pos = ftell(in), size;
+
+ if (fseek(in, 0, SEEK_END) < 0) {
+ fprintf(stderr,"info failed\n");
+ exit(-1);
+ }
+ size = ftell(in);
+ if (fseek(in, pos, SEEK_SET) < 0) {
+ fprintf(stderr,"info failed\n");
+ exit(-1);
+ }
+
+ memset(block, '\0', sizeof(block));
+
+ /* set entry point and boot image size skipping over elf header */
+ store_le32(0x400/*+65536*/, entry);
+ store_le32(size-elfhdr_size+0x400, length);
+
+ /* sets magic number for msdos partition (used by linux) */
+ block[510] = 0x55;
+ block[511] = 0xAA;
+
+ /*
+ * Build a "PReP" partition table entry in the boot record
+ * - "PReP" may only look at the system_indicator
+ */
+ pe.boot_indicator = BootActive;
+ pe.system_indicator = SystemPrep;
+ /*
+ * The first block of the diskette is used by this "boot record" which
+ * actually contains the partition table. (The first block of the
+ * partition contains the boot image, but I digress...) We'll set up
+ * one partition on the diskette and it shall contain the rest of the
+ * diskette.
+ */
+ pe.starting_head = 0; /* zero-based */
+ pe.starting_sector = 2; /* one-based */
+ pe.starting_cylinder = 0; /* zero-based */
+ pe.ending_head = 1; /* assumes two heads */
+ pe.ending_sector = 18; /* assumes 18 sectors/track */
+ pe.ending_cylinder = 79; /* assumes 80 cylinders/diskette */
+
+ /*
+ * The "PReP" software ignores the above fields and just looks at
+ * the next two.
+ * - size of the diskette is (assumed to be)
+ * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
+ * - unlike the above sector numbers, the beginning sector is zero-based!
+ */
#if 0
- pe.beginning_sector = cpu_to_le32(1);
-#else
- /* This has to be 0 on the PowerStack? */
-#ifdef __i386__
- pe.beginning_sector = 0;
+ store_le32(1, pe.beginning_sector);
#else
- pe.beginning_sector = cpu_to_le32(0);
-#endif /* __i386__ */
+ /* This has to be 0 on the PowerStack? */
+ store_le32(0, pe.beginning_sector);
#endif
-#ifdef __i386__
- pe.number_of_sectors = 2*18*80-1;
-#else
- pe.number_of_sectors = cpu_to_le32(2*18*80-1);
-#endif /* __i386__ */
+ store_le32(2*18*80-1, pe.number_of_sectors);
- memcpy(&block[0x1BE], &pe, sizeof(pe));
+ memcpy(&block[0x1BE], &pe, sizeof(pe));
- write( out, block, sizeof(block) );
- write( out, entry, sizeof(*entry) );
- write( out, length, sizeof(*length) );
- /* set file position to 2nd sector where image will be written */
- lseek( out, 0x400, SEEK_SET );
+ fwrite(block, sizeof(block), 1, out);
+ fwrite(entry, 4, 1, out);
+ fwrite(length, 4, 1, out);
+ /* set file position to 2nd sector where image will be written */
+ fseek( out, 0x400, SEEK_SET );
}
-void
-copy_image(int in, int out)
+void copy_image(FILE *in, FILE *out)
{
- char buf[SIZE];
- int n;
+ char buf[SIZE];
+ int n;
- while ( (n = read(in, buf, SIZE)) > 0 )
- write(out, buf, n);
+ while ( (n = fread(buf, 1, SIZE, in)) > 0 )
+ fwrite(buf, 1, n, out);
}
void
-write_asm_data( int in, int out )
+write_asm_data(FILE *in, FILE *out)
{
- int i, cnt, pos, len;
- unsigned int cksum, val;
- unsigned char *lp;
- unsigned char buf[SIZE];
- unsigned char str[256];
-
- write( out, "\t.data\n\t.globl input_data\ninput_data:\n",
- strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) );
- pos = 0;
- cksum = 0;
- while ((len = read(in, buf, sizeof(buf))) > 0)
- {
- cnt = 0;
- lp = (unsigned char *)buf;
- len = (len + 3) & ~3; /* Round up to longwords */
- for (i = 0; i < len; i += 4)
- {
- if (cnt == 0)
- {
- write( out, "\t.long\t", strlen( "\t.long\t" ) );
- }
- sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
- write( out, str, strlen(str) );
- val = *(unsigned long *)lp;
- cksum ^= val;
- lp += 4;
- if (++cnt == 4)
- {
- cnt = 0;
- sprintf( str, " # %x \n", pos+i-12);
- write( out, str, strlen(str) );
- } else
- {
- write( out, ",", 1 );
- }
- }
- if (cnt)
- {
- write( out, "0\n", 2 );
- }
- pos += len;
- }
- sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
- write( out, str, strlen(str) );
-
- fprintf(stderr, "cksum = %x\n", cksum);
+ int i, cnt, pos = 0;
+ unsigned int cksum = 0, val;
+ unsigned char *lp;
+ unsigned char buf[SIZE];
+ size_t len;
+
+ fputs("\t.data\n\t.globl input_data\ninput_data:\n", out);
+ while ((len = fread(buf, 1, sizeof(buf), in)) > 0) {
+ cnt = 0;
+ lp = buf;
+ /* Round up to longwords */
+ while (len & 3)
+ buf[len++] = '\0';
+ for (i = 0; i < len; i += 4) {
+ if (cnt == 0)
+ fputs("\t.long\t", out);
+ fprintf(out, "0x%02X%02X%02X%02X",
+ lp[0], lp[1], lp[2], lp[3]);
+ val = *(unsigned long *)lp;
+ cksum ^= val;
+ lp += 4;
+ if (++cnt == 4) {
+ cnt = 0;
+ fprintf(out, " # %x \n", pos+i-12);
+ } else {
+ fputs(",", out);
+ }
+ }
+ if (cnt)
+ fputs("0\n", out);
+ pos += len;
+ }
+ fprintf(out, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
+ fprintf(stderr, "cksum = %x\n", cksum);
}
diff --git a/trunk/arch/ppc/kernel/misc.S b/trunk/arch/ppc/kernel/misc.S
index 2fa0075f2b5f..50b4bbd06804 100644
--- a/trunk/arch/ppc/kernel/misc.S
+++ b/trunk/arch/ppc/kernel/misc.S
@@ -768,91 +768,6 @@ _GLOBAL(_outsb)
bdnz 00b
blr
-_GLOBAL(_insw)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,2
- blelr-
-00: lhbrx r5,0,r3
-01: eieio
-02: sthu r5,2(r4)
- ISYNC_8xx
- .section .fixup,"ax"
-03: blr
- .text
- .section __ex_table, "a"
- .align 2
- .long 00b, 03b
- .long 01b, 03b
- .long 02b, 03b
- .text
- bdnz 00b
- blr
-
-_GLOBAL(_outsw)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,2
- blelr-
-00: lhzu r5,2(r4)
-01: eieio
-02: sthbrx r5,0,r3
- ISYNC_8xx
- .section .fixup,"ax"
-03: blr
- .text
- .section __ex_table, "a"
- .align 2
- .long 00b, 03b
- .long 01b, 03b
- .long 02b, 03b
- .text
- bdnz 00b
- blr
-
-_GLOBAL(_insl)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,4
- blelr-
-00: lwbrx r5,0,r3
-01: eieio
-02: stwu r5,4(r4)
- ISYNC_8xx
- .section .fixup,"ax"
-03: blr
- .text
- .section __ex_table, "a"
- .align 2
- .long 00b, 03b
- .long 01b, 03b
- .long 02b, 03b
- .text
- bdnz 00b
- blr
-
-_GLOBAL(_outsl)
- cmpwi 0,r5,0
- mtctr r5
- subi r4,r4,4
- blelr-
-00: lwzu r5,4(r4)
-01: stwbrx r5,0,r3
-02: eieio
- ISYNC_8xx
- .section .fixup,"ax"
-03: blr
- .text
- .section __ex_table, "a"
- .align 2
- .long 00b, 03b
- .long 01b, 03b
- .long 02b, 03b
- .text
- bdnz 00b
- blr
-
-_GLOBAL(__ide_mm_insw)
_GLOBAL(_insw_ns)
cmpwi 0,r5,0
mtctr r5
@@ -874,7 +789,6 @@ _GLOBAL(_insw_ns)
bdnz 00b
blr
-_GLOBAL(__ide_mm_outsw)
_GLOBAL(_outsw_ns)
cmpwi 0,r5,0
mtctr r5
@@ -896,7 +810,6 @@ _GLOBAL(_outsw_ns)
bdnz 00b
blr
-_GLOBAL(__ide_mm_insl)
_GLOBAL(_insl_ns)
cmpwi 0,r5,0
mtctr r5
@@ -918,7 +831,6 @@ _GLOBAL(_insl_ns)
bdnz 00b
blr
-_GLOBAL(__ide_mm_outsl)
_GLOBAL(_outsl_ns)
cmpwi 0,r5,0
mtctr r5
diff --git a/trunk/arch/ppc/kernel/ppc_ksyms.c b/trunk/arch/ppc/kernel/ppc_ksyms.c
index d1735401384c..c8b65ca8a350 100644
--- a/trunk/arch/ppc/kernel/ppc_ksyms.c
+++ b/trunk/arch/ppc/kernel/ppc_ksyms.c
@@ -115,17 +115,8 @@ EXPORT_SYMBOL(outw);
EXPORT_SYMBOL(outl);
EXPORT_SYMBOL(outsl);*/
-EXPORT_SYMBOL(__ide_mm_insl);
-EXPORT_SYMBOL(__ide_mm_outsw);
-EXPORT_SYMBOL(__ide_mm_insw);
-EXPORT_SYMBOL(__ide_mm_outsl);
-
EXPORT_SYMBOL(_insb);
EXPORT_SYMBOL(_outsb);
-EXPORT_SYMBOL(_insw);
-EXPORT_SYMBOL(_outsw);
-EXPORT_SYMBOL(_insl);
-EXPORT_SYMBOL(_outsl);
EXPORT_SYMBOL(_insw_ns);
EXPORT_SYMBOL(_outsw_ns);
EXPORT_SYMBOL(_insl_ns);
diff --git a/trunk/arch/ppc/platforms/85xx/sbc8560.h b/trunk/arch/ppc/platforms/85xx/sbc8560.h
index c7d61cf3a449..e5e156f60100 100644
--- a/trunk/arch/ppc/platforms/85xx/sbc8560.h
+++ b/trunk/arch/ppc/platforms/85xx/sbc8560.h
@@ -14,6 +14,7 @@
#define __MACH_SBC8560_H__
#include
+#include
#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
diff --git a/trunk/arch/ppc/platforms/85xx/sbc85xx.h b/trunk/arch/ppc/platforms/85xx/sbc85xx.h
index 21ea7a55639b..51df4dc04e22 100644
--- a/trunk/arch/ppc/platforms/85xx/sbc85xx.h
+++ b/trunk/arch/ppc/platforms/85xx/sbc85xx.h
@@ -49,4 +49,22 @@ extern void sbc8560_init_IRQ(void) __init;
#define MPC85XX_PCI1_IO_SIZE 0x01000000
+/* FCC1 Clock Source Configuration. These can be
+ * redefined in the board specific file.
+ * Can only choose from CLK9-12 */
+#define F1_RXCLK 12
+#define F1_TXCLK 11
+
+/* FCC2 Clock Source Configuration. These can be
+ * redefined in the board specific file.
+ * Can only choose from CLK13-16 */
+#define F2_RXCLK 13
+#define F2_TXCLK 14
+
+/* FCC3 Clock Source Configuration. These can be
+ * redefined in the board specific file.
+ * Can only choose from CLK13-16 */
+#define F3_RXCLK 15
+#define F3_TXCLK 16
+
#endif /* __PLATFORMS_85XX_SBC85XX_H__ */
diff --git a/trunk/arch/ppc/syslib/m8260_pci_erratum9.c b/trunk/arch/ppc/syslib/m8260_pci_erratum9.c
index 974581ea4849..5475709ce07b 100644
--- a/trunk/arch/ppc/syslib/m8260_pci_erratum9.c
+++ b/trunk/arch/ppc/syslib/m8260_pci_erratum9.c
@@ -339,20 +339,6 @@ void insl(unsigned port, void *buf, int nl)
idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
}
-void insw_ns(unsigned port, void *buf, int ns)
-{
- u8 *addr = (u8 *)(port + _IO_BASE);
-
- idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
-}
-
-void insl_ns(unsigned port, void *buf, int nl)
-{
- u8 *addr = (u8 *)(port + _IO_BASE);
-
- idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
-}
-
void *memcpy_fromio(void *dest, unsigned long src, size_t count)
{
unsigned long pa = iopa((unsigned long) src);
@@ -373,8 +359,6 @@ EXPORT_SYMBOL(inl);
EXPORT_SYMBOL(insb);
EXPORT_SYMBOL(insw);
EXPORT_SYMBOL(insl);
-EXPORT_SYMBOL(insw_ns);
-EXPORT_SYMBOL(insl_ns);
EXPORT_SYMBOL(memcpy_fromio);
#endif /* ifdef CONFIG_8260_PCI9 */
diff --git a/trunk/arch/ppc/xmon/xmon.c b/trunk/arch/ppc/xmon/xmon.c
index 25d032b2aec7..b1a91744fd2d 100644
--- a/trunk/arch/ppc/xmon/xmon.c
+++ b/trunk/arch/ppc/xmon/xmon.c
@@ -806,7 +806,7 @@ backtrace(struct pt_regs *excp)
for (; sp != 0; sp = stack[0]) {
if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
break;
- printf("[%.8lx] ", stack);
+ printf("[%.8lx] ", stack[0]);
xmon_print_symbol(stack[1], " ", "\n");
if (stack[1] == (unsigned) &ret_from_except
|| stack[1] == (unsigned) &ret_from_except_full
diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig
index 2f4f70c4dbb2..b216ca659cdf 100644
--- a/trunk/arch/s390/Kconfig
+++ b/trunk/arch/s390/Kconfig
@@ -460,8 +460,7 @@ config S390_HYPFS_FS
information in an s390 hypervisor environment.
config KEXEC
- bool "kexec system call (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ bool "kexec system call"
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
@@ -487,8 +486,22 @@ source "drivers/net/Kconfig"
source "fs/Kconfig"
+menu "Instrumentation Support"
+
source "arch/s390/oprofile/Kconfig"
+config KPROBES
+ bool "Kprobes (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && MODULES
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+
+endmenu
+
source "arch/s390/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/s390/appldata/appldata.h b/trunk/arch/s390/appldata/appldata.h
index 71d65eb30650..0429481dea63 100644
--- a/trunk/arch/s390/appldata/appldata.h
+++ b/trunk/arch/s390/appldata/appldata.h
@@ -29,22 +29,6 @@
#define CTL_APPLDATA_NET_SUM 2125
#define CTL_APPLDATA_PROC 2126
-#ifndef CONFIG_64BIT
-
-#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */
-#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */
-#define APPLDATA_GEN_EVENT_RECORD 0x02
-#define APPLDATA_START_CONFIG_REC 0x03
-
-#else
-
-#define APPLDATA_START_INTERVAL_REC 0x80
-#define APPLDATA_STOP_REC 0x81
-#define APPLDATA_GEN_EVENT_RECORD 0x82
-#define APPLDATA_START_CONFIG_REC 0x83
-
-#endif /* CONFIG_64BIT */
-
#define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x)
#define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x)
#define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x)
diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c
index a0a94e0ef8d1..b69ed742f981 100644
--- a/trunk/arch/s390/appldata/appldata_base.c
+++ b/trunk/arch/s390/appldata/appldata_base.c
@@ -14,20 +14,20 @@
#include
#include
#include
-#include
-#include
-#include
#include
#include
#include
#include
#include
#include
-#include
-//#include
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
#include "appldata.h"
@@ -39,34 +39,6 @@
#define TOD_MICRO 0x01000 /* nr. of TOD clock units
for 1 microsecond */
-
-/*
- * Parameter list for DIAGNOSE X'DC'
- */
-#ifndef CONFIG_64BIT
-struct appldata_parameter_list {
- u16 diag; /* The DIAGNOSE code X'00DC' */
- u8 function; /* The function code for the DIAGNOSE */
- u8 parlist_length; /* Length of the parameter list */
- u32 product_id_addr; /* Address of the 16-byte product ID */
- u16 reserved;
- u16 buffer_length; /* Length of the application data buffer */
- u32 buffer_addr; /* Address of the application data buffer */
-};
-#else
-struct appldata_parameter_list {
- u16 diag;
- u8 function;
- u8 parlist_length;
- u32 unused01;
- u16 reserved;
- u16 buffer_length;
- u32 unused02;
- u64 product_id_addr;
- u64 buffer_addr;
-};
-#endif /* CONFIG_64BIT */
-
/*
* /proc entries (sysctl)
*/
@@ -181,46 +153,17 @@ static void appldata_work_fn(void *data)
int appldata_diag(char record_nr, u16 function, unsigned long buffer,
u16 length, char *mod_lvl)
{
- unsigned long ry;
- struct appldata_product_id {
- char prod_nr[7]; /* product nr. */
- char prod_fn[2]; /* product function */
- char record_nr; /* record nr. */
- char version_nr[2]; /* version */
- char release_nr[2]; /* release */
- char mod_lvl[2]; /* modification lvl. */
- } appldata_product_id = {
- /* all strings are EBCDIC, record_nr is byte */
+ struct appldata_product_id id = {
.prod_nr = {0xD3, 0xC9, 0xD5, 0xE4,
- 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */
- .prod_fn = {0xD5, 0xD3}, /* "NL" */
+ 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */
+ .prod_fn = 0xD5D3, /* "NL" */
.record_nr = record_nr,
- .version_nr = {0xF2, 0xF6}, /* "26" */
- .release_nr = {0xF0, 0xF1}, /* "01" */
- .mod_lvl = {mod_lvl[0], mod_lvl[1]},
- };
- struct appldata_parameter_list appldata_parameter_list = {
- .diag = 0xDC,
- .function = function,
- .parlist_length =
- sizeof(appldata_parameter_list),
- .buffer_length = length,
- .product_id_addr =
- (unsigned long) &appldata_product_id,
- .buffer_addr = virt_to_phys((void *) buffer)
+ .version_nr = 0xF2F6, /* "26" */
+ .release_nr = 0xF0F1, /* "01" */
+ .mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1],
};
- if (!MACHINE_IS_VM)
- return -ENOSYS;
- ry = -1;
- asm volatile(
- "diag %1,%0,0xDC\n\t"
- : "=d" (ry)
- : "d" (&appldata_parameter_list),
- "m" (appldata_parameter_list),
- "m" (appldata_product_id)
- : "cc");
- return (int) ry;
+ return appldata_asm(&id, function, (void *) buffer, length);
}
/************************ timer, work, DIAG ****************************/
diff --git a/trunk/arch/s390/appldata/appldata_os.c b/trunk/arch/s390/appldata/appldata_os.c
index 161acc5c8a1b..76a15523ae9e 100644
--- a/trunk/arch/s390/appldata/appldata_os.c
+++ b/trunk/arch/s390/appldata/appldata_os.c
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include
#include "appldata.h"
diff --git a/trunk/arch/s390/crypto/aes_s390.c b/trunk/arch/s390/crypto/aes_s390.c
index 5713c7e5bd16..15c9eec02928 100644
--- a/trunk/arch/s390/crypto/aes_s390.c
+++ b/trunk/arch/s390/crypto/aes_s390.c
@@ -16,9 +16,9 @@
*
*/
+#include
#include
#include
-#include
#include "crypt_s390.h"
#define AES_MIN_KEY_SIZE 16
@@ -34,13 +34,16 @@ int has_aes_256 = 0;
struct s390_aes_ctx {
u8 iv[AES_BLOCK_SIZE];
u8 key[AES_MAX_KEY_SIZE];
+ long enc;
+ long dec;
int key_len;
};
static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
- unsigned int key_len, u32 *flags)
+ unsigned int key_len)
{
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
+ u32 *flags = &tfm->crt_flags;
switch (key_len) {
case 16:
@@ -110,133 +113,206 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
}
}
-static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
- const u8 *in, unsigned int nbytes)
-{
- struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
- /* only use complete blocks */
- nbytes &= ~(AES_BLOCK_SIZE - 1);
+static struct crypto_alg aes_alg = {
+ .cra_name = "aes",
+ .cra_driver_name = "aes-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct s390_aes_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+ .cia_setkey = aes_set_key,
+ .cia_encrypt = aes_encrypt,
+ .cia_decrypt = aes_decrypt,
+ }
+ }
+};
+
+static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
- switch (sctx->key_len) {
+ switch (key_len) {
case 16:
- ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ sctx->enc = KM_AES_128_ENCRYPT;
+ sctx->dec = KM_AES_128_DECRYPT;
break;
case 24:
- ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ sctx->enc = KM_AES_192_ENCRYPT;
+ sctx->dec = KM_AES_192_DECRYPT;
break;
case 32:
- ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ sctx->enc = KM_AES_256_ENCRYPT;
+ sctx->dec = KM_AES_256_DECRYPT;
break;
}
- return nbytes;
+
+ return aes_set_key(tfm, in_key, key_len);
}
-static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
- const u8 *in, unsigned int nbytes)
+static int ecb_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
+ struct blkcipher_walk *walk)
{
- struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+ int ret = blkcipher_walk_virt(desc, walk);
+ unsigned int nbytes;
- /* only use complete blocks */
- nbytes &= ~(AES_BLOCK_SIZE - 1);
+ while ((nbytes = walk->nbytes)) {
+ /* only use complete blocks */
+ unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
+ u8 *out = walk->dst.virt.addr;
+ u8 *in = walk->src.virt.addr;
- switch (sctx->key_len) {
- case 16:
- ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
- break;
- case 24:
- ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
- break;
- case 32:
- ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
- break;
+ ret = crypt_s390_km(func, param, out, in, n);
+ BUG_ON((ret < 0) || (ret != n));
+
+ nbytes &= AES_BLOCK_SIZE - 1;
+ ret = blkcipher_walk_done(desc, walk, nbytes);
}
- return nbytes;
+
+ return ret;
}
-static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
- const u8 *in, unsigned int nbytes)
+static int ecb_aes_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
{
- struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+ struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- /* only use complete blocks */
- nbytes &= ~(AES_BLOCK_SIZE - 1);
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk);
+}
- memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
- switch (sctx->key_len) {
+static int ecb_aes_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk);
+}
+
+static struct crypto_alg ecb_aes_alg = {
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ecb-aes-s390",
+ .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct s390_aes_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = ecb_aes_set_key,
+ .encrypt = ecb_aes_encrypt,
+ .decrypt = ecb_aes_decrypt,
+ }
+ }
+};
+
+static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
+
+ switch (key_len) {
case 16:
- ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ sctx->enc = KMC_AES_128_ENCRYPT;
+ sctx->dec = KMC_AES_128_DECRYPT;
break;
case 24:
- ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ sctx->enc = KMC_AES_192_ENCRYPT;
+ sctx->dec = KMC_AES_192_DECRYPT;
break;
case 32:
- ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ sctx->enc = KMC_AES_256_ENCRYPT;
+ sctx->dec = KMC_AES_256_DECRYPT;
break;
}
- memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);
- return nbytes;
+ return aes_set_key(tfm, in_key, key_len);
}
-static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
- const u8 *in, unsigned int nbytes)
+static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
+ struct blkcipher_walk *walk)
{
- struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+ int ret = blkcipher_walk_virt(desc, walk);
+ unsigned int nbytes = walk->nbytes;
- /* only use complete blocks */
- nbytes &= ~(AES_BLOCK_SIZE - 1);
+ if (!nbytes)
+ goto out;
- memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
- switch (sctx->key_len) {
- case 16:
- ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
- break;
- case 24:
- ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
- break;
- case 32:
- ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
- break;
- }
- return nbytes;
+ memcpy(param, walk->iv, AES_BLOCK_SIZE);
+ do {
+ /* only use complete blocks */
+ unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
+ u8 *out = walk->dst.virt.addr;
+ u8 *in = walk->src.virt.addr;
+
+ ret = crypt_s390_kmc(func, param, out, in, n);
+ BUG_ON((ret < 0) || (ret != n));
+
+ nbytes &= AES_BLOCK_SIZE - 1;
+ ret = blkcipher_walk_done(desc, walk, nbytes);
+ } while ((nbytes = walk->nbytes));
+ memcpy(walk->iv, param, AES_BLOCK_SIZE);
+
+out:
+ return ret;
}
+static int cbc_aes_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
-static struct crypto_alg aes_alg = {
- .cra_name = "aes",
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
+}
+
+static int cbc_aes_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
+}
+
+static struct crypto_alg cbc_aes_alg = {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-s390",
+ .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_blocksize = AES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct s390_aes_ctx),
+ .cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
+ .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
.cra_u = {
- .cipher = {
- .cia_min_keysize = AES_MIN_KEY_SIZE,
- .cia_max_keysize = AES_MAX_KEY_SIZE,
- .cia_setkey = aes_set_key,
- .cia_encrypt = aes_encrypt,
- .cia_decrypt = aes_decrypt,
- .cia_encrypt_ecb = aes_encrypt_ecb,
- .cia_decrypt_ecb = aes_decrypt_ecb,
- .cia_encrypt_cbc = aes_encrypt_cbc,
- .cia_decrypt_cbc = aes_decrypt_cbc,
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = cbc_aes_set_key,
+ .encrypt = cbc_aes_encrypt,
+ .decrypt = cbc_aes_decrypt,
}
}
};
@@ -256,13 +332,40 @@ static int __init aes_init(void)
return -ENOSYS;
ret = crypto_register_alg(&aes_alg);
- if (ret != 0)
- printk(KERN_INFO "crypt_s390: aes_s390 couldn't be loaded.\n");
+ if (ret != 0) {
+ printk(KERN_INFO "crypt_s390: aes-s390 couldn't be loaded.\n");
+ goto aes_err;
+ }
+
+ ret = crypto_register_alg(&ecb_aes_alg);
+ if (ret != 0) {
+ printk(KERN_INFO
+ "crypt_s390: ecb-aes-s390 couldn't be loaded.\n");
+ goto ecb_aes_err;
+ }
+
+ ret = crypto_register_alg(&cbc_aes_alg);
+ if (ret != 0) {
+ printk(KERN_INFO
+ "crypt_s390: cbc-aes-s390 couldn't be loaded.\n");
+ goto cbc_aes_err;
+ }
+
+out:
return ret;
+
+cbc_aes_err:
+ crypto_unregister_alg(&ecb_aes_alg);
+ecb_aes_err:
+ crypto_unregister_alg(&aes_alg);
+aes_err:
+ goto out;
}
static void __exit aes_fini(void)
{
+ crypto_unregister_alg(&cbc_aes_alg);
+ crypto_unregister_alg(&ecb_aes_alg);
crypto_unregister_alg(&aes_alg);
}
diff --git a/trunk/arch/s390/crypto/crypt_s390.h b/trunk/arch/s390/crypto/crypt_s390.h
index d1c259a7fe33..efd836c2e4a6 100644
--- a/trunk/arch/s390/crypto/crypt_s390.h
+++ b/trunk/arch/s390/crypto/crypt_s390.h
@@ -20,6 +20,9 @@
#define CRYPT_S390_OP_MASK 0xFF00
#define CRYPT_S390_FUNC_MASK 0x00FF
+#define CRYPT_S390_PRIORITY 300
+#define CRYPT_S390_COMPOSITE_PRIORITY 400
+
/* s930 cryptographic operations */
enum crypt_s390_operations {
CRYPT_S390_KM = 0x0100,
diff --git a/trunk/arch/s390/crypto/des_s390.c b/trunk/arch/s390/crypto/des_s390.c
index b3f7496a79b4..2aba04852fe3 100644
--- a/trunk/arch/s390/crypto/des_s390.c
+++ b/trunk/arch/s390/crypto/des_s390.c
@@ -13,9 +13,10 @@
* (at your option) any later version.
*
*/
+
+#include
#include
#include
-#include
#include "crypt_s390.h"
#include "crypto_des.h"
@@ -45,9 +46,10 @@ struct crypt_s390_des3_192_ctx {
};
static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen, u32 *flags)
+ unsigned int keylen)
{
struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
+ u32 *flags = &tfm->crt_flags;
int ret;
/* test if key is valid (not a weak key) */
@@ -71,85 +73,159 @@ static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
}
-static unsigned int des_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
- const u8 *in, unsigned int nbytes)
+static struct crypto_alg des_alg = {
+ .cra_name = "des",
+ .cra_driver_name = "des-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES_KEY_SIZE,
+ .cia_max_keysize = DES_KEY_SIZE,
+ .cia_setkey = des_setkey,
+ .cia_encrypt = des_encrypt,
+ .cia_decrypt = des_decrypt,
+ }
+ }
+};
+
+static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
+ void *param, struct blkcipher_walk *walk)
{
- struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+ int ret = blkcipher_walk_virt(desc, walk);
+ unsigned int nbytes;
+
+ while ((nbytes = walk->nbytes)) {
+ /* only use complete blocks */
+ unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
+ u8 *out = walk->dst.virt.addr;
+ u8 *in = walk->src.virt.addr;
- /* only use complete blocks */
- nbytes &= ~(DES_BLOCK_SIZE - 1);
- ret = crypt_s390_km(KM_DEA_ENCRYPT, sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ ret = crypt_s390_km(func, param, out, in, n);
+ BUG_ON((ret < 0) || (ret != n));
- return nbytes;
+ nbytes &= DES_BLOCK_SIZE - 1;
+ ret = blkcipher_walk_done(desc, walk, nbytes);
+ }
+
+ return ret;
}
-static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
- const u8 *in, unsigned int nbytes)
+static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
+ void *param, struct blkcipher_walk *walk)
{
- struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+ int ret = blkcipher_walk_virt(desc, walk);
+ unsigned int nbytes = walk->nbytes;
+
+ if (!nbytes)
+ goto out;
+
+ memcpy(param, walk->iv, DES_BLOCK_SIZE);
+ do {
+ /* only use complete blocks */
+ unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
+ u8 *out = walk->dst.virt.addr;
+ u8 *in = walk->src.virt.addr;
- /* only use complete blocks */
- nbytes &= ~(DES_BLOCK_SIZE - 1);
- ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ ret = crypt_s390_kmc(func, param, out, in, n);
+ BUG_ON((ret < 0) || (ret != n));
- return nbytes;
+ nbytes &= DES_BLOCK_SIZE - 1;
+ ret = blkcipher_walk_done(desc, walk, nbytes);
+ } while ((nbytes = walk->nbytes));
+ memcpy(walk->iv, param, DES_BLOCK_SIZE);
+
+out:
+ return ret;
}
-static unsigned int des_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
- const u8 *in, unsigned int nbytes)
+static int ecb_des_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
{
- struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+ struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- /* only use complete blocks */
- nbytes &= ~(DES_BLOCK_SIZE - 1);
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, sctx->key, &walk);
+}
- memcpy(sctx->iv, desc->info, DES_BLOCK_SIZE);
- ret = crypt_s390_kmc(KMC_DEA_ENCRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+static int ecb_des_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- memcpy(desc->info, sctx->iv, DES_BLOCK_SIZE);
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_desall_crypt(desc, KM_DEA_DECRYPT, sctx->key, &walk);
}
-static unsigned int des_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
- const u8 *in, unsigned int nbytes)
+static struct crypto_alg ecb_des_alg = {
+ .cra_name = "ecb(des)",
+ .cra_driver_name = "ecb-des-s390",
+ .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = DES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ecb_des_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ .setkey = des_setkey,
+ .encrypt = ecb_des_encrypt,
+ .decrypt = ecb_des_decrypt,
+ }
+ }
+};
+
+static int cbc_des_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
{
- struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+ struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- /* only use complete blocks */
- nbytes &= ~(DES_BLOCK_SIZE - 1);
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, sctx->iv, &walk);
+}
- memcpy(&sctx->iv, desc->info, DES_BLOCK_SIZE);
- ret = crypt_s390_kmc(KMC_DEA_DECRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+static int cbc_des_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, sctx->iv, &walk);
}
-static struct crypto_alg des_alg = {
- .cra_name = "des",
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+static struct crypto_alg cbc_des_alg = {
+ .cra_name = "cbc(des)",
+ .cra_driver_name = "cbc-des-s390",
+ .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_blocksize = DES_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
+ .cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
+ .cra_list = LIST_HEAD_INIT(cbc_des_alg.cra_list),
.cra_u = {
- .cipher = {
- .cia_min_keysize = DES_KEY_SIZE,
- .cia_max_keysize = DES_KEY_SIZE,
- .cia_setkey = des_setkey,
- .cia_encrypt = des_encrypt,
- .cia_decrypt = des_decrypt,
- .cia_encrypt_ecb = des_encrypt_ecb,
- .cia_decrypt_ecb = des_decrypt_ecb,
- .cia_encrypt_cbc = des_encrypt_cbc,
- .cia_decrypt_cbc = des_decrypt_cbc,
+ .blkcipher = {
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ .ivsize = DES_BLOCK_SIZE,
+ .setkey = des_setkey,
+ .encrypt = cbc_des_encrypt,
+ .decrypt = cbc_des_decrypt,
}
}
};
@@ -167,11 +243,12 @@ static struct crypto_alg des_alg = {
*
*/
static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen, u32 *flags)
+ unsigned int keylen)
{
int i, ret;
struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm);
- const u8* temp_key = key;
+ const u8 *temp_key = key;
+ u32 *flags = &tfm->crt_flags;
if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
@@ -202,89 +279,111 @@ static void des3_128_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
DES3_128_BLOCK_SIZE);
}
-static unsigned int des3_128_encrypt_ecb(const struct cipher_desc *desc,
- u8 *out, const u8 *in,
- unsigned int nbytes)
-{
- struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+static struct crypto_alg des3_128_alg = {
+ .cra_name = "des3_ede128",
+ .cra_driver_name = "des3_ede128-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = DES3_128_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES3_128_KEY_SIZE,
+ .cia_max_keysize = DES3_128_KEY_SIZE,
+ .cia_setkey = des3_128_setkey,
+ .cia_encrypt = des3_128_encrypt,
+ .cia_decrypt = des3_128_decrypt,
+ }
+ }
+};
- /* only use complete blocks */
- nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
- ret = crypt_s390_km(KM_TDEA_128_ENCRYPT, sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+static int ecb_des3_128_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_desall_crypt(desc, KM_TDEA_128_ENCRYPT, sctx->key, &walk);
}
-static unsigned int des3_128_decrypt_ecb(const struct cipher_desc *desc,
- u8 *out, const u8 *in,
- unsigned int nbytes)
+static int ecb_des3_128_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
{
- struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+ struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- /* only use complete blocks */
- nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
- ret = crypt_s390_km(KM_TDEA_128_DECRYPT, sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
-
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_desall_crypt(desc, KM_TDEA_128_DECRYPT, sctx->key, &walk);
}
-static unsigned int des3_128_encrypt_cbc(const struct cipher_desc *desc,
- u8 *out, const u8 *in,
- unsigned int nbytes)
-{
- struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
-
- /* only use complete blocks */
- nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+static struct crypto_alg ecb_des3_128_alg = {
+ .cra_name = "ecb(des3_ede128)",
+ .cra_driver_name = "ecb-des3_ede128-s390",
+ .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = DES3_128_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(
+ ecb_des3_128_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = DES3_128_KEY_SIZE,
+ .max_keysize = DES3_128_KEY_SIZE,
+ .setkey = des3_128_setkey,
+ .encrypt = ecb_des3_128_encrypt,
+ .decrypt = ecb_des3_128_decrypt,
+ }
+ }
+};
- memcpy(sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
- ret = crypt_s390_kmc(KMC_TDEA_128_ENCRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+static int cbc_des3_128_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- memcpy(desc->info, sctx->iv, DES3_128_BLOCK_SIZE);
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return cbc_desall_crypt(desc, KMC_TDEA_128_ENCRYPT, sctx->iv, &walk);
}
-static unsigned int des3_128_decrypt_cbc(const struct cipher_desc *desc,
- u8 *out, const u8 *in,
- unsigned int nbytes)
+static int cbc_des3_128_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
{
- struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
-
- /* only use complete blocks */
- nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
-
- memcpy(&sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
- ret = crypt_s390_kmc(KMC_TDEA_128_DECRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return cbc_desall_crypt(desc, KMC_TDEA_128_DECRYPT, sctx->iv, &walk);
}
-static struct crypto_alg des3_128_alg = {
- .cra_name = "des3_ede128",
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+static struct crypto_alg cbc_des3_128_alg = {
+ .cra_name = "cbc(des3_ede128)",
+ .cra_driver_name = "cbc-des3_ede128-s390",
+ .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_blocksize = DES3_128_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
+ .cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list),
+ .cra_list = LIST_HEAD_INIT(
+ cbc_des3_128_alg.cra_list),
.cra_u = {
- .cipher = {
- .cia_min_keysize = DES3_128_KEY_SIZE,
- .cia_max_keysize = DES3_128_KEY_SIZE,
- .cia_setkey = des3_128_setkey,
- .cia_encrypt = des3_128_encrypt,
- .cia_decrypt = des3_128_decrypt,
- .cia_encrypt_ecb = des3_128_encrypt_ecb,
- .cia_decrypt_ecb = des3_128_decrypt_ecb,
- .cia_encrypt_cbc = des3_128_encrypt_cbc,
- .cia_decrypt_cbc = des3_128_decrypt_cbc,
+ .blkcipher = {
+ .min_keysize = DES3_128_KEY_SIZE,
+ .max_keysize = DES3_128_KEY_SIZE,
+ .ivsize = DES3_128_BLOCK_SIZE,
+ .setkey = des3_128_setkey,
+ .encrypt = cbc_des3_128_encrypt,
+ .decrypt = cbc_des3_128_decrypt,
}
}
};
@@ -303,11 +402,12 @@ static struct crypto_alg des3_128_alg = {
*
*/
static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen, u32 *flags)
+ unsigned int keylen)
{
int i, ret;
struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
- const u8* temp_key = key;
+ const u8 *temp_key = key;
+ u32 *flags = &tfm->crt_flags;
if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
@@ -341,89 +441,111 @@ static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
DES3_192_BLOCK_SIZE);
}
-static unsigned int des3_192_encrypt_ecb(const struct cipher_desc *desc,
- u8 *out, const u8 *in,
- unsigned int nbytes)
-{
- struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+static struct crypto_alg des3_192_alg = {
+ .cra_name = "des3_ede",
+ .cra_driver_name = "des3_ede-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = DES3_192_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES3_192_KEY_SIZE,
+ .cia_max_keysize = DES3_192_KEY_SIZE,
+ .cia_setkey = des3_192_setkey,
+ .cia_encrypt = des3_192_encrypt,
+ .cia_decrypt = des3_192_decrypt,
+ }
+ }
+};
- /* only use complete blocks */
- nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
- ret = crypt_s390_km(KM_TDEA_192_ENCRYPT, sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, sctx->key, &walk);
}
-static unsigned int des3_192_decrypt_ecb(const struct cipher_desc *desc,
- u8 *out, const u8 *in,
- unsigned int nbytes)
+static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
{
- struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
-
- /* only use complete blocks */
- nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
- ret = crypt_s390_km(KM_TDEA_192_DECRYPT, sctx->key, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+ struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, sctx->key, &walk);
}
-static unsigned int des3_192_encrypt_cbc(const struct cipher_desc *desc,
- u8 *out, const u8 *in,
- unsigned int nbytes)
-{
- struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
-
- /* only use complete blocks */
- nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+static struct crypto_alg ecb_des3_192_alg = {
+ .cra_name = "ecb(des3_ede)",
+ .cra_driver_name = "ecb-des3_ede-s390",
+ .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = DES3_192_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(
+ ecb_des3_192_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = DES3_192_KEY_SIZE,
+ .max_keysize = DES3_192_KEY_SIZE,
+ .setkey = des3_192_setkey,
+ .encrypt = ecb_des3_192_encrypt,
+ .decrypt = ecb_des3_192_decrypt,
+ }
+ }
+};
- memcpy(sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
- ret = crypt_s390_kmc(KMC_TDEA_192_ENCRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
+static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- memcpy(desc->info, sctx->iv, DES3_192_BLOCK_SIZE);
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, sctx->iv, &walk);
}
-static unsigned int des3_192_decrypt_cbc(const struct cipher_desc *desc,
- u8 *out, const u8 *in,
- unsigned int nbytes)
+static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst,
+ struct scatterlist *src, unsigned int nbytes)
{
- struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
- int ret;
+ struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ struct blkcipher_walk walk;
- /* only use complete blocks */
- nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
-
- memcpy(&sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
- ret = crypt_s390_kmc(KMC_TDEA_192_DECRYPT, &sctx->iv, out, in, nbytes);
- BUG_ON((ret < 0) || (ret != nbytes));
-
- return nbytes;
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, sctx->iv, &walk);
}
-static struct crypto_alg des3_192_alg = {
- .cra_name = "des3_ede",
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+static struct crypto_alg cbc_des3_192_alg = {
+ .cra_name = "cbc(des3_ede)",
+ .cra_driver_name = "cbc-des3_ede-s390",
+ .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
.cra_blocksize = DES3_192_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
+ .cra_type = &crypto_blkcipher_type,
.cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list),
+ .cra_list = LIST_HEAD_INIT(
+ cbc_des3_192_alg.cra_list),
.cra_u = {
- .cipher = {
- .cia_min_keysize = DES3_192_KEY_SIZE,
- .cia_max_keysize = DES3_192_KEY_SIZE,
- .cia_setkey = des3_192_setkey,
- .cia_encrypt = des3_192_encrypt,
- .cia_decrypt = des3_192_decrypt,
- .cia_encrypt_ecb = des3_192_encrypt_ecb,
- .cia_decrypt_ecb = des3_192_decrypt_ecb,
- .cia_encrypt_cbc = des3_192_encrypt_cbc,
- .cia_decrypt_cbc = des3_192_decrypt_cbc,
+ .blkcipher = {
+ .min_keysize = DES3_192_KEY_SIZE,
+ .max_keysize = DES3_192_KEY_SIZE,
+ .ivsize = DES3_192_BLOCK_SIZE,
+ .setkey = des3_192_setkey,
+ .encrypt = cbc_des3_192_encrypt,
+ .decrypt = cbc_des3_192_decrypt,
}
}
};
@@ -437,22 +559,69 @@ static int init(void)
!crypt_s390_func_available(KM_TDEA_192_ENCRYPT))
return -ENOSYS;
- ret |= (crypto_register_alg(&des_alg) == 0) ? 0:1;
- ret |= (crypto_register_alg(&des3_128_alg) == 0) ? 0:2;
- ret |= (crypto_register_alg(&des3_192_alg) == 0) ? 0:4;
- if (ret) {
- crypto_unregister_alg(&des3_192_alg);
- crypto_unregister_alg(&des3_128_alg);
- crypto_unregister_alg(&des_alg);
- return -EEXIST;
- }
- return 0;
+ ret = crypto_register_alg(&des_alg);
+ if (ret)
+ goto des_err;
+ ret = crypto_register_alg(&ecb_des_alg);
+ if (ret)
+ goto ecb_des_err;
+ ret = crypto_register_alg(&cbc_des_alg);
+ if (ret)
+ goto cbc_des_err;
+
+ ret = crypto_register_alg(&des3_128_alg);
+ if (ret)
+ goto des3_128_err;
+ ret = crypto_register_alg(&ecb_des3_128_alg);
+ if (ret)
+ goto ecb_des3_128_err;
+ ret = crypto_register_alg(&cbc_des3_128_alg);
+ if (ret)
+ goto cbc_des3_128_err;
+
+ ret = crypto_register_alg(&des3_192_alg);
+ if (ret)
+ goto des3_192_err;
+ ret = crypto_register_alg(&ecb_des3_192_alg);
+ if (ret)
+ goto ecb_des3_192_err;
+ ret = crypto_register_alg(&cbc_des3_192_alg);
+ if (ret)
+ goto cbc_des3_192_err;
+
+out:
+ return ret;
+
+cbc_des3_192_err:
+ crypto_unregister_alg(&ecb_des3_192_alg);
+ecb_des3_192_err:
+ crypto_unregister_alg(&des3_192_alg);
+des3_192_err:
+ crypto_unregister_alg(&cbc_des3_128_alg);
+cbc_des3_128_err:
+ crypto_unregister_alg(&ecb_des3_128_alg);
+ecb_des3_128_err:
+ crypto_unregister_alg(&des3_128_alg);
+des3_128_err:
+ crypto_unregister_alg(&cbc_des_alg);
+cbc_des_err:
+ crypto_unregister_alg(&ecb_des_alg);
+ecb_des_err:
+ crypto_unregister_alg(&des_alg);
+des_err:
+ goto out;
}
static void __exit fini(void)
{
+ crypto_unregister_alg(&cbc_des3_192_alg);
+ crypto_unregister_alg(&ecb_des3_192_alg);
crypto_unregister_alg(&des3_192_alg);
+ crypto_unregister_alg(&cbc_des3_128_alg);
+ crypto_unregister_alg(&ecb_des3_128_alg);
crypto_unregister_alg(&des3_128_alg);
+ crypto_unregister_alg(&cbc_des_alg);
+ crypto_unregister_alg(&ecb_des_alg);
crypto_unregister_alg(&des_alg);
}
diff --git a/trunk/arch/s390/crypto/sha1_s390.c b/trunk/arch/s390/crypto/sha1_s390.c
index 9d34a35b1aa5..49ca8690ee39 100644
--- a/trunk/arch/s390/crypto/sha1_s390.c
+++ b/trunk/arch/s390/crypto/sha1_s390.c
@@ -126,6 +126,8 @@ static void sha1_final(struct crypto_tfm *tfm, u8 *out)
static struct crypto_alg alg = {
.cra_name = "sha1",
+ .cra_driver_name = "sha1-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = SHA1_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct crypt_s390_sha1_ctx),
diff --git a/trunk/arch/s390/crypto/sha256_s390.c b/trunk/arch/s390/crypto/sha256_s390.c
index f573df30f31d..8e4e67503fe7 100644
--- a/trunk/arch/s390/crypto/sha256_s390.c
+++ b/trunk/arch/s390/crypto/sha256_s390.c
@@ -127,6 +127,8 @@ static void sha256_final(struct crypto_tfm *tfm, u8 *out)
static struct crypto_alg alg = {
.cra_name = "sha256",
+ .cra_driver_name = "sha256-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
.cra_flags = CRYPTO_ALG_TYPE_DIGEST,
.cra_blocksize = SHA256_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct s390_sha256_ctx),
diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig
index f1d4591eddbb..35da53986b1b 100644
--- a/trunk/arch/s390/defconfig
+++ b/trunk/arch/s390/defconfig
@@ -428,6 +428,7 @@ CONFIG_S390_TAPE_34XX=m
# CONFIG_VMLOGRDR is not set
# CONFIG_VMCP is not set
# CONFIG_MONREADER is not set
+CONFIG_MONWRITER=m
#
# Cryptographic devices
diff --git a/trunk/arch/s390/hypfs/hypfs.h b/trunk/arch/s390/hypfs/hypfs.h
index ea5567be00fc..f3dbd91965c6 100644
--- a/trunk/arch/s390/hypfs/hypfs.h
+++ b/trunk/arch/s390/hypfs/hypfs.h
@@ -1,5 +1,5 @@
/*
- * fs/hypfs/hypfs.h
+ * arch/s390/hypfs/hypfs.h
* Hypervisor filesystem for Linux on s390.
*
* Copyright (C) IBM Corp. 2006
diff --git a/trunk/arch/s390/hypfs/hypfs_diag.c b/trunk/arch/s390/hypfs/hypfs_diag.c
index 1785bce2b919..75144efbb92b 100644
--- a/trunk/arch/s390/hypfs/hypfs_diag.c
+++ b/trunk/arch/s390/hypfs/hypfs_diag.c
@@ -1,5 +1,5 @@
/*
- * fs/hypfs/hypfs_diag.c
+ * arch/s390/hypfs/hypfs_diag.c
* Hypervisor filesystem for Linux on s390. Diag 204 and 224
* implementation.
*
@@ -432,12 +432,14 @@ static int diag204_probe(void)
buf = diag204_get_buffer(INFO_EXT, &pages);
if (!IS_ERR(buf)) {
- if (diag204(SUBC_STIB7 | INFO_EXT, pages, buf) >= 0) {
+ if (diag204((unsigned long)SUBC_STIB7 |
+ (unsigned long)INFO_EXT, pages, buf) >= 0) {
diag204_store_sc = SUBC_STIB7;
diag204_info_type = INFO_EXT;
goto out;
}
- if (diag204(SUBC_STIB6 | INFO_EXT, pages, buf) >= 0) {
+ if (diag204((unsigned long)SUBC_STIB6 |
+ (unsigned long)INFO_EXT, pages, buf) >= 0) {
diag204_store_sc = SUBC_STIB7;
diag204_info_type = INFO_EXT;
goto out;
@@ -452,7 +454,8 @@ static int diag204_probe(void)
rc = PTR_ERR(buf);
goto fail_alloc;
}
- if (diag204(SUBC_STIB4 | INFO_SIMPLE, pages, buf) >= 0) {
+ if (diag204((unsigned long)SUBC_STIB4 |
+ (unsigned long)INFO_SIMPLE, pages, buf) >= 0) {
diag204_store_sc = SUBC_STIB4;
diag204_info_type = INFO_SIMPLE;
goto out;
@@ -476,7 +479,8 @@ static void *diag204_store(void)
buf = diag204_get_buffer(diag204_info_type, &pages);
if (IS_ERR(buf))
goto out;
- if (diag204(diag204_store_sc | diag204_info_type, pages, buf) < 0)
+ if (diag204((unsigned long)diag204_store_sc |
+ (unsigned long)diag204_info_type, pages, buf) < 0)
return ERR_PTR(-ENOSYS);
out:
return buf;
@@ -531,7 +535,7 @@ __init int hypfs_diag_init(void)
return rc;
}
-__exit void hypfs_diag_exit(void)
+void hypfs_diag_exit(void)
{
diag224_delete_name_table();
diag204_free_buffer();
diff --git a/trunk/arch/s390/hypfs/hypfs_diag.h b/trunk/arch/s390/hypfs/hypfs_diag.h
index 793dea6b9bb6..256b384aebe1 100644
--- a/trunk/arch/s390/hypfs/hypfs_diag.h
+++ b/trunk/arch/s390/hypfs/hypfs_diag.h
@@ -1,5 +1,5 @@
/*
- * fs/hypfs/hypfs_diag.h
+ * arch/s390/hypfs_diag.h
* Hypervisor filesystem for Linux on s390.
*
* Copyright (C) IBM Corp. 2006
diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c
index 18c091925ea5..bdade5f2e325 100644
--- a/trunk/arch/s390/hypfs/inode.c
+++ b/trunk/arch/s390/hypfs/inode.c
@@ -1,5 +1,5 @@
/*
- * fs/hypfs/inode.c
+ * arch/s390/hypfs/inode.c
* Hypervisor filesystem for Linux on s390.
*
* Copyright (C) IBM Corp. 2006
@@ -312,10 +312,12 @@ static void hypfs_kill_super(struct super_block *sb)
{
struct hypfs_sb_info *sb_info = sb->s_fs_info;
- hypfs_delete_tree(sb->s_root);
- hypfs_remove(sb_info->update_file);
- kfree(sb->s_fs_info);
- sb->s_fs_info = NULL;
+ if (sb->s_root) {
+ hypfs_delete_tree(sb->s_root);
+ hypfs_remove(sb_info->update_file);
+ kfree(sb->s_fs_info);
+ sb->s_fs_info = NULL;
+ }
kill_litter_super(sb);
}
diff --git a/trunk/arch/s390/kernel/Makefile b/trunk/arch/s390/kernel/Makefile
index 9a33ed6ca696..aa978978d3d1 100644
--- a/trunk/arch/s390/kernel/Makefile
+++ b/trunk/arch/s390/kernel/Makefile
@@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional
obj-y := bitmap.o traps.o time.o process.o \
setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
- semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o
+ semaphore.o s390_ext.o debug.o profile.o irq.o ipl.o
obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
@@ -24,6 +24,7 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \
obj-$(CONFIG_VIRT_TIMER) += vtime.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
+obj-$(CONFIG_KPROBES) += kprobes.o
# Kexec part
S390_KEXEC_OBJS := machine_kexec.o crash.o
diff --git a/trunk/arch/s390/kernel/entry.S b/trunk/arch/s390/kernel/entry.S
index 5b5799ac8f83..0c712b78a7e8 100644
--- a/trunk/arch/s390/kernel/entry.S
+++ b/trunk/arch/s390/kernel/entry.S
@@ -505,6 +505,8 @@ pgm_no_vtime2:
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+ tm SP_PSW+1(%r15),0x01 # kernel per event ?
+ bz BASED(kernel_per)
l %r3,__LC_PGM_ILC # load program interruption code
la %r8,0x7f
nr %r8,%r3 # clear per-event-bit and ilc
@@ -536,6 +538,16 @@ pgm_no_vtime3:
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
b BASED(sysc_do_svc)
+#
+# per was called from kernel, must be kprobes
+#
+kernel_per:
+ mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
+ la %r2,SP_PTREGS(%r15) # address of register-save area
+ l %r1,BASED(.Lhandle_per) # load adr. of per handler
+ la %r14,BASED(sysc_leave) # load adr. of system return
+ br %r1 # branch to do_single_step
+
/*
* IO interrupt handler routine
*/
diff --git a/trunk/arch/s390/kernel/entry64.S b/trunk/arch/s390/kernel/entry64.S
index 56f5f613b868..29bbfbab7332 100644
--- a/trunk/arch/s390/kernel/entry64.S
+++ b/trunk/arch/s390/kernel/entry64.S
@@ -518,6 +518,8 @@ pgm_no_vtime2:
#endif
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
lg %r1,__TI_task(%r9)
+ tm SP_PSW+1(%r15),0x01 # kernel per event ?
+ jz kernel_per
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
@@ -553,6 +555,16 @@ pgm_no_vtime3:
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
j sysc_do_svc
+#
+# per was called from kernel, must be kprobes
+#
+kernel_per:
+ lhi %r0,__LC_PGM_OLD_PSW
+ sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
+ la %r2,SP_PTREGS(%r15) # address of register-save area
+ larl %r14,sysc_leave # load adr. of system ret, no work
+ jg do_single_step # branch to do_single_step
+
/*
* IO interrupt handler routine
*/
@@ -815,7 +827,7 @@ restart_go:
*/
stack_overflow:
lg %r15,__LC_PANIC_STACK # change to panic stack
- aghi %r1,-SP_SIZE
+ aghi %r15,-SP_SIZE
mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
la %r1,__LC_SAVE_AREA
@@ -823,7 +835,7 @@ stack_overflow:
je 0f
chi %r12,__LC_PGM_OLD_PSW
je 0f
- la %r1,__LC_SAVE_AREA+16
+ la %r1,__LC_SAVE_AREA+32
0: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
la %r2,SP_PTREGS(%r15) # load pt_regs
diff --git a/trunk/arch/s390/kernel/head.S b/trunk/arch/s390/kernel/head.S
index adad8863ee2f..0f1db268a8a9 100644
--- a/trunk/arch/s390/kernel/head.S
+++ b/trunk/arch/s390/kernel/head.S
@@ -272,7 +272,7 @@ iplstart:
# load parameter file from ipl device
#
.Lagain1:
- l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp
+ l %r2,.Linitrd # ramdisk loc. is temp
bas %r14,.Lloader # load parameter file
ltr %r2,%r2 # got anything ?
bz .Lnopf
@@ -280,7 +280,7 @@ iplstart:
bnh .Lnotrunc
la %r2,895
.Lnotrunc:
- l %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
+ l %r4,.Linitrd
clc 0(3,%r4),.L_hdr # if it is HDRx
bz .Lagain1 # skip dataset header
clc 0(3,%r4),.L_eof # if it is EOFx
@@ -323,14 +323,15 @@ iplstart:
# load ramdisk from ipl device
#
.Lagain2:
- l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk
+ l %r2,.Linitrd # addr of ramdisk
+ st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
bas %r14,.Lloader # load ramdisk
st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
ltr %r2,%r2
bnz .Lrdcont
st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
.Lrdcont:
- l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
+ l %r2,.Linitrd
clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
bz .Lagain2
@@ -379,6 +380,7 @@ iplstart:
l %r1,.Lstartup
br %r1
+.Linitrd:.long _end + 0x400000 # default address of initrd
.Lparm: .long PARMAREA
.Lstartup: .long startup
.Lcvtab:.long _ebcasc # ebcdic to ascii table
@@ -479,65 +481,6 @@ start:
.byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
.byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
-.macro GET_IPL_DEVICE
-.Lget_ipl_device:
- l %r1,0xb8 # get sid
- sll %r1,15 # test if subchannel is enabled
- srl %r1,31
- ltr %r1,%r1
- bz 2f-.LPG1(%r13) # subchannel disabled
- l %r1,0xb8
- la %r5,.Lipl_schib-.LPG1(%r13)
- stsch 0(%r5) # get schib of subchannel
- bnz 2f-.LPG1(%r13) # schib not available
- tm 5(%r5),0x01 # devno valid?
- bno 2f-.LPG1(%r13)
- la %r6,ipl_parameter_flags-.LPG1(%r13)
- oi 3(%r6),0x01 # set flag
- la %r2,ipl_devno-.LPG1(%r13)
- mvc 0(2,%r2),6(%r5) # store devno
- tm 4(%r5),0x80 # qdio capable device?
- bno 2f-.LPG1(%r13)
- oi 3(%r6),0x02 # set flag
-
- # copy ipl parameters
-
- lhi %r0,4096
- l %r2,20(%r0) # get address of parameter list
- lhi %r3,IPL_PARMBLOCK_ORIGIN
- st %r3,20(%r0)
- lhi %r4,1
- cr %r2,%r3 # start parameters < destination ?
- jl 0f
- lhi %r1,1 # copy direction is upwards
- j 1f
-0: lhi %r1,-1 # copy direction is downwards
- ar %r2,%r0
- ar %r3,%r0
- ar %r2,%r1
- ar %r3,%r1
-1: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
- ar %r3,%r1
- ar %r2,%r1
- sr %r0,%r4
- jne 1b
- b 2f-.LPG1(%r13)
-
- .align 4
-.Lipl_schib:
- .rept 13
- .long 0
- .endr
-
- .globl ipl_parameter_flags
-ipl_parameter_flags:
- .long 0
- .globl ipl_devno
-ipl_devno:
- .word 0
-2:
-.endm
-
#ifdef CONFIG_64BIT
#include "head64.S"
#else
diff --git a/trunk/arch/s390/kernel/head31.S b/trunk/arch/s390/kernel/head31.S
index a4dc61f3285e..1fa9fa1ca740 100644
--- a/trunk/arch/s390/kernel/head31.S
+++ b/trunk/arch/s390/kernel/head31.S
@@ -26,8 +26,8 @@ startup:basr %r13,0 # get base
#
.org PARMAREA
.long 0,0 # IPL_DEVICE
- .long 0,RAMDISK_ORIGIN # INITRD_START
- .long 0,RAMDISK_SIZE # INITRD_SIZE
+ .long 0,0 # INITRD_START
+ .long 0,0 # INITRD_SIZE
.org COMMAND_LINE
.byte "root=/dev/ram0 ro"
@@ -37,12 +37,23 @@ startup:basr %r13,0 # get base
startup_continue:
basr %r13,0 # get base
-.LPG1: GET_IPL_DEVICE
+.LPG1: mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
# move IPL device to lowcore
mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
+#
+# Setup stack
+#
+ l %r15,.Linittu-.LPG1(%r13)
+ mvc __LC_CURRENT(4),__TI_task(%r15)
+ ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
+ st %r15,__LC_KERNEL_STACK # set end of kernel stack
+ ahi %r15,-96
+ xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
+ l %r14,.Lipl_save_parameters-.LPG1(%r13)
+ basr %r14,%r14
#
# clear bss memory
#
@@ -114,6 +125,10 @@ startup_continue:
b .Lfchunk-.LPG1(%r13)
.align 4
+.Lipl_save_parameters:
+ .long ipl_save_parameters
+.Linittu:
+ .long init_thread_union
.Lpmask:
.byte 0
.align 8
@@ -273,7 +288,23 @@ startup_continue:
.Lbss_end: .long _end
.Lparmaddr: .long PARMAREA
.Lsccbaddr: .long .Lsccb
+
+ .globl ipl_schib
+ipl_schib:
+ .rept 13
+ .long 0
+ .endr
+
+ .globl ipl_flags
+ipl_flags:
+ .long 0
+ .globl ipl_devno
+ipl_devno:
+ .word 0
+
.org 0x12000
+.globl s390_readinfo_sccb
+s390_readinfo_sccb:
.Lsccb:
.hword 0x1000 # length, one page
.byte 0x00,0x00,0x00
@@ -302,16 +333,6 @@ startup_continue:
.globl _stext
_stext: basr %r13,0 # get base
.LPG3:
-#
-# Setup stack
-#
- l %r15,.Linittu-.LPG3(%r13)
- mvc __LC_CURRENT(4),__TI_task(%r15)
- ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
- st %r15,__LC_KERNEL_STACK # set end of kernel stack
- ahi %r15,-96
- xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
-
# check control registers
stctl %c0,%c15,0(%r15)
oi 2(%r15),0x40 # enable sigp emergency signal
@@ -330,6 +351,5 @@ _stext: basr %r13,0 # get base
#
.align 8
.Ldw: .long 0x000a0000,0x00000000
-.Linittu:.long init_thread_union
.Lstart:.long start_kernel
.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/trunk/arch/s390/kernel/head64.S b/trunk/arch/s390/kernel/head64.S
index 9d80c5b1ef95..a8bdd96494c7 100644
--- a/trunk/arch/s390/kernel/head64.S
+++ b/trunk/arch/s390/kernel/head64.S
@@ -26,8 +26,8 @@ startup:basr %r13,0 # get base
#
.org PARMAREA
.quad 0 # IPL_DEVICE
- .quad RAMDISK_ORIGIN # INITRD_START
- .quad RAMDISK_SIZE # INITRD_SIZE
+ .quad 0 # INITRD_START
+ .quad 0 # INITRD_SIZE
.org COMMAND_LINE
.byte "root=/dev/ram0 ro"
@@ -39,8 +39,8 @@ startup_continue:
basr %r13,0 # get base
.LPG1: sll %r13,1 # remove high order bit
srl %r13,1
- GET_IPL_DEVICE
lhi %r1,1 # mode 1 = esame
+ mvi __LC_AR_MODE_ID,1 # set esame flag
slr %r0,%r0 # set cpuid to zero
sigp %r1,%r0,0x12 # switch to esame mode
sam64 # switch to 64 bit mode
@@ -48,7 +48,18 @@ startup_continue:
lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area
# move IPL device to lowcore
mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
+#
+# Setup stack
+#
+ larl %r15,init_thread_union
+ lg %r14,__TI_task(%r15) # cache current in lowcore
+ stg %r14,__LC_CURRENT
+ aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
+ stg %r15,__LC_KERNEL_STACK # set end of kernel stack
+ aghi %r15,-160
+ xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
+ brasl %r14,ipl_save_parameters
#
# clear bss memory
#
@@ -239,6 +250,19 @@ startup_continue:
oi 7(%r12),0x80 # set IDTE flag
0:
+#
+# find out if we have the MVCOS instruction
+#
+ la %r1,0f-.LPG1(%r13) # set program check address
+ stg %r1,__LC_PGM_NEW_PSW+8
+ .short 0xc800 # mvcos 0(%r0),0(%r0),%r0
+ .short 0x0000
+ .short 0x0000
+0: tm 0x8f,0x13 # special-operation exception?
+ bno 1f-.LPG1(%r13) # if yes, MVCOS is present
+ oi 6(%r12),2 # set MVCOS flag
+1:
+
lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space,
# virtual and never return ...
.align 16
@@ -268,7 +292,22 @@ startup_continue:
.Lparmaddr:
.quad PARMAREA
+ .globl ipl_schib
+ipl_schib:
+ .rept 13
+ .long 0
+ .endr
+
+ .globl ipl_flags
+ipl_flags:
+ .long 0
+ .globl ipl_devno
+ipl_devno:
+ .word 0
+
.org 0x12000
+.globl s390_readinfo_sccb
+s390_readinfo_sccb:
.Lsccb:
.hword 0x1000 # length, one page
.byte 0x00,0x00,0x00
@@ -297,24 +336,12 @@ startup_continue:
.globl _stext
_stext: basr %r13,0 # get base
.LPG3:
-#
-# Setup stack
-#
- larl %r15,init_thread_union
- lg %r14,__TI_task(%r15) # cache current in lowcore
- stg %r14,__LC_CURRENT
- aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
- stg %r15,__LC_KERNEL_STACK # set end of kernel stack
- aghi %r15,-160
- xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
-
# check control registers
stctg %c0,%c15,0(%r15)
oi 6(%r15),0x40 # enable sigp emergency signal
oi 4(%r15),0x10 # switch on low address proctection
lctlg %c0,%c15,0(%r15)
-#
lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
brasl %r14,start_kernel # go to C code
#
@@ -322,7 +349,7 @@ _stext: basr %r13,0 # get base
#
basr %r13,0
lpswe .Ldw-.(%r13) # load disabled wait psw
-#
+
.align 8
.Ldw: .quad 0x0002000180000000,0x0000000000000000
.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/trunk/arch/s390/kernel/ipl.c b/trunk/arch/s390/kernel/ipl.c
new file mode 100644
index 000000000000..6555cc48e28f
--- /dev/null
+++ b/trunk/arch/s390/kernel/ipl.c
@@ -0,0 +1,942 @@
+/*
+ * arch/s390/kernel/ipl.c
+ * ipl/reipl/dump support for Linux on s390.
+ *
+ * Copyright (C) IBM Corp. 2005,2006
+ * Author(s): Michael Holzheu
+ * Heiko Carstens
+ * Volker Sameske
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define IPL_PARM_BLOCK_VERSION 0
+
+enum ipl_type {
+ IPL_TYPE_NONE = 1,
+ IPL_TYPE_UNKNOWN = 2,
+ IPL_TYPE_CCW = 4,
+ IPL_TYPE_FCP = 8,
+};
+
+#define IPL_NONE_STR "none"
+#define IPL_UNKNOWN_STR "unknown"
+#define IPL_CCW_STR "ccw"
+#define IPL_FCP_STR "fcp"
+
+static char *ipl_type_str(enum ipl_type type)
+{
+ switch (type) {
+ case IPL_TYPE_NONE:
+ return IPL_NONE_STR;
+ case IPL_TYPE_CCW:
+ return IPL_CCW_STR;
+ case IPL_TYPE_FCP:
+ return IPL_FCP_STR;
+ case IPL_TYPE_UNKNOWN:
+ default:
+ return IPL_UNKNOWN_STR;
+ }
+}
+
+enum ipl_method {
+ IPL_METHOD_NONE,
+ IPL_METHOD_CCW_CIO,
+ IPL_METHOD_CCW_DIAG,
+ IPL_METHOD_CCW_VM,
+ IPL_METHOD_FCP_RO_DIAG,
+ IPL_METHOD_FCP_RW_DIAG,
+ IPL_METHOD_FCP_RO_VM,
+};
+
+enum shutdown_action {
+ SHUTDOWN_REIPL,
+ SHUTDOWN_DUMP,
+ SHUTDOWN_STOP,
+};
+
+#define SHUTDOWN_REIPL_STR "reipl"
+#define SHUTDOWN_DUMP_STR "dump"
+#define SHUTDOWN_STOP_STR "stop"
+
+static char *shutdown_action_str(enum shutdown_action action)
+{
+ switch (action) {
+ case SHUTDOWN_REIPL:
+ return SHUTDOWN_REIPL_STR;
+ case SHUTDOWN_DUMP:
+ return SHUTDOWN_DUMP_STR;
+ case SHUTDOWN_STOP:
+ return SHUTDOWN_STOP_STR;
+ default:
+ BUG();
+ }
+}
+
+enum diag308_subcode {
+ DIAG308_IPL = 3,
+ DIAG308_DUMP = 4,
+ DIAG308_SET = 5,
+ DIAG308_STORE = 6,
+};
+
+enum diag308_ipl_type {
+ DIAG308_IPL_TYPE_FCP = 0,
+ DIAG308_IPL_TYPE_CCW = 2,
+};
+
+enum diag308_opt {
+ DIAG308_IPL_OPT_IPL = 0x10,
+ DIAG308_IPL_OPT_DUMP = 0x20,
+};
+
+enum diag308_rc {
+ DIAG308_RC_OK = 1,
+};
+
+static int diag308_set_works = 0;
+
+static int reipl_capabilities = IPL_TYPE_UNKNOWN;
+static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
+static enum ipl_method reipl_method = IPL_METHOD_NONE;
+static struct ipl_parameter_block *reipl_block_fcp;
+static struct ipl_parameter_block *reipl_block_ccw;
+
+static int dump_capabilities = IPL_TYPE_NONE;
+static enum ipl_type dump_type = IPL_TYPE_NONE;
+static enum ipl_method dump_method = IPL_METHOD_NONE;
+static struct ipl_parameter_block *dump_block_fcp;
+static struct ipl_parameter_block *dump_block_ccw;
+
+static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
+
+static int diag308(unsigned long subcode, void *addr)
+{
+ register unsigned long _addr asm("0") = (unsigned long)addr;
+ register unsigned long _rc asm("1") = 0;
+
+ asm volatile (
+ " diag %0,%2,0x308\n"
+ "0: \n"
+ ".section __ex_table,\"a\"\n"
+#ifdef CONFIG_64BIT
+ " .align 8\n"
+ " .quad 0b, 0b\n"
+#else
+ " .align 4\n"
+ " .long 0b, 0b\n"
+#endif
+ ".previous\n"
+ : "+d" (_addr), "+d" (_rc)
+ : "d" (subcode) : "cc", "memory" );
+
+ return _rc;
+}
+
+/* SYSFS */
+
+#define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \
+static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
+ char *page) \
+{ \
+ return sprintf(page, _format, _value); \
+} \
+static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
+ __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL);
+
+#define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \
+static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
+ char *page) \
+{ \
+ return sprintf(page, _fmt_out, \
+ (unsigned long long) _value); \
+} \
+static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\
+ const char *buf, size_t len) \
+{ \
+ unsigned long long value; \
+ if (sscanf(buf, _fmt_in, &value) != 1) \
+ return -EINVAL; \
+ _value = value; \
+ return len; \
+} \
+static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
+ __ATTR(_name,(S_IRUGO | S_IWUSR), \
+ sys_##_prefix##_##_name##_show, \
+ sys_##_prefix##_##_name##_store);
+
+static void make_attrs_ro(struct attribute **attrs)
+{
+ while (*attrs) {
+ (*attrs)->mode = S_IRUGO;
+ attrs++;
+ }
+}
+
+/*
+ * ipl section
+ */
+
+static enum ipl_type ipl_get_type(void)
+{
+ struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
+
+ if (!(ipl_flags & IPL_DEVNO_VALID))
+ return IPL_TYPE_UNKNOWN;
+ if (!(ipl_flags & IPL_PARMBLOCK_VALID))
+ return IPL_TYPE_CCW;
+ if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION)
+ return IPL_TYPE_UNKNOWN;
+ if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP)
+ return IPL_TYPE_UNKNOWN;
+ return IPL_TYPE_FCP;
+}
+
+static ssize_t ipl_type_show(struct subsystem *subsys, char *page)
+{
+ return sprintf(page, "%s\n", ipl_type_str(ipl_get_type()));
+}
+
+static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
+
+static ssize_t sys_ipl_device_show(struct subsystem *subsys, char *page)
+{
+ struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
+
+ switch (ipl_get_type()) {
+ case IPL_TYPE_CCW:
+ return sprintf(page, "0.0.%04x\n", ipl_devno);
+ case IPL_TYPE_FCP:
+ return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno);
+ default:
+ return 0;
+ }
+}
+
+static struct subsys_attribute sys_ipl_device_attr =
+ __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
+
+static ssize_t ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ unsigned int size = IPL_PARMBLOCK_SIZE;
+
+ if (off > size)
+ return 0;
+ if (off + count > size)
+ count = size - off;
+ memcpy(buf, (void *)IPL_PARMBLOCK_START + off, count);
+ return count;
+}
+
+static struct bin_attribute ipl_parameter_attr = {
+ .attr = {
+ .name = "binary_parameter",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = PAGE_SIZE,
+ .read = &ipl_parameter_read,
+};
+
+static ssize_t ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len;
+ void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data;
+
+ if (off > size)
+ return 0;
+ if (off + count > size)
+ count = size - off;
+ memcpy(buf, scp_data + off, count);
+ return count;
+}
+
+static struct bin_attribute ipl_scp_data_attr = {
+ .attr = {
+ .name = "scp_data",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = PAGE_SIZE,
+ .read = &ipl_scp_data_read,
+};
+
+/* FCP ipl device attributes */
+
+DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", (unsigned long long)
+ IPL_PARMBLOCK_START->ipl_info.fcp.wwpn);
+DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", (unsigned long long)
+ IPL_PARMBLOCK_START->ipl_info.fcp.lun);
+DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long)
+ IPL_PARMBLOCK_START->ipl_info.fcp.bootprog);
+DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long)
+ IPL_PARMBLOCK_START->ipl_info.fcp.br_lba);
+
+static struct attribute *ipl_fcp_attrs[] = {
+ &sys_ipl_type_attr.attr,
+ &sys_ipl_device_attr.attr,
+ &sys_ipl_fcp_wwpn_attr.attr,
+ &sys_ipl_fcp_lun_attr.attr,
+ &sys_ipl_fcp_bootprog_attr.attr,
+ &sys_ipl_fcp_br_lba_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ipl_fcp_attr_group = {
+ .attrs = ipl_fcp_attrs,
+};
+
+/* CCW ipl device attributes */
+
+static struct attribute *ipl_ccw_attrs[] = {
+ &sys_ipl_type_attr.attr,
+ &sys_ipl_device_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ipl_ccw_attr_group = {
+ .attrs = ipl_ccw_attrs,
+};
+
+/* UNKNOWN ipl device attributes */
+
+static struct attribute *ipl_unknown_attrs[] = {
+ &sys_ipl_type_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ipl_unknown_attr_group = {
+ .attrs = ipl_unknown_attrs,
+};
+
+static decl_subsys(ipl, NULL, NULL);
+
+/*
+ * reipl section
+ */
+
+/* FCP reipl device attributes */
+
+DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n",
+ reipl_block_fcp->ipl_info.fcp.wwpn);
+DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n",
+ reipl_block_fcp->ipl_info.fcp.lun);
+DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
+ reipl_block_fcp->ipl_info.fcp.bootprog);
+DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
+ reipl_block_fcp->ipl_info.fcp.br_lba);
+DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
+ reipl_block_fcp->ipl_info.fcp.devno);
+
+static struct attribute *reipl_fcp_attrs[] = {
+ &sys_reipl_fcp_device_attr.attr,
+ &sys_reipl_fcp_wwpn_attr.attr,
+ &sys_reipl_fcp_lun_attr.attr,
+ &sys_reipl_fcp_bootprog_attr.attr,
+ &sys_reipl_fcp_br_lba_attr.attr,
+ NULL,
+};
+
+static struct attribute_group reipl_fcp_attr_group = {
+ .name = IPL_FCP_STR,
+ .attrs = reipl_fcp_attrs,
+};
+
+/* CCW reipl device attributes */
+
+DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
+ reipl_block_ccw->ipl_info.ccw.devno);
+
+static struct attribute *reipl_ccw_attrs[] = {
+ &sys_reipl_ccw_device_attr.attr,
+ NULL,
+};
+
+static struct attribute_group reipl_ccw_attr_group = {
+ .name = IPL_CCW_STR,
+ .attrs = reipl_ccw_attrs,
+};
+
+/* reipl type */
+
+static int reipl_set_type(enum ipl_type type)
+{
+ if (!(reipl_capabilities & type))
+ return -EINVAL;
+
+ switch(type) {
+ case IPL_TYPE_CCW:
+ if (MACHINE_IS_VM)
+ reipl_method = IPL_METHOD_CCW_VM;
+ else
+ reipl_method = IPL_METHOD_CCW_CIO;
+ break;
+ case IPL_TYPE_FCP:
+ if (diag308_set_works)
+ reipl_method = IPL_METHOD_FCP_RW_DIAG;
+ else if (MACHINE_IS_VM)
+ reipl_method = IPL_METHOD_FCP_RO_VM;
+ else
+ reipl_method = IPL_METHOD_FCP_RO_DIAG;
+ break;
+ default:
+ reipl_method = IPL_METHOD_NONE;
+ }
+ reipl_type = type;
+ return 0;
+}
+
+static ssize_t reipl_type_show(struct subsystem *subsys, char *page)
+{
+ return sprintf(page, "%s\n", ipl_type_str(reipl_type));
+}
+
+static ssize_t reipl_type_store(struct subsystem *subsys, const char *buf,
+ size_t len)
+{
+ int rc = -EINVAL;
+
+ if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
+ rc = reipl_set_type(IPL_TYPE_CCW);
+ else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
+ rc = reipl_set_type(IPL_TYPE_FCP);
+ return (rc != 0) ? rc : len;
+}
+
+static struct subsys_attribute reipl_type_attr =
+ __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
+
+static decl_subsys(reipl, NULL, NULL);
+
+/*
+ * dump section
+ */
+
+/* FCP dump device attributes */
+
+DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
+ dump_block_fcp->ipl_info.fcp.wwpn);
+DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
+ dump_block_fcp->ipl_info.fcp.lun);
+DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
+ dump_block_fcp->ipl_info.fcp.bootprog);
+DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
+ dump_block_fcp->ipl_info.fcp.br_lba);
+DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
+ dump_block_fcp->ipl_info.fcp.devno);
+
+static struct attribute *dump_fcp_attrs[] = {
+ &sys_dump_fcp_device_attr.attr,
+ &sys_dump_fcp_wwpn_attr.attr,
+ &sys_dump_fcp_lun_attr.attr,
+ &sys_dump_fcp_bootprog_attr.attr,
+ &sys_dump_fcp_br_lba_attr.attr,
+ NULL,
+};
+
+static struct attribute_group dump_fcp_attr_group = {
+ .name = IPL_FCP_STR,
+ .attrs = dump_fcp_attrs,
+};
+
+/* CCW dump device attributes */
+
+DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
+ dump_block_ccw->ipl_info.ccw.devno);
+
+static struct attribute *dump_ccw_attrs[] = {
+ &sys_dump_ccw_device_attr.attr,
+ NULL,
+};
+
+static struct attribute_group dump_ccw_attr_group = {
+ .name = IPL_CCW_STR,
+ .attrs = dump_ccw_attrs,
+};
+
+/* dump type */
+
+static int dump_set_type(enum ipl_type type)
+{
+ if (!(dump_capabilities & type))
+ return -EINVAL;
+ switch(type) {
+ case IPL_TYPE_CCW:
+ if (MACHINE_IS_VM)
+ dump_method = IPL_METHOD_CCW_VM;
+ else
+ dump_method = IPL_METHOD_CCW_CIO;
+ break;
+ case IPL_TYPE_FCP:
+ dump_method = IPL_METHOD_FCP_RW_DIAG;
+ break;
+ default:
+ dump_method = IPL_METHOD_NONE;
+ }
+ dump_type = type;
+ return 0;
+}
+
+static ssize_t dump_type_show(struct subsystem *subsys, char *page)
+{
+ return sprintf(page, "%s\n", ipl_type_str(dump_type));
+}
+
+static ssize_t dump_type_store(struct subsystem *subsys, const char *buf,
+ size_t len)
+{
+ int rc = -EINVAL;
+
+ if (strncmp(buf, IPL_NONE_STR, strlen(IPL_NONE_STR)) == 0)
+ rc = dump_set_type(IPL_TYPE_NONE);
+ else if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
+ rc = dump_set_type(IPL_TYPE_CCW);
+ else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
+ rc = dump_set_type(IPL_TYPE_FCP);
+ return (rc != 0) ? rc : len;
+}
+
+static struct subsys_attribute dump_type_attr =
+ __ATTR(dump_type, 0644, dump_type_show, dump_type_store);
+
+static decl_subsys(dump, NULL, NULL);
+
+#ifdef CONFIG_SMP
+static void dump_smp_stop_all(void)
+{
+ int cpu;
+ preempt_disable();
+ for_each_online_cpu(cpu) {
+ if (cpu == smp_processor_id())
+ continue;
+ while (signal_processor(cpu, sigp_stop) == sigp_busy)
+ udelay(10);
+ }
+ preempt_enable();
+}
+#else
+#define dump_smp_stop_all() do { } while (0)
+#endif
+
+/*
+ * Shutdown actions section
+ */
+
+static decl_subsys(shutdown_actions, NULL, NULL);
+
+/* on panic */
+
+static ssize_t on_panic_show(struct subsystem *subsys, char *page)
+{
+ return sprintf(page, "%s\n", shutdown_action_str(on_panic_action));
+}
+
+static ssize_t on_panic_store(struct subsystem *subsys, const char *buf,
+ size_t len)
+{
+ if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0)
+ on_panic_action = SHUTDOWN_REIPL;
+ else if (strncmp(buf, SHUTDOWN_DUMP_STR,
+ strlen(SHUTDOWN_DUMP_STR)) == 0)
+ on_panic_action = SHUTDOWN_DUMP;
+ else if (strncmp(buf, SHUTDOWN_STOP_STR,
+ strlen(SHUTDOWN_STOP_STR)) == 0)
+ on_panic_action = SHUTDOWN_STOP;
+ else
+ return -EINVAL;
+
+ return len;
+}
+
+static struct subsys_attribute on_panic_attr =
+ __ATTR(on_panic, 0644, on_panic_show, on_panic_store);
+
+static void print_fcp_block(struct ipl_parameter_block *fcp_block)
+{
+ printk(KERN_EMERG "wwpn: %016llx\n",
+ (unsigned long long)fcp_block->ipl_info.fcp.wwpn);
+ printk(KERN_EMERG "lun: %016llx\n",
+ (unsigned long long)fcp_block->ipl_info.fcp.lun);
+ printk(KERN_EMERG "bootprog: %lld\n",
+ (unsigned long long)fcp_block->ipl_info.fcp.bootprog);
+ printk(KERN_EMERG "br_lba: %lld\n",
+ (unsigned long long)fcp_block->ipl_info.fcp.br_lba);
+ printk(KERN_EMERG "device: %llx\n",
+ (unsigned long long)fcp_block->ipl_info.fcp.devno);
+ printk(KERN_EMERG "opt: %x\n", fcp_block->ipl_info.fcp.opt);
+}
+
+void do_reipl(void)
+{
+ struct ccw_dev_id devid;
+ static char buf[100];
+
+ switch (reipl_type) {
+ case IPL_TYPE_CCW:
+ printk(KERN_EMERG "reboot on ccw device: 0.0.%04x\n",
+ reipl_block_ccw->ipl_info.ccw.devno);
+ break;
+ case IPL_TYPE_FCP:
+ printk(KERN_EMERG "reboot on fcp device:\n");
+ print_fcp_block(reipl_block_fcp);
+ break;
+ default:
+ break;
+ }
+
+ switch (reipl_method) {
+ case IPL_METHOD_CCW_CIO:
+ devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
+ devid.ssid = 0;
+ reipl_ccw_dev(&devid);
+ break;
+ case IPL_METHOD_CCW_VM:
+ sprintf(buf, "IPL %X", reipl_block_ccw->ipl_info.ccw.devno);
+ cpcmd(buf, NULL, 0, NULL);
+ break;
+ case IPL_METHOD_CCW_DIAG:
+ diag308(DIAG308_SET, reipl_block_ccw);
+ diag308(DIAG308_IPL, NULL);
+ break;
+ case IPL_METHOD_FCP_RW_DIAG:
+ diag308(DIAG308_SET, reipl_block_fcp);
+ diag308(DIAG308_IPL, NULL);
+ break;
+ case IPL_METHOD_FCP_RO_DIAG:
+ diag308(DIAG308_IPL, NULL);
+ break;
+ case IPL_METHOD_FCP_RO_VM:
+ cpcmd("IPL", NULL, 0, NULL);
+ break;
+ case IPL_METHOD_NONE:
+ default:
+ if (MACHINE_IS_VM)
+ cpcmd("IPL", NULL, 0, NULL);
+ diag308(DIAG308_IPL, NULL);
+ break;
+ }
+ panic("reipl failed!\n");
+}
+
+static void do_dump(void)
+{
+ struct ccw_dev_id devid;
+ static char buf[100];
+
+ switch (dump_type) {
+ case IPL_TYPE_CCW:
+ printk(KERN_EMERG "Automatic dump on ccw device: 0.0.%04x\n",
+ dump_block_ccw->ipl_info.ccw.devno);
+ break;
+ case IPL_TYPE_FCP:
+ printk(KERN_EMERG "Automatic dump on fcp device:\n");
+ print_fcp_block(dump_block_fcp);
+ break;
+ default:
+ return;
+ }
+
+ switch (dump_method) {
+ case IPL_METHOD_CCW_CIO:
+ dump_smp_stop_all();
+ devid.devno = dump_block_ccw->ipl_info.ccw.devno;
+ devid.ssid = 0;
+ reipl_ccw_dev(&devid);
+ break;
+ case IPL_METHOD_CCW_VM:
+ dump_smp_stop_all();
+ sprintf(buf, "STORE STATUS");
+ cpcmd(buf, NULL, 0, NULL);
+ sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
+ cpcmd(buf, NULL, 0, NULL);
+ break;
+ case IPL_METHOD_CCW_DIAG:
+ diag308(DIAG308_SET, dump_block_ccw);
+ diag308(DIAG308_DUMP, NULL);
+ break;
+ case IPL_METHOD_FCP_RW_DIAG:
+ diag308(DIAG308_SET, dump_block_fcp);
+ diag308(DIAG308_DUMP, NULL);
+ break;
+ case IPL_METHOD_NONE:
+ default:
+ return;
+ }
+ printk(KERN_EMERG "Dump failed!\n");
+}
+
+/* init functions */
+
+static int __init ipl_register_fcp_files(void)
+{
+ int rc;
+
+ rc = sysfs_create_group(&ipl_subsys.kset.kobj,
+ &ipl_fcp_attr_group);
+ if (rc)
+ goto out;
+ rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+ &ipl_parameter_attr);
+ if (rc)
+ goto out_ipl_parm;
+ rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+ &ipl_scp_data_attr);
+ if (!rc)
+ goto out;
+
+ sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr);
+
+out_ipl_parm:
+ sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
+out:
+ return rc;
+}
+
+static int __init ipl_init(void)
+{
+ int rc;
+
+ rc = firmware_register(&ipl_subsys);
+ if (rc)
+ return rc;
+ switch (ipl_get_type()) {
+ case IPL_TYPE_CCW:
+ rc = sysfs_create_group(&ipl_subsys.kset.kobj,
+ &ipl_ccw_attr_group);
+ break;
+ case IPL_TYPE_FCP:
+ rc = ipl_register_fcp_files();
+ break;
+ default:
+ rc = sysfs_create_group(&ipl_subsys.kset.kobj,
+ &ipl_unknown_attr_group);
+ break;
+ }
+ if (rc)
+ firmware_unregister(&ipl_subsys);
+ return rc;
+}
+
+static void __init reipl_probe(void)
+{
+ void *buffer;
+
+ buffer = (void *) get_zeroed_page(GFP_KERNEL);
+ if (!buffer)
+ return;
+ if (diag308(DIAG308_STORE, buffer) == DIAG308_RC_OK)
+ diag308_set_works = 1;
+ free_page((unsigned long)buffer);
+}
+
+static int __init reipl_ccw_init(void)
+{
+ int rc;
+
+ reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
+ if (!reipl_block_ccw)
+ return -ENOMEM;
+ rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_ccw_attr_group);
+ if (rc) {
+ free_page((unsigned long)reipl_block_ccw);
+ return rc;
+ }
+ reipl_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
+ reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
+ reipl_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw);
+ reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
+ if (ipl_get_type() == IPL_TYPE_CCW)
+ reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
+ reipl_capabilities |= IPL_TYPE_CCW;
+ return 0;
+}
+
+static int __init reipl_fcp_init(void)
+{
+ int rc;
+
+ if ((!diag308_set_works) && (ipl_get_type() != IPL_TYPE_FCP))
+ return 0;
+ if ((!diag308_set_works) && (ipl_get_type() == IPL_TYPE_FCP))
+ make_attrs_ro(reipl_fcp_attrs);
+
+ reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
+ if (!reipl_block_fcp)
+ return -ENOMEM;
+ rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_fcp_attr_group);
+ if (rc) {
+ free_page((unsigned long)reipl_block_fcp);
+ return rc;
+ }
+ if (ipl_get_type() == IPL_TYPE_FCP) {
+ memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
+ } else {
+ reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
+ reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
+ reipl_block_fcp->hdr.blk0_len =
+ sizeof(reipl_block_fcp->ipl_info.fcp);
+ reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
+ reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL;
+ }
+ reipl_capabilities |= IPL_TYPE_FCP;
+ return 0;
+}
+
+static int __init reipl_init(void)
+{
+ int rc;
+
+ rc = firmware_register(&reipl_subsys);
+ if (rc)
+ return rc;
+ rc = subsys_create_file(&reipl_subsys, &reipl_type_attr);
+ if (rc) {
+ firmware_unregister(&reipl_subsys);
+ return rc;
+ }
+ rc = reipl_ccw_init();
+ if (rc)
+ return rc;
+ rc = reipl_fcp_init();
+ if (rc)
+ return rc;
+ rc = reipl_set_type(ipl_get_type());
+ if (rc)
+ return rc;
+ return 0;
+}
+
+static int __init dump_ccw_init(void)
+{
+ int rc;
+
+ dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
+ if (!dump_block_ccw)
+ return -ENOMEM;
+ rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_ccw_attr_group);
+ if (rc) {
+ free_page((unsigned long)dump_block_ccw);
+ return rc;
+ }
+ dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
+ dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
+ dump_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw);
+ dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
+ dump_capabilities |= IPL_TYPE_CCW;
+ return 0;
+}
+
+extern char s390_readinfo_sccb[];
+
+static int __init dump_fcp_init(void)
+{
+ int rc;
+
+ if(!(s390_readinfo_sccb[91] & 0x2))
+ return 0; /* LDIPL DUMP is not installed */
+ if (!diag308_set_works)
+ return 0;
+ dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
+ if (!dump_block_fcp)
+ return -ENOMEM;
+ rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_fcp_attr_group);
+ if (rc) {
+ free_page((unsigned long)dump_block_fcp);
+ return rc;
+ }
+ dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
+ dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
+ dump_block_fcp->hdr.blk0_len = sizeof(dump_block_fcp->ipl_info.fcp);
+ dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
+ dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP;
+ dump_capabilities |= IPL_TYPE_FCP;
+ return 0;
+}
+
+#define SHUTDOWN_ON_PANIC_PRIO 0
+
+static int shutdown_on_panic_notify(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ if (on_panic_action == SHUTDOWN_DUMP)
+ do_dump();
+ else if (on_panic_action == SHUTDOWN_REIPL)
+ do_reipl();
+ return NOTIFY_OK;
+}
+
+static struct notifier_block shutdown_on_panic_nb = {
+ .notifier_call = shutdown_on_panic_notify,
+ .priority = SHUTDOWN_ON_PANIC_PRIO
+};
+
+static int __init dump_init(void)
+{
+ int rc;
+
+ rc = firmware_register(&dump_subsys);
+ if (rc)
+ return rc;
+ rc = subsys_create_file(&dump_subsys, &dump_type_attr);
+ if (rc) {
+ firmware_unregister(&dump_subsys);
+ return rc;
+ }
+ rc = dump_ccw_init();
+ if (rc)
+ return rc;
+ rc = dump_fcp_init();
+ if (rc)
+ return rc;
+ dump_set_type(IPL_TYPE_NONE);
+ return 0;
+}
+
+static int __init shutdown_actions_init(void)
+{
+ int rc;
+
+ rc = firmware_register(&shutdown_actions_subsys);
+ if (rc)
+ return rc;
+ rc = subsys_create_file(&shutdown_actions_subsys, &on_panic_attr);
+ if (rc) {
+ firmware_unregister(&shutdown_actions_subsys);
+ return rc;
+ }
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &shutdown_on_panic_nb);
+ return 0;
+}
+
+static int __init s390_ipl_init(void)
+{
+ int rc;
+
+ reipl_probe();
+ rc = ipl_init();
+ if (rc)
+ return rc;
+ rc = reipl_init();
+ if (rc)
+ return rc;
+ rc = dump_init();
+ if (rc)
+ return rc;
+ rc = shutdown_actions_init();
+ if (rc)
+ return rc;
+ return 0;
+}
+
+__initcall(s390_ipl_init);
diff --git a/trunk/arch/s390/kernel/kprobes.c b/trunk/arch/s390/kernel/kprobes.c
new file mode 100644
index 000000000000..ca28fb0b3790
--- /dev/null
+++ b/trunk/arch/s390/kernel/kprobes.c
@@ -0,0 +1,657 @@
+/*
+ * Kernel Probes (KProbes)
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2002, 2006
+ *
+ * s390 port, used ppc64 as template. Mike Grundy
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
+{
+ /* Make sure the probe isn't going on a difficult instruction */
+ if (is_prohibited_opcode((kprobe_opcode_t *) p->addr))
+ return -EINVAL;
+
+ if ((unsigned long)p->addr & 0x01) {
+ printk("Attempt to register kprobe at an unaligned address\n");
+ return -EINVAL;
+ }
+
+ /* Use the get_insn_slot() facility for correctness */
+ if (!(p->ainsn.insn = get_insn_slot()))
+ return -ENOMEM;
+
+ memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+
+ get_instruction_type(&p->ainsn);
+ p->opcode = *p->addr;
+ return 0;
+}
+
+int __kprobes is_prohibited_opcode(kprobe_opcode_t *instruction)
+{
+ switch (*(__u8 *) instruction) {
+ case 0x0c: /* bassm */
+ case 0x0b: /* bsm */
+ case 0x83: /* diag */
+ case 0x44: /* ex */
+ return -EINVAL;
+ }
+ switch (*(__u16 *) instruction) {
+ case 0x0101: /* pr */
+ case 0xb25a: /* bsa */
+ case 0xb240: /* bakr */
+ case 0xb258: /* bsg */
+ case 0xb218: /* pc */
+ case 0xb228: /* pt */
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void __kprobes get_instruction_type(struct arch_specific_insn *ainsn)
+{
+ /* default fixup method */
+ ainsn->fixup = FIXUP_PSW_NORMAL;
+
+ /* save r1 operand */
+ ainsn->reg = (*ainsn->insn & 0xf0) >> 4;
+
+ /* save the instruction length (pop 5-5) in bytes */
+ switch (*(__u8 *) (ainsn->insn) >> 4) {
+ case 0:
+ ainsn->ilen = 2;
+ break;
+ case 1:
+ case 2:
+ ainsn->ilen = 4;
+ break;
+ case 3:
+ ainsn->ilen = 6;
+ break;
+ }
+
+ switch (*(__u8 *) ainsn->insn) {
+ case 0x05: /* balr */
+ case 0x0d: /* basr */
+ ainsn->fixup = FIXUP_RETURN_REGISTER;
+ /* if r2 = 0, no branch will be taken */
+ if ((*ainsn->insn & 0x0f) == 0)
+ ainsn->fixup |= FIXUP_BRANCH_NOT_TAKEN;
+ break;
+ case 0x06: /* bctr */
+ case 0x07: /* bcr */
+ ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
+ break;
+ case 0x45: /* bal */
+ case 0x4d: /* bas */
+ ainsn->fixup = FIXUP_RETURN_REGISTER;
+ break;
+ case 0x47: /* bc */
+ case 0x46: /* bct */
+ case 0x86: /* bxh */
+ case 0x87: /* bxle */
+ ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
+ break;
+ case 0x82: /* lpsw */
+ ainsn->fixup = FIXUP_NOT_REQUIRED;
+ break;
+ case 0xb2: /* lpswe */
+ if (*(((__u8 *) ainsn->insn) + 1) == 0xb2) {
+ ainsn->fixup = FIXUP_NOT_REQUIRED;
+ }
+ break;
+ case 0xa7: /* bras */
+ if ((*ainsn->insn & 0x0f) == 0x05) {
+ ainsn->fixup |= FIXUP_RETURN_REGISTER;
+ }
+ break;
+ case 0xc0:
+ if ((*ainsn->insn & 0x0f) == 0x00 /* larl */
+ || (*ainsn->insn & 0x0f) == 0x05) /* brasl */
+ ainsn->fixup |= FIXUP_RETURN_REGISTER;
+ break;
+ case 0xeb:
+ if (*(((__u8 *) ainsn->insn) + 5 ) == 0x44 || /* bxhg */
+ *(((__u8 *) ainsn->insn) + 5) == 0x45) {/* bxleg */
+ ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
+ }
+ break;
+ case 0xe3: /* bctg */
+ if (*(((__u8 *) ainsn->insn) + 5) == 0x46) {
+ ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
+ }
+ break;
+ }
+}
+
+static int __kprobes swap_instruction(void *aref)
+{
+ struct ins_replace_args *args = aref;
+ int err = -EFAULT;
+
+ asm volatile(
+ "0: mvc 0(2,%2),0(%3)\n"
+ "1: la %0,0\n"
+ "2:\n"
+ EX_TABLE(0b,2b)
+ : "+d" (err), "=m" (*args->ptr)
+ : "a" (args->ptr), "a" (&args->new), "m" (args->new));
+ return err;
+}
+
+void __kprobes arch_arm_kprobe(struct kprobe *p)
+{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ unsigned long status = kcb->kprobe_status;
+ struct ins_replace_args args;
+
+ args.ptr = p->addr;
+ args.old = p->opcode;
+ args.new = BREAKPOINT_INSTRUCTION;
+
+ kcb->kprobe_status = KPROBE_SWAP_INST;
+ stop_machine_run(swap_instruction, &args, NR_CPUS);
+ kcb->kprobe_status = status;
+}
+
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
+{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ unsigned long status = kcb->kprobe_status;
+ struct ins_replace_args args;
+
+ args.ptr = p->addr;
+ args.old = BREAKPOINT_INSTRUCTION;
+ args.new = p->opcode;
+
+ kcb->kprobe_status = KPROBE_SWAP_INST;
+ stop_machine_run(swap_instruction, &args, NR_CPUS);
+ kcb->kprobe_status = status;
+}
+
+void __kprobes arch_remove_kprobe(struct kprobe *p)
+{
+ mutex_lock(&kprobe_mutex);
+ free_insn_slot(p->ainsn.insn);
+ mutex_unlock(&kprobe_mutex);
+}
+
+static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+{
+ per_cr_bits kprobe_per_regs[1];
+
+ memset(kprobe_per_regs, 0, sizeof(per_cr_bits));
+ regs->psw.addr = (unsigned long)p->ainsn.insn | PSW_ADDR_AMODE;
+
+ /* Set up the per control reg info, will pass to lctl */
+ kprobe_per_regs[0].em_instruction_fetch = 1;
+ kprobe_per_regs[0].starting_addr = (unsigned long)p->ainsn.insn;
+ kprobe_per_regs[0].ending_addr = (unsigned long)p->ainsn.insn + 1;
+
+ /* Set the PER control regs, turns on single step for this address */
+ __ctl_load(kprobe_per_regs, 9, 11);
+ regs->psw.mask |= PSW_MASK_PER;
+ regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
+}
+
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+ kcb->prev_kprobe.kp = kprobe_running();
+ kcb->prev_kprobe.status = kcb->kprobe_status;
+ kcb->prev_kprobe.kprobe_saved_imask = kcb->kprobe_saved_imask;
+ memcpy(kcb->prev_kprobe.kprobe_saved_ctl, kcb->kprobe_saved_ctl,
+ sizeof(kcb->kprobe_saved_ctl));
+}
+
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
+ kcb->kprobe_saved_imask = kcb->prev_kprobe.kprobe_saved_imask;
+ memcpy(kcb->kprobe_saved_ctl, kcb->prev_kprobe.kprobe_saved_ctl,
+ sizeof(kcb->kprobe_saved_ctl));
+}
+
+static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
+{
+ __get_cpu_var(current_kprobe) = p;
+ /* Save the interrupt and per flags */
+ kcb->kprobe_saved_imask = regs->psw.mask &
+ (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
+ /* Save the control regs that govern PER */
+ __ctl_store(kcb->kprobe_saved_ctl, 9, 11);
+}
+
+/* Called with kretprobe_lock held */
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+ struct pt_regs *regs)
+{
+ struct kretprobe_instance *ri;
+
+ if ((ri = get_free_rp_inst(rp)) != NULL) {
+ ri->rp = rp;
+ ri->task = current;
+ ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
+
+ /* Replace the return addr with trampoline addr */
+ regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
+
+ add_rp_inst(ri);
+ } else {
+ rp->nmissed++;
+ }
+}
+
+static int __kprobes kprobe_handler(struct pt_regs *regs)
+{
+ struct kprobe *p;
+ int ret = 0;
+ unsigned long *addr = (unsigned long *)
+ ((regs->psw.addr & PSW_ADDR_INSN) - 2);
+ struct kprobe_ctlblk *kcb;
+
+ /*
+ * We don't want to be preempted for the entire
+ * duration of kprobe processing
+ */
+ preempt_disable();
+ kcb = get_kprobe_ctlblk();
+
+ /* Check we're not actually recursing */
+ if (kprobe_running()) {
+ p = get_kprobe(addr);
+ if (p) {
+ if (kcb->kprobe_status == KPROBE_HIT_SS &&
+ *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
+ regs->psw.mask &= ~PSW_MASK_PER;
+ regs->psw.mask |= kcb->kprobe_saved_imask;
+ goto no_kprobe;
+ }
+ /* We have reentered the kprobe_handler(), since
+ * another probe was hit while within the handler.
+ * We here save the original kprobes variables and
+ * just single step on the instruction of the new probe
+ * without calling any user handlers.
+ */
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p, regs, kcb);
+ kprobes_inc_nmissed_count(p);
+ prepare_singlestep(p, regs);
+ kcb->kprobe_status = KPROBE_REENTER;
+ return 1;
+ } else {
+ p = __get_cpu_var(current_kprobe);
+ if (p->break_handler && p->break_handler(p, regs)) {
+ goto ss_probe;
+ }
+ }
+ goto no_kprobe;
+ }
+
+ p = get_kprobe(addr);
+ if (!p) {
+ if (*addr != BREAKPOINT_INSTRUCTION) {
+ /*
+ * The breakpoint instruction was removed right
+ * after we hit it. Another cpu has removed
+ * either a probepoint or a debugger breakpoint
+ * at this address. In either case, no further
+ * handling of this interrupt is appropriate.
+ *
+ */
+ ret = 1;
+ }
+ /* Not one of ours: let kernel handle it */
+ goto no_kprobe;
+ }
+
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+ set_current_kprobe(p, regs, kcb);
+ if (p->pre_handler && p->pre_handler(p, regs))
+ /* handler has already set things up, so skip ss setup */
+ return 1;
+
+ss_probe:
+ prepare_singlestep(p, regs);
+ kcb->kprobe_status = KPROBE_HIT_SS;
+ return 1;
+
+no_kprobe:
+ preempt_enable_no_resched();
+ return ret;
+}
+
+/*
+ * Function return probe trampoline:
+ * - init_kprobes() establishes a probepoint here
+ * - When the probed function returns, this probe
+ * causes the handlers to fire
+ */
+void __kprobes kretprobe_trampoline_holder(void)
+{
+ asm volatile(".global kretprobe_trampoline\n"
+ "kretprobe_trampoline: bcr 0,0\n");
+}
+
+/*
+ * Called when the probe at kretprobe trampoline is hit
+ */
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct kretprobe_instance *ri = NULL;
+ struct hlist_head *head;
+ struct hlist_node *node, *tmp;
+ unsigned long flags, orig_ret_address = 0;
+ unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
+
+ spin_lock_irqsave(&kretprobe_lock, flags);
+ head = kretprobe_inst_table_head(current);
+
+ /*
+ * It is possible to have multiple instances associated with a given
+ * task either because an multiple functions in the call path
+ * have a return probe installed on them, and/or more then one return
+ * return probe was registered for a target function.
+ *
+ * We can handle this because:
+ * - instances are always inserted at the head of the list
+ * - when multiple return probes are registered for the same
+ * function, the first instance's ret_addr will point to the
+ * real return address, and all the rest will point to
+ * kretprobe_trampoline
+ */
+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+ if (ri->task != current)
+ /* another task is sharing our hash bucket */
+ continue;
+
+ if (ri->rp && ri->rp->handler)
+ ri->rp->handler(ri, regs);
+
+ orig_ret_address = (unsigned long)ri->ret_addr;
+ recycle_rp_inst(ri);
+
+ if (orig_ret_address != trampoline_address) {
+ /*
+ * This is the real return address. Any other
+ * instances associated with this task are for
+ * other calls deeper on the call stack
+ */
+ break;
+ }
+ }
+ BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+ regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE;
+
+ reset_current_kprobe();
+ spin_unlock_irqrestore(&kretprobe_lock, flags);
+ preempt_enable_no_resched();
+
+ /*
+ * By returning a non-zero value, we are telling
+ * kprobe_handler() that we don't want the post_handler
+ * to run (and have re-enabled preemption)
+ */
+ return 1;
+}
+
+/*
+ * Called after single-stepping. p->addr is the address of the
+ * instruction whose first byte has been replaced by the "breakpoint"
+ * instruction. To avoid the SMP problems that can occur when we
+ * temporarily put back the original opcode to single-step, we
+ * single-stepped a copy of the instruction. The address of this
+ * copy is p->ainsn.insn.
+ */
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ regs->psw.addr &= PSW_ADDR_INSN;
+
+ if (p->ainsn.fixup & FIXUP_PSW_NORMAL)
+ regs->psw.addr = (unsigned long)p->addr +
+ ((unsigned long)regs->psw.addr -
+ (unsigned long)p->ainsn.insn);
+
+ if (p->ainsn.fixup & FIXUP_BRANCH_NOT_TAKEN)
+ if ((unsigned long)regs->psw.addr -
+ (unsigned long)p->ainsn.insn == p->ainsn.ilen)
+ regs->psw.addr = (unsigned long)p->addr + p->ainsn.ilen;
+
+ if (p->ainsn.fixup & FIXUP_RETURN_REGISTER)
+ regs->gprs[p->ainsn.reg] = ((unsigned long)p->addr +
+ (regs->gprs[p->ainsn.reg] -
+ (unsigned long)p->ainsn.insn))
+ | PSW_ADDR_AMODE;
+
+ regs->psw.addr |= PSW_ADDR_AMODE;
+ /* turn off PER mode */
+ regs->psw.mask &= ~PSW_MASK_PER;
+ /* Restore the original per control regs */
+ __ctl_load(kcb->kprobe_saved_ctl, 9, 11);
+ regs->psw.mask |= kcb->kprobe_saved_imask;
+}
+
+static int __kprobes post_kprobe_handler(struct pt_regs *regs)
+{
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (!cur)
+ return 0;
+
+ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ cur->post_handler(cur, regs, 0);
+ }
+
+ resume_execution(cur, regs);
+
+ /*Restore back the original saved kprobes variables and continue. */
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
+ goto out;
+ }
+ reset_current_kprobe();
+out:
+ preempt_enable_no_resched();
+
+ /*
+ * if somebody else is singlestepping across a probe point, psw mask
+ * will have PER set, in which case, continue the remaining processing
+ * of do_single_step, as if this is not a probe hit.
+ */
+ if (regs->psw.mask & PSW_MASK_PER) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+{
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ const struct exception_table_entry *entry;
+
+ switch(kcb->kprobe_status) {
+ case KPROBE_SWAP_INST:
+ /* We are here because the instruction replacement failed */
+ return 0;
+ case KPROBE_HIT_SS:
+ case KPROBE_REENTER:
+ /*
+ * We are here because the instruction being single
+ * stepped caused a page fault. We reset the current
+ * kprobe and the nip points back to the probe address
+ * and allow the page fault handler to continue as a
+ * normal page fault.
+ */
+ regs->psw.addr = (unsigned long)cur->addr | PSW_ADDR_AMODE;
+ regs->psw.mask &= ~PSW_MASK_PER;
+ regs->psw.mask |= kcb->kprobe_saved_imask;
+ if (kcb->kprobe_status == KPROBE_REENTER)
+ restore_previous_kprobe(kcb);
+ else
+ reset_current_kprobe();
+ preempt_enable_no_resched();
+ break;
+ case KPROBE_HIT_ACTIVE:
+ case KPROBE_HIT_SSDONE:
+ /*
+ * We increment the nmissed count for accounting,
+ * we can also use npre/npostfault count for accouting
+ * these specific fault cases.
+ */
+ kprobes_inc_nmissed_count(cur);
+
+ /*
+ * We come here because instructions in the pre/post
+ * handler caused the page_fault, this could happen
+ * if handler tries to access user space by
+ * copy_from_user(), get_user() etc. Let the
+ * user-specified handler try to fix it first.
+ */
+ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+ return 1;
+
+ /*
+ * In case the user-specified fault handler returned
+ * zero, try to fix up.
+ */
+ entry = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
+ if (entry) {
+ regs->psw.addr = entry->fixup | PSW_ADDR_AMODE;
+ return 1;
+ }
+
+ /*
+ * fixup_exception() could not handle it,
+ * Let do_page_fault() fix it.
+ */
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/*
+ * Wrapper routine to for handling exceptions.
+ */
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ struct die_args *args = (struct die_args *)data;
+ int ret = NOTIFY_DONE;
+
+ switch (val) {
+ case DIE_BPT:
+ if (kprobe_handler(args->regs))
+ ret = NOTIFY_STOP;
+ break;
+ case DIE_SSTEP:
+ if (post_kprobe_handler(args->regs))
+ ret = NOTIFY_STOP;
+ break;
+ case DIE_TRAP:
+ case DIE_PAGE_FAULT:
+ /* kprobe_running() needs smp_processor_id() */
+ preempt_disable();
+ if (kprobe_running() &&
+ kprobe_fault_handler(args->regs, args->trapnr))
+ ret = NOTIFY_STOP;
+ preempt_enable();
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct jprobe *jp = container_of(p, struct jprobe, kp);
+ unsigned long addr;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
+
+ /* setup return addr to the jprobe handler routine */
+ regs->psw.addr = (unsigned long)(jp->entry) | PSW_ADDR_AMODE;
+
+ /* r14 is the function return address */
+ kcb->jprobe_saved_r14 = (unsigned long)regs->gprs[14];
+ /* r15 is the stack pointer */
+ kcb->jprobe_saved_r15 = (unsigned long)regs->gprs[15];
+ addr = (unsigned long)kcb->jprobe_saved_r15;
+
+ memcpy(kcb->jprobes_stack, (kprobe_opcode_t *) addr,
+ MIN_STACK_SIZE(addr));
+ return 1;
+}
+
+void __kprobes jprobe_return(void)
+{
+ asm volatile(".word 0x0002");
+}
+
+void __kprobes jprobe_return_end(void)
+{
+ asm volatile("bcr 0,0");
+}
+
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_r15);
+
+ /* Put the regs back */
+ memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
+ /* put the stack back */
+ memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
+ MIN_STACK_SIZE(stack_addr));
+ preempt_enable_no_resched();
+ return 1;
+}
+
+static struct kprobe trampoline_p = {
+ .addr = (kprobe_opcode_t *) & kretprobe_trampoline,
+ .pre_handler = trampoline_probe_handler
+};
+
+int __init arch_init_kprobes(void)
+{
+ return register_kprobe(&trampoline_p);
+}
diff --git a/trunk/arch/s390/kernel/reipl.S b/trunk/arch/s390/kernel/reipl.S
index 658e5ac484f9..4562cdbce8eb 100644
--- a/trunk/arch/s390/kernel/reipl.S
+++ b/trunk/arch/s390/kernel/reipl.S
@@ -8,13 +8,30 @@
#include
- .globl do_reipl
-do_reipl: basr %r13,0
+ .globl do_reipl_asm
+do_reipl_asm: basr %r13,0
.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13)
-.Lpg1: lctl %c6,%c6,.Lall-.Lpg0(%r13)
- stctl %c0,%c0,.Lctlsave-.Lpg0(%r13)
- ni .Lctlsave-.Lpg0(%r13),0xef
- lctl %c0,%c0,.Lctlsave-.Lpg0(%r13)
+
+ # switch off lowcore protection
+
+.Lpg1: stctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
+ stctl %c0,%c0,.Lctlsave2-.Lpg0(%r13)
+ ni .Lctlsave1-.Lpg0(%r13),0xef
+ lctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
+
+ # do store status of all registers
+
+ stm %r0,%r15,__LC_GPREGS_SAVE_AREA
+ stctl %c0,%c15,__LC_CREGS_SAVE_AREA
+ mvc __LC_CREGS_SAVE_AREA(4),.Lctlsave2-.Lpg0(%r13)
+ stam %a0,%a15,__LC_AREGS_SAVE_AREA
+ stpx __LC_PREFIX_SAVE_AREA
+ stckc .Lclkcmp-.Lpg0(%r13)
+ mvc __LC_CLOCK_COMP_SAVE_AREA(8),.Lclkcmp-.Lpg0(%r13)
+ stpt __LC_CPU_TIMER_SAVE_AREA
+ st %r13, __LC_PSW_SAVE_AREA+4
+
+ lctl %c6,%c6,.Lall-.Lpg0(%r13)
lr %r1,%r2
mvc __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13)
stsch .Lschib-.Lpg0(%r13)
@@ -46,9 +63,11 @@ do_reipl: basr %r13,0
.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13)
lpsw .Ldispsw-.Lpg0(%r13)
.align 8
+.Lclkcmp: .quad 0x0000000000000000
.Lall: .long 0xff000000
.Lnull: .long 0x00000000
-.Lctlsave: .long 0x00000000
+.Lctlsave1: .long 0x00000000
+.Lctlsave2: .long 0x00000000
.align 8
.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1
.Lpcnew: .long 0x00080000,0x80000000+.Lecs
diff --git a/trunk/arch/s390/kernel/reipl64.S b/trunk/arch/s390/kernel/reipl64.S
index 4d090d60f3ef..95bd1e234f63 100644
--- a/trunk/arch/s390/kernel/reipl64.S
+++ b/trunk/arch/s390/kernel/reipl64.S
@@ -8,13 +8,30 @@
*/
#include
- .globl do_reipl
-do_reipl: basr %r13,0
-.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
+ .globl do_reipl_asm
+do_reipl_asm: basr %r13,0
+
+ # do store status of all registers
+
+.Lpg0: stg %r1,.Lregsave-.Lpg0(%r13)
+ lghi %r1,0x1000
+ stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1)
+ lg %r0,.Lregsave-.Lpg0(%r13)
+ stg %r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1)
+ stctg %c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1)
+ stam %a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1)
+ stpx __LC_PREFIX_SAVE_AREA-0x1000(%r1)
+ stfpc __LC_FP_CREG_SAVE_AREA-0x1000(%r1)
+ stckc .Lclkcmp-.Lpg0(%r13)
+ mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(8,%r1),.Lclkcmp-.Lpg0(%r13)
+ stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
+ stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
+
+ lpswe .Lnewpsw-.Lpg0(%r13)
.Lpg1: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
- stctg %c0,%c0,.Lctlsave-.Lpg0(%r13)
- ni .Lctlsave+4-.Lpg0(%r13),0xef
- lctlg %c0,%c0,.Lctlsave-.Lpg0(%r13)
+ stctg %c0,%c0,.Lregsave-.Lpg0(%r13)
+ ni .Lregsave+4-.Lpg0(%r13),0xef
+ lctlg %c0,%c0,.Lregsave-.Lpg0(%r13)
lgr %r1,%r2
mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
stsch .Lschib-.Lpg0(%r13)
@@ -50,8 +67,9 @@ do_reipl: basr %r13,0
st %r14,.Ldispsw+12-.Lpg0(%r13)
lpswe .Ldispsw-.Lpg0(%r13)
.align 8
+.Lclkcmp: .quad 0x0000000000000000
.Lall: .quad 0x00000000ff000000
-.Lctlsave: .quad 0x0000000000000000
+.Lregsave: .quad 0x0000000000000000
.Lnull: .long 0x0000000000000000
.align 16
/*
@@ -92,5 +110,3 @@ do_reipl: basr %r13,0
.long 0x00000000,0x00000000
.long 0x00000000,0x00000000
-
-
diff --git a/trunk/arch/s390/kernel/reipl_diag.c b/trunk/arch/s390/kernel/reipl_diag.c
deleted file mode 100644
index 1f33951ba439..000000000000
--- a/trunk/arch/s390/kernel/reipl_diag.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file contains the implementation of the
- * Linux re-IPL support
- *
- * (C) Copyright IBM Corp. 2005
- *
- * Author(s): Volker Sameske (sameske@de.ibm.com)
- *
- */
-
-#include
-
-static unsigned int reipl_diag_rc1;
-static unsigned int reipl_diag_rc2;
-
-/*
- * re-IPL the system using the last used IPL parameters
- */
-void reipl_diag(void)
-{
- asm volatile (
- " la %%r4,0\n"
- " la %%r5,0\n"
- " diag %%r4,%2,0x308\n"
- "0:\n"
- " st %%r4,%0\n"
- " st %%r5,%1\n"
- ".section __ex_table,\"a\"\n"
-#ifdef CONFIG_64BIT
- " .align 8\n"
- " .quad 0b, 0b\n"
-#else
- " .align 4\n"
- " .long 0b, 0b\n"
-#endif
- ".previous\n"
- : "=m" (reipl_diag_rc1), "=m" (reipl_diag_rc2)
- : "d" (3) : "cc", "4", "5" );
-}
diff --git a/trunk/arch/s390/kernel/s390_ksyms.c b/trunk/arch/s390/kernel/s390_ksyms.c
index c73a45467fa4..9f19e833a562 100644
--- a/trunk/arch/s390/kernel/s390_ksyms.c
+++ b/trunk/arch/s390/kernel/s390_ksyms.c
@@ -25,12 +25,6 @@ EXPORT_SYMBOL(_oi_bitmap);
EXPORT_SYMBOL(_ni_bitmap);
EXPORT_SYMBOL(_zb_findmap);
EXPORT_SYMBOL(_sb_findmap);
-EXPORT_SYMBOL(__copy_from_user_asm);
-EXPORT_SYMBOL(__copy_to_user_asm);
-EXPORT_SYMBOL(__copy_in_user_asm);
-EXPORT_SYMBOL(__clear_user_asm);
-EXPORT_SYMBOL(__strncpy_from_user_asm);
-EXPORT_SYMBOL(__strnlen_user_asm);
EXPORT_SYMBOL(diag10);
/*
diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c
index c902f059c7aa..e3d9325f6022 100644
--- a/trunk/arch/s390/kernel/setup.c
+++ b/trunk/arch/s390/kernel/setup.c
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#include
@@ -49,6 +50,12 @@
#include
#include
+/*
+ * User copy operations.
+ */
+struct uaccess_ops uaccess;
+EXPORT_SYMBOL_GPL(uaccess);
+
/*
* Machine setup..
*/
@@ -284,16 +291,9 @@ void (*_machine_power_off)(void) = machine_power_off_smp;
/*
* Reboot, halt and power_off routines for non SMP.
*/
-extern void reipl(unsigned long devno);
-extern void reipl_diag(void);
static void do_machine_restart_nonsmp(char * __unused)
{
- reipl_diag();
-
- if (MACHINE_IS_VM)
- cpcmd ("IPL", NULL, 0, NULL);
- else
- reipl (0x10000 | S390_lowcore.ipl_device);
+ do_reipl();
}
static void do_machine_halt_nonsmp(void)
@@ -501,13 +501,47 @@ setup_memory(void)
* partially used pages are not usable - thus
* we are rounding upwards:
*/
- start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT;
- end_pfn = max_pfn = memory_end >> PAGE_SHIFT;
+ start_pfn = PFN_UP(__pa(&_end));
+ end_pfn = max_pfn = PFN_DOWN(memory_end);
/* Initialize storage key for kernel pages */
for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++)
page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
+#ifdef CONFIG_BLK_DEV_INITRD
+ /*
+ * Move the initrd in case the bitmap of the bootmem allocater
+ * would overwrite it.
+ */
+
+ if (INITRD_START && INITRD_SIZE) {
+ unsigned long bmap_size;
+ unsigned long start;
+
+ bmap_size = bootmem_bootmap_pages(end_pfn - start_pfn + 1);
+ bmap_size = PFN_PHYS(bmap_size);
+
+ if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) {
+ start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE;
+
+ if (start + INITRD_SIZE > memory_end) {
+ printk("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx)\n"
+ "disabling initrd\n",
+ start + INITRD_SIZE, memory_end);
+ INITRD_START = INITRD_SIZE = 0;
+ } else {
+ printk("Moving initrd (0x%08lx -> 0x%08lx, "
+ "size: %ld)\n",
+ INITRD_START, start, INITRD_SIZE);
+ memmove((void *) start, (void *) INITRD_START,
+ INITRD_SIZE);
+ INITRD_START = start;
+ }
+ }
+ }
+#endif
+
/*
* Initialize the boot-time allocator (with low memory only):
*/
@@ -559,7 +593,7 @@ setup_memory(void)
reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);
#ifdef CONFIG_BLK_DEV_INITRD
- if (INITRD_START) {
+ if (INITRD_START && INITRD_SIZE) {
if (INITRD_START + INITRD_SIZE <= memory_end) {
reserve_bootmem(INITRD_START, INITRD_SIZE);
initrd_start = INITRD_START;
@@ -613,6 +647,11 @@ setup_arch(char **cmdline_p)
memory_end = memory_size;
+ if (MACHINE_HAS_MVCOS)
+ memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess));
+ else
+ memcpy(&uaccess, &uaccess_std, sizeof(uaccess));
+
parse_early_param();
#ifndef CONFIG_64BIT
@@ -720,214 +759,3 @@ struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};
-#define DEFINE_IPL_ATTR(_name, _format, _value) \
-static ssize_t ipl_##_name##_show(struct subsystem *subsys, \
- char *page) \
-{ \
- return sprintf(page, _format, _value); \
-} \
-static struct subsys_attribute ipl_##_name##_attr = \
- __ATTR(_name, S_IRUGO, ipl_##_name##_show, NULL);
-
-DEFINE_IPL_ATTR(wwpn, "0x%016llx\n", (unsigned long long)
- IPL_PARMBLOCK_START->fcp.wwpn);
-DEFINE_IPL_ATTR(lun, "0x%016llx\n", (unsigned long long)
- IPL_PARMBLOCK_START->fcp.lun);
-DEFINE_IPL_ATTR(bootprog, "%lld\n", (unsigned long long)
- IPL_PARMBLOCK_START->fcp.bootprog);
-DEFINE_IPL_ATTR(br_lba, "%lld\n", (unsigned long long)
- IPL_PARMBLOCK_START->fcp.br_lba);
-
-enum ipl_type_type {
- ipl_type_unknown,
- ipl_type_ccw,
- ipl_type_fcp,
-};
-
-static enum ipl_type_type
-get_ipl_type(void)
-{
- struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
-
- if (!IPL_DEVNO_VALID)
- return ipl_type_unknown;
- if (!IPL_PARMBLOCK_VALID)
- return ipl_type_ccw;
- if (ipl->hdr.header.version > IPL_MAX_SUPPORTED_VERSION)
- return ipl_type_unknown;
- if (ipl->fcp.pbt != IPL_TYPE_FCP)
- return ipl_type_unknown;
- return ipl_type_fcp;
-}
-
-static ssize_t
-ipl_type_show(struct subsystem *subsys, char *page)
-{
- switch (get_ipl_type()) {
- case ipl_type_ccw:
- return sprintf(page, "ccw\n");
- case ipl_type_fcp:
- return sprintf(page, "fcp\n");
- default:
- return sprintf(page, "unknown\n");
- }
-}
-
-static struct subsys_attribute ipl_type_attr = __ATTR_RO(ipl_type);
-
-static ssize_t
-ipl_device_show(struct subsystem *subsys, char *page)
-{
- struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
-
- switch (get_ipl_type()) {
- case ipl_type_ccw:
- return sprintf(page, "0.0.%04x\n", ipl_devno);
- case ipl_type_fcp:
- return sprintf(page, "0.0.%04x\n", ipl->fcp.devno);
- default:
- return 0;
- }
-}
-
-static struct subsys_attribute ipl_device_attr =
- __ATTR(device, S_IRUGO, ipl_device_show, NULL);
-
-static struct attribute *ipl_fcp_attrs[] = {
- &ipl_type_attr.attr,
- &ipl_device_attr.attr,
- &ipl_wwpn_attr.attr,
- &ipl_lun_attr.attr,
- &ipl_bootprog_attr.attr,
- &ipl_br_lba_attr.attr,
- NULL,
-};
-
-static struct attribute_group ipl_fcp_attr_group = {
- .attrs = ipl_fcp_attrs,
-};
-
-static struct attribute *ipl_ccw_attrs[] = {
- &ipl_type_attr.attr,
- &ipl_device_attr.attr,
- NULL,
-};
-
-static struct attribute_group ipl_ccw_attr_group = {
- .attrs = ipl_ccw_attrs,
-};
-
-static struct attribute *ipl_unknown_attrs[] = {
- &ipl_type_attr.attr,
- NULL,
-};
-
-static struct attribute_group ipl_unknown_attr_group = {
- .attrs = ipl_unknown_attrs,
-};
-
-static ssize_t
-ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
-{
- unsigned int size = IPL_PARMBLOCK_SIZE;
-
- if (off > size)
- return 0;
- if (off + count > size)
- count = size - off;
-
- memcpy(buf, (void *) IPL_PARMBLOCK_START + off, count);
- return count;
-}
-
-static struct bin_attribute ipl_parameter_attr = {
- .attr = {
- .name = "binary_parameter",
- .mode = S_IRUGO,
- .owner = THIS_MODULE,
- },
- .size = PAGE_SIZE,
- .read = &ipl_parameter_read,
-};
-
-static ssize_t
-ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
-{
- unsigned int size = IPL_PARMBLOCK_START->fcp.scp_data_len;
- void *scp_data = &IPL_PARMBLOCK_START->fcp.scp_data;
-
- if (off > size)
- return 0;
- if (off + count > size)
- count = size - off;
-
- memcpy(buf, scp_data + off, count);
- return count;
-}
-
-static struct bin_attribute ipl_scp_data_attr = {
- .attr = {
- .name = "scp_data",
- .mode = S_IRUGO,
- .owner = THIS_MODULE,
- },
- .size = PAGE_SIZE,
- .read = &ipl_scp_data_read,
-};
-
-static decl_subsys(ipl, NULL, NULL);
-
-static int ipl_register_fcp_files(void)
-{
- int rc;
-
- rc = sysfs_create_group(&ipl_subsys.kset.kobj,
- &ipl_fcp_attr_group);
- if (rc)
- goto out;
- rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
- &ipl_parameter_attr);
- if (rc)
- goto out_ipl_parm;
- rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
- &ipl_scp_data_attr);
- if (!rc)
- goto out;
-
- sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr);
-
-out_ipl_parm:
- sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
-out:
- return rc;
-}
-
-static int __init
-ipl_device_sysfs_register(void) {
- int rc;
-
- rc = firmware_register(&ipl_subsys);
- if (rc)
- goto out;
-
- switch (get_ipl_type()) {
- case ipl_type_ccw:
- rc = sysfs_create_group(&ipl_subsys.kset.kobj,
- &ipl_ccw_attr_group);
- break;
- case ipl_type_fcp:
- rc = ipl_register_fcp_files();
- break;
- default:
- rc = sysfs_create_group(&ipl_subsys.kset.kobj,
- &ipl_unknown_attr_group);
- break;
- }
-
- if (rc)
- firmware_unregister(&ipl_subsys);
-out:
- return rc;
-}
-
-__initcall(ipl_device_sysfs_register);
diff --git a/trunk/arch/s390/kernel/signal.c b/trunk/arch/s390/kernel/signal.c
index a887b686f279..642095ec7c07 100644
--- a/trunk/arch/s390/kernel/signal.c
+++ b/trunk/arch/s390/kernel/signal.c
@@ -114,29 +114,26 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
{
unsigned long old_mask = regs->psw.mask;
- int err;
-
+ _sigregs user_sregs;
+
save_access_regs(current->thread.acrs);
/* Copy a 'clean' PSW mask to the user to avoid leaking
information about whether PER is currently on. */
regs->psw.mask = PSW_MASK_MERGE(PSW_USER_BITS, regs->psw.mask);
- err = __copy_to_user(&sregs->regs.psw, ®s->psw,
- sizeof(sregs->regs.psw)+sizeof(sregs->regs.gprs));
+ memcpy(&user_sregs.regs.psw, ®s->psw, sizeof(sregs->regs.psw) +
+ sizeof(sregs->regs.gprs));
regs->psw.mask = old_mask;
- if (err != 0)
- return err;
- err = __copy_to_user(&sregs->regs.acrs, current->thread.acrs,
- sizeof(sregs->regs.acrs));
- if (err != 0)
- return err;
+ memcpy(&user_sregs.regs.acrs, current->thread.acrs,
+ sizeof(sregs->regs.acrs));
/*
* We have to store the fp registers to current->thread.fp_regs
* to merge them with the emulated registers.
*/
save_fp_regs(¤t->thread.fp_regs);
- return __copy_to_user(&sregs->fpregs, ¤t->thread.fp_regs,
- sizeof(s390_fp_regs));
+ memcpy(&user_sregs.fpregs, ¤t->thread.fp_regs,
+ sizeof(s390_fp_regs));
+ return __copy_to_user(sregs, &user_sregs, sizeof(_sigregs));
}
/* Returns positive number on error */
@@ -144,27 +141,25 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
{
unsigned long old_mask = regs->psw.mask;
int err;
+ _sigregs user_sregs;
/* Alwys make any pending restarted system call return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
- err = __copy_from_user(®s->psw, &sregs->regs.psw,
- sizeof(sregs->regs.psw)+sizeof(sregs->regs.gprs));
+ err = __copy_from_user(&user_sregs, sregs, sizeof(_sigregs));
regs->psw.mask = PSW_MASK_MERGE(old_mask, regs->psw.mask);
regs->psw.addr |= PSW_ADDR_AMODE;
if (err)
return err;
- err = __copy_from_user(¤t->thread.acrs, &sregs->regs.acrs,
- sizeof(sregs->regs.acrs));
- if (err)
- return err;
+ memcpy(®s->psw, &user_sregs.regs.psw, sizeof(sregs->regs.psw) +
+ sizeof(sregs->regs.gprs));
+ memcpy(¤t->thread.acrs, &user_sregs.regs.acrs,
+ sizeof(sregs->regs.acrs));
restore_access_regs(current->thread.acrs);
- err = __copy_from_user(¤t->thread.fp_regs, &sregs->fpregs,
- sizeof(s390_fp_regs));
+ memcpy(¤t->thread.fp_regs, &user_sregs.fpregs,
+ sizeof(s390_fp_regs));
current->thread.fp_regs.fpc &= FPC_VALID_MASK;
- if (err)
- return err;
restore_fp_regs(¤t->thread.fp_regs);
regs->trap = -1; /* disable syscall checks */
@@ -457,6 +452,7 @@ void do_signal(struct pt_regs *regs)
case -ERESTART_RESTARTBLOCK:
regs->gprs[2] = -EINTR;
}
+ regs->trap = -1; /* Don't deal with this again. */
}
/* Get signal to deliver. When running under ptrace, at this point
diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c
index 8e03219eea76..b2e6f4c8d382 100644
--- a/trunk/arch/s390/kernel/smp.c
+++ b/trunk/arch/s390/kernel/smp.c
@@ -59,9 +59,6 @@ static struct task_struct *current_set[NR_CPUS];
extern char vmhalt_cmd[];
extern char vmpoff_cmd[];
-extern void reipl(unsigned long devno);
-extern void reipl_diag(void);
-
static void smp_ext_bitcall(int, ec_bit_sig);
static void smp_ext_bitcall_others(ec_bit_sig);
@@ -279,12 +276,7 @@ static void do_machine_restart(void * __unused)
* interrupted by an external interrupt and s390irq
* locks are always held disabled).
*/
- reipl_diag();
-
- if (MACHINE_IS_VM)
- cpcmd ("IPL", NULL, 0, NULL);
- else
- reipl (0x10000 | S390_lowcore.ipl_device);
+ do_reipl();
}
void machine_restart_smp(char * __unused)
diff --git a/trunk/arch/s390/kernel/traps.c b/trunk/arch/s390/kernel/traps.c
index bde1d1d59858..c4982c963424 100644
--- a/trunk/arch/s390/kernel/traps.c
+++ b/trunk/arch/s390/kernel/traps.c
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
@@ -39,6 +40,7 @@
#include
#include
#include
+#include
/* Called from entry.S only */
extern void handle_per_exception(struct pt_regs *regs);
@@ -74,6 +76,20 @@ static int kstack_depth_to_print = 12;
static int kstack_depth_to_print = 20;
#endif /* CONFIG_64BIT */
+ATOMIC_NOTIFIER_HEAD(s390die_chain);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&s390die_chain, nb);
+}
+EXPORT_SYMBOL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&s390die_chain, nb);
+}
+EXPORT_SYMBOL(unregister_die_notifier);
+
/*
* For show_trace we have tree different stack to consider:
* - the panic stack which is used if the kernel stack has overflown
@@ -305,8 +321,9 @@ report_user_fault(long interruption_code, struct pt_regs *regs)
#endif
}
-static void inline do_trap(long interruption_code, int signr, char *str,
- struct pt_regs *regs, siginfo_t *info)
+static void __kprobes inline do_trap(long interruption_code, int signr,
+ char *str, struct pt_regs *regs,
+ siginfo_t *info)
{
/*
* We got all needed information from the lowcore and can
@@ -315,6 +332,10 @@ static void inline do_trap(long interruption_code, int signr, char *str,
if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable();
+ if (notify_die(DIE_TRAP, str, regs, interruption_code,
+ interruption_code, signr) == NOTIFY_STOP)
+ return;
+
if (regs->psw.mask & PSW_MASK_PSTATE) {
struct task_struct *tsk = current;
@@ -336,8 +357,12 @@ static inline void __user *get_check_address(struct pt_regs *regs)
return (void __user *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN);
}
-void do_single_step(struct pt_regs *regs)
+void __kprobes do_single_step(struct pt_regs *regs)
{
+ if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0,
+ SIGTRAP) == NOTIFY_STOP){
+ return;
+ }
if ((current->ptrace & PT_PTRACED) != 0)
force_sig(SIGTRAP, current);
}
diff --git a/trunk/arch/s390/kernel/vmlinux.lds.S b/trunk/arch/s390/kernel/vmlinux.lds.S
index ff5f7bb34f75..af9e69a03011 100644
--- a/trunk/arch/s390/kernel/vmlinux.lds.S
+++ b/trunk/arch/s390/kernel/vmlinux.lds.S
@@ -24,6 +24,7 @@ SECTIONS
*(.text)
SCHED_TEXT
LOCK_TEXT
+ KPROBES_TEXT
*(.fixup)
*(.gnu.warning)
} = 0x0700
@@ -117,7 +118,7 @@ SECTIONS
/* Sections to be discarded */
/DISCARD/ : {
- *(.exitcall.exit)
+ *(.exit.text) *(.exit.data) *(.exitcall.exit)
}
/* Stabs debugging sections. */
diff --git a/trunk/arch/s390/lib/Makefile b/trunk/arch/s390/lib/Makefile
index e05d087a6eae..c42ffedfdb49 100644
--- a/trunk/arch/s390/lib/Makefile
+++ b/trunk/arch/s390/lib/Makefile
@@ -4,6 +4,6 @@
EXTRA_AFLAGS := -traditional
-lib-y += delay.o string.o
-lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
+lib-y += delay.o string.o uaccess_std.o
+lib-$(CONFIG_64BIT) += uaccess_mvcos.o
lib-$(CONFIG_SMP) += spinlock.o
diff --git a/trunk/arch/s390/lib/uaccess.S b/trunk/arch/s390/lib/uaccess.S
deleted file mode 100644
index 837275284d9f..000000000000
--- a/trunk/arch/s390/lib/uaccess.S
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * arch/s390/lib/uaccess.S
- * __copy_{from|to}_user functions.
- *
- * s390
- * Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
- *
- * These functions have standard call interface
- */
-
-#include
-#include
-#include
-
- .text
- .align 4
- .globl __copy_from_user_asm
- # %r2 = to, %r3 = n, %r4 = from
-__copy_from_user_asm:
- slr %r0,%r0
-0: mvcp 0(%r3,%r2),0(%r4),%r0
- jnz 1f
- slr %r2,%r2
- br %r14
-1: la %r2,256(%r2)
- la %r4,256(%r4)
- ahi %r3,-256
-2: mvcp 0(%r3,%r2),0(%r4),%r0
- jnz 1b
-3: slr %r2,%r2
- br %r14
-4: lhi %r0,-4096
- lr %r5,%r4
- slr %r5,%r0
- nr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
- slr %r5,%r4 # %r5 = #bytes to next user page boundary
- clr %r3,%r5 # copy crosses next page boundary ?
- jnh 6f # no, the current page faulted
- # move with the reduced length which is < 256
-5: mvcp 0(%r5,%r2),0(%r4),%r0
- slr %r3,%r5
-6: lr %r2,%r3
- br %r14
- .section __ex_table,"a"
- .long 0b,4b
- .long 2b,4b
- .long 5b,6b
- .previous
-
- .align 4
- .text
- .globl __copy_to_user_asm
- # %r2 = from, %r3 = n, %r4 = to
-__copy_to_user_asm:
- slr %r0,%r0
-0: mvcs 0(%r3,%r4),0(%r2),%r0
- jnz 1f
- slr %r2,%r2
- br %r14
-1: la %r2,256(%r2)
- la %r4,256(%r4)
- ahi %r3,-256
-2: mvcs 0(%r3,%r4),0(%r2),%r0
- jnz 1b
-3: slr %r2,%r2
- br %r14
-4: lhi %r0,-4096
- lr %r5,%r4
- slr %r5,%r0
- nr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
- slr %r5,%r4 # %r5 = #bytes to next user page boundary
- clr %r3,%r5 # copy crosses next page boundary ?
- jnh 6f # no, the current page faulted
- # move with the reduced length which is < 256
-5: mvcs 0(%r5,%r4),0(%r2),%r0
- slr %r3,%r5
-6: lr %r2,%r3
- br %r14
- .section __ex_table,"a"
- .long 0b,4b
- .long 2b,4b
- .long 5b,6b
- .previous
-
- .align 4
- .text
- .globl __copy_in_user_asm
- # %r2 = from, %r3 = n, %r4 = to
-__copy_in_user_asm:
- ahi %r3,-1
- jo 6f
- sacf 256
- bras %r1,4f
-0: ahi %r3,257
-1: mvc 0(1,%r4),0(%r2)
- la %r2,1(%r2)
- la %r4,1(%r4)
- ahi %r3,-1
- jnz 1b
-2: lr %r2,%r3
- br %r14
-3: mvc 0(256,%r4),0(%r2)
- la %r2,256(%r2)
- la %r4,256(%r4)
-4: ahi %r3,-256
- jnm 3b
-5: ex %r3,4(%r1)
- sacf 0
-6: slr %r2,%r2
- br %r14
- .section __ex_table,"a"
- .long 1b,2b
- .long 3b,0b
- .long 5b,0b
- .previous
-
- .align 4
- .text
- .globl __clear_user_asm
- # %r2 = to, %r3 = n
-__clear_user_asm:
- bras %r5,0f
- .long empty_zero_page
-0: l %r5,0(%r5)
- slr %r0,%r0
-1: mvcs 0(%r3,%r2),0(%r5),%r0
- jnz 2f
- slr %r2,%r2
- br %r14
-2: la %r2,256(%r2)
- ahi %r3,-256
-3: mvcs 0(%r3,%r2),0(%r5),%r0
- jnz 2b
-4: slr %r2,%r2
- br %r14
-5: lhi %r0,-4096
- lr %r4,%r2
- slr %r4,%r0
- nr %r4,%r0 # %r4 = (%r2 + 4096) & -4096
- slr %r4,%r2 # %r4 = #bytes to next user page boundary
- clr %r3,%r4 # clear crosses next page boundary ?
- jnh 7f # no, the current page faulted
- # clear with the reduced length which is < 256
-6: mvcs 0(%r4,%r2),0(%r5),%r0
- slr %r3,%r4
-7: lr %r2,%r3
- br %r14
- .section __ex_table,"a"
- .long 1b,5b
- .long 3b,5b
- .long 6b,7b
- .previous
-
- .align 4
- .text
- .globl __strncpy_from_user_asm
- # %r2 = count, %r3 = dst, %r4 = src
-__strncpy_from_user_asm:
- lhi %r0,0
- lr %r1,%r4
- la %r4,0(%r4) # clear high order bit from %r4
- la %r2,0(%r2,%r4) # %r2 points to first byte after string
- sacf 256
-0: srst %r2,%r1
- jo 0b
- sacf 0
- lr %r1,%r2
- jh 1f # \0 found in string ?
- ahi %r1,1 # include \0 in copy
-1: slr %r1,%r4 # %r1 = copy length (without \0)
- slr %r2,%r4 # %r2 = return length (including \0)
-2: mvcp 0(%r1,%r3),0(%r4),%r0
- jnz 3f
- br %r14
-3: la %r3,256(%r3)
- la %r4,256(%r4)
- ahi %r1,-256
- mvcp 0(%r1,%r3),0(%r4),%r0
- jnz 3b
- br %r14
-4: sacf 0
- lhi %r2,-EFAULT
- br %r14
- .section __ex_table,"a"
- .long 0b,4b
- .previous
-
- .align 4
- .text
- .globl __strnlen_user_asm
- # %r2 = count, %r3 = src
-__strnlen_user_asm:
- lhi %r0,0
- lr %r1,%r3
- la %r3,0(%r3) # clear high order bit from %r4
- la %r2,0(%r2,%r3) # %r2 points to first byte after string
- sacf 256
-0: srst %r2,%r1
- jo 0b
- sacf 0
- ahi %r2,1 # strnlen_user result includes the \0
- # or return count+1 if \0 not found
- slr %r2,%r3
- br %r14
-2: sacf 0
- slr %r2,%r2 # return 0 on exception
- br %r14
- .section __ex_table,"a"
- .long 0b,2b
- .previous
diff --git a/trunk/arch/s390/lib/uaccess64.S b/trunk/arch/s390/lib/uaccess64.S
deleted file mode 100644
index 1f755be22f92..000000000000
--- a/trunk/arch/s390/lib/uaccess64.S
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * arch/s390x/lib/uaccess.S
- * __copy_{from|to}_user functions.
- *
- * s390
- * Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
- *
- * These functions have standard call interface
- */
-
-#include
-#include
-#include
-
- .text
- .align 4
- .globl __copy_from_user_asm
- # %r2 = to, %r3 = n, %r4 = from
-__copy_from_user_asm:
- slgr %r0,%r0
-0: mvcp 0(%r3,%r2),0(%r4),%r0
- jnz 1f
- slgr %r2,%r2
- br %r14
-1: la %r2,256(%r2)
- la %r4,256(%r4)
- aghi %r3,-256
-2: mvcp 0(%r3,%r2),0(%r4),%r0
- jnz 1b
-3: slgr %r2,%r2
- br %r14
-4: lghi %r0,-4096
- lgr %r5,%r4
- slgr %r5,%r0
- ngr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
- slgr %r5,%r4 # %r5 = #bytes to next user page boundary
- clgr %r3,%r5 # copy crosses next page boundary ?
- jnh 6f # no, the current page faulted
- # move with the reduced length which is < 256
-5: mvcp 0(%r5,%r2),0(%r4),%r0
- slgr %r3,%r5
-6: lgr %r2,%r3
- br %r14
- .section __ex_table,"a"
- .quad 0b,4b
- .quad 2b,4b
- .quad 5b,6b
- .previous
-
- .align 4
- .text
- .globl __copy_to_user_asm
- # %r2 = from, %r3 = n, %r4 = to
-__copy_to_user_asm:
- slgr %r0,%r0
-0: mvcs 0(%r3,%r4),0(%r2),%r0
- jnz 1f
- slgr %r2,%r2
- br %r14
-1: la %r2,256(%r2)
- la %r4,256(%r4)
- aghi %r3,-256
-2: mvcs 0(%r3,%r4),0(%r2),%r0
- jnz 1b
-3: slgr %r2,%r2
- br %r14
-4: lghi %r0,-4096
- lgr %r5,%r4
- slgr %r5,%r0
- ngr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
- slgr %r5,%r4 # %r5 = #bytes to next user page boundary
- clgr %r3,%r5 # copy crosses next page boundary ?
- jnh 6f # no, the current page faulted
- # move with the reduced length which is < 256
-5: mvcs 0(%r5,%r4),0(%r2),%r0
- slgr %r3,%r5
-6: lgr %r2,%r3
- br %r14
- .section __ex_table,"a"
- .quad 0b,4b
- .quad 2b,4b
- .quad 5b,6b
- .previous
-
- .align 4
- .text
- .globl __copy_in_user_asm
- # %r2 = from, %r3 = n, %r4 = to
-__copy_in_user_asm:
- aghi %r3,-1
- jo 6f
- sacf 256
- bras %r1,4f
-0: aghi %r3,257
-1: mvc 0(1,%r4),0(%r2)
- la %r2,1(%r2)
- la %r4,1(%r4)
- aghi %r3,-1
- jnz 1b
-2: lgr %r2,%r3
- br %r14
-3: mvc 0(256,%r4),0(%r2)
- la %r2,256(%r2)
- la %r4,256(%r4)
-4: aghi %r3,-256
- jnm 3b
-5: ex %r3,4(%r1)
- sacf 0
-6: slgr %r2,%r2
- br 14
- .section __ex_table,"a"
- .quad 1b,2b
- .quad 3b,0b
- .quad 5b,0b
- .previous
-
- .align 4
- .text
- .globl __clear_user_asm
- # %r2 = to, %r3 = n
-__clear_user_asm:
- slgr %r0,%r0
- larl %r5,empty_zero_page
-1: mvcs 0(%r3,%r2),0(%r5),%r0
- jnz 2f
- slgr %r2,%r2
- br %r14
-2: la %r2,256(%r2)
- aghi %r3,-256
-3: mvcs 0(%r3,%r2),0(%r5),%r0
- jnz 2b
-4: slgr %r2,%r2
- br %r14
-5: lghi %r0,-4096
- lgr %r4,%r2
- slgr %r4,%r0
- ngr %r4,%r0 # %r4 = (%r2 + 4096) & -4096
- slgr %r4,%r2 # %r4 = #bytes to next user page boundary
- clgr %r3,%r4 # clear crosses next page boundary ?
- jnh 7f # no, the current page faulted
- # clear with the reduced length which is < 256
-6: mvcs 0(%r4,%r2),0(%r5),%r0
- slgr %r3,%r4
-7: lgr %r2,%r3
- br %r14
- .section __ex_table,"a"
- .quad 1b,5b
- .quad 3b,5b
- .quad 6b,7b
- .previous
-
- .align 4
- .text
- .globl __strncpy_from_user_asm
- # %r2 = count, %r3 = dst, %r4 = src
-__strncpy_from_user_asm:
- lghi %r0,0
- lgr %r1,%r4
- la %r2,0(%r2,%r4) # %r2 points to first byte after string
- sacf 256
-0: srst %r2,%r1
- jo 0b
- sacf 0
- lgr %r1,%r2
- jh 1f # \0 found in string ?
- aghi %r1,1 # include \0 in copy
-1: slgr %r1,%r4 # %r1 = copy length (without \0)
- slgr %r2,%r4 # %r2 = return length (including \0)
-2: mvcp 0(%r1,%r3),0(%r4),%r0
- jnz 3f
- br %r14
-3: la %r3,256(%r3)
- la %r4,256(%r4)
- aghi %r1,-256
- mvcp 0(%r1,%r3),0(%r4),%r0
- jnz 3b
- br %r14
-4: sacf 0
- lghi %r2,-EFAULT
- br %r14
- .section __ex_table,"a"
- .quad 0b,4b
- .previous
-
- .align 4
- .text
- .globl __strnlen_user_asm
- # %r2 = count, %r3 = src
-__strnlen_user_asm:
- lghi %r0,0
- lgr %r1,%r3
- la %r2,0(%r2,%r3) # %r2 points to first byte after string
- sacf 256
-0: srst %r2,%r1
- jo 0b
- sacf 0
- aghi %r2,1 # strnlen_user result includes the \0
- # or return count+1 if \0 not found
- slgr %r2,%r3
- br %r14
-2: sacf 0
- slgr %r2,%r2 # return 0 on exception
- br %r14
- .section __ex_table,"a"
- .quad 0b,2b
- .previous
diff --git a/trunk/arch/s390/lib/uaccess_mvcos.c b/trunk/arch/s390/lib/uaccess_mvcos.c
new file mode 100644
index 000000000000..86c96d6c191a
--- /dev/null
+++ b/trunk/arch/s390/lib/uaccess_mvcos.c
@@ -0,0 +1,156 @@
+/*
+ * arch/s390/lib/uaccess_mvcos.c
+ *
+ * Optimized user space space access functions based on mvcos.
+ *
+ * Copyright (C) IBM Corp. 2006
+ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ * Gerald Schaefer (gerald.schaefer@de.ibm.com)
+ */
+
+#include
+#include
+#include
+#include
+
+#ifndef __s390x__
+#define AHI "ahi"
+#define ALR "alr"
+#define CLR "clr"
+#define LHI "lhi"
+#define SLR "slr"
+#else
+#define AHI "aghi"
+#define ALR "algr"
+#define CLR "clgr"
+#define LHI "lghi"
+#define SLR "slgr"
+#endif
+
+size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
+{
+ register unsigned long reg0 asm("0") = 0x81UL;
+ unsigned long tmp1, tmp2;
+
+ tmp1 = -4096UL;
+ asm volatile(
+ "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n"
+ " jz 4f\n"
+ "1:"ALR" %0,%3\n"
+ " "SLR" %1,%3\n"
+ " "SLR" %2,%3\n"
+ " j 0b\n"
+ "2: la %4,4095(%1)\n"/* %4 = ptr + 4095 */
+ " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */
+ " "SLR" %4,%1\n"
+ " "CLR" %0,%4\n" /* copy crosses next page boundary? */
+ " jnh 5f\n"
+ "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n"
+ " "SLR" %0,%4\n"
+ " j 5f\n"
+ "4:"SLR" %0,%0\n"
+ "5: \n"
+ EX_TABLE(0b,2b) EX_TABLE(3b,5b)
+ : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
+ : "d" (reg0) : "cc", "memory");
+ return size;
+}
+
+size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
+{
+ register unsigned long reg0 asm("0") = 0x810000UL;
+ unsigned long tmp1, tmp2;
+
+ tmp1 = -4096UL;
+ asm volatile(
+ "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
+ " jz 4f\n"
+ "1:"ALR" %0,%3\n"
+ " "SLR" %1,%3\n"
+ " "SLR" %2,%3\n"
+ " j 0b\n"
+ "2: la %4,4095(%1)\n"/* %4 = ptr + 4095 */
+ " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */
+ " "SLR" %4,%1\n"
+ " "CLR" %0,%4\n" /* copy crosses next page boundary? */
+ " jnh 5f\n"
+ "3: .insn ss,0xc80000000000,0(%4,%1),0(%2),0\n"
+ " "SLR" %0,%4\n"
+ " j 5f\n"
+ "4:"SLR" %0,%0\n"
+ "5: \n"
+ EX_TABLE(0b,2b) EX_TABLE(3b,5b)
+ : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
+ : "d" (reg0) : "cc", "memory");
+ return size;
+}
+
+size_t copy_in_user_mvcos(size_t size, void __user *to, const void __user *from)
+{
+ register unsigned long reg0 asm("0") = 0x810081UL;
+ unsigned long tmp1, tmp2;
+
+ tmp1 = -4096UL;
+ /* FIXME: copy with reduced length. */
+ asm volatile(
+ "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
+ " jz 2f\n"
+ "1:"ALR" %0,%3\n"
+ " "SLR" %1,%3\n"
+ " "SLR" %2,%3\n"
+ " j 0b\n"
+ "2:"SLR" %0,%0\n"
+ "3: \n"
+ EX_TABLE(0b,3b)
+ : "+a" (size), "+a" (to), "+a" (from), "+a" (tmp1), "=a" (tmp2)
+ : "d" (reg0) : "cc", "memory");
+ return size;
+}
+
+size_t clear_user_mvcos(size_t size, void __user *to)
+{
+ register unsigned long reg0 asm("0") = 0x810000UL;
+ unsigned long tmp1, tmp2;
+
+ tmp1 = -4096UL;
+ asm volatile(
+ "0: .insn ss,0xc80000000000,0(%0,%1),0(%4),0\n"
+ " jz 4f\n"
+ "1:"ALR" %0,%2\n"
+ " "SLR" %1,%2\n"
+ " j 0b\n"
+ "2: la %3,4095(%1)\n"/* %4 = to + 4095 */
+ " nr %3,%2\n" /* %4 = (to + 4095) & -4096 */
+ " "SLR" %3,%1\n"
+ " "CLR" %0,%3\n" /* copy crosses next page boundary? */
+ " jnh 5f\n"
+ "3: .insn ss,0xc80000000000,0(%3,%1),0(%4),0\n"
+ " "SLR" %0,%3\n"
+ " j 5f\n"
+ "4:"SLR" %0,%0\n"
+ "5: \n"
+ EX_TABLE(0b,2b) EX_TABLE(3b,5b)
+ : "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
+ : "a" (empty_zero_page), "d" (reg0) : "cc", "memory");
+ return size;
+}
+
+extern size_t copy_from_user_std_small(size_t, const void __user *, void *);
+extern size_t copy_to_user_std_small(size_t, void __user *, const void *);
+extern size_t strnlen_user_std(size_t, const char __user *);
+extern size_t strncpy_from_user_std(size_t, const char __user *, char *);
+extern int futex_atomic_op(int, int __user *, int, int *);
+extern int futex_atomic_cmpxchg(int __user *, int, int);
+
+struct uaccess_ops uaccess_mvcos = {
+ .copy_from_user = copy_from_user_mvcos,
+ .copy_from_user_small = copy_from_user_std_small,
+ .copy_to_user = copy_to_user_mvcos,
+ .copy_to_user_small = copy_to_user_std_small,
+ .copy_in_user = copy_in_user_mvcos,
+ .clear_user = clear_user_mvcos,
+ .strnlen_user = strnlen_user_std,
+ .strncpy_from_user = strncpy_from_user_std,
+ .futex_atomic_op = futex_atomic_op,
+ .futex_atomic_cmpxchg = futex_atomic_cmpxchg,
+};
diff --git a/trunk/arch/s390/lib/uaccess_std.c b/trunk/arch/s390/lib/uaccess_std.c
new file mode 100644
index 000000000000..9a4d4a29ea79
--- /dev/null
+++ b/trunk/arch/s390/lib/uaccess_std.c
@@ -0,0 +1,340 @@
+/*
+ * arch/s390/lib/uaccess_std.c
+ *
+ * Standard user space access functions based on mvcp/mvcs and doing
+ * interesting things in the secondary space mode.
+ *
+ * Copyright (C) IBM Corp. 2006
+ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ * Gerald Schaefer (gerald.schaefer@de.ibm.com)
+ */
+
+#include
+#include
+#include
+#include
+
+#ifndef __s390x__
+#define AHI "ahi"
+#define ALR "alr"
+#define CLR "clr"
+#define LHI "lhi"
+#define SLR "slr"
+#else
+#define AHI "aghi"
+#define ALR "algr"
+#define CLR "clgr"
+#define LHI "lghi"
+#define SLR "slgr"
+#endif
+
+size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
+{
+ unsigned long tmp1, tmp2;
+
+ tmp1 = -256UL;
+ asm volatile(
+ "0: mvcp 0(%0,%2),0(%1),%3\n"
+ " jz 5f\n"
+ "1:"ALR" %0,%3\n"
+ " la %1,256(%1)\n"
+ " la %2,256(%2)\n"
+ "2: mvcp 0(%0,%2),0(%1),%3\n"
+ " jnz 1b\n"
+ " j 5f\n"
+ "3: la %4,255(%1)\n" /* %4 = ptr + 255 */
+ " "LHI" %3,-4096\n"
+ " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
+ " "SLR" %4,%1\n"
+ " "CLR" %0,%4\n" /* copy crosses next page boundary? */
+ " jnh 6f\n"
+ "4: mvcp 0(%4,%2),0(%1),%3\n"
+ " "SLR" %0,%4\n"
+ " j 6f\n"
+ "5:"SLR" %0,%0\n"
+ "6: \n"
+ EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
+ : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
+ : : "cc", "memory");
+ return size;
+}
+
+size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x)
+{
+ unsigned long tmp1, tmp2;
+
+ tmp1 = 0UL;
+ asm volatile(
+ "0: mvcp 0(%0,%2),0(%1),%3\n"
+ " "SLR" %0,%0\n"
+ " j 3f\n"
+ "1: la %4,255(%1)\n" /* %4 = ptr + 255 */
+ " "LHI" %3,-4096\n"
+ " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
+ " "SLR" %4,%1\n"
+ " "CLR" %0,%4\n" /* copy crosses next page boundary? */
+ " jnh 3f\n"
+ "2: mvcp 0(%4,%2),0(%1),%3\n"
+ " "SLR" %0,%4\n"
+ "3:\n"
+ EX_TABLE(0b,1b) EX_TABLE(2b,3b)
+ : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
+ : : "cc", "memory");
+ return size;
+}
+
+size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
+{
+ unsigned long tmp1, tmp2;
+
+ tmp1 = -256UL;
+ asm volatile(
+ "0: mvcs 0(%0,%1),0(%2),%3\n"
+ " jz 5f\n"
+ "1:"ALR" %0,%3\n"
+ " la %1,256(%1)\n"
+ " la %2,256(%2)\n"
+ "2: mvcs 0(%0,%1),0(%2),%3\n"
+ " jnz 1b\n"
+ " j 5f\n"
+ "3: la %4,255(%1)\n" /* %4 = ptr + 255 */
+ " "LHI" %3,-4096\n"
+ " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
+ " "SLR" %4,%1\n"
+ " "CLR" %0,%4\n" /* copy crosses next page boundary? */
+ " jnh 6f\n"
+ "4: mvcs 0(%4,%1),0(%2),%3\n"
+ " "SLR" %0,%4\n"
+ " j 6f\n"
+ "5:"SLR" %0,%0\n"
+ "6: \n"
+ EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
+ : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
+ : : "cc", "memory");
+ return size;
+}
+
+size_t copy_to_user_std_small(size_t size, void __user *ptr, const void *x)
+{
+ unsigned long tmp1, tmp2;
+
+ tmp1 = 0UL;
+ asm volatile(
+ "0: mvcs 0(%0,%1),0(%2),%3\n"
+ " "SLR" %0,%0\n"
+ " j 3f\n"
+ "1: la %4,255(%1)\n" /* ptr + 255 */
+ " "LHI" %3,-4096\n"
+ " nr %4,%3\n" /* (ptr + 255) & -4096UL */
+ " "SLR" %4,%1\n"
+ " "CLR" %0,%4\n" /* copy crosses next page boundary? */
+ " jnh 3f\n"
+ "2: mvcs 0(%4,%1),0(%2),%3\n"
+ " "SLR" %0,%4\n"
+ "3:\n"
+ EX_TABLE(0b,1b) EX_TABLE(2b,3b)
+ : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
+ : : "cc", "memory");
+ return size;
+}
+
+size_t copy_in_user_std(size_t size, void __user *to, const void __user *from)
+{
+ unsigned long tmp1;
+
+ asm volatile(
+ " "AHI" %0,-1\n"
+ " jo 5f\n"
+ " sacf 256\n"
+ " bras %3,3f\n"
+ "0:"AHI" %0,257\n"
+ "1: mvc 0(1,%1),0(%2)\n"
+ " la %1,1(%1)\n"
+ " la %2,1(%2)\n"
+ " "AHI" %0,-1\n"
+ " jnz 1b\n"
+ " j 5f\n"
+ "2: mvc 0(256,%1),0(%2)\n"
+ " la %1,256(%1)\n"
+ " la %2,256(%2)\n"
+ "3:"AHI" %0,-256\n"
+ " jnm 2b\n"
+ "4: ex %0,1b-0b(%3)\n"
+ " sacf 0\n"
+ "5: "SLR" %0,%0\n"
+ "6:\n"
+ EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
+ : "+a" (size), "+a" (to), "+a" (from), "=a" (tmp1)
+ : : "cc", "memory");
+ return size;
+}
+
+size_t clear_user_std(size_t size, void __user *to)
+{
+ unsigned long tmp1, tmp2;
+
+ asm volatile(
+ " "AHI" %0,-1\n"
+ " jo 5f\n"
+ " sacf 256\n"
+ " bras %3,3f\n"
+ " xc 0(1,%1),0(%1)\n"
+ "0:"AHI" %0,257\n"
+ " la %2,255(%1)\n" /* %2 = ptr + 255 */
+ " srl %2,12\n"
+ " sll %2,12\n" /* %2 = (ptr + 255) & -4096 */
+ " "SLR" %2,%1\n"
+ " "CLR" %0,%2\n" /* clear crosses next page boundary? */
+ " jnh 5f\n"
+ " "AHI" %2,-1\n"
+ "1: ex %2,0(%3)\n"
+ " "AHI" %2,1\n"
+ " "SLR" %0,%2\n"
+ " j 5f\n"
+ "2: xc 0(256,%1),0(%1)\n"
+ " la %1,256(%1)\n"
+ "3:"AHI" %0,-256\n"
+ " jnm 2b\n"
+ "4: ex %0,0(%3)\n"
+ " sacf 0\n"
+ "5: "SLR" %0,%0\n"
+ "6:\n"
+ EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
+ : "+a" (size), "+a" (to), "=a" (tmp1), "=a" (tmp2)
+ : : "cc", "memory");
+ return size;
+}
+
+size_t strnlen_user_std(size_t size, const char __user *src)
+{
+ register unsigned long reg0 asm("0") = 0UL;
+ unsigned long tmp1, tmp2;
+
+ asm volatile(
+ " la %2,0(%1)\n"
+ " la %3,0(%0,%1)\n"
+ " "SLR" %0,%0\n"
+ " sacf 256\n"
+ "0: srst %3,%2\n"
+ " jo 0b\n"
+ " la %0,1(%3)\n" /* strnlen_user results includes \0 */
+ " "SLR" %0,%1\n"
+ "1: sacf 0\n"
+ EX_TABLE(0b,1b)
+ : "+a" (size), "+a" (src), "=a" (tmp1), "=a" (tmp2)
+ : "d" (reg0) : "cc", "memory");
+ return size;
+}
+
+size_t strncpy_from_user_std(size_t size, const char __user *src, char *dst)
+{
+ register unsigned long reg0 asm("0") = 0UL;
+ unsigned long tmp1, tmp2;
+
+ asm volatile(
+ " la %3,0(%1)\n"
+ " la %4,0(%0,%1)\n"
+ " sacf 256\n"
+ "0: srst %4,%3\n"
+ " jo 0b\n"
+ " sacf 0\n"
+ " la %0,0(%4)\n"
+ " jh 1f\n" /* found \0 in string ? */
+ " "AHI" %4,1\n" /* include \0 in copy */
+ "1:"SLR" %0,%1\n" /* %0 = return length (without \0) */
+ " "SLR" %4,%1\n" /* %4 = copy length (including \0) */
+ "2: mvcp 0(%4,%2),0(%1),%5\n"
+ " jz 9f\n"
+ "3:"AHI" %4,-256\n"
+ " la %1,256(%1)\n"
+ " la %2,256(%2)\n"
+ "4: mvcp 0(%4,%2),0(%1),%5\n"
+ " jnz 3b\n"
+ " j 9f\n"
+ "7: sacf 0\n"
+ "8:"LHI" %0,%6\n"
+ "9:\n"
+ EX_TABLE(0b,7b) EX_TABLE(2b,8b) EX_TABLE(4b,8b)
+ : "+a" (size), "+a" (src), "+d" (dst), "=a" (tmp1), "=a" (tmp2)
+ : "d" (reg0), "K" (-EFAULT) : "cc", "memory");
+ return size;
+}
+
+#define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \
+ asm volatile( \
+ " sacf 256\n" \
+ "0: l %1,0(%6)\n" \
+ "1:"insn \
+ "2: cs %1,%2,0(%6)\n" \
+ "3: jl 1b\n" \
+ " lhi %0,0\n" \
+ "4: sacf 0\n" \
+ EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \
+ : "=d" (ret), "=&d" (oldval), "=&d" (newval), \
+ "=m" (*uaddr) \
+ : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
+ "m" (*uaddr) : "cc");
+
+int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old)
+{
+ int oldval = 0, newval, ret;
+
+ inc_preempt_count();
+
+ switch (op) {
+ case FUTEX_OP_SET:
+ __futex_atomic_op("lr %2,%5\n",
+ ret, oldval, newval, uaddr, oparg);
+ break;
+ case FUTEX_OP_ADD:
+ __futex_atomic_op("lr %2,%1\nar %2,%5\n",
+ ret, oldval, newval, uaddr, oparg);
+ break;
+ case FUTEX_OP_OR:
+ __futex_atomic_op("lr %2,%1\nor %2,%5\n",
+ ret, oldval, newval, uaddr, oparg);
+ break;
+ case FUTEX_OP_ANDN:
+ __futex_atomic_op("lr %2,%1\nnr %2,%5\n",
+ ret, oldval, newval, uaddr, oparg);
+ break;
+ case FUTEX_OP_XOR:
+ __futex_atomic_op("lr %2,%1\nxr %2,%5\n",
+ ret, oldval, newval, uaddr, oparg);
+ break;
+ default:
+ ret = -ENOSYS;
+ }
+ dec_preempt_count();
+ *old = oldval;
+ return ret;
+}
+
+int futex_atomic_cmpxchg(int __user *uaddr, int oldval, int newval)
+{
+ int ret;
+
+ asm volatile(
+ " sacf 256\n"
+ " cs %1,%4,0(%5)\n"
+ "0: lr %0,%1\n"
+ "1: sacf 0\n"
+ EX_TABLE(0b,1b)
+ : "=d" (ret), "+d" (oldval), "=m" (*uaddr)
+ : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
+ : "cc", "memory" );
+ return ret;
+}
+
+struct uaccess_ops uaccess_std = {
+ .copy_from_user = copy_from_user_std,
+ .copy_from_user_small = copy_from_user_std_small,
+ .copy_to_user = copy_to_user_std,
+ .copy_to_user_small = copy_to_user_std_small,
+ .copy_in_user = copy_in_user_std,
+ .clear_user = clear_user_std,
+ .strnlen_user = strnlen_user_std,
+ .strncpy_from_user = strncpy_from_user_std,
+ .futex_atomic_op = futex_atomic_op,
+ .futex_atomic_cmpxchg = futex_atomic_cmpxchg,
+};
diff --git a/trunk/arch/s390/mm/cmm.c b/trunk/arch/s390/mm/cmm.c
index ceea51cff03b..786a44dba5bf 100644
--- a/trunk/arch/s390/mm/cmm.c
+++ b/trunk/arch/s390/mm/cmm.c
@@ -52,22 +52,6 @@ static struct timer_list cmm_timer;
static void cmm_timer_fn(unsigned long);
static void cmm_set_timer(void);
-static long
-cmm_strtoul(const char *cp, char **endp)
-{
- unsigned int base = 10;
-
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((*cp == 'x' || *cp == 'X') && isxdigit(cp[1])) {
- base = 16;
- cp++;
- }
- }
- return simple_strtoul(cp, endp, base);
-}
-
static long
cmm_alloc_pages(long pages, long *counter, struct cmm_page_array **list)
{
@@ -276,7 +260,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
return -EFAULT;
buf[sizeof(buf) - 1] = '\0';
cmm_skip_blanks(buf, &p);
- pages = cmm_strtoul(p, &p);
+ pages = simple_strtoul(p, &p, 0);
if (ctl == &cmm_table[0])
cmm_set_pages(pages);
else
@@ -317,9 +301,9 @@ cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
return -EFAULT;
buf[sizeof(buf) - 1] = '\0';
cmm_skip_blanks(buf, &p);
- pages = cmm_strtoul(p, &p);
+ pages = simple_strtoul(p, &p, 0);
cmm_skip_blanks(p, &p);
- seconds = cmm_strtoul(p, &p);
+ seconds = simple_strtoul(p, &p, 0);
cmm_set_timeout(pages, seconds);
} else {
len = sprintf(buf, "%ld %ld\n",
@@ -382,24 +366,24 @@ cmm_smsg_target(char *from, char *msg)
if (strncmp(msg, "SHRINK", 6) == 0) {
if (!cmm_skip_blanks(msg + 6, &msg))
return;
- pages = cmm_strtoul(msg, &msg);
+ pages = simple_strtoul(msg, &msg, 0);
cmm_skip_blanks(msg, &msg);
if (*msg == '\0')
cmm_set_pages(pages);
} else if (strncmp(msg, "RELEASE", 7) == 0) {
if (!cmm_skip_blanks(msg + 7, &msg))
return;
- pages = cmm_strtoul(msg, &msg);
+ pages = simple_strtoul(msg, &msg, 0);
cmm_skip_blanks(msg, &msg);
if (*msg == '\0')
cmm_add_timed_pages(pages);
} else if (strncmp(msg, "REUSE", 5) == 0) {
if (!cmm_skip_blanks(msg + 5, &msg))
return;
- pages = cmm_strtoul(msg, &msg);
+ pages = simple_strtoul(msg, &msg, 0);
if (!cmm_skip_blanks(msg, &msg))
return;
- seconds = cmm_strtoul(msg, &msg);
+ seconds = simple_strtoul(msg, &msg, 0);
cmm_skip_blanks(msg, &msg);
if (*msg == '\0')
cmm_set_timeout(pages, seconds);
diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c
index 7cd82575813d..44f0cda7e72e 100644
--- a/trunk/arch/s390/mm/fault.c
+++ b/trunk/arch/s390/mm/fault.c
@@ -25,10 +25,12 @@
#include
#include
#include
+#include
#include
#include
#include
+#include
#ifndef CONFIG_64BIT
#define __FAIL_ADDR_MASK 0x7ffff000
@@ -48,6 +50,38 @@ extern int sysctl_userprocess_debug;
extern void die(const char *,struct pt_regs *,long);
+#ifdef CONFIG_KPROBES
+ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
+int register_page_fault_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(¬ify_page_fault_chain, nb);
+}
+
+int unregister_page_fault_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb);
+}
+
+static inline int notify_page_fault(enum die_val val, const char *str,
+ struct pt_regs *regs, long err, int trap, int sig)
+{
+ struct die_args args = {
+ .regs = regs,
+ .str = str,
+ .err = err,
+ .trapnr = trap,
+ .signr = sig
+ };
+ return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args);
+}
+#else
+static inline int notify_page_fault(enum die_val val, const char *str,
+ struct pt_regs *regs, long err, int trap, int sig)
+{
+ return NOTIFY_DONE;
+}
+#endif
+
extern spinlock_t timerlist_lock;
/*
@@ -159,7 +193,7 @@ static void do_sigsegv(struct pt_regs *regs, unsigned long error_code,
* 11 Page translation -> Not present (nullification)
* 3b Region third trans. -> Not present (nullification)
*/
-static inline void
+static inline void __kprobes
do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
{
struct task_struct *tsk;
@@ -173,6 +207,10 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
tsk = current;
mm = tsk->mm;
+ if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
+ SIGSEGV) == NOTIFY_STOP)
+ return;
+
/*
* Check for low-address protection. This needs to be treated
* as a special case because the translation exception code
diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c
index 6e6b6de77770..cfd9b8f7a523 100644
--- a/trunk/arch/s390/mm/init.c
+++ b/trunk/arch/s390/mm/init.c
@@ -108,16 +108,23 @@ void __init paging_init(void)
unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE;
static const int ssm_mask = 0x04000000L;
unsigned long ro_start_pfn, ro_end_pfn;
+ unsigned long zones_size[MAX_NR_ZONES];
ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata);
ro_end_pfn = PFN_UP((unsigned long)&__end_rodata);
+ memset(zones_size, 0, sizeof(zones_size));
+ zones_size[ZONE_DMA] = max_low_pfn;
+ free_area_init_node(0, &contig_page_data, zones_size,
+ __pa(PAGE_OFFSET) >> PAGE_SHIFT,
+ zholes_size);
+
/* unmap whole virtual address space */
pg_dir = swapper_pg_dir;
- for (i=0;ipgd0 = (_PAGE_TABLE | __pa(pg_table));
- pg_dir->pgd1 = (_PAGE_TABLE | (__pa(pg_table)+1024));
- pg_dir->pgd2 = (_PAGE_TABLE | (__pa(pg_table)+2048));
- pg_dir->pgd3 = (_PAGE_TABLE | (__pa(pg_table)+3072));
+ pmd_populate_kernel(&init_mm, (pmd_t *) pg_dir, pg_table);
pg_dir++;
for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) {
@@ -143,8 +147,8 @@ void __init paging_init(void)
else
pte = pfn_pte(pfn, PAGE_KERNEL);
if (pfn >= max_low_pfn)
- pte_clear(&init_mm, 0, &pte);
- set_pte(pg_table, pte);
+ pte_val(pte) = _PAGE_TYPE_EMPTY;
+ set_pte(pg_table, pte);
pfn++;
}
}
@@ -159,16 +163,6 @@ void __init paging_init(void)
: : "m" (pgdir_k), "m" (ssm_mask));
local_flush_tlb();
-
- {
- unsigned long zones_size[MAX_NR_ZONES];
-
- memset(zones_size, 0, sizeof(zones_size));
- zones_size[ZONE_DMA] = max_low_pfn;
- free_area_init_node(0, &contig_page_data, zones_size,
- __pa(PAGE_OFFSET) >> PAGE_SHIFT,
- zholes_size);
- }
return;
}
@@ -236,10 +230,8 @@ void __init paging_init(void)
pte = pfn_pte(pfn, __pgprot(_PAGE_RO));
else
pte = pfn_pte(pfn, PAGE_KERNEL);
- if (pfn >= max_low_pfn) {
- pte_clear(&init_mm, 0, &pte);
- continue;
- }
+ if (pfn >= max_low_pfn)
+ pte_val(pte) = _PAGE_TYPE_EMPTY;
set_pte(pt_dir, pte);
pfn++;
}
diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c
index 22dc9c21201d..f2031314cb2b 100644
--- a/trunk/arch/sh/kernel/process.c
+++ b/trunk/arch/sh/kernel/process.c
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
static int hlt_counter=0;
diff --git a/trunk/arch/sparc/kernel/ebus.c b/trunk/arch/sparc/kernel/ebus.c
index 81c0cbd96ff0..75ac24d229b1 100644
--- a/trunk/arch/sparc/kernel/ebus.c
+++ b/trunk/arch/sparc/kernel/ebus.c
@@ -277,7 +277,7 @@ void __init ebus_init(void)
struct pci_dev *pdev;
struct pcidev_cookie *cookie;
struct device_node *dp;
- unsigned long addr, *base;
+ struct resource *p;
unsigned short pci_command;
int len, reg, nreg;
int num_ebus = 0;
@@ -321,13 +321,12 @@ void __init ebus_init(void)
}
nreg = len / sizeof(struct linux_prom_pci_registers);
- base = &ebus->self->resource[0].start;
+ p = &ebus->self->resource[0];
for (reg = 0; reg < nreg; reg++) {
if (!(regs[reg].which_io & 0x03000000))
continue;
- addr = regs[reg].phys_lo;
- *base++ = addr;
+ (p++)->start = regs[reg].phys_lo;
}
ebus->ofdev.node = dp;
diff --git a/trunk/arch/sparc/kernel/ioport.c b/trunk/arch/sparc/kernel/ioport.c
index 8654b446ac9e..d33f8a07ccac 100644
--- a/trunk/arch/sparc/kernel/ioport.c
+++ b/trunk/arch/sparc/kernel/ioport.c
@@ -508,6 +508,7 @@ void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *s
void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
{
+#ifndef CONFIG_SUN4
struct device_node *parent = dp->parent;
if (sparc_cpu_model != sun4d &&
@@ -524,6 +525,7 @@ void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
iounit_init(dp->node, parent->node, sbus);
}
+#endif
}
void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp)
diff --git a/trunk/arch/sparc/kernel/sys_sparc.c b/trunk/arch/sparc/kernel/sys_sparc.c
index 94ff58c9d4a9..896863fb208a 100644
--- a/trunk/arch/sparc/kernel/sys_sparc.c
+++ b/trunk/arch/sparc/kernel/sys_sparc.c
@@ -470,19 +470,21 @@ asmlinkage int sys_getdomainname(char __user *name, int len)
{
int nlen, err;
- if (len < 0 || len > __NEW_UTS_LEN)
+ if (len < 0)
return -EINVAL;
down_read(&uts_sem);
nlen = strlen(system_utsname.domainname) + 1;
- if (nlen < len)
- len = nlen;
+ err = -EINVAL;
+ if (nlen > len)
+ goto out;
err = -EFAULT;
- if (!copy_to_user(name, system_utsname.domainname, len))
+ if (!copy_to_user(name, system_utsname.domainname, nlen))
err = 0;
+out:
up_read(&uts_sem);
return err;
}
diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig
index 43d9229fca07..51cf6027b701 100644
--- a/trunk/arch/sparc64/defconfig
+++ b/trunk/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc2
-# Fri Jul 21 14:19:24 2006
+# Linux kernel version: 2.6.18
+# Sat Sep 23 18:32:19 2006
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
@@ -9,6 +9,7 @@ CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_TIME_INTERPOLATION=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_AUDIT_ARCH=y
CONFIG_SPARC64_PAGE_SIZE_8KB=y
# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
# CONFIG_SPARC64_PAGE_SIZE_512KB is not set
@@ -37,14 +38,14 @@ CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_RELAY=y
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -53,12 +54,12 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
@@ -169,6 +170,7 @@ CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -214,11 +216,15 @@ CONFIG_IPV6_ROUTE_INFO=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
CONFIG_INET6_XFRM_MODE_TUNNEL=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -233,6 +239,7 @@ CONFIG_IP_DCCP_ACKVEC=y
# DCCP CCIDs Configuration (EXPERIMENTAL)
#
CONFIG_IP_DCCP_CCID2=m
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
CONFIG_IP_DCCP_CCID3=m
CONFIG_IP_DCCP_TFRC_LIB=m
@@ -259,7 +266,6 @@ CONFIG_VLAN_8021Q=m
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -1386,6 +1392,10 @@ CONFIG_KEYS=y
# Cryptographic options
#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=y
@@ -1395,9 +1405,12 @@ CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_CAST5=m
diff --git a/trunk/arch/sparc64/kernel/sys_sparc.c b/trunk/arch/sparc64/kernel/sys_sparc.c
index bf5f14ee73de..c608c947e6c3 100644
--- a/trunk/arch/sparc64/kernel/sys_sparc.c
+++ b/trunk/arch/sparc64/kernel/sys_sparc.c
@@ -707,19 +707,21 @@ asmlinkage long sys_getdomainname(char __user *name, int len)
{
int nlen, err;
- if (len < 0 || len > __NEW_UTS_LEN)
+ if (len < 0)
return -EINVAL;
down_read(&uts_sem);
nlen = strlen(system_utsname.domainname) + 1;
- if (nlen < len)
- len = nlen;
+ err = -EINVAL;
+ if (nlen > len)
+ goto out;
err = -EFAULT;
- if (!copy_to_user(name, system_utsname.domainname, len))
+ if (!copy_to_user(name, system_utsname.domainname, nlen))
err = 0;
+out:
up_read(&uts_sem);
return err;
}
diff --git a/trunk/arch/sparc64/kernel/time.c b/trunk/arch/sparc64/kernel/time.c
index 094d3e35be18..b0b4feeec098 100644
--- a/trunk/arch/sparc64/kernel/time.c
+++ b/trunk/arch/sparc64/kernel/time.c
@@ -983,7 +983,7 @@ static struct time_interpolator sparc64_cpu_interpolator = {
};
/* The quotient formula is taken from the IA64 port. */
-#define SPARC64_NSEC_PER_CYC_SHIFT 30UL
+#define SPARC64_NSEC_PER_CYC_SHIFT 10UL
void __init time_init(void)
{
unsigned long clock = sparc64_init_timers();
diff --git a/trunk/arch/sparc64/solaris/misc.c b/trunk/arch/sparc64/solaris/misc.c
index 8135ec322c9c..642541769a17 100644
--- a/trunk/arch/sparc64/solaris/misc.c
+++ b/trunk/arch/sparc64/solaris/misc.c
@@ -736,20 +736,15 @@ struct exec_domain solaris_exec_domain = {
extern int init_socksys(void);
-#ifdef MODULE
-
MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
MODULE_DESCRIPTION("Solaris binary emulation module");
MODULE_LICENSE("GPL");
-#ifdef __sparc_v9__
extern u32 tl0_solaris[8];
#define update_ttable(x) \
tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \
wmb(); \
__asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3]))
-#else
-#endif
extern u32 solaris_sparc_syscall[];
extern u32 solaris_syscall[];
@@ -757,7 +752,7 @@ extern void cleanup_socksys(void);
extern u32 entry64_personality_patch;
-int init_module(void)
+static int __init solaris_init(void)
{
int ret;
@@ -777,19 +772,12 @@ int init_module(void)
return 0;
}
-void cleanup_module(void)
+static void __exit solaris_exit(void)
{
update_ttable(solaris_syscall);
cleanup_socksys();
unregister_exec_domain(&solaris_exec_domain);
}
-#else
-int init_solaris_emul(void)
-{
- register_exec_domain(&solaris_exec_domain);
- init_socksys();
- return 0;
-}
-#endif
-
+module_init(solaris_init);
+module_exit(solaris_exit);
diff --git a/trunk/arch/sparc64/solaris/socksys.c b/trunk/arch/sparc64/solaris/socksys.c
index bc3df95bc057..7c90e41fd3be 100644
--- a/trunk/arch/sparc64/solaris/socksys.c
+++ b/trunk/arch/sparc64/solaris/socksys.c
@@ -168,8 +168,7 @@ static struct file_operations socksys_fops = {
.release = socksys_release,
};
-int __init
-init_socksys(void)
+int __init init_socksys(void)
{
int ret;
struct file * file;
@@ -199,8 +198,7 @@ init_socksys(void)
return 0;
}
-void
-cleanup_socksys(void)
+void __exit cleanup_socksys(void)
{
if (unregister_chrdev(30, "socksys"))
printk ("Couldn't unregister socksys character device\n");
diff --git a/trunk/arch/x86_64/crypto/Makefile b/trunk/arch/x86_64/crypto/Makefile
index 426d20f4b72e..15b538a8b7f7 100644
--- a/trunk/arch/x86_64/crypto/Makefile
+++ b/trunk/arch/x86_64/crypto/Makefile
@@ -5,5 +5,8 @@
#
obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
+obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
aes-x86_64-y := aes-x86_64-asm.o aes.o
+twofish-x86_64-y := twofish-x86_64-asm.o twofish.o
+
diff --git a/trunk/arch/x86_64/crypto/aes.c b/trunk/arch/x86_64/crypto/aes.c
index 68866fab37aa..5cdb13ea5cc2 100644
--- a/trunk/arch/x86_64/crypto/aes.c
+++ b/trunk/arch/x86_64/crypto/aes.c
@@ -228,13 +228,14 @@ static void __init gen_tabs(void)
}
static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
- unsigned int key_len, u32 *flags)
+ unsigned int key_len)
{
struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
const __le32 *key = (const __le32 *)in_key;
+ u32 *flags = &tfm->crt_flags;
u32 i, j, t, u, v, w;
- if (key_len != 16 && key_len != 24 && key_len != 32) {
+ if (key_len % 8) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}
diff --git a/trunk/arch/x86_64/crypto/twofish-x86_64-asm.S b/trunk/arch/x86_64/crypto/twofish-x86_64-asm.S
new file mode 100644
index 000000000000..35974a586615
--- /dev/null
+++ b/trunk/arch/x86_64/crypto/twofish-x86_64-asm.S
@@ -0,0 +1,324 @@
+/***************************************************************************
+* Copyright (C) 2006 by Joachim Fritschi, *
+* *
+* 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; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* 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. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+***************************************************************************/
+
+.file "twofish-x86_64-asm.S"
+.text
+
+#include
+
+#define a_offset 0
+#define b_offset 4
+#define c_offset 8
+#define d_offset 12
+
+/* Structure of the crypto context struct*/
+
+#define s0 0 /* S0 Array 256 Words each */
+#define s1 1024 /* S1 Array */
+#define s2 2048 /* S2 Array */
+#define s3 3072 /* S3 Array */
+#define w 4096 /* 8 whitening keys (word) */
+#define k 4128 /* key 1-32 ( word ) */
+
+/* define a few register aliases to allow macro substitution */
+
+#define R0 %rax
+#define R0D %eax
+#define R0B %al
+#define R0H %ah
+
+#define R1 %rbx
+#define R1D %ebx
+#define R1B %bl
+#define R1H %bh
+
+#define R2 %rcx
+#define R2D %ecx
+#define R2B %cl
+#define R2H %ch
+
+#define R3 %rdx
+#define R3D %edx
+#define R3B %dl
+#define R3H %dh
+
+
+/* performs input whitening */
+#define input_whitening(src,context,offset)\
+ xor w+offset(context), src;
+
+/* performs input whitening */
+#define output_whitening(src,context,offset)\
+ xor w+16+offset(context), src;
+
+
+/*
+ * a input register containing a (rotated 16)
+ * b input register containing b
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ */
+#define encrypt_round(a,b,c,d,round)\
+ movzx b ## B, %edi;\
+ mov s1(%r11,%rdi,4),%r8d;\
+ movzx a ## B, %edi;\
+ mov s2(%r11,%rdi,4),%r9d;\
+ movzx b ## H, %edi;\
+ ror $16, b ## D;\
+ xor s2(%r11,%rdi,4),%r8d;\
+ movzx a ## H, %edi;\
+ ror $16, a ## D;\
+ xor s3(%r11,%rdi,4),%r9d;\
+ movzx b ## B, %edi;\
+ xor s3(%r11,%rdi,4),%r8d;\
+ movzx a ## B, %edi;\
+ xor (%r11,%rdi,4), %r9d;\
+ movzx b ## H, %edi;\
+ ror $15, b ## D;\
+ xor (%r11,%rdi,4), %r8d;\
+ movzx a ## H, %edi;\
+ xor s1(%r11,%rdi,4),%r9d;\
+ add %r8d, %r9d;\
+ add %r9d, %r8d;\
+ add k+round(%r11), %r9d;\
+ xor %r9d, c ## D;\
+ rol $15, c ## D;\
+ add k+4+round(%r11),%r8d;\
+ xor %r8d, d ## D;
+
+/*
+ * a input register containing a(rotated 16)
+ * b input register containing b
+ * c input register containing c
+ * d input register containing d (already rol $1)
+ * operations on a and b are interleaved to increase performance
+ * during the round a and b are prepared for the output whitening
+ */
+#define encrypt_last_round(a,b,c,d,round)\
+ mov b ## D, %r10d;\
+ shl $32, %r10;\
+ movzx b ## B, %edi;\
+ mov s1(%r11,%rdi,4),%r8d;\
+ movzx a ## B, %edi;\
+ mov s2(%r11,%rdi,4),%r9d;\
+ movzx b ## H, %edi;\
+ ror $16, b ## D;\
+ xor s2(%r11,%rdi,4),%r8d;\
+ movzx a ## H, %edi;\
+ ror $16, a ## D;\
+ xor s3(%r11,%rdi,4),%r9d;\
+ movzx b ## B, %edi;\
+ xor s3(%r11,%rdi,4),%r8d;\
+ movzx a ## B, %edi;\
+ xor (%r11,%rdi,4), %r9d;\
+ xor a, %r10;\
+ movzx b ## H, %edi;\
+ xor (%r11,%rdi,4), %r8d;\
+ movzx a ## H, %edi;\
+ xor s1(%r11,%rdi,4),%r9d;\
+ add %r8d, %r9d;\
+ add %r9d, %r8d;\
+ add k+round(%r11), %r9d;\
+ xor %r9d, c ## D;\
+ ror $1, c ## D;\
+ add k+4+round(%r11),%r8d;\
+ xor %r8d, d ## D
+
+/*
+ * a input register containing a
+ * b input register containing b (rotated 16)
+ * c input register containing c (already rol $1)
+ * d input register containing d
+ * operations on a and b are interleaved to increase performance
+ */
+#define decrypt_round(a,b,c,d,round)\
+ movzx a ## B, %edi;\
+ mov (%r11,%rdi,4), %r9d;\
+ movzx b ## B, %edi;\
+ mov s3(%r11,%rdi,4),%r8d;\
+ movzx a ## H, %edi;\
+ ror $16, a ## D;\
+ xor s1(%r11,%rdi,4),%r9d;\
+ movzx b ## H, %edi;\
+ ror $16, b ## D;\
+ xor (%r11,%rdi,4), %r8d;\
+ movzx a ## B, %edi;\
+ xor s2(%r11,%rdi,4),%r9d;\
+ movzx b ## B, %edi;\
+ xor s1(%r11,%rdi,4),%r8d;\
+ movzx a ## H, %edi;\
+ ror $15, a ## D;\
+ xor s3(%r11,%rdi,4),%r9d;\
+ movzx b ## H, %edi;\
+ xor s2(%r11,%rdi,4),%r8d;\
+ add %r8d, %r9d;\
+ add %r9d, %r8d;\
+ add k+round(%r11), %r9d;\
+ xor %r9d, c ## D;\
+ add k+4+round(%r11),%r8d;\
+ xor %r8d, d ## D;\
+ rol $15, d ## D;
+
+/*
+ * a input register containing a
+ * b input register containing b
+ * c input register containing c (already rol $1)
+ * d input register containing d
+ * operations on a and b are interleaved to increase performance
+ * during the round a and b are prepared for the output whitening
+ */
+#define decrypt_last_round(a,b,c,d,round)\
+ movzx a ## B, %edi;\
+ mov (%r11,%rdi,4), %r9d;\
+ movzx b ## B, %edi;\
+ mov s3(%r11,%rdi,4),%r8d;\
+ movzx b ## H, %edi;\
+ ror $16, b ## D;\
+ xor (%r11,%rdi,4), %r8d;\
+ movzx a ## H, %edi;\
+ mov b ## D, %r10d;\
+ shl $32, %r10;\
+ xor a, %r10;\
+ ror $16, a ## D;\
+ xor s1(%r11,%rdi,4),%r9d;\
+ movzx b ## B, %edi;\
+ xor s1(%r11,%rdi,4),%r8d;\
+ movzx a ## B, %edi;\
+ xor s2(%r11,%rdi,4),%r9d;\
+ movzx b ## H, %edi;\
+ xor s2(%r11,%rdi,4),%r8d;\
+ movzx a ## H, %edi;\
+ xor s3(%r11,%rdi,4),%r9d;\
+ add %r8d, %r9d;\
+ add %r9d, %r8d;\
+ add k+round(%r11), %r9d;\
+ xor %r9d, c ## D;\
+ add k+4+round(%r11),%r8d;\
+ xor %r8d, d ## D;\
+ ror $1, d ## D;
+
+.align 8
+.global twofish_enc_blk
+.global twofish_dec_blk
+
+twofish_enc_blk:
+ pushq R1
+
+ /* %rdi contains the crypto tfm adress */
+ /* %rsi contains the output adress */
+ /* %rdx contains the input adress */
+ add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */
+ /* ctx adress is moved to free one non-rex register
+ as target for the 8bit high operations */
+ mov %rdi, %r11
+
+ movq (R3), R1
+ movq 8(R3), R3
+ input_whitening(R1,%r11,a_offset)
+ input_whitening(R3,%r11,c_offset)
+ mov R1D, R0D
+ rol $16, R0D
+ shr $32, R1
+ mov R3D, R2D
+ shr $32, R3
+ rol $1, R3D
+
+ encrypt_round(R0,R1,R2,R3,0);
+ encrypt_round(R2,R3,R0,R1,8);
+ encrypt_round(R0,R1,R2,R3,2*8);
+ encrypt_round(R2,R3,R0,R1,3*8);
+ encrypt_round(R0,R1,R2,R3,4*8);
+ encrypt_round(R2,R3,R0,R1,5*8);
+ encrypt_round(R0,R1,R2,R3,6*8);
+ encrypt_round(R2,R3,R0,R1,7*8);
+ encrypt_round(R0,R1,R2,R3,8*8);
+ encrypt_round(R2,R3,R0,R1,9*8);
+ encrypt_round(R0,R1,R2,R3,10*8);
+ encrypt_round(R2,R3,R0,R1,11*8);
+ encrypt_round(R0,R1,R2,R3,12*8);
+ encrypt_round(R2,R3,R0,R1,13*8);
+ encrypt_round(R0,R1,R2,R3,14*8);
+ encrypt_last_round(R2,R3,R0,R1,15*8);
+
+
+ output_whitening(%r10,%r11,a_offset)
+ movq %r10, (%rsi)
+
+ shl $32, R1
+ xor R0, R1
+
+ output_whitening(R1,%r11,c_offset)
+ movq R1, 8(%rsi)
+
+ popq R1
+ movq $1,%rax
+ ret
+
+twofish_dec_blk:
+ pushq R1
+
+ /* %rdi contains the crypto tfm adress */
+ /* %rsi contains the output adress */
+ /* %rdx contains the input adress */
+ add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */
+ /* ctx adress is moved to free one non-rex register
+ as target for the 8bit high operations */
+ mov %rdi, %r11
+
+ movq (R3), R1
+ movq 8(R3), R3
+ output_whitening(R1,%r11,a_offset)
+ output_whitening(R3,%r11,c_offset)
+ mov R1D, R0D
+ shr $32, R1
+ rol $16, R1D
+ mov R3D, R2D
+ shr $32, R3
+ rol $1, R2D
+
+ decrypt_round(R0,R1,R2,R3,15*8);
+ decrypt_round(R2,R3,R0,R1,14*8);
+ decrypt_round(R0,R1,R2,R3,13*8);
+ decrypt_round(R2,R3,R0,R1,12*8);
+ decrypt_round(R0,R1,R2,R3,11*8);
+ decrypt_round(R2,R3,R0,R1,10*8);
+ decrypt_round(R0,R1,R2,R3,9*8);
+ decrypt_round(R2,R3,R0,R1,8*8);
+ decrypt_round(R0,R1,R2,R3,7*8);
+ decrypt_round(R2,R3,R0,R1,6*8);
+ decrypt_round(R0,R1,R2,R3,5*8);
+ decrypt_round(R2,R3,R0,R1,4*8);
+ decrypt_round(R0,R1,R2,R3,3*8);
+ decrypt_round(R2,R3,R0,R1,2*8);
+ decrypt_round(R0,R1,R2,R3,1*8);
+ decrypt_last_round(R2,R3,R0,R1,0);
+
+ input_whitening(%r10,%r11,a_offset)
+ movq %r10, (%rsi)
+
+ shl $32, R1
+ xor R0, R1
+
+ input_whitening(R1,%r11,c_offset)
+ movq R1, 8(%rsi)
+
+ popq R1
+ movq $1,%rax
+ ret
diff --git a/trunk/arch/x86_64/crypto/twofish.c b/trunk/arch/x86_64/crypto/twofish.c
new file mode 100644
index 000000000000..182d91d5cfb9
--- /dev/null
+++ b/trunk/arch/x86_64/crypto/twofish.c
@@ -0,0 +1,97 @@
+/*
+ * Glue Code for optimized x86_64 assembler version of TWOFISH
+ *
+ * Originally Twofish for GPG
+ * By Matthew Skala , July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ * Ported to the kerneli patch by Marc Mutz
+ * Ported to CryptoAPI by Colin Slater
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus put it in the public domain. The subsequent authors
+ * have put this under the GNU General Public License.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
+asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
+
+static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ twofish_enc_blk(tfm, dst, src);
+}
+
+static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ twofish_dec_blk(tfm, dst, src);
+}
+
+static struct crypto_alg alg = {
+ .cra_name = "twofish",
+ .cra_driver_name = "twofish-x86_64",
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = TF_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct twofish_ctx),
+ .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = TF_MIN_KEY_SIZE,
+ .cia_max_keysize = TF_MAX_KEY_SIZE,
+ .cia_setkey = twofish_setkey,
+ .cia_encrypt = twofish_encrypt,
+ .cia_decrypt = twofish_decrypt
+ }
+ }
+};
+
+static int __init init(void)
+{
+ return crypto_register_alg(&alg);
+}
+
+static void __exit fini(void)
+{
+ crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION ("Twofish Cipher Algorithm, x86_64 asm optimized");
+MODULE_ALIAS("twofish");
diff --git a/trunk/arch/x86_64/kernel/e820.c b/trunk/arch/x86_64/kernel/e820.c
index 764bf23c7103..d6d7f731f6f0 100644
--- a/trunk/arch/x86_64/kernel/e820.c
+++ b/trunk/arch/x86_64/kernel/e820.c
@@ -108,6 +108,35 @@ e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
return 0;
}
+/*
+ * This function checks if the entire range is mapped with type.
+ *
+ * Note: this function only works correct if the e820 table is sorted and
+ * not-overlapping, which is the case
+ */
+int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type)
+{
+ int i;
+ for (i = 0; i < e820.nr_map; i++) {
+ struct e820entry *ei = &e820.map[i];
+ if (type && ei->type != type)
+ continue;
+ /* is the region (part) in overlap with the current region ?*/
+ if (ei->addr >= end || ei->addr + ei->size <= start)
+ continue;
+
+ /* if the region is at the beginning of we move
+ * start to the end of the region since it's ok until there
+ */
+ if (ei->addr <= start)
+ start = ei->addr + ei->size;
+ /* if start is now at or beyond end, we're done, full coverage */
+ if (start >= end)
+ return 1; /* we're done */
+ }
+ return 0;
+}
+
/*
* Find a free area in a specific range.
*/
diff --git a/trunk/arch/x86_64/pci/mmconfig.c b/trunk/arch/x86_64/pci/mmconfig.c
index 2d48a7941d48..3c55c76c6fd5 100644
--- a/trunk/arch/x86_64/pci/mmconfig.c
+++ b/trunk/arch/x86_64/pci/mmconfig.c
@@ -9,7 +9,6 @@
#include
#include
#include
-#include
#include