瀏覽代碼

Merge branch 'linux-2.6'

Paul Mackerras 17 年之前
父節點
當前提交
0ce49a3945
共有 100 個文件被更改,包括 3819 次插入760 次删除
  1. 1 1
      Documentation/ManagementStyle
  2. 8 0
      Documentation/feature-removal-schedule.txt
  3. 0 3
      Documentation/kernel-parameters.txt
  4. 3 0
      Documentation/networking/00-INDEX
  5. 568 0
      Documentation/networking/sk98lin.txt
  6. 77 19
      Documentation/thinkpad-acpi.txt
  7. 3 1
      Documentation/video4linux/cx2341x/fw-encoder-api.txt
  8. 1 1
      arch/arm/mach-realview/realview_eb.c
  9. 1 0
      arch/arm/vfp/vfpmodule.c
  10. 6 0
      arch/blackfin/mach-common/pm.c
  11. 2 2
      arch/i386/xen/enlighten.c
  12. 1 1
      arch/mips/dec/setup.c
  13. 2 2
      arch/mips/kernel/cpu-bugs64.c
  14. 8 1
      arch/mips/kernel/cpu-probe.c
  15. 1 3
      arch/mips/kernel/rtlx.c
  16. 1 1
      arch/mips/kernel/scall64-n32.S
  17. 1 0
      arch/mips/kernel/time.c
  18. 1 1
      arch/mips/mips-boards/malta/malta_int.c
  19. 25 1
      arch/mips/mm/tlbex.c
  20. 5 3
      arch/powerpc/kernel/time.c
  21. 12 0
      arch/powerpc/kernel/vdso.c
  22. 2 2
      arch/powerpc/platforms/cell/spufs/sched.c
  23. 5 11
      arch/sparc64/defconfig
  24. 30 5
      arch/sparc64/kernel/head.S
  25. 5 1
      arch/sparc64/kernel/mdesc.c
  26. 5 1
      arch/sparc64/kernel/prom.c
  27. 28 5
      arch/sparc64/kernel/trampoline.S
  28. 0 16
      arch/sparc64/prom/misc.c
  29. 1 1
      arch/um/include/kern_util.h
  30. 4 3
      arch/um/kernel/irq.c
  31. 2 1
      arch/um/os-Linux/file.c
  32. 2 2
      arch/um/os-Linux/signal.c
  33. 7 0
      arch/x86_64/mm/fault.c
  34. 6 1
      arch/xtensa/Makefile
  35. 1 1
      arch/xtensa/kernel/Makefile
  36. 6 7
      arch/xtensa/kernel/asm-offsets.c
  37. 98 17
      arch/xtensa/kernel/entry.S
  38. 38 0
      arch/xtensa/kernel/init_task.c
  39. 75 0
      arch/xtensa/kernel/io.c
  40. 177 18
      arch/xtensa/kernel/module.c
  41. 0 69
      arch/xtensa/kernel/pci.c
  42. 0 14
      arch/xtensa/kernel/process.c
  43. 1 1
      arch/xtensa/kernel/semaphore.c
  44. 5 0
      arch/xtensa/kernel/syscall.c
  45. 29 17
      arch/xtensa/kernel/time.c
  46. 2 2
      arch/xtensa/kernel/traps.c
  47. 1 5
      arch/xtensa/mm/Makefile
  48. 256 0
      arch/xtensa/mm/cache.c
  49. 4 2
      arch/xtensa/mm/fault.c
  50. 15 237
      arch/xtensa/mm/init.c
  51. 271 35
      arch/xtensa/mm/misc.S
  52. 0 1
      arch/xtensa/platform-iss/console.c
  53. 17 6
      block/ll_rw_blk.c
  54. 1 1
      drivers/acpi/event.c
  55. 21 0
      drivers/acpi/processor_core.c
  56. 5 5
      drivers/acpi/sleep/proc.c
  57. 23 6
      drivers/base/core.c
  58. 1 0
      drivers/block/DAC960.c
  59. 2 1
      drivers/char/agp/agp.h
  60. 1 1
      drivers/char/agp/intel-agp.c
  61. 2 1
      drivers/char/ipmi/ipmi_si_intf.c
  62. 48 21
      drivers/char/mspec.c
  63. 14 0
      drivers/char/tty_ioctl.c
  64. 1 0
      drivers/ide/ide-disk.c
  65. 0 2
      drivers/ide/ppc/pmac.c
  66. 7 3
      drivers/kvm/kvm.h
  67. 3 2
      drivers/kvm/mmu.c
  68. 3 0
      drivers/md/dm-bio-list.h
  69. 1 1
      drivers/media/video/cx88/cx88-mpeg.c
  70. 4 2
      drivers/media/video/ivtv/ivtv-fileops.c
  71. 12 5
      drivers/media/video/ivtv/ivtv-ioctl.c
  72. 1 1
      drivers/media/video/pwc/pwc-if.c
  73. 6 6
      drivers/media/video/saa7134/saa7134-cards.c
  74. 2 2
      drivers/media/video/saa7191.c
  75. 1 0
      drivers/media/video/usbvision/usbvision-cards.c
  76. 0 20
      drivers/misc/Kconfig
  77. 1 1
      drivers/misc/msi-laptop.c
  78. 87 57
      drivers/misc/thinkpad_acpi.c
  79. 1 0
      drivers/misc/thinkpad_acpi.h
  80. 2 1
      drivers/mtd/nand/cafe_nand.c
  81. 88 1
      drivers/net/Kconfig
  82. 1 0
      drivers/net/Makefile
  83. 7 12
      drivers/net/atl1/atl1_main.c
  84. 4 1
      drivers/net/ehea/ehea.h
  85. 14 2
      drivers/net/ehea/ehea_main.c
  86. 1 1
      drivers/net/mv643xx_eth.c
  87. 1 1
      drivers/net/pcmcia/3c589_cs.c
  88. 2 2
      drivers/net/phy/phy.c
  89. 2 2
      drivers/net/phy/phy_device.c
  90. 28 30
      drivers/net/ppp_generic.c
  91. 22 48
      drivers/net/pppoe.c
  92. 87 0
      drivers/net/sk98lin/Makefile
  93. 179 0
      drivers/net/sk98lin/h/lm80.h
  94. 285 0
      drivers/net/sk98lin/h/skaddr.h
  95. 213 0
      drivers/net/sk98lin/h/skcsum.h
  96. 74 0
      drivers/net/sk98lin/h/skdebug.h
  97. 188 0
      drivers/net/sk98lin/h/skdrv1st.h
  98. 447 0
      drivers/net/sk98lin/h/skdrv2nd.h
  99. 55 0
      drivers/net/sk98lin/h/skerror.h
  100. 51 0
      drivers/net/sk98lin/h/skgedrv.h

+ 1 - 1
Documentation/ManagementStyle

@@ -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. 
 

+ 8 - 0
Documentation/feature-removal-schedule.txt

@@ -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>
+
+---------------------------

+ 0 - 3
Documentation/kernel-parameters.txt

@@ -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.

+ 3 - 0
Documentation/networking/00-INDEX

@@ -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

+ 568 - 0
Documentation/networking/sk98lin.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***

+ 77 - 19
Documentation/thinkpad-acpi.txt

@@ -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
 ---------

+ 3 - 1
Documentation/video4linux/cx2341x/fw-encoder-api.txt

@@ -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.
 	};

+ 1 - 1
arch/arm/mach-realview/realview_eb.c

@@ -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);

+ 1 - 0
arch/arm/vfp/vfpmodule.c

@@ -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;

+ 6 - 0
arch/blackfin/mach-common/pm.c

@@ -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)

+ 2 - 2
arch/i386/xen/enlighten.c

@@ -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)

+ 1 - 1
arch/mips/dec/setup.c

@@ -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;
 

+ 2 - 2
arch/mips/kernel/cpu-bugs64.c

@@ -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,

+ 8 - 1
arch/mips/kernel/cpu-probe.c

@@ -199,7 +199,14 @@ static inline void check_wait(void)
 		if ((c->processor_id & 0xff) <= 0x64)
 			break;
 
-		cpu_wait = r4k_wait;
+		/*
+		 * 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)

+ 1 - 3
arch/mips/kernel/rtlx.c

@@ -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;
 	}
 

+ 1 - 1
arch/mips/kernel/scall64-n32.S

@@ -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

+ 1 - 0
arch/mips/kernel/time.c

@@ -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>

+ 1 - 1
arch/mips/mips-boards/malta/malta_int.c

@@ -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();

+ 25 - 1
arch/mips/mm/tlbex.c

@@ -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,7 +1722,8 @@ 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 */
-	build_tlb_probe_entry(p);
+	if (!m4kc_tlbp_war())
+		build_tlb_probe_entry(p);
 }
 
 static void __init
@@ -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);

+ 5 - 3
arch/powerpc/kernel/time.c

@@ -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();
 

+ 12 - 0
arch/powerpc/kernel/vdso.c

@@ -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
+	},
 };
 
 /*

+ 2 - 2
arch/powerpc/platforms/cell/spufs/sched.c

@@ -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);

+ 5 - 11
arch/sparc64/defconfig

@@ -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
 
 #

+ 30 - 5
arch/sparc64/kernel/head.S

@@ -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
+	sethi	%hi(sparc64_ttable_tl0), %o0
 
-	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

+ 5 - 1
arch/sparc64/kernel/mdesc.c

@@ -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

+ 5 - 1
arch/sparc64/kernel/prom.c

@@ -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

+ 28 - 5
arch/sparc64/kernel/trampoline.S

@@ -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
+	sethi		%hi(sparc64_ttable_tl0), %o0
 
-	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

+ 0 - 16
arch/sparc64/prom/misc.c

@@ -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;

+ 1 - 1
arch/um/include/kern_util.h

@@ -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

+ 4 - 3
arch/um/kernel/irq.c

@@ -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;

+ 2 - 1
arch/um/os-Linux/file.c

@@ -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){

+ 2 - 2
arch/um/os-Linux/signal.c

@@ -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;
 

+ 7 - 0
arch/x86_64/mm/fault.c

@@ -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

+ 6 - 1
arch/xtensa/Makefile

@@ -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
 

+ 1 - 1
arch/xtensa/kernel/Makefile

@@ -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
 

+ 6 - 7
arch/xtensa/kernel/asm-offsets.c

@@ -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;
 }
 
-

+ 98 - 17
arch/xtensa/kernel/entry.S

@@ -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
 
+	/*
+	 * 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)
+	 */
+
+	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	a1, a1, DTLB_WAY_PGD	# ... + way_number
+	addi	a3, a3, DTLB_WAY_PGD
+	add	a1, a1, a3		# ... + way_number
 
-	wdtlb	a0, a1
+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. */
 

+ 38 - 0
arch/xtensa/kernel/init_task.c

@@ -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);

+ 75 - 0
arch/xtensa/kernel/io.c

@@ -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;
+        }
+}

+ 177 - 18
arch/xtensa/kernel/module.c

@@ -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");
 }

+ 0 - 69
arch/xtensa/kernel/pci.c

@@ -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;
-        }
-}
-
-
-

+ 0 - 14
arch/xtensa/kernel/process.c

@@ -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;

+ 1 - 1
arch/xtensa/kernel/semaphore.c

@@ -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:

+ 5 - 0
arch/xtensa/kernel/syscall.c

@@ -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);
+}
+

+ 29 - 17
arch/xtensa/kernel/time.c

@@ -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,9 +171,12 @@ again:
 
 		write_seqlock(&xtime_lock);
 
-		last_ccount_stamp = next;
+		do_timer(1); /* Linux handler in kernel/timer.c */
+
+		/* Note that writing CCOMPARE clears the interrupt. */
+
 		next += CCOUNT_PER_JIFFY;
-		do_timer (1); /* Linux handler in kernel/timer.c */
+		set_linux_timer(next);
 
 		if (ntp_synced() &&
 		    xtime.tv_sec - last_rtc_update >= 659 &&
@@ -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;
 }
 

+ 2 - 2
arch/xtensa/kernel/traps.c

@@ -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;
 

+ 1 - 5
arch/xtensa/mm/Makefile

@@ -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

+ 256 - 0
arch/xtensa/mm/cache.c

@@ -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

+ 4 - 2
arch/xtensa/mm/fault.c

@@ -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 - 237
arch/xtensa/mm/init.c

@@ -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);
 }
 
-/* ------------------------------------------------------------------------- */
-
-#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)
-{
-
-  	/*  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).
- */
+struct kmem_cache *pgtable_cache __read_mostly;
 
-void copy_user_page(void* to, void* from, unsigned long vaddr,
-    		    struct page* to_page)
+static void pgd_ctor(void *addr, struct kmem_cache *cache, unsigned long flags)
 {
-	/* 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);
-		int i;
+	pte_t* ptep = (pte_t*)addr;
+	int i;
 
-		for (i = 0; i < 1024; i++, ptep++)
-			pte_clear(mm, addr, ptep);
+	for (i = 0; i < 1024; i++, 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);
 }
-

+ 271 - 35
arch/xtensa/mm/misc.S

@@ -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
+ *               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
-	addi	a2, a2, 32
-	addi	a3, a3, 32
-	blt	a2, a4, 1b
 
+	__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
+
+	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
 
 /*

+ 0 - 1
arch/xtensa/platform-iss/console.c

@@ -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>

+ 17 - 6
block/ll_rw_blk.c

@@ -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;

+ 1 - 1
drivers/acpi/event.c

@@ -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)
 {

+ 21 - 0
drivers/acpi/processor_core.c

@@ -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);
 }
 
 /*

+ 5 - 5
drivers/acpi/sleep/proc.c

@@ -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,

+ 23 - 6
drivers/base/core.c

@@ -679,14 +679,26 @@ static int device_add_class_symlinks(struct device *dev)
 			goto out_subsys;
 	}
 	if (dev->parent) {
-		error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
-					  "device");
-		if (error)
-			goto out_busid;
 #ifdef CONFIG_SYSFS_DEPRECATED
 		{
-			char * class_name = make_class_name(dev->class->name,
-								&dev->kobj);
+			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;
+
+			class_name = make_class_name(dev->class->name,
+							&dev->kobj);
 			if (class_name)
 				error = sysfs_create_link(&dev->parent->kobj,
 							&dev->kobj, class_name);
@@ -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;

+ 1 - 0
drivers/block/DAC960.c

@@ -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>

+ 2 - 1
drivers/char/agp/agp.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)

+ 1 - 1
drivers/char/agp/intel-agp.c

@@ -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;

+ 2 - 1
drivers/char/ipmi/ipmi_si_intf.c

@@ -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);
 

+ 48 - 21
drivers/char/mspec.c

@@ -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);

+ 14 - 0
drivers/char/tty_ioctl.c

@@ -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:
 		{

+ 1 - 0
drivers/ide/ide-disk.c

@@ -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 }
 };
 

+ 0 - 2
drivers/ide/ppc/pmac.c

@@ -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)

+ 7 - 3
drivers/kvm/kvm.h

@@ -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))

+ 3 - 2
drivers/kvm/mmu.c

@@ -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)
 {

+ 3 - 0
drivers/md/dm-bio-list.h

@@ -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

+ 1 - 1
drivers/media/video/cx88/cx88-mpeg.c

@@ -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;
 	}
 

+ 4 - 2
drivers/media/video/ivtv/ivtv-fileops.c

@@ -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;

+ 12 - 5
drivers/media/video/ivtv/ivtv-ioctl.c

@@ -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;

+ 1 - 1
drivers/media/video/pwc/pwc-if.c

@@ -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) */

+ 6 - 6
drivers/media/video/saa7134/saa7134-cards.c

@@ -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,

+ 2 - 2
drivers/media/video/saa7191.c

@@ -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;

+ 1 - 0
drivers/media/video/usbvision/usbvision-cards.c

@@ -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);

+ 0 - 20
drivers/misc/Kconfig

@@ -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

+ 1 - 1
drivers/misc/msi-laptop.c

@@ -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)

+ 87 - 57
drivers/misc/thinkpad_acpi.c

@@ -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,58 +1158,65 @@ 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 */
-				scancode = hkey & 0xfff;
-				if (scancode > 0 && scancode < 0x21) {
-					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);
-				}
-				break;
-			case 5:
-				/* 0x5000-0x5FFF: LID */
-				/* we don't handle it through this path, just
-				 * eat up known LID events */
-				if (hkey != 0x5001 && hkey != 0x5002) {
-					printk(IBM_ERR
-						"unknown LID-related hotkey event: 0x%04x\n",
-						hkey);
-				}
+		switch (hkey >> 12) {
+		case 1:
+			/* 0x1000-0x1FFF: key presses */
+			scancode = hkey & 0xfff;
+			if (scancode > 0 && scancode < 0x21) {
+				scancode--;
+				keycode = hotkey_keycode_map[scancode];
+				tpacpi_input_send_key(scancode, keycode);
+			} else {
+				printk(IBM_ERR
+				       "hotkey 0x%04x out of range for keyboard map\n",
+				       hkey);
+				send_acpi_ev = 1;
+			}
+			break;
+		case 5:
+			/* 0x5000-0x5FFF: LID */
+			/* we don't handle it through this path, just
+			 * eat up known LID events */
+			if (hkey != 0x5001 && hkey != 0x5002) {
+				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();
 				break;
-			case 7:
-				/* 0x7000-0x7FFF: misc */
-				if (tp_features.hotkey_wlsw && hkey == 0x7000) {
-						tpacpi_input_send_radiosw();
-						sendacpi = 0;
-					break;
-				}
-				/* fallthrough to default */
-			default:
-				/* case 2: dock-related */
-				/*	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);
 			}
+			/* fallthrough to default */
+		default:
+			/* case 2: dock-related */
+			/*	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 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);

+ 1 - 0
drivers/misc/thinkpad_acpi.h

@@ -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);

+ 2 - 1
drivers/mtd/nand/cafe_nand.c

@@ -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);

+ 88 - 1
drivers/net/Kconfig

@@ -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

+ 1 - 0
drivers/net/Makefile

@@ -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

+ 7 - 12
drivers/net/atl1/atl1_main.c

@@ -2203,21 +2203,20 @@ 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);
+	/*
+	 * 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) {
-		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;
+		dev_err(&pdev->dev, "no usable DMA configuration\n");
+		goto err_dma;
 	}
 	/* 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;
 
 	/*

+ 4 - 1
drivers/net/ehea/ehea.h

@@ -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;

+ 14 - 2
drivers/net/ehea/ehea_main.c

@@ -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");
 		}
 	}
-	netif_carrier_on(port->netdev);
+	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))

+ 1 - 1
drivers/net/mv643xx_eth.c

@@ -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;
 

+ 1 - 1
drivers/net/pcmcia/3c589_cs.c

@@ -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" };
 
 /*====================================================================*/
 

+ 2 - 2
drivers/net/phy/phy.c

@@ -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);

+ 2 - 2
drivers/net/phy/phy_device.c

@@ -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;
 

+ 28 - 30
drivers/net/ppp_generic.c

@@ -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)
-			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;
-	}
+	if (skb_cow_head(skb, PPP_HDRLEN))
+		goto outf;
+
 	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,23 +1648,29 @@ 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 */
-		*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");
-			kfree_skb(skb);
-			return;
-		}
-		if (!(ppp->active_filter
-		      && sk_run_filter(skb, ppp->active_filter,
-				       ppp->active_len) == 0))
-			ppp->last_recv = jiffies;
-		skb_pull(skb, 2);
-#else
-		ppp->last_recv = jiffies;
+		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");
+				kfree_skb(skb);
+				return;
+			}
+			if (!(ppp->active_filter
+			      && sk_run_filter(skb, ppp->active_filter,
+					       ppp->active_len) == 0))
+				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 */

+ 22 - 48
drivers/net/pppoe.c

@@ -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.
-		 */
-		skb2 = skb_clone(skb, GFP_ATOMIC);
-
-		if (skb2 == NULL)
-			goto abort;
-	}
+	/* Copy the data if there is no space for the header or if it's
+	 * read-only.
+	 */
+	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;
 }
 
 

+ 87 - 0
drivers/net/sk98lin/Makefile

@@ -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
+
+
+
+
+
+

+ 179 - 0
drivers/net/sk98lin/h/lm80.h

@@ -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 */

+ 285 - 0
drivers/net/sk98lin/h/skaddr.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 */

+ 213 - 0
drivers/net/sk98lin/h/skcsum.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 */

+ 74 - 0
drivers/net/sk98lin/h/skdebug.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 */

+ 188 - 0
drivers/net/sk98lin/h/skdrv1st.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
+

+ 447 - 0
drivers/net/sk98lin/h/skdrv2nd.h

@@ -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 */
+

+ 55 - 0
drivers/net/sk98lin/h/skerror.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_ */

+ 51 - 0
drivers/net/sk98lin/h/skgedrv.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_ */

部分文件因文件數量過多而無法顯示