Merge branch 'linux-2.6'
This commit is contained in:
Коммит
0ce49a3945
|
@ -166,7 +166,7 @@ To solve this problem, you really only have two options:
|
|||
The option of being unfailingly polite really doesn't exist. Nobody will
|
||||
trust somebody who is so clearly hiding his true character.
|
||||
|
||||
(*) Paul Simon sang "Fifty Ways to Lose Your Lover", because quite
|
||||
(*) Paul Simon sang "Fifty Ways to Leave Your Lover", because quite
|
||||
frankly, "A Million Ways to Tell a Developer He Is a D*ckhead" doesn't
|
||||
scan nearly as well. But I'm sure he thought about it.
|
||||
|
||||
|
|
|
@ -298,3 +298,11 @@ Why: All mthca hardware also supports MSI-X, which provides
|
|||
Who: Roland Dreier <rolandd@cisco.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: sk98lin network driver
|
||||
When: Feburary 2008
|
||||
Why: In kernel tree version of driver is unmaintained. Sk98lin driver
|
||||
replaced by the skge driver.
|
||||
Who: Stephen Hemminger <shemminger@linux-foundation.org>
|
||||
|
||||
---------------------------
|
||||
|
|
|
@ -468,9 +468,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
Format:
|
||||
<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
|
||||
|
||||
cpia_pp= [HW,PPT]
|
||||
Format: { parport<nr> | auto | none }
|
||||
|
||||
crashkernel=nn[KMG]@ss[KMG]
|
||||
[KNL] Reserve a chunk of physical memory to
|
||||
hold a kernel to switch to with kexec on panic.
|
||||
|
|
|
@ -96,6 +96,9 @@ routing.txt
|
|||
- the new routing mechanism
|
||||
shaper.txt
|
||||
- info on the module that can shape/limit transmitted traffic.
|
||||
sk98lin.txt
|
||||
- Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit
|
||||
Ethernet Adapter family driver info
|
||||
skfp.txt
|
||||
- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
|
||||
smc9.txt
|
||||
|
|
|
@ -0,0 +1,568 @@
|
|||
(C)Copyright 1999-2004 Marvell(R).
|
||||
All rights reserved
|
||||
===========================================================================
|
||||
|
||||
sk98lin.txt created 13-Feb-2004
|
||||
|
||||
Readme File for sk98lin v6.23
|
||||
Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
|
||||
|
||||
This file contains
|
||||
1 Overview
|
||||
2 Required Files
|
||||
3 Installation
|
||||
3.1 Driver Installation
|
||||
3.2 Inclusion of adapter at system start
|
||||
4 Driver Parameters
|
||||
4.1 Per-Port Parameters
|
||||
4.2 Adapter Parameters
|
||||
5 Large Frame Support
|
||||
6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
|
||||
7 Troubleshooting
|
||||
|
||||
===========================================================================
|
||||
|
||||
|
||||
1 Overview
|
||||
===========
|
||||
|
||||
The sk98lin driver supports the Marvell Yukon and SysKonnect
|
||||
SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has
|
||||
been tested with Linux on Intel/x86 machines.
|
||||
***
|
||||
|
||||
|
||||
2 Required Files
|
||||
=================
|
||||
|
||||
The linux kernel source.
|
||||
No additional files required.
|
||||
***
|
||||
|
||||
|
||||
3 Installation
|
||||
===============
|
||||
|
||||
It is recommended to download the latest version of the driver from the
|
||||
SysKonnect web site www.syskonnect.com. If you have downloaded the latest
|
||||
driver, the Linux kernel has to be patched before the driver can be
|
||||
installed. For details on how to patch a Linux kernel, refer to the
|
||||
patch.txt file.
|
||||
|
||||
3.1 Driver Installation
|
||||
------------------------
|
||||
|
||||
The following steps describe the actions that are required to install
|
||||
the driver and to start it manually. These steps should be carried
|
||||
out for the initial driver setup. Once confirmed to be ok, they can
|
||||
be included in the system start.
|
||||
|
||||
NOTE 1: To perform the following tasks you need 'root' access.
|
||||
|
||||
NOTE 2: In case of problems, please read the section "Troubleshooting"
|
||||
below.
|
||||
|
||||
The driver can either be integrated into the kernel or it can be compiled
|
||||
as a module. Select the appropriate option during the kernel
|
||||
configuration.
|
||||
|
||||
Compile/use the driver as a module
|
||||
----------------------------------
|
||||
To compile the driver, go to the directory /usr/src/linux and
|
||||
execute the command "make menuconfig" or "make xconfig" and proceed as
|
||||
follows:
|
||||
|
||||
To integrate the driver permanently into the kernel, proceed as follows:
|
||||
|
||||
1. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
|
||||
2. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support"
|
||||
with (*)
|
||||
3. Build a new kernel when the configuration of the above options is
|
||||
finished.
|
||||
4. Install the new kernel.
|
||||
5. Reboot your system.
|
||||
|
||||
To use the driver as a module, proceed as follows:
|
||||
|
||||
1. Enable 'loadable module support' in the kernel.
|
||||
2. For automatic driver start, enable the 'Kernel module loader'.
|
||||
3. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
|
||||
4. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support"
|
||||
with (M)
|
||||
5. Execute the command "make modules".
|
||||
6. Execute the command "make modules_install".
|
||||
The appropriate modules will be installed.
|
||||
7. Reboot your system.
|
||||
|
||||
|
||||
Load the module manually
|
||||
------------------------
|
||||
To load the module manually, proceed as follows:
|
||||
|
||||
1. Enter "modprobe sk98lin".
|
||||
2. If a Marvell Yukon or SysKonnect SK-98xx adapter is installed in
|
||||
your computer and you have a /proc file system, execute the command:
|
||||
"ls /proc/net/sk98lin/"
|
||||
This should produce an output containing a line with the following
|
||||
format:
|
||||
eth0 eth1 ...
|
||||
which indicates that your adapter has been found and initialized.
|
||||
|
||||
NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx
|
||||
adapter installed, the adapters will be listed as 'eth0',
|
||||
'eth1', 'eth2', etc.
|
||||
For each adapter, repeat steps 3 and 4 below.
|
||||
|
||||
NOTE 2: If you have other Ethernet adapters installed, your Marvell
|
||||
Yukon or SysKonnect SK-98xx adapter will be mapped to the
|
||||
next available number, e.g. 'eth1'. The mapping is executed
|
||||
automatically.
|
||||
The module installation message (displayed either in a system
|
||||
log file or on the console) prints a line for each adapter
|
||||
found containing the corresponding 'ethX'.
|
||||
|
||||
3. Select an IP address and assign it to the respective adapter by
|
||||
entering:
|
||||
ifconfig eth0 <ip-address>
|
||||
With this command, the adapter is connected to the Ethernet.
|
||||
|
||||
SK-98xx Gigabit Ethernet Server Adapters: The yellow LED on the adapter
|
||||
is now active, the link status LED of the primary port is active and
|
||||
the link status LED of the secondary port (on dual port adapters) is
|
||||
blinking (if the ports are connected to a switch or hub).
|
||||
SK-98xx V2.0 Gigabit Ethernet Adapters: The link status LED is active.
|
||||
In addition, you will receive a status message on the console stating
|
||||
"ethX: network connection up using port Y" and showing the selected
|
||||
connection parameters (x stands for the ethernet device number
|
||||
(0,1,2, etc), y stands for the port name (A or B)).
|
||||
|
||||
NOTE: If you are in doubt about IP addresses, ask your network
|
||||
administrator for assistance.
|
||||
|
||||
4. Your adapter should now be fully operational.
|
||||
Use 'ping <otherstation>' to verify the connection to other computers
|
||||
on your network.
|
||||
5. To check the adapter configuration view /proc/net/sk98lin/[devicename].
|
||||
For example by executing:
|
||||
"cat /proc/net/sk98lin/eth0"
|
||||
|
||||
Unload the module
|
||||
-----------------
|
||||
To stop and unload the driver modules, proceed as follows:
|
||||
|
||||
1. Execute the command "ifconfig eth0 down".
|
||||
2. Execute the command "rmmod sk98lin".
|
||||
|
||||
3.2 Inclusion of adapter at system start
|
||||
-----------------------------------------
|
||||
|
||||
Since a large number of different Linux distributions are
|
||||
available, we are unable to describe a general installation procedure
|
||||
for the driver module.
|
||||
Because the driver is now integrated in the kernel, installation should
|
||||
be easy, using the standard mechanism of your distribution.
|
||||
Refer to the distribution's manual for installation of ethernet adapters.
|
||||
|
||||
***
|
||||
|
||||
4 Driver Parameters
|
||||
====================
|
||||
|
||||
Parameters can be set at the command line after the module has been
|
||||
loaded with the command 'modprobe'.
|
||||
In some distributions, the configuration tools are able to pass parameters
|
||||
to the driver module.
|
||||
|
||||
If you use the kernel module loader, you can set driver parameters
|
||||
in the file /etc/modprobe.conf (or /etc/modules.conf in 2.4 or earlier).
|
||||
To set the driver parameters in this file, proceed as follows:
|
||||
|
||||
1. Insert a line of the form :
|
||||
options sk98lin ...
|
||||
For "...", the same syntax is required as described for the command
|
||||
line parameters of modprobe below.
|
||||
2. To activate the new parameters, either reboot your computer
|
||||
or
|
||||
unload and reload the driver.
|
||||
The syntax of the driver parameters is:
|
||||
|
||||
modprobe sk98lin parameter=value1[,value2[,value3...]]
|
||||
|
||||
where value1 refers to the first adapter, value2 to the second etc.
|
||||
|
||||
NOTE: All parameters are case sensitive. Write them exactly as shown
|
||||
below.
|
||||
|
||||
Example:
|
||||
Suppose you have two adapters. You want to set auto-negotiation
|
||||
on the first adapter to ON and on the second adapter to OFF.
|
||||
You also want to set DuplexCapabilities on the first adapter
|
||||
to FULL, and on the second adapter to HALF.
|
||||
Then, you must enter:
|
||||
|
||||
modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half
|
||||
|
||||
NOTE: The number of adapters that can be configured this way is
|
||||
limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM).
|
||||
The current limit is 16. If you happen to install
|
||||
more adapters, adjust this and recompile.
|
||||
|
||||
|
||||
4.1 Per-Port Parameters
|
||||
------------------------
|
||||
|
||||
These settings are available for each port on the adapter.
|
||||
In the following description, '?' stands for the port for
|
||||
which you set the parameter (A or B).
|
||||
|
||||
Speed
|
||||
-----
|
||||
Parameter: Speed_?
|
||||
Values: 10, 100, 1000, Auto
|
||||
Default: Auto
|
||||
|
||||
This parameter is used to set the speed capabilities. It is only valid
|
||||
for the SK-98xx V2.0 copper adapters.
|
||||
Usually, the speed is negotiated between the two ports during link
|
||||
establishment. If this fails, a port can be forced to a specific setting
|
||||
with this parameter.
|
||||
|
||||
Auto-Negotiation
|
||||
----------------
|
||||
Parameter: AutoNeg_?
|
||||
Values: On, Off, Sense
|
||||
Default: On
|
||||
|
||||
The "Sense"-mode automatically detects whether the link partner supports
|
||||
auto-negotiation or not.
|
||||
|
||||
Duplex Capabilities
|
||||
-------------------
|
||||
Parameter: DupCap_?
|
||||
Values: Half, Full, Both
|
||||
Default: Both
|
||||
|
||||
This parameters is only relevant if auto-negotiation for this port is
|
||||
not set to "Sense". If auto-negotiation is set to "On", all three values
|
||||
are possible. If it is set to "Off", only "Full" and "Half" are allowed.
|
||||
This parameter is useful if your link partner does not support all
|
||||
possible combinations.
|
||||
|
||||
Flow Control
|
||||
------------
|
||||
Parameter: FlowCtrl_?
|
||||
Values: Sym, SymOrRem, LocSend, None
|
||||
Default: SymOrRem
|
||||
|
||||
This parameter can be used to set the flow control capabilities the
|
||||
port reports during auto-negotiation. It can be set for each port
|
||||
individually.
|
||||
Possible modes:
|
||||
-- Sym = Symmetric: both link partners are allowed to send
|
||||
PAUSE frames
|
||||
-- SymOrRem = SymmetricOrRemote: both or only remote partner
|
||||
are allowed to send PAUSE frames
|
||||
-- LocSend = LocalSend: only local link partner is allowed
|
||||
to send PAUSE frames
|
||||
-- None = no link partner is allowed to send PAUSE frames
|
||||
|
||||
NOTE: This parameter is ignored if auto-negotiation is set to "Off".
|
||||
|
||||
Role in Master-Slave-Negotiation (1000Base-T only)
|
||||
--------------------------------------------------
|
||||
Parameter: Role_?
|
||||
Values: Auto, Master, Slave
|
||||
Default: Auto
|
||||
|
||||
This parameter is only valid for the SK-9821 and SK-9822 adapters.
|
||||
For two 1000Base-T ports to communicate, one must take the role of the
|
||||
master (providing timing information), while the other must be the
|
||||
slave. Usually, this is negotiated between the two ports during link
|
||||
establishment. If this fails, a port can be forced to a specific setting
|
||||
with this parameter.
|
||||
|
||||
|
||||
4.2 Adapter Parameters
|
||||
-----------------------
|
||||
|
||||
Connection Type (SK-98xx V2.0 copper adapters only)
|
||||
---------------
|
||||
Parameter: ConType
|
||||
Values: Auto, 100FD, 100HD, 10FD, 10HD
|
||||
Default: Auto
|
||||
|
||||
The parameter 'ConType' is a combination of all five per-port parameters
|
||||
within one single parameter. This simplifies the configuration of both ports
|
||||
of an adapter card! The different values of this variable reflect the most
|
||||
meaningful combinations of port parameters.
|
||||
|
||||
The following table shows the values of 'ConType' and the corresponding
|
||||
combinations of the per-port parameters:
|
||||
|
||||
ConType | DupCap AutoNeg FlowCtrl Role Speed
|
||||
----------+------------------------------------------------------
|
||||
Auto | Both On SymOrRem Auto Auto
|
||||
100FD | Full Off None Auto (ignored) 100
|
||||
100HD | Half Off None Auto (ignored) 100
|
||||
10FD | Full Off None Auto (ignored) 10
|
||||
10HD | Half Off None Auto (ignored) 10
|
||||
|
||||
Stating any other port parameter together with this 'ConType' variable
|
||||
will result in a merged configuration of those settings. This due to
|
||||
the fact, that the per-port parameters (e.g. Speed_? ) have a higher
|
||||
priority than the combined variable 'ConType'.
|
||||
|
||||
NOTE: This parameter is always used on both ports of the adapter card.
|
||||
|
||||
Interrupt Moderation
|
||||
--------------------
|
||||
Parameter: Moderation
|
||||
Values: None, Static, Dynamic
|
||||
Default: None
|
||||
|
||||
Interrupt moderation is employed to limit the maximum number of interrupts
|
||||
the driver has to serve. That is, one or more interrupts (which indicate any
|
||||
transmit or receive packet to be processed) are queued until the driver
|
||||
processes them. When queued interrupts are to be served, is determined by the
|
||||
'IntsPerSec' parameter, which is explained later below.
|
||||
|
||||
Possible modes:
|
||||
|
||||
-- None - No interrupt moderation is applied on the adapter card.
|
||||
Therefore, each transmit or receive interrupt is served immediately
|
||||
as soon as it appears on the interrupt line of the adapter card.
|
||||
|
||||
-- Static - Interrupt moderation is applied on the adapter card.
|
||||
All transmit and receive interrupts are queued until a complete
|
||||
moderation interval ends. If such a moderation interval ends, all
|
||||
queued interrupts are processed in one big bunch without any delay.
|
||||
The term 'static' reflects the fact, that interrupt moderation is
|
||||
always enabled, regardless how much network load is currently
|
||||
passing via a particular interface. In addition, the duration of
|
||||
the moderation interval has a fixed length that never changes while
|
||||
the driver is operational.
|
||||
|
||||
-- Dynamic - Interrupt moderation might be applied on the adapter card,
|
||||
depending on the load of the system. If the driver detects that the
|
||||
system load is too high, the driver tries to shield the system against
|
||||
too much network load by enabling interrupt moderation. If - at a later
|
||||
time - the CPU utilization decreases again (or if the network load is
|
||||
negligible) the interrupt moderation will automatically be disabled.
|
||||
|
||||
Interrupt moderation should be used when the driver has to handle one or more
|
||||
interfaces with a high network load, which - as a consequence - leads also to a
|
||||
high CPU utilization. When moderation is applied in such high network load
|
||||
situations, CPU load might be reduced by 20-30%.
|
||||
|
||||
NOTE: The drawback of using interrupt moderation is an increase of the round-
|
||||
trip-time (RTT), due to the queueing and serving of interrupts at dedicated
|
||||
moderation times.
|
||||
|
||||
Interrupts per second
|
||||
---------------------
|
||||
Parameter: IntsPerSec
|
||||
Values: 30...40000 (interrupts per second)
|
||||
Default: 2000
|
||||
|
||||
This parameter is only used if either static or dynamic interrupt moderation
|
||||
is used on a network adapter card. Using this parameter if no moderation is
|
||||
applied will lead to no action performed.
|
||||
|
||||
This parameter determines the length of any interrupt moderation interval.
|
||||
Assuming that static interrupt moderation is to be used, an 'IntsPerSec'
|
||||
parameter value of 2000 will lead to an interrupt moderation interval of
|
||||
500 microseconds.
|
||||
|
||||
NOTE: The duration of the moderation interval is to be chosen with care.
|
||||
At first glance, selecting a very long duration (e.g. only 100 interrupts per
|
||||
second) seems to be meaningful, but the increase of packet-processing delay
|
||||
is tremendous. On the other hand, selecting a very short moderation time might
|
||||
compensate the use of any moderation being applied.
|
||||
|
||||
|
||||
Preferred Port
|
||||
--------------
|
||||
Parameter: PrefPort
|
||||
Values: A, B
|
||||
Default: A
|
||||
|
||||
This is used to force the preferred port to A or B (on dual-port network
|
||||
adapters). The preferred port is the one that is used if both are detected
|
||||
as fully functional.
|
||||
|
||||
RLMT Mode (Redundant Link Management Technology)
|
||||
------------------------------------------------
|
||||
Parameter: RlmtMode
|
||||
Values: CheckLinkState,CheckLocalPort, CheckSeg, DualNet
|
||||
Default: CheckLinkState
|
||||
|
||||
RLMT monitors the status of the port. If the link of the active port
|
||||
fails, RLMT switches immediately to the standby link. The virtual link is
|
||||
maintained as long as at least one 'physical' link is up.
|
||||
|
||||
Possible modes:
|
||||
|
||||
-- CheckLinkState - Check link state only: RLMT uses the link state
|
||||
reported by the adapter hardware for each individual port to
|
||||
determine whether a port can be used for all network traffic or
|
||||
not.
|
||||
|
||||
-- CheckLocalPort - In this mode, RLMT monitors the network path
|
||||
between the two ports of an adapter by regularly exchanging packets
|
||||
between them. This mode requires a network configuration in which
|
||||
the two ports are able to "see" each other (i.e. there must not be
|
||||
any router between the ports).
|
||||
|
||||
-- CheckSeg - Check local port and segmentation: This mode supports the
|
||||
same functions as the CheckLocalPort mode and additionally checks
|
||||
network segmentation between the ports. Therefore, this mode is only
|
||||
to be used if Gigabit Ethernet switches are installed on the network
|
||||
that have been configured to use the Spanning Tree protocol.
|
||||
|
||||
-- DualNet - In this mode, ports A and B are used as separate devices.
|
||||
If you have a dual port adapter, port A will be configured as eth0
|
||||
and port B as eth1. Both ports can be used independently with
|
||||
distinct IP addresses. The preferred port setting is not used.
|
||||
RLMT is turned off.
|
||||
|
||||
NOTE: RLMT modes CLP and CLPSS are designed to operate in configurations
|
||||
where a network path between the ports on one adapter exists.
|
||||
Moreover, they are not designed to work where adapters are connected
|
||||
back-to-back.
|
||||
***
|
||||
|
||||
|
||||
5 Large Frame Support
|
||||
======================
|
||||
|
||||
The driver supports large frames (also called jumbo frames). Using large
|
||||
frames can result in an improved throughput if transferring large amounts
|
||||
of data.
|
||||
To enable large frames, set the MTU (maximum transfer unit) of the
|
||||
interface to the desired value (up to 9000), execute the following
|
||||
command:
|
||||
ifconfig eth0 mtu 9000
|
||||
This will only work if you have two adapters connected back-to-back
|
||||
or if you use a switch that supports large frames. When using a switch,
|
||||
it should be configured to allow large frames and auto-negotiation should
|
||||
be set to OFF. The setting must be configured on all adapters that can be
|
||||
reached by the large frames. If one adapter is not set to receive large
|
||||
frames, it will simply drop them.
|
||||
|
||||
You can switch back to the standard ethernet frame size by executing the
|
||||
following command:
|
||||
ifconfig eth0 mtu 1500
|
||||
|
||||
To permanently configure this setting, add a script with the 'ifconfig'
|
||||
line to the system startup sequence (named something like "S99sk98lin"
|
||||
in /etc/rc.d/rc2.d).
|
||||
***
|
||||
|
||||
|
||||
6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
|
||||
==================================================================
|
||||
|
||||
The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and
|
||||
Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad.
|
||||
These features are only available after installation of open source
|
||||
modules available on the Internet:
|
||||
For VLAN go to: http://www.candelatech.com/~greear/vlan.html
|
||||
For Link Aggregation go to: http://www.st.rim.or.jp/~yumo
|
||||
|
||||
NOTE: SysKonnect GmbH does not offer any support for these open source
|
||||
modules and does not take the responsibility for any kind of
|
||||
failures or problems arising in connection with these modules.
|
||||
|
||||
NOTE: Configuring Link Aggregation on a SysKonnect dual link adapter may
|
||||
cause problems when unloading the driver.
|
||||
|
||||
|
||||
7 Troubleshooting
|
||||
==================
|
||||
|
||||
If any problems occur during the installation process, check the
|
||||
following list:
|
||||
|
||||
|
||||
Problem: The SK-98xx adapter cannot be found by the driver.
|
||||
Solution: In /proc/pci search for the following entry:
|
||||
'Ethernet controller: SysKonnect SK-98xx ...'
|
||||
If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has
|
||||
been found by the system and should be operational.
|
||||
If this entry does not exist or if the file '/proc/pci' is not
|
||||
found, there may be a hardware problem or the PCI support may
|
||||
not be enabled in your kernel.
|
||||
The adapter can be checked using the diagnostics program which
|
||||
is available on the SysKonnect web site:
|
||||
www.syskonnect.com
|
||||
|
||||
Some COMPAQ machines have problems dealing with PCI under Linux.
|
||||
This problem is described in the 'PCI howto' document
|
||||
(included in some distributions or available from the
|
||||
web, e.g. at 'www.linux.org').
|
||||
|
||||
|
||||
Problem: Programs such as 'ifconfig' or 'route' cannot be found or the
|
||||
error message 'Operation not permitted' is displayed.
|
||||
Reason: You are not logged in as user 'root'.
|
||||
Solution: Logout and login as 'root' or change to 'root' via 'su'.
|
||||
|
||||
|
||||
Problem: Upon use of the command 'ping <address>' the message
|
||||
"ping: sendto: Network is unreachable" is displayed.
|
||||
Reason: Your route is not set correctly.
|
||||
Solution: If you are using RedHat, you probably forgot to set up the
|
||||
route in the 'network configuration'.
|
||||
Check the existing routes with the 'route' command and check
|
||||
if an entry for 'eth0' exists, and if so, if it is set correctly.
|
||||
|
||||
|
||||
Problem: The driver can be started, the adapter is connected to the
|
||||
network, but you cannot receive or transmit any packets;
|
||||
e.g. 'ping' does not work.
|
||||
Reason: There is an incorrect route in your routing table.
|
||||
Solution: Check the routing table with the command 'route' and read the
|
||||
manual help pages dealing with routes (enter 'man route').
|
||||
|
||||
NOTE: Although the 2.2.x kernel versions generate the routing entry
|
||||
automatically, problems of this kind may occur here as well. We've
|
||||
come across a situation in which the driver started correctly at
|
||||
system start, but after the driver has been removed and reloaded,
|
||||
the route of the adapter's network pointed to the 'dummy0'device
|
||||
and had to be corrected manually.
|
||||
|
||||
|
||||
Problem: Your computer should act as a router between multiple
|
||||
IP subnetworks (using multiple adapters), but computers in
|
||||
other subnetworks cannot be reached.
|
||||
Reason: Either the router's kernel is not configured for IP forwarding
|
||||
or the routing table and gateway configuration of at least one
|
||||
computer is not working.
|
||||
|
||||
Problem: Upon driver start, the following error message is displayed:
|
||||
"eth0: -- ERROR --
|
||||
Class: internal Software error
|
||||
Nr: 0xcc
|
||||
Msg: SkGeInitPort() cannot init running ports"
|
||||
Reason: You are using a driver compiled for single processor machines
|
||||
on a multiprocessor machine with SMP (Symmetric MultiProcessor)
|
||||
kernel.
|
||||
Solution: Configure your kernel appropriately and recompile the kernel or
|
||||
the modules.
|
||||
|
||||
|
||||
|
||||
If your problem is not listed here, please contact SysKonnect's technical
|
||||
support for help (linux@syskonnect.de).
|
||||
When contacting our technical support, please ensure that the following
|
||||
information is available:
|
||||
- System Manufacturer and HW Informations (CPU, Memory... )
|
||||
- PCI-Boards in your system
|
||||
- Distribution
|
||||
- Kernel version
|
||||
- Driver version
|
||||
***
|
||||
|
||||
|
||||
|
||||
***End of Readme File***
|
|
@ -1,7 +1,7 @@
|
|||
ThinkPad ACPI Extras Driver
|
||||
|
||||
Version 0.15
|
||||
July 1st, 2007
|
||||
Version 0.16
|
||||
August 2nd, 2007
|
||||
|
||||
Borislav Deianov <borislav@users.sf.net>
|
||||
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||
|
@ -161,20 +161,22 @@ system. Enabling the hotkey functionality of thinkpad-acpi signals the
|
|||
firmware that such a driver is present, and modifies how the ThinkPad
|
||||
firmware will behave in many situations.
|
||||
|
||||
The driver enables the hot key feature automatically when loaded. The
|
||||
feature can later be disabled and enabled back at runtime. The driver
|
||||
will also restore the hot key feature to its previous state and mask
|
||||
when it is unloaded.
|
||||
|
||||
When the hotkey feature is enabled and the hot key mask is set (see
|
||||
below), the various hot keys either generate ACPI events in the
|
||||
following format:
|
||||
below), the driver will report HKEY events in the following format:
|
||||
|
||||
ibm/hotkey HKEY 00000080 0000xxxx
|
||||
|
||||
or events over the input layer. The input layer support accepts the
|
||||
standard IOCTLs to remap the keycodes assigned to each hotkey.
|
||||
Some of these events refer to hot key presses, but not all.
|
||||
|
||||
When the input device is open, the driver will suppress any ACPI hot key
|
||||
events that get translated into a meaningful input layer event, in order
|
||||
to avoid sending duplicate events to userspace. Hot keys that are
|
||||
mapped to KEY_RESERVED in the keymap are not translated, and will always
|
||||
generate an ACPI ibm/hotkey HKEY event, and no input layer events.
|
||||
The driver will generate events over the input layer for hot keys and
|
||||
radio switches, and over the ACPI netlink layer for other events. The
|
||||
input layer support accepts the standard IOCTLs to remap the keycodes
|
||||
assigned to each hot key.
|
||||
|
||||
The hot key bit mask allows some control over which hot keys generate
|
||||
events. If a key is "masked" (bit set to 0 in the mask), the firmware
|
||||
|
@ -256,6 +258,20 @@ sysfs notes:
|
|||
disabled" postition, and 1 if the switch is in the
|
||||
"radios enabled" position.
|
||||
|
||||
hotkey_report_mode:
|
||||
Returns the state of the procfs ACPI event report mode
|
||||
filter for hot keys. If it is set to 1 (the default),
|
||||
all hot key presses are reported both through the input
|
||||
layer and also as ACPI events through procfs (but not
|
||||
through netlink). If it is set to 2, hot key presses
|
||||
are reported only through the input layer.
|
||||
|
||||
This attribute is read-only in kernels 2.6.23 or later,
|
||||
and read-write on earlier kernels.
|
||||
|
||||
May return -EPERM (write access locked out by module
|
||||
parameter) or -EACCES (read-only).
|
||||
|
||||
input layer notes:
|
||||
|
||||
A Hot key is mapped to a single input layer EV_KEY event, possibly
|
||||
|
@ -393,21 +409,63 @@ unknown by the driver if the ThinkPad firmware triggered these events on
|
|||
hot key press or release, but the firmware will do it for either one, not
|
||||
both.
|
||||
|
||||
If a key is mapped to KEY_RESERVED, it generates no input events at all,
|
||||
and it may generate a legacy thinkpad-acpi ACPI hotkey event.
|
||||
|
||||
If a key is mapped to KEY_RESERVED, it generates no input events at all.
|
||||
If a key is mapped to KEY_UNKNOWN, it generates an input event that
|
||||
includes an scan code, and it may also generate a legacy thinkpad-acpi
|
||||
ACPI hotkey event.
|
||||
|
||||
If a key is mapped to anything else, it will only generate legacy
|
||||
thinkpad-acpi ACPI hotkey events if nobody has opened the input device.
|
||||
includes an scan code. If a key is mapped to anything else, it will
|
||||
generate input device EV_KEY events.
|
||||
|
||||
Non hot-key ACPI HKEY event map:
|
||||
0x5001 Lid closed
|
||||
0x5002 Lid opened
|
||||
0x7000 Radio Switch may have changed state
|
||||
|
||||
The above events are not propagated by the driver, except for legacy
|
||||
compatibility purposes when hotkey_report_mode is set to 1.
|
||||
|
||||
Compatibility notes:
|
||||
|
||||
ibm-acpi and thinkpad-acpi 0.15 (mainline kernels before 2.6.23) never
|
||||
supported the input layer, and sent events over the procfs ACPI event
|
||||
interface.
|
||||
|
||||
To avoid sending duplicate events over the input layer and the ACPI
|
||||
event interface, thinkpad-acpi 0.16 implements a module parameter
|
||||
(hotkey_report_mode), and also a sysfs device attribute with the same
|
||||
name.
|
||||
|
||||
Make no mistake here: userspace is expected to switch to using the input
|
||||
layer interface of thinkpad-acpi, together with the ACPI netlink event
|
||||
interface in kernels 2.6.23 and later, or with the ACPI procfs event
|
||||
interface in kernels 2.6.22 and earlier.
|
||||
|
||||
If no hotkey_report_mode module parameter is specified (or it is set to
|
||||
zero), the driver defaults to mode 1 (see below), and on kernels 2.6.22
|
||||
and earlier, also allows one to change the hotkey_report_mode through
|
||||
sysfs. In kernels 2.6.23 and later, where the netlink ACPI event
|
||||
interface is available, hotkey_report_mode cannot be changed through
|
||||
sysfs (it is read-only).
|
||||
|
||||
If the hotkey_report_mode module parameter is set to 1 or 2, it cannot
|
||||
be changed later through sysfs (any writes will return -EPERM to signal
|
||||
that hotkey_report_mode was locked. On 2.6.23 and later, where
|
||||
hotkey_report_mode cannot be changed at all, writes will return -EACES).
|
||||
|
||||
hotkey_report_mode set to 1 makes the driver export through the procfs
|
||||
ACPI event interface all hot key presses (which are *also* sent to the
|
||||
input layer). This is a legacy compatibility behaviour, and it is also
|
||||
the default mode of operation for the driver.
|
||||
|
||||
hotkey_report_mode set to 2 makes the driver filter out the hot key
|
||||
presses from the procfs ACPI event interface, so these events will only
|
||||
be sent through the input layer. Userspace that has been updated to use
|
||||
the thinkpad-acpi input layer interface should set hotkey_report_mode to
|
||||
2.
|
||||
|
||||
Hot key press events are never sent to the ACPI netlink event interface.
|
||||
Really up-to-date userspace under kernel 2.6.23 and later is to use the
|
||||
netlink interface and the input layer interface, and don't bother at all
|
||||
with hotkey_report_mode.
|
||||
|
||||
|
||||
Bluetooth
|
||||
---------
|
||||
|
|
|
@ -407,8 +407,10 @@ Description
|
|||
u32 length; // Length of this frame
|
||||
u32 offset_low; // Offset in the file of the
|
||||
u32 offset_high; // start of this frame
|
||||
u32 mask1; // Bits 0-1 are the type mask:
|
||||
u32 mask1; // Bits 0-2 are the type mask:
|
||||
// 1=I, 2=P, 4=B
|
||||
// 0=End of Program Index, other fields
|
||||
// are invalid.
|
||||
u32 pts; // The PTS of the frame
|
||||
u32 mask2; // Bit 0 is bit 32 of the pts.
|
||||
};
|
||||
|
|
|
@ -165,7 +165,7 @@ static void __init gic_init_irq(void)
|
|||
#endif
|
||||
gic_dist_init(0, __io_address(REALVIEW_GIC_DIST_BASE), 29);
|
||||
gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE));
|
||||
#ifdef CONFIG_REALVIEW_MPCORE
|
||||
#if defined(CONFIG_REALVIEW_MPCORE) && !defined(CONFIG_REALVIEW_MPCORE_REVB)
|
||||
gic_dist_init(1, __io_address(REALVIEW_GIC1_DIST_BASE), 64);
|
||||
gic_cpu_init(1, __io_address(REALVIEW_GIC1_CPU_BASE));
|
||||
gic_cascade_irq(1, IRQ_EB_IRQ1);
|
||||
|
|
|
@ -323,6 +323,7 @@ static int __init vfp_init(void)
|
|||
* we just need to read the VFPSID register.
|
||||
*/
|
||||
vfp_vector = vfp_testing_entry;
|
||||
barrier();
|
||||
vfpsid = fmrx(FPSID);
|
||||
barrier();
|
||||
vfp_vector = vfp_null_entry;
|
||||
|
|
|
@ -158,10 +158,16 @@ static int bfin_pm_finish(suspend_state_t state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bfin_pm_valid(suspend_state_t state)
|
||||
{
|
||||
return (state == PM_SUSPEND_STANDBY);
|
||||
}
|
||||
|
||||
struct pm_ops bfin_pm_ops = {
|
||||
.prepare = bfin_pm_prepare,
|
||||
.enter = bfin_pm_enter,
|
||||
.finish = bfin_pm_finish,
|
||||
.valid = bfin_pm_valid,
|
||||
};
|
||||
|
||||
static int __init bfin_pm_init(void)
|
||||
|
|
|
@ -623,8 +623,8 @@ static unsigned long xen_read_cr2_direct(void)
|
|||
|
||||
static void xen_write_cr4(unsigned long cr4)
|
||||
{
|
||||
/* never allow TSC to be disabled */
|
||||
native_write_cr4(cr4 & ~X86_CR4_TSD);
|
||||
/* Just ignore cr4 changes; Xen doesn't allow us to do
|
||||
anything anyway. */
|
||||
}
|
||||
|
||||
static unsigned long xen_read_cr3(void)
|
||||
|
|
|
@ -55,7 +55,7 @@ EXPORT_SYMBOL(dec_kn_slot_size);
|
|||
|
||||
int dec_tc_bus;
|
||||
|
||||
spinlock_t ioasic_ssr_lock;
|
||||
DEFINE_SPINLOCK(ioasic_ssr_lock);
|
||||
|
||||
volatile u32 *ioasic_base;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2003, 2004 Maciej W. Rozycki
|
||||
* Copyright (C) 2003, 2004, 2007 Maciej W. Rozycki
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -29,7 +29,7 @@ static inline void align_mod(const int align, const int mod)
|
|||
".endr\n\t"
|
||||
".set pop"
|
||||
:
|
||||
: "rn" (align), "rn" (mod));
|
||||
: GCC_IMM_ASM (align), GCC_IMM_ASM (mod));
|
||||
}
|
||||
|
||||
static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
|
||||
|
|
|
@ -199,7 +199,14 @@ static inline void check_wait(void)
|
|||
if ((c->processor_id & 0xff) <= 0x64)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Another rev is incremeting c0_count at a reduced clock
|
||||
* rate while in WAIT mode. So we basically have the choice
|
||||
* between using the cp0 timer as clocksource or avoiding
|
||||
* the WAIT instruction. Until more details are known,
|
||||
* disable the use of WAIT for 20Kc entirely.
|
||||
cpu_wait = r4k_wait;
|
||||
*/
|
||||
break;
|
||||
case CPU_RM9000:
|
||||
if ((c->processor_id & 0x00ff) >= 0x40)
|
||||
|
|
|
@ -56,8 +56,6 @@ static struct chan_waitqueues {
|
|||
struct mutex mutex;
|
||||
} channel_wqs[RTLX_CHANNELS];
|
||||
|
||||
static struct irqaction irq;
|
||||
static int irq_num;
|
||||
static struct vpe_notifications notify;
|
||||
static int sp_stopping = 0;
|
||||
|
||||
|
@ -111,7 +109,7 @@ static void __used dump_rtlx(void)
|
|||
static int rtlx_init(struct rtlx_info *rtlxi)
|
||||
{
|
||||
if (rtlxi->id != RTLX_ID) {
|
||||
printk(KERN_ERR "no valid RTLX id at 0x%p 0x%x\n", rtlxi, rtlxi->id);
|
||||
printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n", rtlxi, rtlxi->id);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ EXPORT(sysn32_call_table)
|
|||
PTR sys_mkdirat
|
||||
PTR sys_mknodat
|
||||
PTR sys_fchownat
|
||||
PTR sys_futimesat /* 6255 */
|
||||
PTR compat_sys_futimesat /* 6255 */
|
||||
PTR sys_newfstatat
|
||||
PTR sys_unlinkat
|
||||
PTR sys_renameat
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/param.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/smp.h>
|
||||
|
|
|
@ -256,7 +256,7 @@ asmlinkage void plat_irq_dispatch(void)
|
|||
|
||||
if (irq == MIPSCPU_INT_I8259A)
|
||||
malta_hw0_irqdispatch();
|
||||
else if (irq > 0)
|
||||
else if (irq >= 0)
|
||||
do_IRQ(MIPS_CPU_IRQ_BASE + irq);
|
||||
else
|
||||
spurious_interrupt();
|
||||
|
|
|
@ -57,6 +57,21 @@ static __init int __maybe_unused r10000_llsc_war(void)
|
|||
return R10000_LLSC_WAR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Found by experiment: At least some revisions of the 4kc throw under
|
||||
* some circumstances a machine check exception, triggered by invalid
|
||||
* values in the index register. Delaying the tlbp instruction until
|
||||
* after the next branch, plus adding an additional nop in front of
|
||||
* tlbwi/tlbwr avoids the invalid index register values. Nobody knows
|
||||
* why; it's not an issue caused by the core RTL.
|
||||
*
|
||||
*/
|
||||
static __init int __attribute__((unused)) m4kc_tlbp_war(void)
|
||||
{
|
||||
return (current_cpu_data.processor_id & 0xffff00) ==
|
||||
(PRID_COMP_MIPS | PRID_IMP_4KC);
|
||||
}
|
||||
|
||||
/*
|
||||
* A little micro-assembler, intended for TLB refill handler
|
||||
* synthesizing. It is intentionally kept simple, does only support
|
||||
|
@ -894,6 +909,8 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
|
|||
case CPU_20KC:
|
||||
case CPU_25KF:
|
||||
case CPU_LOONGSON2:
|
||||
if (m4kc_tlbp_war())
|
||||
i_nop(p);
|
||||
tlbw(p);
|
||||
break;
|
||||
|
||||
|
@ -1705,6 +1722,7 @@ build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
|
|||
l_smp_pgtable_change(l, *p);
|
||||
# endif
|
||||
iPTE_LW(p, l, pte, ptr); /* get even pte */
|
||||
if (!m4kc_tlbp_war())
|
||||
build_tlb_probe_entry(p);
|
||||
}
|
||||
|
||||
|
@ -1747,6 +1765,8 @@ static void __init build_r4000_tlb_load_handler(void)
|
|||
|
||||
build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
|
||||
build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
|
||||
if (m4kc_tlbp_war())
|
||||
build_tlb_probe_entry(&p);
|
||||
build_make_valid(&p, &r, K0, K1);
|
||||
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
|
||||
|
||||
|
@ -1781,6 +1801,8 @@ static void __init build_r4000_tlb_store_handler(void)
|
|||
|
||||
build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
|
||||
build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
|
||||
if (m4kc_tlbp_war())
|
||||
build_tlb_probe_entry(&p);
|
||||
build_make_write(&p, &r, K0, K1);
|
||||
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
|
||||
|
||||
|
@ -1815,6 +1837,8 @@ static void __init build_r4000_tlb_modify_handler(void)
|
|||
|
||||
build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
|
||||
build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
|
||||
if (m4kc_tlbp_war())
|
||||
build_tlb_probe_entry(&p);
|
||||
/* Present and writable bits set, set accessed and dirty bits. */
|
||||
build_make_write(&p, &r, K0, K1);
|
||||
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
|
||||
|
|
|
@ -238,7 +238,7 @@ static void snapshot_tb_and_purr(void *data)
|
|||
struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
|
||||
|
||||
local_irq_save(flags);
|
||||
p->tb = mftb();
|
||||
p->tb = get_tb_or_rtc();
|
||||
p->purr = mfspr(SPRN_PURR);
|
||||
wmb();
|
||||
p->initialized = 1;
|
||||
|
@ -316,7 +316,7 @@ static void snapshot_purr(void)
|
|||
*/
|
||||
void snapshot_timebase(void)
|
||||
{
|
||||
__get_cpu_var(last_jiffy) = get_tb();
|
||||
__get_cpu_var(last_jiffy) = get_tb_or_rtc();
|
||||
snapshot_purr();
|
||||
}
|
||||
|
||||
|
@ -683,6 +683,8 @@ void timer_interrupt(struct pt_regs * regs)
|
|||
|
||||
write_seqlock(&xtime_lock);
|
||||
tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
|
||||
if (__USE_RTC() && tb_next_jiffy >= 1000000000)
|
||||
tb_next_jiffy -= 1000000000;
|
||||
if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
|
||||
tb_last_jiffy = tb_next_jiffy;
|
||||
do_timer(1);
|
||||
|
@ -976,7 +978,7 @@ void __init time_init(void)
|
|||
tb_to_ns_scale = scale;
|
||||
tb_to_ns_shift = shift;
|
||||
/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
|
||||
boot_tb = get_tb();
|
||||
boot_tb = get_tb_or_rtc();
|
||||
|
||||
tm = get_boot_time();
|
||||
|
||||
|
|
|
@ -98,6 +98,18 @@ static struct vdso_patch_def vdso_patches[] = {
|
|||
CPU_FTR_USE_TB, 0,
|
||||
"__kernel_gettimeofday", NULL
|
||||
},
|
||||
{
|
||||
CPU_FTR_USE_TB, 0,
|
||||
"__kernel_clock_gettime", NULL
|
||||
},
|
||||
{
|
||||
CPU_FTR_USE_TB, 0,
|
||||
"__kernel_clock_getres", NULL
|
||||
},
|
||||
{
|
||||
CPU_FTR_USE_TB, 0,
|
||||
"__kernel_get_tbfreq", NULL
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -594,7 +594,7 @@ static struct spu *find_victim(struct spu_context *ctx)
|
|||
list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) {
|
||||
struct spu_context *tmp = spu->ctx;
|
||||
|
||||
if (tmp->prio > ctx->prio &&
|
||||
if (tmp && tmp->prio > ctx->prio &&
|
||||
(!victim || tmp->prio > victim->prio))
|
||||
victim = spu->ctx;
|
||||
}
|
||||
|
@ -626,9 +626,9 @@ static struct spu *find_victim(struct spu_context *ctx)
|
|||
|
||||
mutex_lock(&cbe_spu_info[node].list_mutex);
|
||||
cbe_spu_info[node].nr_active--;
|
||||
spu_unbind_context(spu, victim);
|
||||
mutex_unlock(&cbe_spu_info[node].list_mutex);
|
||||
|
||||
spu_unbind_context(spu, victim);
|
||||
victim->stats.invol_ctx_switch++;
|
||||
spu->stats.invol_ctx_switch++;
|
||||
mutex_unlock(&victim->state_mutex);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.23-rc1
|
||||
# Sun Jul 22 19:24:37 2007
|
||||
# Linux kernel version: 2.6.23-rc6
|
||||
# Sun Sep 16 09:52:11 2007
|
||||
#
|
||||
CONFIG_SPARC=y
|
||||
CONFIG_SPARC64=y
|
||||
|
@ -32,15 +32,11 @@ CONFIG_HZ=100
|
|||
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
|
||||
|
||||
#
|
||||
# Code maturity level options
|
||||
# General setup
|
||||
#
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_BROKEN_ON_SMP=y
|
||||
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_LOCALVERSION=""
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SWAP=y
|
||||
|
@ -555,6 +551,7 @@ CONFIG_E1000_NAPI=y
|
|||
# CONFIG_SIS190 is not set
|
||||
# CONFIG_SKGE is not set
|
||||
# CONFIG_SKY2 is not set
|
||||
# CONFIG_SK98LIN is not set
|
||||
# CONFIG_VIA_VELOCITY is not set
|
||||
CONFIG_TIGON3=m
|
||||
CONFIG_BNX2=m
|
||||
|
@ -809,6 +806,7 @@ CONFIG_HWMON=y
|
|||
# CONFIG_SENSORS_SMSC47M1 is not set
|
||||
# CONFIG_SENSORS_SMSC47M192 is not set
|
||||
# CONFIG_SENSORS_SMSC47B397 is not set
|
||||
# CONFIG_SENSORS_THMC50 is not set
|
||||
# CONFIG_SENSORS_VIA686A is not set
|
||||
# CONFIG_SENSORS_VT1211 is not set
|
||||
# CONFIG_SENSORS_VT8231 is not set
|
||||
|
@ -1162,10 +1160,6 @@ CONFIG_USB_STORAGE=m
|
|||
# CONFIG_MMC is not set
|
||||
# CONFIG_NEW_LEDS is not set
|
||||
# CONFIG_INFINIBAND is not set
|
||||
|
||||
#
|
||||
# Real Time Clock
|
||||
#
|
||||
# CONFIG_RTC_CLASS is not set
|
||||
|
||||
#
|
||||
|
|
|
@ -98,7 +98,7 @@ sparc64_boot:
|
|||
.globl prom_boot_mapped_pc, prom_boot_mapping_mode
|
||||
.globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
|
||||
.globl prom_compatible_name, prom_cpu_path, prom_cpu_compatible
|
||||
.globl is_sun4v, sun4v_chip_type
|
||||
.globl is_sun4v, sun4v_chip_type, prom_set_trap_table_name
|
||||
prom_peer_name:
|
||||
.asciz "peer"
|
||||
prom_compatible_name:
|
||||
|
@ -121,6 +121,8 @@ prom_map_name:
|
|||
.asciz "map"
|
||||
prom_unmap_name:
|
||||
.asciz "unmap"
|
||||
prom_set_trap_table_name:
|
||||
.asciz "SUNW,set-trap-table"
|
||||
prom_sun4v_name:
|
||||
.asciz "sun4v"
|
||||
prom_niagara_prefix:
|
||||
|
@ -691,15 +693,38 @@ setup_trap_table:
|
|||
sethi %hi(kern_base), %g3
|
||||
ldx [%g3 + %lo(kern_base)], %g3
|
||||
add %g2, %g3, %o1
|
||||
|
||||
call prom_set_trap_table_sun4v
|
||||
sethi %hi(sparc64_ttable_tl0), %o0
|
||||
|
||||
set prom_set_trap_table_name, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x00]
|
||||
mov 2, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x08]
|
||||
mov 0, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x10]
|
||||
stx %o0, [%sp + 2047 + 128 + 0x18]
|
||||
stx %o1, [%sp + 2047 + 128 + 0x20]
|
||||
sethi %hi(p1275buf), %g2
|
||||
or %g2, %lo(p1275buf), %g2
|
||||
ldx [%g2 + 0x08], %o1
|
||||
call %o1
|
||||
add %sp, (2047 + 128), %o0
|
||||
|
||||
ba,pt %xcc, 2f
|
||||
nop
|
||||
|
||||
1: call prom_set_trap_table
|
||||
sethi %hi(sparc64_ttable_tl0), %o0
|
||||
1: sethi %hi(sparc64_ttable_tl0), %o0
|
||||
set prom_set_trap_table_name, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x00]
|
||||
mov 1, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x08]
|
||||
mov 0, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x10]
|
||||
stx %o0, [%sp + 2047 + 128 + 0x18]
|
||||
sethi %hi(p1275buf), %g2
|
||||
or %g2, %lo(p1275buf), %g2
|
||||
ldx [%g2 + 0x08], %o1
|
||||
call %o1
|
||||
add %sp, (2047 + 128), %o0
|
||||
|
||||
/* Start using proper page size encodings in ctx register. */
|
||||
2: sethi %hi(sparc64_kern_pri_context), %g3
|
||||
|
|
|
@ -777,8 +777,12 @@ void __devinit mdesc_fill_in_cpu_data(cpumask_t mask)
|
|||
cpuid = *id;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (cpuid >= NR_CPUS)
|
||||
if (cpuid >= NR_CPUS) {
|
||||
printk(KERN_WARNING "Ignoring CPU %d which is "
|
||||
">= NR_CPUS (%d)\n",
|
||||
cpuid, NR_CPUS);
|
||||
continue;
|
||||
}
|
||||
if (!cpu_isset(cpuid, mask))
|
||||
continue;
|
||||
#else
|
||||
|
|
|
@ -1583,8 +1583,12 @@ static void __init of_fill_in_cpu_data(void)
|
|||
ncpus_probed++;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (cpuid >= NR_CPUS)
|
||||
if (cpuid >= NR_CPUS) {
|
||||
printk(KERN_WARNING "Ignoring CPU %d which is "
|
||||
">= NR_CPUS (%d)\n",
|
||||
cpuid, NR_CPUS);
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
/* On uniprocessor we only want the values for the
|
||||
* real physical cpu the kernel booted onto, however
|
||||
|
|
|
@ -345,7 +345,7 @@ after_lock_tlb:
|
|||
sethi %hi(tramp_stack), %g1
|
||||
or %g1, %lo(tramp_stack), %g1
|
||||
add %g1, TRAMP_STACK_SIZE, %g1
|
||||
sub %g1, STACKFRAME_SZ + STACK_BIAS, %sp
|
||||
sub %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp
|
||||
mov 0, %fp
|
||||
|
||||
/* Put garbage in these registers to trap any access to them. */
|
||||
|
@ -411,15 +411,38 @@ after_lock_tlb:
|
|||
sethi %hi(kern_base), %g3
|
||||
ldx [%g3 + %lo(kern_base)], %g3
|
||||
add %g2, %g3, %o1
|
||||
|
||||
call prom_set_trap_table_sun4v
|
||||
sethi %hi(sparc64_ttable_tl0), %o0
|
||||
|
||||
set prom_set_trap_table_name, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x00]
|
||||
mov 2, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x08]
|
||||
mov 0, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x10]
|
||||
stx %o0, [%sp + 2047 + 128 + 0x18]
|
||||
stx %o1, [%sp + 2047 + 128 + 0x20]
|
||||
sethi %hi(p1275buf), %g2
|
||||
or %g2, %lo(p1275buf), %g2
|
||||
ldx [%g2 + 0x08], %o1
|
||||
call %o1
|
||||
add %sp, (2047 + 128), %o0
|
||||
|
||||
ba,pt %xcc, 2f
|
||||
nop
|
||||
|
||||
1: call prom_set_trap_table
|
||||
sethi %hi(sparc64_ttable_tl0), %o0
|
||||
1: sethi %hi(sparc64_ttable_tl0), %o0
|
||||
set prom_set_trap_table_name, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x00]
|
||||
mov 1, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x08]
|
||||
mov 0, %g2
|
||||
stx %g2, [%sp + 2047 + 128 + 0x10]
|
||||
stx %o0, [%sp + 2047 + 128 + 0x18]
|
||||
sethi %hi(p1275buf), %g2
|
||||
or %g2, %lo(p1275buf), %g2
|
||||
ldx [%g2 + 0x08], %o1
|
||||
call %o1
|
||||
add %sp, (2047 + 128), %o0
|
||||
|
||||
2: ldx [%l0], %g6
|
||||
ldx [%g6 + TI_TASK], %g4
|
||||
|
|
|
@ -143,22 +143,6 @@ unsigned char prom_get_idprom(char *idbuf, int num_bytes)
|
|||
return 0xff;
|
||||
}
|
||||
|
||||
/* Install Linux trap table so PROM uses that instead of its own. */
|
||||
void prom_set_trap_table(unsigned long tba)
|
||||
{
|
||||
p1275_cmd("SUNW,set-trap-table",
|
||||
(P1275_ARG(0, P1275_ARG_IN_64B) |
|
||||
P1275_INOUT(1, 0)), tba);
|
||||
}
|
||||
|
||||
void prom_set_trap_table_sun4v(unsigned long tba, unsigned long mmfsa)
|
||||
{
|
||||
p1275_cmd("SUNW,set-trap-table",
|
||||
(P1275_ARG(0, P1275_ARG_IN_64B) |
|
||||
P1275_ARG(1, P1275_ARG_IN_64B) |
|
||||
P1275_INOUT(2, 0)), tba, mmfsa);
|
||||
}
|
||||
|
||||
int prom_get_mmu_ihandle(void)
|
||||
{
|
||||
int node, ret;
|
||||
|
|
|
@ -117,7 +117,7 @@ extern void sigio_handler(int sig, union uml_pt_regs *regs);
|
|||
|
||||
extern void copy_sc(union uml_pt_regs *regs, void *from);
|
||||
|
||||
unsigned long to_irq_stack(int sig, unsigned long *mask_out);
|
||||
extern unsigned long to_irq_stack(unsigned long *mask_out);
|
||||
unsigned long from_irq_stack(int nested);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -518,13 +518,13 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
|
|||
|
||||
static unsigned long pending_mask;
|
||||
|
||||
unsigned long to_irq_stack(int sig, unsigned long *mask_out)
|
||||
unsigned long to_irq_stack(unsigned long *mask_out)
|
||||
{
|
||||
struct thread_info *ti;
|
||||
unsigned long mask, old;
|
||||
int nested;
|
||||
|
||||
mask = xchg(&pending_mask, 1 << sig);
|
||||
mask = xchg(&pending_mask, *mask_out);
|
||||
if(mask != 0){
|
||||
/* If any interrupts come in at this point, we want to
|
||||
* make sure that their bits aren't lost by our
|
||||
|
@ -534,7 +534,7 @@ unsigned long to_irq_stack(int sig, unsigned long *mask_out)
|
|||
* and pending_mask contains a bit for each interrupt
|
||||
* that came in.
|
||||
*/
|
||||
old = 1 << sig;
|
||||
old = *mask_out;
|
||||
do {
|
||||
old |= mask;
|
||||
mask = xchg(&pending_mask, old);
|
||||
|
@ -550,6 +550,7 @@ unsigned long to_irq_stack(int sig, unsigned long *mask_out)
|
|||
|
||||
task = cpu_tasks[ti->cpu].task;
|
||||
tti = task_thread_info(task);
|
||||
|
||||
*ti = *tti;
|
||||
ti->real_thread = tti;
|
||||
task->stack = ti;
|
||||
|
|
|
@ -320,7 +320,8 @@ int os_file_size(char *file, unsigned long long *size_out)
|
|||
}
|
||||
|
||||
if(S_ISBLK(buf.ust_mode)){
|
||||
int fd, blocks;
|
||||
int fd;
|
||||
long blocks;
|
||||
|
||||
fd = os_open_file(file, of_read(OPENFLAGS()), 0);
|
||||
if(fd < 0){
|
||||
|
|
|
@ -119,7 +119,7 @@ void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
|
|||
|
||||
void handle_signal(int sig, struct sigcontext *sc)
|
||||
{
|
||||
unsigned long pending = 0;
|
||||
unsigned long pending = 1UL << sig;
|
||||
|
||||
do {
|
||||
int nested, bail;
|
||||
|
@ -134,7 +134,7 @@ void handle_signal(int sig, struct sigcontext *sc)
|
|||
* have to return, and the upper handler will deal
|
||||
* with this interrupt.
|
||||
*/
|
||||
bail = to_irq_stack(sig, &pending);
|
||||
bail = to_irq_stack(&pending);
|
||||
if(bail)
|
||||
return;
|
||||
|
||||
|
|
|
@ -374,6 +374,13 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
|
|||
if (unlikely(in_atomic() || !mm))
|
||||
goto bad_area_nosemaphore;
|
||||
|
||||
/*
|
||||
* User-mode registers count as a user access even for any
|
||||
* potential system fault or CPU buglet.
|
||||
*/
|
||||
if (user_mode_vm(regs))
|
||||
error_code |= PF_USER;
|
||||
|
||||
again:
|
||||
/* When running in the kernel we expect faults to occur only to
|
||||
* addresses in user space. All other faults represent errors in the
|
||||
|
|
|
@ -27,7 +27,12 @@ platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss
|
|||
PLATFORM = $(platform-y)
|
||||
export PLATFORM
|
||||
|
||||
CFLAGS += -pipe -mlongcalls
|
||||
# temporarily until string.h is fixed
|
||||
cflags-y += -ffreestanding
|
||||
|
||||
cflags-y += -pipe -mlongcalls
|
||||
|
||||
CFLAGS += $(cflags-y)
|
||||
|
||||
KBUILD_DEFCONFIG := iss_defconfig
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ extra-y := head.o vmlinux.lds
|
|||
|
||||
obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o semaphore.o \
|
||||
setup.o signal.o syscall.o time.o traps.o vectors.o platform.o \
|
||||
pci-dma.o
|
||||
pci-dma.o init_task.o io.o
|
||||
|
||||
## windowspill.o
|
||||
|
||||
|
|
|
@ -18,12 +18,13 @@
|
|||
#include <linux/stddef.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
|
||||
#define BLANK() asm volatile("\n->" : : )
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
@ -63,7 +64,6 @@ int main(void)
|
|||
DEFINE(PT_SIZE, sizeof(struct pt_regs));
|
||||
DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS]));
|
||||
DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS]));
|
||||
BLANK();
|
||||
|
||||
/* struct task_struct */
|
||||
DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace));
|
||||
|
@ -73,27 +73,26 @@ int main(void)
|
|||
DEFINE(TASK_THREAD, offsetof (struct task_struct, thread));
|
||||
DEFINE(TASK_THREAD_INFO, offsetof (struct task_struct, stack));
|
||||
DEFINE(TASK_STRUCT_SIZE, sizeof (struct task_struct));
|
||||
BLANK();
|
||||
|
||||
/* struct thread_info (offset from start_struct) */
|
||||
DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
|
||||
DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
|
||||
DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save));
|
||||
DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
|
||||
BLANK();
|
||||
|
||||
/* struct mm_struct */
|
||||
DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users));
|
||||
DEFINE(MM_PGD, offsetof (struct mm_struct, pgd));
|
||||
DEFINE(MM_CONTEXT, offsetof (struct mm_struct, context));
|
||||
BLANK();
|
||||
DEFINE(PT_SINGLESTEP_BIT, PT_SINGLESTEP_BIT);
|
||||
|
||||
/* struct page */
|
||||
DEFINE(PAGE_FLAGS, offsetof(struct page, flags));
|
||||
|
||||
/* constants */
|
||||
DEFINE(_CLONE_VM, CLONE_VM);
|
||||
DEFINE(_CLONE_UNTRACED, CLONE_UNTRACED);
|
||||
DEFINE(PG_ARCH_1, PG_arch_1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2004-2005 by Tensilica Inc.
|
||||
* Copyright (C) 2004-2007 by Tensilica Inc.
|
||||
*
|
||||
* Chris Zankel <chris@zankel.net>
|
||||
*
|
||||
|
@ -169,7 +169,7 @@ _user_exception:
|
|||
* We have to save all registers up to the first '1' from
|
||||
* the right, except the current frame (bit 0).
|
||||
* Assume a2 is: 001001000110001
|
||||
* All regiser frames starting from the top fiel to the marked '1'
|
||||
* All register frames starting from the top field to the marked '1'
|
||||
* must be saved.
|
||||
*/
|
||||
|
||||
|
@ -1572,10 +1572,12 @@ ENTRY(fast_second_level_miss)
|
|||
l32i a0, a1, TASK_MM # tsk->mm
|
||||
beqz a0, 9f
|
||||
|
||||
8: rsr a1, EXCVADDR # fault address
|
||||
_PGD_OFFSET(a0, a1, a1)
|
||||
|
||||
/* We deliberately destroy a3 that holds the exception table. */
|
||||
|
||||
8: rsr a3, EXCVADDR # fault address
|
||||
_PGD_OFFSET(a0, a3, a1)
|
||||
l32i a0, a0, 0 # read pmdval
|
||||
//beqi a0, _PAGE_USER, 2f
|
||||
beqz a0, 2f
|
||||
|
||||
/* Read ptevaddr and convert to top of page-table page.
|
||||
|
@ -1588,7 +1590,7 @@ ENTRY(fast_second_level_miss)
|
|||
* The messy computation for 'pteval' above really simplifies
|
||||
* into the following:
|
||||
*
|
||||
* pteval = ((pmdval - PAGE_OFFSET) & PAGE_MASK) | PAGE_KERNEL
|
||||
* pteval = ((pmdval - PAGE_OFFSET) & PAGE_MASK) | PAGE_DIRECTORY
|
||||
*/
|
||||
|
||||
movi a1, -PAGE_OFFSET
|
||||
|
@ -1596,20 +1598,34 @@ ENTRY(fast_second_level_miss)
|
|||
extui a1, a0, 0, PAGE_SHIFT # ... & PAGE_MASK
|
||||
xor a0, a0, a1
|
||||
|
||||
|
||||
movi a1, PAGE_DIRECTORY
|
||||
movi a1, _PAGE_DIRECTORY
|
||||
or a0, a0, a1 # ... | PAGE_DIRECTORY
|
||||
|
||||
rsr a1, PTEVADDR
|
||||
srli a1, a1, PAGE_SHIFT
|
||||
slli a1, a1, PAGE_SHIFT # ptevaddr & PAGE_MASK
|
||||
addi a1, a1, DTLB_WAY_PGD # ... + way_number
|
||||
/*
|
||||
* We utilize all three wired-ways (7-9) to hold pmd translations.
|
||||
* Memory regions are mapped to the DTLBs according to bits 28 and 29.
|
||||
* This allows to map the three most common regions to three different
|
||||
* DTLBs:
|
||||
* 0,1 -> way 7 program (0040.0000) and virtual (c000.0000)
|
||||
* 2 -> way 8 shared libaries (2000.0000)
|
||||
* 3 -> way 0 stack (3000.0000)
|
||||
*/
|
||||
|
||||
wdtlb a0, a1
|
||||
extui a3, a3, 28, 2 # addr. bit 28 and 29 0,1,2,3
|
||||
rsr a1, PTEVADDR
|
||||
addx2 a3, a3, a3 # -> 0,3,6,9
|
||||
srli a1, a1, PAGE_SHIFT
|
||||
extui a3, a3, 2, 2 # -> 0,0,1,2
|
||||
slli a1, a1, PAGE_SHIFT # ptevaddr & PAGE_MASK
|
||||
addi a3, a3, DTLB_WAY_PGD
|
||||
add a1, a1, a3 # ... + way_number
|
||||
|
||||
3: wdtlb a0, a1
|
||||
dsync
|
||||
|
||||
/* Exit critical section. */
|
||||
|
||||
4: movi a3, exc_table # restore a3
|
||||
movi a0, 0
|
||||
s32i a0, a3, EXC_TABLE_FIXUP
|
||||
|
||||
|
@ -1636,8 +1652,76 @@ ENTRY(fast_second_level_miss)
|
|||
9: l32i a0, a1, TASK_ACTIVE_MM # unlikely case mm == 0
|
||||
j 8b
|
||||
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE)
|
||||
|
||||
2: /* Special case for cache aliasing.
|
||||
* We (should) only get here if a clear_user_page, copy_user_page
|
||||
* or the aliased cache flush functions got preemptively interrupted
|
||||
* by another task. Re-establish temporary mapping to the
|
||||
* TLBTEMP_BASE areas.
|
||||
*/
|
||||
|
||||
/* We shouldn't be in a double exception */
|
||||
|
||||
l32i a0, a2, PT_DEPC
|
||||
bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 2f
|
||||
|
||||
/* Make sure the exception originated in the special functions */
|
||||
|
||||
movi a0, __tlbtemp_mapping_start
|
||||
rsr a3, EPC_1
|
||||
bltu a3, a0, 2f
|
||||
movi a0, __tlbtemp_mapping_end
|
||||
bgeu a3, a0, 2f
|
||||
|
||||
/* Check if excvaddr was in one of the TLBTEMP_BASE areas. */
|
||||
|
||||
movi a3, TLBTEMP_BASE_1
|
||||
rsr a0, EXCVADDR
|
||||
bltu a0, a3, 2f
|
||||
|
||||
addi a1, a0, -(2 << (DCACHE_ALIAS_ORDER + PAGE_SHIFT))
|
||||
bgeu a1, a3, 2f
|
||||
|
||||
/* Check if we have to restore an ITLB mapping. */
|
||||
|
||||
movi a1, __tlbtemp_mapping_itlb
|
||||
rsr a3, EPC_1
|
||||
sub a3, a3, a1
|
||||
|
||||
/* Calculate VPN */
|
||||
|
||||
movi a1, PAGE_MASK
|
||||
and a1, a1, a0
|
||||
|
||||
/* Jump for ITLB entry */
|
||||
|
||||
bgez a3, 1f
|
||||
|
||||
/* We can use up to two TLBTEMP areas, one for src and one for dst. */
|
||||
|
||||
extui a3, a0, PAGE_SHIFT + DCACHE_ALIAS_ORDER, 1
|
||||
add a1, a3, a1
|
||||
|
||||
/* PPN is in a6 for the first TLBTEMP area and in a7 for the second. */
|
||||
|
||||
mov a0, a6
|
||||
movnez a0, a7, a3
|
||||
j 3b
|
||||
|
||||
/* ITLB entry. We only use dst in a6. */
|
||||
|
||||
1: witlb a6, a1
|
||||
isync
|
||||
j 4b
|
||||
|
||||
|
||||
#endif // DCACHE_WAY_SIZE > PAGE_SIZE
|
||||
|
||||
|
||||
2: /* Invalid PGD, default exception handling */
|
||||
|
||||
movi a3, exc_table
|
||||
rsr a1, DEPC
|
||||
xsr a3, EXCSAVE_1
|
||||
s32i a1, a2, PT_AREG2
|
||||
|
@ -1682,15 +1766,15 @@ ENTRY(fast_store_prohibited)
|
|||
8: rsr a1, EXCVADDR # fault address
|
||||
_PGD_OFFSET(a0, a1, a4)
|
||||
l32i a0, a0, 0
|
||||
//beqi a0, _PAGE_USER, 2f # FIXME use _PAGE_INVALID
|
||||
beqz a0, 2f
|
||||
|
||||
/* Note that we assume _PAGE_WRITABLE_BIT is only set if pte is valid.*/
|
||||
|
||||
_PTE_OFFSET(a0, a1, a4)
|
||||
l32i a4, a0, 0 # read pteval
|
||||
movi a1, _PAGE_VALID | _PAGE_RW
|
||||
bnall a4, a1, 2f
|
||||
bbci.l a4, _PAGE_WRITABLE_BIT, 2f
|
||||
|
||||
movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_WRENABLE
|
||||
movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HW_WRITE
|
||||
or a4, a4, a1
|
||||
rsr a1, EXCVADDR
|
||||
s32i a4, a0, 0
|
||||
|
@ -1700,10 +1784,7 @@ ENTRY(fast_store_prohibited)
|
|||
dhwb a0, 0
|
||||
#endif
|
||||
pdtlb a0, a1
|
||||
beqz a0, 1f
|
||||
idtlb a0 // FIXME do we need this?
|
||||
wdtlb a4, a0
|
||||
1:
|
||||
|
||||
/* Exit critical section. */
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* arch/xtensa/kernel/init_task.c
|
||||
*
|
||||
* Xtensa Processor version.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2007 Tensilica Inc.
|
||||
*
|
||||
* Chris Zankel <chris@zankel.net>
|
||||
*/
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/init_task.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mqueue.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
static struct fs_struct init_fs = INIT_FS;
|
||||
static struct files_struct init_files = INIT_FILES;
|
||||
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
|
||||
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
|
||||
struct mm_struct init_mm = INIT_MM(init_mm);
|
||||
|
||||
EXPORT_SYMBOL(init_mm);
|
||||
|
||||
union thread_union init_thread_union
|
||||
__attribute__((__section__(".data.init_task"))) =
|
||||
{ INIT_THREAD_INFO(init_task) };
|
||||
|
||||
struct task_struct init_task = INIT_TASK(init_task);
|
||||
|
||||
EXPORT_SYMBOL(init_task);
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* arch/xtensa/io.c
|
||||
*
|
||||
* IO primitives
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Copied from sparc.
|
||||
*
|
||||
* Chris Zankel <chris@zankel.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
void outsb(unsigned long addr, const void *src, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 1;
|
||||
writeb(*(const char *)src, addr);
|
||||
src += 1;
|
||||
addr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void outsw(unsigned long addr, const void *src, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 2;
|
||||
writew(*(const short *)src, addr);
|
||||
src += 2;
|
||||
addr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void outsl(unsigned long addr, const void *src, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 4;
|
||||
writel(*(const long *)src, addr);
|
||||
src += 4;
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void insb(unsigned long addr, void *dst, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 1;
|
||||
*(unsigned char *)dst = readb(addr);
|
||||
dst += 1;
|
||||
addr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void insw(unsigned long addr, void *dst, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 2;
|
||||
*(unsigned short *)dst = readw(addr);
|
||||
dst += 2;
|
||||
addr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void insl(unsigned long addr, void *dst, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 4;
|
||||
/*
|
||||
* XXX I am sure we are in for an unaligned trap here.
|
||||
*/
|
||||
*(unsigned long *)dst = readl(addr);
|
||||
dst += 4;
|
||||
addr += 4;
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2001 - 2005 Tensilica Inc.
|
||||
* Copyright (C) 2001 - 2006 Tensilica Inc.
|
||||
*
|
||||
* Chris Zankel <chris@zankel.net>
|
||||
*
|
||||
|
@ -22,57 +22,216 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/cache.h>
|
||||
|
||||
LIST_HEAD(module_buf_list);
|
||||
#undef DEBUG_RELOCATE
|
||||
|
||||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
panic("module_alloc not implemented");
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
return vmalloc(size);
|
||||
}
|
||||
|
||||
void module_free(struct module *mod, void *module_region)
|
||||
{
|
||||
panic("module_free not implemented");
|
||||
vfree(module_region);
|
||||
/* FIXME: If module_region == mod->init_region, trim exception
|
||||
table entries. */
|
||||
}
|
||||
|
||||
int module_frob_arch_sections(Elf32_Ehdr *hdr,
|
||||
Elf32_Shdr *sechdrs,
|
||||
char *secstrings,
|
||||
struct module *me)
|
||||
struct module *mod)
|
||||
{
|
||||
panic("module_frob_arch_sections not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
decode_calln_opcode (unsigned char *location)
|
||||
{
|
||||
#ifdef __XTENSA_EB__
|
||||
return (location[0] & 0xf0) == 0x50;
|
||||
#endif
|
||||
#ifdef __XTENSA_EL__
|
||||
return (location[0] & 0xf) == 0x5;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
decode_l32r_opcode (unsigned char *location)
|
||||
{
|
||||
#ifdef __XTENSA_EB__
|
||||
return (location[0] & 0xf0) == 0x10;
|
||||
#endif
|
||||
#ifdef __XTENSA_EL__
|
||||
return (location[0] & 0xf) == 0x1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int apply_relocate(Elf32_Shdr *sechdrs,
|
||||
const char *strtab,
|
||||
unsigned int symindex,
|
||||
unsigned int relsec,
|
||||
struct module *module)
|
||||
struct module *mod)
|
||||
{
|
||||
panic ("apply_relocate not implemented");
|
||||
printk(KERN_ERR "module %s: REL RELOCATION unsupported\n",
|
||||
mod->name);
|
||||
return -ENOEXEC;
|
||||
|
||||
}
|
||||
|
||||
int apply_relocate_add(Elf32_Shdr *sechdrs,
|
||||
const char *strtab,
|
||||
unsigned int symindex,
|
||||
unsigned int relsec,
|
||||
struct module *module)
|
||||
struct module *mod)
|
||||
{
|
||||
panic("apply_relocate_add not implemented");
|
||||
unsigned int i;
|
||||
Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
|
||||
Elf32_Sym *sym;
|
||||
unsigned char *location;
|
||||
uint32_t value;
|
||||
|
||||
#ifdef DEBUG_RELOCATE
|
||||
printk("Applying relocate section %u to %u\n", relsec,
|
||||
sechdrs[relsec].sh_info);
|
||||
#endif
|
||||
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
|
||||
location = (char *)sechdrs[sechdrs[relsec].sh_info].sh_addr
|
||||
+ rela[i].r_offset;
|
||||
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
|
||||
+ ELF32_R_SYM(rela[i].r_info);
|
||||
value = sym->st_value + rela[i].r_addend;
|
||||
|
||||
switch (ELF32_R_TYPE(rela[i].r_info)) {
|
||||
case R_XTENSA_NONE:
|
||||
case R_XTENSA_DIFF8:
|
||||
case R_XTENSA_DIFF16:
|
||||
case R_XTENSA_DIFF32:
|
||||
case R_XTENSA_ASM_EXPAND:
|
||||
break;
|
||||
|
||||
case R_XTENSA_32:
|
||||
case R_XTENSA_PLT:
|
||||
*(uint32_t *)location += value;
|
||||
break;
|
||||
|
||||
case R_XTENSA_SLOT0_OP:
|
||||
if (decode_calln_opcode(location)) {
|
||||
value -= ((unsigned long)location & -4) + 4;
|
||||
if ((value & 3) != 0 ||
|
||||
((value + (1 << 19)) >> 20) != 0) {
|
||||
printk("%s: relocation out of range, "
|
||||
"section %d reloc %d "
|
||||
"sym '%s'\n",
|
||||
mod->name, relsec, i,
|
||||
strtab + sym->st_name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
value = (signed int)value >> 2;
|
||||
#ifdef __XTENSA_EB__
|
||||
location[0] = ((location[0] & ~0x3) |
|
||||
((value >> 16) & 0x3));
|
||||
location[1] = (value >> 8) & 0xff;
|
||||
location[2] = value & 0xff;
|
||||
#endif
|
||||
#ifdef __XTENSA_EL__
|
||||
location[0] = ((location[0] & ~0xc0) |
|
||||
((value << 6) & 0xc0));
|
||||
location[1] = (value >> 2) & 0xff;
|
||||
location[2] = (value >> 10) & 0xff;
|
||||
#endif
|
||||
} else if (decode_l32r_opcode(location)) {
|
||||
value -= (((unsigned long)location + 3) & -4);
|
||||
if ((value & 3) != 0 ||
|
||||
(signed int)value >> 18 != -1) {
|
||||
printk("%s: relocation out of range, "
|
||||
"section %d reloc %d "
|
||||
"sym '%s'\n",
|
||||
mod->name, relsec, i,
|
||||
strtab + sym->st_name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
value = (signed int)value >> 2;
|
||||
|
||||
#ifdef __XTENSA_EB__
|
||||
location[1] = (value >> 8) & 0xff;
|
||||
location[2] = value & 0xff;
|
||||
#endif
|
||||
#ifdef __XTENSA_EL__
|
||||
location[1] = value & 0xff;
|
||||
location[2] = (value >> 8) & 0xff;
|
||||
#endif
|
||||
}
|
||||
/* FIXME: Ignore any other opcodes. The Xtensa
|
||||
assembler currently assumes that the linker will
|
||||
always do relaxation and so all PC-relative
|
||||
operands need relocations. (The assembler also
|
||||
writes out the tentative PC-relative values,
|
||||
assuming no link-time relaxation, so it is usually
|
||||
safe to ignore the relocations.) If the
|
||||
assembler's "--no-link-relax" flag can be made to
|
||||
work, and if all kernel modules can be assembled
|
||||
with that flag, then unexpected relocations could
|
||||
be detected here. */
|
||||
break;
|
||||
|
||||
case R_XTENSA_SLOT1_OP:
|
||||
case R_XTENSA_SLOT2_OP:
|
||||
case R_XTENSA_SLOT3_OP:
|
||||
case R_XTENSA_SLOT4_OP:
|
||||
case R_XTENSA_SLOT5_OP:
|
||||
case R_XTENSA_SLOT6_OP:
|
||||
case R_XTENSA_SLOT7_OP:
|
||||
case R_XTENSA_SLOT8_OP:
|
||||
case R_XTENSA_SLOT9_OP:
|
||||
case R_XTENSA_SLOT10_OP:
|
||||
case R_XTENSA_SLOT11_OP:
|
||||
case R_XTENSA_SLOT12_OP:
|
||||
case R_XTENSA_SLOT13_OP:
|
||||
case R_XTENSA_SLOT14_OP:
|
||||
printk("%s: unexpected FLIX relocation: %u\n",
|
||||
mod->name,
|
||||
ELF32_R_TYPE(rela[i].r_info));
|
||||
return -ENOEXEC;
|
||||
|
||||
case R_XTENSA_SLOT0_ALT:
|
||||
case R_XTENSA_SLOT1_ALT:
|
||||
case R_XTENSA_SLOT2_ALT:
|
||||
case R_XTENSA_SLOT3_ALT:
|
||||
case R_XTENSA_SLOT4_ALT:
|
||||
case R_XTENSA_SLOT5_ALT:
|
||||
case R_XTENSA_SLOT6_ALT:
|
||||
case R_XTENSA_SLOT7_ALT:
|
||||
case R_XTENSA_SLOT8_ALT:
|
||||
case R_XTENSA_SLOT9_ALT:
|
||||
case R_XTENSA_SLOT10_ALT:
|
||||
case R_XTENSA_SLOT11_ALT:
|
||||
case R_XTENSA_SLOT12_ALT:
|
||||
case R_XTENSA_SLOT13_ALT:
|
||||
case R_XTENSA_SLOT14_ALT:
|
||||
printk("%s: unexpected ALT relocation: %u\n",
|
||||
mod->name,
|
||||
ELF32_R_TYPE(rela[i].r_info));
|
||||
return -ENOEXEC;
|
||||
|
||||
default:
|
||||
printk("%s: unexpected relocation: %u\n",
|
||||
mod->name,
|
||||
ELF32_R_TYPE(rela[i].r_info));
|
||||
return -ENOEXEC;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int module_finalize(const Elf_Ehdr *hdr,
|
||||
const Elf_Shdr *sechdrs,
|
||||
struct module *me)
|
||||
struct module *mod)
|
||||
{
|
||||
panic ("module_finalize not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
panic("module_arch_cleanup not implemented");
|
||||
}
|
||||
|
||||
struct bug_entry *module_find_bug(unsigned long bugaddr)
|
||||
{
|
||||
panic("module_find_bug not implemented");
|
||||
}
|
||||
|
|
|
@ -394,72 +394,3 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This probably belongs here rather than ioport.c because
|
||||
* we do not want this crud linked into SBus kernels.
|
||||
* Also, think for a moment about likes of floppy.c that
|
||||
* include architecture specific parts. They may want to redefine ins/outs.
|
||||
*
|
||||
* We do not use horrible macros here because we want to
|
||||
* advance pointer by sizeof(size).
|
||||
*/
|
||||
void outsb(unsigned long addr, const void *src, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 1;
|
||||
writeb(*(const char *)src, addr);
|
||||
src += 1;
|
||||
addr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void outsw(unsigned long addr, const void *src, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 2;
|
||||
writew(*(const short *)src, addr);
|
||||
src += 2;
|
||||
addr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void outsl(unsigned long addr, const void *src, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 4;
|
||||
writel(*(const long *)src, addr);
|
||||
src += 4;
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void insb(unsigned long addr, void *dst, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 1;
|
||||
*(unsigned char *)dst = readb(addr);
|
||||
dst += 1;
|
||||
addr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void insw(unsigned long addr, void *dst, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 2;
|
||||
*(unsigned short *)dst = readw(addr);
|
||||
dst += 2;
|
||||
addr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void insl(unsigned long addr, void *dst, unsigned long count) {
|
||||
while (count) {
|
||||
count -= 4;
|
||||
/*
|
||||
* XXX I am sure we are in for an unaligned trap here.
|
||||
*/
|
||||
*(unsigned long *)dst = readl(addr);
|
||||
dst += 4;
|
||||
addr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -46,20 +46,6 @@
|
|||
|
||||
extern void ret_from_fork(void);
|
||||
|
||||
static struct fs_struct init_fs = INIT_FS;
|
||||
static struct files_struct init_files = INIT_FILES;
|
||||
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
|
||||
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
|
||||
struct mm_struct init_mm = INIT_MM(init_mm);
|
||||
EXPORT_SYMBOL(init_mm);
|
||||
|
||||
union thread_union init_thread_union
|
||||
__attribute__((__section__(".data.init_task"))) =
|
||||
{ INIT_THREAD_INFO(init_task) };
|
||||
|
||||
struct task_struct init_task = INIT_TASK(init_task);
|
||||
EXPORT_SYMBOL(init_task);
|
||||
|
||||
struct task_struct *current_set[NR_CPUS] = {&init_task, };
|
||||
|
||||
void (*pm_power_off)(void) = NULL;
|
||||
|
|
|
@ -100,7 +100,7 @@ static __inline__ int waking_non_zero_trylock(struct semaphore *sem)
|
|||
return ret;
|
||||
}
|
||||
|
||||
spinlock_t semaphore_wake_lock;
|
||||
DEFINE_SPINLOCK(semaphore_wake_lock);
|
||||
|
||||
/*
|
||||
* Semaphores are implemented using a two-way counter:
|
||||
|
|
|
@ -93,3 +93,8 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg)
|
|||
return (long)ret;
|
||||
}
|
||||
|
||||
asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len)
|
||||
{
|
||||
return sys_fadvise64_64(fd, offset, len, advice);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,12 +32,20 @@ EXPORT_SYMBOL(rtc_lock);
|
|||
|
||||
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
|
||||
unsigned long ccount_per_jiffy; /* per 1/HZ */
|
||||
unsigned long ccount_nsec; /* nsec per ccount increment */
|
||||
unsigned long nsec_per_ccount; /* nsec per ccount increment */
|
||||
#endif
|
||||
|
||||
unsigned int last_ccount_stamp;
|
||||
static long last_rtc_update = 0;
|
||||
|
||||
/*
|
||||
* Scheduler clock - returns current tim in nanosec units.
|
||||
*/
|
||||
|
||||
unsigned long long sched_clock(void)
|
||||
{
|
||||
return (unsigned long long)jiffies * (1000000000 / HZ);
|
||||
}
|
||||
|
||||
static irqreturn_t timer_interrupt(int irq, void *dev_id);
|
||||
static struct irqaction timer_irqaction = {
|
||||
.handler = timer_interrupt,
|
||||
|
@ -69,7 +77,6 @@ void __init time_init(void)
|
|||
|
||||
xtime.tv_nsec = 0;
|
||||
last_rtc_update = xtime.tv_sec = sec_n;
|
||||
last_ccount_stamp = get_ccount();
|
||||
|
||||
set_normalized_timespec(&wall_to_monotonic,
|
||||
-xtime.tv_sec, -xtime.tv_nsec);
|
||||
|
@ -85,7 +92,7 @@ int do_settimeofday(struct timespec *tv)
|
|||
{
|
||||
time_t wtm_sec, sec = tv->tv_sec;
|
||||
long wtm_nsec, nsec = tv->tv_nsec;
|
||||
unsigned long ccount;
|
||||
unsigned long delta;
|
||||
|
||||
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
|
||||
return -EINVAL;
|
||||
|
@ -97,8 +104,10 @@ int do_settimeofday(struct timespec *tv)
|
|||
* wall time. Discover what correction gettimeofday() would have
|
||||
* made, and then undo it!
|
||||
*/
|
||||
ccount = get_ccount();
|
||||
nsec -= (ccount - last_ccount_stamp) * CCOUNT_NSEC;
|
||||
|
||||
delta = CCOUNT_PER_JIFFY;
|
||||
delta += get_ccount() - get_linux_timer();
|
||||
nsec -= delta * NSEC_PER_CCOUNT;
|
||||
|
||||
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
|
||||
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
|
||||
|
@ -117,17 +126,21 @@ EXPORT_SYMBOL(do_settimeofday);
|
|||
void do_gettimeofday(struct timeval *tv)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long sec, usec, delta, seq;
|
||||
unsigned long volatile sec, usec, delta, seq;
|
||||
|
||||
do {
|
||||
seq = read_seqbegin_irqsave(&xtime_lock, flags);
|
||||
|
||||
delta = get_ccount() - last_ccount_stamp;
|
||||
sec = xtime.tv_sec;
|
||||
usec = (xtime.tv_nsec / NSEC_PER_USEC);
|
||||
|
||||
delta = get_linux_timer() - get_ccount();
|
||||
|
||||
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
|
||||
|
||||
usec += (delta * CCOUNT_NSEC) / NSEC_PER_USEC;
|
||||
usec += (((unsigned long) CCOUNT_PER_JIFFY - delta)
|
||||
* (unsigned long) NSEC_PER_CCOUNT) / NSEC_PER_USEC;
|
||||
|
||||
for (; usec >= 1000000; sec++, usec -= 1000000)
|
||||
;
|
||||
|
||||
|
@ -158,10 +171,13 @@ again:
|
|||
|
||||
write_seqlock(&xtime_lock);
|
||||
|
||||
last_ccount_stamp = next;
|
||||
next += CCOUNT_PER_JIFFY;
|
||||
do_timer(1); /* Linux handler in kernel/timer.c */
|
||||
|
||||
/* Note that writing CCOMPARE clears the interrupt. */
|
||||
|
||||
next += CCOUNT_PER_JIFFY;
|
||||
set_linux_timer(next);
|
||||
|
||||
if (ntp_synced() &&
|
||||
xtime.tv_sec - last_rtc_update >= 659 &&
|
||||
abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) {
|
||||
|
@ -175,19 +191,15 @@ again:
|
|||
write_sequnlock(&xtime_lock);
|
||||
}
|
||||
|
||||
/* NOTE: writing CCOMPAREn clears the interrupt. */
|
||||
/* Allow platform to do something useful (Wdog). */
|
||||
|
||||
set_linux_timer (next);
|
||||
platform_heartbeat();
|
||||
|
||||
/* Make sure we didn't miss any tick... */
|
||||
|
||||
if ((signed long)(get_ccount() - next) > 0)
|
||||
goto again;
|
||||
|
||||
/* Allow platform to do something useful (Wdog). */
|
||||
|
||||
platform_heartbeat();
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ typedef struct {
|
|||
void* handler;
|
||||
} dispatch_init_table_t;
|
||||
|
||||
dispatch_init_table_t __init dispatch_init_table[] = {
|
||||
static dispatch_init_table_t __initdata dispatch_init_table[] = {
|
||||
|
||||
{ EXCCAUSE_ILLEGAL_INSTRUCTION, 0, do_illegal_instruction},
|
||||
{ EXCCAUSE_SYSTEM_CALL, KRNL, fast_syscall_kernel },
|
||||
|
@ -305,7 +305,7 @@ do_debug(struct pt_regs *regs)
|
|||
|
||||
#define set_handler(idx,handler) (exc_table[idx] = (unsigned long) (handler))
|
||||
|
||||
void trap_init(void)
|
||||
void __init trap_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
|
@ -5,9 +5,5 @@
|
|||
# removes any old dependencies. DON'T put your own dependencies here
|
||||
# unless it's something special (ie not a .c file).
|
||||
#
|
||||
# Note 2! The CFLAGS definition is now in the main makefile...
|
||||
|
||||
obj-y := init.o fault.o tlb.o misc.o
|
||||
obj-m :=
|
||||
obj-n :=
|
||||
obj- :=
|
||||
obj-y := init.o fault.o tlb.o misc.o cache.o
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* arch/xtensa/mm/cache.c
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2001-2006 Tensilica Inc.
|
||||
*
|
||||
* Chris Zankel <chris@zankel.net>
|
||||
* Joe Taylor
|
||||
* Marc Gauthier
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/pagemap.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/bootparam.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
//#define printd(x...) printk(x)
|
||||
#define printd(x...) do { } while(0)
|
||||
|
||||
/*
|
||||
* Note:
|
||||
* The kernel provides one architecture bit PG_arch_1 in the page flags that
|
||||
* can be used for cache coherency.
|
||||
*
|
||||
* I$-D$ coherency.
|
||||
*
|
||||
* The Xtensa architecture doesn't keep the instruction cache coherent with
|
||||
* the data cache. We use the architecture bit to indicate if the caches
|
||||
* are coherent. The kernel clears this bit whenever a page is added to the
|
||||
* page cache. At that time, the caches might not be in sync. We, therefore,
|
||||
* define this flag as 'clean' if set.
|
||||
*
|
||||
* D-cache aliasing.
|
||||
*
|
||||
* With cache aliasing, we have to always flush the cache when pages are
|
||||
* unmapped (see tlb_start_vma(). So, we use this flag to indicate a dirty
|
||||
* page.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
|
||||
|
||||
/*
|
||||
* Any time the kernel writes to a user page cache page, or it is about to
|
||||
* read from a page cache page this routine is called.
|
||||
*
|
||||
*/
|
||||
|
||||
void flush_dcache_page(struct page *page)
|
||||
{
|
||||
struct address_space *mapping = page_mapping(page);
|
||||
|
||||
/*
|
||||
* If we have a mapping but the page is not mapped to user-space
|
||||
* yet, we simply mark this page dirty and defer flushing the
|
||||
* caches until update_mmu().
|
||||
*/
|
||||
|
||||
if (mapping && !mapping_mapped(mapping)) {
|
||||
if (!test_bit(PG_arch_1, &page->flags))
|
||||
set_bit(PG_arch_1, &page->flags);
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
unsigned long phys = page_to_phys(page);
|
||||
unsigned long temp = page->index << PAGE_SHIFT;
|
||||
unsigned long alias = !(DCACHE_ALIAS_EQ(temp, phys));
|
||||
unsigned long virt;
|
||||
|
||||
/*
|
||||
* Flush the page in kernel space and user space.
|
||||
* Note that we can omit that step if aliasing is not
|
||||
* an issue, but we do have to synchronize I$ and D$
|
||||
* if we have a mapping.
|
||||
*/
|
||||
|
||||
if (!alias && !mapping)
|
||||
return;
|
||||
|
||||
__flush_invalidate_dcache_page((long)page_address(page));
|
||||
|
||||
virt = TLBTEMP_BASE_1 + (temp & DCACHE_ALIAS_MASK);
|
||||
|
||||
if (alias)
|
||||
__flush_invalidate_dcache_page_alias(virt, phys);
|
||||
|
||||
if (mapping)
|
||||
__invalidate_icache_page_alias(virt, phys);
|
||||
}
|
||||
|
||||
/* There shouldn't be an entry in the cache for this page anymore. */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* For now, flush the whole cache. FIXME??
|
||||
*/
|
||||
|
||||
void flush_cache_range(struct vm_area_struct* vma,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
__flush_invalidate_dcache_all();
|
||||
__invalidate_icache_all();
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove any entry in the cache for this page.
|
||||
*
|
||||
* Note that this function is only called for user pages, so use the
|
||||
* alias versions of the cache flush functions.
|
||||
*/
|
||||
|
||||
void flush_cache_page(struct vm_area_struct* vma, unsigned long address,
|
||||
unsigned long pfn)
|
||||
{
|
||||
/* Note that we have to use the 'alias' address to avoid multi-hit */
|
||||
|
||||
unsigned long phys = page_to_phys(pfn_to_page(pfn));
|
||||
unsigned long virt = TLBTEMP_BASE_1 + (address & DCACHE_ALIAS_MASK);
|
||||
|
||||
__flush_invalidate_dcache_page_alias(virt, phys);
|
||||
__invalidate_icache_page_alias(virt, phys);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
|
||||
{
|
||||
unsigned long pfn = pte_pfn(pte);
|
||||
struct page *page;
|
||||
|
||||
if (!pfn_valid(pfn))
|
||||
return;
|
||||
|
||||
page = pfn_to_page(pfn);
|
||||
|
||||
/* Invalidate old entry in TLBs */
|
||||
|
||||
invalidate_itlb_mapping(addr);
|
||||
invalidate_dtlb_mapping(addr);
|
||||
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
|
||||
|
||||
if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) {
|
||||
|
||||
unsigned long vaddr = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK);
|
||||
unsigned long paddr = (unsigned long) page_address(page);
|
||||
unsigned long phys = page_to_phys(page);
|
||||
|
||||
__flush_invalidate_dcache_page(paddr);
|
||||
|
||||
__flush_invalidate_dcache_page_alias(vaddr, phys);
|
||||
__invalidate_icache_page_alias(vaddr, phys);
|
||||
|
||||
clear_bit(PG_arch_1, &page->flags);
|
||||
}
|
||||
#else
|
||||
if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)
|
||||
&& (vma->vm_flags & VM_EXEC) != 0) {
|
||||
unsigned long vaddr = addr & PAGE_MASK;
|
||||
__flush_dcache_page(vaddr);
|
||||
__invalidate_icache_page(vaddr);
|
||||
set_bit(PG_arch_1, &page->flags);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* access_process_vm() has called get_user_pages(), which has done a
|
||||
* flush_dcache_page() on the page.
|
||||
*/
|
||||
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
|
||||
|
||||
void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
|
||||
unsigned long vaddr, void *dst, const void *src,
|
||||
unsigned long len)
|
||||
{
|
||||
unsigned long phys = page_to_phys(page);
|
||||
unsigned long alias = !(DCACHE_ALIAS_EQ(vaddr, phys));
|
||||
|
||||
/* Flush and invalidate user page if aliased. */
|
||||
|
||||
if (alias) {
|
||||
unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
|
||||
__flush_invalidate_dcache_page_alias(temp, phys);
|
||||
}
|
||||
|
||||
/* Copy data */
|
||||
|
||||
memcpy(dst, src, len);
|
||||
|
||||
/*
|
||||
* Flush and invalidate kernel page if aliased and synchronize
|
||||
* data and instruction caches for executable pages.
|
||||
*/
|
||||
|
||||
if (alias) {
|
||||
unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
|
||||
|
||||
__flush_invalidate_dcache_range((unsigned long) dst, len);
|
||||
if ((vma->vm_flags & VM_EXEC) != 0) {
|
||||
__invalidate_icache_page_alias(temp, phys);
|
||||
}
|
||||
|
||||
} else if ((vma->vm_flags & VM_EXEC) != 0) {
|
||||
__flush_dcache_range((unsigned long)dst,len);
|
||||
__invalidate_icache_range((unsigned long) dst, len);
|
||||
}
|
||||
}
|
||||
|
||||
extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
|
||||
unsigned long vaddr, void *dst, const void *src,
|
||||
unsigned long len)
|
||||
{
|
||||
unsigned long phys = page_to_phys(page);
|
||||
unsigned long alias = !(DCACHE_ALIAS_EQ(vaddr, phys));
|
||||
|
||||
/*
|
||||
* Flush user page if aliased.
|
||||
* (Note: a simply flush would be sufficient)
|
||||
*/
|
||||
|
||||
if (alias) {
|
||||
unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK);
|
||||
__flush_invalidate_dcache_page_alias(temp, phys);
|
||||
}
|
||||
|
||||
memcpy(dst, src, len);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -24,6 +24,8 @@
|
|||
unsigned long asid_cache = ASID_USER_FIRST;
|
||||
void bad_page_fault(struct pt_regs*, unsigned long, int);
|
||||
|
||||
#undef DEBUG_PAGE_FAULT
|
||||
|
||||
/*
|
||||
* This routine handles page faults. It determines the address,
|
||||
* and the problem, and then passes it off to one of the appropriate
|
||||
|
@ -64,7 +66,7 @@ void do_page_fault(struct pt_regs *regs)
|
|||
exccause == EXCCAUSE_ITLB_MISS ||
|
||||
exccause == EXCCAUSE_FETCH_CACHE_ATTRIBUTE) ? 1 : 0;
|
||||
|
||||
#if 0
|
||||
#ifdef DEBUG_PAGE_FAULT
|
||||
printk("[%s:%d:%08x:%d:%08x:%s%s]\n", current->comm, current->pid,
|
||||
address, exccause, regs->pc, is_write? "w":"", is_exec? "x":"");
|
||||
#endif
|
||||
|
@ -219,7 +221,7 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
|
|||
|
||||
/* Are we prepared to handle this kernel fault? */
|
||||
if ((entry = search_exception_tables(regs->pc)) != NULL) {
|
||||
#if 1
|
||||
#ifdef DEBUG_PAGE_FAULT
|
||||
printk(KERN_DEBUG "%s: Exception at pc=%#010lx (%lx)\n",
|
||||
current->comm, regs->pc, entry->fixup);
|
||||
#endif
|
||||
|
|
|
@ -15,40 +15,24 @@
|
|||
* Kevin Chea
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/nodemask.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/bootparam.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
|
||||
//static DEFINE_SPINLOCK(tlb_lock);
|
||||
|
||||
/*
|
||||
* This flag is used to indicate that the page was mapped and modified in
|
||||
* kernel space, so the cache is probably dirty at that address.
|
||||
* If cache aliasing is enabled and the page color mismatches, update_mmu_cache
|
||||
* synchronizes the caches if this bit is set.
|
||||
*/
|
||||
|
||||
#define PG_cache_clean PG_arch_1
|
||||
|
||||
/* References to section boundaries */
|
||||
|
||||
|
@ -323,228 +307,22 @@ void show_mem(void)
|
|||
printk("%d free pages\n", free);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
struct kmem_cache *pgtable_cache __read_mostly;
|
||||
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE)
|
||||
|
||||
/*
|
||||
* With cache aliasing, the page color of the page in kernel space and user
|
||||
* space might mismatch. We temporarily map the page to a different virtual
|
||||
* address with the same color and clear the page there.
|
||||
*/
|
||||
|
||||
void clear_user_page(void *kaddr, unsigned long vaddr, struct page* page)
|
||||
static void pgd_ctor(void *addr, struct kmem_cache *cache, unsigned long flags)
|
||||
{
|
||||
|
||||
/* There shouldn't be any entries for this page. */
|
||||
|
||||
__flush_invalidate_dcache_page_phys(__pa(page_address(page)));
|
||||
|
||||
if (!PAGE_COLOR_EQ(vaddr, kaddr)) {
|
||||
unsigned long v, p;
|
||||
|
||||
/* Temporarily map page to DTLB_WAY_DCACHE_ALIAS0. */
|
||||
|
||||
spin_lock(&tlb_lock);
|
||||
|
||||
p = (unsigned long)pte_val((mk_pte(page,PAGE_KERNEL)));
|
||||
kaddr = (void*)PAGE_COLOR_MAP0(vaddr);
|
||||
v = (unsigned long)kaddr | DTLB_WAY_DCACHE_ALIAS0;
|
||||
__asm__ __volatile__("wdtlb %0,%1; dsync" : :"a" (p), "a" (v));
|
||||
|
||||
clear_page(kaddr);
|
||||
|
||||
spin_unlock(&tlb_lock);
|
||||
} else {
|
||||
clear_page(kaddr);
|
||||
}
|
||||
|
||||
/* We need to make sure that i$ and d$ are coherent. */
|
||||
|
||||
clear_bit(PG_cache_clean, &page->flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* With cache aliasing, we have to make sure that the page color of the page
|
||||
* in kernel space matches that of the virtual user address before we read
|
||||
* the page. If the page color differ, we create a temporary DTLB entry with
|
||||
* the corrent page color and use this 'temporary' address as the source.
|
||||
* We then use the same approach as in clear_user_page and copy the data
|
||||
* to the kernel space and clear the PG_cache_clean bit to synchronize caches
|
||||
* later.
|
||||
*
|
||||
* Note:
|
||||
* Instead of using another 'way' for the temporary DTLB entry, we could
|
||||
* probably use the same entry that points to the kernel address (after
|
||||
* saving the original value and restoring it when we are done).
|
||||
*/
|
||||
|
||||
void copy_user_page(void* to, void* from, unsigned long vaddr,
|
||||
struct page* to_page)
|
||||
{
|
||||
/* There shouldn't be any entries for the new page. */
|
||||
|
||||
__flush_invalidate_dcache_page_phys(__pa(page_address(to_page)));
|
||||
|
||||
spin_lock(&tlb_lock);
|
||||
|
||||
if (!PAGE_COLOR_EQ(vaddr, from)) {
|
||||
unsigned long v, p, t;
|
||||
|
||||
__asm__ __volatile__ ("pdtlb %1,%2; rdtlb1 %0,%1"
|
||||
: "=a"(p), "=a"(t) : "a"(from));
|
||||
from = (void*)PAGE_COLOR_MAP0(vaddr);
|
||||
v = (unsigned long)from | DTLB_WAY_DCACHE_ALIAS0;
|
||||
__asm__ __volatile__ ("wdtlb %0,%1; dsync" ::"a" (p), "a" (v));
|
||||
}
|
||||
|
||||
if (!PAGE_COLOR_EQ(vaddr, to)) {
|
||||
unsigned long v, p;
|
||||
|
||||
p = (unsigned long)pte_val((mk_pte(to_page,PAGE_KERNEL)));
|
||||
to = (void*)PAGE_COLOR_MAP1(vaddr);
|
||||
v = (unsigned long)to | DTLB_WAY_DCACHE_ALIAS1;
|
||||
__asm__ __volatile__ ("wdtlb %0,%1; dsync" ::"a" (p), "a" (v));
|
||||
}
|
||||
copy_page(to, from);
|
||||
|
||||
spin_unlock(&tlb_lock);
|
||||
|
||||
/* We need to make sure that i$ and d$ are coherent. */
|
||||
|
||||
clear_bit(PG_cache_clean, &to_page->flags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Any time the kernel writes to a user page cache page, or it is about to
|
||||
* read from a page cache page this routine is called.
|
||||
*
|
||||
* Note:
|
||||
* The kernel currently only provides one architecture bit in the page
|
||||
* flags that we use for I$/D$ coherency. Maybe, in future, we can
|
||||
* use a sepearte bit for deferred dcache aliasing:
|
||||
* If the page is not mapped yet, we only need to set a flag,
|
||||
* if mapped, we need to invalidate the page.
|
||||
*/
|
||||
// FIXME: we probably need this for WB caches not only for Page Coloring..
|
||||
|
||||
void flush_dcache_page(struct page *page)
|
||||
{
|
||||
unsigned long addr = __pa(page_address(page));
|
||||
struct address_space *mapping = page_mapping(page);
|
||||
|
||||
__flush_invalidate_dcache_page_phys(addr);
|
||||
|
||||
if (!test_bit(PG_cache_clean, &page->flags))
|
||||
return;
|
||||
|
||||
/* If this page hasn't been mapped, yet, handle I$/D$ coherency later.*/
|
||||
#if 0
|
||||
if (mapping && !mapping_mapped(mapping))
|
||||
clear_bit(PG_cache_clean, &page->flags);
|
||||
else
|
||||
#endif
|
||||
__invalidate_icache_page_phys(addr);
|
||||
}
|
||||
|
||||
void flush_cache_range(struct vm_area_struct* vma, unsigned long s,
|
||||
unsigned long e)
|
||||
{
|
||||
__flush_invalidate_cache_all();
|
||||
}
|
||||
|
||||
void flush_cache_page(struct vm_area_struct* vma, unsigned long address,
|
||||
unsigned long pfn)
|
||||
{
|
||||
struct page *page = pfn_to_page(pfn);
|
||||
|
||||
/* Remove any entry for the old mapping. */
|
||||
|
||||
if (current->active_mm == vma->vm_mm) {
|
||||
unsigned long addr = __pa(page_address(page));
|
||||
__flush_invalidate_dcache_page_phys(addr);
|
||||
if ((vma->vm_flags & VM_EXEC) != 0)
|
||||
__invalidate_icache_page_phys(addr);
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* (DCACHE_WAY_SIZE > PAGE_SIZE) */
|
||||
|
||||
|
||||
pte_t* pte_alloc_one_kernel (struct mm_struct* mm, unsigned long addr)
|
||||
{
|
||||
pte_t* pte = (pte_t*)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 0);
|
||||
if (likely(pte)) {
|
||||
pte_t* ptep = (pte_t*)(pte_val(*pte) + PAGE_OFFSET);
|
||||
int i;
|
||||
for (i = 0; i < 1024; i++, ptep++)
|
||||
pte_clear(mm, addr, ptep);
|
||||
}
|
||||
return pte;
|
||||
}
|
||||
|
||||
struct page* pte_alloc_one(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
struct page *page;
|
||||
|
||||
page = alloc_pages(GFP_KERNEL | __GFP_REPEAT, 0);
|
||||
|
||||
if (likely(page)) {
|
||||
pte_t* ptep = kmap_atomic(page, KM_USER0);
|
||||
pte_t* ptep = (pte_t*)addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 1024; i++, ptep++)
|
||||
pte_clear(mm, addr, ptep);
|
||||
pte_clear(NULL, 0, ptep);
|
||||
|
||||
kunmap_atomic(ptep, KM_USER0);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle D$/I$ coherency.
|
||||
*
|
||||
* Note:
|
||||
* We only have one architecture bit for the page flags, so we cannot handle
|
||||
* cache aliasing, yet.
|
||||
*/
|
||||
|
||||
void
|
||||
update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
|
||||
void __init pgtable_cache_init(void)
|
||||
{
|
||||
unsigned long pfn = pte_pfn(pte);
|
||||
struct page *page;
|
||||
unsigned long vaddr = addr & PAGE_MASK;
|
||||
|
||||
if (!pfn_valid(pfn))
|
||||
return;
|
||||
|
||||
page = pfn_to_page(pfn);
|
||||
|
||||
invalidate_itlb_mapping(addr);
|
||||
invalidate_dtlb_mapping(addr);
|
||||
|
||||
/* We have a new mapping. Use it. */
|
||||
|
||||
write_dtlb_entry(pte, dtlb_probe(addr));
|
||||
|
||||
/* If the processor can execute from this page, synchronize D$/I$. */
|
||||
|
||||
if ((vma->vm_flags & VM_EXEC) != 0) {
|
||||
|
||||
write_itlb_entry(pte, itlb_probe(addr));
|
||||
|
||||
/* Synchronize caches, if not clean. */
|
||||
|
||||
if (!test_and_set_bit(PG_cache_clean, &page->flags)) {
|
||||
__flush_dcache_page(vaddr);
|
||||
__invalidate_icache_page(vaddr);
|
||||
pgtable_cache = kmem_cache_create("pgd",
|
||||
PAGE_SIZE, PAGE_SIZE,
|
||||
SLAB_HWCACHE_ALIGN,
|
||||
pgd_ctor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,29 +7,33 @@
|
|||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2001 - 2005 Tensilica Inc.
|
||||
* Copyright (C) 2001 - 2007 Tensilica Inc.
|
||||
*
|
||||
* Chris Zankel <chris@zankel.net>
|
||||
*/
|
||||
|
||||
/* Note: we might want to implement some of the loops as zero-overhead-loops,
|
||||
* where applicable and if supported by the processor.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/cacheasm.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
/* clear_page (page) */
|
||||
|
||||
/*
|
||||
* clear_page and clear_user_page are the same for non-cache-aliased configs.
|
||||
*
|
||||
* clear_page (unsigned long page)
|
||||
* a2
|
||||
*/
|
||||
|
||||
ENTRY(clear_page)
|
||||
entry a1, 16
|
||||
addi a4, a2, PAGE_SIZE
|
||||
movi a3, 0
|
||||
|
||||
1: s32i a3, a2, 0
|
||||
movi a3, 0
|
||||
__loopi a2, a7, PAGE_SIZE, 32
|
||||
s32i a3, a2, 0
|
||||
s32i a3, a2, 4
|
||||
s32i a3, a2, 8
|
||||
s32i a3, a2, 12
|
||||
|
@ -37,42 +41,277 @@ ENTRY(clear_page)
|
|||
s32i a3, a2, 20
|
||||
s32i a3, a2, 24
|
||||
s32i a3, a2, 28
|
||||
addi a2, a2, 32
|
||||
blt a2, a4, 1b
|
||||
__endla a2, a7, 32
|
||||
|
||||
retw
|
||||
|
||||
/*
|
||||
* copy_page and copy_user_page are the same for non-cache-aliased configs.
|
||||
*
|
||||
* copy_page (void *to, void *from)
|
||||
* a2 a3
|
||||
*/
|
||||
|
||||
ENTRY(copy_page)
|
||||
entry a1, 16
|
||||
addi a4, a2, PAGE_SIZE
|
||||
|
||||
1: l32i a5, a3, 0
|
||||
l32i a6, a3, 4
|
||||
l32i a7, a3, 8
|
||||
s32i a5, a2, 0
|
||||
s32i a6, a2, 4
|
||||
s32i a7, a2, 8
|
||||
l32i a5, a3, 12
|
||||
l32i a6, a3, 16
|
||||
l32i a7, a3, 20
|
||||
s32i a5, a2, 12
|
||||
s32i a6, a2, 16
|
||||
s32i a7, a2, 20
|
||||
l32i a5, a3, 24
|
||||
l32i a6, a3, 28
|
||||
s32i a5, a2, 24
|
||||
s32i a6, a2, 28
|
||||
__loopi a2, a4, PAGE_SIZE, 32
|
||||
|
||||
l32i a8, a3, 0
|
||||
l32i a9, a3, 4
|
||||
s32i a8, a2, 0
|
||||
s32i a9, a2, 4
|
||||
|
||||
l32i a8, a3, 8
|
||||
l32i a9, a3, 12
|
||||
s32i a8, a2, 8
|
||||
s32i a9, a2, 12
|
||||
|
||||
l32i a8, a3, 16
|
||||
l32i a9, a3, 20
|
||||
s32i a8, a2, 16
|
||||
s32i a9, a2, 20
|
||||
|
||||
l32i a8, a3, 24
|
||||
l32i a9, a3, 28
|
||||
s32i a8, a2, 24
|
||||
s32i a9, a2, 28
|
||||
|
||||
addi a2, a2, 32
|
||||
addi a3, a3, 32
|
||||
blt a2, a4, 1b
|
||||
|
||||
__endl a2, a4
|
||||
|
||||
retw
|
||||
|
||||
/*
|
||||
* If we have to deal with cache aliasing, we use temporary memory mappings
|
||||
* to ensure that the source and destination pages have the same color as
|
||||
* the virtual address. We use way 0 and 1 for temporary mappings in such cases.
|
||||
*
|
||||
* The temporary DTLB entries shouldn't be flushed by interrupts, but are
|
||||
* flushed by preemptive task switches. Special code in the
|
||||
* fast_second_level_miss handler re-established the temporary mapping.
|
||||
* It requires that the PPNs for the destination and source addresses are
|
||||
* in a6, and a7, respectively.
|
||||
*/
|
||||
|
||||
/* TLB miss exceptions are treated special in the following region */
|
||||
|
||||
ENTRY(__tlbtemp_mapping_start)
|
||||
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE)
|
||||
|
||||
/*
|
||||
* clear_user_page (void *addr, unsigned long vaddr, struct page *page)
|
||||
* a2 a3 a4
|
||||
*/
|
||||
|
||||
ENTRY(clear_user_page)
|
||||
entry a1, 32
|
||||
|
||||
/* Mark page dirty and determine alias. */
|
||||
|
||||
movi a7, (1 << PG_ARCH_1)
|
||||
l32i a5, a4, PAGE_FLAGS
|
||||
xor a6, a2, a3
|
||||
extui a3, a3, PAGE_SHIFT, DCACHE_ALIAS_ORDER
|
||||
extui a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER
|
||||
or a5, a5, a7
|
||||
slli a3, a3, PAGE_SHIFT
|
||||
s32i a5, a4, PAGE_FLAGS
|
||||
|
||||
/* Skip setting up a temporary DTLB if not aliased. */
|
||||
|
||||
beqz a6, 1f
|
||||
|
||||
/* Invalidate kernel page. */
|
||||
|
||||
mov a10, a2
|
||||
call8 __invalidate_dcache_page
|
||||
|
||||
/* Setup a temporary DTLB with the color of the VPN */
|
||||
|
||||
movi a4, -PAGE_OFFSET + (PAGE_KERNEL | _PAGE_HW_WRITE)
|
||||
movi a5, TLBTEMP_BASE_1 # virt
|
||||
add a6, a2, a4 # ppn
|
||||
add a2, a5, a3 # add 'color'
|
||||
|
||||
wdtlb a6, a2
|
||||
dsync
|
||||
|
||||
1: movi a3, 0
|
||||
__loopi a2, a7, PAGE_SIZE, 32
|
||||
s32i a3, a2, 0
|
||||
s32i a3, a2, 4
|
||||
s32i a3, a2, 8
|
||||
s32i a3, a2, 12
|
||||
s32i a3, a2, 16
|
||||
s32i a3, a2, 20
|
||||
s32i a3, a2, 24
|
||||
s32i a3, a2, 28
|
||||
__endla a2, a7, 32
|
||||
|
||||
bnez a6, 1f
|
||||
retw
|
||||
|
||||
/* We need to invalidate the temporary idtlb entry, if any. */
|
||||
|
||||
1: addi a2, a2, -PAGE_SIZE
|
||||
idtlb a2
|
||||
dsync
|
||||
|
||||
retw
|
||||
|
||||
/*
|
||||
* copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page)
|
||||
* a2 a3 a4 a5
|
||||
*/
|
||||
|
||||
ENTRY(copy_user_page)
|
||||
|
||||
entry a1, 32
|
||||
|
||||
/* Mark page dirty and determine alias for destination. */
|
||||
|
||||
movi a8, (1 << PG_ARCH_1)
|
||||
l32i a9, a5, PAGE_FLAGS
|
||||
xor a6, a2, a4
|
||||
xor a7, a3, a4
|
||||
extui a4, a4, PAGE_SHIFT, DCACHE_ALIAS_ORDER
|
||||
extui a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER
|
||||
extui a7, a7, PAGE_SHIFT, DCACHE_ALIAS_ORDER
|
||||
or a9, a9, a8
|
||||
slli a4, a4, PAGE_SHIFT
|
||||
s32i a9, a5, PAGE_FLAGS
|
||||
movi a5, -PAGE_OFFSET + (PAGE_KERNEL | _PAGE_HW_WRITE)
|
||||
|
||||
beqz a6, 1f
|
||||
|
||||
/* Invalidate dcache */
|
||||
|
||||
mov a10, a2
|
||||
call8 __invalidate_dcache_page
|
||||
|
||||
/* Setup a temporary DTLB with a matching color. */
|
||||
|
||||
movi a8, TLBTEMP_BASE_1 # base
|
||||
add a6, a2, a5 # ppn
|
||||
add a2, a8, a4 # add 'color'
|
||||
|
||||
wdtlb a6, a2
|
||||
dsync
|
||||
|
||||
/* Skip setting up a temporary DTLB for destination if not aliased. */
|
||||
|
||||
1: beqz a7, 1f
|
||||
|
||||
/* Setup a temporary DTLB with a matching color. */
|
||||
|
||||
movi a8, TLBTEMP_BASE_2 # base
|
||||
add a7, a3, a5 # ppn
|
||||
add a3, a8, a4
|
||||
addi a8, a3, 1 # way1
|
||||
|
||||
wdtlb a7, a8
|
||||
dsync
|
||||
|
||||
1: __loopi a2, a4, PAGE_SIZE, 32
|
||||
|
||||
l32i a8, a3, 0
|
||||
l32i a9, a3, 4
|
||||
s32i a8, a2, 0
|
||||
s32i a9, a2, 4
|
||||
|
||||
l32i a8, a3, 8
|
||||
l32i a9, a3, 12
|
||||
s32i a8, a2, 8
|
||||
s32i a9, a2, 12
|
||||
|
||||
l32i a8, a3, 16
|
||||
l32i a9, a3, 20
|
||||
s32i a8, a2, 16
|
||||
s32i a9, a2, 20
|
||||
|
||||
l32i a8, a3, 24
|
||||
l32i a9, a3, 28
|
||||
s32i a8, a2, 24
|
||||
s32i a9, a2, 28
|
||||
|
||||
addi a2, a2, 32
|
||||
addi a3, a3, 32
|
||||
|
||||
__endl a2, a4
|
||||
|
||||
/* We need to invalidate any temporary mapping! */
|
||||
|
||||
bnez a6, 1f
|
||||
bnez a7, 2f
|
||||
retw
|
||||
|
||||
1: addi a2, a2, -PAGE_SIZE
|
||||
idtlb a2
|
||||
dsync
|
||||
bnez a7, 2f
|
||||
retw
|
||||
|
||||
2: addi a3, a3, -PAGE_SIZE+1
|
||||
idtlb a3
|
||||
dsync
|
||||
|
||||
retw
|
||||
|
||||
#endif
|
||||
|
||||
#if (DCACHE_WAY_SIZE > PAGE_SIZE)
|
||||
|
||||
/*
|
||||
* void __flush_invalidate_dcache_page_alias (addr, phys)
|
||||
* a2 a3
|
||||
*/
|
||||
|
||||
ENTRY(__flush_invalidate_dcache_page_alias)
|
||||
entry sp, 16
|
||||
|
||||
movi a7, 0 # required for exception handler
|
||||
addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
|
||||
mov a4, a2
|
||||
wdtlb a6, a2
|
||||
dsync
|
||||
|
||||
___flush_invalidate_dcache_page a2 a3
|
||||
|
||||
idtlb a4
|
||||
dsync
|
||||
|
||||
retw
|
||||
|
||||
#endif
|
||||
|
||||
ENTRY(__tlbtemp_mapping_itlb)
|
||||
|
||||
#if (ICACHE_WAY_SIZE > PAGE_SIZE)
|
||||
|
||||
ENTRY(__invalidate_icache_page_alias)
|
||||
entry sp, 16
|
||||
|
||||
addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
|
||||
mov a4, a2
|
||||
witlb a6, a2
|
||||
isync
|
||||
|
||||
___invalidate_icache_page a2 a3
|
||||
|
||||
iitlb a4
|
||||
isync
|
||||
retw
|
||||
|
||||
#endif
|
||||
|
||||
/* End of special treatment in tlb miss exception */
|
||||
|
||||
ENTRY(__tlbtemp_mapping_end)
|
||||
|
||||
/*
|
||||
* void __invalidate_icache_page(ulong start)
|
||||
*/
|
||||
|
@ -121,8 +360,6 @@ ENTRY(__flush_dcache_page)
|
|||
dsync
|
||||
retw
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void __invalidate_icache_range(ulong start, ulong size)
|
||||
*/
|
||||
|
@ -168,7 +405,6 @@ ENTRY(__invalidate_dcache_range)
|
|||
|
||||
___invalidate_dcache_range a2 a3 a4
|
||||
|
||||
|
||||
retw
|
||||
|
||||
/*
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <linux/param.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serialP.h>
|
||||
#include <linux/console.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/irq.h>
|
||||
|
|
|
@ -1075,12 +1075,6 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
|
|||
*/
|
||||
return;
|
||||
|
||||
if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) {
|
||||
printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
|
||||
__FUNCTION__, tag);
|
||||
return;
|
||||
}
|
||||
|
||||
list_del_init(&rq->queuelist);
|
||||
rq->cmd_flags &= ~REQ_QUEUED;
|
||||
rq->tag = -1;
|
||||
|
@ -1090,6 +1084,19 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
|
|||
__FUNCTION__, tag);
|
||||
|
||||
bqt->tag_index[tag] = NULL;
|
||||
|
||||
/*
|
||||
* We use test_and_clear_bit's memory ordering properties here.
|
||||
* The tag_map bit acts as a lock for tag_index[bit], so we need
|
||||
* a barrer before clearing the bit (precisely: release semantics).
|
||||
* Could use clear_bit_unlock when it is merged.
|
||||
*/
|
||||
if (unlikely(!test_and_clear_bit(tag, bqt->tag_map))) {
|
||||
printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
|
||||
__FUNCTION__, tag);
|
||||
return;
|
||||
}
|
||||
|
||||
bqt->busy--;
|
||||
}
|
||||
|
||||
|
@ -1136,6 +1143,10 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
|
|||
return 1;
|
||||
|
||||
} while (test_and_set_bit(tag, bqt->tag_map));
|
||||
/*
|
||||
* We rely on test_and_set_bit providing lock memory ordering semantics
|
||||
* (could use test_and_set_bit_lock when it is merged).
|
||||
*/
|
||||
|
||||
rq->cmd_flags |= REQ_QUEUED;
|
||||
rq->tag = tag;
|
||||
|
|
|
@ -240,7 +240,7 @@ int acpi_bus_generate_netlink_event(const char *device_class,
|
|||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_generate_netlink_event);
|
||||
EXPORT_SYMBOL(acpi_bus_generate_netlink_event);
|
||||
|
||||
static int acpi_event_genetlink_init(void)
|
||||
{
|
||||
|
|
|
@ -724,6 +724,25 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
|
|||
return;
|
||||
}
|
||||
|
||||
static int acpi_cpu_soft_notify(struct notifier_block *nfb,
|
||||
unsigned long action, void *hcpu)
|
||||
{
|
||||
unsigned int cpu = (unsigned long)hcpu;
|
||||
struct acpi_processor *pr = processors[cpu];
|
||||
|
||||
if (action == CPU_ONLINE && pr) {
|
||||
acpi_processor_ppc_has_changed(pr);
|
||||
acpi_processor_cst_has_changed(pr);
|
||||
acpi_processor_tstate_has_changed(pr);
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block acpi_cpu_notifier =
|
||||
{
|
||||
.notifier_call = acpi_cpu_soft_notify,
|
||||
};
|
||||
|
||||
static int acpi_processor_add(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_processor *pr = NULL;
|
||||
|
@ -987,6 +1006,7 @@ void acpi_processor_install_hotplug_notify(void)
|
|||
ACPI_UINT32_MAX,
|
||||
processor_walk_namespace_cb, &action, NULL);
|
||||
#endif
|
||||
register_hotcpu_notifier(&acpi_cpu_notifier);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -999,6 +1019,7 @@ void acpi_processor_uninstall_hotplug_notify(void)
|
|||
ACPI_UINT32_MAX,
|
||||
processor_walk_namespace_cb, &action, NULL);
|
||||
#endif
|
||||
unregister_hotcpu_notifier(&acpi_cpu_notifier);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
ACPI_MODULE_NAME("sleep")
|
||||
#ifdef CONFIG_ACPI_PROCFS_SLEEP
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
int i;
|
||||
|
@ -76,7 +76,7 @@ acpi_system_write_sleep(struct file *file,
|
|||
Done:
|
||||
return error ? error : count;
|
||||
}
|
||||
#endif /* CONFIG_ACPI_PROCFS_SLEEP */
|
||||
#endif /* CONFIG_ACPI_PROCFS */
|
||||
|
||||
#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86)
|
||||
/* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */
|
||||
|
@ -471,7 +471,7 @@ static const struct file_operations acpi_system_wakeup_device_fops = {
|
|||
.release = single_release,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS_SLEEP
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
static const struct file_operations acpi_system_sleep_fops = {
|
||||
.open = acpi_system_sleep_open_fs,
|
||||
.read = seq_read,
|
||||
|
@ -479,7 +479,7 @@ static const struct file_operations acpi_system_sleep_fops = {
|
|||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
#endif /* CONFIG_ACPI_PROCFS_SLEEP */
|
||||
#endif /* CONFIG_ACPI_PROCFS */
|
||||
|
||||
#ifdef HAVE_ACPI_LEGACY_ALARM
|
||||
static const struct file_operations acpi_system_alarm_fops = {
|
||||
|
@ -506,7 +506,7 @@ static int __init acpi_sleep_proc_init(void)
|
|||
if (acpi_disabled)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_ACPI_PROCFS_SLEEP
|
||||
#ifdef CONFIG_ACPI_PROCFS
|
||||
/* 'sleep' [R/W] */
|
||||
entry =
|
||||
create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR,
|
||||
|
|
|
@ -679,13 +679,25 @@ static int device_add_class_symlinks(struct device *dev)
|
|||
goto out_subsys;
|
||||
}
|
||||
if (dev->parent) {
|
||||
error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
|
||||
#ifdef CONFIG_SYSFS_DEPRECATED
|
||||
{
|
||||
struct device *parent = dev->parent;
|
||||
char *class_name;
|
||||
|
||||
/*
|
||||
* In old sysfs stacked class devices had 'device'
|
||||
* link pointing to real device instead of parent
|
||||
*/
|
||||
while (parent->class && !parent->bus && parent->parent)
|
||||
parent = parent->parent;
|
||||
|
||||
error = sysfs_create_link(&dev->kobj,
|
||||
&parent->kobj,
|
||||
"device");
|
||||
if (error)
|
||||
goto out_busid;
|
||||
#ifdef CONFIG_SYSFS_DEPRECATED
|
||||
{
|
||||
char * class_name = make_class_name(dev->class->name,
|
||||
|
||||
class_name = make_class_name(dev->class->name,
|
||||
&dev->kobj);
|
||||
if (class_name)
|
||||
error = sysfs_create_link(&dev->parent->kobj,
|
||||
|
@ -694,6 +706,11 @@ static int device_add_class_symlinks(struct device *dev)
|
|||
if (error)
|
||||
goto out_device;
|
||||
}
|
||||
#else
|
||||
error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
|
||||
"device");
|
||||
if (error)
|
||||
goto out_busid;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <linux/genhd.h>
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/blkpg.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/mm.h>
|
||||
|
|
|
@ -176,7 +176,7 @@ struct agp_bridge_data {
|
|||
#define I830_GMCH_MEM_MASK 0x1
|
||||
#define I830_GMCH_MEM_64M 0x1
|
||||
#define I830_GMCH_MEM_128M 0
|
||||
#define I830_GMCH_GMS_MASK 0xF0
|
||||
#define I830_GMCH_GMS_MASK 0x70
|
||||
#define I830_GMCH_GMS_DISABLED 0x00
|
||||
#define I830_GMCH_GMS_LOCAL 0x10
|
||||
#define I830_GMCH_GMS_STOLEN_512 0x20
|
||||
|
@ -190,6 +190,7 @@ struct agp_bridge_data {
|
|||
#define INTEL_I830_ERRSTS 0x92
|
||||
|
||||
/* Intel 855GM/852GM registers */
|
||||
#define I855_GMCH_GMS_MASK 0xF0
|
||||
#define I855_GMCH_GMS_STOLEN_0M 0x0
|
||||
#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
|
||||
#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4)
|
||||
|
|
|
@ -511,7 +511,7 @@ static void intel_i830_init_gtt_entries(void)
|
|||
*/
|
||||
if (IS_G33)
|
||||
size = 0;
|
||||
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
|
||||
switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
|
||||
case I855_GMCH_GMS_STOLEN_1M:
|
||||
gtt_entries = MB(1) - KB(size);
|
||||
break;
|
||||
|
|
|
@ -2215,7 +2215,8 @@ static int ipmi_pci_resume(struct pci_dev *pdev)
|
|||
|
||||
static struct pci_device_id ipmi_pci_devices[] = {
|
||||
{ PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
|
||||
{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }
|
||||
{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) },
|
||||
{ 0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
/*
|
||||
* Page types allocated by the device.
|
||||
*/
|
||||
enum {
|
||||
enum mspec_page_type {
|
||||
MSPEC_FETCHOP = 1,
|
||||
MSPEC_CACHED,
|
||||
MSPEC_UNCACHED
|
||||
|
@ -83,15 +83,25 @@ static int is_sn2;
|
|||
* One of these structures is allocated when an mspec region is mmaped. The
|
||||
* structure is pointed to by the vma->vm_private_data field in the vma struct.
|
||||
* This structure is used to record the addresses of the mspec pages.
|
||||
* This structure is shared by all vma's that are split off from the
|
||||
* original vma when split_vma()'s are done.
|
||||
*
|
||||
* The refcnt is incremented atomically because mm->mmap_sem does not
|
||||
* protect in fork case where multiple tasks share the vma_data.
|
||||
*/
|
||||
struct vma_data {
|
||||
atomic_t refcnt; /* Number of vmas sharing the data. */
|
||||
spinlock_t lock; /* Serialize access to the vma. */
|
||||
spinlock_t lock; /* Serialize access to this structure. */
|
||||
int count; /* Number of pages allocated. */
|
||||
int type; /* Type of pages allocated. */
|
||||
enum mspec_page_type type; /* Type of pages allocated. */
|
||||
int flags; /* See VMD_xxx below. */
|
||||
unsigned long vm_start; /* Original (unsplit) base. */
|
||||
unsigned long vm_end; /* Original (unsplit) end. */
|
||||
unsigned long maddr[0]; /* Array of MSPEC addresses. */
|
||||
};
|
||||
|
||||
#define VMD_VMALLOCED 0x1 /* vmalloc'd rather than kmalloc'd */
|
||||
|
||||
/* used on shub2 to clear FOP cache in the HUB */
|
||||
static unsigned long scratch_page[MAX_NUMNODES];
|
||||
#define SH2_AMO_CACHE_ENTRIES 4
|
||||
|
@ -129,8 +139,8 @@ mspec_zero_block(unsigned long addr, int len)
|
|||
* mspec_open
|
||||
*
|
||||
* Called when a device mapping is created by a means other than mmap
|
||||
* (via fork, etc.). Increments the reference count on the underlying
|
||||
* mspec data so it is not freed prematurely.
|
||||
* (via fork, munmap, etc.). Increments the reference count on the
|
||||
* underlying mspec data so it is not freed prematurely.
|
||||
*/
|
||||
static void
|
||||
mspec_open(struct vm_area_struct *vma)
|
||||
|
@ -151,34 +161,44 @@ static void
|
|||
mspec_close(struct vm_area_struct *vma)
|
||||
{
|
||||
struct vma_data *vdata;
|
||||
int i, pages, result, vdata_size;
|
||||
int index, last_index, result;
|
||||
unsigned long my_page;
|
||||
|
||||
vdata = vma->vm_private_data;
|
||||
if (!atomic_dec_and_test(&vdata->refcnt))
|
||||
return;
|
||||
|
||||
pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
|
||||
vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
|
||||
for (i = 0; i < pages; i++) {
|
||||
if (vdata->maddr[i] == 0)
|
||||
BUG_ON(vma->vm_start < vdata->vm_start || vma->vm_end > vdata->vm_end);
|
||||
|
||||
spin_lock(&vdata->lock);
|
||||
index = (vma->vm_start - vdata->vm_start) >> PAGE_SHIFT;
|
||||
last_index = (vma->vm_end - vdata->vm_start) >> PAGE_SHIFT;
|
||||
for (; index < last_index; index++) {
|
||||
if (vdata->maddr[index] == 0)
|
||||
continue;
|
||||
/*
|
||||
* Clear the page before sticking it back
|
||||
* into the pool.
|
||||
*/
|
||||
result = mspec_zero_block(vdata->maddr[i], PAGE_SIZE);
|
||||
my_page = vdata->maddr[index];
|
||||
vdata->maddr[index] = 0;
|
||||
spin_unlock(&vdata->lock);
|
||||
result = mspec_zero_block(my_page, PAGE_SIZE);
|
||||
if (!result)
|
||||
uncached_free_page(vdata->maddr[i]);
|
||||
uncached_free_page(my_page);
|
||||
else
|
||||
printk(KERN_WARNING "mspec_close(): "
|
||||
"failed to zero page %i\n",
|
||||
result);
|
||||
spin_lock(&vdata->lock);
|
||||
}
|
||||
spin_unlock(&vdata->lock);
|
||||
|
||||
if (vdata_size <= PAGE_SIZE)
|
||||
kfree(vdata);
|
||||
else
|
||||
if (!atomic_dec_and_test(&vdata->refcnt))
|
||||
return;
|
||||
|
||||
if (vdata->flags & VMD_VMALLOCED)
|
||||
vfree(vdata);
|
||||
else
|
||||
kfree(vdata);
|
||||
}
|
||||
|
||||
|
||||
|
@ -195,7 +215,8 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address)
|
|||
int index;
|
||||
struct vma_data *vdata = vma->vm_private_data;
|
||||
|
||||
index = (address - vma->vm_start) >> PAGE_SHIFT;
|
||||
BUG_ON(address < vdata->vm_start || address >= vdata->vm_end);
|
||||
index = (address - vdata->vm_start) >> PAGE_SHIFT;
|
||||
maddr = (volatile unsigned long) vdata->maddr[index];
|
||||
if (maddr == 0) {
|
||||
maddr = uncached_alloc_page(numa_node_id());
|
||||
|
@ -237,10 +258,11 @@ static struct vm_operations_struct mspec_vm_ops = {
|
|||
* underlying pages.
|
||||
*/
|
||||
static int
|
||||
mspec_mmap(struct file *file, struct vm_area_struct *vma, int type)
|
||||
mspec_mmap(struct file *file, struct vm_area_struct *vma,
|
||||
enum mspec_page_type type)
|
||||
{
|
||||
struct vma_data *vdata;
|
||||
int pages, vdata_size;
|
||||
int pages, vdata_size, flags = 0;
|
||||
|
||||
if (vma->vm_pgoff != 0)
|
||||
return -EINVAL;
|
||||
|
@ -255,12 +277,17 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, int type)
|
|||
vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
|
||||
if (vdata_size <= PAGE_SIZE)
|
||||
vdata = kmalloc(vdata_size, GFP_KERNEL);
|
||||
else
|
||||
else {
|
||||
vdata = vmalloc(vdata_size);
|
||||
flags = VMD_VMALLOCED;
|
||||
}
|
||||
if (!vdata)
|
||||
return -ENOMEM;
|
||||
memset(vdata, 0, vdata_size);
|
||||
|
||||
vdata->vm_start = vma->vm_start;
|
||||
vdata->vm_end = vma->vm_end;
|
||||
vdata->flags = flags;
|
||||
vdata->type = type;
|
||||
spin_lock_init(&vdata->lock);
|
||||
vdata->refcnt = ATOMIC_INIT(1);
|
||||
|
|
|
@ -795,6 +795,19 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
|
|||
if (L_ICANON(tty))
|
||||
retval = inq_canon(tty);
|
||||
return put_user(retval, (unsigned int __user *) arg);
|
||||
#ifndef TCGETS2
|
||||
case TIOCGLCKTRMIOS:
|
||||
if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case TIOCSLCKTRMIOS:
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
#else
|
||||
case TIOCGLCKTRMIOS:
|
||||
if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
|
||||
return -EFAULT;
|
||||
|
@ -806,6 +819,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
|
|||
if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case TIOCPKT:
|
||||
{
|
||||
|
|
|
@ -487,6 +487,7 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id)
|
|||
*/
|
||||
static const struct drive_list_entry hpa_list[] = {
|
||||
{ "ST340823A", NULL },
|
||||
{ "ST320413A", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -1802,9 +1802,7 @@ pmac_ide_dma_check(ide_drive_t *drive)
|
|||
{
|
||||
struct hd_driveid *id = drive->id;
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
|
||||
int enable = 1;
|
||||
int map;
|
||||
drive->using_dma = 0;
|
||||
|
||||
if (drive->media == ide_floppy)
|
||||
|
|
|
@ -619,7 +619,7 @@ unsigned long segment_base(u16 selector);
|
|||
void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||
const u8 *old, const u8 *new, int bytes);
|
||||
int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva);
|
||||
void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
|
||||
void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
|
||||
int kvm_mmu_load(struct kvm_vcpu *vcpu);
|
||||
void kvm_mmu_unload(struct kvm_vcpu *vcpu);
|
||||
|
||||
|
@ -628,11 +628,15 @@ int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
|||
static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
|
||||
u32 error_code)
|
||||
{
|
||||
if (unlikely(vcpu->kvm->n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
|
||||
kvm_mmu_free_some_pages(vcpu);
|
||||
return vcpu->mmu.page_fault(vcpu, gva, error_code);
|
||||
}
|
||||
|
||||
static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (unlikely(vcpu->kvm->n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
|
||||
__kvm_mmu_free_some_pages(vcpu);
|
||||
}
|
||||
|
||||
static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (likely(vcpu->mmu.root_hpa != INVALID_PAGE))
|
||||
|
|
|
@ -273,12 +273,14 @@ static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu)
|
|||
int r;
|
||||
|
||||
r = __mmu_topup_memory_caches(vcpu, GFP_NOWAIT);
|
||||
kvm_mmu_free_some_pages(vcpu);
|
||||
if (r < 0) {
|
||||
spin_unlock(&vcpu->kvm->lock);
|
||||
kvm_arch_ops->vcpu_put(vcpu);
|
||||
r = __mmu_topup_memory_caches(vcpu, GFP_KERNEL);
|
||||
kvm_arch_ops->vcpu_load(vcpu);
|
||||
spin_lock(&vcpu->kvm->lock);
|
||||
kvm_mmu_free_some_pages(vcpu);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
@ -1208,7 +1210,7 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
|
|||
return kvm_mmu_unprotect_page(vcpu, gpa >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
|
||||
void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
while (vcpu->kvm->n_free_mmu_pages < KVM_REFILL_PAGES) {
|
||||
struct kvm_mmu_page *page;
|
||||
|
@ -1218,7 +1220,6 @@ void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
|
|||
kvm_mmu_zap_page(vcpu->kvm, page);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_mmu_free_some_pages);
|
||||
|
||||
static void free_mmu_pages(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <linux/bio.h>
|
||||
|
||||
#ifdef CONFIG_BLOCK
|
||||
|
||||
struct bio_list {
|
||||
struct bio *head;
|
||||
struct bio *tail;
|
||||
|
@ -106,4 +108,5 @@ static inline struct bio *bio_list_get(struct bio_list *bl)
|
|||
return bio;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BLOCK */
|
||||
#endif
|
||||
|
|
|
@ -580,7 +580,7 @@ struct cx8802_dev * cx8802_get_device(struct inode *inode)
|
|||
|
||||
list_for_each(list,&cx8802_devlist) {
|
||||
h = list_entry(list, struct cx8802_dev, devlist);
|
||||
if (h->mpeg_dev->minor == minor)
|
||||
if (h->mpeg_dev && h->mpeg_dev->minor == minor)
|
||||
return h;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,7 +190,9 @@ static void ivtv_update_pgm_info(struct ivtv *itv)
|
|||
int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
|
||||
struct v4l2_enc_idx_entry *e = itv->pgm_info + idx;
|
||||
u32 addr = itv->pgm_info_offset + 4 + idx * 24;
|
||||
const int mapping[] = { V4L2_ENC_IDX_FRAME_P, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_B, 0 };
|
||||
const int mapping[8] = { -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P, -1,
|
||||
V4L2_ENC_IDX_FRAME_B, -1, -1, -1 };
|
||||
// 1=I, 2=P, 4=B
|
||||
|
||||
e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32);
|
||||
if (e->offset > itv->mpg_data_received) {
|
||||
|
@ -199,7 +201,7 @@ static void ivtv_update_pgm_info(struct ivtv *itv)
|
|||
e->offset += itv->vbi_data_inserted;
|
||||
e->length = read_enc(addr);
|
||||
e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32);
|
||||
e->flags = mapping[read_enc(addr + 12) & 3];
|
||||
e->flags = mapping[read_enc(addr + 12) & 7];
|
||||
i++;
|
||||
}
|
||||
itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
|
||||
|
|
|
@ -1099,14 +1099,21 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
|
|||
|
||||
case VIDIOC_G_ENC_INDEX: {
|
||||
struct v4l2_enc_idx *idx = arg;
|
||||
struct v4l2_enc_idx_entry *e = idx->entry;
|
||||
int entries;
|
||||
int i;
|
||||
|
||||
idx->entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
|
||||
entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
|
||||
IVTV_MAX_PGM_INDEX;
|
||||
if (idx->entries > V4L2_ENC_IDX_ENTRIES)
|
||||
idx->entries = V4L2_ENC_IDX_ENTRIES;
|
||||
for (i = 0; i < idx->entries; i++) {
|
||||
idx->entry[i] = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
|
||||
if (entries > V4L2_ENC_IDX_ENTRIES)
|
||||
entries = V4L2_ENC_IDX_ENTRIES;
|
||||
idx->entries = 0;
|
||||
for (i = 0; i < entries; i++) {
|
||||
*e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
|
||||
if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
|
||||
idx->entries++;
|
||||
e++;
|
||||
}
|
||||
}
|
||||
itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
|
||||
break;
|
||||
|
|
|
@ -1243,7 +1243,7 @@ static int pwc_video_close(struct inode *inode, struct file *file)
|
|||
PWC_ERROR("Failed to power down camera (%d)\n", i);
|
||||
}
|
||||
pdev->vopen--;
|
||||
PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i);
|
||||
PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
|
||||
} else {
|
||||
pwc_cleanup(pdev);
|
||||
/* Free memory (don't set pdev to 0 just yet) */
|
||||
|
|
|
@ -1537,18 +1537,18 @@ struct saa7134_board saa7134_boards[] = {
|
|||
},{
|
||||
.name = name_comp1,
|
||||
.vmux = 0,
|
||||
.amux = LINE2,
|
||||
.gpio = 0x00,
|
||||
.amux = LINE1,
|
||||
.gpio = 0x02,
|
||||
},{
|
||||
.name = name_comp2,
|
||||
.vmux = 3,
|
||||
.amux = LINE2,
|
||||
.gpio = 0x00,
|
||||
.amux = LINE1,
|
||||
.gpio = 0x02,
|
||||
},{
|
||||
.name = name_svideo,
|
||||
.vmux = 8,
|
||||
.amux = LINE2,
|
||||
.gpio = 0x00,
|
||||
.amux = LINE1,
|
||||
.gpio = 0x02,
|
||||
}},
|
||||
.radio = {
|
||||
.name = name_radio,
|
||||
|
|
|
@ -130,7 +130,7 @@ static int saa7191_write_reg(struct i2c_client *client, u8 reg,
|
|||
|
||||
/* the first byte of data must be the first subaddress number (register) */
|
||||
static int saa7191_write_block(struct i2c_client *client,
|
||||
u8 length, u8 *data)
|
||||
u8 length, const u8 *data)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
@ -592,7 +592,7 @@ static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
|
|||
if (err)
|
||||
goto out_free_decoder;
|
||||
|
||||
err = saa7191_write_block(client, sizeof(initseq), (u8 *)initseq);
|
||||
err = saa7191_write_block(client, sizeof(initseq), initseq);
|
||||
if (err) {
|
||||
printk(KERN_ERR "SAA7191 initialization failed\n");
|
||||
goto out_detach_client;
|
||||
|
|
|
@ -1081,6 +1081,7 @@ struct usb_device_id usbvision_table [] = {
|
|||
{ USB_DEVICE(0x2304, 0x0301), .driver_info=PINNA_LINX_VD_IN_CAB_PAL },
|
||||
{ USB_DEVICE(0x2304, 0x0419), .driver_info=PINNA_PCTV_BUNGEE_PAL_FM },
|
||||
{ USB_DEVICE(0x2400, 0x4200), .driver_info=HPG_WINTV },
|
||||
{ }, /* terminate list */
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE (usb, usbvision_table);
|
||||
|
|
|
@ -202,25 +202,5 @@ config THINKPAD_ACPI_BAY
|
|||
|
||||
If you are not sure, say Y here.
|
||||
|
||||
config THINKPAD_ACPI_INPUT_ENABLED
|
||||
bool "Enable input layer support by default"
|
||||
depends on THINKPAD_ACPI
|
||||
default n
|
||||
---help---
|
||||
This option enables thinkpad-acpi hot key handling over the input
|
||||
layer at driver load time. When it is unset, the driver does not
|
||||
enable hot key handling by default, and also starts up with a mostly
|
||||
empty keymap.
|
||||
|
||||
This option should be enabled if you have a new enough HAL or other
|
||||
userspace support that properly handles the thinkpad-acpi event
|
||||
device. It auto-tunes the hot key support to those reported by the
|
||||
firmware and enables it automatically.
|
||||
|
||||
If unsure, say N here to retain the old behaviour of ibm-acpi, and
|
||||
thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and
|
||||
set up the thinkpad-acpi hot key handling using the sysfs interace
|
||||
after loading the driver.
|
||||
|
||||
|
||||
endif # MISC_DEVICES
|
||||
|
|
|
@ -353,7 +353,7 @@ static int __init msi_init(void)
|
|||
if (IS_ERR(msibl_device))
|
||||
return PTR_ERR(msibl_device);
|
||||
|
||||
msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1,
|
||||
msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
|
||||
|
||||
ret = platform_driver_register(&msipf_driver);
|
||||
if (ret)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define IBM_VERSION "0.15"
|
||||
#define IBM_VERSION "0.16"
|
||||
#define TPACPI_SYSFS_VERSION 0x010000
|
||||
|
||||
/*
|
||||
|
@ -906,9 +906,26 @@ static ssize_t hotkey_radio_sw_show(struct device *dev,
|
|||
static struct device_attribute dev_attr_hotkey_radio_sw =
|
||||
__ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
|
||||
|
||||
/* sysfs hotkey report_mode -------------------------------------------- */
|
||||
static ssize_t hotkey_report_mode_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n",
|
||||
(hotkey_report_mode != 0) ? hotkey_report_mode : 1);
|
||||
}
|
||||
|
||||
static struct device_attribute dev_attr_hotkey_report_mode =
|
||||
__ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static struct attribute *hotkey_mask_attributes[] = {
|
||||
static struct attribute *hotkey_attributes[] __initdata = {
|
||||
&dev_attr_hotkey_enable.attr,
|
||||
&dev_attr_hotkey_report_mode.attr,
|
||||
};
|
||||
|
||||
static struct attribute *hotkey_mask_attributes[] __initdata = {
|
||||
&dev_attr_hotkey_mask.attr,
|
||||
&dev_attr_hotkey_bios_enabled.attr,
|
||||
&dev_attr_hotkey_bios_mask.attr,
|
||||
|
@ -987,11 +1004,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
|||
str_supported(tp_features.hotkey));
|
||||
|
||||
if (tp_features.hotkey) {
|
||||
hotkey_dev_attributes = create_attr_set(7, NULL);
|
||||
hotkey_dev_attributes = create_attr_set(8, NULL);
|
||||
if (!hotkey_dev_attributes)
|
||||
return -ENOMEM;
|
||||
res = add_to_attr_set(hotkey_dev_attributes,
|
||||
&dev_attr_hotkey_enable.attr);
|
||||
res = add_many_to_attr_set(hotkey_dev_attributes,
|
||||
hotkey_attributes,
|
||||
ARRAY_SIZE(hotkey_attributes));
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
|
@ -1055,11 +1073,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
|||
TPACPI_HOTKEY_MAP_SIZE);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
|
||||
for (i = 0; i < 12; i++)
|
||||
hotkey_keycode_map[i] = KEY_UNKNOWN;
|
||||
#endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
|
||||
|
||||
set_bit(EV_KEY, tpacpi_inputdev->evbit);
|
||||
set_bit(EV_MSC, tpacpi_inputdev->evbit);
|
||||
set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
|
||||
|
@ -1081,14 +1094,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
|||
set_bit(SW_RADIO, tpacpi_inputdev->swbit);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
|
||||
dbg_printk(TPACPI_DBG_INIT,
|
||||
"enabling hot key handling\n");
|
||||
res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)
|
||||
| hotkey_orig_mask);
|
||||
if (res)
|
||||
return res;
|
||||
#endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
|
||||
|
||||
dbg_printk(TPACPI_DBG_INIT,
|
||||
"legacy hot key reporting over procfs %s\n",
|
||||
(hotkey_report_mode < 2) ?
|
||||
"enabled" : "disabled");
|
||||
}
|
||||
|
||||
return (tp_features.hotkey)? 0 : 1;
|
||||
|
@ -1142,10 +1158,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
|
|||
{
|
||||
u32 hkey;
|
||||
unsigned int keycode, scancode;
|
||||
int sendacpi = 1;
|
||||
int send_acpi_ev = 0;
|
||||
|
||||
if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
|
||||
if (tpacpi_inputdev->users > 0) {
|
||||
switch (hkey >> 12) {
|
||||
case 1:
|
||||
/* 0x1000-0x1FFF: key presses */
|
||||
|
@ -1154,12 +1169,11 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
|
|||
scancode--;
|
||||
keycode = hotkey_keycode_map[scancode];
|
||||
tpacpi_input_send_key(scancode, keycode);
|
||||
sendacpi = (keycode == KEY_RESERVED
|
||||
|| keycode == KEY_UNKNOWN);
|
||||
} else {
|
||||
printk(IBM_ERR
|
||||
"hotkey 0x%04x out of range for keyboard map\n",
|
||||
hkey);
|
||||
send_acpi_ev = 1;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
|
@ -1170,13 +1184,13 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
|
|||
printk(IBM_ERR
|
||||
"unknown LID-related hotkey event: 0x%04x\n",
|
||||
hkey);
|
||||
send_acpi_ev = 1;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
/* 0x7000-0x7FFF: misc */
|
||||
if (tp_features.hotkey_wlsw && hkey == 0x7000) {
|
||||
tpacpi_input_send_radiosw();
|
||||
sendacpi = 0;
|
||||
break;
|
||||
}
|
||||
/* fallthrough to default */
|
||||
|
@ -1185,15 +1199,24 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
|
|||
/* 0x2305 - T43 waking up due to bay lever eject while aslept */
|
||||
/* case 3: ultra-bay related. maybe bay in dock? */
|
||||
/* 0x3003 - T43 after wake up by bay lever eject (0x2305) */
|
||||
printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey);
|
||||
printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);
|
||||
send_acpi_ev = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sendacpi)
|
||||
acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
|
||||
} else {
|
||||
printk(IBM_ERR "unknown hotkey notification event %d\n", event);
|
||||
acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);
|
||||
hkey = 0;
|
||||
send_acpi_ev = 1;
|
||||
}
|
||||
|
||||
/* Legacy events */
|
||||
if (send_acpi_ev || hotkey_report_mode < 2)
|
||||
acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
|
||||
|
||||
/* netlink events */
|
||||
if (send_acpi_ev) {
|
||||
acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
|
||||
ibm->acpi->device->dev.bus_id,
|
||||
event, hkey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4623,6 +4646,9 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
|
|||
static int brightness_mode;
|
||||
module_param_named(brightness_mode, brightness_mode, int, 0);
|
||||
|
||||
static unsigned int hotkey_report_mode;
|
||||
module_param(hotkey_report_mode, uint, 0);
|
||||
|
||||
#define IBM_PARAM(feature) \
|
||||
module_param_call(feature, set_ibm_param, NULL, NULL, 0)
|
||||
|
||||
|
@ -4648,6 +4674,10 @@ static int __init thinkpad_acpi_module_init(void)
|
|||
{
|
||||
int ret, i;
|
||||
|
||||
/* Parameter checking */
|
||||
if (hotkey_report_mode > 2)
|
||||
return -EINVAL;
|
||||
|
||||
/* Driver-level probe */
|
||||
|
||||
get_thinkpad_model_data(&thinkpad_id);
|
||||
|
|
|
@ -181,6 +181,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv);
|
|||
static int experimental;
|
||||
static u32 dbg_level;
|
||||
static int force_load;
|
||||
static unsigned int hotkey_report_mode;
|
||||
|
||||
static int thinkpad_acpi_module_init(void);
|
||||
static void thinkpad_acpi_module_exit(void);
|
||||
|
|
|
@ -816,7 +816,8 @@ static void __devexit cafe_nand_remove(struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
static struct pci_device_id cafe_nand_tbl[] = {
|
||||
{ 0x11ab, 0x4100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MEMORY_FLASH << 8, 0xFFFF0 }
|
||||
{ 0x11ab, 0x4100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MEMORY_FLASH << 8, 0xFFFF0 },
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, cafe_nand_tbl);
|
||||
|
|
|
@ -2177,7 +2177,7 @@ config SKGE
|
|||
with better performance and more complete ethtool support.
|
||||
|
||||
It does not support the link failover and network management
|
||||
features available in the hardware.
|
||||
features that "portable" vendor supplied sk98lin driver does.
|
||||
|
||||
This driver supports adapters based on the original Yukon chipset:
|
||||
Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
|
||||
|
@ -2215,6 +2215,93 @@ config SKY2_DEBUG
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config SK98LIN
|
||||
tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)"
|
||||
depends on PCI
|
||||
---help---
|
||||
Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
|
||||
compliant Gigabit Ethernet Adapter.
|
||||
|
||||
This driver supports the original Yukon chipset. This driver is
|
||||
deprecated and will be removed from the kernel in the near future,
|
||||
it has been replaced by the skge driver. skge is cleaner and
|
||||
seems to work better.
|
||||
|
||||
This driver does not support the newer Yukon2 chipset. A separate
|
||||
driver, sky2, is provided to support Yukon2-based adapters.
|
||||
|
||||
The following adapters are supported by this driver:
|
||||
- 3Com 3C940 Gigabit LOM Ethernet Adapter
|
||||
- 3Com 3C941 Gigabit LOM Ethernet Adapter
|
||||
- Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
|
||||
- Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
|
||||
- Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
|
||||
- Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
|
||||
- Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
|
||||
- Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
|
||||
- Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
|
||||
- Allied Telesyn AT-2971T Gigabit Ethernet Adapter
|
||||
- Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
|
||||
- EG1032 v2 Instant Gigabit Network Adapter
|
||||
- EG1064 v2 Instant Gigabit Network Adapter
|
||||
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
|
||||
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
|
||||
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
|
||||
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
|
||||
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
|
||||
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
|
||||
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
|
||||
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
|
||||
- Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
|
||||
- Marvell RDK-8001 Adapter
|
||||
- Marvell RDK-8002 Adapter
|
||||
- Marvell RDK-8003 Adapter
|
||||
- Marvell RDK-8004 Adapter
|
||||
- Marvell RDK-8006 Adapter
|
||||
- Marvell RDK-8007 Adapter
|
||||
- Marvell RDK-8008 Adapter
|
||||
- Marvell RDK-8009 Adapter
|
||||
- Marvell RDK-8010 Adapter
|
||||
- Marvell RDK-8011 Adapter
|
||||
- Marvell RDK-8012 Adapter
|
||||
- Marvell RDK-8052 Adapter
|
||||
- Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
|
||||
- Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
|
||||
- N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
|
||||
- SK-9521 10/100/1000Base-T Adapter
|
||||
- SK-9521 V2.0 10/100/1000Base-T Adapter
|
||||
- SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
|
||||
- SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
|
||||
- SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
|
||||
- SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
|
||||
- SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
|
||||
- SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
|
||||
- SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
|
||||
- SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
|
||||
- SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
|
||||
- SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
|
||||
- SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
|
||||
- SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
|
||||
- SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
|
||||
- SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
|
||||
- SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
|
||||
- SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
|
||||
- SMC EZ Card 1000 (SMC9452TXV.2)
|
||||
|
||||
The adapters support Jumbo Frames.
|
||||
The dual link adapters support link-failover and dual port features.
|
||||
Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support
|
||||
the scatter-gather functionality with sendfile(). Please refer to
|
||||
<file:Documentation/networking/sk98lin.txt> for more information about
|
||||
optional driver parameters.
|
||||
Questions concerning this driver may be addressed to:
|
||||
<linux@syskonnect.de>
|
||||
|
||||
If you want to compile this driver as a module ( = code which can be
|
||||
inserted in and removed from the running kernel whenever you want),
|
||||
say M here and read <file:Documentation/kbuild/modules.txt>. The module will
|
||||
be called sk98lin. This is recommended.
|
||||
|
||||
config VIA_VELOCITY
|
||||
tristate "VIA Velocity support"
|
||||
depends on PCI
|
||||
|
|
|
@ -66,6 +66,7 @@ ps3_gelic-objs += ps3_gelic_net.o
|
|||
obj-$(CONFIG_TC35815) += tc35815.o
|
||||
obj-$(CONFIG_SKGE) += skge.o
|
||||
obj-$(CONFIG_SKY2) += sky2.o
|
||||
obj-$(CONFIG_SK98LIN) += sk98lin/
|
||||
obj-$(CONFIG_SKFP) += skfp/
|
||||
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
|
||||
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
|
||||
|
|
|
@ -2203,22 +2203,21 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
|
|||
struct net_device *netdev;
|
||||
struct atl1_adapter *adapter;
|
||||
static int cards_found = 0;
|
||||
bool pci_using_64 = true;
|
||||
int err;
|
||||
|
||||
err = pci_enable_device(pdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
|
||||
if (err) {
|
||||
/*
|
||||
* 64-bit DMA currently has data corruption problems, so let's just
|
||||
* use 32-bit DMA for now. This is a big hack that is probably wrong.
|
||||
*/
|
||||
err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "no usable DMA configuration\n");
|
||||
goto err_dma;
|
||||
}
|
||||
pci_using_64 = false;
|
||||
}
|
||||
/* Mark all PCI regions associated with PCI device
|
||||
* pdev as being reserved by owner atl1_driver_name
|
||||
*/
|
||||
|
@ -2282,7 +2281,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
|
|||
|
||||
netdev->ethtool_ops = &atl1_ethtool_ops;
|
||||
adapter->bd_number = cards_found;
|
||||
adapter->pci_using_64 = pci_using_64;
|
||||
|
||||
/* setup the private structure */
|
||||
err = atl1_sw_init(adapter);
|
||||
|
@ -2299,9 +2297,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
|
|||
*/
|
||||
/* netdev->features |= NETIF_F_TSO; */
|
||||
|
||||
if (pci_using_64)
|
||||
netdev->features |= NETIF_F_HIGHDMA;
|
||||
|
||||
netdev->features |= NETIF_F_LLTX;
|
||||
|
||||
/*
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include <asm/io.h>
|
||||
|
||||
#define DRV_NAME "ehea"
|
||||
#define DRV_VERSION "EHEA_0073"
|
||||
#define DRV_VERSION "EHEA_0074"
|
||||
|
||||
/* eHEA capability flags */
|
||||
#define DLPAR_PORT_ADD_REM 1
|
||||
|
@ -402,6 +402,8 @@ struct ehea_mc_list {
|
|||
|
||||
#define EHEA_PORT_UP 1
|
||||
#define EHEA_PORT_DOWN 0
|
||||
#define EHEA_PHY_LINK_UP 1
|
||||
#define EHEA_PHY_LINK_DOWN 0
|
||||
#define EHEA_MAX_PORT_RES 16
|
||||
struct ehea_port {
|
||||
struct ehea_adapter *adapter; /* adapter that owns this port */
|
||||
|
@ -427,6 +429,7 @@ struct ehea_port {
|
|||
u32 msg_enable;
|
||||
u32 sig_comp_iv;
|
||||
u32 state;
|
||||
u8 phy_link;
|
||||
u8 full_duplex;
|
||||
u8 autoneg;
|
||||
u8 num_def_qps;
|
||||
|
|
|
@ -53,17 +53,21 @@ static int rq3_entries = EHEA_DEF_ENTRIES_RQ3;
|
|||
static int sq_entries = EHEA_DEF_ENTRIES_SQ;
|
||||
static int use_mcs = 0;
|
||||
static int num_tx_qps = EHEA_NUM_TX_QP;
|
||||
static int prop_carrier_state = 0;
|
||||
|
||||
module_param(msg_level, int, 0);
|
||||
module_param(rq1_entries, int, 0);
|
||||
module_param(rq2_entries, int, 0);
|
||||
module_param(rq3_entries, int, 0);
|
||||
module_param(sq_entries, int, 0);
|
||||
module_param(prop_carrier_state, int, 0);
|
||||
module_param(use_mcs, int, 0);
|
||||
module_param(num_tx_qps, int, 0);
|
||||
|
||||
MODULE_PARM_DESC(num_tx_qps, "Number of TX-QPS");
|
||||
MODULE_PARM_DESC(msg_level, "msg_level");
|
||||
MODULE_PARM_DESC(prop_carrier_state, "Propagate carrier state of physical "
|
||||
"port to stack. 1:yes, 0:no. Default = 0 ");
|
||||
MODULE_PARM_DESC(rq3_entries, "Number of entries for Receive Queue 3 "
|
||||
"[2^x - 1], x = [6..14]. Default = "
|
||||
__MODULE_STRING(EHEA_DEF_ENTRIES_RQ3) ")");
|
||||
|
@ -467,7 +471,7 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
|
|||
else
|
||||
netif_receive_skb(skb);
|
||||
|
||||
dev->last_rx = jiffies;
|
||||
port->netdev->last_rx = jiffies;
|
||||
} else {
|
||||
pr->p_stats.poll_receive_errors++;
|
||||
port_reset = ehea_treat_poll_error(pr, rq, cqe,
|
||||
|
@ -814,7 +818,9 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed)
|
|||
ehea_error("Failed setting port speed");
|
||||
}
|
||||
}
|
||||
if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP))
|
||||
netif_carrier_on(port->netdev);
|
||||
|
||||
kfree(cb4);
|
||||
out:
|
||||
return ret;
|
||||
|
@ -869,13 +875,19 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe)
|
|||
}
|
||||
|
||||
if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PORT_UP, eqe)) {
|
||||
port->phy_link = EHEA_PHY_LINK_UP;
|
||||
if (netif_msg_link(port))
|
||||
ehea_info("%s: Physical port up",
|
||||
port->netdev->name);
|
||||
if (prop_carrier_state)
|
||||
netif_carrier_on(port->netdev);
|
||||
} else {
|
||||
port->phy_link = EHEA_PHY_LINK_DOWN;
|
||||
if (netif_msg_link(port))
|
||||
ehea_info("%s: Physical port down",
|
||||
port->netdev->name);
|
||||
if (prop_carrier_state)
|
||||
netif_carrier_off(port->netdev);
|
||||
}
|
||||
|
||||
if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PRIMARY, eqe))
|
||||
|
|
|
@ -1222,7 +1222,7 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
spin_lock_irqsave(&mp->lock, flags);
|
||||
|
||||
eth_tx_submit_descs_for_skb(mp, skb);
|
||||
stats->tx_bytes = skb->len;
|
||||
stats->tx_bytes += skb->len;
|
||||
stats->tx_packets++;
|
||||
dev->trans_start = jiffies;
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ struct el3_private {
|
|||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static const char *if_names[] = { "auto", "10baseT", "10base2", "AUI" };
|
||||
static const char *if_names[] = { "auto", "10base2", "10baseT", "AUI" };
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
|
|
@ -755,7 +755,7 @@ out_unlock:
|
|||
*/
|
||||
void phy_start(struct phy_device *phydev)
|
||||
{
|
||||
spin_lock(&phydev->lock);
|
||||
spin_lock_bh(&phydev->lock);
|
||||
|
||||
switch (phydev->state) {
|
||||
case PHY_STARTING:
|
||||
|
@ -769,7 +769,7 @@ void phy_start(struct phy_device *phydev)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
spin_unlock(&phydev->lock);
|
||||
spin_unlock_bh(&phydev->lock);
|
||||
}
|
||||
EXPORT_SYMBOL(phy_stop);
|
||||
EXPORT_SYMBOL(phy_start);
|
||||
|
|
|
@ -644,7 +644,7 @@ static int phy_probe(struct device *dev)
|
|||
if (!(phydrv->flags & PHY_HAS_INTERRUPT))
|
||||
phydev->irq = PHY_POLL;
|
||||
|
||||
spin_lock(&phydev->lock);
|
||||
spin_lock_bh(&phydev->lock);
|
||||
|
||||
/* Start out supporting everything. Eventually,
|
||||
* a controller will attach, and may modify one
|
||||
|
@ -658,7 +658,7 @@ static int phy_probe(struct device *dev)
|
|||
if (phydev->drv->probe)
|
||||
err = phydev->drv->probe(phydev);
|
||||
|
||||
spin_unlock(&phydev->lock);
|
||||
spin_unlock_bh(&phydev->lock);
|
||||
|
||||
return err;
|
||||
|
||||
|
|
|
@ -899,17 +899,9 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
/* Put the 2-byte PPP protocol number on the front,
|
||||
making sure there is room for the address and control fields. */
|
||||
if (skb_headroom(skb) < PPP_HDRLEN) {
|
||||
struct sk_buff *ns;
|
||||
|
||||
ns = alloc_skb(skb->len + dev->hard_header_len, GFP_ATOMIC);
|
||||
if (ns == 0)
|
||||
if (skb_cow_head(skb, PPP_HDRLEN))
|
||||
goto outf;
|
||||
skb_reserve(ns, dev->hard_header_len);
|
||||
skb_copy_bits(skb, 0, skb_put(ns, skb->len), skb->len);
|
||||
kfree_skb(skb);
|
||||
skb = ns;
|
||||
}
|
||||
|
||||
pp = skb_push(skb, 2);
|
||||
proto = npindex_to_proto[npi];
|
||||
pp[0] = proto >> 8;
|
||||
|
@ -1533,7 +1525,7 @@ ppp_input_error(struct ppp_channel *chan, int code)
|
|||
static void
|
||||
ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
|
||||
{
|
||||
if (skb->len >= 2) {
|
||||
if (pskb_may_pull(skb, 2)) {
|
||||
#ifdef CONFIG_PPP_MULTILINK
|
||||
/* XXX do channel-level decompression here */
|
||||
if (PPP_PROTO(skb) == PPP_MP)
|
||||
|
@ -1585,7 +1577,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
|
|||
if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP))
|
||||
goto err;
|
||||
|
||||
if (skb_tailroom(skb) < 124) {
|
||||
if (skb_tailroom(skb) < 124 || skb_cloned(skb)) {
|
||||
/* copy to a new sk_buff with more tailroom */
|
||||
ns = dev_alloc_skb(skb->len + 128);
|
||||
if (ns == 0) {
|
||||
|
@ -1656,12 +1648,18 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
|
|||
/* check if the packet passes the pass and active filters */
|
||||
/* the filter instructions are constructed assuming
|
||||
a four-byte PPP header on each packet */
|
||||
if (ppp->pass_filter || ppp->active_filter) {
|
||||
if (skb_cloned(skb) &&
|
||||
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
|
||||
goto err;
|
||||
|
||||
*skb_push(skb, 2) = 0;
|
||||
if (ppp->pass_filter
|
||||
&& sk_run_filter(skb, ppp->pass_filter,
|
||||
ppp->pass_len) == 0) {
|
||||
if (ppp->debug & 1)
|
||||
printk(KERN_DEBUG "PPP: inbound frame not passed\n");
|
||||
printk(KERN_DEBUG "PPP: inbound frame "
|
||||
"not passed\n");
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
@ -1669,10 +1667,10 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
|
|||
&& sk_run_filter(skb, ppp->active_filter,
|
||||
ppp->active_len) == 0))
|
||||
ppp->last_recv = jiffies;
|
||||
skb_pull(skb, 2);
|
||||
#else
|
||||
ppp->last_recv = jiffies;
|
||||
__skb_pull(skb, 2);
|
||||
} else
|
||||
#endif /* CONFIG_PPP_FILTER */
|
||||
ppp->last_recv = jiffies;
|
||||
|
||||
if ((ppp->dev->flags & IFF_UP) == 0
|
||||
|| ppp->npmode[npi] != NPMODE_PASS) {
|
||||
|
@ -1770,7 +1768,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
|
|||
struct channel *ch;
|
||||
int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
|
||||
|
||||
if (!pskb_may_pull(skb, mphdrlen) || ppp->mrru == 0)
|
||||
if (!pskb_may_pull(skb, mphdrlen + 1) || ppp->mrru == 0)
|
||||
goto err; /* no good, throw it away */
|
||||
|
||||
/* Decode sequence number and begin/end bits */
|
||||
|
|
|
@ -385,12 +385,12 @@ static int pppoe_rcv(struct sk_buff *skb,
|
|||
struct pppoe_hdr *ph;
|
||||
struct pppox_sock *po;
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
|
||||
goto drop;
|
||||
|
||||
if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
|
||||
goto out;
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
|
||||
goto drop;
|
||||
|
||||
ph = pppoe_hdr(skb);
|
||||
|
||||
po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
|
||||
|
@ -848,71 +848,45 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
|
|||
{
|
||||
struct pppox_sock *po = pppox_sk(sk);
|
||||
struct net_device *dev = po->pppoe_dev;
|
||||
struct pppoe_hdr hdr;
|
||||
struct pppoe_hdr *ph;
|
||||
int headroom = skb_headroom(skb);
|
||||
int data_len = skb->len;
|
||||
struct sk_buff *skb2;
|
||||
|
||||
if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
|
||||
goto abort;
|
||||
|
||||
hdr.ver = 1;
|
||||
hdr.type = 1;
|
||||
hdr.code = 0;
|
||||
hdr.sid = po->num;
|
||||
hdr.length = htons(skb->len);
|
||||
|
||||
if (!dev)
|
||||
goto abort;
|
||||
|
||||
/* Copy the skb if there is no space for the header. */
|
||||
if (headroom < (sizeof(struct pppoe_hdr) + dev->hard_header_len)) {
|
||||
skb2 = dev_alloc_skb(32+skb->len +
|
||||
sizeof(struct pppoe_hdr) +
|
||||
dev->hard_header_len);
|
||||
|
||||
if (skb2 == NULL)
|
||||
goto abort;
|
||||
|
||||
skb_reserve(skb2, dev->hard_header_len + sizeof(struct pppoe_hdr));
|
||||
skb_copy_from_linear_data(skb, skb_put(skb2, skb->len),
|
||||
skb->len);
|
||||
} else {
|
||||
/* Make a clone so as to not disturb the original skb,
|
||||
* give dev_queue_xmit something it can free.
|
||||
/* Copy the data if there is no space for the header or if it's
|
||||
* read-only.
|
||||
*/
|
||||
skb2 = skb_clone(skb, GFP_ATOMIC);
|
||||
|
||||
if (skb2 == NULL)
|
||||
if (skb_cow_head(skb, sizeof(*ph) + dev->hard_header_len))
|
||||
goto abort;
|
||||
}
|
||||
|
||||
ph = (struct pppoe_hdr *) skb_push(skb2, sizeof(struct pppoe_hdr));
|
||||
memcpy(ph, &hdr, sizeof(struct pppoe_hdr));
|
||||
skb2->protocol = __constant_htons(ETH_P_PPP_SES);
|
||||
__skb_push(skb, sizeof(*ph));
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
skb_reset_network_header(skb2);
|
||||
ph = pppoe_hdr(skb);
|
||||
ph->ver = 1;
|
||||
ph->type = 1;
|
||||
ph->code = 0;
|
||||
ph->sid = po->num;
|
||||
ph->length = htons(data_len);
|
||||
|
||||
skb2->dev = dev;
|
||||
skb->protocol = __constant_htons(ETH_P_PPP_SES);
|
||||
skb->dev = dev;
|
||||
|
||||
dev->hard_header(skb2, dev, ETH_P_PPP_SES,
|
||||
dev->hard_header(skb, dev, ETH_P_PPP_SES,
|
||||
po->pppoe_pa.remote, NULL, data_len);
|
||||
|
||||
/* We're transmitting skb2, and assuming that dev_queue_xmit
|
||||
* will free it. The generic ppp layer however, is expecting
|
||||
* that we give back 'skb' (not 'skb2') in case of failure,
|
||||
* but free it in case of success.
|
||||
*/
|
||||
|
||||
if (dev_queue_xmit(skb2) < 0)
|
||||
if (dev_queue_xmit(skb) < 0)
|
||||
goto abort;
|
||||
|
||||
kfree_skb(skb);
|
||||
return 1;
|
||||
|
||||
abort:
|
||||
return 0;
|
||||
kfree_skb(skb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
#
|
||||
# Makefile for the SysKonnect SK-98xx device driver.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Standalone driver params
|
||||
# SKPARAM += -DSK_KERNEL_24
|
||||
# SKPARAM += -DSK_KERNEL_24_26
|
||||
# SKPARAM += -DSK_KERNEL_26
|
||||
# SKPARAM += -DSK_KERNEL_22_24
|
||||
|
||||
obj-$(CONFIG_SK98LIN) += sk98lin.o
|
||||
sk98lin-objs := \
|
||||
skge.o \
|
||||
skethtool.o \
|
||||
skdim.o \
|
||||
skaddr.o \
|
||||
skgehwt.o \
|
||||
skgeinit.o \
|
||||
skgepnmi.o \
|
||||
skgesirq.o \
|
||||
ski2c.o \
|
||||
sklm80.o \
|
||||
skqueue.o \
|
||||
skrlmt.o \
|
||||
sktimer.o \
|
||||
skvpd.o \
|
||||
skxmac2.o
|
||||
|
||||
# DBGDEF = \
|
||||
# -DDEBUG
|
||||
|
||||
ifdef DEBUG
|
||||
DBGDEF += \
|
||||
-DSK_DEBUG_CHKMOD=0x00000000L \
|
||||
-DSK_DEBUG_CHKCAT=0x00000000L
|
||||
endif
|
||||
|
||||
|
||||
# **** possible debug modules for SK_DEBUG_CHKMOD *****************
|
||||
# SK_DBGMOD_MERR 0x00000001L /* general module error indication */
|
||||
# SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
|
||||
# SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
|
||||
# SK_DBGMOD_VPD 0x00000008L /* VPD module */
|
||||
# SK_DBGMOD_I2C 0x00000010L /* I2C module */
|
||||
# SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
|
||||
# SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
|
||||
# SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
|
||||
# SK_DBGMOD_DRV 0x00010000L /* DRV module */
|
||||
|
||||
# **** possible debug categories for SK_DEBUG_CHKCAT **************
|
||||
# *** common modules ***
|
||||
# SK_DBGCAT_INIT 0x00000001L module/driver initialization
|
||||
# SK_DBGCAT_CTRL 0x00000002L controlling: add/rmv MCA/MAC and other controls (IOCTL)
|
||||
# SK_DBGCAT_ERR 0x00000004L error handling paths
|
||||
# SK_DBGCAT_TX 0x00000008L transmit path
|
||||
# SK_DBGCAT_RX 0x00000010L receive path
|
||||
# SK_DBGCAT_IRQ 0x00000020L general IRQ handling
|
||||
# SK_DBGCAT_QUEUE 0x00000040L any queue management
|
||||
# SK_DBGCAT_DUMP 0x00000080L large data output e.g. hex dump
|
||||
# SK_DBGCAT_FATAL 0x00000100L large data output e.g. hex dump
|
||||
|
||||
# *** driver (file skge.c) ***
|
||||
# SK_DBGCAT_DRV_ENTRY 0x00010000 entry points
|
||||
# SK_DBGCAT_DRV_??? 0x00020000 not used
|
||||
# SK_DBGCAT_DRV_MCA 0x00040000 multicast
|
||||
# SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 tx path
|
||||
# SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 rx path
|
||||
# SK_DBGCAT_DRV_PROGRESS 0x00200000 general runtime
|
||||
# SK_DBGCAT_DRV_??? 0x00400000 not used
|
||||
# SK_DBGCAT_DRV_PROM 0x00800000 promiscuous mode
|
||||
# SK_DBGCAT_DRV_TX_FRAME 0x01000000 display tx frames
|
||||
# SK_DBGCAT_DRV_ERROR 0x02000000 error conditions
|
||||
# SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources
|
||||
# SK_DBGCAT_DRV_EVENT 0x08000000 driver events
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
|
||||
|
||||
clean:
|
||||
rm -f core *.o *.a *.s
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: lm80.h
|
||||
* Project: Gigabit Ethernet Adapters, Common Modules
|
||||
* Version: $Revision: 1.6 $
|
||||
* Date: $Date: 2003/05/13 17:26:52 $
|
||||
* Purpose: Contains all defines for the LM80 Chip
|
||||
* (National Semiconductor).
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* (C)Copyright 1998-2002 SysKonnect.
|
||||
* (C)Copyright 2002-2003 Marvell.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The information in this file is provided "AS IS" without warranty.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __INC_LM80_H
|
||||
#define __INC_LM80_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* defines ********************************************************************/
|
||||
|
||||
/*
|
||||
* LM80 register definition
|
||||
*
|
||||
* All registers are 8 bit wide
|
||||
*/
|
||||
#define LM80_CFG 0x00 /* Configuration Register */
|
||||
#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */
|
||||
#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */
|
||||
#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */
|
||||
#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */
|
||||
#define LM80_FAN_CTRL 0x05 /* Fan Devisor/RST#/OS# Register */
|
||||
#define LM80_TEMP_CTRL 0x06 /* OS# Config, Temp Res. Reg */
|
||||
/* 0x07 - 0x1f reserved */
|
||||
/* current values */
|
||||
#define LM80_VT0_IN 0x20 /* current Voltage 0 value */
|
||||
#define LM80_VT1_IN 0x21 /* current Voltage 1 value */
|
||||
#define LM80_VT2_IN 0x22 /* current Voltage 2 value */
|
||||
#define LM80_VT3_IN 0x23 /* current Voltage 3 value */
|
||||
#define LM80_VT4_IN 0x24 /* current Voltage 4 value */
|
||||
#define LM80_VT5_IN 0x25 /* current Voltage 5 value */
|
||||
#define LM80_VT6_IN 0x26 /* current Voltage 6 value */
|
||||
#define LM80_TEMP_IN 0x27 /* current Temperature value */
|
||||
#define LM80_FAN1_IN 0x28 /* current Fan 1 count */
|
||||
#define LM80_FAN2_IN 0x29 /* current Fan 2 count */
|
||||
/* limit values */
|
||||
#define LM80_VT0_HIGH_LIM 0x2a /* high limit val for Voltage 0 */
|
||||
#define LM80_VT0_LOW_LIM 0x2b /* low limit val for Voltage 0 */
|
||||
#define LM80_VT1_HIGH_LIM 0x2c /* high limit val for Voltage 1 */
|
||||
#define LM80_VT1_LOW_LIM 0x2d /* low limit val for Voltage 1 */
|
||||
#define LM80_VT2_HIGH_LIM 0x2e /* high limit val for Voltage 2 */
|
||||
#define LM80_VT2_LOW_LIM 0x2f /* low limit val for Voltage 2 */
|
||||
#define LM80_VT3_HIGH_LIM 0x30 /* high limit val for Voltage 3 */
|
||||
#define LM80_VT3_LOW_LIM 0x31 /* low limit val for Voltage 3 */
|
||||
#define LM80_VT4_HIGH_LIM 0x32 /* high limit val for Voltage 4 */
|
||||
#define LM80_VT4_LOW_LIM 0x33 /* low limit val for Voltage 4 */
|
||||
#define LM80_VT5_HIGH_LIM 0x34 /* high limit val for Voltage 5 */
|
||||
#define LM80_VT5_LOW_LIM 0x35 /* low limit val for Voltage 5 */
|
||||
#define LM80_VT6_HIGH_LIM 0x36 /* high limit val for Voltage 6 */
|
||||
#define LM80_VT6_LOW_LIM 0x37 /* low limit val for Voltage 6 */
|
||||
#define LM80_THOT_LIM_UP 0x38 /* hot temperature limit (high) */
|
||||
#define LM80_THOT_LIM_LO 0x39 /* hot temperature limit (low) */
|
||||
#define LM80_TOS_LIM_UP 0x3a /* OS temperature limit (high) */
|
||||
#define LM80_TOS_LIM_LO 0x3b /* OS temperature limit (low) */
|
||||
#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */
|
||||
#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */
|
||||
/* 0x3e - 0x3f reserved */
|
||||
|
||||
/*
|
||||
* LM80 bit definitions
|
||||
*/
|
||||
|
||||
/* LM80_CFG Configuration Register */
|
||||
#define LM80_CFG_START (1<<0) /* start monitoring operation */
|
||||
#define LM80_CFG_INT_ENA (1<<1) /* enables the INT# Interrupt output */
|
||||
#define LM80_CFG_INT_POL (1<<2) /* INT# pol: 0 act low, 1 act high */
|
||||
#define LM80_CFG_INT_CLR (1<<3) /* disables INT#/RST_OUT#/OS# outputs */
|
||||
#define LM80_CFG_RESET (1<<4) /* signals a reset */
|
||||
#define LM80_CFG_CHASS_CLR (1<<5) /* clears Chassis Intrusion (CI) pin */
|
||||
#define LM80_CFG_GPO (1<<6) /* drives the GPO# pin */
|
||||
#define LM80_CFG_INIT (1<<7) /* restore power on defaults */
|
||||
|
||||
/* LM80_ISRC_1 Interrupt Status Register 1 */
|
||||
/* LM80_IMSK_1 Interrupt Mask Register 1 */
|
||||
#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */
|
||||
#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */
|
||||
#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */
|
||||
#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */
|
||||
#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */
|
||||
#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */
|
||||
#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */
|
||||
#define LM80_IS_INT_IN (1<<7) /* state of INT_IN# */
|
||||
|
||||
/* LM80_ISRC_2 Interrupt Status Register 2 */
|
||||
/* LM80_IMSK_2 Interrupt Mask Register 2 */
|
||||
#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */
|
||||
#define LM80_IS_BTI (1<<1) /* state of BTI# pin */
|
||||
#define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */
|
||||
#define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */
|
||||
#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */
|
||||
#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */
|
||||
/* bit 6 and 7 are reserved in LM80_ISRC_2 */
|
||||
#define LM80_IS_HT_IRQ_MD (1<<6) /* Hot temperature interrupt mode */
|
||||
#define LM80_IS_OT_IRQ_MD (1<<7) /* OS temperature interrupt mode */
|
||||
|
||||
/* LM80_FAN_CTRL Fan Devisor/RST#/OS# Register */
|
||||
#define LM80_FAN1_MD_SEL (1<<0) /* Fan 1 mode select */
|
||||
#define LM80_FAN2_MD_SEL (1<<1) /* Fan 2 mode select */
|
||||
#define LM80_FAN1_PRM_CTL (3<<2) /* Fan 1 speed control */
|
||||
#define LM80_FAN2_PRM_CTL (3<<4) /* Fan 2 speed control */
|
||||
#define LM80_FAN_OS_ENA (1<<6) /* enable OS mode on RST_OUT#/OS# pins*/
|
||||
#define LM80_FAN_RST_ENA (1<<7) /* sets RST_OUT#/OS# pins in RST mode */
|
||||
|
||||
/* LM80_TEMP_CTRL OS# Config, Temp Res. Reg */
|
||||
#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */
|
||||
#define LM80_TEMP_OS_POL (1<<1) /* select OS# polarity */
|
||||
#define LM80_TEMP_OS_MODE (1<<2) /* selects Interrupt mode */
|
||||
#define LM80_TEMP_RES (1<<3) /* selects 9 or 11 bit temp resulution*/
|
||||
#define LM80_TEMP_LSB (0xf<<4)/* 4 LSBs of 11 bit temp data */
|
||||
#define LM80_TEMP_LSB_9 (1<<7) /* LSB of 9 bit temperature data */
|
||||
|
||||
/* 0x07 - 0x1f reserved */
|
||||
/* LM80_VT0_IN current Voltage 0 value */
|
||||
/* LM80_VT1_IN current Voltage 1 value */
|
||||
/* LM80_VT2_IN current Voltage 2 value */
|
||||
/* LM80_VT3_IN current Voltage 3 value */
|
||||
/* LM80_VT4_IN current Voltage 4 value */
|
||||
/* LM80_VT5_IN current Voltage 5 value */
|
||||
/* LM80_VT6_IN current Voltage 6 value */
|
||||
/* LM80_TEMP_IN current temperature value */
|
||||
/* LM80_FAN1_IN current Fan 1 count */
|
||||
/* LM80_FAN2_IN current Fan 2 count */
|
||||
/* LM80_VT0_HIGH_LIM high limit val for Voltage 0 */
|
||||
/* LM80_VT0_LOW_LIM low limit val for Voltage 0 */
|
||||
/* LM80_VT1_HIGH_LIM high limit val for Voltage 1 */
|
||||
/* LM80_VT1_LOW_LIM low limit val for Voltage 1 */
|
||||
/* LM80_VT2_HIGH_LIM high limit val for Voltage 2 */
|
||||
/* LM80_VT2_LOW_LIM low limit val for Voltage 2 */
|
||||
/* LM80_VT3_HIGH_LIM high limit val for Voltage 3 */
|
||||
/* LM80_VT3_LOW_LIM low limit val for Voltage 3 */
|
||||
/* LM80_VT4_HIGH_LIM high limit val for Voltage 4 */
|
||||
/* LM80_VT4_LOW_LIM low limit val for Voltage 4 */
|
||||
/* LM80_VT5_HIGH_LIM high limit val for Voltage 5 */
|
||||
/* LM80_VT5_LOW_LIM low limit val for Voltage 5 */
|
||||
/* LM80_VT6_HIGH_LIM high limit val for Voltage 6 */
|
||||
/* LM80_VT6_LOW_LIM low limit val for Voltage 6 */
|
||||
/* LM80_THOT_LIM_UP hot temperature limit (high) */
|
||||
/* LM80_THOT_LIM_LO hot temperature limit (low) */
|
||||
/* LM80_TOS_LIM_UP OS temperature limit (high) */
|
||||
/* LM80_TOS_LIM_LO OS temperature limit (low) */
|
||||
/* LM80_FAN1_COUNT_LIM Fan 1 count limit (high) */
|
||||
/* LM80_FAN2_COUNT_LIM Fan 2 count limit (low) */
|
||||
/* 0x3e - 0x3f reserved */
|
||||
|
||||
#define LM80_ADDR 0x28 /* LM80 default addr */
|
||||
|
||||
/* typedefs *******************************************************************/
|
||||
|
||||
|
||||
/* function prototypes ********************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __INC_LM80_H */
|
|
@ -0,0 +1,285 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: skaddr.h
|
||||
* Project: Gigabit Ethernet Adapters, ADDR-Modul
|
||||
* Version: $Revision: 1.29 $
|
||||
* Date: $Date: 2003/05/13 16:57:24 $
|
||||
* Purpose: Header file for Address Management (MC, UC, Prom).
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* (C)Copyright 1998-2002 SysKonnect GmbH.
|
||||
* (C)Copyright 2002-2003 Marvell.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The information in this file is provided "AS IS" without warranty.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This module is intended to manage multicast addresses and promiscuous mode
|
||||
* on GEnesis adapters.
|
||||
*
|
||||
* Include File Hierarchy:
|
||||
*
|
||||
* "skdrv1st.h"
|
||||
* ...
|
||||
* "sktypes.h"
|
||||
* "skqueue.h"
|
||||
* "skaddr.h"
|
||||
* ...
|
||||
* "skdrv2nd.h"
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __INC_SKADDR_H
|
||||
#define __INC_SKADDR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* cplusplus */
|
||||
|
||||
/* defines ********************************************************************/
|
||||
|
||||
#define SK_MAC_ADDR_LEN 6 /* Length of MAC address. */
|
||||
#define SK_MAX_ADDRS 14 /* #Addrs for exact match. */
|
||||
|
||||
/* ----- Common return values ----- */
|
||||
|
||||
#define SK_ADDR_SUCCESS 0 /* Function returned successfully. */
|
||||
#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */
|
||||
#define SK_ADDR_TOO_EARLY 101 /* Function called too early. */
|
||||
|
||||
/* ----- Clear/Add flag bits ----- */
|
||||
|
||||
#define SK_ADDR_PERMANENT 1 /* RLMT Address */
|
||||
|
||||
/* ----- Additional Clear flag bits ----- */
|
||||
|
||||
#define SK_MC_SW_ONLY 2 /* Do not update HW when clearing. */
|
||||
|
||||
/* ----- Override flag bits ----- */
|
||||
|
||||
#define SK_ADDR_LOGICAL_ADDRESS 0
|
||||
#define SK_ADDR_VIRTUAL_ADDRESS (SK_ADDR_LOGICAL_ADDRESS) /* old */
|
||||
#define SK_ADDR_PHYSICAL_ADDRESS 1
|
||||
#define SK_ADDR_CLEAR_LOGICAL 2
|
||||
#define SK_ADDR_SET_LOGICAL 4
|
||||
|
||||
/* ----- Override return values ----- */
|
||||
|
||||
#define SK_ADDR_OVERRIDE_SUCCESS (SK_ADDR_SUCCESS)
|
||||
#define SK_ADDR_DUPLICATE_ADDRESS 1
|
||||
#define SK_ADDR_MULTICAST_ADDRESS 2
|
||||
|
||||
/* ----- Partitioning of excact match table ----- */
|
||||
|
||||
#define SK_ADDR_EXACT_MATCHES 16 /* #Exact match entries. */
|
||||
|
||||
#define SK_ADDR_FIRST_MATCH_RLMT 1
|
||||
#define SK_ADDR_LAST_MATCH_RLMT 2
|
||||
#define SK_ADDR_FIRST_MATCH_DRV 3
|
||||
#define SK_ADDR_LAST_MATCH_DRV (SK_ADDR_EXACT_MATCHES - 1)
|
||||
|
||||
/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
|
||||
|
||||
#define SK_MC_FILTERING_EXACT 0 /* Exact filtering. */
|
||||
#define SK_MC_FILTERING_INEXACT 1 /* Inexact filtering. */
|
||||
|
||||
/* ----- Additional SkAddrMcAdd return values ----- */
|
||||
|
||||
#define SK_MC_ILLEGAL_ADDRESS 2 /* Illegal address. */
|
||||
#define SK_MC_ILLEGAL_PORT 3 /* Illegal port (not the active one). */
|
||||
#define SK_MC_RLMT_OVERFLOW 4 /* Too many RLMT mc addresses. */
|
||||
|
||||
/* Promiscuous mode bits ----- */
|
||||
|
||||
#define SK_PROM_MODE_NONE 0 /* Normal receive. */
|
||||
#define SK_PROM_MODE_LLC 1 /* Receive all LLC frames. */
|
||||
#define SK_PROM_MODE_ALL_MC 2 /* Receive all multicast frames. */
|
||||
/* #define SK_PROM_MODE_NON_LLC 4 */ /* Receive all non-LLC frames. */
|
||||
|
||||
/* Macros */
|
||||
|
||||
#ifdef OLD_STUFF
|
||||
#ifndef SK_ADDR_EQUAL
|
||||
/*
|
||||
* "&" instead of "&&" allows better optimization on IA-64.
|
||||
* The replacement is safe here, as all bytes exist.
|
||||
*/
|
||||
#ifndef SK_ADDR_DWORD_COMPARE
|
||||
#define SK_ADDR_EQUAL(A1,A2) ( \
|
||||
(((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
|
||||
(((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
|
||||
(((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
|
||||
(((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
|
||||
(((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
|
||||
(((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
|
||||
#else /* SK_ADDR_DWORD_COMPARE */
|
||||
#define SK_ADDR_EQUAL(A1,A2) ( \
|
||||
(*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
|
||||
(*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
|
||||
#endif /* SK_ADDR_DWORD_COMPARE */
|
||||
#endif /* SK_ADDR_EQUAL */
|
||||
#endif /* 0 */
|
||||
|
||||
#ifndef SK_ADDR_EQUAL
|
||||
#ifndef SK_ADDR_DWORD_COMPARE
|
||||
#define SK_ADDR_EQUAL(A1,A2) ( \
|
||||
(((SK_U8 SK_FAR *)(A1))[5] == ((SK_U8 SK_FAR *)(A2))[5]) & \
|
||||
(((SK_U8 SK_FAR *)(A1))[4] == ((SK_U8 SK_FAR *)(A2))[4]) & \
|
||||
(((SK_U8 SK_FAR *)(A1))[3] == ((SK_U8 SK_FAR *)(A2))[3]) & \
|
||||
(((SK_U8 SK_FAR *)(A1))[2] == ((SK_U8 SK_FAR *)(A2))[2]) & \
|
||||
(((SK_U8 SK_FAR *)(A1))[1] == ((SK_U8 SK_FAR *)(A2))[1]) & \
|
||||
(((SK_U8 SK_FAR *)(A1))[0] == ((SK_U8 SK_FAR *)(A2))[0]))
|
||||
#else /* SK_ADDR_DWORD_COMPARE */
|
||||
#define SK_ADDR_EQUAL(A1,A2) ( \
|
||||
(*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[4]) == \
|
||||
*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[4])) && \
|
||||
(*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[0]) == \
|
||||
*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[0])))
|
||||
#endif /* SK_ADDR_DWORD_COMPARE */
|
||||
#endif /* SK_ADDR_EQUAL */
|
||||
|
||||
/* typedefs *******************************************************************/
|
||||
|
||||
typedef struct s_MacAddr {
|
||||
SK_U8 a[SK_MAC_ADDR_LEN];
|
||||
} SK_MAC_ADDR;
|
||||
|
||||
|
||||
/* SK_FILTER is used to ensure alignment of the filter. */
|
||||
typedef union s_InexactFilter {
|
||||
SK_U8 Bytes[8];
|
||||
SK_U64 Val; /* Dummy entry for alignment only. */
|
||||
} SK_FILTER64;
|
||||
|
||||
|
||||
typedef struct s_AddrNet SK_ADDR_NET;
|
||||
|
||||
|
||||
typedef struct s_AddrPort {
|
||||
|
||||
/* ----- Public part (read-only) ----- */
|
||||
|
||||
SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */
|
||||
SK_MAC_ADDR PermanentMacAddress; /* Permanent physical MAC Address. */
|
||||
int PromMode; /* Promiscuous Mode. */
|
||||
|
||||
/* ----- Private part ----- */
|
||||
|
||||
SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */
|
||||
SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
|
||||
SK_U8 Align01;
|
||||
|
||||
SK_U32 FirstExactMatchRlmt;
|
||||
SK_U32 NextExactMatchRlmt;
|
||||
SK_U32 FirstExactMatchDrv;
|
||||
SK_U32 NextExactMatchDrv;
|
||||
SK_MAC_ADDR Exact[SK_ADDR_EXACT_MATCHES];
|
||||
SK_FILTER64 InexactFilter; /* For 64-bit hash register. */
|
||||
SK_FILTER64 InexactRlmtFilter; /* For 64-bit hash register. */
|
||||
SK_FILTER64 InexactDrvFilter; /* For 64-bit hash register. */
|
||||
} SK_ADDR_PORT;
|
||||
|
||||
|
||||
struct s_AddrNet {
|
||||
/* ----- Public part (read-only) ----- */
|
||||
|
||||
SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */
|
||||
SK_MAC_ADDR PermanentMacAddress; /* Logical MAC Address. */
|
||||
|
||||
/* ----- Private part ----- */
|
||||
|
||||
SK_U32 ActivePort; /* View of module ADDR. */
|
||||
SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
|
||||
SK_U8 Align01;
|
||||
SK_U16 Align02;
|
||||
};
|
||||
|
||||
|
||||
typedef struct s_Addr {
|
||||
|
||||
/* ----- Public part (read-only) ----- */
|
||||
|
||||
SK_ADDR_NET Net[SK_MAX_NETS];
|
||||
SK_ADDR_PORT Port[SK_MAX_MACS];
|
||||
|
||||
/* ----- Private part ----- */
|
||||
} SK_ADDR;
|
||||
|
||||
/* function prototypes ********************************************************/
|
||||
|
||||
#ifndef SK_KR_PROTO
|
||||
|
||||
/* Functions provided by SkAddr */
|
||||
|
||||
/* ANSI/C++ compliant function prototypes */
|
||||
|
||||
extern int SkAddrInit(
|
||||
SK_AC *pAC,
|
||||
SK_IOC IoC,
|
||||
int Level);
|
||||
|
||||
extern int SkAddrMcClear(
|
||||
SK_AC *pAC,
|
||||
SK_IOC IoC,
|
||||
SK_U32 PortNumber,
|
||||
int Flags);
|
||||
|
||||
extern int SkAddrMcAdd(
|
||||
SK_AC *pAC,
|
||||
SK_IOC IoC,
|
||||
SK_U32 PortNumber,
|
||||
SK_MAC_ADDR *pMc,
|
||||
int Flags);
|
||||
|
||||
extern int SkAddrMcUpdate(
|
||||
SK_AC *pAC,
|
||||
SK_IOC IoC,
|
||||
SK_U32 PortNumber);
|
||||
|
||||
extern int SkAddrOverride(
|
||||
SK_AC *pAC,
|
||||
SK_IOC IoC,
|
||||
SK_U32 PortNumber,
|
||||
SK_MAC_ADDR SK_FAR *pNewAddr,
|
||||
int Flags);
|
||||
|
||||
extern int SkAddrPromiscuousChange(
|
||||
SK_AC *pAC,
|
||||
SK_IOC IoC,
|
||||
SK_U32 PortNumber,
|
||||
int NewPromMode);
|
||||
|
||||
#ifndef SK_SLIM
|
||||
extern int SkAddrSwap(
|
||||
SK_AC *pAC,
|
||||
SK_IOC IoC,
|
||||
SK_U32 FromPortNumber,
|
||||
SK_U32 ToPortNumber);
|
||||
#endif
|
||||
|
||||
#else /* defined(SK_KR_PROTO)) */
|
||||
|
||||
/* Non-ANSI/C++ compliant function prototypes */
|
||||
|
||||
#error KR-style prototypes are not yet provided.
|
||||
|
||||
#endif /* defined(SK_KR_PROTO)) */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __INC_SKADDR_H */
|
|
@ -0,0 +1,213 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: skcsum.h
|
||||
* Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
|
||||
* Version: $Revision: 1.10 $
|
||||
* Date: $Date: 2003/08/20 13:59:57 $
|
||||
* Purpose: Store/verify Internet checksum in send/receive packets.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* (C)Copyright 1998-2001 SysKonnect GmbH.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The information in this file is provided "AS IS" without warranty.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Public header file for the "GEnesis" common module "CSUM".
|
||||
*
|
||||
* "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
|
||||
* and is the code name of this SysKonnect project.
|
||||
*
|
||||
* Compilation Options:
|
||||
*
|
||||
* SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
|
||||
* empty module.
|
||||
*
|
||||
* SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
|
||||
* definitions. In this case, all SKCS_PROTO_xxx definitions must be made
|
||||
* external.
|
||||
*
|
||||
* SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
|
||||
* definitions. In this case, all SKCS_STATUS_xxx definitions must be made
|
||||
* external.
|
||||
*
|
||||
* Include File Hierarchy:
|
||||
*
|
||||
* "h/skcsum.h"
|
||||
* "h/sktypes.h"
|
||||
* "h/skqueue.h"
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __INC_SKCSUM_H
|
||||
#define __INC_SKCSUM_H
|
||||
|
||||
#include "h/sktypes.h"
|
||||
#include "h/skqueue.h"
|
||||
|
||||
/* defines ********************************************************************/
|
||||
|
||||
/*
|
||||
* Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags' if no user
|
||||
* overwrite.
|
||||
*/
|
||||
#ifndef SKCS_OVERWRITE_PROTO /* User overwrite? */
|
||||
#define SKCS_PROTO_IP 0x1 /* IP (Internet Protocol version 4) */
|
||||
#define SKCS_PROTO_TCP 0x2 /* TCP (Transmission Control Protocol) */
|
||||
#define SKCS_PROTO_UDP 0x4 /* UDP (User Datagram Protocol) */
|
||||
|
||||
/* Indices for protocol statistics. */
|
||||
#define SKCS_PROTO_STATS_IP 0
|
||||
#define SKCS_PROTO_STATS_UDP 1
|
||||
#define SKCS_PROTO_STATS_TCP 2
|
||||
#define SKCS_NUM_PROTOCOLS 3 /* Number of supported protocols. */
|
||||
#endif /* !SKCS_OVERWRITE_PROTO */
|
||||
|
||||
/*
|
||||
* Define the default SKCS_STATUS type and values if no user overwrite.
|
||||
*
|
||||
* SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
|
||||
* SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
|
||||
* SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
|
||||
* SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
|
||||
* SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
|
||||
* SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
|
||||
* SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
|
||||
* SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
|
||||
* SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
|
||||
* SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
|
||||
* SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
|
||||
*/
|
||||
#ifndef SKCS_OVERWRITE_STATUS /* User overwrite? */
|
||||
#define SKCS_STATUS int /* Define status type. */
|
||||
|
||||
#define SKCS_STATUS_UNKNOWN_IP_VERSION 1
|
||||
#define SKCS_STATUS_IP_CSUM_ERROR 2
|
||||
#define SKCS_STATUS_IP_FRAGMENT 3
|
||||
#define SKCS_STATUS_IP_CSUM_OK 4
|
||||
#define SKCS_STATUS_TCP_CSUM_ERROR 5
|
||||
#define SKCS_STATUS_UDP_CSUM_ERROR 6
|
||||
#define SKCS_STATUS_TCP_CSUM_OK 7
|
||||
#define SKCS_STATUS_UDP_CSUM_OK 8
|
||||
/* needed for Microsoft */
|
||||
#define SKCS_STATUS_IP_CSUM_ERROR_UDP 9
|
||||
#define SKCS_STATUS_IP_CSUM_ERROR_TCP 10
|
||||
/* UDP checksum may be omitted */
|
||||
#define SKCS_STATUS_IP_CSUM_OK_NO_UDP 11
|
||||
#endif /* !SKCS_OVERWRITE_STATUS */
|
||||
|
||||
/* Clear protocol statistics event. */
|
||||
#define SK_CSUM_EVENT_CLEAR_PROTO_STATS 1
|
||||
|
||||
/*
|
||||
* Add two values in one's complement.
|
||||
*
|
||||
* Note: One of the two input values may be "longer" than 16-bit, but then the
|
||||
* resulting sum may be 17 bits long. In this case, add zero to the result using
|
||||
* SKCS_OC_ADD() again.
|
||||
*
|
||||
* Result = Value1 + Value2
|
||||
*/
|
||||
#define SKCS_OC_ADD(Result, Value1, Value2) { \
|
||||
unsigned long Sum; \
|
||||
\
|
||||
Sum = (unsigned long) (Value1) + (unsigned long) (Value2); \
|
||||
/* Add-in any carry. */ \
|
||||
(Result) = (Sum & 0xffff) + (Sum >> 16); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Subtract two values in one's complement.
|
||||
*
|
||||
* Result = Value1 - Value2
|
||||
*/
|
||||
#define SKCS_OC_SUB(Result, Value1, Value2) \
|
||||
SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff)
|
||||
|
||||
/* typedefs *******************************************************************/
|
||||
|
||||
/*
|
||||
* SKCS_PROTO_STATS - The CSUM protocol statistics structure.
|
||||
*
|
||||
* There is one instance of this structure for each protocol supported.
|
||||
*/
|
||||
typedef struct s_CsProtocolStatistics {
|
||||
SK_U64 RxOkCts; /* Receive checksum ok. */
|
||||
SK_U64 RxUnableCts; /* Unable to verify receive checksum. */
|
||||
SK_U64 RxErrCts; /* Receive checksum error. */
|
||||
SK_U64 TxOkCts; /* Transmit checksum ok. */
|
||||
SK_U64 TxUnableCts; /* Unable to calculate checksum in hw. */
|
||||
} SKCS_PROTO_STATS;
|
||||
|
||||
/*
|
||||
* s_Csum - The CSUM module context structure.
|
||||
*/
|
||||
typedef struct s_Csum {
|
||||
/* Enabled receive SK_PROTO_XXX bit flags. */
|
||||
unsigned ReceiveFlags[SK_MAX_NETS];
|
||||
#ifdef TX_CSUM
|
||||
unsigned TransmitFlags[SK_MAX_NETS];
|
||||
#endif /* TX_CSUM */
|
||||
|
||||
/* The protocol statistics structure; one per supported protocol. */
|
||||
SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
|
||||
} SK_CSUM;
|
||||
|
||||
/*
|
||||
* SKCS_PACKET_INFO - The packet information structure.
|
||||
*/
|
||||
typedef struct s_CsPacketInfo {
|
||||
/* Bit field specifiying the desired/found protocols. */
|
||||
unsigned ProtocolFlags;
|
||||
|
||||
/* Length of complete IP header, including any option fields. */
|
||||
unsigned IpHeaderLength;
|
||||
|
||||
/* IP header checksum. */
|
||||
unsigned IpHeaderChecksum;
|
||||
|
||||
/* TCP/UDP pseudo header checksum. */
|
||||
unsigned PseudoHeaderChecksum;
|
||||
} SKCS_PACKET_INFO;
|
||||
|
||||
/* function prototypes ********************************************************/
|
||||
|
||||
#ifndef SK_CS_CALCULATE_CHECKSUM
|
||||
extern unsigned SkCsCalculateChecksum(
|
||||
void *pData,
|
||||
unsigned Length);
|
||||
#endif /* SK_CS_CALCULATE_CHECKSUM */
|
||||
|
||||
extern int SkCsEvent(
|
||||
SK_AC *pAc,
|
||||
SK_IOC Ioc,
|
||||
SK_U32 Event,
|
||||
SK_EVPARA Param);
|
||||
|
||||
extern SKCS_STATUS SkCsGetReceiveInfo(
|
||||
SK_AC *pAc,
|
||||
void *pIpHeader,
|
||||
unsigned Checksum1,
|
||||
unsigned Checksum2,
|
||||
int NetNumber);
|
||||
|
||||
extern void SkCsSetReceiveFlags(
|
||||
SK_AC *pAc,
|
||||
unsigned ReceiveFlags,
|
||||
unsigned *pChecksum1Offset,
|
||||
unsigned *pChecksum2Offset,
|
||||
int NetNumber);
|
||||
|
||||
#endif /* __INC_SKCSUM_H */
|
|
@ -0,0 +1,74 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: skdebug.h
|
||||
* Project: Gigabit Ethernet Adapters, Common Modules
|
||||
* Version: $Revision: 1.14 $
|
||||
* Date: $Date: 2003/05/13 17:26:00 $
|
||||
* Purpose: SK specific DEBUG support
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* (C)Copyright 1998-2002 SysKonnect.
|
||||
* (C)Copyright 2002-2003 Marvell.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The information in this file is provided "AS IS" without warranty.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __INC_SKDEBUG_H
|
||||
#define __INC_SKDEBUG_H
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef SK_DBG_MSG
|
||||
#define SK_DBG_MSG(pAC,comp,cat,arg) \
|
||||
if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \
|
||||
((cat) & SK_DBG_CHKCAT(pAC)) ) { \
|
||||
SK_DBG_PRINTF arg ; \
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#define SK_DBG_MSG(pAC,comp,lev,arg)
|
||||
#endif
|
||||
|
||||
/* PLS NOTE:
|
||||
* =========
|
||||
* Due to any restrictions of kernel printf routines do not use other
|
||||
* format identifiers as: %x %d %c %s .
|
||||
* Never use any combined format identifiers such as: %lx %ld in your
|
||||
* printf - argument (arg) because some OS specific kernel printfs may
|
||||
* only support some basic identifiers.
|
||||
*/
|
||||
|
||||
/* Debug modules */
|
||||
|
||||
#define SK_DBGMOD_MERR 0x00000001L /* general module error indication */
|
||||
#define SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
|
||||
#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
|
||||
#define SK_DBGMOD_VPD 0x00000008L /* VPD module */
|
||||
#define SK_DBGMOD_I2C 0x00000010L /* I2C module */
|
||||
#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
|
||||
#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
|
||||
#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
|
||||
#define SK_DBGMOD_PECP 0x00000100L /* PECP module */
|
||||
#define SK_DBGMOD_POWM 0x00000200L /* Power Management module */
|
||||
|
||||
/* Debug events */
|
||||
|
||||
#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */
|
||||
#define SK_DBGCAT_CTRL 0x00000002L /* controlling devices */
|
||||
#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */
|
||||
#define SK_DBGCAT_TX 0x00000008L /* transmit path */
|
||||
#define SK_DBGCAT_RX 0x00000010L /* receive path */
|
||||
#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */
|
||||
#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */
|
||||
#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */
|
||||
#define SK_DBGCAT_FATAL 0x00000100L /* fatal error */
|
||||
|
||||
#endif /* __INC_SKDEBUG_H */
|
|
@ -0,0 +1,188 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: skdrv1st.h
|
||||
* Project: GEnesis, PCI Gigabit Ethernet Adapter
|
||||
* Version: $Revision: 1.4 $
|
||||
* Date: $Date: 2003/11/12 14:28:14 $
|
||||
* Purpose: First header file for driver and all other modules
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* (C)Copyright 1998-2002 SysKonnect GmbH.
|
||||
* (C)Copyright 2002-2003 Marvell.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The information in this file is provided "AS IS" without warranty.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This is the first include file of the driver, which includes all
|
||||
* neccessary system header files and some of the GEnesis header files.
|
||||
* It also defines some basic items.
|
||||
*
|
||||
* Include File Hierarchy:
|
||||
*
|
||||
* see skge.c
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __INC_SKDRV1ST_H
|
||||
#define __INC_SKDRV1ST_H
|
||||
|
||||
typedef struct s_AC SK_AC;
|
||||
|
||||
/* Set card versions */
|
||||
#define SK_FAR
|
||||
|
||||
/* override some default functions with optimized linux functions */
|
||||
|
||||
#define SK_PNMI_STORE_U16(p,v) memcpy((char*)(p),(char*)&(v),2)
|
||||
#define SK_PNMI_STORE_U32(p,v) memcpy((char*)(p),(char*)&(v),4)
|
||||
#define SK_PNMI_STORE_U64(p,v) memcpy((char*)(p),(char*)&(v),8)
|
||||
#define SK_PNMI_READ_U16(p,v) memcpy((char*)&(v),(char*)(p),2)
|
||||
#define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4)
|
||||
#define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8)
|
||||
|
||||
#define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6))
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <net/checksum.h>
|
||||
|
||||
#define SK_CS_CALCULATE_CHECKSUM
|
||||
#ifndef CONFIG_X86_64
|
||||
#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff)
|
||||
#else
|
||||
#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff)
|
||||
#endif
|
||||
|
||||
#include "h/sktypes.h"
|
||||
#include "h/skerror.h"
|
||||
#include "h/skdebug.h"
|
||||
#include "h/lm80.h"
|
||||
#include "h/xmac_ii.h"
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
#define SK_LITTLE_ENDIAN
|
||||
#else
|
||||
#define SK_BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
#define SK_NET_DEVICE net_device
|
||||
|
||||
|
||||
/* we use gethrtime(), return unit: nanoseconds */
|
||||
#define SK_TICKS_PER_SEC 100
|
||||
|
||||
#define SK_MEM_MAPPED_IO
|
||||
|
||||
// #define SK_RLMT_SLOW_LOOKAHEAD
|
||||
|
||||
#define SK_MAX_MACS 2
|
||||
#define SK_MAX_NETS 2
|
||||
|
||||
#define SK_IOC char __iomem *
|
||||
|
||||
typedef struct s_DrvRlmtMbuf SK_MBUF;
|
||||
|
||||
#define SK_CONST64 INT64_C
|
||||
#define SK_CONSTU64 UINT64_C
|
||||
|
||||
#define SK_MEMCPY(dest,src,size) memcpy(dest,src,size)
|
||||
#define SK_MEMCMP(s1,s2,size) memcmp(s1,s2,size)
|
||||
#define SK_MEMSET(dest,val,size) memset(dest,val,size)
|
||||
#define SK_STRLEN(pStr) strlen((char*)(pStr))
|
||||
#define SK_STRNCPY(pDest,pSrc,size) strncpy((char*)(pDest),(char*)(pSrc),size)
|
||||
#define SK_STRCMP(pStr1,pStr2) strcmp((char*)(pStr1),(char*)(pStr2))
|
||||
|
||||
/* macros to access the adapter */
|
||||
#define SK_OUT8(b,a,v) writeb((v), ((b)+(a)))
|
||||
#define SK_OUT16(b,a,v) writew((v), ((b)+(a)))
|
||||
#define SK_OUT32(b,a,v) writel((v), ((b)+(a)))
|
||||
#define SK_IN8(b,a,pv) (*(pv) = readb((b)+(a)))
|
||||
#define SK_IN16(b,a,pv) (*(pv) = readw((b)+(a)))
|
||||
#define SK_IN32(b,a,pv) (*(pv) = readl((b)+(a)))
|
||||
|
||||
#define int8_t char
|
||||
#define int16_t short
|
||||
#define int32_t long
|
||||
#define int64_t long long
|
||||
#define uint8_t u_char
|
||||
#define uint16_t u_short
|
||||
#define uint32_t u_long
|
||||
#define uint64_t unsigned long long
|
||||
#define t_scalar_t int
|
||||
#define t_uscalar_t unsigned int
|
||||
#define uintptr_t unsigned long
|
||||
|
||||
#define __CONCAT__(A,B) A##B
|
||||
|
||||
#define INT32_C(a) __CONCAT__(a,L)
|
||||
#define INT64_C(a) __CONCAT__(a,LL)
|
||||
#define UINT32_C(a) __CONCAT__(a,UL)
|
||||
#define UINT64_C(a) __CONCAT__(a,ULL)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define SK_DBG_PRINTF printk
|
||||
#ifndef SK_DEBUG_CHKMOD
|
||||
#define SK_DEBUG_CHKMOD 0
|
||||
#endif
|
||||
#ifndef SK_DEBUG_CHKCAT
|
||||
#define SK_DEBUG_CHKCAT 0
|
||||
#endif
|
||||
/* those come from the makefile */
|
||||
#define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD)
|
||||
#define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT)
|
||||
|
||||
extern void SkDbgPrintf(const char *format,...);
|
||||
|
||||
#define SK_DBGMOD_DRV 0x00010000
|
||||
|
||||
/**** possible driver debug categories ********************************/
|
||||
#define SK_DBGCAT_DRV_ENTRY 0x00010000
|
||||
#define SK_DBGCAT_DRV_SAP 0x00020000
|
||||
#define SK_DBGCAT_DRV_MCA 0x00040000
|
||||
#define SK_DBGCAT_DRV_TX_PROGRESS 0x00080000
|
||||
#define SK_DBGCAT_DRV_RX_PROGRESS 0x00100000
|
||||
#define SK_DBGCAT_DRV_PROGRESS 0x00200000
|
||||
#define SK_DBGCAT_DRV_MSG 0x00400000
|
||||
#define SK_DBGCAT_DRV_PROM 0x00800000
|
||||
#define SK_DBGCAT_DRV_TX_FRAME 0x01000000
|
||||
#define SK_DBGCAT_DRV_ERROR 0x02000000
|
||||
#define SK_DBGCAT_DRV_INT_SRC 0x04000000
|
||||
#define SK_DBGCAT_DRV_EVENT 0x08000000
|
||||
|
||||
#endif
|
||||
|
||||
#define SK_ERR_LOG SkErrorLog
|
||||
|
||||
extern void SkErrorLog(SK_AC*, int, int, char*);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: skdrv2nd.h
|
||||
* Project: GEnesis, PCI Gigabit Ethernet Adapter
|
||||
* Version: $Revision: 1.10 $
|
||||
* Date: $Date: 2003/12/11 16:04:45 $
|
||||
* Purpose: Second header file for driver and all other modules
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* (C)Copyright 1998-2002 SysKonnect GmbH.
|
||||
* (C)Copyright 2002-2003 Marvell.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The information in this file is provided "AS IS" without warranty.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This is the second include file of the driver, which includes all other
|
||||
* neccessary files and defines all structures and constants used by the
|
||||
* driver and the common modules.
|
||||
*
|
||||
* Include File Hierarchy:
|
||||
*
|
||||
* see skge.c
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __INC_SKDRV2ND_H
|
||||
#define __INC_SKDRV2ND_H
|
||||
|
||||
#include "h/skqueue.h"
|
||||
#include "h/skgehwt.h"
|
||||
#include "h/sktimer.h"
|
||||
#include "h/ski2c.h"
|
||||
#include "h/skgepnmi.h"
|
||||
#include "h/skvpd.h"
|
||||
#include "h/skgehw.h"
|
||||
#include "h/skgeinit.h"
|
||||
#include "h/skaddr.h"
|
||||
#include "h/skgesirq.h"
|
||||
#include "h/skcsum.h"
|
||||
#include "h/skrlmt.h"
|
||||
#include "h/skgedrv.h"
|
||||
|
||||
|
||||
extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
|
||||
extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
|
||||
extern SK_U64 SkOsGetTime(SK_AC*);
|
||||
extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
|
||||
extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*);
|
||||
extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*);
|
||||
extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16);
|
||||
extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8);
|
||||
extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
|
||||
|
||||
#ifdef SK_DIAG_SUPPORT
|
||||
extern int SkDrvEnterDiagMode(SK_AC *pAc);
|
||||
extern int SkDrvLeaveDiagMode(SK_AC *pAc);
|
||||
#endif
|
||||
|
||||
struct s_DrvRlmtMbuf {
|
||||
SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */
|
||||
SK_U8 *pData; /* Data buffer (virtually contig.). */
|
||||
unsigned Size; /* Data buffer size. */
|
||||
unsigned Length; /* Length of packet (<= Size). */
|
||||
SK_U32 PortIdx; /* Receiving/transmitting port. */
|
||||
#ifdef SK_RLMT_MBUF_PRIVATE
|
||||
SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */
|
||||
#endif /* SK_RLMT_MBUF_PRIVATE */
|
||||
struct sk_buff *pOs; /* Pointer to message block */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Time macros
|
||||
*/
|
||||
#if SK_TICKS_PER_SEC == 100
|
||||
#define SK_PNMI_HUNDREDS_SEC(t) (t)
|
||||
#else
|
||||
#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \
|
||||
(SK_TICKS_PER_SEC))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* New SkOsGetTime
|
||||
*/
|
||||
#define SkOsGetTimeCurrent(pAC, pUsec) {\
|
||||
struct timeval t;\
|
||||
do_gettimeofday(&t);\
|
||||
*pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ioctl definitions
|
||||
*/
|
||||
#define SK_IOCTL_BASE (SIOCDEVPRIVATE)
|
||||
#define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0)
|
||||
#define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1)
|
||||
#define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2)
|
||||
#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3)
|
||||
#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4)
|
||||
|
||||
typedef struct s_IOCTL SK_GE_IOCTL;
|
||||
|
||||
struct s_IOCTL {
|
||||
char __user * pData;
|
||||
unsigned int Len;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* define sizes of descriptor rings in bytes
|
||||
*/
|
||||
|
||||
#define TX_RING_SIZE (8*1024)
|
||||
#define RX_RING_SIZE (24*1024)
|
||||
|
||||
/*
|
||||
* Buffer size for ethernet packets
|
||||
*/
|
||||
#define ETH_BUF_SIZE 1540
|
||||
#define ETH_MAX_MTU 1514
|
||||
#define ETH_MIN_MTU 60
|
||||
#define ETH_MULTICAST_BIT 0x01
|
||||
#define SK_JUMBO_MTU 9000
|
||||
|
||||
/*
|
||||
* transmit priority selects the queue: LOW=asynchron, HIGH=synchron
|
||||
*/
|
||||
#define TX_PRIO_LOW 0
|
||||
#define TX_PRIO_HIGH 1
|
||||
|
||||
/*
|
||||
* alignment of rx/tx descriptors
|
||||
*/
|
||||
#define DESCR_ALIGN 64
|
||||
|
||||
/*
|
||||
* definitions for pnmi. TODO
|
||||
*/
|
||||
#define SK_DRIVER_RESET(pAC, IoC) 0
|
||||
#define SK_DRIVER_SENDEVENT(pAC, IoC) 0
|
||||
#define SK_DRIVER_SELFTEST(pAC, IoC) 0
|
||||
/* For get mtu you must add an own function */
|
||||
#define SK_DRIVER_GET_MTU(pAc,IoC,i) 0
|
||||
#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0
|
||||
#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0
|
||||
|
||||
/*
|
||||
** Interim definition of SK_DRV_TIMER placed in this file until
|
||||
** common modules have been finalized
|
||||
*/
|
||||
#define SK_DRV_TIMER 11
|
||||
#define SK_DRV_MODERATION_TIMER 1
|
||||
#define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */
|
||||
#define SK_DRV_RX_CLEANUP_TIMER 2
|
||||
#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */
|
||||
|
||||
/*
|
||||
** Definitions regarding transmitting frames
|
||||
** any calculating any checksum.
|
||||
*/
|
||||
#define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6
|
||||
#define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6
|
||||
#define C_LEN_ETHERMAC_HEADER_LENTYPE 2
|
||||
#define C_LEN_ETHERMAC_HEADER ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \
|
||||
(C_LEN_ETHERMAC_HEADER_SRC_ADDR) + \
|
||||
(C_LEN_ETHERMAC_HEADER_LENTYPE) )
|
||||
|
||||
#define C_LEN_ETHERMTU_MINSIZE 46
|
||||
#define C_LEN_ETHERMTU_MAXSIZE_STD 1500
|
||||
#define C_LEN_ETHERMTU_MAXSIZE_JUMBO 9000
|
||||
|
||||
#define C_LEN_ETHERNET_MINSIZE ( (C_LEN_ETHERMAC_HEADER) + \
|
||||
(C_LEN_ETHERMTU_MINSIZE) )
|
||||
|
||||
#define C_OFFSET_IPHEADER C_LEN_ETHERMAC_HEADER
|
||||
#define C_OFFSET_IPHEADER_IPPROTO 9
|
||||
#define C_OFFSET_TCPHEADER_TCPCS 16
|
||||
#define C_OFFSET_UDPHEADER_UDPCS 6
|
||||
|
||||
#define C_OFFSET_IPPROTO ( (C_LEN_ETHERMAC_HEADER) + \
|
||||
(C_OFFSET_IPHEADER_IPPROTO) )
|
||||
|
||||
#define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */
|
||||
#define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */
|
||||
|
||||
/* TX and RX descriptors *****************************************************/
|
||||
|
||||
typedef struct s_RxD RXD; /* the receive descriptor */
|
||||
|
||||
struct s_RxD {
|
||||
volatile SK_U32 RBControl; /* Receive Buffer Control */
|
||||
SK_U32 VNextRxd; /* Next receive descriptor,low dword */
|
||||
SK_U32 VDataLow; /* Receive buffer Addr, low dword */
|
||||
SK_U32 VDataHigh; /* Receive buffer Addr, high dword */
|
||||
SK_U32 FrameStat; /* Receive Frame Status word */
|
||||
SK_U32 TimeStamp; /* Time stamp from XMAC */
|
||||
SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */
|
||||
SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */
|
||||
RXD *pNextRxd; /* Pointer to next Rxd */
|
||||
struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
|
||||
};
|
||||
|
||||
typedef struct s_TxD TXD; /* the transmit descriptor */
|
||||
|
||||
struct s_TxD {
|
||||
volatile SK_U32 TBControl; /* Transmit Buffer Control */
|
||||
SK_U32 VNextTxd; /* Next transmit descriptor,low dword */
|
||||
SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */
|
||||
SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */
|
||||
SK_U32 FrameStat; /* Transmit Frame Status Word */
|
||||
SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */
|
||||
SK_U16 TcpSumSt; /* TCP Sum Start */
|
||||
SK_U16 TcpSumWr; /* TCP Sum Write */
|
||||
SK_U32 TcpReserved; /* not used */
|
||||
TXD *pNextTxd; /* Pointer to next Txd */
|
||||
struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
|
||||
};
|
||||
|
||||
/* Used interrupt bits in the interrupts source register *********************/
|
||||
|
||||
#define DRIVER_IRQS ((IS_IRQ_SW) | \
|
||||
(IS_R1_F) |(IS_R2_F) | \
|
||||
(IS_XS1_F) |(IS_XA1_F) | \
|
||||
(IS_XS2_F) |(IS_XA2_F))
|
||||
|
||||
#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \
|
||||
(IS_EXT_REG) |(IS_TIMINT) | \
|
||||
(IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \
|
||||
(IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \
|
||||
(IS_MAC1) |(IS_LNK_SYNC_M1)| \
|
||||
(IS_MAC2) |(IS_LNK_SYNC_M2)| \
|
||||
(IS_R1_C) |(IS_R2_C) | \
|
||||
(IS_XS1_C) |(IS_XA1_C) | \
|
||||
(IS_XS2_C) |(IS_XA2_C))
|
||||
|
||||
#define IRQ_MASK ((IS_IRQ_SW) | \
|
||||
(IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \
|
||||
(IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \
|
||||
(IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \
|
||||
(IS_HW_ERR) |(IS_I2C_READY)| \
|
||||
(IS_EXT_REG) |(IS_TIMINT) | \
|
||||
(IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
|
||||
(IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
|
||||
(IS_MAC1) |(IS_MAC2) | \
|
||||
(IS_R1_C) |(IS_R2_C) | \
|
||||
(IS_XS1_C) |(IS_XA1_C) | \
|
||||
(IS_XS2_C) |(IS_XA2_C))
|
||||
|
||||
#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */
|
||||
|
||||
typedef struct s_DevNet DEV_NET;
|
||||
|
||||
struct s_DevNet {
|
||||
int PortNr;
|
||||
int NetNr;
|
||||
SK_AC *pAC;
|
||||
};
|
||||
|
||||
typedef struct s_TxPort TX_PORT;
|
||||
|
||||
struct s_TxPort {
|
||||
/* the transmit descriptor rings */
|
||||
caddr_t pTxDescrRing; /* descriptor area memory */
|
||||
SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */
|
||||
TXD *pTxdRingHead; /* Head of Tx rings */
|
||||
TXD *pTxdRingTail; /* Tail of Tx rings */
|
||||
TXD *pTxdRingPrev; /* descriptor sent previously */
|
||||
int TxdRingFree; /* # of free entrys */
|
||||
spinlock_t TxDesRingLock; /* serialize descriptor accesses */
|
||||
SK_IOC HwAddr; /* bmu registers address */
|
||||
int PortIndex; /* index number of port (0 or 1) */
|
||||
};
|
||||
|
||||
typedef struct s_RxPort RX_PORT;
|
||||
|
||||
struct s_RxPort {
|
||||
/* the receive descriptor rings */
|
||||
caddr_t pRxDescrRing; /* descriptor area memory */
|
||||
SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */
|
||||
RXD *pRxdRingHead; /* Head of Rx rings */
|
||||
RXD *pRxdRingTail; /* Tail of Rx rings */
|
||||
RXD *pRxdRingPrev; /* descriptor given to BMU previously */
|
||||
int RxdRingFree; /* # of free entrys */
|
||||
int RxCsum; /* use receive checksum hardware */
|
||||
spinlock_t RxDesRingLock; /* serialize descriptor accesses */
|
||||
int RxFillLimit; /* limit for buffers in ring */
|
||||
SK_IOC HwAddr; /* bmu registers address */
|
||||
int PortIndex; /* index number of port (0 or 1) */
|
||||
};
|
||||
|
||||
/* Definitions needed for interrupt moderation *******************************/
|
||||
|
||||
#define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F))
|
||||
#define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F))
|
||||
#define IRQ_MASK_TX_ONLY ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX))
|
||||
#define IRQ_MASK_RX_ONLY ((IS_R1_F) | (IS_R2_F))
|
||||
#define IRQ_MASK_SP_ONLY (SPECIAL_IRQS)
|
||||
#define IRQ_MASK_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY))
|
||||
#define IRQ_MASK_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY))
|
||||
#define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY))
|
||||
#define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX))
|
||||
|
||||
#define C_INT_MOD_NONE 1
|
||||
#define C_INT_MOD_STATIC 2
|
||||
#define C_INT_MOD_DYNAMIC 4
|
||||
|
||||
#define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */
|
||||
#define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */
|
||||
|
||||
#define C_INTS_PER_SEC_DEFAULT 2000
|
||||
#define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */
|
||||
#define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */
|
||||
#define C_INT_MOD_IPS_LOWER_RANGE 30
|
||||
#define C_INT_MOD_IPS_UPPER_RANGE 40000
|
||||
|
||||
|
||||
typedef struct s_DynIrqModInfo DIM_INFO;
|
||||
struct s_DynIrqModInfo {
|
||||
unsigned long PrevTimeVal;
|
||||
unsigned int PrevSysLoad;
|
||||
unsigned int PrevUsedTime;
|
||||
unsigned int PrevTotalTime;
|
||||
int PrevUsedDescrRatio;
|
||||
int NbrProcessedDescr;
|
||||
SK_U64 PrevPort0RxIntrCts;
|
||||
SK_U64 PrevPort1RxIntrCts;
|
||||
SK_U64 PrevPort0TxIntrCts;
|
||||
SK_U64 PrevPort1TxIntrCts;
|
||||
SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */
|
||||
|
||||
int MaxModIntsPerSec; /* Moderation Threshold */
|
||||
int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */
|
||||
int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */
|
||||
|
||||
long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */
|
||||
SK_BOOL DisplayStats; /* Stats yes/no */
|
||||
SK_BOOL AutoSizing; /* Resize DIM-timer on/off */
|
||||
int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */
|
||||
|
||||
SK_TIMER ModTimer; /* just some timer */
|
||||
};
|
||||
|
||||
typedef struct s_PerStrm PER_STRM;
|
||||
|
||||
#define SK_ALLOC_IRQ 0x00000001
|
||||
|
||||
#ifdef SK_DIAG_SUPPORT
|
||||
#define DIAG_ACTIVE 1
|
||||
#define DIAG_NOTACTIVE 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Per board structure / Adapter Context structure:
|
||||
* Allocated within attach(9e) and freed within detach(9e).
|
||||
* Contains all 'per device' necessary handles, flags, locks etc.:
|
||||
*/
|
||||
struct s_AC {
|
||||
SK_GEINIT GIni; /* GE init struct */
|
||||
SK_PNMI Pnmi; /* PNMI data struct */
|
||||
SK_VPD vpd; /* vpd data struct */
|
||||
SK_QUEUE Event; /* Event queue */
|
||||
SK_HWT Hwt; /* Hardware Timer control struct */
|
||||
SK_TIMCTRL Tim; /* Software Timer control struct */
|
||||
SK_I2C I2c; /* I2C relevant data structure */
|
||||
SK_ADDR Addr; /* for Address module */
|
||||
SK_CSUM Csum; /* for checksum module */
|
||||
SK_RLMT Rlmt; /* for rlmt module */
|
||||
spinlock_t SlowPathLock; /* Normal IRQ lock */
|
||||
struct timer_list BlinkTimer; /* for LED blinking */
|
||||
int LedsOn;
|
||||
SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
|
||||
int RlmtMode; /* link check mode to set */
|
||||
int RlmtNets; /* Number of nets */
|
||||
|
||||
SK_IOC IoBase; /* register set of adapter */
|
||||
int BoardLevel; /* level of active hw init (0-2) */
|
||||
|
||||
SK_U32 AllocFlag; /* flag allocation of resources */
|
||||
struct pci_dev *PciDev; /* for access to pci config space */
|
||||
struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */
|
||||
|
||||
int RxBufSize; /* length of receive buffers */
|
||||
struct net_device_stats stats; /* linux 'netstat -i' statistics */
|
||||
int Index; /* internal board index number */
|
||||
|
||||
/* adapter RAM sizes for queues of active port */
|
||||
int RxQueueSize; /* memory used for receive queue */
|
||||
int TxSQueueSize; /* memory used for sync. tx queue */
|
||||
int TxAQueueSize; /* memory used for async. tx queue */
|
||||
|
||||
int PromiscCount; /* promiscuous mode counter */
|
||||
int AllMultiCount; /* allmulticast mode counter */
|
||||
int MulticCount; /* number of different MC */
|
||||
/* addresses for this board */
|
||||
/* (may be more than HW can)*/
|
||||
|
||||
int HWRevision; /* Hardware revision */
|
||||
int ActivePort; /* the active XMAC port */
|
||||
int MaxPorts; /* number of activated ports */
|
||||
int TxDescrPerRing; /* # of descriptors per tx ring */
|
||||
int RxDescrPerRing; /* # of descriptors per rx ring */
|
||||
|
||||
caddr_t pDescrMem; /* Pointer to the descriptor area */
|
||||
dma_addr_t pDescrMemDMA; /* PCI DMA address of area */
|
||||
|
||||
/* the port structures with descriptor rings */
|
||||
TX_PORT TxPort[SK_MAX_MACS][2];
|
||||
RX_PORT RxPort[SK_MAX_MACS];
|
||||
|
||||
SK_BOOL CheckQueue; /* check event queue soon */
|
||||
SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */
|
||||
DIM_INFO DynIrqModInfo; /* all data related to DIM */
|
||||
|
||||
/* Only for tests */
|
||||
int PortDown;
|
||||
int ChipsetType; /* Chipset family type
|
||||
* 0 == Genesis family support
|
||||
* 1 == Yukon family support
|
||||
*/
|
||||
#ifdef SK_DIAG_SUPPORT
|
||||
SK_U32 DiagModeActive; /* is diag active? */
|
||||
SK_BOOL DiagFlowCtrl; /* for control purposes */
|
||||
SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */
|
||||
SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while
|
||||
* DIAG is busy with NIC
|
||||
*/
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /* __INC_SKDRV2ND_H */
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: skerror.h
|
||||
* Project: Gigabit Ethernet Adapters, Common Modules
|
||||
* Version: $Revision: 1.7 $
|
||||
* Date: $Date: 2003/05/13 17:25:13 $
|
||||
* Purpose: SK specific Error log support
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* (C)Copyright 1998-2002 SysKonnect.
|
||||
* (C)Copyright 2002-2003 Marvell.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The information in this file is provided "AS IS" without warranty.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _INC_SKERROR_H_
|
||||
#define _INC_SKERROR_H_
|
||||
|
||||
/*
|
||||
* Define Error Classes
|
||||
*/
|
||||
#define SK_ERRCL_OTHER (0) /* Other error */
|
||||
#define SK_ERRCL_CONFIG (1L<<0) /* Configuration error */
|
||||
#define SK_ERRCL_INIT (1L<<1) /* Initialization error */
|
||||
#define SK_ERRCL_NORES (1L<<2) /* Out of Resources error */
|
||||
#define SK_ERRCL_SW (1L<<3) /* Internal Software error */
|
||||
#define SK_ERRCL_HW (1L<<4) /* Hardware Failure */
|
||||
#define SK_ERRCL_COMM (1L<<5) /* Communication error */
|
||||
|
||||
|
||||
/*
|
||||
* Define Error Code Bases
|
||||
*/
|
||||
#define SK_ERRBASE_RLMT 100 /* Base Error number for RLMT */
|
||||
#define SK_ERRBASE_HWINIT 200 /* Base Error number for HWInit */
|
||||
#define SK_ERRBASE_VPD 300 /* Base Error number for VPD */
|
||||
#define SK_ERRBASE_PNMI 400 /* Base Error number for PNMI */
|
||||
#define SK_ERRBASE_CSUM 500 /* Base Error number for Checksum */
|
||||
#define SK_ERRBASE_SIRQ 600 /* Base Error number for Special IRQ */
|
||||
#define SK_ERRBASE_I2C 700 /* Base Error number for I2C module */
|
||||
#define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */
|
||||
#define SK_ERRBASE_ADDR 900 /* Base Error number for Address module */
|
||||
#define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */
|
||||
#define SK_ERRBASE_DRV 1100 /* Base Error number for Driver */
|
||||
|
||||
#endif /* _INC_SKERROR_H_ */
|
|
@ -0,0 +1,51 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: skgedrv.h
|
||||
* Project: Gigabit Ethernet Adapters, Common Modules
|
||||
* Version: $Revision: 1.10 $
|
||||
* Date: $Date: 2003/07/04 12:25:01 $
|
||||
* Purpose: Interface with the driver
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* (C)Copyright 1998-2002 SysKonnect.
|
||||
* (C)Copyright 2002-2003 Marvell.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The information in this file is provided "AS IS" without warranty.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __INC_SKGEDRV_H_
|
||||
#define __INC_SKGEDRV_H_
|
||||
|
||||
/* defines ********************************************************************/
|
||||
|
||||
/*
|
||||
* Define the driver events.
|
||||
* Usually the events are defined by the destination module.
|
||||
* In case of the driver we put the definition of the events here.
|
||||
*/
|
||||
#define SK_DRV_PORT_RESET 1 /* The port needs to be reset */
|
||||
#define SK_DRV_NET_UP 2 /* The net is operational */
|
||||
#define SK_DRV_NET_DOWN 3 /* The net is down */
|
||||
#define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links connected */
|
||||
#define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */
|
||||
#define SK_DRV_RLMT_SEND 6 /* Send a RLMT packet */
|
||||
#define SK_DRV_ADAP_FAIL 7 /* The whole adapter fails */
|
||||
#define SK_DRV_PORT_FAIL 8 /* One port fails */
|
||||
#define SK_DRV_SWITCH_INTERN 9 /* Port switch by the driver itself */
|
||||
#define SK_DRV_POWER_DOWN 10 /* Power down mode */
|
||||
#define SK_DRV_TIMER 11 /* Timer for free use */
|
||||
#ifdef SK_NO_RLMT
|
||||
#define SK_DRV_LINK_UP 12 /* Link Up event for driver */
|
||||
#define SK_DRV_LINK_DOWN 13 /* Link Down event for driver */
|
||||
#endif
|
||||
#define SK_DRV_DOWNSHIFT_DET 14 /* Downshift 4-Pair / 2-Pair (YUKON only) */
|
||||
#endif /* __INC_SKGEDRV_H_ */
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче