Merge branch 'master'
This commit is contained in:
commit
30765528d1
127 changed files with 2144 additions and 1894 deletions
12
CREDITS
12
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
|
||||
|
|
|
@ -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
|
||||
|
|
618
Documentation/HOWTO
Normal file
618
Documentation/HOWTO
Normal file
|
@ -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>
|
|
@ -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
|
||||
|
|
16
MAINTAINERS
16
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
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 15
|
||||
EXTRAVERSION =-rc1
|
||||
EXTRAVERSION =-rc2
|
||||
NAME=Affluent Albatross
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -595,10 +595,14 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|
|||
*/
|
||||
ret |= !valid_user_regs(regs);
|
||||
|
||||
/*
|
||||
* Block the signal if we were unsuccessful.
|
||||
*/
|
||||
if (ret != 0) {
|
||||
force_sigsegv(sig, tsk);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Block the signal if we were successful.
|
||||
*/
|
||||
spin_lock_irq(&tsk->sighand->siglock);
|
||||
sigorsets(&tsk->blocked, &tsk->blocked,
|
||||
&ka->sa.sa_mask);
|
||||
|
@ -606,12 +610,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|
|||
sigaddset(&tsk->blocked, sig);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(&tsk->sighand->siglock);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
return;
|
||||
|
||||
force_sigsegv(sig, tsk);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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];
|
||||
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
|
||||
};
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
@ -339,6 +347,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;
|
||||
data.wait = wait;
|
||||
|
|
|
@ -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! */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/block/as-iosched.c
|
||||
*
|
||||
* Anticipatory & deadline i/o scheduler.
|
||||
*
|
||||
* Copyright (C) 2002 Jens Axboe <axboe@suse.de>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/block/deadline-iosched.c
|
||||
*
|
||||
* Deadline i/o scheduler.
|
||||
*
|
||||
* Copyright (C) 2002 Jens Axboe <axboe@suse.de>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/block/elevator.c
|
||||
*
|
||||
* Block device elevator/IO-scheduler.
|
||||
*
|
||||
* Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
} 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) {
|
||||
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);
|
||||
if (disk) {
|
||||
request_queue_t *q = disk->queue;
|
||||
if (disk->flags & GENHD_FL_UP)
|
||||
del_gendisk(disk);
|
||||
drv->queue = NULL;
|
||||
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) {
|
||||
if (disk) {
|
||||
request_queue_t *q = disk->queue;
|
||||
|
||||
if (disk->flags & GENHD_FL_UP)
|
||||
del_gendisk(disk);
|
||||
blk_cleanup_queue(disk->queue);
|
||||
if (q)
|
||||
blk_cleanup_queue(q);
|
||||
put_disk(disk);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>.
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
@ -3511,7 +3511,7 @@ 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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
if (!PCI_DMA_BUS_IS_PHYS) {
|
||||
addr = BLK_BOUNCE_ANY;
|
||||
else if (HWIF(drive)->pci_dev)
|
||||
} else if (on && drive->media == ide_disk) {
|
||||
if (HWIF(drive)->pci_dev)
|
||||
addr = HWIF(drive)->pci_dev->dma_mask;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ®49h);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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:
|
||||
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);
|
||||
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) {
|
||||
} 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.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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 = {
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -730,14 +730,15 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
|
|||
}
|
||||
|
||||
if (attr_mask & IB_QP_ACCESS_FLAGS) {
|
||||
/*
|
||||
* Only enable RDMA/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);
|
||||
|
||||
/*
|
||||
* 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_READ ?
|
||||
MTHCA_QP_BIT_RRE : 0);
|
||||
|
@ -759,22 +760,19 @@ 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);
|
||||
|
@ -782,8 +780,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
|
|||
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) -
|
||||
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);
|
||||
sizeof (struct mthca_data_seg));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -159,11 +159,11 @@ 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",
|
||||
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",
|
||||
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",
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
|
|
|
@ -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,24 +1007,263 @@ 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,
|
||||
};
|
||||
/* *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* */
|
||||
|
||||
if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
|
||||
for(i = 0; i < UCODE_SIZE; i++)
|
||||
/*************************************************************************
|
||||
* 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
|
||||
return;
|
||||
}
|
||||
|
||||
noloaducode:
|
||||
cb->command = cpu_to_le16(cb_nop);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -154,6 +154,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
|
||||
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(¤t_time);
|
||||
DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
|
||||
current_time.tv_sec, (long)current_time.tv_usec, reg);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
@ -486,7 +492,9 @@ static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_
|
|||
}
|
||||
|
||||
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, }
|
||||
};
|
||||
|
||||
|
@ -506,6 +514,5 @@ static void __exit superio_exit(void)
|
|||
pci_unregister_driver(&superio_driver);
|
||||
}
|
||||
|
||||
|
||||
module_init(superio_modinit);
|
||||
module_exit(superio_exit);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 int sil24_issue_SRST(struct ata_port *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);
|
||||
|
||||
/*
|
||||
* XXX: Not sure whether the following sleep is needed or not.
|
||||
* The original driver had it. So....
|
||||
*/
|
||||
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);
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
|
||||
ap->device[0].class = ATA_DEV_ATA;
|
||||
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;
|
||||
|
||||
if (tmp & PORT_CS_RDY)
|
||||
return 0;
|
||||
|
||||
return __sil24_restart_controller(port);
|
||||
}
|
||||
|
||||
static void sil24_reset_controller(struct ata_port *ap)
|
||||
|
@ -567,7 +684,13 @@ 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"
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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---
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -54,6 +54,12 @@ extern void __raw_readsl(void __iomem *addr, void *data, int longlen);
|
|||
#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
|
||||
#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...
|
||||
*/
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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; \
|
||||
})
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue