aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS12
-rw-r--r--Documentation/00-INDEX6
-rw-r--r--Documentation/HOWTO618
-rw-r--r--Documentation/arm/memory.txt4
-rw-r--r--MAINTAINERS16
-rw-r--r--Makefile2
-rw-r--r--arch/arm/kernel/armksyms.c1
-rw-r--r--arch/arm/kernel/entry-common.S3
-rw-r--r--arch/arm/kernel/signal.c25
-rw-r--r--arch/arm/kernel/vmlinux.lds.S6
-rw-r--r--arch/arm/lib/getuser.S11
-rw-r--r--arch/arm/mm/Makefile2
-rw-r--r--arch/arm/mm/blockops.c185
-rw-r--r--arch/arm/mm/init.c24
-rw-r--r--arch/arm/mm/ioremap.c3
-rw-r--r--arch/ia64/kernel/ivt.S133
-rw-r--r--arch/parisc/kernel/drivers.c8
-rw-r--r--arch/parisc/kernel/entry.S1
-rw-r--r--arch/parisc/kernel/inventory.c2
-rw-r--r--arch/parisc/kernel/ioctl32.c546
-rw-r--r--arch/parisc/kernel/irq.c110
-rw-r--r--arch/parisc/kernel/perf.c33
-rw-r--r--arch/parisc/kernel/ptrace.c5
-rw-r--r--arch/parisc/kernel/signal.c1
-rw-r--r--arch/parisc/kernel/smp.c24
-rw-r--r--arch/parisc/kernel/syscall.S3
-rw-r--r--arch/powerpc/kernel/pci_64.c18
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c3
-rw-r--r--arch/powerpc/kernel/ptrace-common.h (renamed from include/asm-ppc64/ptrace-common.h)0
-rw-r--r--arch/powerpc/kernel/ptrace.c3
-rw-r--r--arch/powerpc/kernel/ptrace32.c3
-rw-r--r--arch/powerpc/mm/imalloc.c3
-rw-r--r--arch/powerpc/mm/init_64.c3
-rw-r--r--arch/powerpc/mm/mmu_decl.h14
-rw-r--r--arch/powerpc/mm/pgtable_64.c3
-rw-r--r--arch/powerpc/platforms/powermac/smp.c6
-rw-r--r--arch/powerpc/sysdev/mpic.c13
-rw-r--r--block/as-iosched.c2
-rw-r--r--block/cfq-iosched.c2
-rw-r--r--block/deadline-iosched.c2
-rw-r--r--block/elevator.c2
-rw-r--r--block/ll_rw_blk.c2
-rw-r--r--drivers/block/cciss.c40
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c6
-rw-r--r--drivers/i2c/busses/i2c-ixp4xx.c7
-rw-r--r--drivers/ide/Kconfig2
-rw-r--r--drivers/ide/ide-cd.c6
-rw-r--r--drivers/ide/ide-disk.c4
-rw-r--r--drivers/ide/ide-floppy.c7
-rw-r--r--drivers/ide/ide-io.c6
-rw-r--r--drivers/ide/ide-lib.c8
-rw-r--r--drivers/ide/ide-tape.c7
-rw-r--r--drivers/ide/ide-taskfile.c27
-rw-r--r--drivers/ide/pci/aec62xx.c47
-rw-r--r--drivers/ide/pci/alim15x3.c9
-rw-r--r--drivers/ide/pci/cs5520.c5
-rw-r--r--drivers/ide/pci/siimage.c8
-rw-r--r--drivers/ide/pci/sis5513.c1
-rw-r--r--drivers/ide/pci/via82cxxx.c407
-rw-r--r--drivers/ide/ppc/pmac.c14
-rw-r--r--drivers/ide/setup-pci.c2
-rw-r--r--drivers/infiniband/core/user_mad.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c37
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c17
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h1
-rw-r--r--drivers/isdn/hisax/Kconfig12
-rw-r--r--drivers/isdn/pcbit/Kconfig2
-rw-r--r--drivers/mtd/maps/ipaq-flash.c6
-rw-r--r--drivers/mtd/maps/ixp2000.c22
-rw-r--r--drivers/mtd/nand/h1910.c2
-rw-r--r--drivers/net/au1000_eth.c1
-rw-r--r--drivers/net/e100.c275
-rw-r--r--drivers/net/fec_8xx/Kconfig2
-rw-r--r--drivers/net/ioc3-eth.c2
-rw-r--r--drivers/net/r8169.c6
-rw-r--r--drivers/net/saa9730.h36
-rw-r--r--drivers/net/smc91x.c17
-rw-r--r--drivers/net/wan/hdlc_cisco.c6
-rw-r--r--drivers/net/wan/hdlc_fr.c4
-rw-r--r--drivers/net/wan/hdlc_generic.c6
-rw-r--r--drivers/net/wireless/hermes.c6
-rw-r--r--drivers/net/wireless/hermes.h6
-rw-r--r--drivers/net/wireless/i82593.h11
-rw-r--r--drivers/net/wireless/ipw2100.c29
-rw-r--r--drivers/net/wireless/ipw2100.h2
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c4
-rw-r--r--drivers/parisc/iosapic.c26
-rw-r--r--drivers/parisc/superio.c35
-rw-r--r--drivers/scsi/ide-scsi.c2
-rw-r--r--drivers/scsi/sata_mv.c3
-rw-r--r--drivers/scsi/sata_sil24.c197
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/amba-pl011.c45
-rw-r--r--drivers/serial/mux.c19
-rw-r--r--drivers/serial/sa1100.c1
-rw-r--r--fs/compat_ioctl.c2
-rw-r--r--include/asm-arm/arch-ixp4xx/io.h9
-rw-r--r--include/asm-arm/hardware/amba_serial.h5
-rw-r--r--include/asm-arm/io.h21
-rw-r--r--include/asm-arm/uaccess.h8
-rw-r--r--include/asm-parisc/irq.h5
-rw-r--r--include/asm-parisc/smp.h7
-rw-r--r--include/asm-parisc/spinlock.h19
-rw-r--r--include/asm-parisc/tlbflush.h16
-rw-r--r--include/asm-powerpc/dma-mapping.h (renamed from include/asm-ppc/dma-mapping.h)138
-rw-r--r--include/asm-powerpc/io.h (renamed from include/asm-ppc64/io.h)12
-rw-r--r--include/asm-powerpc/mmu.h (renamed from include/asm-ppc64/mmu.h)14
-rw-r--r--include/asm-powerpc/mmu_context.h (renamed from include/asm-ppc64/mmu_context.h)12
-rw-r--r--include/asm-powerpc/mmzone.h (renamed from include/asm-ppc64/mmzone.h)0
-rw-r--r--include/asm-powerpc/pci-bridge.h (renamed from include/asm-ppc64/pci-bridge.h)12
-rw-r--r--include/asm-powerpc/pci.h (renamed from include/asm-ppc64/pci.h)110
-rw-r--r--include/asm-powerpc/pgalloc.h (renamed from include/asm-ppc64/pgalloc.h)11
-rw-r--r--include/asm-powerpc/pgtable-4k.h (renamed from include/asm-ppc64/pgtable-4k.h)0
-rw-r--r--include/asm-powerpc/pgtable-64k.h (renamed from include/asm-ppc64/pgtable-64k.h)0
-rw-r--r--include/asm-powerpc/pgtable.h (renamed from include/asm-ppc64/pgtable.h)20
-rw-r--r--include/asm-powerpc/ppc-pci.h2
-rw-r--r--include/asm-powerpc/spinlock.h (renamed from include/asm-ppc64/spinlock.h)72
-rw-r--r--include/asm-ppc/io.h17
-rw-r--r--include/asm-ppc64/dma-mapping.h136
-rw-r--r--include/asm-ppc64/imalloc.h26
-rw-r--r--include/linux/cciss_ioctl.h2
-rw-r--r--include/linux/hdreg.h6
-rw-r--r--include/linux/ide.h30
-rw-r--r--include/linux/mm.h2
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/net/ieee80211.h2
-rw-r--r--mm/mmap.c2
127 files changed, 2145 insertions, 1895 deletions
diff --git a/CREDITS b/CREDITS
index 192f749eba2..1b4f8694fa4 100644
--- a/CREDITS
+++ b/CREDITS
@@ -611,8 +611,7 @@ S: USA
N: Randolph Chung
E: tausq@debian.org
D: Linux/PA-RISC hacker
-S: Los Altos, CA 94022
-S: USA
+S: Hong Kong
N: Juan Jose Ciarlante
W: http://juanjox.kernelnotes.org/
@@ -3405,6 +3404,15 @@ S: Chudenicka 8
S: 10200 Prague 10, Hostivar
S: Czech Republic
+N: Thibaut Varene
+E: T-Bone@parisc-linux.org
+W: http://www.parisc-linux.org/
+P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063
+D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits
+D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there
+D: AD1889 sound driver
+S: Paris, France
+
N: Heikki Vatiainen
E: hessu@cs.tut.fi
D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 433cf5e9ae0..5f7f7d7f77d 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -24,6 +24,8 @@ DMA-mapping.txt
- info for PCI drivers using DMA portably across all platforms.
DocBook/
- directory with DocBook templates etc. for kernel documentation.
+HOWTO
+ - The process and procedures of how to do Linux kernel development.
IO-mapping.txt
- how to access I/O mapped memory from within device drivers.
IPMI.txt
@@ -256,6 +258,10 @@ specialix.txt
- info on hardware/driver for specialix IO8+ multiport serial card.
spinlocks.txt
- info on using spinlocks to provide exclusive access in kernel.
+stable_api_nonsense.txt
+ - info on why the kernel does not have a stable in-kernel api or abi.
+stable_kernel_rules.txt
+ - rules and procedures for the -stable kernel releases.
stallion.txt
- info on using the Stallion multiport serial driver.
svga.txt
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
new file mode 100644
index 00000000000..6c9e746267d
--- /dev/null
+++ b/Documentation/HOWTO
@@ -0,0 +1,618 @@
+HOWTO do Linux kernel development
+---------------------------------
+
+This is the be-all, end-all document on this topic. It contains
+instructions on how to become a Linux kernel developer and how to learn
+to work with the Linux kernel development community. It tries to not
+contain anything related to the technical aspects of kernel programming,
+but will help point you in the right direction for that.
+
+If anything in this document becomes out of date, please send in patches
+to the maintainer of this file, who is listed at the bottom of the
+document.
+
+
+Introduction
+------------
+
+So, you want to learn how to become a Linux kernel developer? Or you
+have been told by your manager, "Go write a Linux driver for this
+device." This document's goal is to teach you everything you need to
+know to achieve this by describing the process you need to go through,
+and hints on how to work with the community. It will also try to
+explain some of the reasons why the community works like it does.
+
+The kernel is written mostly in C, with some architecture-dependent
+parts written in assembly. A good understanding of C is required for
+kernel development. Assembly (any architecture) is not required unless
+you plan to do low-level development for that architecture. Though they
+are not a good substitute for a solid C education and/or years of
+experience, the following books are good for, if anything, reference:
+ - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
+ - "Practical C Programming" by Steve Oualline [O'Reilly]
+
+The kernel is written using GNU C and the GNU toolchain. While it
+adheres to the ISO C89 standard, it uses a number of extensions that are
+not featured in the standard. The kernel is a freestanding C
+environment, with no reliance on the standard C library, so some
+portions of the C standard are not supported. Arbitrary long long
+divisions and floating point are not allowed. It can sometimes be
+difficult to understand the assumptions the kernel has on the toolchain
+and the extensions that it uses, and unfortunately there is no
+definitive reference for them. Please check the gcc info pages (`info
+gcc`) for some information on them.
+
+Please remember that you are trying to learn how to work with the
+existing development community. It is a diverse group of people, with
+high standards for coding, style and procedure. These standards have
+been created over time based on what they have found to work best for
+such a large and geographically dispersed team. Try to learn as much as
+possible about these standards ahead of time, as they are well
+documented; do not expect people to adapt to you or your company's way
+of doing things.
+
+
+Legal Issues
+------------
+
+The Linux kernel source code is released under the GPL. Please see the
+file, COPYING, in the main directory of the source tree, for details on
+the license. If you have further questions about the license, please
+contact a lawyer, and do not ask on the Linux kernel mailing list. The
+people on the mailing lists are not lawyers, and you should not rely on
+their statements on legal matters.
+
+For common questions and answers about the GPL, please see:
+ http://www.gnu.org/licenses/gpl-faq.html
+
+
+Documentation
+------------
+
+The Linux kernel source tree has a large range of documents that are
+invaluable for learning how to interact with the kernel community. When
+new features are added to the kernel, it is recommended that new
+documentation files are also added which explain how to use the feature.
+When a kernel change causes the interface that the kernel exposes to
+userspace to change, it is recommended that you send the information or
+a patch to the manual pages explaining the change to the manual pages
+maintainer at mtk-manpages@gmx.net.
+
+Here is a list of files that are in the kernel source tree that are
+required reading:
+ README
+ This file gives a short background on the Linux kernel and describes
+ what is necessary to do to configure and build the kernel. People
+ who are new to the kernel should start here.
+
+ Documentation/Changes
+ This file gives a list of the minimum levels of various software
+ packages that are necessary to build and run the kernel
+ successfully.
+
+ Documentation/CodingStyle
+ This describes the Linux kernel coding style, and some of the
+ rationale behind it. All new code is expected to follow the
+ guidelines in this document. Most maintainers will only accept
+ patches if these rules are followed, and many people will only
+ review code if it is in the proper style.
+
+ Documentation/SubmittingPatches
+ Documentation/SubmittingDrivers
+ These files describe in explicit detail how to successfully create
+ and send a patch, including (but not limited to):
+ - Email contents
+ - Email format
+ - Who to send it to
+ Following these rules will not guarantee success (as all patches are
+ subject to scrutiny for content and style), but not following them
+ will almost always prevent it.
+
+ Other excellent descriptions of how to create patches properly are:
+ "The Perfect Patch"
+ http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
+ "Linux kernel patch submission format"
+ http://linux.yyz.us/patch-format.html
+
+ Documentation/stable_api_nonsense.txt
+ This file describes the rationale behind the conscious decision to
+ not have a stable API within the kernel, including things like:
+ - Subsystem shim-layers (for compatibility?)
+ - Driver portability between Operating Systems.
+ - Mitigating rapid change within the kernel source tree (or
+ preventing rapid change)
+ This document is crucial for understanding the Linux development
+ philosophy and is very important for people moving to Linux from
+ development on other Operating Systems.
+
+ Documentation/SecurityBugs
+ If you feel you have found a security problem in the Linux kernel,
+ please follow the steps in this document to help notify the kernel
+ developers, and help solve the issue.
+
+ Documentation/ManagementStyle
+ This document describes how Linux kernel maintainers operate and the
+ shared ethos behind their methodologies. This is important reading
+ for anyone new to kernel development (or anyone simply curious about
+ it), as it resolves a lot of common misconceptions and confusion
+ about the unique behavior of kernel maintainers.
+
+ Documentation/stable_kernel_rules.txt
+ This file describes the rules on how the stable kernel releases
+ happen, and what to do if you want to get a change into one of these
+ releases.
+
+ Documentation/kernel-docs.txt
+ A list of external documentation that pertains to kernel
+ development. Please consult this list if you do not find what you
+ are looking for within the in-kernel documentation.
+
+ Documentation/applying-patches.txt
+ A good introduction describing exactly what a patch is and how to
+ apply it to the different development branches of the kernel.
+
+The kernel also has a large number of documents that can be
+automatically generated from the source code itself. This includes a
+full description of the in-kernel API, and rules on how to handle
+locking properly. The documents will be created in the
+Documentation/DocBook/ directory and can be generated as PDF,
+Postscript, HTML, and man pages by running:
+ make pdfdocs
+ make psdocs
+ make htmldocs
+ make mandocs
+respectively from the main kernel source directory.
+
+
+Becoming A Kernel Developer
+---------------------------
+
+If you do not know anything about Linux kernel development, you should
+look at the Linux KernelNewbies project:
+ http://kernelnewbies.org
+It consists of a helpful mailing list where you can ask almost any type
+of basic kernel development question (make sure to search the archives
+first, before asking something that has already been answered in the
+past.) It also has an IRC channel that you can use to ask questions in
+real-time, and a lot of helpful documentation that is useful for
+learning about Linux kernel development.
+
+The website has basic information about code organization, subsystems,
+and current projects (both in-tree and out-of-tree). It also describes
+some basic logistical information, like how to compile a kernel and
+apply a patch.
+
+If you do not know where you want to start, but you want to look for
+some task to start doing to join into the kernel development community,
+go to the Linux Kernel Janitor's project:
+ http://janitor.kernelnewbies.org/
+It is a great place to start. It describes a list of relatively simple
+problems that need to be cleaned up and fixed within the Linux kernel
+source tree. Working with the developers in charge of this project, you
+will learn the basics of getting your patch into the Linux kernel tree,
+and possibly be pointed in the direction of what to go work on next, if
+you do not already have an idea.
+
+If you already have a chunk of code that you want to put into the kernel
+tree, but need some help getting it in the proper form, the
+kernel-mentors project was created to help you out with this. It is a
+mailing list, and can be found at:
+ http://selenic.com/mailman/listinfo/kernel-mentors
+
+Before making any actual modifications to the Linux kernel code, it is
+imperative to understand how the code in question works. For this
+purpose, nothing is better than reading through it directly (most tricky
+bits are commented well), perhaps even with the help of specialized
+tools. One such tool that is particularly recommended is the Linux
+Cross-Reference project, which is able to present source code in a
+self-referential, indexed webpage format. An excellent up-to-date
+repository of the kernel code may be found at:
+ http://sosdg.org/~coywolf/lxr/
+
+
+The development process
+-----------------------
+
+Linux kernel development process currently consists of a few different
+main kernel "branches" and lots of different subsystem-specific kernel
+branches. These different branches are:
+ - main 2.6.x kernel tree
+ - 2.6.x.y -stable kernel tree
+ - 2.6.x -git kernel patches
+ - 2.6.x -mm kernel patches
+ - subsystem specific kernel trees and patches
+
+2.6.x kernel tree
+-----------------
+2.6.x kernels are maintained by Linus Torvalds, and can be found on
+kernel.org in the pub/linux/kernel/v2.6/ directory. Its development
+process is as follows:
+ - As soon as a new kernel is released a two weeks window is open,
+ during this period of time maintainers can submit big diffs to
+ Linus, usually the patches that have already been included in the
+ -mm kernel for a few weeks. The preferred way to submit big changes
+ is using git (the kernel's source management tool, more information
+ can be found at http://git.or.cz/) but plain patches are also just
+ fine.
+ - After two weeks a -rc1 kernel is released it is now possible to push
+ only patches that do not include new features that could affect the
+ stability of the whole kernel. Please note that a whole new driver
+ (or filesystem) might be accepted after -rc1 because there is no
+ risk of causing regressions with such a change as long as the change
+ is self-contained and does not affect areas outside of the code that
+ is being added. git can be used to send patches to Linus after -rc1
+ is released, but the patches need to also be sent to a public
+ mailing list for review.
+ - A new -rc is released whenever Linus deems the current git tree to
+ be in a reasonably sane state adequate for testing. The goal is to
+ release a new -rc kernel every week.
+ - Process continues until the kernel is considered "ready", the
+ process should last around 6 weeks.
+
+It is worth mentioning what Andrew Morton wrote on the linux-kernel
+mailing list about kernel releases:
+ "Nobody knows when a kernel will be released, because it's
+ released according to perceived bug status, not according to a
+ preconceived timeline."
+
+2.6.x.y -stable kernel tree
+---------------------------
+Kernels with 4 digit versions are -stable kernels. They contain
+relatively small and critical fixes for security problems or significant
+regressions discovered in a given 2.6.x kernel.
+
+This is the recommended branch for users who want the most recent stable
+kernel and are not interested in helping test development/experimental
+versions.
+
+If no 2.6.x.y kernel is available, then the highest numbered 2.6.x
+kernel is the current stable kernel.
+
+2.6.x.y are maintained by the "stable" team <stable@kernel.org>, and are
+released almost every other week.
+
+The file Documentation/stable_kernel_rules.txt in the kernel tree
+documents what kinds of changes are acceptable for the -stable tree, and
+how the release process works.
+
+2.6.x -git patches
+------------------
+These are daily snapshots of Linus' kernel tree which are managed in a
+git repository (hence the name.) These patches are usually released
+daily and represent the current state of Linus' tree. They are more
+experimental than -rc kernels since they are generated automatically
+without even a cursory glance to see if they are sane.
+
+2.6.x -mm kernel patches
+------------------------
+These are experimental kernel patches released by Andrew Morton. Andrew
+takes all of the different subsystem kernel trees and patches and mushes
+them together, along with a lot of patches that have been plucked from
+the linux-kernel mailing list. This tree serves as a proving ground for
+new features and patches. Once a patch has proved its worth in -mm for
+a while Andrew or the subsystem maintainer pushes it on to Linus for
+inclusion in mainline.
+
+It is heavily encouraged that all new patches get tested in the -mm tree
+before they are sent to Linus for inclusion in the main kernel tree.
+
+These kernels are not appropriate for use on systems that are supposed
+to be stable and they are more risky to run than any of the other
+branches.
+
+If you wish to help out with the kernel development process, please test
+and use these kernel releases and provide feedback to the linux-kernel
+mailing list if you have any problems, and if everything works properly.
+
+In addition to all the other experimental patches, these kernels usually
+also contain any changes in the mainline -git kernels available at the
+time of release.
+
+The -mm kernels are not released on a fixed schedule, but usually a few
+-mm kernels are released in between each -rc kernel (1 to 3 is common).
+
+Subsystem Specific kernel trees and patches
+-------------------------------------------
+A number of the different kernel subsystem developers expose their
+development trees so that others can see what is happening in the
+different areas of the kernel. These trees are pulled into the -mm
+kernel releases as described above.
+
+Here is a list of some of the different kernel trees available:
+ git trees:
+ - Kbuild development tree, Sam Ravnborg <sam@ravnborg.org>
+ kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
+
+ - ACPI development tree, Len Brown <len.brown@intel.com>
+ kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
+
+ - Block development tree, Jens Axboe <axboe@suse.de>
+ kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
+
+ - DRM development tree, Dave Airlie <airlied@linux.ie>
+ kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
+
+ - ia64 development tree, Tony Luck <tony.luck@intel.com>
+ kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
+
+ - ieee1394 development tree, Jody McIntyre <scjody@modernduck.com>
+ kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
+
+ - infiniband, Roland Dreier <rolandd@cisco.com>
+ kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
+
+ - libata, Jeff Garzik <jgarzik@pobox.com>
+ kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
+
+ - network drivers, Jeff Garzik <jgarzik@pobox.com>
+ kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
+
+ - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
+ kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
+
+ - SCSI, James Bottomley <James.Bottomley@SteelEye.com>
+ kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
+
+ Other git kernel trees can be found listed at http://kernel.org/git
+
+ quilt trees:
+ - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman <gregkh@suse.de>
+ kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+
+
+Bug Reporting
+-------------
+
+bugzilla.kernel.org is where the Linux kernel developers track kernel
+bugs. Users are encouraged to report all bugs that they find in this
+tool. For details on how to use the kernel bugzilla, please see:
+ http://test.kernel.org/bugzilla/faq.html
+
+The file REPORTING-BUGS in the main kernel source directory has a good
+template for how to report a possible kernel bug, and details what kind
+of information is needed by the kernel developers to help track down the
+problem.
+
+
+Mailing lists
+-------------
+
+As some of the above documents describe, the majority of the core kernel
+developers participate on the Linux Kernel Mailing list. Details on how
+to subscribe and unsubscribe from the list can be found at:
+ http://vger.kernel.org/vger-lists.html#linux-kernel
+There are archives of the mailing list on the web in many different
+places. Use a search engine to find these archives. For example:
+ http://dir.gmane.org/gmane.linux.kernel
+It is highly recommended that you search the archives about the topic
+you want to bring up, before you post it to the list. A lot of things
+already discussed in detail are only recorded at the mailing list
+archives.
+
+Most of the individual kernel subsystems also have their own separate
+mailing list where they do their development efforts. See the
+MAINTAINERS file for a list of what these lists are for the different
+groups.
+
+Many of the lists are hosted on kernel.org. Information on them can be
+found at:
+ http://vger.kernel.org/vger-lists.html
+
+Please remember to follow good behavioral habits when using the lists.
+Though a bit cheesy, the following URL has some simple guidelines for
+interacting with the list (or any list):
+ http://www.albion.com/netiquette/
+
+If multiple people respond to your mail, the CC: list of recipients may
+get pretty large. Don't remove anybody from the CC: list without a good
+reason, or don't reply only to the list address. Get used to receiving the
+mail twice, one from the sender and the one from the list, and don't try
+to tune that by adding fancy mail-headers, people will not like it.
+
+Remember to keep the context and the attribution of your replies intact,
+keep the "John Kernelhacker wrote ...:" lines at the top of your reply, and
+add your statements between the individual quoted sections instead of
+writing at the top of the mail.
+
+If you add patches to your mail, make sure they are plain readable text
+as stated in Documentation/SubmittingPatches. Kernel developers don't
+want to deal with attachments or compressed patches; they may want
+to comment on individual lines of your patch, which works only that way.
+Make sure you use a mail program that does not mangle spaces and tab
+characters. A good first test is to send the mail to yourself and try
+to apply your own patch by yourself. If that doesn't work, get your
+mail program fixed or change it until it works.
+
+Above all, please remember to show respect to other subscribers.
+
+
+Working with the community
+--------------------------
+
+The goal of the kernel community is to provide the best possible kernel
+there is. When you submit a patch for acceptance, it will be reviewed
+on its technical merits and those alone. So, what should you be
+expecting?
+ - criticism
+ - comments
+ - requests for change
+ - requests for justification
+ - silence
+
+Remember, this is part of getting your patch into the kernel. You have
+to be able to take criticism and comments about your patches, evaluate
+them at a technical level and either rework your patches or provide
+clear and concise reasoning as to why those changes should not be made.
+If there are no responses to your posting, wait a few days and try
+again, sometimes things get lost in the huge volume.
+
+What should you not do?
+ - expect your patch to be accepted without question
+ - become defensive
+ - ignore comments
+ - resubmit the patch without making any of the requested changes
+
+In a community that is looking for the best technical solution possible,
+there will always be differing opinions on how beneficial a patch is.
+You have to be cooperative, and willing to adapt your idea to fit within
+the kernel. Or at least be willing to prove your idea is worth it.
+Remember, being wrong is acceptable as long as you are willing to work
+toward a solution that is right.
+
+It is normal that the answers to your first patch might simply be a list
+of a dozen things you should correct. This does _not_ imply that your
+patch will not be accepted, and it is _not_ meant against you
+personally. Simply correct all issues raised against your patch and
+resend it.
+
+
+Differences between the kernel community and corporate structures
+-----------------------------------------------------------------
+
+The kernel community works differently than most traditional corporate
+development environments. Here are a list of things that you can try to
+do to try to avoid problems:
+ Good things to say regarding your proposed changes:
+ - "This solves multiple problems."
+ - "This deletes 2000 lines of code."
+ - "Here is a patch that explains what I am trying to describe."
+ - "I tested it on 5 different architectures..."
+ - "Here is a series of small patches that..."
+ - "This increases performance on typical machines..."
+
+ Bad things you should avoid saying:
+ - "We did it this way in AIX/ptx/Solaris, so therefore it must be
+ good..."
+ - "I've being doing this for 20 years, so..."
+ - "This is required for my company to make money"
+ - "This is for our Enterprise product line."
+ - "Here is my 1000 page design document that describes my idea"
+ - "I've been working on this for 6 months..."
+ - "Here's a 5000 line patch that..."
+ - "I rewrote all of the current mess, and here it is..."
+ - "I have a deadline, and this patch needs to be applied now."
+
+Another way the kernel community is different than most traditional
+software engineering work environments is the faceless nature of
+interaction. One benefit of using email and irc as the primary forms of
+communication is the lack of discrimination based on gender or race.
+The Linux kernel work environment is accepting of women and minorities
+because all you are is an email address. The international aspect also
+helps to level the playing field because you can't guess gender based on
+a person's name. A man may be named Andrea and a woman may be named Pat.
+Most women who have worked in the Linux kernel and have expressed an
+opinion have had positive experiences.
+
+The language barrier can cause problems for some people who are not
+comfortable with English. A good grasp of the language can be needed in
+order to get ideas across properly on mailing lists, so it is
+recommended that you check your emails to make sure they make sense in
+English before sending them.
+
+
+Break up your changes
+---------------------
+
+The Linux kernel community does not gladly accept large chunks of code
+dropped on it all at once. The changes need to be properly introduced,
+discussed, and broken up into tiny, individual portions. This is almost
+the exact opposite of what companies are used to doing. Your proposal
+should also be introduced very early in the development process, so that
+you can receive feedback on what you are doing. It also lets the
+community feel that you are working with them, and not simply using them
+as a dumping ground for your feature. However, don't send 50 emails at
+one time to a mailing list, your patch series should be smaller than
+that almost all of the time.
+
+The reasons for breaking things up are the following:
+
+1) Small patches increase the likelihood that your patches will be
+ applied, since they don't take much time or effort to verify for
+ correctness. A 5 line patch can be applied by a maintainer with
+ barely a second glance. However, a 500 line patch may take hours to
+ review for correctness (the time it takes is exponentially
+ proportional to the size of the patch, or something).
+
+ Small patches also make it very easy to debug when something goes
+ wrong. It's much easier to back out patches one by one than it is
+ to dissect a very large patch after it's been applied (and broken
+ something).
+
+2) It's important not only to send small patches, but also to rewrite
+ and simplify (or simply re-order) patches before submitting them.
+
+Here is an analogy from kernel developer Al Viro:
+ "Think of a teacher grading homework from a math student. The
+ teacher does not want to see the student's trials and errors
+ before they came up with the solution. They want to see the
+ cleanest, most elegant answer. A good student knows this, and
+ would never submit her intermediate work before the final
+ solution."
+
+ The same is true of kernel development. The maintainers and
+ reviewers do not want to see the thought process behind the
+ solution to the problem one is solving. They want to see a
+ simple and elegant solution."
+
+It may be challenging to keep the balance between presenting an elegant
+solution and working together with the community and discussing your
+unfinished work. Therefore it is good to get early in the process to
+get feedback to improve your work, but also keep your changes in small
+chunks that they may get already accepted, even when your whole task is
+not ready for inclusion now.
+
+Also realize that it is not acceptable to send patches for inclusion
+that are unfinished and will be "fixed up later."
+
+
+Justify your change
+-------------------
+
+Along with breaking up your patches, it is very important for you to let
+the Linux community know why they should add this change. New features
+must be justified as being needed and useful.
+
+
+Document your change
+--------------------
+
+When sending in your patches, pay special attention to what you say in
+the text in your email. This information will become the ChangeLog
+information for the patch, and will be preserved for everyone to see for
+all time. It should describe the patch completely, containing:
+ - why the change is necessary
+ - the overall design approach in the patch
+ - implementation details
+ - testing results
+
+For more details on what this should all look like, please see the
+ChangeLog section of the document:
+ "The Perfect Patch"
+ http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
+
+
+
+
+All of these things are sometimes very hard to do. It can take years to
+perfect these practices (if at all). It's a continuous process of
+improvement that requires a lot of patience and determination. But
+don't give up, it's possible. Many have done it before, and each had to
+start exactly where you are now.
+
+
+
+
+----------
+Thanks to Paolo Ciarrocchi who allowed the "Development Process" section
+to be based on text he had written, and to Randy Dunlap and Gerrit
+Huizenga for some of the list of things you should and should not say.
+Also thanks to Pat Mochel, Hanna Linder, Randy Dunlap, Kay Sievers,
+Vojtech Pavlik, Jan Kara, Josh Boyer, Kees Cook, Andrew Morton, Andi
+Kleen, Vadim Lobanov, Jesper Juhl, Adrian Bunk, Keri Harris, Frans Pop,
+David A. Wheeler, Junio Hamano, Michael Kerrisk, and Alex Shepard for
+their review, comments, and contributions. Without their help, this
+document would not have been possible.
+
+
+
+Maintainer: Greg Kroah-Hartman <greg@kroah.com>
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index 4b1c93a8177..dc6045577a8 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -1,7 +1,7 @@
Kernel Memory Layout on ARM Linux
Russell King <rmk@arm.linux.org.uk>
- May 21, 2004 (2.6.6)
+ November 17, 2005 (2.6.15)
This document describes the virtual memory layout which the Linux
kernel uses for ARM processors. It indicates which regions are
@@ -37,6 +37,8 @@ ff000000 ffbfffff Reserved for future expansion of DMA
mapping region.
VMALLOC_END feffffff Free for platform use, recommended.
+ VMALLOC_END must be aligned to a 2MB
+ boundary.
VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space.
Memory returned by vmalloc/ioremap will
diff --git a/MAINTAINERS b/MAINTAINERS
index 509927e40bb..f239ac4762d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -58,6 +58,7 @@ P: Person
M: Mail patches to
L: Mailing list that is relevant to this area
W: Web-page with status/info
+T: SCM tree type and URL. Type is one of: git, hg, quilt.
S: Status, one of the following:
Supported: Someone is actually paid to look after this.
@@ -183,6 +184,7 @@ P: Len Brown
M: len.brown@intel.com
L: acpi-devel@lists.sourceforge.net
W: http://acpi.sourceforge.net/
+T: git kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
S: Maintained
AD1816 SOUND DRIVER
@@ -418,6 +420,7 @@ BLOCK LAYER
P: Jens Axboe
M: axboe@suse.de
L: linux-kernel@vger.kernel.org
+T: git kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
S: Maintained
BLUETOOTH SUBSYSTEM
@@ -803,12 +806,14 @@ DRIVER CORE, KOBJECTS, AND SYSFS
P: Greg Kroah-Hartman
M: gregkh@suse.de
L: linux-kernel@vger.kernel.org
+T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Supported
DRM DRIVERS
P: David Airlie
M: airlied@linux.ie
L: dri-devel@lists.sourceforge.net
+T: git kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
S: Maintained
DSCC4 DRIVER
@@ -1113,6 +1118,7 @@ P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
W: http://www.lm-sensors.nu/
+T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Maintained
I2O
@@ -1145,6 +1151,7 @@ P: Tony Luck
M: tony.luck@intel.com
L: linux-ia64@vger.kernel.org
W: http://www.ia64-linux.org/
+T: git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
S: Maintained
SN-IA64 (Itanium) SUB-PLATFORM
@@ -1212,6 +1219,7 @@ P: Jody McIntyre
M: scjody@steamballoon.com
L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/
+T: git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
S: Maintained
IEEE 1394 OHCI DRIVER
@@ -1263,6 +1271,7 @@ P: Hal Rosenstock
M: halr@voltaire.com
L: openib-general@openib.org
W: http://www.openib.org/
+T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
S: Supported
INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS
@@ -1436,6 +1445,7 @@ P: Kai Germaschewski
M: kai@germaschewski.name
P: Sam Ravnborg
M: sam@ravnborg.org
+T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
S: Maintained
KERNEL JANITORS
@@ -1782,6 +1792,7 @@ M: akpm@osdl.org
P: Jeff Garzik
M: jgarzik@pobox.com
L: netdev@vger.kernel.org
+T: git kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
S: Maintained
NETWORKING [GENERAL]
@@ -1959,6 +1970,7 @@ P: Greg Kroah-Hartman
M: gregkh@suse.de
L: linux-kernel@vger.kernel.org
L: linux-pci@atrey.karlin.mff.cuni.cz
+T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Supported
PCI HOTPLUG CORE
@@ -1980,6 +1992,7 @@ S: Maintained
PCMCIA SUBSYSTEM
P: Linux PCMCIA Team
L: http://lists.infradead.org/mailman/listinfo/linux-pcmcia
+T: git kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
S: Maintained
PCNET32 NETWORK DRIVER
@@ -2189,6 +2202,7 @@ SCSI SUBSYSTEM
P: James E.J. Bottomley
M: James.Bottomley@SteelEye.com
L: linux-scsi@vger.kernel.org
+T: git kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
S: Maintained
SCSI TAPE DRIVER
@@ -2228,6 +2242,7 @@ SERIAL ATA (SATA) SUBSYSTEM:
P: Jeff Garzik
M: jgarzik@pobox.com
L: linux-ide@vger.kernel.org
+T: git kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
S: Supported
SGI SN-IA64 (Altix) SERIAL CONSOLE DRIVER
@@ -2749,6 +2764,7 @@ M: gregkh@suse.de
L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
W: http://www.linux-usb.org
+T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
S: Supported
USB UHCI DRIVER
diff --git a/Makefile b/Makefile
index c3191440095..e7a0443c867 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 15
-EXTRAVERSION =-rc1
+EXTRAVERSION =-rc2
NAME=Affluent Albatross
# *DOCUMENTATION*
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 7a3261f0bf7..9997098009a 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -120,7 +120,6 @@ EXPORT_SYMBOL(__arch_strncpy_from_user);
EXPORT_SYMBOL(__get_user_1);
EXPORT_SYMBOL(__get_user_2);
EXPORT_SYMBOL(__get_user_4);
-EXPORT_SYMBOL(__get_user_8);
EXPORT_SYMBOL(__put_user_1);
EXPORT_SYMBOL(__put_user_2);
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 066597f4345..f7f18307523 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -48,8 +48,7 @@ work_pending:
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
bl do_notify_resume
- disable_irq @ disable interrupts
- b no_work_pending
+ b ret_slow_syscall @ Check work again
work_resched:
bl schedule
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index a917e3dd366..765922bcf9e 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -595,23 +595,22 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
ret |= !valid_user_regs(regs);
- /*
- * Block the signal if we were unsuccessful.
- */
if (ret != 0) {
- spin_lock_irq(&tsk->sighand->siglock);
- sigorsets(&tsk->blocked, &tsk->blocked,
- &ka->sa.sa_mask);
- if (!(ka->sa.sa_flags & SA_NODEFER))
- sigaddset(&tsk->blocked, sig);
- recalc_sigpending();
- spin_unlock_irq(&tsk->sighand->siglock);
+ force_sigsegv(sig, tsk);
+ return;
}
- if (ret == 0)
- return;
+ /*
+ * Block the signal if we were successful.
+ */
+ spin_lock_irq(&tsk->sighand->siglock);
+ sigorsets(&tsk->blocked, &tsk->blocked,
+ &ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NODEFER))
+ sigaddset(&tsk->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&tsk->sighand->siglock);
- force_sigsegv(sig, tsk);
}
/*
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 80c8e4c8cef..9a47770114d 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -172,6 +172,10 @@ SECTIONS
.comment 0 : { *(.comment) }
}
-/* those must never be empty */
+/*
+ * These must never be empty
+ * If you have to comment these two assert statements out, your
+ * binutils is too old (for other reasons as well)
+ */
ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index d204018070a..c03ea8e666b 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -54,15 +54,6 @@ __get_user_4:
mov r0, #0
mov pc, lr
- .global __get_user_8
-__get_user_8:
-5: ldrt r2, [r0], #4
-6: ldrt r3, [r0]
- mov r0, #0
- mov pc, lr
-
-__get_user_bad_8:
- mov r3, #0
__get_user_bad:
mov r2, #0
mov r0, #-EFAULT
@@ -73,6 +64,4 @@ __get_user_bad:
.long 2b, __get_user_bad
.long 3b, __get_user_bad
.long 4b, __get_user_bad
- .long 5b, __get_user_bad_8
- .long 6b, __get_user_bad_8
.previous
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 59f47d4c2df..ffe73ba2bf1 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -51,4 +51,4 @@ obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
obj-$(CONFIG_CPU_SA110) += proc-sa110.o
obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
-obj-$(CONFIG_CPU_V6) += proc-v6.o blockops.o
+obj-$(CONFIG_CPU_V6) += proc-v6.o
diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c
deleted file mode 100644
index 4f5ee2d0899..00000000000
--- a/arch/arm/mm/blockops.c
+++ /dev/null
@@ -1,185 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <asm/memory.h>
-#include <asm/ptrace.h>
-#include <asm/cacheflush.h>
-#include <asm/traps.h>
-
-extern struct cpu_cache_fns blk_cache_fns;
-
-#define HARVARD_CACHE
-
-/*
- * blk_flush_kern_dcache_page(kaddr)
- *
- * Ensure that the data held in the page kaddr is written back
- * to the page in question.
- *
- * - kaddr - kernel address (guaranteed to be page aligned)
- */
-static void __attribute__((naked))
-blk_flush_kern_dcache_page(void *kaddr)
-{
- asm(
- "add r1, r0, %0 \n\
- sub r1, r1, %1 \n\
-1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\
- mov r0, #0 \n\
- mcr p15, 0, r0, c7, c5, 0 \n\
- mcr p15, 0, r0, c7, c10, 4 \n\
- mov pc, lr"
- :
- : "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES));
-}
-
-/*
- * blk_dma_inv_range(start,end)
- *
- * Invalidate the data cache within the specified region; we will
- * be performing a DMA operation in this region and we want to
- * purge old data in the cache.
- *
- * - start - virtual start address of region
- * - end - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_inv_range_unified(unsigned long start, unsigned long end)
-{
- asm(
- "tst r0, %0 \n\
- mcrne p15, 0, r0, c7, c11, 1 @ clean unified line \n\
- tst r1, %0 \n\
- mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line\n\
- .word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\
- mov r0, #0 \n\
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
- mov pc, lr"
- :
- : "I" (L1_CACHE_BYTES - 1));
-}
-
-static void __attribute__((naked))
-blk_dma_inv_range_harvard(unsigned long start, unsigned long end)
-{
- asm(
- "tst r0, %0 \n\
- mcrne p15, 0, r0, c7, c10, 1 @ clean D line \n\
- tst r1, %0 \n\
- mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line \n\
- .word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\
- mov r0, #0 \n\
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
- mov pc, lr"
- :
- : "I" (L1_CACHE_BYTES - 1));
-}
-
-/*
- * blk_dma_clean_range(start,end)
- * - start - virtual start address of region
- * - end - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_clean_range(unsigned long start, unsigned long end)
-{
- asm(
- ".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0 @ blocking \n\
- mov r0, #0 \n\
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
- mov pc, lr");
-}
-
-/*
- * blk_dma_flush_range(start,end)
- * - start - virtual start address of region
- * - end - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_flush_range(unsigned long start, unsigned long end)
-{
- asm(
- ".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0 @ blocking \n\
- mov pc, lr");
-}
-
-static int blockops_trap(struct pt_regs *regs, unsigned int instr)
-{
- regs->ARM_r4 |= regs->ARM_r2;
- regs->ARM_pc += 4;
- return 0;
-}
-
-static char *func[] = {
- "Prefetch data range",
- "Clean+Invalidate data range",
- "Clean data range",
- "Invalidate data range",
- "Invalidate instr range"
-};
-
-static struct undef_hook blockops_hook __initdata = {
- .instr_mask = 0x0fffffd0,
- .instr_val = 0x0c401f00,
- .cpsr_mask = PSR_T_BIT,
- .cpsr_val = 0,
- .fn = blockops_trap,
-};
-
-static int __init blockops_check(void)
-{
- register unsigned int err asm("r4") = 0;
- unsigned int err_pos = 1;
- unsigned int cache_type;
- int i;
-
- asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (cache_type));
-
- printk("Checking V6 block cache operations:\n");
- register_undef_hook(&blockops_hook);
-
- __asm__ ("mov r0, %0\n\t"
- "mov r1, %1\n\t"
- "mov r2, #1\n\t"
- ".word 0xec401f2c @ mcrr p15, 0, r1, r0, c12, 2\n\t"
- "mov r2, #2\n\t"
- ".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0\n\t"
- "mov r2, #4\n\t"
- ".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0\n\t"
- "mov r2, #8\n\t"
- ".word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0\n\t"
- "mov r2, #16\n\t"
- ".word 0xec401f05 @ mcrr p15, 0, r1, r0, c5, 0\n\t"
- :
- : "r" (PAGE_OFFSET), "r" (PAGE_OFFSET + 128)
- : "r0", "r1", "r2");
-
- unregister_undef_hook(&blockops_hook);
-
- for (i = 0; i < ARRAY_SIZE(func); i++, err_pos <<= 1)
- printk("%30s: %ssupported\n", func[i], err & err_pos ? "not " : "");
-
- if ((err & 8) == 0) {
- printk(" --> Using %s block cache invalidate\n",
- cache_type & (1 << 24) ? "harvard" : "unified");
- if (cache_type & (1 << 24))
- cpu_cache.dma_inv_range = blk_dma_inv_range_harvard;
- else
- cpu_cache.dma_inv_range = blk_dma_inv_range_unified;
- }
- if ((err & 4) == 0) {
- printk(" --> Using block cache clean\n");
- cpu_cache.dma_clean_range = blk_dma_clean_range;
- }
- if ((err & 2) == 0) {
- printk(" --> Using block cache clean+invalidate\n");
- cpu_cache.dma_flush_range = blk_dma_flush_range;
- cpu_cache.flush_kern_dcache_page = blk_flush_kern_dcache_page;
- }
-
- return 0;
-}
-
-__initcall(blockops_check);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index c168f322ef8..8b276ee38ac 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -420,7 +420,8 @@ static void __init bootmem_init(struct meminfo *mi)
* Set up device the mappings. Since we clear out the page tables for all
* mappings above VMALLOC_END, we will remove any debug device mappings.
* This means you have to be careful how you debug this function, or any
- * called function. (Do it by code inspection!)
+ * called function. This means you can't use any function or debugging
+ * method which may touch any device, otherwise the kernel _will_ crash.
*/
static void __init devicemaps_init(struct machine_desc *mdesc)
{
@@ -428,6 +429,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
unsigned long addr;
void *vectors;
+ /*
+ * Allocate the vector page early.
+ */
+ vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+ BUG_ON(!vectors);
+
for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
pmd_clear(pmd_off_k(addr));
@@ -461,12 +468,6 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
create_mapping(&map);
#endif
- flush_cache_all();
- local_flush_tlb_all();
-
- vectors = alloc_bootmem_low_pages(PAGE_SIZE);
- BUG_ON(!vectors);
-
/*
* Create a mapping for the machine vectors at the high-vectors
* location (0xffff0000). If we aren't using high-vectors, also
@@ -491,12 +492,13 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
mdesc->map_io();
/*
- * Finally flush the tlb again - this ensures that we're in a
- * consistent state wrt the writebuffer if the writebuffer needs
- * draining. After this point, we can start to touch devices
- * again.
+ * Finally flush the caches and tlb to ensure that we're in a
+ * consistent state wrt the writebuffer. This also ensures that
+ * any write-allocated cache lines in the vector page are written
+ * back. After this point, we can start to touch devices again.
*/
local_flush_tlb_all();
+ flush_cache_all();
}
/*
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 0f128c28fee..10901398e4a 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -130,8 +130,7 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
* mapping. See include/asm-arm/proc-armv/pgtable.h for more information.
*/
void __iomem *
-__ioremap(unsigned long phys_addr, size_t size, unsigned long flags,
- unsigned long align)
+__ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
{
void * addr;
struct vm_struct * area;
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index e06f21f60dc..301f2e9d262 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -91,16 +91,17 @@ ENTRY(vhpt_miss)
* (the "original") TLB miss, which may either be caused by an instruction
* fetch or a data access (or non-access).
*
- * What we do here is normal TLB miss handing for the _original_ miss, followed
- * by inserting the TLB entry for the virtual page table page that the VHPT
- * walker was attempting to access. The latter gets inserted as long
- * as both L1 and L2 have valid mappings for the faulting address.
- * The TLB entry for the original miss gets inserted only if
- * the L3 entry indicates that the page is present.
+ * What we do here is normal TLB miss handing for the _original_ miss,
+ * followed by inserting the TLB entry for the virtual page table page
+ * that the VHPT walker was attempting to access. The latter gets
+ * inserted as long as page table entry above pte level have valid
+ * mappings for the faulting address. The TLB entry for the original
+ * miss gets inserted only if the pte entry indicates that the page is
+ * present.
*
* do_page_fault gets invoked in the following cases:
* - the faulting virtual address uses unimplemented address bits
- * - the faulting virtual address has no L1, L2, or L3 mapping
+ * - the faulting virtual address has no valid page table mapping
*/
mov r16=cr.ifa // get address that caused the TLB miss
#ifdef CONFIG_HUGETLB_PAGE
@@ -126,7 +127,7 @@ ENTRY(vhpt_miss)
#endif
;;
cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5?
- shr.u r18=r22,PGDIR_SHIFT // get bits 33-63 of the faulting address
+ shr.u r18=r22,PGDIR_SHIFT // get bottom portion of pgd index bit
;;
(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place
@@ -137,38 +138,38 @@ ENTRY(vhpt_miss)
(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
;;
-(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8
-(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
+(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=pgd_offset for region 5
+(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=pgd_offset for region[0-4]
cmp.eq p7,p6=0,r21 // unused address bits all zeroes?
#ifdef CONFIG_PGTABLE_4
- shr.u r28=r22,PUD_SHIFT // shift L2 index into position
+ shr.u r28=r22,PUD_SHIFT // shift pud index into position
#else
- shr.u r18=r22,PMD_SHIFT // shift L3 index into position
+ shr.u r18=r22,PMD_SHIFT // shift pmd index into position
#endif
;;
- ld8 r17=[r17] // fetch the L1 entry (may be 0)
+ ld8 r17=[r17] // get *pgd (may be 0)
;;
-(p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL?
+(p7) cmp.eq p6,p7=r17,r0 // was pgd_present(*pgd) == NULL?
#ifdef CONFIG_PGTABLE_4
- dep r28=r28,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry
+ dep r28=r28,r17,3,(PAGE_SHIFT-3) // r28=pud_offset(pgd,addr)
;;
- shr.u r18=r22,PMD_SHIFT // shift L3 index into position
-(p7) ld8 r29=[r28] // fetch the L2 entry (may be 0)
+ shr.u r18=r22,PMD_SHIFT // shift pmd index into position
+(p7) ld8 r29=[r28] // get *pud (may be 0)
;;
-(p7) cmp.eq.or.andcm p6,p7=r29,r0 // was L2 entry NULL?
- dep r17=r18,r29,3,(PAGE_SHIFT-3) // compute address of L3 page table entry
+(p7) cmp.eq.or.andcm p6,p7=r29,r0 // was pud_present(*pud) == NULL?
+ dep r17=r18,r29,3,(PAGE_SHIFT-3) // r17=pmd_offset(pud,addr)
#else
- dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry
+ dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=pmd_offset(pgd,addr)
#endif
;;
-(p7) ld8 r20=[r17] // fetch the L3 entry (may be 0)
- shr.u r19=r22,PAGE_SHIFT // shift L4 index into position
+(p7) ld8 r20=[r17] // get *pmd (may be 0)
+ shr.u r19=r22,PAGE_SHIFT // shift pte index into position
;;
-(p7) cmp.eq.or.andcm p6,p7=r20,r0 // was L3 entry NULL?
- dep r21=r19,r20,3,(PAGE_SHIFT-3) // compute address of L4 page table entry
+(p7) cmp.eq.or.andcm p6,p7=r20,r0 // was pmd_present(*pmd) == NULL?
+ dep r21=r19,r20,3,(PAGE_SHIFT-3) // r21=pte_offset(pmd,addr)
;;
-(p7) ld8 r18=[r21] // read the L4 PTE
- mov r19=cr.isr // cr.isr bit 0 tells us if this is an insn miss
+(p7) ld8 r18=[r21] // read *pte
+ mov r19=cr.isr // cr.isr bit 32 tells us if this is an insn miss
;;
(p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared?
mov r22=cr.iha // get the VHPT address that caused the TLB miss
@@ -202,25 +203,33 @@ ENTRY(vhpt_miss)
dv_serialize_data
/*
- * Re-check L2 and L3 pagetable. If they changed, we may have received a ptc.g
+ * Re-check pagetable entry. If they changed, we may have received a ptc.g
* between reading the pagetable and the "itc". If so, flush the entry we
- * inserted and retry.
+ * inserted and retry. At this point, we have:
+ *
+ * r28 = equivalent of pud_offset(pgd, ifa)
+ * r17 = equivalent of pmd_offset(pud, ifa)
+ * r21 = equivalent of pte_offset(pmd, ifa)
+ *
+ * r29 = *pud
+ * r20 = *pmd
+ * r18 = *pte
*/
- ld8 r25=[r21] // read L4 entry again
- ld8 r26=[r17] // read L3 PTE again
+ ld8 r25=[r21] // read *pte again
+ ld8 r26=[r17] // read *pmd again
#ifdef CONFIG_PGTABLE_4
- ld8 r18=[r28] // read L2 entry again
+ ld8 r19=[r28] // read *pud again
#endif
cmp.ne p6,p7=r0,r0
;;
- cmp.ne.or.andcm p6,p7=r26,r20 // did L3 entry change
+ cmp.ne.or.andcm p6,p7=r26,r20 // did *pmd change
#ifdef CONFIG_PGTABLE_4
- cmp.ne.or.andcm p6,p7=r29,r18 // did L4 PTE change
+ cmp.ne.or.andcm p6,p7=r19,r29 // did *pud change
#endif
mov r27=PAGE_SHIFT<<2
;;
(p6) ptc.l r22,r27 // purge PTE page translation
-(p7) cmp.ne.or.andcm p6,p7=r25,r18 // did L4 PTE change
+(p7) cmp.ne.or.andcm p6,p7=r25,r18 // did *pte change
;;
(p6) ptc.l r16,r27 // purge translation
#endif
@@ -235,19 +244,19 @@ END(vhpt_miss)
ENTRY(itlb_miss)
DBG_FAULT(1)
/*
- * The ITLB handler accesses the L3 PTE via the virtually mapped linear
+ * The ITLB handler accesses the PTE via the virtually mapped linear
* page table. If a nested TLB miss occurs, we switch into physical
- * mode, walk the page table, and then re-execute the L3 PTE read
- * and go on normally after that.
+ * mode, walk the page table, and then re-execute the PTE read and
+ * go on normally after that.
*/
mov r16=cr.ifa // get virtual address
mov r29=b0 // save b0
mov r31=pr // save predicates
.itlb_fault:
- mov r17=cr.iha // get virtual address of L3 PTE
+ mov r17=cr.iha // get virtual address of PTE
movl r30=1f // load nested fault continuation point
;;
-1: ld8 r18=[r17] // read L3 PTE
+1: ld8 r18=[r17] // read *pte
;;
mov b0=r29
tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
@@ -262,7 +271,7 @@ ENTRY(itlb_miss)
*/
dv_serialize_data
- ld8 r19=[r17] // read L3 PTE again and see if same
+ ld8 r19=[r17] // read *pte again and see if same
mov r20=PAGE_SHIFT<<2 // setup page size for purge
;;
cmp.ne p7,p0=r18,r19
@@ -279,19 +288,19 @@ END(itlb_miss)
ENTRY(dtlb_miss)
DBG_FAULT(2)
/*
- * The DTLB handler accesses the L3 PTE via the virtually mapped linear
+ * The DTLB handler accesses the PTE via the virtually mapped linear
* page table. If a nested TLB miss occurs, we switch into physical
- * mode, walk the page table, and then re-execute the L3 PTE read
- * and go on normally after that.
+ * mode, walk the page table, and then re-execute the PTE read and
+ * go on normally after that.
*/
mov r16=cr.ifa // get virtual address
mov r29=b0 // save b0
mov r31=pr // save predicates
dtlb_fault:
- mov r17=cr.iha // get virtual address of L3 PTE
+ mov r17=cr.iha // get virtual address of PTE
movl r30=1f // load nested fault continuation point
;;
-1: ld8 r18=[r17] // read L3 PTE
+1: ld8 r18=[r17] // read *pte
;;
mov b0=r29
tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
@@ -306,7 +315,7 @@ dtlb_fault:
*/
dv_serialize_data
- ld8 r19=[r17] // read L3 PTE again and see if same
+ ld8 r19=[r17] // read *pte again and see if same
mov r20=PAGE_SHIFT<<2 // setup page size for purge
;;
cmp.ne p7,p0=r18,r19
@@ -420,7 +429,7 @@ ENTRY(nested_dtlb_miss)
* r30: continuation address
* r31: saved pr
*
- * Output: r17: physical address of L3 PTE of faulting address
+ * Output: r17: physical address of PTE of faulting address
* r29: saved b0
* r30: continuation address
* r31: saved pr
@@ -450,33 +459,33 @@ ENTRY(nested_dtlb_miss)
(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
;;
-(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8
-(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
+(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=pgd_offset for region 5
+(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=pgd_offset for region[0-4]
cmp.eq p7,p6=0,r21 // unused address bits all zeroes?
#ifdef CONFIG_PGTABLE_4
- shr.u r18=r22,PUD_SHIFT // shift L2 index into position
+ shr.u r18=r22,PUD_SHIFT // shift pud index into position
#else
- shr.u r18=r22,PMD_SHIFT // shift L3 index into position
+ shr.u r18=r22,PMD_SHIFT // shift pmd index into position
#endif
;;
- ld8 r17=[r17] // fetch the L1 entry (may be 0)
+ ld8 r17=[r17] // get *pgd (may be 0)
;;
-(p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL?
- dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry
+(p7) cmp.eq p6,p7=r17,r0 // was pgd_present(*pgd) == NULL?
+ dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=p[u|m]d_offset(pgd,addr)
;;
#ifdef CONFIG_PGTABLE_4
-(p7) ld8 r17=[r17] // fetch the L2 entry (may be 0)
- shr.u r18=r22,PMD_SHIFT // shift L3 index into position
+(p7) ld8 r17=[r17] // get *pud (may be 0)
+ shr.u r18=r22,PMD_SHIFT // shift pmd index into position
;;
-(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL?
- dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry
+(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was pud_present(*pud) == NULL?
+ dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=pmd_offset(pud,addr)
;;
#endif
-(p7) ld8 r17=[r17] // fetch the L3 entry (may be 0)
- shr.u r19=r22,PAGE_SHIFT // shift L4 index into position
+(p7) ld8 r17=[r17] // get *pmd (may be 0)
+ shr.u r19=r22,PAGE_SHIFT // shift pte index into position
;;
-(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L3 entry NULL?
- dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L4 page table entry
+(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was pmd_present(*pmd) == NULL?
+ dep r17=r19,r17,3,(PAGE_SHIFT-3) // r17=pte_offset(pmd,addr);
(p6) br.cond.spnt page_fault
mov b0=r30
br.sptk.many b0 // return to continuation point
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 988844a169e..d016d672ec2 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -499,8 +499,12 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
dev = create_parisc_device(mod_path);
if (dev->id.hw_type != HPHW_FAULTY) {
- printk("Two devices have hardware path %s. Please file a bug with HP.\n"
- "In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev));
+ printk(KERN_ERR "Two devices have hardware path [%s]. "
+ "IODC data for second device: "
+ "%02x%02x%02x%02x%02x%02x\n"
+ "Rearranging GSC cards sometimes helps\n",
+ parisc_pathname(dev), iodc_data[0], iodc_data[1],
+ iodc_data[3], iodc_data[4], iodc_data[5], iodc_data[6]);
return NULL;
}
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index c7e66ee5b08..9af4b22a6d7 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -1846,6 +1846,7 @@ sys_clone_wrapper:
ldo -16(%r30),%r29 /* Reference param save area */
#endif
+ /* WARNING - Clobbers r19 and r21, userspace must save these! */
STREG %r2,PT_GR19(%r1) /* save for child */
STREG %r30,PT_GR21(%r1)
BL sys_clone,%r2
diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
index 1a1c6642273..8f563871e83 100644
--- a/arch/parisc/kernel/inventory.c
+++ b/arch/parisc/kernel/inventory.c
@@ -188,7 +188,7 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
temp = pa_pdc_cell.cba;
dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
if (!dev) {
- return PDC_NE_MOD;
+ return PDC_OK;
}
/* alloc_pa_dev sets dev->hpa */
diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
index 0a331104ad5..4eada1bb27f 100644
--- a/arch/parisc/kernel/ioctl32.c
+++ b/arch/parisc/kernel/ioctl32.c
@@ -19,536 +19,6 @@
#define CODE
#include "compat_ioctl.c"
-/* Use this to get at 32-bit user passed pointers.
- See sys_sparc32.c for description about these. */
-#define A(__x) ((unsigned long)(__x))
-/* The same for use with copy_from_user() and copy_to_user(). */
-#define B(__x) ((void *)(unsigned long)(__x))
-
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-/* This really belongs in include/linux/drm.h -DaveM */
-#include "../../../drivers/char/drm/drm.h"
-
-typedef struct drm32_version {
- int version_major; /* Major version */
- int version_minor; /* Minor version */
- int version_patchlevel;/* Patch level */
- int name_len; /* Length of name buffer */
- u32 name; /* Name of driver */
- int date_len; /* Length of date buffer */
- u32 date; /* User-space buffer to hold date */
- int desc_len; /* Length of desc buffer */
- u32 desc; /* User-space buffer to hold desc */
-} drm32_version_t;
-#define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
-
-static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_version_t *uversion = (drm32_version_t *)arg;
- char *name_ptr, *date_ptr, *desc_ptr;
- u32 tmp1, tmp2, tmp3;
- drm_version_t kversion;
- mm_segment_t old_fs;
- int ret;
-
- memset(&kversion, 0, sizeof(kversion));
- if (get_user(kversion.name_len, &uversion->name_len) ||
- get_user(kversion.date_len, &uversion->date_len) ||
- get_user(kversion.desc_len, &uversion->desc_len) ||
- get_user(tmp1, &uversion->name) ||
- get_user(tmp2, &uversion->date) ||
- get_user(tmp3, &uversion->desc))
- return -EFAULT;
-
- name_ptr = (char *) A(tmp1);
- date_ptr = (char *) A(tmp2);
- desc_ptr = (char *) A(tmp3);
-
- ret = -ENOMEM;
- if (kversion.name_len && name_ptr) {
- kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
- if (!kversion.name)
- goto out;
- }
- if (kversion.date_len && date_ptr) {
- kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
- if (!kversion.date)
- goto out;
- }
- if (kversion.desc_len && desc_ptr) {
- kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
- if (!kversion.desc)
- goto out;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
- set_fs(old_fs);
-
- if (!ret) {
- if ((kversion.name &&
- copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
- (kversion.date &&
- copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
- (kversion.desc &&
- copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
- ret = -EFAULT;
- if (put_user(kversion.version_major, &uversion->version_major) ||
- put_user(kversion.version_minor, &uversion->version_minor) ||
- put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
- put_user(kversion.name_len, &uversion->name_len) ||
- put_user(kversion.date_len, &uversion->date_len) ||
- put_user(kversion.desc_len, &uversion->desc_len))
- ret = -EFAULT;
- }
-
-out:
- kfree(kversion.name);
- kfree(kversion.date);
- kfree(kversion.desc);
- return ret;
-}
-
-typedef struct drm32_unique {
- int unique_len; /* Length of unique */
- u32 unique; /* Unique name for driver instantiation */
-} drm32_unique_t;
-#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
-#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
-
-static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_unique_t *uarg = (drm32_unique_t *)arg;
- drm_unique_t karg;
- mm_segment_t old_fs;
- char *uptr;
- u32 tmp;
- int ret;
-
- if (get_user(karg.unique_len, &uarg->unique_len))
- return -EFAULT;
- karg.unique = NULL;
-
- if (get_user(tmp, &uarg->unique))
- return -EFAULT;
-
- uptr = (char *) A(tmp);
-
- if (uptr) {
- karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
- if (!karg.unique)
- return -ENOMEM;
- if (cmd == DRM32_IOCTL_SET_UNIQUE &&
- copy_from_user(karg.unique, uptr, karg.unique_len)) {
- kfree(karg.unique);
- return -EFAULT;
- }
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- if (cmd == DRM32_IOCTL_GET_UNIQUE)
- ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
- else
- ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (cmd == DRM32_IOCTL_GET_UNIQUE &&
- uptr != NULL &&
- copy_to_user(uptr, karg.unique, karg.unique_len))
- ret = -EFAULT;
- if (put_user(karg.unique_len, &uarg->unique_len))
- ret = -EFAULT;
- }
-
- kfree(karg.unique);
- return ret;
-}
-
-typedef struct drm32_map {
- u32 offset; /* Requested physical address (0 for SAREA)*/
- u32 size; /* Requested physical size (bytes) */
- drm_map_type_t type; /* Type of memory to map */
- drm_map_flags_t flags; /* Flags */
- u32 handle; /* User-space: "Handle" to pass to mmap */
- /* Kernel-space: kernel-virtual address */
- int mtrr; /* MTRR slot used */
- /* Private data */
-} drm32_map_t;
-#define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
-
-static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_map_t *uarg = (drm32_map_t *) arg;
- drm_map_t karg;
- mm_segment_t old_fs;
- u32 tmp;
- int ret;
-
- ret = get_user(karg.offset, &uarg->offset);
- ret |= get_user(karg.size, &uarg->size);
- ret |= get_user(karg.type, &uarg->type);
- ret |= get_user(karg.flags, &uarg->flags);
- ret |= get_user(tmp, &uarg->handle);
- ret |= get_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- return -EFAULT;
-
- karg.handle = (void *) A(tmp);
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- ret = put_user(karg.offset, &uarg->offset);
- ret |= put_user(karg.size, &uarg->size);
- ret |= put_user(karg.type, &uarg->type);
- ret |= put_user(karg.flags, &uarg->flags);
- tmp = (u32) (long)karg.handle;
- ret |= put_user(tmp, &uarg->handle);
- ret |= put_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- ret = -EFAULT;
- }
-
- return ret;
-}
-
-typedef struct drm32_buf_info {
- int count; /* Entries in list */
- u32 list; /* (drm_buf_desc_t *) */
-} drm32_buf_info_t;
-#define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
-
-static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
- drm_buf_desc_t *ulist;
- drm_buf_info_t karg;
- mm_segment_t old_fs;
- int orig_count, ret;
- u32 tmp;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->list))
- return -EFAULT;
-
- ulist = (drm_buf_desc_t *) A(tmp);
-
- orig_count = karg.count;
-
- karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
- if (!karg.list)
- return -EFAULT;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (karg.count <= orig_count &&
- (copy_to_user(ulist, karg.list,
- karg.count * sizeof(drm_buf_desc_t))))
- ret = -EFAULT;
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
- kfree(karg.list);
- return ret;
-}
-
-typedef struct drm32_buf_free {
- int count;
- u32 list; /* (int *) */
-} drm32_buf_free_t;
-#define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
-
-static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
- drm_buf_free_t karg;
- mm_segment_t old_fs;
- int *ulist;
- int ret;
- u32 tmp;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->list))
- return -EFAULT;
-
- ulist = (int *) A(tmp);
-
- karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
- if (!karg.list)
- return -ENOMEM;
-
- ret = -EFAULT;
- if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
- goto out;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
-out:
- kfree(karg.list);
- return ret;
-}
-
-typedef struct drm32_buf_pub {
- int idx; /* Index into master buflist */
- int total; /* Buffer size */
- int used; /* Amount of buffer in use (for DMA) */
- u32 address; /* Address of buffer (void *) */
-} drm32_buf_pub_t;
-
-typedef struct drm32_buf_map {
- int count; /* Length of buflist */
- u32 virtual; /* Mmaped area in user-virtual (void *) */
- u32 list; /* Buffer information (drm_buf_pub_t *) */
-} drm32_buf_map_t;
-#define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
-
-static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
- drm32_buf_pub_t *ulist;
- drm_buf_map_t karg;
- mm_segment_t old_fs;
- int orig_count, ret, i;
- u32 tmp1, tmp2;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp1, &uarg->virtual) ||
- get_user(tmp2, &uarg->list))
- return -EFAULT;
-
- karg.virtual = (void *) A(tmp1);
- ulist = (drm32_buf_pub_t *) A(tmp2);
-
- orig_count = karg.count;
-
- karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
- if (!karg.list)
- return -ENOMEM;
-
- ret = -EFAULT;
- for (i = 0; i < karg.count; i++) {
- if (get_user(karg.list[i].idx, &ulist[i].idx) ||
- get_user(karg.list[i].total, &ulist[i].total) ||
- get_user(karg.list[i].used, &ulist[i].used) ||
- get_user(tmp1, &ulist[i].address))
- goto out;
-
- karg.list[i].address = (void *) A(tmp1);
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- for (i = 0; i < orig_count; i++) {
- tmp1 = (u32) (long) karg.list[i].address;
- if (put_user(karg.list[i].idx, &ulist[i].idx) ||
- put_user(karg.list[i].total, &ulist[i].total) ||
- put_user(karg.list[i].used, &ulist[i].used) ||
- put_user(tmp1, &ulist[i].address)) {
- ret = -EFAULT;
- goto out;
- }
- }
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
-out:
- kfree(karg.list);
- return ret;
-}
-
-typedef struct drm32_dma {
- /* Indices here refer to the offset into
- buflist in drm_buf_get_t. */
- int context; /* Context handle */
- int send_count; /* Number of buffers to send */
- u32 send_indices; /* List of handles to buffers (int *) */
- u32 send_sizes; /* Lengths of data to send (int *) */
- drm_dma_flags_t flags; /* Flags */
- int request_count; /* Number of buffers requested */
- int request_size; /* Desired size for buffers */
- u32 request_indices; /* Buffer information (int *) */
- u32 request_sizes; /* (int *) */
- int granted_count; /* Number of buffers granted */
-} drm32_dma_t;
-#define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
-
-/* RED PEN The DRM layer blindly dereferences the send/request
- * indice/size arrays even though they are userland
- * pointers. -DaveM
- */
-static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_dma_t *uarg = (drm32_dma_t *) arg;
- int *u_si, *u_ss, *u_ri, *u_rs;
- drm_dma_t karg;
- mm_segment_t old_fs;
- int ret;
- u32 tmp1, tmp2, tmp3, tmp4;
-
- karg.send_indices = karg.send_sizes = NULL;
- karg.request_indices = karg.request_sizes = NULL;
-
- if (get_user(karg.context, &uarg->context) ||
- get_user(karg.send_count, &uarg->send_count) ||
- get_user(tmp1, &uarg->send_indices) ||
- get_user(tmp2, &uarg->send_sizes) ||
- get_user(karg.flags, &uarg->flags) ||
- get_user(karg.request_count, &uarg->request_count) ||
- get_user(karg.request_size, &uarg->request_size) ||
- get_user(tmp3, &uarg->request_indices) ||
- get_user(tmp4, &uarg->request_sizes) ||
- get_user(karg.granted_count, &uarg->granted_count))
- return -EFAULT;
-
- u_si = (int *) A(tmp1);
- u_ss = (int *) A(tmp2);
- u_ri = (int *) A(tmp3);
- u_rs = (int *) A(tmp4);
-
- if (karg.send_count) {
- karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
- karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-
- ret = -ENOMEM;
- if (!karg.send_indices || !karg.send_sizes)
- goto out;
-
- ret = -EFAULT;
- if (copy_from_user(karg.send_indices, u_si,
- (karg.send_count * sizeof(int))) ||
- copy_from_user(karg.send_sizes, u_ss,
- (karg.send_count * sizeof(int))))
- goto out;
- }
-
- if (karg.request_count) {
- karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
- karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-
- ret = -ENOMEM;
- if (!karg.request_indices || !karg.request_sizes)
- goto out;
-
- ret = -EFAULT;
- if (copy_from_user(karg.request_indices, u_ri,
- (karg.request_count * sizeof(int))) ||
- copy_from_user(karg.request_sizes, u_rs,
- (karg.request_count * sizeof(int))))
- goto out;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (put_user(karg.context, &uarg->context) ||
- put_user(karg.send_count, &uarg->send_count) ||
- put_user(karg.flags, &uarg->flags) ||
- put_user(karg.request_count, &uarg->request_count) ||
- put_user(karg.request_size, &uarg->request_size) ||
- put_user(karg.granted_count, &uarg->granted_count))
- ret = -EFAULT;
-
- if (karg.send_count) {
- if (copy_to_user(u_si, karg.send_indices,
- (karg.send_count * sizeof(int))) ||
- copy_to_user(u_ss, karg.send_sizes,
- (karg.send_count * sizeof(int))))
- ret = -EFAULT;
- }
- if (karg.request_count) {
- if (copy_to_user(u_ri, karg.request_indices,
- (karg.request_count * sizeof(int))) ||
- copy_to_user(u_rs, karg.request_sizes,
- (karg.request_count * sizeof(int))))
- ret = -EFAULT;
- }
- }
-
-out:
- kfree(karg.send_indices);
- kfree(karg.send_sizes);
- kfree(karg.request_indices);
- kfree(karg.request_sizes);
- return ret;
-}
-
-typedef struct drm32_ctx_res {
- int count;
- u32 contexts; /* (drm_ctx_t *) */
-} drm32_ctx_res_t;
-#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
-
-static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
- drm_ctx_t *ulist;
- drm_ctx_res_t karg;
- mm_segment_t old_fs;
- int orig_count, ret;
- u32 tmp;
-
- karg.contexts = NULL;
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->contexts))
- return -EFAULT;
-
- ulist = (drm_ctx_t *) A(tmp);
-
- orig_count = karg.count;
- if (karg.count && ulist) {
- karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
- if (!karg.contexts)
- return -ENOMEM;
- if (copy_from_user(karg.contexts, ulist,
- (karg.count * sizeof(drm_ctx_t)))) {
- kfree(karg.contexts);
- return -EFAULT;
- }
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (orig_count) {
- if (copy_to_user(ulist, karg.contexts,
- (orig_count * sizeof(drm_ctx_t))))
- ret = -EFAULT;
- }
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
- kfree(karg.contexts);
- return ret;
-}
-
-#endif
-
#define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl)
@@ -561,11 +31,6 @@ IOCTL_TABLE_START
#define DECLARES
#include "compat_ioctl.c"
-/* PA-specific ioctls */
-COMPATIBLE_IOCTL(PA_PERF_ON)
-COMPATIBLE_IOCTL(PA_PERF_OFF)
-COMPATIBLE_IOCTL(PA_PERF_VERSION)
-
/* And these ioctls need translation */
HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
@@ -590,17 +55,6 @@ HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
COMPATIBLE_IOCTL(RTC_EPOCH_SET)
#endif
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
-#endif /* DRM */
IOCTL_TABLE_END
int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 006385dbee6..197936d9359 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -30,6 +30,9 @@
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/types.h>
+#include <asm/io.h>
+
+#include <asm/smp.h>
#undef PARISC_IRQ_CR16_COUNTS
@@ -43,26 +46,34 @@ extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
*/
static volatile unsigned long cpu_eiem = 0;
-static void cpu_set_eiem(void *info)
-{
- set_eiem((unsigned long) info);
-}
-
-static inline void cpu_disable_irq(unsigned int irq)
+static void cpu_disable_irq(unsigned int irq)
{
unsigned long eirr_bit = EIEM_MASK(irq);
cpu_eiem &= ~eirr_bit;
- on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+ /* Do nothing on the other CPUs. If they get this interrupt,
+ * The & cpu_eiem in the do_cpu_irq_mask() ensures they won't
+ * handle it, and the set_eiem() at the bottom will ensure it
+ * then gets disabled */
}
static void cpu_enable_irq(unsigned int irq)
{
unsigned long eirr_bit = EIEM_MASK(irq);
- mtctl(eirr_bit, 23); /* clear EIRR bit before unmasking */
cpu_eiem |= eirr_bit;
- on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+
+ /* FIXME: while our interrupts aren't nested, we cannot reset
+ * the eiem mask if we're already in an interrupt. Once we
+ * implement nested interrupts, this can go away
+ */
+ if (!in_interrupt())
+ set_eiem(cpu_eiem);
+
+ /* This is just a simple NOP IPI. But what it does is cause
+ * all the other CPUs to do a set_eiem(cpu_eiem) at the end
+ * of the interrupt handler */
+ smp_send_all_nop();
}
static unsigned int cpu_startup_irq(unsigned int irq)
@@ -74,6 +85,35 @@ static unsigned int cpu_startup_irq(unsigned int irq)
void no_ack_irq(unsigned int irq) { }
void no_end_irq(unsigned int irq) { }
+#ifdef CONFIG_SMP
+int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
+{
+ int cpu_dest;
+
+ /* timer and ipi have to always be received on all CPUs */
+ if (irq == TIMER_IRQ || irq == IPI_IRQ) {
+ /* Bad linux design decision. The mask has already
+ * been set; we must reset it */
+ irq_affinity[irq] = CPU_MASK_ALL;
+ return -EINVAL;
+ }
+
+ /* whatever mask they set, we just allow one CPU */
+ cpu_dest = first_cpu(*dest);
+ *dest = cpumask_of_cpu(cpu_dest);
+
+ return 0;
+}
+
+static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest)
+{
+ if (cpu_check_affinity(irq, &dest))
+ return;
+
+ irq_affinity[irq] = dest;
+}
+#endif
+
static struct hw_interrupt_type cpu_interrupt_type = {
.typename = "CPU",
.startup = cpu_startup_irq,
@@ -82,7 +122,9 @@ static struct hw_interrupt_type cpu_interrupt_type = {
.disable = cpu_disable_irq,
.ack = no_ack_irq,
.end = no_end_irq,
-// .set_affinity = cpu_set_affinity_irq,
+#ifdef CONFIG_SMP
+ .set_affinity = cpu_set_affinity_irq,
+#endif
};
int show_interrupts(struct seq_file *p, void *v)
@@ -219,6 +261,17 @@ int txn_alloc_irq(unsigned int bits_wide)
return -1;
}
+
+unsigned long txn_affinity_addr(unsigned int irq, int cpu)
+{
+#ifdef CONFIG_SMP
+ irq_affinity[irq] = cpumask_of_cpu(cpu);
+#endif
+
+ return cpu_data[cpu].txn_addr;
+}
+
+
unsigned long txn_alloc_addr(unsigned int virt_irq)
{
static int next_cpu = -1;
@@ -233,7 +286,7 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
if (next_cpu >= NR_CPUS)
next_cpu = 0; /* nothing else, assign monarch */
- return cpu_data[next_cpu].txn_addr;
+ return txn_affinity_addr(virt_irq, next_cpu);
}
@@ -250,10 +303,11 @@ void do_cpu_irq_mask(struct pt_regs *regs)
irq_enter();
/*
- * Only allow interrupt processing to be interrupted by the
- * timer tick
+ * Don't allow TIMER or IPI nested interrupts.
+ * Allowing any single interrupt to nest can lead to that CPU
+ * handling interrupts with all enabled interrupts unmasked.
*/
- set_eiem(EIEM_MASK(TIMER_IRQ));
+ set_eiem(0UL);
/* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
* 2) We loop here on EIRR contents in order to avoid
@@ -267,23 +321,41 @@ void do_cpu_irq_mask(struct pt_regs *regs)
if (!eirr_val)
break;
- if (eirr_val & EIEM_MASK(TIMER_IRQ))
- set_eiem(0);
-
mtctl(eirr_val, 23); /* reset bits we are going to process */
/* Work our way from MSb to LSb...same order we alloc EIRs */
for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
+#ifdef CONFIG_SMP
+ cpumask_t dest = irq_affinity[irq];
+#endif
if (!(bit & eirr_val))
continue;
/* clear bit in mask - can exit loop sooner */
eirr_val &= ~bit;
+#ifdef CONFIG_SMP
+ /* FIXME: because generic set affinity mucks
+ * with the affinity before sending it to us
+ * we can get the situation where the affinity is
+ * wrong for our CPU type interrupts */
+ if (irq != TIMER_IRQ && irq != IPI_IRQ &&
+ !cpu_isset(smp_processor_id(), dest)) {
+ int cpu = first_cpu(dest);
+
+ printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
+ irq, smp_processor_id(), cpu);
+ gsc_writel(irq + CPU_IRQ_BASE,
+ cpu_data[cpu].hpa);
+ continue;
+ }
+#endif
+
__do_IRQ(irq, regs);
}
}
- set_eiem(cpu_eiem);
+
+ set_eiem(cpu_eiem); /* restore original mask */
irq_exit();
}
@@ -291,12 +363,14 @@ void do_cpu_irq_mask(struct pt_regs *regs)
static struct irqaction timer_action = {
.handler = timer_interrupt,
.name = "timer",
+ .flags = SA_INTERRUPT,
};
#ifdef CONFIG_SMP
static struct irqaction ipi_action = {
.handler = ipi_interrupt,
.name = "IPI",
+ .flags = SA_INTERRUPT,
};
#endif
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index 44670d6e06f..f6fec62b6a2 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -196,8 +196,7 @@ static int perf_open(struct inode *inode, struct file *file);
static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
static ssize_t perf_write(struct file *file, const char __user *buf, size_t count,
loff_t *ppos);
-static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg);
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static void perf_start_counters(void);
static int perf_stop_counters(uint32_t *raddr);
static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
@@ -438,48 +437,56 @@ static void perf_patch_images(void)
* must be running on the processor that you wish to change.
*/
-static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long error_start;
- uint32_t raddr[4];
+ uint32_t raddr[4];
+ int error = 0;
+ lock_kernel();
switch (cmd) {
case PA_PERF_ON:
/* Start the counters */
perf_start_counters();
- return 0;
+ break;
case PA_PERF_OFF:
error_start = perf_stop_counters(raddr);
if (error_start != 0) {
printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
- return -EFAULT;
+ error = -EFAULT;
+ break;
}
/* copy out the Counters */
if (copy_to_user((void __user *)arg, raddr,
sizeof (raddr)) != 0) {
- return -EFAULT;
+ error = -EFAULT;
+ break;
}
- return 0;
+ break;
case PA_PERF_VERSION:
/* Return the version # */
- return put_user(PERF_VERSION, (int *)arg);
+ error = put_user(PERF_VERSION, (int *)arg);
+ break;
default:
- break;
+ error = -ENOTTY;
}
- return -ENOTTY;
+
+ unlock_kernel();
+
+ return error;
}
static struct file_operations perf_fops = {
.llseek = no_llseek,
.read = perf_read,
.write = perf_write,
- .ioctl = perf_ioctl,
+ .unlocked_ioctl = perf_ioctl,
+ .compat_ioctl = perf_ioctl,
.open = perf_open,
.release = perf_release
};
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index b6fe202a620..27160e8bf15 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -264,6 +264,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
* sigkill. perhaps it should be put in the status
* that it wants to exit.
*/
+ ret = 0;
DBG("sys_ptrace(KILL)\n");
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
goto out_tsk;
@@ -344,11 +345,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_GETEVENTMSG:
ret = put_user(child->ptrace_message, (unsigned int __user *) data);
- goto out;
+ goto out_tsk;
default:
ret = ptrace_request(child, request, addr, data);
- goto out;
+ goto out_tsk;
}
out_wake_notrap:
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 82c24e62ab6..3a25a7bd673 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -296,7 +296,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
struct rt_sigframe __user *frame;
unsigned long rp, usp;
unsigned long haddr, sigframe_size;
- struct siginfo si;
int err = 0;
#ifdef __LP64__
compat_int_t compat_val;
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index a9ecf646578..ce89da0f654 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -181,12 +181,19 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while (ops) {
unsigned long which = ffz(~ops);
+ ops &= ~(1 << which);
+
switch (which) {
+ case IPI_NOP:
+#if (kDEBUG>=100)
+ printk(KERN_DEBUG "CPU%d IPI_NOP\n",this_cpu);
+#endif /* kDEBUG */
+ break;
+
case IPI_RESCHEDULE:
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_RESCHEDULE);
/*
* Reschedule callback. Everything to be
* done is done by the interrupt return path.
@@ -197,7 +204,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_CALL_FUNC);
{
volatile struct smp_call_struct *data;
void (*func)(void *info);
@@ -231,7 +237,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_CPU_START);
#ifdef ENTRY_SYS_CPUS
p->state = STATE_RUNNING;
#endif
@@ -241,7 +246,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_CPU_STOP);
#ifdef ENTRY_SYS_CPUS
#else
halt_processor();
@@ -252,13 +256,11 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_CPU_TEST);
break;
default:
printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
this_cpu, which);
- ops &= ~(1 << which);
return IRQ_NONE;
} /* Switch */
} /* while (ops) */
@@ -312,6 +314,12 @@ smp_send_start(void) { send_IPI_allbutself(IPI_CPU_START); }
void
smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
+void
+smp_send_all_nop(void)
+{
+ send_IPI_allbutself(IPI_NOP);
+}
+
/**
* Run a function on all other CPUs.
@@ -338,6 +346,10 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
+
+ /* can also deadlock if IPIs are disabled */
+ WARN_ON((get_eiem() & (1UL<<(CPU_IRQ_MAX - IPI_IRQ))) == 0);
+
data.func = func;
data.info = info;
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index b29b76b42bb..d6616349289 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -164,7 +164,7 @@ linux_gateway_entry:
#endif
STREG %r2, TASK_PT_GR30(%r1) /* ... and save it */
- STREG %r20, TASK_PT_GR20(%r1)
+ STREG %r20, TASK_PT_GR20(%r1) /* Syscall number */
STREG %r21, TASK_PT_GR21(%r1)
STREG %r22, TASK_PT_GR22(%r1)
STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */
@@ -527,6 +527,7 @@ lws_compare_and_swap:
We *must* giveup this call and fail.
*/
ldw 4(%sr2,%r20), %r28 /* Load thread register */
+ /* WARNING: If cr27 cycles to the same value we have problems */
mfctl %cr27, %r21 /* Get current thread register */
cmpb,<>,n %r21, %r28, cas_lock /* Called recursive? */
b lws_exit /* Return error! */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 5a5b2468508..8b6008ab217 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -40,7 +40,7 @@
#endif
unsigned long pci_probe_only = 1;
-unsigned long pci_assign_all_buses = 0;
+int pci_assign_all_buses = 0;
/*
* legal IO pages under MAX_ISA_PORT. This is to ensure we don't touch
@@ -55,11 +55,6 @@ static void fixup_resource(struct resource *res, struct pci_dev *dev);
static void do_bus_setup(struct pci_bus *bus);
#endif
-unsigned int pcibios_assign_all_busses(void)
-{
- return pci_assign_all_buses;
-}
-
/* pci_io_base -- the base address from which io bars are offsets.
* This is the lowest I/O base address (so bar values are always positive),
* and it *must* be the start of ISA space if an ISA bus exists because
@@ -1186,17 +1181,6 @@ void phbs_remap_io(void)
remap_bus_range(hose->bus);
}
-/*
- * ppc64 can have multifunction devices that do not respond to function 0.
- * In this case we must scan all functions.
- * XXX this can go now, we use the OF device tree in all the
- * cases that caused problems. -- paulus
- */
-int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
-{
- return 0;
-}
-
static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
{
struct pci_controller *hose = pci_bus_to_host(dev->bus);
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 59846b40d52..af4d1bc9a2e 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -146,9 +146,6 @@ EXPORT_SYMBOL(pci_bus_io_base);
EXPORT_SYMBOL(pci_bus_io_base_phys);
EXPORT_SYMBOL(pci_bus_mem_base_phys);
EXPORT_SYMBOL(pci_bus_to_hose);
-EXPORT_SYMBOL(pci_resource_to_bus);
-EXPORT_SYMBOL(pci_phys_to_bus);
-EXPORT_SYMBOL(pci_bus_to_phys);
#endif /* CONFIG_PCI */
#ifdef CONFIG_NOT_COHERENT_CACHE
diff --git a/include/asm-ppc64/ptrace-common.h b/arch/powerpc/kernel/ptrace-common.h
index b1babb72967..b1babb72967 100644
--- a/include/asm-ppc64/ptrace-common.h
+++ b/arch/powerpc/kernel/ptrace-common.h
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 3d2abd95c7a..400793c7130 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -36,8 +36,9 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
+
#ifdef CONFIG_PPC64
-#include <asm/ptrace-common.h>
+#include "ptrace-common.h"
#endif
#ifdef CONFIG_PPC32
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 91eb952e029..61762640b87 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -33,7 +33,8 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
-#include <asm/ptrace-common.h>
+
+#include "ptrace-common.h"
/*
* does not yet catch signals sent when the child dies.
diff --git a/arch/powerpc/mm/imalloc.c b/arch/powerpc/mm/imalloc.c
index f4ca29cf536..f9587bcc6a4 100644
--- a/arch/powerpc/mm/imalloc.c
+++ b/arch/powerpc/mm/imalloc.c
@@ -14,9 +14,10 @@
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/semaphore.h>
-#include <asm/imalloc.h>
#include <asm/cacheflush.h>
+#include "mmu_decl.h"
+
static DECLARE_MUTEX(imlist_sem);
struct vm_struct * imlist = NULL;
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 1134f70f231..81cfb0c2ec5 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -64,7 +64,8 @@
#include <asm/iommu.h>
#include <asm/abs_addr.h>
#include <asm/vdso.h>
-#include <asm/imalloc.h>
+
+#include "mmu_decl.h"
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index a4d7a327c0e..bea2d21ac6f 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -33,7 +33,6 @@ extern void invalidate_tlbcam_entry(int index);
extern int __map_without_bats;
extern unsigned long ioremap_base;
-extern unsigned long ioremap_bot;
extern unsigned int rtas_data, rtas_size;
extern PTE *Hash, *Hash_end;
@@ -42,6 +41,7 @@ extern unsigned long Hash_size, Hash_mask;
extern unsigned int num_tlbcam_entries;
#endif
+extern unsigned long ioremap_bot;
extern unsigned long __max_low_memory;
extern unsigned long __initial_memory_limit;
extern unsigned long total_memory;
@@ -84,4 +84,16 @@ static inline void flush_HPTE(unsigned context, unsigned long va,
else
_tlbie(va);
}
+#else /* CONFIG_PPC64 */
+/* imalloc region types */
+#define IM_REGION_UNUSED 0x1
+#define IM_REGION_SUBSET 0x2
+#define IM_REGION_EXISTS 0x4
+#define IM_REGION_OVERLAP 0x8
+#define IM_REGION_SUPERSET 0x10
+
+extern struct vm_struct * im_get_free_area(unsigned long size);
+extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
+ int region_type);
+extern void im_free(void *addr);
#endif
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index c7f7bb6f30b..2ffca63602c 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -64,7 +64,8 @@
#include <asm/iommu.h>
#include <asm/abs_addr.h>
#include <asm/vdso.h>
-#include <asm/imalloc.h>
+
+#include "mmu_decl.h"
unsigned long ioremap_bot = IMALLOC_BASE;
static unsigned long phbs_io_bot = PHBS_IO_BASE;
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 957b0910342..fb2a7c798e8 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -34,6 +34,7 @@
#include <linux/errno.h>
#include <linux/hardirq.h>
#include <linux/cpu.h>
+#include <linux/compiler.h>
#include <asm/ptrace.h>
#include <asm/atomic.h>
@@ -631,8 +632,9 @@ void smp_core99_give_timebase(void)
mb();
/* wait for the secondary to have taken it */
- for (t = 100000; t > 0 && sec_tb_reset; --t)
- udelay(10);
+ /* note: can't use udelay here, since it needs the timebase running */
+ for (t = 10000000; t > 0 && sec_tb_reset; --t)
+ barrier();
if (sec_tb_reset)
/* XXX BUG_ON here? */
printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 105f05341a4..58d1cc2023c 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -361,7 +361,8 @@ static void mpic_enable_irq(unsigned int irq)
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK);
+ mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+ ~MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -381,7 +382,8 @@ static void mpic_disable_irq(unsigned int irq)
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK);
+ mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+ MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -735,12 +737,13 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
spin_lock_irqsave(&mpic_lock, flags);
if (is_ipi) {
- reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK;
+ reg = mpic_ipi_read(irq - mpic->ipi_offset) &
+ ~MPIC_VECPRI_PRIORITY_MASK;
mpic_ipi_write(irq - mpic->ipi_offset,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
} else {
- reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI)
- & MPIC_VECPRI_PRIORITY_MASK;
+ reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
+ & ~MPIC_VECPRI_PRIORITY_MASK;
mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
}
diff --git a/block/as-iosched.c b/block/as-iosched.c
index a78e160b59a..fbe050124ec 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -1,6 +1,4 @@
/*
- * linux/drivers/block/as-iosched.c
- *
* Anticipatory & deadline i/o scheduler.
*
* Copyright (C) 2002 Jens Axboe <axboe@suse.de>
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 2b64f5852bf..ee0bb41694b 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1,6 +1,4 @@
/*
- * linux/drivers/block/cfq-iosched.c
- *
* CFQ, or complete fairness queueing, disk scheduler.
*
* Based on ideas from a previously unfinished io
diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c
index 7929471d7df..9cbec09e841 100644
--- a/block/deadline-iosched.c
+++ b/block/deadline-iosched.c
@@ -1,6 +1,4 @@
/*
- * linux/drivers/block/deadline-iosched.c
- *
* Deadline i/o scheduler.
*
* Copyright (C) 2002 Jens Axboe <axboe@suse.de>
diff --git a/block/elevator.c b/block/elevator.c
index e4c58827bb4..6c3fc8a10bf 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -1,6 +1,4 @@
/*
- * linux/drivers/block/elevator.c
- *
* Block device elevator/IO-scheduler.
*
* Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 5f52e30b43f..99c9ca6d599 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1,6 +1,4 @@
/*
- * linux/drivers/block/ll_rw_blk.c
- *
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1994, Karl Keyte: Added support for disk statistics
* Elevator latency, (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index e239a6c2923..a9e33db46e6 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1017,10 +1017,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
status = -ENOMEM;
goto cleanup1;
}
- if (ioc->Request.Type.Direction == XFER_WRITE &&
- copy_from_user(buff[sg_used], data_ptr, sz)) {
+ if (ioc->Request.Type.Direction == XFER_WRITE) {
+ if (copy_from_user(buff[sg_used], data_ptr, sz)) {
status = -ENOMEM;
- goto cleanup1;
+ goto cleanup1;
+ }
} else {
memset(buff[sg_used], 0, sz);
}
@@ -1138,8 +1139,15 @@ static int revalidate_allvol(ctlr_info_t *host)
for(i=0; i< NWD; i++) {
struct gendisk *disk = host->gendisk[i];
- if (disk->flags & GENHD_FL_UP)
- del_gendisk(disk);
+ if (disk) {
+ request_queue_t *q = disk->queue;
+
+ if (disk->flags & GENHD_FL_UP)
+ del_gendisk(disk);
+ if (q)
+ blk_cleanup_queue(q);
+ put_disk(disk);
+ }
}
/*
@@ -1453,10 +1461,13 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
* allows us to delete disk zero but keep the controller registered.
*/
if (h->gendisk[0] != disk){
- if (disk->flags & GENHD_FL_UP){
- blk_cleanup_queue(disk->queue);
- del_gendisk(disk);
- drv->queue = NULL;
+ if (disk) {
+ request_queue_t *q = disk->queue;
+ if (disk->flags & GENHD_FL_UP)
+ del_gendisk(disk);
+ if (q)
+ blk_cleanup_queue(q);
+ put_disk(disk);
}
}
@@ -3225,9 +3236,14 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
/* remove it from the disk list */
for (j = 0; j < NWD; j++) {
struct gendisk *disk = hba[i]->gendisk[j];
- if (disk->flags & GENHD_FL_UP) {
- del_gendisk(disk);
- blk_cleanup_queue(disk->queue);
+ if (disk) {
+ request_queue_t *q = disk->queue;
+
+ if (disk->flags & GENHD_FL_UP)
+ del_gendisk(disk);
+ if (q)
+ blk_cleanup_queue(q);
+ put_disk(disk);
}
}
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index cef024a7d04..cd6f45d186a 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -36,8 +36,6 @@
#include <asm/hardware.h> /* Pick up IXP2000-specific bits */
#include <asm/arch/gpio.h>
-static struct device_driver ixp2000_i2c_driver;
-
static inline int ixp2000_scl_pin(void *data)
{
return ((struct ixp2000_i2c_pins*)data)->scl_pin;
@@ -120,7 +118,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP2000,
- strlcpy(drv_data->adapter.name, ixp2000_i2c_driver.name,
+ strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
I2C_NAME_SIZE);
drv_data->adapter.algo_data = &drv_data->algo_data,
@@ -132,7 +130,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
gpio_line_set(gpio->sda_pin, 0);
if ((err = i2c_bit_add_bus(&drv_data->adapter)) != 0) {
- dev_err(dev, "Could not install, error %d\n", err);
+ dev_err(&plat_dev->dev, "Could not install, error %d\n", err);
kfree(drv_data);
return err;
}
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c
index f87220be3c8..e422d8b2d4d 100644
--- a/drivers/i2c/busses/i2c-ixp4xx.c
+++ b/drivers/i2c/busses/i2c-ixp4xx.c
@@ -35,8 +35,6 @@
#include <asm/hardware.h> /* Pick up IXP4xx-specific bits */
-static struct platform_driver ixp4xx_i2c_driver;
-
static inline int ixp4xx_scl_pin(void *data)
{
return ((struct ixp4xx_i2c_pins*)data)->scl_pin;
@@ -128,7 +126,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP4XX;
- strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.driver.name,
+ strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
I2C_NAME_SIZE);
drv_data->adapter.algo_data = &drv_data->algo_data;
@@ -140,8 +138,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
gpio_line_set(gpio->sda_pin, 0);
if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) {
- printk(KERN_ERR "ERROR: Could not install %s\n",
- plat_dev->dev.bus_id);
+ printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id);
kfree(drv_data);
return err;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index ed2bc87f475..31e649a9ff7 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -625,7 +625,7 @@ config BLK_DEV_NS87415
tristate "NS87415 chipset support"
help
This driver adds detection and support for the NS87415 chip
- (used in SPARC64, among others).
+ (used mainly on SPARC64 and PA-RISC machines).
Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index c2f47923d17..9455e42abb2 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3328,8 +3328,8 @@ static ide_proc_entry_t idecd_proc[] = {
#endif
static ide_driver_t ide_cdrom_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-cdrom",
.bus = &ide_bus_type,
.probe = ide_cd_probe,
@@ -3510,8 +3510,8 @@ static void __exit ide_cdrom_exit(void)
{
driver_unregister(&ide_cdrom_driver.gen_driver);
}
-
-static int ide_cdrom_init(void)
+
+static int __init ide_cdrom_init(void)
{
return driver_register(&ide_cdrom_driver.gen_driver);
}
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index e827b39e4b3..f4e3d3527b0 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1089,8 +1089,8 @@ static void ide_device_shutdown(struct device *dev)
}
static ide_driver_t idedisk_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-disk",
.bus = &ide_bus_type,
.probe = ide_disk_probe,
@@ -1266,7 +1266,7 @@ static void __exit idedisk_exit (void)
driver_unregister(&idedisk_driver.gen_driver);
}
-static int idedisk_init (void)
+static int __init idedisk_init(void)
{
return driver_register(&idedisk_driver.gen_driver);
}
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index f615ab75996..9e293c8063d 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -1925,8 +1925,8 @@ static ide_proc_entry_t idefloppy_proc[] = {
static int ide_floppy_probe(struct device *);
static ide_driver_t idefloppy_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-floppy",
.bus = &ide_bus_type,
.probe = ide_floppy_probe,
@@ -2191,10 +2191,7 @@ static void __exit idefloppy_exit (void)
driver_unregister(&idefloppy_driver.gen_driver);
}
-/*
- * idefloppy_init will register the driver for each floppy.
- */
-static int idefloppy_init (void)
+static int __init idefloppy_init(void)
{
printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
return driver_register(&idefloppy_driver.gen_driver);
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 5275cbb1afe..ecfafcdafea 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -1629,12 +1629,6 @@ EXPORT_SYMBOL(ide_init_drive_cmd);
* for the new rq to be completed. This is VERY DANGEROUS, and is
* intended for careful use by the ATAPI tape/cdrom driver code.
*
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed. As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
* If action is ide_end, then the rq is queued at the end of the
* request queue, and the function returns immediately without waiting
* for the new rq to be completed. This is again intended for careful
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index b09a6537c7a..41d46dbe6c2 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
{
u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */
- if (on && drive->media == ide_disk) {
- if (!PCI_DMA_BUS_IS_PHYS)
- addr = BLK_BOUNCE_ANY;
- else if (HWIF(drive)->pci_dev)
+ if (!PCI_DMA_BUS_IS_PHYS) {
+ addr = BLK_BOUNCE_ANY;
+ } else if (on && drive->media == ide_disk) {
+ if (HWIF(drive)->pci_dev)
addr = HWIF(drive)->pci_dev->dma_mask;
}
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 0ac7eb8f40d..7d7944ed415 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -4748,8 +4748,8 @@ static ide_proc_entry_t idetape_proc[] = {
static int ide_tape_probe(struct device *);
static ide_driver_t idetape_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-tape",
.bus = &ide_bus_type,
.probe = ide_tape_probe,
@@ -4916,10 +4916,7 @@ static void __exit idetape_exit (void)
unregister_chrdev(IDETAPE_MAJOR, "ht");
}
-/*
- * idetape_init will register the driver for each tape.
- */
-static int idetape_init (void)
+static int __init idetape_init(void)
{
int error = 1;
idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 54f9639c2a8..62ebefd6394 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -51,8 +51,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-#define DEBUG_TASKFILE 0 /* unset when fixed */
-
static void ata_bswap_data (void *buffer, int wcount)
{
u16 *p = buffer;
@@ -765,9 +763,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
ide_hwif_t *hwif = HWIF(drive);
task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
-#if DEBUG_TASKFILE
- u8 status;
-#endif
if (task->data_phase == TASKFILE_MULTI_IN ||
task->data_phase == TASKFILE_MULTI_OUT) {
@@ -778,19 +773,13 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
}
/*
- * (ks) Check taskfile in/out flags.
+ * (ks) Check taskfile in flags.
* If set, then execute as it is defined.
* If not set, then define default settings.
* The default values are:
- * write and read all taskfile registers (except data)
- * write and read the hob registers (sector,nsector,lcyl,hcyl)
+ * read all taskfile registers (except data)
+ * read the hob registers (sector, nsector, lcyl, hcyl)
*/
- if (task->tf_out_flags.all == 0) {
- task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
- if (drive->addressing == 1)
- task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
- }
-
if (task->tf_in_flags.all == 0) {
task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
if (drive->addressing == 1)
@@ -803,16 +792,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
SELECT_MASK(drive, 0);
-#if DEBUG_TASKFILE
- status = hwif->INB(IDE_STATUS_REG);
- if (status & 0x80) {
- printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status);
- udelay(100);
- status = hwif->INB(IDE_STATUS_REG);
- printk("flagged_taskfile -> Status = %02x\n", status);
- }
-#endif
-
if (task->tf_out_flags.b.data) {
u16 data = taskfile->data + (hobfile->data << 8);
hwif->OUTW(data, IDE_DATA_REG);
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index 52cadc005d7..a21b1e11eef 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -65,23 +65,6 @@ static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
#define BUSCLOCK(D) \
((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))
-#if 0
- if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
- (void) pci_read_config_byte(dev, 0x54, &art);
- p += sprintf(p, "DMA Mode: %s(%s)",
- (c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO",
- (art&0x02)?"2":(art&0x01)?"1":"0");
- p += sprintf(p, " %s(%s)",
- (c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO",
- (art&0x08)?"2":(art&0x04)?"1":"0");
- p += sprintf(p, " %s(%s)",
- (c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO",
- (art&0x20)?"2":(art&0x10)?"1":"0");
- p += sprintf(p, " %s(%s)\n",
- (c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO",
- (art&0x80)?"2":(art&0x40)?"1":"0");
- } else {
-#endif
/*
* TO DO: active tuning and correction of cards without a bios.
@@ -112,13 +95,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive)
switch(hwif->pci_dev->device) {
case PCI_DEVICE_ID_ARTOP_ATP865:
case PCI_DEVICE_ID_ARTOP_ATP865R:
-#if 0
- mode = (hwif->INB(hwif->dma_master) & 0x10) ? 4 : 3;
-#else
mode = (hwif->INB(((hwif->channel) ?
hwif->mate->dma_status :
hwif->dma_status)) & 0x10) ? 4 : 3;
-#endif
break;
case PCI_DEVICE_ID_ARTOP_ATP860:
case PCI_DEVICE_ID_ARTOP_ATP860R:
@@ -263,35 +242,9 @@ static int aec62xx_irq_timeout (ide_drive_t *drive)
case PCI_DEVICE_ID_ARTOP_ATP865:
case PCI_DEVICE_ID_ARTOP_ATP865R:
printk(" AEC62XX time out ");
-#if 0
- {
- int i = 0;
- u8 reg49h = 0;
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, &reg49h);
- for (i=0;i<256;i++)
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10);
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10);
- }
- return 0;
-#endif
default:
break;
}
-#if 0
- {
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = hwif->pci_dev;
- u8 tmp1 = 0, tmp2 = 0, mode6 = 0;
-
- pci_read_config_byte(dev, 0x44, &tmp1);
- pci_read_config_byte(dev, 0x45, &tmp2);
- printk(" AEC6280 r44=%x r45=%x ",tmp1,tmp2);
- mode6 = HWIF(drive)->INB(((hwif->channel) ?
- hwif->mate->dma_status :
- hwif->dma_status));
- printk(" AEC6280 133=%x ", (mode6 & 0x10));
- }
-#endif
return 0;
}
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 6cf49394a80..cf84350efc5 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -876,10 +876,15 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = {
static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
+ static struct pci_device_id ati_rs100[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) },
+ { },
+ };
+
ide_pci_device_t *d = &ali15x3_chipset;
- if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL))
- printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n");
+ if (pci_dev_present(ati_rs100))
+ printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
#if defined(CONFIG_SPARC64)
d->init_hwif = init_hwif_common_ali15x3;
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index 7dc24682d19..ea3c52cc8ac 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -222,10 +222,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
/* We must not grab the entire device, it has 'ISA' space in its
BARS too and we will freak out other bits of the kernel */
- if(pci_enable_device_bars(dev, 1<<2))
- {
+ if (pci_enable_device_bars(dev, 1<<2)) {
printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
- return 1;
+ return -ENODEV;
}
pci_set_master(dev);
if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 022d244f2eb..f1ca154dd52 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -6,7 +6,13 @@
*
* May be copied or modified under the terms of the GNU General Public License
*
- * Documentation available under NDA only
+ * Documentation for CMD680:
+ * http://gkernel.sourceforge.net/specs/sii/sii-0680a-v1.31.pdf.bz2
+ *
+ * Documentation for SiI 3112:
+ * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
+ *
+ * Errata and other documentation only available under NDA.
*
*
* FAQ Items:
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 16b3e2d8bfb..75a2253a3e6 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -87,6 +87,7 @@ static const struct {
u8 chipset_family;
u8 flags;
} SiSHostChipInfo[] = {
+ { "SiS965", PCI_DEVICE_ID_SI_965, ATA_133 },
{ "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 },
{ "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 },
{ "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 },
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index a4d099c937f..7161ce0ef5a 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -79,6 +79,7 @@ static struct via_isa_bridge {
u8 rev_max;
u16 flags;
} via_isa_bridges[] = {
+ { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -100,185 +101,14 @@ static struct via_isa_bridge {
{ NULL }
};
-static struct via_isa_bridge *via_config;
-static unsigned int via_80w;
static unsigned int via_clock;
static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
-/*
- * VIA /proc entry.
- */
-
-#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
-
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 via_proc = 0;
-static unsigned long via_base;
-static struct pci_dev *bmide_dev, *isa_dev;
-
-static char *via_control3[] = { "No limit", "64", "128", "192" };
-
-#define via_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
-#define via_print_drive(name, format, arg...)\
- p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
-
-
-/**
- * via_get_info - generate via /proc file
- * @buffer: buffer for data
- * @addr: set to start of data to use
- * @offset: current file offset
- * @count: size of read
- *
- * Fills in buffer with the debugging/configuration information for
- * the VIA chipset tuning and attached drives
- */
-
-static int via_get_info(char *buffer, char **addr, off_t offset, int count)
+struct via82cxxx_dev
{
- int speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
- uen[4], udma[4], umul[4], active8b[4], recover8b[4];
- struct pci_dev *dev = bmide_dev;
- unsigned int v, u, i;
- int len;
- u16 c, w;
- u8 t, x;
- char *p = buffer;
-
- via_print("----------VIA BusMastering IDE Configuration"
- "----------------");
-
- via_print("Driver Version: 3.38");
- via_print("South Bridge: VIA %s",
- via_config->name);
-
- pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
- pci_read_config_byte(dev, PCI_REVISION_ID, &x);
- via_print("Revision: ISA %#x IDE %#x", t, x);
- via_print("Highest DMA rate: %s",
- via_dma[via_config->flags & VIA_UDMA]);
-
- via_print("BM-DMA base: %#lx", via_base);
- via_print("PCI clock: %d.%dMHz",
- via_clock / 1000, via_clock / 100 % 10);
-
- pci_read_config_byte(dev, VIA_MISC_1, &t);
- via_print("Master Read Cycle IRDY: %dws",
- (t & 64) >> 6);
- via_print("Master Write Cycle IRDY: %dws",
- (t & 32) >> 5);
- via_print("BM IDE Status Register Read Retry: %s",
- (t & 8) ? "yes" : "no");
-
- pci_read_config_byte(dev, VIA_MISC_3, &t);
- via_print("Max DRDY Pulse Width: %s%s",
- via_control3[(t & 0x03)], (t & 0x03) ? " PCI clocks" : "");
-
- via_print("-----------------------Primary IDE"
- "-------Secondary IDE------");
- via_print("Read DMA FIFO flush: %10s%20s",
- (t & 0x80) ? "yes" : "no", (t & 0x40) ? "yes" : "no");
- via_print("End Sector FIFO flush: %10s%20s",
- (t & 0x20) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
-
- pci_read_config_byte(dev, VIA_IDE_CONFIG, &t);
- via_print("Prefetch Buffer: %10s%20s",
- (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no");
- via_print("Post Write Buffer: %10s%20s",
- (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
-
- pci_read_config_byte(dev, VIA_IDE_ENABLE, &t);
- via_print("Enabled: %10s%20s",
- (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no");
-
- c = inb(via_base + 0x02) | (inb(via_base + 0x0a) << 8);
- via_print("Simplex only: %10s%20s",
- (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
-
- via_print("Cable Type: %10s%20s",
- (via_80w & 1) ? "80w" : "40w", (via_80w & 2) ? "80w" : "40w");
-
- via_print("-------------------drive0----drive1"
- "----drive2----drive3-----");
-
- pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
- pci_read_config_dword(dev, VIA_DRIVE_TIMING, &v);
- pci_read_config_word(dev, VIA_8BIT_TIMING, &w);
-
- if (via_config->flags & VIA_UDMA)
- pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
- else u = 0;
-
- for (i = 0; i < 4; i++) {
-
- setup[i] = ((t >> ((3 - i) << 1)) & 0x3) + 1;
- recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1;
- active8b[i] = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1;
- active[i] = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1;
- recover[i] = ((v >> ((3 - i) << 3)) & 0xf) + 1;
- udma[i] = ((u >> ((3 - i) << 3)) & 0x7) + 2;
- umul[i] = ((u >> (((3 - i) & 2) << 3)) & 0x8) ? 1 : 2;
- uen[i] = ((u >> ((3 - i) << 3)) & 0x20);
- den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
-
- speed[i] = 2 * via_clock / (active[i] + recover[i]);
- cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock;
-
- if (!uen[i] || !den[i])
- continue;
-
- switch (via_config->flags & VIA_UDMA) {
-
- case VIA_UDMA_33:
- speed[i] = 2 * via_clock / udma[i];
- cycle[i] = 1000000 * udma[i] / via_clock;
- break;
-
- case VIA_UDMA_66:
- speed[i] = 4 * via_clock / (udma[i] * umul[i]);
- cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock;
- break;
-
- case VIA_UDMA_100:
- speed[i] = 6 * via_clock / udma[i];
- cycle[i] = 333333 * udma[i] / via_clock;
- break;
-
- case VIA_UDMA_133:
- speed[i] = 8 * via_clock / udma[i];
- cycle[i] = 250000 * udma[i] / via_clock;
- break;
- }
- }
-
- via_print_drive("Transfer Mode: ", "%10s",
- den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
-
- via_print_drive("Address Setup: ", "%8dns",
- 1000000 * setup[i] / via_clock);
- via_print_drive("Cmd Active: ", "%8dns",
- 1000000 * active8b[i] / via_clock);
- via_print_drive("Cmd Recovery: ", "%8dns",
- 1000000 * recover8b[i] / via_clock);
- via_print_drive("Data Active: ", "%8dns",
- 1000000 * active[i] / via_clock);
- via_print_drive("Data Recovery: ", "%8dns",
- 1000000 * recover[i] / via_clock);
- via_print_drive("Cycle Time: ", "%8dns",
- cycle[i]);
- via_print_drive("Transfer Rate: ", "%4d.%dMB/s",
- speed[i] / 1000, speed[i] / 100 % 10);
-
- /* hoping it is less than 4K... */
- len = (p - buffer) - offset;
- *addr = buffer + offset;
-
- return len > count ? count : len;
-}
-
-#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
+ struct via_isa_bridge *via_config;
+ unsigned int via_80w;
+};
/**
* via_set_speed - write timing registers
@@ -289,11 +119,13 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
* via_set_speed writes timing values to the chipset registers
*/
-static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
+static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
{
+ struct pci_dev *dev = hwif->pci_dev;
+ struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
u8 t;
- if (~via_config->flags & VIA_BAD_AST) {
+ if (~vdev->via_config->flags & VIA_BAD_AST) {
pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
@@ -305,7 +137,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
- switch (via_config->flags & VIA_UDMA) {
+ switch (vdev->via_config->flags & VIA_UDMA) {
case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
@@ -329,6 +161,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
static int via_set_drive(ide_drive_t *drive, u8 speed)
{
ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
+ struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif);
struct ide_timing t, p;
unsigned int T, UT;
@@ -337,7 +170,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
T = 1000000000 / via_clock;
- switch (via_config->flags & VIA_UDMA) {
+ switch (vdev->via_config->flags & VIA_UDMA) {
case VIA_UDMA_33: UT = T; break;
case VIA_UDMA_66: UT = T/2; break;
case VIA_UDMA_100: UT = T/3; break;
@@ -352,7 +185,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
}
- via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
+ via_set_speed(HWIF(drive), drive->dn, &t);
if (!drive->init_speed)
drive->init_speed = speed;
@@ -390,20 +223,41 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
static int via82cxxx_ide_dma_check (ide_drive_t *drive)
{
- u16 w80 = HWIF(drive)->udma_four;
+ ide_hwif_t *hwif = HWIF(drive);
+ struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
+ u16 w80 = hwif->udma_four;
u16 speed = ide_find_best_mode(drive,
XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
- (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
- (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
- (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
- (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
+ (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
+ (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
+ (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
+ (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
via_set_drive(drive, speed);
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
- return HWIF(drive)->ide_dma_on(drive);
- return HWIF(drive)->ide_dma_off_quietly(drive);
+ return hwif->ide_dma_on(drive);
+ return hwif->ide_dma_off_quietly(drive);
+}
+
+static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
+{
+ struct via_isa_bridge *via_config;
+ u8 t;
+
+ for (via_config = via_isa_bridges; via_config->id; via_config++)
+ if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA +
+ !!(via_config->flags & VIA_BAD_ID),
+ via_config->id, NULL))) {
+
+ pci_read_config_byte(*isa, PCI_REVISION_ID, &t);
+ if (t >= via_config->rev_min &&
+ t <= via_config->rev_max)
+ break;
+ }
+
+ return via_config;
}
/**
@@ -418,82 +272,28 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
{
struct pci_dev *isa = NULL;
+ struct via_isa_bridge *via_config;
u8 t, v;
unsigned int u;
- int i;
/*
* Find the ISA bridge to see how good the IDE is.
*/
-
- for (via_config = via_isa_bridges; via_config->id; via_config++)
- if ((isa = pci_find_device(PCI_VENDOR_ID_VIA +
- !!(via_config->flags & VIA_BAD_ID),
- via_config->id, NULL))) {
-
- pci_read_config_byte(isa, PCI_REVISION_ID, &t);
- if (t >= via_config->rev_min &&
- t <= via_config->rev_max)
- break;
- }
-
+ via_config = via_config_find(&isa);
if (!via_config->id) {
printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
return -ENODEV;
}
/*
- * Check 80-wire cable presence and setup Clk66.
+ * Setup or disable Clk66 if appropriate
*/
- switch (via_config->flags & VIA_UDMA) {
-
- case VIA_UDMA_66:
- /* Enable Clk66 */
- pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
- pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
- for (i = 24; i >= 0; i -= 8)
- if (((u >> (i & 16)) & 8) &&
- ((u >> i) & 0x20) &&
- (((u >> i) & 7) < 2)) {
- /*
- * 2x PCI clock and
- * UDMA w/ < 3T/cycle
- */
- via_80w |= (1 << (1 - (i >> 4)));
- }
- break;
-
- case VIA_UDMA_100:
- pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
- for (i = 24; i >= 0; i -= 8)
- if (((u >> i) & 0x10) ||
- (((u >> i) & 0x20) &&
- (((u >> i) & 7) < 4))) {
- /* BIOS 80-wire bit or
- * UDMA w/ < 60ns/cycle
- */
- via_80w |= (1 << (1 - (i >> 4)));
- }
- break;
-
- case VIA_UDMA_133:
- pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
- for (i = 24; i >= 0; i -= 8)
- if (((u >> i) & 0x10) ||
- (((u >> i) & 0x20) &&
- (((u >> i) & 7) < 6))) {
- /* BIOS 80-wire bit or
- * UDMA w/ < 60ns/cycle
- */
- via_80w |= (1 << (1 - (i >> 4)));
- }
- break;
-
- }
-
- /* Disable Clk66 */
- if (via_config->flags & VIA_BAD_CLK66) {
+ if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) {
+ /* Enable Clk66 */
+ pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+ pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
+ } else if (via_config->flags & VIA_BAD_CLK66) {
/* Would cause trouble on 596a and 686 */
pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008);
@@ -560,26 +360,78 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
via_dma[via_config->flags & VIA_UDMA],
pci_name(dev));
- /*
- * Setup /proc/ide/via entry.
- */
+ return 0;
+}
+
+/*
+ * Check and handle 80-wire cable presence
+ */
+static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev)
+{
+ unsigned int u;
+ int i;
+ pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+
+ switch (vdev->via_config->flags & VIA_UDMA) {
+
+ case VIA_UDMA_66:
+ for (i = 24; i >= 0; i -= 8)
+ if (((u >> (i & 16)) & 8) &&
+ ((u >> i) & 0x20) &&
+ (((u >> i) & 7) < 2)) {
+ /*
+ * 2x PCI clock and
+ * UDMA w/ < 3T/cycle
+ */
+ vdev->via_80w |= (1 << (1 - (i >> 4)));
+ }
+ break;
+
+ case VIA_UDMA_100:
+ for (i = 24; i >= 0; i -= 8)
+ if (((u >> i) & 0x10) ||
+ (((u >> i) & 0x20) &&
+ (((u >> i) & 7) < 4))) {
+ /* BIOS 80-wire bit or
+ * UDMA w/ < 60ns/cycle
+ */
+ vdev->via_80w |= (1 << (1 - (i >> 4)));
+ }
+ break;
+
+ case VIA_UDMA_133:
+ for (i = 24; i >= 0; i -= 8)
+ if (((u >> i) & 0x10) ||
+ (((u >> i) & 0x20) &&
+ (((u >> i) & 7) < 6))) {
+ /* BIOS 80-wire bit or
+ * UDMA w/ < 60ns/cycle
+ */
+ vdev->via_80w |= (1 << (1 - (i >> 4)));
+ }
+ break;
-#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
- if (!via_proc) {
- via_base = pci_resource_start(dev, 4);
- bmide_dev = dev;
- isa_dev = isa;
- ide_pci_create_host_proc("via", via_get_info);
- via_proc = 1;
}
-#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
- return 0;
}
static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
{
+ struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev),
+ GFP_KERNEL);
+ struct pci_dev *isa = NULL;
int i;
+ if (vdev == NULL) {
+ printk(KERN_ERR "VP_IDE: out of memory :(\n");
+ return;
+ }
+
+ memset(vdev, 0, sizeof(struct via82cxxx_dev));
+ ide_set_hwifdata(hwif, vdev);
+
+ vdev->via_config = via_config_find(&isa);
+ via_cable_detect(hwif->pci_dev, vdev);
+
hwif->autodma = 0;
hwif->tuneproc = &via82cxxx_tune_drive;
@@ -594,7 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
for (i = 0; i < 2; i++) {
hwif->drives[i].io_32bit = 1;
- hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
+ hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
hwif->drives[i].autotune = 1;
hwif->drives[i].dn = hwif->channel * 2 + i;
}
@@ -608,7 +460,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->swdma_mask = 0x07;
if (!hwif->udma_four)
- hwif->udma_four = (via_80w >> hwif->channel) & 1;
+ hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1;
hwif->ide_dma_check = &via82cxxx_ide_dma_check;
if (!noautodma)
hwif->autodma = 1;
@@ -616,24 +468,35 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->drives[1].autodma = hwif->autodma;
}
-static ide_pci_device_t via82cxxx_chipset __devinitdata = {
- .name = "VP_IDE",
- .init_chipset = init_chipset_via82cxxx,
- .init_hwif = init_hwif_via82cxxx,
- .channels = 2,
- .autodma = NOAUTODMA,
- .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
- .bootable = ON_BOARD,
+static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "VP_IDE",
+ .init_chipset = init_chipset_via82cxxx,
+ .init_hwif = init_hwif_via82cxxx,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+ .bootable = ON_BOARD
+ },{ /* 1 */
+ .name = "VP_IDE",
+ .init_chipset = init_chipset_via82cxxx,
+ .init_hwif = init_hwif_via82cxxx,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+ .bootable = ON_BOARD,
+ }
};
static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- return ide_setup_pci_device(dev, &via82cxxx_chipset);
+ return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
}
static struct pci_device_id via_pci_tbl[] = {
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, via_pci_tbl);
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 136911a86e8..16b28357885 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1401,20 +1401,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
/* We probe the hwif now */
probe_hwif_init(hwif);
- /* The code IDE code will have set hwif->present if we have devices attached,
- * if we don't, the discard the interface except if we are on a media bay slot
- */
- if (!hwif->present && !pmif->mediabay) {
- printk(KERN_INFO "ide%d: Bus empty, interface released.\n",
- hwif->index);
- default_hwif_iops(hwif);
- for (i = IDE_DATA_OFFSET; i <= IDE_CONTROL_OFFSET; ++i)
- hwif->io_ports[i] = 0;
- hwif->chipset = ide_unknown;
- hwif->noprobe = 1;
- return -ENODEV;
- }
-
return 0;
}
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index d4f2111d436..7ebf992e8c2 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -787,7 +787,7 @@ static int pre_init = 1; /* Before first ordered IDE scan */
static LIST_HEAD(ide_pci_drivers);
/*
- * __ide_register_pci_driver - attach IDE driver
+ * __ide_pci_register_driver - attach IDE driver
* @driver: pci driver
* @module: owner module of the driver
*
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 5ea741f47fc..e73f81c2238 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -312,7 +312,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
int ret, length, hdr_len, copy_offset;
int rmpp_active = 0;
- if (count < sizeof (struct ib_user_mad))
+ if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)
return -EINVAL;
length = count - sizeof (struct ib_user_mad);
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 760c418d5bc..dd4e13303e9 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -730,15 +730,16 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
}
if (attr_mask & IB_QP_ACCESS_FLAGS) {
+ qp_context->params2 |=
+ cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
+ MTHCA_QP_BIT_RWE : 0);
+
/*
- * Only enable RDMA/atomics if we have responder
- * resources set to a non-zero value.
+ * Only enable RDMA reads and atomics if we have
+ * responder resources set to a non-zero value.
*/
if (qp->resp_depth) {
qp_context->params2 |=
- cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
- MTHCA_QP_BIT_RWE : 0);
- qp_context->params2 |=
cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?
MTHCA_QP_BIT_RRE : 0);
qp_context->params2 |=
@@ -759,31 +760,27 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
if (qp->resp_depth && !attr->max_dest_rd_atomic) {
/*
* Lowering our responder resources to zero.
- * Turn off RDMA/atomics as responder.
- * (RWE/RRE/RAE in params2 already zero)
+ * Turn off reads RDMA and atomics as responder.
+ * (RRE/RAE in params2 already zero)
*/
- qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
- MTHCA_QP_OPTPAR_RRE |
+ qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
MTHCA_QP_OPTPAR_RAE);
}
if (!qp->resp_depth && attr->max_dest_rd_atomic) {
/*
* Increasing our responder resources from
- * zero. Turn on RDMA/atomics as appropriate.
+ * zero. Turn on RDMA reads and atomics as
+ * appropriate.
*/
qp_context->params2 |=
- cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_WRITE ?
- MTHCA_QP_BIT_RWE : 0);
- qp_context->params2 |=
cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ?
MTHCA_QP_BIT_RRE : 0);
qp_context->params2 |=
cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ?
MTHCA_QP_BIT_RAE : 0);
- qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
- MTHCA_QP_OPTPAR_RRE |
+ qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
MTHCA_QP_OPTPAR_RAE);
}
@@ -921,10 +918,12 @@ static void mthca_adjust_qp_caps(struct mthca_dev *dev,
else
qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
- qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg);
- qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
- sizeof (struct mthca_next_seg)) /
- sizeof (struct mthca_data_seg);
+ qp->sq.max_gs = min_t(int, dev->limits.max_sg,
+ max_data_size / sizeof (struct mthca_data_seg));
+ qp->rq.max_gs = min_t(int, dev->limits.max_sg,
+ (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
+ sizeof (struct mthca_next_seg)) /
+ sizeof (struct mthca_data_seg));
}
/*
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 321a3a10e69..ee9fe226ae9 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -802,13 +802,21 @@ static int srp_post_recv(struct srp_target_port *target)
/*
* Must be called with target->scsi_host->host_lock held to protect
- * req_lim and tx_head.
+ * req_lim and tx_head. Lock cannot be dropped between call here and
+ * call to __srp_post_send().
*/
static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target)
{
if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
return NULL;
+ if (unlikely(target->req_lim < 1)) {
+ if (printk_ratelimit())
+ printk(KERN_DEBUG PFX "Target has req_lim %d\n",
+ target->req_lim);
+ return NULL;
+ }
+
return target->tx_ring[target->tx_head & SRP_SQ_SIZE];
}
@@ -823,11 +831,6 @@ static int __srp_post_send(struct srp_target_port *target,
struct ib_send_wr wr, *bad_wr;
int ret = 0;
- if (target->req_lim < 1) {
- printk(KERN_ERR PFX "Target has req_lim %d\n", target->req_lim);
- return -EAGAIN;
- }
-
list.addr = iu->dma;
list.length = len;
list.lkey = target->srp_host->mr->lkey;
@@ -1417,6 +1420,8 @@ static ssize_t srp_create_target(struct class_device *class_dev,
if (!target_host)
return -ENOMEM;
+ target_host->max_lun = SRP_MAX_LUN;
+
target = host_to_target(target_host);
memset(target, 0, sizeof *target);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index 4fec28a7136..b564f18caf7 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -54,6 +54,7 @@ enum {
SRP_PORT_REDIRECT = 1,
SRP_DLID_REDIRECT = 2,
+ SRP_MAX_LUN = 512,
SRP_MAX_IU_LEN = 256,
SRP_RQ_SHIFT = 6,
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 801c98f30e5..c82105920d7 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -110,7 +110,7 @@ config HISAX_16_3
config HISAX_TELESPCI
bool "Teles PCI"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the Teles PCI.
See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -238,7 +238,7 @@ config HISAX_MIC
config HISAX_NETJET
bool "NETjet card"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the NetJet from Traverse
Technologies.
@@ -249,7 +249,7 @@ config HISAX_NETJET
config HISAX_NETJET_U
bool "NETspider U card"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the Netspider U interface ISDN card
from Traverse Technologies.
@@ -317,7 +317,7 @@ config HISAX_GAZEL
config HISAX_HFC_PCI
bool "HFC PCI-Bus cards"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
@@ -344,14 +344,14 @@ config HISAX_HFC_SX
config HISAX_ENTERNOW_PCI
bool "Formula-n enter:now PCI card"
- depends on PCI && (BROKEN || !(SPARC64 || PPC))
+ depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
help
This enables HiSax support for the Formula-n enter:now PCI
ISDN card.
config HISAX_AMD7930
bool "Am7930 (EXPERIMENTAL)"
- depends on EXPERIMENTAL && (SPARC32 || SPARC64)
+ depends on EXPERIMENTAL && SPARC
help
This enables HiSax support for the AMD7930 chips on some SPARCs.
This code is not finished yet.
diff --git a/drivers/isdn/pcbit/Kconfig b/drivers/isdn/pcbit/Kconfig
index f06997faef1..0933881ab0c 100644
--- a/drivers/isdn/pcbit/Kconfig
+++ b/drivers/isdn/pcbit/Kconfig
@@ -3,7 +3,7 @@
#
config ISDN_DRV_PCBIT
tristate "PCBIT-D support"
- depends on ISDN_I4L && ISA && (BROKEN || !PPC)
+ depends on ISDN_I4L && ISA && (BROKEN || X86)
help
This enables support for the PCBIT ISDN-card. This card is
manufactured in Portugal by Octal. For running this card,
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c
index 35097c9bbf5..b8ccb0a9578 100644
--- a/drivers/mtd/maps/ipaq-flash.c
+++ b/drivers/mtd/maps/ipaq-flash.c
@@ -246,7 +246,7 @@ int __init ipaq_mtd_init(void)
ipaq_map[i].size = h3xxx_max_flash_size;
ipaq_map[i].set_vpp = h3xxx_set_vpp;
ipaq_map[i].phys = cs_phys[i];
- ipaq_map[i].virt = __ioremap(cs_phys[i], 0x04000000, 0, 1);
+ ipaq_map[i].virt = ioremap(cs_phys[i], 0x04000000);
if (machine_is_h3100 () || machine_is_h1900())
ipaq_map[i].bankwidth = 2;
}
@@ -280,7 +280,7 @@ int __init ipaq_mtd_init(void)
nb_parts = ARRAY_SIZE(jornada_partitions);
ipaq_map[0].size = jornada_max_flash_size;
ipaq_map[0].set_vpp = jornada56x_set_vpp;
- ipaq_map[0].virt = (__u32)__ioremap(0x0, 0x04000000, 0, 1);
+ ipaq_map[0].virt = (__u32)ioremap(0x0, 0x04000000);
}
#endif
#ifdef CONFIG_SA1100_JORNADA720
@@ -442,7 +442,7 @@ static int __init h1900_special_case(void)
ipaq_map[0].size = 0x80000;
ipaq_map[0].set_vpp = h3xxx_set_vpp;
ipaq_map[0].phys = 0x0;
- ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1);
+ ipaq_map[0].virt = ioremap(0x0, 0x04000000);
ipaq_map[0].bankwidth = 2;
printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index fc7a78e3173..2c9cc7f37e9 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -159,12 +159,12 @@ static int ixp2000_flash_probe(struct platform_device *dev)
return -ENODEV;
window_size = dev->resource->end - dev->resource->start + 1;
- dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
- ixp_data->nr_banks, ((u32)window_size >> 20));
+ dev_info(&dev->dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
+ ixp_data->nr_banks, ((u32)window_size >> 20));
if (plat->width != 1) {
- dev_err(_dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
- plat->width * 8);
+ dev_err(&dev->dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
+ plat->width * 8);
return -EIO;
}
@@ -202,7 +202,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
dev->resource->end - dev->resource->start + 1,
dev->dev.bus_id);
if (!info->res) {
- dev_err(_dev, "Could not reserve memory region\n");
+ dev_err(&dev->dev, "Could not reserve memory region\n");
err = -ENOMEM;
goto Error;
}
@@ -210,7 +210,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
dev->resource->end - dev->resource->start + 1);
if (!info->map.map_priv_1) {
- dev_err(_dev, "Failed to ioremap flash region\n");
+ dev_err(&dev->dev, "Failed to ioremap flash region\n");
err = -EIO;
goto Error;
}
@@ -221,13 +221,13 @@ static int ixp2000_flash_probe(struct platform_device *dev)
*/
erratum44_workaround = ixp2000_has_broken_slowport();
- dev_info(_dev, "Erratum 44 workaround %s\n",
+ dev_info(&dev->dev, "Erratum 44 workaround %s\n",
erratum44_workaround ? "enabled" : "disabled");
#endif
info->mtd = do_map_probe(plat->map_name, &info->map);
if (!info->mtd) {
- dev_err(_dev, "map_probe failed\n");
+ dev_err(&dev->dev, "map_probe failed\n");
err = -ENXIO;
goto Error;
}
@@ -237,7 +237,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
if (err > 0) {
err = add_mtd_partitions(info->mtd, info->partitions, err);
if(err)
- dev_err(_dev, "Could not parse partitions\n");
+ dev_err(&dev->dev, "Could not parse partitions\n");
}
if (err)
@@ -251,8 +251,8 @@ Error:
}
static struct platform_driver ixp2000_flash_driver = {
- .probe = &ixp2000_flash_probe,
- .remove = &ixp2000_flash_remove
+ .probe = ixp2000_flash_probe,
+ .remove = ixp2000_flash_remove,
.driver = {
.name = "IXP2000-Flash",
},
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
index 041e4b3358f..f68f7a99a63 100644
--- a/drivers/mtd/nand/h1910.c
+++ b/drivers/mtd/nand/h1910.c
@@ -112,7 +112,7 @@ static int __init h1910_init (void)
if (!machine_is_h1900())
return -ENODEV;
- nandaddr = __ioremap(0x08000000, 0x1000, 0, 1);
+ nandaddr = ioremap(0x08000000, 0x1000);
if (!nandaddr) {
printk("Failed to ioremap nand flash.\n");
return -ENOMEM;
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 332e9953c55..cd0b1dccfb6 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -32,6 +32,7 @@
*
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 7a6aeae2c9f..22cd0455670 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -156,7 +156,7 @@
#define DRV_NAME "e100"
#define DRV_EXT "-NAPI"
-#define DRV_VERSION "3.4.14-k2"DRV_EXT
+#define DRV_VERSION "3.4.14-k4"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation"
#define PFX DRV_NAME ": "
@@ -903,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
static void e100_get_defaults(struct nic *nic)
{
- struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
- struct param_range cbs = { .min = 64, .max = 256, .count = 64 };
+ struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
+ struct param_range cbs = { .min = 64, .max = 256, .count = 128 };
pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
@@ -1007,25 +1007,264 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
}
+/********************************************************/
+/* Micro code for 8086:1229 Rev 8 */
+/********************************************************/
+
+/* Parameter values for the D101M B-step */
+#define D101M_CPUSAVER_TIMER_DWORD 78
+#define D101M_CPUSAVER_BUNDLE_DWORD 65
+#define D101M_CPUSAVER_MIN_SIZE_DWORD 126
+
+#define D101M_B_RCVBUNDLE_UCODE \
+{\
+0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
+0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
+0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
+0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
+0x00380438, 0x00000000, 0x00140000, 0x00380555, \
+0x00308000, 0x00100662, 0x00100561, 0x000E0408, \
+0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
+0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
+0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
+0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
+0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
+0x00041000, 0x00010004, 0x00130826, 0x000C0006, \
+0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+0x00101210, 0x00380C34, 0x00000000, 0x00000000, \
+0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
+0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
+0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
+0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
+0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
+0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
+0x00130826, 0x000C0001, 0x00220559, 0x00101313, \
+0x00380559, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00130831, 0x0010090B, 0x00124813, \
+0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
+0x003806A8, 0x00000000, 0x00000000, 0x00000000, \
+}
+
+/********************************************************/
+/* Micro code for 8086:1229 Rev 9 */
+/********************************************************/
+
+/* Parameter values for the D101S */
+#define D101S_CPUSAVER_TIMER_DWORD 78
+#define D101S_CPUSAVER_BUNDLE_DWORD 67
+#define D101S_CPUSAVER_MIN_SIZE_DWORD 128
+
+#define D101S_RCVBUNDLE_UCODE \
+{\
+0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
+0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
+0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
+0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
+0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
+0x00308000, 0x00100610, 0x00100561, 0x000E0408, \
+0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
+0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
+0x003A047E, 0x00044010, 0x00380819, 0x00000000, \
+0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
+0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
+0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
+0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
+0x00101313, 0x00380700, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
+0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
+0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
+0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
+0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
+0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
+0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
+0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
+0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00130831, \
+0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
+0x00041000, 0x00010004, 0x00380700 \
+}
+
+/********************************************************/
+/* Micro code for the 8086:1229 Rev F/10 */
+/********************************************************/
+
+/* Parameter values for the D102 E-step */
+#define D102_E_CPUSAVER_TIMER_DWORD 42
+#define D102_E_CPUSAVER_BUNDLE_DWORD 54
+#define D102_E_CPUSAVER_MIN_SIZE_DWORD 46
+
+#define D102_E_RCVBUNDLE_UCODE \
+{\
+0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \
+0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
+0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
+0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
+0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
+0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \
+0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+}
+
static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
{
- int i;
- static const u32 ucode[UCODE_SIZE] = {
- /* NFS packets are misinterpreted as TCO packets and
- * incorrectly routed to the BMC over SMBus. This
- * microcode patch checks the fragmented IP bit in the
- * NFS/UDP header to distinguish between NFS and TCO. */
- 0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
- 0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
- 0x00906EFD, 0x00900EFD, 0x00E00EF8,
- };
-
- if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
- for(i = 0; i < UCODE_SIZE; i++)
+/* *INDENT-OFF* */
+ static struct {
+ u32 ucode[UCODE_SIZE + 1];
+ u8 mac;
+ u8 timer_dword;
+ u8 bundle_dword;
+ u8 min_size_dword;
+ } ucode_opts[] = {
+ { D101M_B_RCVBUNDLE_UCODE,
+ mac_82559_D101M,
+ D101M_CPUSAVER_TIMER_DWORD,
+ D101M_CPUSAVER_BUNDLE_DWORD,
+ D101M_CPUSAVER_MIN_SIZE_DWORD },
+ { D101S_RCVBUNDLE_UCODE,
+ mac_82559_D101S,
+ D101S_CPUSAVER_TIMER_DWORD,
+ D101S_CPUSAVER_BUNDLE_DWORD,
+ D101S_CPUSAVER_MIN_SIZE_DWORD },
+ { D102_E_RCVBUNDLE_UCODE,
+ mac_82551_F,
+ D102_E_CPUSAVER_TIMER_DWORD,
+ D102_E_CPUSAVER_BUNDLE_DWORD,
+ D102_E_CPUSAVER_MIN_SIZE_DWORD },
+ { D102_E_RCVBUNDLE_UCODE,
+ mac_82551_10,
+ D102_E_CPUSAVER_TIMER_DWORD,
+ D102_E_CPUSAVER_BUNDLE_DWORD,
+ D102_E_CPUSAVER_MIN_SIZE_DWORD },
+ { {0}, 0, 0, 0, 0}
+ }, *opts;
+/* *INDENT-ON* */
+
+/*************************************************************************
+* CPUSaver parameters
+*
+* All CPUSaver parameters are 16-bit literals that are part of a
+* "move immediate value" instruction. By changing the value of
+* the literal in the instruction before the code is loaded, the
+* driver can change the algorithm.
+*
+* INTDELAY - This loads the dead-man timer with its inital value.
+* When this timer expires the interrupt is asserted, and the
+* timer is reset each time a new packet is received. (see
+* BUNDLEMAX below to set the limit on number of chained packets)
+* The current default is 0x600 or 1536. Experiments show that
+* the value should probably stay within the 0x200 - 0x1000.
+*
+* BUNDLEMAX -
+* This sets the maximum number of frames that will be bundled. In
+* some situations, such as the TCP windowing algorithm, it may be
+* better to limit the growth of the bundle size than let it go as
+* high as it can, because that could cause too much added latency.
+* The default is six, because this is the number of packets in the
+* default TCP window size. A value of 1 would make CPUSaver indicate
+* an interrupt for every frame received. If you do not want to put
+* a limit on the bundle size, set this value to xFFFF.
+*
+* BUNDLESMALL -
+* This contains a bit-mask describing the minimum size frame that
+* will be bundled. The default masks the lower 7 bits, which means
+* that any frame less than 128 bytes in length will not be bundled,
+* but will instead immediately generate an interrupt. This does
+* not affect the current bundle in any way. Any frame that is 128
+* bytes or large will be bundled normally. This feature is meant
+* to provide immediate indication of ACK frames in a TCP environment.
+* Customers were seeing poor performance when a machine with CPUSaver
+* enabled was sending but not receiving. The delay introduced when
+* the ACKs were received was enough to reduce total throughput, because
+* the sender would sit idle until the ACK was finally seen.
+*
+* The current default is 0xFF80, which masks out the lower 7 bits.
+* This means that any frame which is x7F (127) bytes or smaller
+* will cause an immediate interrupt. Because this value must be a
+* bit mask, there are only a few valid values that can be used. To
+* turn this feature off, the driver can write the value xFFFF to the
+* lower word of this instruction (in the same way that the other
+* parameters are used). Likewise, a value of 0xF800 (2047) would
+* cause an interrupt to be generated for every frame, because all
+* standard Ethernet frames are <= 2047 bytes in length.
+*************************************************************************/
+
+/* if you wish to disable the ucode functionality, while maintaining the
+ * workarounds it provides, set the following defines to:
+ * BUNDLESMALL 0
+ * BUNDLEMAX 1
+ * INTDELAY 1
+ */
+#define BUNDLESMALL 1
+#define BUNDLEMAX (u16)6
+#define INTDELAY (u16)1536 /* 0x600 */
+
+ /* do not load u-code for ICH devices */
+ if (nic->flags & ich)
+ goto noloaducode;
+
+ /* Search for ucode match against h/w rev_id */
+ for (opts = ucode_opts; opts->mac; opts++) {
+ int i;
+ u32 *ucode = opts->ucode;
+ if (nic->mac != opts->mac)
+ continue;
+
+ /* Insert user-tunable settings */
+ ucode[opts->timer_dword] &= 0xFFFF0000;
+ ucode[opts->timer_dword] |= INTDELAY;
+ ucode[opts->bundle_dword] &= 0xFFFF0000;
+ ucode[opts->bundle_dword] |= BUNDLEMAX;
+ ucode[opts->min_size_dword] &= 0xFFFF0000;
+ ucode[opts->min_size_dword] |= (BUNDLESMALL) ? 0xFFFF : 0xFF80;
+
+ for (i = 0; i < UCODE_SIZE; i++)
cb->u.ucode[i] = cpu_to_le32(ucode[i]);
cb->command = cpu_to_le16(cb_ucode);
- } else
- cb->command = cpu_to_le16(cb_nop);
+ return;
+ }
+
+noloaducode:
+ cb->command = cpu_to_le16(cb_nop);
}
static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index 94e7a9af870..a84c232395e 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -1,6 +1,6 @@
config FEC_8XX
tristate "Motorola 8xx FEC driver"
- depends on NET_ETHERNET && FEC
+ depends on NET_ETHERNET && 8xx
select MII
config FEC_8XX_GENERIC_PHY
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 6a3129bc15a..9b8295ee06e 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1360,7 +1360,7 @@ static struct pci_driver ioc3_driver = {
static int __init ioc3_init_module(void)
{
- return pci_module_init(&ioc3_driver);
+ return pci_register_driver(&ioc3_driver);
}
static void __exit ioc3_cleanup_module(void)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 159b56a56ef..14a76f7cf90 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1346,10 +1346,8 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
} else {
if (netif_msg_probe(tp)) {
printk(KERN_ERR PFX
- "Cannot find PowerManagement capability. "
- "Aborting.\n");
+ "PowerManagement capability not found.\n");
}
- goto err_out_mwi;
}
/* make sure PCI base addr 1 is MMIO */
@@ -2516,7 +2514,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
} while (boguscnt > 0);
if (boguscnt <= 0) {
- if (net_ratelimit() && netif_msg_intr(tp)) {
+ if (netif_msg_intr(tp) && net_ratelimit() ) {
printk(KERN_WARNING
"%s: Too much work at interrupt!\n", dev->name);
}
diff --git a/drivers/net/saa9730.h b/drivers/net/saa9730.h
index 9e9da6b4080..a7e9d29a86a 100644
--- a/drivers/net/saa9730.h
+++ b/drivers/net/saa9730.h
@@ -1,6 +1,7 @@
/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 2000, 2005 MIPS Technologies, Inc. All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
*
* ########################################################################
*
@@ -265,6 +266,7 @@
/* The SAA9730 (LAN) controller register map, as seen via the PCI-bus. */
#define SAA9730_LAN_REGS_ADDR 0x20400
+#define SAA9730_LAN_REGS_SIZE 0x00400
struct lan_saa9730_regmap {
volatile unsigned int TxBuffA; /* 0x20400 */
@@ -309,6 +311,7 @@ typedef volatile struct lan_saa9730_regmap t_lan_saa9730_regmap;
/* The SAA9730 (EVM) controller register map, as seen via the PCI-bus. */
#define SAA9730_EVM_REGS_ADDR 0x02000
+#define SAA9730_EVM_REGS_SIZE 0x00400
struct evm_saa9730_regmap {
volatile unsigned int InterruptStatus1; /* 0x2000 */
@@ -329,16 +332,32 @@ typedef volatile struct evm_saa9730_regmap t_evm_saa9730_regmap;
struct lan_saa9730_private {
+ /*
+ * Rx/Tx packet buffers.
+ * The Rx and Tx packets must be PACKET_SIZE aligned.
+ */
+ void *buffer_start;
+ unsigned int buffer_size;
+
+ /*
+ * DMA address of beginning of this object, returned
+ * by pci_alloc_consistent().
+ */
+ dma_addr_t dma_addr;
+
+ /* Pointer to the associated pci device structure */
+ struct pci_dev *pci_dev;
+
/* Pointer for the SAA9730 LAN controller register set. */
t_lan_saa9730_regmap *lan_saa9730_regs;
/* Pointer to the SAA9730 EVM register. */
t_evm_saa9730_regmap *evm_saa9730_regs;
- /* TRUE if the next buffer to write is RxBuffA, FALSE if RxBuffB. */
- unsigned char NextRcvToUseIsA;
/* Rcv buffer Index. */
unsigned char NextRcvPacketIndex;
+ /* Next buffer index. */
+ unsigned char NextRcvBufferIndex;
/* Index of next packet to use in that buffer. */
unsigned char NextTxmPacketIndex;
@@ -353,13 +372,8 @@ struct lan_saa9730_private {
unsigned char DmaRcvPackets;
unsigned char DmaTxmPackets;
- unsigned char RcvAIndex; /* index into RcvBufferSpace[] for Blk A */
- unsigned char RcvBIndex; /* index into RcvBufferSpace[] for Blk B */
-
- unsigned int
- TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
- unsigned int
- RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
+ void *TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
+ void *RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index c91e2e81f13..28bf2e69eb5 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -155,6 +155,12 @@ MODULE_LICENSE("GPL");
#define MEMORY_WAIT_TIME 16
/*
+ * The maximum number of processing loops allowed for each call to the
+ * IRQ handler.
+ */
+#define MAX_IRQ_LOOPS 8
+
+/*
* This selects whether TX packets are sent one by one to the SMC91x internal
* memory and throttled until transmission completes. This may prevent
* RX overruns a litle by keeping much of the memory free for RX packets
@@ -684,7 +690,6 @@ static void smc_hardware_send_pkt(unsigned long data)
/* queue the packet for TX */
SMC_SET_MMU_CMD(MC_ENQUEUE);
- SMC_ACK_INT(IM_TX_EMPTY_INT);
smc_special_unlock(&lp->lock);
dev->trans_start = jiffies;
@@ -1207,6 +1212,7 @@ static void smc_phy_configure(void *data)
smc_phy_check_media(dev, 1);
smc_phy_configure_exit:
+ SMC_SELECT_BANK(2);
spin_unlock_irq(&lp->lock);
lp->work_pending = 0;
}
@@ -1305,7 +1311,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
SMC_SET_INT_MASK(0);
/* set a timeout value, so I don't stay here forever */
- timeout = 8;
+ timeout = MAX_IRQ_LOOPS;
do {
status = SMC_GET_INT();
@@ -1372,10 +1378,13 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* restore register states */
SMC_SET_PTR(saved_pointer);
SMC_SET_INT_MASK(mask);
-
spin_unlock(&lp->lock);
- DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
+ if (timeout == MAX_IRQ_LOOPS)
+ PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
+ dev->name, mask);
+ DBG(3, "%s: Interrupt done (%d loops)\n",
+ dev->name, MAX_IRQ_LOOPS - timeout);
/*
* We return IRQ_HANDLED unconditionally here even if there was
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index a01efa6d5c6..1fd04662c4f 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -192,7 +192,9 @@ static int cisco_rx(struct sk_buff *skb)
"uptime %ud%uh%um%us)\n",
dev->name, days, hrs,
min, sec);
+#if 0
netif_carrier_on(dev);
+#endif
hdlc->state.cisco.up = 1;
}
}
@@ -225,7 +227,9 @@ static void cisco_timer(unsigned long arg)
hdlc->state.cisco.settings.timeout * HZ)) {
hdlc->state.cisco.up = 0;
printk(KERN_INFO "%s: Link down\n", dev->name);
+#if 0
netif_carrier_off(dev);
+#endif
}
cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
@@ -261,8 +265,10 @@ static void cisco_stop(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
del_timer_sync(&hdlc->state.cisco.timer);
+#if 0
if (netif_carrier_ok(dev))
netif_carrier_off(dev);
+#endif
hdlc->state.cisco.up = 0;
hdlc->state.cisco.request_sent = 0;
}
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index e1601d35dce..523afe17564 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -545,8 +545,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
hdlc->state.fr.reliable = reliable;
if (reliable) {
+#if 0
if (!netif_carrier_ok(dev))
netif_carrier_on(dev);
+#endif
hdlc->state.fr.n391cnt = 0; /* Request full status */
hdlc->state.fr.dce_changed = 1;
@@ -560,8 +562,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
}
}
} else {
+#if 0
if (netif_carrier_ok(dev))
netif_carrier_off(dev);
+#endif
while (pvc) { /* Deactivate all PVCs */
pvc_carrier(0, pvc);
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c
index cdd4c09c2d9..46cef8f9213 100644
--- a/drivers/net/wan/hdlc_generic.c
+++ b/drivers/net/wan/hdlc_generic.c
@@ -79,11 +79,13 @@ static void __hdlc_set_carrier_on(struct net_device *dev)
hdlc_device *hdlc = dev_to_hdlc(dev);
if (hdlc->proto.start)
return hdlc->proto.start(dev);
+#if 0
#ifdef DEBUG_LINK
if (netif_carrier_ok(dev))
printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
#endif
netif_carrier_on(dev);
+#endif
}
@@ -94,11 +96,13 @@ static void __hdlc_set_carrier_off(struct net_device *dev)
if (hdlc->proto.stop)
return hdlc->proto.stop(dev);
+#if 0
#ifdef DEBUG_LINK
if (!netif_carrier_ok(dev))
printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
#endif
netif_carrier_off(dev);
+#endif
}
@@ -294,8 +298,10 @@ int register_hdlc_device(struct net_device *dev)
if (result != 0)
return -EIO;
+#if 0
if (netif_carrier_ok(dev))
netif_carrier_off(dev); /* no carrier until DCD goes up */
+#endif
return 0;
}
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index 579480dad37..346c6febb03 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -398,7 +398,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
*
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
u16 id, u16 offset)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -424,7 +424,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
*
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
u16 id, u16 offset)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -450,7 +450,7 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
*
* Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
*/
-int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, unsigned len,
+int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, int len,
u16 id, u16 offset)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index a6bd472d75d..7644f72a9f4 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -372,12 +372,12 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
struct hermes_response *resp);
int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
u16 id, u16 offset);
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
u16 id, u16 offset);
int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf,
- unsigned data_len, unsigned len, u16 id, u16 offset);
+ unsigned data_len, int len, u16 id, u16 offset);
int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
u16 *length, void *buf);
int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
diff --git a/drivers/net/wireless/i82593.h b/drivers/net/wireless/i82593.h
index 33acb8add4d..afac5c7a323 100644
--- a/drivers/net/wireless/i82593.h
+++ b/drivers/net/wireless/i82593.h
@@ -7,11 +7,16 @@
*
* Copyright 1994, Anders Klemets <klemets@it.kth.se>
*
- * This software may be freely distributed for noncommercial purposes
- * as long as this notice is retained.
- *
* HISTORY
* i82593.h,v
+ * Revision 1.4 2005/11/4 09:15:00 baroniunas
+ * Modified copyright with permission of author as follows:
+ *
+ * "If I82539.H is the only file with my copyright statement
+ * that is included in the Source Forge project, then you have
+ * my approval to change the copyright statement to be a GPL
+ * license, in the way you proposed on October 10."
+ *
* Revision 1.1 1996/07/17 15:23:12 root
* Initial revision
*
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index a2e6214169e..77d2a21d4cd 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -6344,7 +6344,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
dev->ethtool_ops = &ipw2100_ethtool_ops;
dev->tx_timeout = ipw2100_tx_timeout;
dev->wireless_handlers = &ipw2100_wx_handler_def;
- dev->get_wireless_stats = ipw2100_wx_wireless_stats;
+ priv->wireless_data.ieee80211 = priv->ieee;
+ dev->wireless_data = &priv->wireless_data;
dev->set_mac_address = ipw2100_set_address;
dev->watchdog_timeo = 3 * HZ;
dev->irq = 0;
@@ -7178,6 +7179,11 @@ static int ipw2100_wx_get_range(struct net_device *dev,
}
range->num_frequency = val;
+ /* Event capability (kernel + driver) */
+ range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+ IW_EVENT_CAPA_MASK(SIOCGIWAP));
+ range->event_capa[1] = IW_EVENT_CAPA_K_1;
+
IPW_DEBUG_WX("GET Range\n");
return 0;
@@ -8446,16 +8452,6 @@ static iw_handler ipw2100_private_handler[] = {
#endif /* CONFIG_IPW2100_MONITOR */
};
-static struct iw_handler_def ipw2100_wx_handler_def = {
- .standard = ipw2100_wx_handlers,
- .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
- .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
- .num_private_args = sizeof(ipw2100_private_args) /
- sizeof(struct iw_priv_args),
- .private = (iw_handler *) ipw2100_private_handler,
- .private_args = (struct iw_priv_args *)ipw2100_private_args,
-};
-
/*
* Get wireless statistics.
* Called by /proc/net/wireless
@@ -8597,6 +8593,17 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
return (struct iw_statistics *)NULL;
}
+static struct iw_handler_def ipw2100_wx_handler_def = {
+ .standard = ipw2100_wx_handlers,
+ .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
+ .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
+ .num_private_args = sizeof(ipw2100_private_args) /
+ sizeof(struct iw_priv_args),
+ .private = (iw_handler *) ipw2100_private_handler,
+ .private_args = (struct iw_priv_args *)ipw2100_private_args,
+ .get_wireless_stats = ipw2100_wx_wireless_stats,
+};
+
static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
{
union iwreq_data wrqu;
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 140fdf2a0a0..7c65b10bb16 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -571,6 +571,8 @@ struct ipw2100_priv {
struct net_device *net_dev;
struct iw_statistics wstats;
+ struct iw_public_data wireless_data;
+
struct tasklet_struct irq_tasklet;
struct workqueue_struct *workqueue;
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 109a96d9000..23deee69974 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -164,12 +164,12 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
/* assert the Wakeup interrupt in the Device Interrupt Register */
isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_WAKEUP,
ISL38XX_DEV_INT_REG);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
udelay(ISL38XX_WRITEIO_DELAY);
/* perform another read on the Device Status Register */
reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
do_gettimeofday(&current_time);
DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
current_time.tv_sec, (long)current_time.tv_usec, reg);
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index a39fbfef789..19657efa8dc 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -700,6 +700,28 @@ static unsigned int iosapic_startup_irq(unsigned int irq)
return 0;
}
+#ifdef CONFIG_SMP
+static void iosapic_set_affinity_irq(unsigned int irq, cpumask_t dest)
+{
+ struct vector_info *vi = iosapic_get_vector(irq);
+ u32 d0, d1, dummy_d0;
+ unsigned long flags;
+
+ if (cpu_check_affinity(irq, &dest))
+ return;
+
+ vi->txn_addr = txn_affinity_addr(irq, first_cpu(dest));
+
+ spin_lock_irqsave(&iosapic_lock, flags);
+ /* d1 contains the destination CPU, so only want to set that
+ * entry */
+ iosapic_rd_irt_entry(vi, &d0, &d1);
+ iosapic_set_irt_data(vi, &dummy_d0, &d1);
+ iosapic_wr_irt_entry(vi, d0, d1);
+ spin_unlock_irqrestore(&iosapic_lock, flags);
+}
+#endif
+
static struct hw_interrupt_type iosapic_interrupt_type = {
.typename = "IO-SAPIC-level",
.startup = iosapic_startup_irq,
@@ -708,7 +730,9 @@ static struct hw_interrupt_type iosapic_interrupt_type = {
.disable = iosapic_disable_irq,
.ack = no_ack_irq,
.end = iosapic_end_irq,
-// .set_affinity = iosapic_set_affinity_irq,
+#ifdef CONFIG_SMP
+ .set_affinity = iosapic_set_affinity_irq,
+#endif
};
int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index bab3bcabcb6..d14888e149b 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -24,6 +24,9 @@
* Major changes to get basic interrupt infrastructure working to
* hopefully be able to support all SuperIO devices. Currently
* works with serial. -- John Marvin <jsm@fc.hp.com>
+ *
+ * Converted superio_init() to be a PCI_FIXUP_FINAL callee.
+ * -- Kyle McMartin <kyle@parisc-linux.org>
*/
@@ -141,10 +144,10 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
}
/* Initialize Super I/O device */
-
-static void __devinit
-superio_init(struct superio_device *sio)
+static void
+superio_init(struct pci_dev *pcidev)
{
+ struct superio_device *sio = &sio_dev;
struct pci_dev *pdev = sio->lio_pdev;
u16 word;
@@ -160,8 +163,8 @@ superio_init(struct superio_device *sio)
/* ...then properly fixup the USB to point at suckyio PIC */
sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
- printk (KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
- pci_name(pdev),pdev->irq);
+ printk(KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
+ pci_name(pdev), pdev->irq);
pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
sio->sp1_base &= ~1;
@@ -274,7 +277,7 @@ superio_init(struct superio_device *sio)
sio->suckyio_irq_enabled = 1;
}
-
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init);
static void superio_disable_irq(unsigned int irq)
{
@@ -452,8 +455,10 @@ static void superio_fixup_pci(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci);
-static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int __devinit
+superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
+ struct superio_device *sio = &sio_dev;
/*
** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a
@@ -466,7 +471,8 @@ static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_
dev->subsystem_vendor, dev->subsystem_device,
dev->class);
- superio_init(&sio_dev);
+ if (!sio->suckyio_irq_enabled)
+ BUG(); /* Enabled by PCI_FIXUP_FINAL */
if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) { /* Function 1 */
superio_parport_init();
@@ -481,19 +487,21 @@ static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_
DBG_INIT("superio_probe: WTF? Fire Extinguisher?\n");
}
- /* Let appropriate other driver claim this device. */
+ /* Let appropriate other driver claim this device. */
return -ENODEV;
}
static struct pci_device_id superio_tbl[] = {
- { PCI_VENDOR_ID_NS, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) },
{ 0, }
};
static struct pci_driver superio_driver = {
- .name = "SuperIO",
- .id_table = superio_tbl,
- .probe = superio_probe,
+ .name = "SuperIO",
+ .id_table = superio_tbl,
+ .probe = superio_probe,
};
static int __init superio_modinit(void)
@@ -506,6 +514,5 @@ static void __exit superio_exit(void)
pci_unregister_driver(&superio_driver);
}
-
module_init(superio_modinit);
module_exit(superio_exit);
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index e1960d69fb9..4cb1f3ed910 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -784,8 +784,8 @@ static ide_proc_entry_t idescsi_proc[] = {
#endif
static ide_driver_t idescsi_driver = {
- .owner = THIS_MODULE,
.gen_driver = {
+ .owner = THIS_MODULE,
.name = "ide-scsi",
.bus = &ide_bus_type,
.probe = ide_scsi_probe,
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index ac184e60797..ab7432a5778 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -2,6 +2,7 @@
* sata_mv.c - Marvell SATA support
*
* Copyright 2005: EMC Corporation, all rights reserved.
+ * Copyright 2005 Red Hat, Inc. All rights reserved.
*
* Please ALWAYS copy linux-ide@vger.kernel.org on emails.
*
@@ -36,7 +37,7 @@
#include <asm/io.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "0.25"
+#define DRV_VERSION "0.5"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index cb1933a3bd5..e0d6f194f54 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -5,17 +5,6 @@
*
* Based on preview driver from Silicon Image.
*
- * NOTE: No NCQ/ATAPI support yet. The preview driver didn't support
- * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
- * those work. Enabling those shouldn't be difficult. Basic
- * structure is all there (in libata-dev tree). If you have any
- * information about this hardware, please contact me or linux-ide.
- * Info is needed on...
- *
- * - How to issue tagged commands and turn on sactive on issue accordingly.
- * - Where to put an ATAPI command and how to tell the device to send it.
- * - How to enable/use 64bit.
- *
* 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, or (at your option) any
@@ -42,7 +31,7 @@
#include <asm/io.h>
#define DRV_NAME "sata_sil24"
-#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */
+#define DRV_VERSION "0.23"
/*
* Port request block (PRB) 32 bytes
@@ -221,11 +210,22 @@ enum {
IRQ_STAT_4PORTS = 0xf,
};
-struct sil24_cmd_block {
+struct sil24_ata_block {
struct sil24_prb prb;
struct sil24_sge sge[LIBATA_MAX_PRD];
};
+struct sil24_atapi_block {
+ struct sil24_prb prb;
+ u8 cdb[16];
+ struct sil24_sge sge[LIBATA_MAX_PRD - 1];
+};
+
+union sil24_cmd_block {
+ struct sil24_ata_block ata;
+ struct sil24_atapi_block atapi;
+};
+
/*
* ap->private_data
*
@@ -233,7 +233,7 @@ struct sil24_cmd_block {
* here from the previous interrupt.
*/
struct sil24_port_priv {
- struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */
+ union sil24_cmd_block *cmd_block; /* 32 cmd blocks */
dma_addr_t cmd_block_dma; /* DMA base addr for them */
struct ata_taskfile tf; /* Cached taskfile registers */
};
@@ -244,6 +244,7 @@ struct sil24_host_priv {
void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */
};
+static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev);
static u8 sil24_check_status(struct ata_port *ap);
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
@@ -297,6 +298,8 @@ static struct scsi_host_template sil24_sht = {
static const struct ata_port_operations sil24_ops = {
.port_disable = ata_port_disable,
+ .dev_config = sil24_dev_config,
+
.check_status = sil24_check_status,
.check_altstatus = sil24_check_status,
.dev_select = ata_noop_dev_select,
@@ -333,7 +336,7 @@ static struct ata_port_info sil24_port_info[] = {
{
.sht = &sil24_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_SRST | ATA_FLAG_MMIO |
ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -344,7 +347,7 @@ static struct ata_port_info sil24_port_info[] = {
{
.sht = &sil24_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_SRST | ATA_FLAG_MMIO |
ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -355,7 +358,7 @@ static struct ata_port_info sil24_port_info[] = {
{
.sht = &sil24_sht,
.host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+ ATA_FLAG_SRST | ATA_FLAG_MMIO |
ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -364,6 +367,16 @@ static struct ata_port_info sil24_port_info[] = {
},
};
+static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
+{
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+
+ if (ap->cdb_len == 16)
+ writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
+ else
+ writel(PORT_CS_CDB16, port + PORT_CTRL_CLR);
+}
+
static inline void sil24_update_tf(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
@@ -415,22 +428,73 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
*tf = pp->tf;
}
-static void sil24_phy_reset(struct ata_port *ap)
+static int sil24_issue_SRST(struct ata_port *ap)
{
- __sata_phy_reset(ap);
+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ struct sil24_port_priv *pp = ap->private_data;
+ struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
+ dma_addr_t paddr = pp->cmd_block_dma;
+ u32 irq_enable, irq_stat;
+ int cnt;
+
+ /* temporarily turn off IRQs during SRST */
+ irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
+ writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);
+
/*
- * No ATAPI yet. Just unconditionally indicate ATA device.
- * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA
- * and libata core will ignore the device.
+ * XXX: Not sure whether the following sleep is needed or not.
+ * The original driver had it. So....
*/
- if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
- ap->device[0].class = ATA_DEV_ATA;
+ msleep(10);
+
+ prb->ctrl = PRB_CTRL_SRST;
+ prb->fis[1] = 0; /* no PM yet */
+
+ writel((u32)paddr, port + PORT_CMD_ACTIVATE);
+
+ for (cnt = 0; cnt < 100; cnt++) {
+ irq_stat = readl(port + PORT_IRQ_STAT);
+ writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
+
+ irq_stat >>= PORT_IRQ_RAW_SHIFT;
+ if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR))
+ break;
+
+ msleep(1);
+ }
+
+ /* restore IRQs */
+ writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
+
+ if (!(irq_stat & PORT_IRQ_COMPLETE))
+ return -1;
+
+ /* update TF */
+ sil24_update_tf(ap);
+ return 0;
+}
+
+static void sil24_phy_reset(struct ata_port *ap)
+{
+ struct sil24_port_priv *pp = ap->private_data;
+
+ __sata_phy_reset(ap);
+ if (ap->flags & ATA_FLAG_PORT_DISABLED)
+ return;
+
+ if (sil24_issue_SRST(ap) < 0) {
+ printk(KERN_ERR DRV_NAME
+ " ata%u: SRST failed, disabling port\n", ap->id);
+ ap->ops->port_disable(ap);
+ return;
+ }
+
+ ap->device->class = ata_dev_classify(&pp->tf);
}
static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
- struct sil24_cmd_block *cb)
+ struct sil24_sge *sge)
{
- struct sil24_sge *sge = cb->sge;
struct scatterlist *sg;
unsigned int idx = 0;
@@ -451,23 +515,47 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct sil24_port_priv *pp = ap->private_data;
- struct sil24_cmd_block *cb = pp->cmd_block + qc->tag;
- struct sil24_prb *prb = &cb->prb;
+ union sil24_cmd_block *cb = pp->cmd_block + qc->tag;
+ struct sil24_prb *prb;
+ struct sil24_sge *sge;
switch (qc->tf.protocol) {
case ATA_PROT_PIO:
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
+ prb = &cb->ata.prb;
+ sge = cb->ata.sge;
+ prb->ctrl = 0;
+ break;
+
+ case ATA_PROT_ATAPI:
+ case ATA_PROT_ATAPI_DMA:
+ case ATA_PROT_ATAPI_NODATA:
+ prb = &cb->atapi.prb;
+ sge = cb->atapi.sge;
+ memset(cb->atapi.cdb, 0, 32);
+ memcpy(cb->atapi.cdb, qc->cdb, ap->cdb_len);
+
+ if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {
+ if (qc->tf.flags & ATA_TFLAG_WRITE)
+ prb->ctrl = PRB_CTRL_PACKET_WRITE;
+ else
+ prb->ctrl = PRB_CTRL_PACKET_READ;
+ } else
+ prb->ctrl = 0;
+
break;
+
default:
- /* ATAPI isn't supported yet */
+ prb = NULL; /* shut up, gcc */
+ sge = NULL;
BUG();
}
ata_tf_to_fis(&qc->tf, prb->fis, 0);
if (qc->flags & ATA_QCFLAG_DMAMAP)
- sil24_fill_sg(qc, cb);
+ sil24_fill_sg(qc, sge);
}
static int sil24_qc_issue(struct ata_queued_cmd *qc)
@@ -486,6 +574,31 @@ static void sil24_irq_clear(struct ata_port *ap)
/* unused */
}
+static int __sil24_restart_controller(void __iomem *port)
+{
+ u32 tmp;
+ int cnt;
+
+ writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
+
+ /* Max ~10ms */
+ for (cnt = 0; cnt < 10000; cnt++) {
+ tmp = readl(port + PORT_CTRL_STAT);
+ if (tmp & PORT_CS_RDY)
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+static void sil24_restart_controller(struct ata_port *ap)
+{
+ if (__sil24_restart_controller((void __iomem *)ap->ioaddr.cmd_addr))
+ printk(KERN_ERR DRV_NAME
+ " ata%u: failed to restart controller\n", ap->id);
+}
+
static int __sil24_reset_controller(void __iomem *port)
{
int cnt;
@@ -505,7 +618,11 @@ static int __sil24_reset_controller(void __iomem *port)
if (tmp & PORT_CS_DEV_RST)
return -1;
- return 0;
+
+ if (tmp & PORT_CS_RDY)
+ return 0;
+
+ return __sil24_restart_controller(port);
}
static void sil24_reset_controller(struct ata_port *ap)
@@ -567,9 +684,15 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
if (serror)
writel(serror, port + PORT_SERROR);
- printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n"
- " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
- ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
+ /*
+ * Don't log ATAPI device errors. They're supposed to happen
+ * and any serious errors will be logged using sense data by
+ * the SCSI layer.
+ */
+ if (ap->device[0].class != ATA_DEV_ATAPI || cmd_err > PORT_CERR_SDB)
+ printk("ata%u: error interrupt on port%d\n"
+ " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
+ ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
/*
@@ -577,6 +700,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
*/
sil24_update_tf(ap);
err_mask = ac_err_mask(pp->tf.command);
+ sil24_restart_controller(ap);
} else {
/*
* Other errors. libata currently doesn't have any
@@ -584,12 +708,11 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
* ATA_ERR.
*/
err_mask = AC_ERR_OTHER;
+ sil24_reset_controller(ap);
}
if (qc)
ata_qc_complete(qc, err_mask);
-
- sil24_reset_controller(ap);
}
static inline void sil24_host_intr(struct ata_port *ap)
@@ -665,7 +788,7 @@ static int sil24_port_start(struct ata_port *ap)
{
struct device *dev = ap->host_set->dev;
struct sil24_port_priv *pp;
- struct sil24_cmd_block *cb;
+ union sil24_cmd_block *cb;
size_t cb_size = sizeof(*cb);
dma_addr_t cb_dma;
int rc = -ENOMEM;
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index ff36f0c9fda..ad47c1b84c3 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -507,7 +507,7 @@ config SERIAL_SUNSU_CONSOLE
config SERIAL_MUX
tristate "Serial MUX support"
- depends on PARISC
+ depends on GSC
select SERIAL_CORE
default y
---help---
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 938d185841c..89d7bd3eaee 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -49,7 +49,6 @@
#include <linux/serial.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/sizes.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/clock.h>
@@ -63,7 +62,8 @@
#define AMBA_ISR_PASS_LIMIT 256
-#define UART_DUMMY_RSR_RX 256
+#define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
+#define UART_DUMMY_DR_RX (1 << 16)
/*
* We wrap our port structure around the generic uart_port.
@@ -116,7 +116,7 @@ pl011_rx_chars(struct uart_amba_port *uap)
#endif
{
struct tty_struct *tty = uap->port.info->tty;
- unsigned int status, ch, flag, rsr, max_count = 256;
+ unsigned int status, ch, flag, max_count = 256;
status = readw(uap->port.membase + UART01x_FR);
while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
@@ -129,7 +129,7 @@ pl011_rx_chars(struct uart_amba_port *uap)
*/
}
- ch = readw(uap->port.membase + UART01x_DR);
+ ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
flag = TTY_NORMAL;
uap->port.icount.rx++;
@@ -137,34 +137,33 @@ pl011_rx_chars(struct uart_amba_port *uap)
* Note that the error handling code is
* out of the main execution path
*/
- rsr = readw(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
- if (unlikely(rsr & UART01x_RSR_ANY)) {
- if (rsr & UART01x_RSR_BE) {
- rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
+ if (unlikely(ch & UART_DR_ERROR)) {
+ if (ch & UART011_DR_BE) {
+ ch &= ~(UART011_DR_FE | UART011_DR_PE);
uap->port.icount.brk++;
if (uart_handle_break(&uap->port))
goto ignore_char;
- } else if (rsr & UART01x_RSR_PE)
+ } else if (ch & UART011_DR_PE)
uap->port.icount.parity++;
- else if (rsr & UART01x_RSR_FE)
+ else if (ch & UART011_DR_FE)
uap->port.icount.frame++;
- if (rsr & UART01x_RSR_OE)
+ if (ch & UART011_DR_OE)
uap->port.icount.overrun++;
- rsr &= uap->port.read_status_mask;
+ ch &= uap->port.read_status_mask;
- if (rsr & UART01x_RSR_BE)
+ if (ch & UART011_DR_BE)
flag = TTY_BREAK;
- else if (rsr & UART01x_RSR_PE)
+ else if (ch & UART011_DR_PE)
flag = TTY_PARITY;
- else if (rsr & UART01x_RSR_FE)
+ else if (ch & UART011_DR_FE)
flag = TTY_FRAME;
}
if (uart_handle_sysrq_char(&uap->port, ch, regs))
goto ignore_char;
- uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag);
+ uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
ignore_char:
status = readw(uap->port.membase + UART01x_FR);
@@ -476,33 +475,33 @@ pl011_set_termios(struct uart_port *port, struct termios *termios,
*/
uart_update_timeout(port, termios->c_cflag, baud);
- port->read_status_mask = UART01x_RSR_OE;
+ port->read_status_mask = UART011_DR_OE | 255;
if (termios->c_iflag & INPCK)
- port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+ port->read_status_mask |= UART011_DR_FE | UART011_DR_PE;
if (termios->c_iflag & (BRKINT | PARMRK))
- port->read_status_mask |= UART01x_RSR_BE;
+ port->read_status_mask |= UART011_DR_BE;
/*
* Characters to ignore
*/
port->ignore_status_mask = 0;
if (termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+ port->ignore_status_mask |= UART011_DR_FE | UART011_DR_PE;
if (termios->c_iflag & IGNBRK) {
- port->ignore_status_mask |= UART01x_RSR_BE;
+ port->ignore_status_mask |= UART011_DR_BE;
/*
* If we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if (termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= UART01x_RSR_OE;
+ port->ignore_status_mask |= UART011_DR_OE;
}
/*
* Ignore all characters if CREAD is not set.
*/
if ((termios->c_cflag & CREAD) == 0)
- port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+ port->ignore_status_mask |= UART_DUMMY_DR_RX;
if (UART_ENABLE_MS(port, termios->c_cflag))
pl011_enable_ms(port);
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 660bae5ba17..7633132a10a 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -65,8 +65,8 @@ static struct uart_driver mux_driver = {
static struct timer_list mux_timer;
-#define UART_PUT_CHAR(p, c) __raw_writel((c), (unsigned long)(p)->membase + IO_DATA_REG_OFFSET)
-#define UART_GET_FIFO_CNT(p) __raw_readl((unsigned long)(p)->membase + IO_DCOUNT_REG_OFFSET)
+#define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET)
+#define UART_GET_FIFO_CNT(p) __raw_readl((p)->membase + IO_DCOUNT_REG_OFFSET)
#define GET_MUX_PORTS(iodc_data) ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8
/**
@@ -79,10 +79,7 @@ static struct timer_list mux_timer;
*/
static unsigned int mux_tx_empty(struct uart_port *port)
{
- unsigned int cnt = __raw_readl((unsigned long)port->membase
- + IO_DCOUNT_REG_OFFSET);
-
- return cnt ? 0 : TIOCSER_TEMT;
+ return UART_GET_FIFO_CNT(port) ? 0 : TIOCSER_TEMT;
}
/**
@@ -218,8 +215,7 @@ static void mux_read(struct uart_port *port)
__u32 start_count = port->icount.rx;
while(1) {
- data = __raw_readl((unsigned long)port->membase
- + IO_DATA_REG_OFFSET);
+ data = __raw_readl(port->membase + IO_DATA_REG_OFFSET);
if (MUX_STATUS(data))
continue;
@@ -481,6 +477,13 @@ static int __init mux_probe(struct parisc_device *dev)
port->ops = &mux_pops;
port->flags = UPF_BOOT_AUTOCONF;
port->line = port_cnt;
+
+ /* The port->timeout needs to match what is present in
+ * uart_wait_until_sent in serial_core.c. Otherwise
+ * the time spent in msleep_interruptable will be very
+ * long, causing the appearance of a console hang.
+ */
+ port->timeout = HZ / 50;
spin_lock_init(&port->lock);
status = uart_add_one_port(&mux_driver, port);
BUG_ON(status);
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 0e3daf6d7b5..25a086458ab 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -161,7 +161,6 @@ static void sa1100_stop_tx(struct uart_port *port)
static void sa1100_start_tx(struct uart_port *port)
{
struct sa1100_port *sport = (struct sa1100_port *)port;
- unsigned long flags;
u32 utcr3;
utcr3 = UART_GET_UTCR3(sport);
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 991c00de5c4..31b7efd94d6 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -137,7 +137,7 @@
#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int)
#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int)
#define EXT3_IOC32_GETVERSION _IOR('f', 3, int)
-#define EXT3_IOC32_SETVERSION _IOR('f', 4, int)
+#define EXT3_IOC32_SETVERSION _IOW('f', 4, int)
#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int)
#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int)
#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int)
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index 688f7f90d93..942b622455b 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -59,11 +59,10 @@ extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
* fallback to the default.
*/
static inline void __iomem *
-__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags, unsigned long align)
+__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags)
{
- extern void __iomem * __ioremap(unsigned long, size_t, unsigned long, unsigned long);
if((addr < 0x48000000) || (addr > 0x4fffffff))
- return __ioremap(addr, size, flags, align);
+ return __ioremap(addr, size, flags);
return (void *)addr;
}
@@ -71,13 +70,11 @@ __ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags, unsigned
static inline void
__ixp4xx_iounmap(void __iomem *addr)
{
- extern void __iounmap(void __iomem *addr);
-
if ((u32)addr >= VMALLOC_START)
__iounmap(addr);
}
-#define __arch_ioremap(a, s, f, x) __ixp4xx_ioremap(a, s, f, x)
+#define __arch_ioremap(a, s, f) __ixp4xx_ioremap(a, s, f)
#define __arch_iounmap(a) __ixp4xx_iounmap(a)
#define writeb(v, p) __ixp4xx_writeb(v, p)
diff --git a/include/asm-arm/hardware/amba_serial.h b/include/asm-arm/hardware/amba_serial.h
index 71770aa6389..dc726ffcceb 100644
--- a/include/asm-arm/hardware/amba_serial.h
+++ b/include/asm-arm/hardware/amba_serial.h
@@ -50,6 +50,11 @@
#define UART011_ICR 0x44 /* Interrupt clear register. */
#define UART011_DMACR 0x48 /* DMA control register. */
+#define UART011_DR_OE (1 << 11)
+#define UART011_DR_BE (1 << 10)
+#define UART011_DR_PE (1 << 9)
+#define UART011_DR_FE (1 << 8)
+
#define UART01x_RSR_OE 0x08
#define UART01x_RSR_BE 0x04
#define UART01x_RSR_PE 0x02
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 2e6799632f1..ae69db4a101 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -55,6 +55,12 @@ extern void __raw_readsl(void __iomem *addr, void *data, int longlen);
#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
/*
+ * Architecture ioremap implementation.
+ */
+extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
+extern void __iounmap(void __iomem *addr);
+
+/*
* Bad read/write accesses...
*/
extern void __readwrite_bug(const char *fn);
@@ -256,18 +262,15 @@ out:
* ioremap takes a PCI memory address, as specified in
* Documentation/IO-mapping.txt.
*/
-extern void __iomem * __ioremap(unsigned long, size_t, unsigned long, unsigned long);
-extern void __iounmap(void __iomem *addr);
-
#ifndef __arch_ioremap
-#define ioremap(cookie,size) __ioremap(cookie,size,0,1)
-#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0,1)
-#define ioremap_cached(cookie,size) __ioremap(cookie,size,L_PTE_CACHEABLE,1)
+#define ioremap(cookie,size) __ioremap(cookie,size,0)
+#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0)
+#define ioremap_cached(cookie,size) __ioremap(cookie,size,L_PTE_CACHEABLE)
#define iounmap(cookie) __iounmap(cookie)
#else
-#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0,1)
-#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0,1)
-#define ioremap_cached(cookie,size) __arch_ioremap((cookie),(size),L_PTE_CACHEABLE,1)
+#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0)
+#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0)
+#define ioremap_cached(cookie,size) __arch_ioremap((cookie),(size),L_PTE_CACHEABLE)
#define iounmap(cookie) __arch_iounmap(cookie)
#endif
diff --git a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h
index a2fdad0138b..064f0f5e8e2 100644
--- a/include/asm-arm/uaccess.h
+++ b/include/asm-arm/uaccess.h
@@ -100,7 +100,6 @@ static inline void set_fs (mm_segment_t fs)
extern int __get_user_1(void *);
extern int __get_user_2(void *);
extern int __get_user_4(void *);
-extern int __get_user_8(void *);
extern int __get_user_bad(void);
#define __get_user_x(__r2,__p,__e,__s,__i...) \
@@ -114,7 +113,7 @@ extern int __get_user_bad(void);
#define get_user(x,p) \
({ \
const register typeof(*(p)) __user *__p asm("r0") = (p);\
- register typeof(*(p)) __r2 asm("r2"); \
+ register unsigned int __r2 asm("r2"); \
register int __e asm("r0"); \
switch (sizeof(*(__p))) { \
case 1: \
@@ -126,12 +125,9 @@ extern int __get_user_bad(void);
case 4: \
__get_user_x(__r2, __p, __e, 4, "lr"); \
break; \
- case 8: \
- __get_user_x(__r2, __p, __e, 8, "lr"); \
- break; \
default: __e = __get_user_bad(); break; \
} \
- x = __r2; \
+ x = (typeof(*(p))) __r2; \
__e; \
})
diff --git a/include/asm-parisc/irq.h b/include/asm-parisc/irq.h
index f876bdf2205..b0a30e2c981 100644
--- a/include/asm-parisc/irq.h
+++ b/include/asm-parisc/irq.h
@@ -8,6 +8,7 @@
#define _ASM_PARISC_IRQ_H
#include <linux/config.h>
+#include <linux/cpumask.h>
#include <asm/types.h>
#define NO_IRQ (-1)
@@ -49,10 +50,10 @@ extern int txn_alloc_irq(unsigned int nbits);
extern int txn_claim_irq(int);
extern unsigned int txn_alloc_data(unsigned int);
extern unsigned long txn_alloc_addr(unsigned int);
+extern unsigned long txn_affinity_addr(unsigned int irq, int cpu);
extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
-
-extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
+extern int cpu_check_affinity(unsigned int irq, cpumask_t *dest);
/* soft power switch support (power.c) */
extern struct tasklet_struct power_tasklet;
diff --git a/include/asm-parisc/smp.h b/include/asm-parisc/smp.h
index 9413f67a540..dbdbd2e9fdf 100644
--- a/include/asm-parisc/smp.h
+++ b/include/asm-parisc/smp.h
@@ -29,6 +29,7 @@ extern cpumask_t cpu_online_map;
#define cpu_logical_map(cpu) (cpu)
extern void smp_send_reschedule(int cpu);
+extern void smp_send_all_nop(void);
#endif /* !ASSEMBLY */
@@ -53,7 +54,11 @@ extern unsigned long cpu_present_mask;
#define raw_smp_processor_id() (current_thread_info()->cpu)
-#endif /* CONFIG_SMP */
+#else /* CONFIG_SMP */
+
+static inline void smp_send_all_nop(void) { return; }
+
+#endif
#define NO_PROC_ID 0xFF /* No processor magic marker */
#define ANY_PROC_ID 0xFF /* Any processor magic marker */
diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
index 7c3f406a746..16c2ac075fc 100644
--- a/include/asm-parisc/spinlock.h
+++ b/include/asm-parisc/spinlock.h
@@ -11,18 +11,25 @@ static inline int __raw_spin_is_locked(raw_spinlock_t *x)
return *a == 0;
}
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_spin_lock(lock) __raw_spin_lock_flags(lock, 0)
#define __raw_spin_unlock_wait(x) \
do { cpu_relax(); } while (__raw_spin_is_locked(x))
-static inline void __raw_spin_lock(raw_spinlock_t *x)
+static inline void __raw_spin_lock_flags(raw_spinlock_t *x,
+ unsigned long flags)
{
volatile unsigned int *a;
mb();
a = __ldcw_align(x);
while (__ldcw(a) == 0)
- while (*a == 0);
+ while (*a == 0)
+ if (flags & PSW_SM_I) {
+ local_irq_enable();
+ cpu_relax();
+ local_irq_disable();
+ } else
+ cpu_relax();
mb();
}
@@ -60,26 +67,20 @@ static inline int __raw_spin_trylock(raw_spinlock_t *x)
static __inline__ void __raw_read_lock(raw_rwlock_t *rw)
{
- unsigned long flags;
- local_irq_save(flags);
__raw_spin_lock(&rw->lock);
rw->counter++;
__raw_spin_unlock(&rw->lock);
- local_irq_restore(flags);
}
static __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
{
- unsigned long flags;
- local_irq_save(flags);
__raw_spin_lock(&rw->lock);
rw->counter--;
__raw_spin_unlock(&rw->lock);
- local_irq_restore(flags);
}
/* write_lock is less trivial. We optimistically grab the lock and check
diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h
index e97aa8d1eff..c9ec39c6fc6 100644
--- a/include/asm-parisc/tlbflush.h
+++ b/include/asm-parisc/tlbflush.h
@@ -12,21 +12,15 @@
* N class systems, only one PxTLB inter processor broadcast can be
* active at any one time on the Merced bus. This tlb purge
* synchronisation is fairly lightweight and harmless so we activate
- * it on all SMP systems not just the N class. */
-#ifdef CONFIG_SMP
+ * it on all SMP systems not just the N class. We also need to have
+ * preemption disabled on uniprocessor machines, and spin_lock does that
+ * nicely.
+ */
extern spinlock_t pa_tlb_lock;
#define purge_tlb_start(x) spin_lock(&pa_tlb_lock)
#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock)
-#else
-
-#define purge_tlb_start(x) do { } while(0)
-#define purge_tlb_end(x) do { } while (0)
-
-#endif
-
-
extern void flush_tlb_all(void);
/*
@@ -88,7 +82,6 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */
flush_tlb_all();
else {
- preempt_disable();
mtsp(vma->vm_mm->context,1);
purge_tlb_start();
if (split_tlb) {
@@ -102,7 +95,6 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
pdtlb(start);
start += PAGE_SIZE;
}
- preempt_enable();
}
purge_tlb_end();
}
diff --git a/include/asm-ppc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 6e963511443..59a80163f75 100644
--- a/include/asm-ppc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -1,15 +1,22 @@
/*
- * This is based on both include/asm-sh/dma-mapping.h and
- * include/asm-ppc/pci.h
+ * Copyright (C) 2004 IBM
+ *
+ * Implements the generic device dma API for powerpc.
+ * the pci and vio busses
*/
-#ifndef __ASM_PPC_DMA_MAPPING_H
-#define __ASM_PPC_DMA_MAPPING_H
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/cache.h>
/* need struct page definitions */
#include <linux/mm.h>
#include <asm/scatterlist.h>
#include <asm/io.h>
+#include <asm/bug.h>
+
+#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
#ifdef CONFIG_NOT_COHERENT_CACHE
/*
@@ -24,22 +31,12 @@ extern void __dma_free_coherent(size_t size, void *vaddr);
extern void __dma_sync(void *vaddr, size_t size, int direction);
extern void __dma_sync_page(struct page *page, unsigned long offset,
size_t size, int direction);
-#define dma_cache_inv(_start,_size) \
- invalidate_dcache_range(_start, (_start + _size))
-#define dma_cache_wback(_start,_size) \
- clean_dcache_range(_start, (_start + _size))
-#define dma_cache_wback_inv(_start,_size) \
- flush_dcache_range(_start, (_start + _size))
#else /* ! CONFIG_NOT_COHERENT_CACHE */
/*
* Cache coherent cores.
*/
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
#define __dma_alloc_coherent(gfp, size, handle) NULL
#define __dma_free_coherent(size, addr) do { } while (0)
#define __dma_sync(addr, size, rw) do { } while (0)
@@ -47,6 +44,30 @@ extern void __dma_sync_page(struct page *page, unsigned long offset,
#endif /* ! CONFIG_NOT_COHERENT_CACHE */
+#ifdef CONFIG_PPC64
+
+extern int dma_supported(struct device *dev, u64 mask);
+extern int dma_set_mask(struct device *dev, u64 dma_mask);
+extern void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag);
+extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t dma_handle);
+extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction direction);
+extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction);
+extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction);
+extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+ size_t size, enum dma_data_direction direction);
+extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction);
+extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction direction);
+
+#else /* CONFIG_PPC64 */
+
#define dma_supported(dev, mask) (1)
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
@@ -144,29 +165,27 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
/* We don't do anything here. */
#define dma_unmap_sg(dev, sg, nents, dir) do { } while (0)
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
- size_t size,
- enum dma_data_direction direction)
+#endif /* CONFIG_PPC64 */
+
+static inline void dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
-
__dma_sync(bus_to_virt(dma_handle), size, direction);
}
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
- size_t size,
- enum dma_data_direction direction)
+static inline void dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
-
__dma_sync(bus_to_virt(dma_handle), size, direction);
}
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
+static inline void dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
{
int i;
@@ -176,9 +195,9 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
__dma_sync_page(sg->page, sg->offset, sg->length, direction);
}
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
+static inline void dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
{
int i;
@@ -188,6 +207,15 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
__dma_sync_page(sg->page, sg->offset, sg->length, direction);
}
+static inline int dma_mapping_error(dma_addr_t dma_addr)
+{
+#ifdef CONFIG_PPC64
+ return (dma_addr == DMA_ERROR_CODE);
+#else
+ return 0;
+#endif
+}
+
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
#ifdef CONFIG_NOT_COHERENT_CACHE
@@ -198,40 +226,60 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
static inline int dma_get_cache_alignment(void)
{
+#ifdef CONFIG_PPC64
+ /* no easy way to get cache size on all processors, so return
+ * the maximum possible, to be safe */
+ return (1 << L1_CACHE_SHIFT_MAX);
+#else
/*
* Each processor family will define its own L1_CACHE_SHIFT,
* L1_CACHE_BYTES wraps to this, so this is always safe.
*/
return L1_CACHE_BYTES;
+#endif
}
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, unsigned long offset, size_t size,
+ enum dma_data_direction direction)
{
/* just sync everything for now */
dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
}
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
+static inline void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t dma_handle, unsigned long offset, size_t size,
+ enum dma_data_direction direction)
{
/* just sync everything for now */
dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
}
static inline void dma_cache_sync(void *vaddr, size_t size,
- enum dma_data_direction direction)
+ enum dma_data_direction direction)
{
+ BUG_ON(direction == DMA_NONE);
__dma_sync(vaddr, size, (int)direction);
}
-static inline int dma_mapping_error(dma_addr_t dma_addr)
-{
- return 0;
-}
-
-#endif /* __ASM_PPC_DMA_MAPPING_H */
+/*
+ * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
+ */
+struct dma_mapping_ops {
+ void * (*alloc_coherent)(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag);
+ void (*free_coherent)(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+ dma_addr_t (*map_single)(struct device *dev, void *ptr,
+ size_t size, enum dma_data_direction direction);
+ void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction);
+ int (*map_sg)(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction);
+ void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction);
+ int (*dma_supported)(struct device *dev, u64 mask);
+ int (*dac_dma_supported)(struct device *dev, u64 mask);
+};
+
+#endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-ppc64/io.h b/include/asm-powerpc/io.h
index 77fc07c3c6b..48938d84d05 100644
--- a/include/asm-ppc64/io.h
+++ b/include/asm-powerpc/io.h
@@ -1,5 +1,5 @@
-#ifndef _PPC64_IO_H
-#define _PPC64_IO_H
+#ifndef _ASM_POWERPC_IO_H
+#define _ASM_POWERPC_IO_H
/*
* This program is free software; you can redistribute it and/or
@@ -8,7 +8,10 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
+#ifndef CONFIG_PPC64
+#include <asm-ppc/io.h>
+#else
+
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/byteorder.h>
@@ -455,4 +458,5 @@ extern int check_legacy_ioport(unsigned long base_port);
#endif /* __KERNEL__ */
-#endif /* _PPC64_IO_H */
+#endif /* CONFIG_PPC64 */
+#endif /* _ASM_POWERPC_IO_H */
diff --git a/include/asm-ppc64/mmu.h b/include/asm-powerpc/mmu.h
index 1a7e0afa2dc..c1b4bbabbe9 100644
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-powerpc/mmu.h
@@ -1,3 +1,10 @@
+#ifndef _ASM_POWERPC_MMU_H_
+#define _ASM_POWERPC_MMU_H_
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/mmu.h>
+#else
+
/*
* PowerPC memory management structures
*
@@ -10,10 +17,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifndef _PPC64_MMU_H_
-#define _PPC64_MMU_H_
-
-#include <linux/config.h>
#include <asm/asm-compat.h>
#include <asm/page.h>
@@ -392,4 +395,5 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea)
#endif /* __ASSEMBLY */
-#endif /* _PPC64_MMU_H_ */
+#endif /* CONFIG_PPC64 */
+#endif /* _ASM_POWERPC_MMU_H_ */
diff --git a/include/asm-ppc64/mmu_context.h b/include/asm-powerpc/mmu_context.h
index 4f512e9fa6b..ea6798c7d5f 100644
--- a/include/asm-ppc64/mmu_context.h
+++ b/include/asm-powerpc/mmu_context.h
@@ -1,7 +1,10 @@
-#ifndef __PPC64_MMU_CONTEXT_H
-#define __PPC64_MMU_CONTEXT_H
+#ifndef __ASM_POWERPC_MMU_CONTEXT_H
+#define __ASM_POWERPC_MMU_CONTEXT_H
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/mmu_context.h>
+#else
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/mmu.h>
@@ -82,4 +85,5 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
local_irq_restore(flags);
}
-#endif /* __PPC64_MMU_CONTEXT_H */
+#endif /* CONFIG_PPC64 */
+#endif /* __ASM_POWERPC_MMU_CONTEXT_H */
diff --git a/include/asm-ppc64/mmzone.h b/include/asm-powerpc/mmzone.h
index 54958d6cae0..54958d6cae0 100644
--- a/include/asm-ppc64/mmzone.h
+++ b/include/asm-powerpc/mmzone.h
diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index cf04327a597..223ec7bd81d 100644
--- a/include/asm-ppc64/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -1,8 +1,10 @@
-#ifdef __KERNEL__
-#ifndef _ASM_PCI_BRIDGE_H
-#define _ASM_PCI_BRIDGE_H
+#ifndef _ASM_POWERPC_PCI_BRIDGE_H
+#define _ASM_POWERPC_PCI_BRIDGE_H
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/pci-bridge.h>
+#else
-#include <linux/config.h>
#include <linux/pci.h>
#include <linux/list.h>
@@ -147,5 +149,5 @@ extern void pcibios_free_controller(struct pci_controller *phb);
#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */
#define PCI_PROBE_DEVTREE 1 /* Instantiate from device tree */
+#endif /* CONFIG_PPC64 */
#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/pci.h b/include/asm-powerpc/pci.h
index fafdf885a3c..d5934a076bd 100644
--- a/include/asm-ppc64/pci.h
+++ b/include/asm-powerpc/pci.h
@@ -1,5 +1,5 @@
-#ifndef __PPC64_PCI_H
-#define __PPC64_PCI_H
+#ifndef __ASM_POWERPC_PCI_H
+#define __ASM_POWERPC_PCI_H
#ifdef __KERNEL__
/*
@@ -18,6 +18,7 @@
#include <asm/scatterlist.h>
#include <asm/io.h>
#include <asm/prom.h>
+#include <asm/pci-bridge.h>
#include <asm-generic/pci-dma-compat.h>
@@ -26,11 +27,21 @@
struct pci_dev;
-#ifdef CONFIG_PPC_ISERIES
+/* Values for the `which' argument to sys_pciconfig_iobase syscall. */
+#define IOBASE_BRIDGE_NUMBER 0
+#define IOBASE_MEMORY 1
+#define IOBASE_IO 2
+#define IOBASE_ISA_IO 3
+#define IOBASE_ISA_MEM 4
+
+/*
+ * Set this to 1 if you want the kernel to re-assign all PCI
+ * bus numbers
+ */
+extern int pci_assign_all_buses;
+#define pcibios_assign_all_busses() (pci_assign_all_buses)
+
#define pcibios_scan_all_fns(a, b) 0
-#else
-extern int pcibios_scan_all_fns(struct pci_bus *bus, int devfn);
-#endif
static inline void pcibios_set_master(struct pci_dev *dev)
{
@@ -50,6 +61,7 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
return channel ? 15 : 14;
}
+#ifdef CONFIG_PPC64
#define HAVE_ARCH_PCI_MWI 1
static inline int pcibios_prep_mwi(struct pci_dev *dev)
{
@@ -64,12 +76,10 @@ static inline int pcibios_prep_mwi(struct pci_dev *dev)
return 0;
}
-extern unsigned int pcibios_assign_all_busses(void);
-
extern struct dma_mapping_ops pci_dma_ops;
/* For DAC DMA, we currently don't support it by default, but
- * we let the platform override this
+ * we let 64-bit platforms override this.
*/
static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
{
@@ -102,6 +112,35 @@ extern int pci_domain_nr(struct pci_bus *bus);
/* Decide whether to display the domain number in /proc */
extern int pci_proc_domain(struct pci_bus *bus);
+#else /* 32-bit */
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+ enum pci_dma_burst_strategy *strat,
+ unsigned long *strategy_parameter)
+{
+ *strat = PCI_DMA_BURST_INFINITY;
+ *strategy_parameter = ~0UL;
+}
+#endif
+
+/*
+ * At present there are very few 32-bit PPC machines that can have
+ * memory above the 4GB point, and we don't support that.
+ */
+#define pci_dac_dma_supported(pci_dev, mask) (0)
+
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
+
+/* Set the name of the bus as it appears in /proc/bus/pci */
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ return 0;
+}
+
+#endif /* CONFIG_PPC64 */
+
struct vm_area_struct;
/* Map a range of PCI memory or I/O space for a device into user space */
int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
@@ -110,6 +149,7 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
#define HAVE_PCI_MMAP 1
+#ifdef CONFIG_PPC64
/* pci_unmap_{single,page} is not a nop, thus... */
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
dma_addr_t ADDR_NAME;
@@ -124,22 +164,40 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
(((PTR)->LEN_NAME) = (VAL))
-/* The PCI address space does equal the physical memory
- * address space. The networking and block device layers use
+/* The PCI address space does not equal the physical memory address
+ * space (we have an IOMMU). The IDE and SCSI device layers use
* this boolean for bounce buffer decisions.
*/
#define PCI_DMA_BUS_IS_PHYS (0)
+
+#else /* 32-bit */
+
+/* The PCI address space does equal the physical memory
+ * address space (no IOMMU). The IDE and SCSI device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS (1)
+
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME) (0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME) (0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
+
+#endif /* CONFIG_PPC64 */
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+extern void pcibios_resource_to_bus(struct pci_dev *dev,
+ struct pci_bus_region *region,
struct resource *res);
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+extern void pcibios_bus_to_resource(struct pci_dev *dev,
+ struct resource *res,
struct pci_bus_region *region);
-static inline struct resource *
-pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
+ struct resource *res)
{
struct resource *root = NULL;
@@ -151,14 +209,12 @@ pcibios_select_root(struct pci_dev *pdev, struct resource *res)
return root;
}
-extern int
-unmap_bus_range(struct pci_bus *bus);
+extern int unmap_bus_range(struct pci_bus *bus);
-extern int
-remap_bus_range(struct pci_bus *bus);
+extern int remap_bus_range(struct pci_bus *bus);
-extern void
-pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus);
+extern void pcibios_fixup_device_resources(struct pci_dev *dev,
+ struct pci_bus *bus);
extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
@@ -180,14 +236,12 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file,
unsigned long size,
pgprot_t prot);
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#if defined(CONFIG_PPC_MULTIPLATFORM) || defined(CONFIG_PPC32)
#define HAVE_ARCH_PCI_RESOURCE_TO_USER
extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
const struct resource *rsrc,
u64 *start, u64 *end);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
+#endif /* CONFIG_PPC_MULTIPLATFORM || CONFIG_PPC32 */
#endif /* __KERNEL__ */
-
-#endif /* __PPC64_PCI_H */
+#endif /* __ASM_POWERPC_PCI_H */
diff --git a/include/asm-ppc64/pgalloc.h b/include/asm-powerpc/pgalloc.h
index dcf3622d194..bfc2113b363 100644
--- a/include/asm-ppc64/pgalloc.h
+++ b/include/asm-powerpc/pgalloc.h
@@ -1,5 +1,9 @@
-#ifndef _PPC64_PGALLOC_H
-#define _PPC64_PGALLOC_H
+#ifndef _ASM_POWERPC_PGALLOC_H
+#define _ASM_POWERPC_PGALLOC_H
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/pgalloc.h>
+#else
#include <linux/mm.h>
#include <linux/slab.h>
@@ -148,4 +152,5 @@ extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
#define check_pgt_cache() do { } while (0)
-#endif /* _PPC64_PGALLOC_H */
+#endif /* CONFIG_PPC64 */
+#endif /* _ASM_POWERPC_PGALLOC_H */
diff --git a/include/asm-ppc64/pgtable-4k.h b/include/asm-powerpc/pgtable-4k.h
index e9590c06ad9..e9590c06ad9 100644
--- a/include/asm-ppc64/pgtable-4k.h
+++ b/include/asm-powerpc/pgtable-4k.h
diff --git a/include/asm-ppc64/pgtable-64k.h b/include/asm-powerpc/pgtable-64k.h
index 154f1840ece..154f1840ece 100644
--- a/include/asm-ppc64/pgtable-64k.h
+++ b/include/asm-powerpc/pgtable-64k.h
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-powerpc/pgtable.h
index a9783ba7fe9..0303f57366c 100644
--- a/include/asm-ppc64/pgtable.h
+++ b/include/asm-powerpc/pgtable.h
@@ -1,5 +1,9 @@
-#ifndef _PPC64_PGTABLE_H
-#define _PPC64_PGTABLE_H
+#ifndef _ASM_POWERPC_PGTABLE_H
+#define _ASM_POWERPC_PGTABLE_H
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/pgtable.h>
+#else
/*
* This file contains the functions and defines necessary to modify and use
@@ -47,6 +51,13 @@ struct mm_struct;
#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
/*
+ * Define the address range of the imalloc VM area.
+ */
+#define PHBS_IO_BASE VMALLOC_END
+#define IMALLOC_BASE (PHBS_IO_BASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */
+#define IMALLOC_END (VMALLOC_START + PGTABLE_RANGE)
+
+/*
* Common bits in a linux-style PTE. These match the bits in the
* (hardware-defined) PowerPC PTE as closely as possible. Additional
* bits may be defined in pgtable-*.h
@@ -69,7 +80,7 @@ struct mm_struct;
#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY)
-/* __pgprot defined in asm-ppc64/page.h */
+/* __pgprot defined in asm-powerpc/page.h */
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
@@ -509,4 +520,5 @@ void pgtable_cache_init(void);
#endif /* __ASSEMBLY__ */
-#endif /* _PPC64_PGTABLE_H */
+#endif /* CONFIG_PPC64 */
+#endif /* _ASM_POWERPC_PGTABLE_H */
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index 2e36e5a7f4f..36cdc869e58 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -48,8 +48,6 @@ extern void pSeries_final_fixup(void);
extern void pSeries_irq_bus_setup(struct pci_bus *bus);
extern unsigned long pci_probe_only;
-extern unsigned long pci_assign_all_buses;
-extern int pci_read_irq_line(struct pci_dev *pci_dev);
/* ---- EEH internal-use-only related routines ---- */
#ifdef CONFIG_EEH
diff --git a/include/asm-ppc64/spinlock.h b/include/asm-powerpc/spinlock.h
index 7d84fb5e39f..caa4b14e0e9 100644
--- a/include/asm-ppc64/spinlock.h
+++ b/include/asm-powerpc/spinlock.h
@@ -18,31 +18,41 @@
*
* (the type definitions are in asm/spinlock_types.h)
*/
-#include <linux/config.h>
+#ifdef CONFIG_PPC64
#include <asm/paca.h>
#include <asm/hvcall.h>
#include <asm/iseries/hv_call.h>
+#endif
+#include <asm/asm-compat.h>
+#include <asm/synch.h>
#define __raw_spin_is_locked(x) ((x)->slock != 0)
+#ifdef CONFIG_PPC64
+/* use 0x800000yy when locked, where yy == CPU number */
+#define LOCK_TOKEN (*(u32 *)(&get_paca()->lock_token))
+#else
+#define LOCK_TOKEN 1
+#endif
+
/*
* This returns the old value in the lock, so we succeeded
* in getting the lock if the return value is 0.
*/
static __inline__ unsigned long __spin_trylock(raw_spinlock_t *lock)
{
- unsigned long tmp, tmp2;
+ unsigned long tmp, token;
+ token = LOCK_TOKEN;
__asm__ __volatile__(
-" lwz %1,%3(13) # __spin_trylock\n\
-1: lwarx %0,0,%2\n\
+"1: lwarx %0,0,%2 # __spin_trylock\n\
cmpwi 0,%0,0\n\
bne- 2f\n\
stwcx. %1,0,%2\n\
bne- 1b\n\
isync\n\
-2:" : "=&r" (tmp), "=&r" (tmp2)
- : "r" (&lock->slock), "i" (offsetof(struct paca_struct, lock_token))
+2:" : "=&r" (tmp)
+ : "r" (token), "r" (&lock->slock)
: "cr0", "memory");
return tmp;
@@ -113,11 +123,17 @@ static void __inline__ __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long
static __inline__ void __raw_spin_unlock(raw_spinlock_t *lock)
{
- __asm__ __volatile__("lwsync # __raw_spin_unlock": : :"memory");
+ __asm__ __volatile__(SYNC_ON_SMP" # __raw_spin_unlock"
+ : : :"memory");
lock->slock = 0;
}
+#ifdef CONFIG_PPC64
extern void __raw_spin_unlock_wait(raw_spinlock_t *lock);
+#else
+#define __raw_spin_unlock_wait(lock) \
+ do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+#endif
/*
* Read-write spinlocks, allowing multiple readers
@@ -133,6 +149,14 @@ extern void __raw_spin_unlock_wait(raw_spinlock_t *lock);
#define __raw_read_can_lock(rw) ((rw)->lock >= 0)
#define __raw_write_can_lock(rw) (!(rw)->lock)
+#ifdef CONFIG_PPC64
+#define __DO_SIGN_EXTEND "extsw %0,%0\n"
+#define WRLOCK_TOKEN LOCK_TOKEN /* it's negative */
+#else
+#define __DO_SIGN_EXTEND
+#define WRLOCK_TOKEN (-1)
+#endif
+
/*
* This returns the old value in the lock + 1,
* so we got a read lock if the return value is > 0.
@@ -142,11 +166,12 @@ static long __inline__ __read_trylock(raw_rwlock_t *rw)
long tmp;
__asm__ __volatile__(
-"1: lwarx %0,0,%1 # read_trylock\n\
- extsw %0,%0\n\
- addic. %0,%0,1\n\
- ble- 2f\n\
- stwcx. %0,0,%1\n\
+"1: lwarx %0,0,%1 # read_trylock\n"
+ __DO_SIGN_EXTEND
+" addic. %0,%0,1\n\
+ ble- 2f\n"
+ PPC405_ERR77(0,%1)
+" stwcx. %0,0,%1\n\
bne- 1b\n\
isync\n\
2:" : "=&r" (tmp)
@@ -162,18 +187,19 @@ static long __inline__ __read_trylock(raw_rwlock_t *rw)
*/
static __inline__ long __write_trylock(raw_rwlock_t *rw)
{
- long tmp, tmp2;
+ long tmp, token;
+ token = WRLOCK_TOKEN;
__asm__ __volatile__(
-" lwz %1,%3(13) # write_trylock\n\
-1: lwarx %0,0,%2\n\
+"1: lwarx %0,0,%2 # write_trylock\n\
cmpwi 0,%0,0\n\
- bne- 2f\n\
- stwcx. %1,0,%2\n\
+ bne- 2f\n"
+ PPC405_ERR77(0,%1)
+" stwcx. %1,0,%2\n\
bne- 1b\n\
isync\n\
-2:" : "=&r" (tmp), "=&r" (tmp2)
- : "r" (&rw->lock), "i" (offsetof(struct paca_struct, lock_token))
+2:" : "=&r" (tmp)
+ : "r" (token), "r" (&rw->lock)
: "cr0", "memory");
return tmp;
@@ -224,8 +250,9 @@ static void __inline__ __raw_read_unlock(raw_rwlock_t *rw)
__asm__ __volatile__(
"eieio # read_unlock\n\
1: lwarx %0,0,%1\n\
- addic %0,%0,-1\n\
- stwcx. %0,0,%1\n\
+ addic %0,%0,-1\n"
+ PPC405_ERR77(0,%1)
+" stwcx. %0,0,%1\n\
bne- 1b"
: "=&r"(tmp)
: "r"(&rw->lock)
@@ -234,7 +261,8 @@ static void __inline__ __raw_read_unlock(raw_rwlock_t *rw)
static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
{
- __asm__ __volatile__("lwsync # write_unlock": : :"memory");
+ __asm__ __volatile__(SYNC_ON_SMP" # write_unlock"
+ : : :"memory");
rw->lock = 0;
}
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 2bfdf9c9845..84ac6e258ee 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -545,6 +545,23 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
#include <asm/mpc8260_pci9.h>
#endif
+#ifdef CONFIG_NOT_COHERENT_CACHE
+
+#define dma_cache_inv(_start,_size) \
+ invalidate_dcache_range(_start, (_start + _size))
+#define dma_cache_wback(_start,_size) \
+ clean_dcache_range(_start, (_start + _size))
+#define dma_cache_wback_inv(_start,_size) \
+ flush_dcache_range(_start, (_start + _size))
+
+#else
+
+#define dma_cache_inv(_start,_size) do { } while (0)
+#define dma_cache_wback(_start,_size) do { } while (0)
+#define dma_cache_wback_inv(_start,_size) do { } while (0)
+
+#endif
+
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
diff --git a/include/asm-ppc64/dma-mapping.h b/include/asm-ppc64/dma-mapping.h
deleted file mode 100644
index fb68fa23bea..00000000000
--- a/include/asm-ppc64/dma-mapping.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (C) 2004 IBM
- *
- * Implements the generic device dma API for ppc64. Handles
- * the pci and vio busses
- */
-
-#ifndef _ASM_DMA_MAPPING_H
-#define _ASM_DMA_MAPPING_H
-
-#include <linux/types.h>
-#include <linux/cache.h>
-/* need struct page definitions */
-#include <linux/mm.h>
-#include <asm/scatterlist.h>
-#include <asm/bug.h>
-
-#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
-
-extern int dma_supported(struct device *dev, u64 mask);
-extern int dma_set_mask(struct device *dev, u64 dma_mask);
-extern void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
-extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle);
-extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
- size_t size, enum dma_data_direction direction);
-extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction direction);
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction direction);
-extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
- size_t size, enum dma_data_direction direction);
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction);
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction direction);
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- /* nothing to do */
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- /* nothing to do */
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- /* nothing to do */
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- /* nothing to do */
-}
-
-static inline int dma_mapping_error(dma_addr_t dma_addr)
-{
- return (dma_addr == DMA_ERROR_CODE);
-}
-
-/* Now for the API extensions over the pci_ one */
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_is_consistent(d) (1)
-
-static inline int
-dma_get_cache_alignment(void)
-{
- /* no easy way to get cache size on all processors, so return
- * the maximum possible, to be safe */
- return (1 << L1_CACHE_SHIFT_MAX);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- /* nothing to do */
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- /* nothing to do */
-}
-
-static inline void
-dma_cache_sync(void *vaddr, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(direction == DMA_NONE);
- /* nothing to do */
-}
-
-/*
- * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
- */
-struct dma_mapping_ops {
- void * (*alloc_coherent)(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
- void (*free_coherent)(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
- dma_addr_t (*map_single)(struct device *dev, void *ptr,
- size_t size, enum dma_data_direction direction);
- void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction direction);
- int (*map_sg)(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction);
- void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction);
- int (*dma_supported)(struct device *dev, u64 mask);
- int (*dac_dma_supported)(struct device *dev, u64 mask);
-};
-
-#endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-ppc64/imalloc.h b/include/asm-ppc64/imalloc.h
deleted file mode 100644
index 42adf7033a8..00000000000
--- a/include/asm-ppc64/imalloc.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _PPC64_IMALLOC_H
-#define _PPC64_IMALLOC_H
-
-/*
- * Define the address range of the imalloc VM area.
- */
-#define PHBS_IO_BASE VMALLOC_END
-#define IMALLOC_BASE (PHBS_IO_BASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */
-#define IMALLOC_END (VMALLOC_START + PGTABLE_RANGE)
-
-
-/* imalloc region types */
-#define IM_REGION_UNUSED 0x1
-#define IM_REGION_SUBSET 0x2
-#define IM_REGION_EXISTS 0x4
-#define IM_REGION_OVERLAP 0x8
-#define IM_REGION_SUPERSET 0x10
-
-extern struct vm_struct * im_get_free_area(unsigned long size);
-extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
- int region_type);
-extern void im_free(void *addr);
-
-extern unsigned long ioremap_bot;
-
-#endif /* _PPC64_IMALLOC_H */
diff --git a/include/linux/cciss_ioctl.h b/include/linux/cciss_ioctl.h
index 424d5e622b4..6e27f42e3a5 100644
--- a/include/linux/cciss_ioctl.h
+++ b/include/linux/cciss_ioctl.h
@@ -10,8 +10,8 @@
typedef struct _cciss_pci_info_struct
{
unsigned char bus;
- unsigned short domain;
unsigned char dev_fn;
+ unsigned short domain;
__u32 board_id;
} cciss_pci_info_struct;
diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h
index b5d660089de..2b54eac738e 100644
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -80,10 +80,12 @@
/*
* Define standard taskfile in/out register
*/
-#define IDE_TASKFILE_STD_OUT_FLAGS 0xFE
#define IDE_TASKFILE_STD_IN_FLAGS 0xFE
-#define IDE_HOB_STD_OUT_FLAGS 0x3C
#define IDE_HOB_STD_IN_FLAGS 0x3C
+#ifndef __KERNEL__
+#define IDE_TASKFILE_STD_OUT_FLAGS 0xFE
+#define IDE_HOB_STD_OUT_FLAGS 0x3C
+#endif
typedef unsigned char task_ioreg_t;
typedef unsigned long sata_ioreg_t;
diff --git a/include/linux/ide.h b/include/linux/ide.h
index ac8b25fa650..a39c3c59789 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1089,9 +1089,11 @@ enum {
/*
* Subdrivers support.
+ *
+ * The gendriver.owner field should be set to the module owner of this driver.
+ * The gendriver.name field should be set to the name of this driver
*/
typedef struct ide_driver_s {
- struct module *owner;
const char *version;
u8 media;
unsigned supports_dsc_overlap : 1;
@@ -1199,37 +1201,11 @@ extern u64 ide_get_error_location(ide_drive_t *, char *);
*/
typedef enum {
ide_wait, /* insert rq at end of list, and wait for it */
- ide_next, /* insert rq immediately after current request */
ide_preempt, /* insert rq in front of current request */
ide_head_wait, /* insert rq in front of current request and wait for it */
ide_end /* insert rq at end of list, but don't wait for it */
} ide_action_t;
-/*
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
- *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed. This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
- *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed. As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
- */
extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t);
/*
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 1013a42d10b..0986d19be0b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -940,7 +940,9 @@ unsigned long max_sane_readahead(unsigned long nr);
/* Do stack extension */
extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
+#ifdef CONFIG_IA64
extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
+#endif
/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 7b387faedb4..efb60d06caa 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -620,6 +620,7 @@
#define PCI_DEVICE_ID_SI_961 0x0961
#define PCI_DEVICE_ID_SI_962 0x0962
#define PCI_DEVICE_ID_SI_963 0x0963
+#define PCI_DEVICE_ID_SI_965 0x0965
#define PCI_DEVICE_ID_SI_5511 0x5511
#define PCI_DEVICE_ID_SI_5513 0x5513
#define PCI_DEVICE_ID_SI_5518 0x5518
@@ -1234,6 +1235,7 @@
#define PCI_DEVICE_ID_VIA_8703_51_0 0x3148
#define PCI_DEVICE_ID_VIA_8237_SATA 0x3149
#define PCI_DEVICE_ID_VIA_XN266 0x3156
+#define PCI_DEVICE_ID_VIA_6410 0x3164
#define PCI_DEVICE_ID_VIA_8754C_0 0x3168
#define PCI_DEVICE_ID_VIA_8235 0x3177
#define PCI_DEVICE_ID_VIA_8385_0 0x3188
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index b93fd8c1d88..cde2f4f4f50 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -1042,7 +1042,7 @@ static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
case IEEE80211_4ADDR_LEN:
return ((struct ieee80211_hdr_4addr *)hdr)->payload;
}
-
+ return NULL;
}
static inline int ieee80211_is_ofdm_rate(u8 rate)
diff --git a/mm/mmap.c b/mm/mmap.c
index 6c997b15960..4f8def03428 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1501,7 +1501,7 @@ static int acct_stack_growth(struct vm_area_struct * vma, unsigned long size, un
* PA-RISC uses this for its stack; IA64 for its Register Backing Store.
* vma is the last one with address > vma->vm_end. Have to extend vma.
*/
-#ifdef CONFIG_STACK_GROWSUP
+#ifndef CONFIG_IA64
static inline
#endif
int expand_upwards(struct vm_area_struct *vma, unsigned long address)