Browse Source

Merge branch 'linux-2.6'

Paul Mackerras 17 years ago
parent
commit
0ce49a3945
100 changed files with 3819 additions and 760 deletions
  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
 The option of being unfailingly polite really doesn't exist. Nobody will
 trust somebody who is so clearly hiding his true character.
 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
 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. 
 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>
 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:
 			Format:
 			<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
 			<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
 
 
-	cpia_pp=	[HW,PPT]
-			Format: { parport<nr> | auto | none }
-
 	crashkernel=nn[KMG]@ss[KMG]
 	crashkernel=nn[KMG]@ss[KMG]
 			[KNL] Reserve a chunk of physical memory to
 			[KNL] Reserve a chunk of physical memory to
 			hold a kernel to switch to with kexec on panic.
 			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
 	- the new routing mechanism
 shaper.txt
 shaper.txt
 	- info on the module that can shape/limit transmitted traffic.
 	- 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
 skfp.txt
 	- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
 	- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
 smc9.txt
 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
 		     ThinkPad ACPI Extras Driver
 
 
-                            Version 0.15
-                           July 1st, 2007
+                            Version 0.16
+                          August 2nd, 2007
 
 
                Borislav Deianov <borislav@users.sf.net>
                Borislav Deianov <borislav@users.sf.net>
              Henrique de Moraes Holschuh <hmh@hmh.eng.br>
              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 that such a driver is present, and modifies how the ThinkPad
 firmware will behave in many situations.
 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
 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
 	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
 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
 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
 		disabled" postition, and 1 if the switch is in the
 		"radios enabled" position.
 		"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:
 input layer notes:
 
 
 A Hot key is mapped to a single input layer EV_KEY event, possibly
 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
 hot key press or release, but the firmware will do it for either one, not
 both.
 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
 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:
 Non hot-key ACPI HKEY event map:
 0x5001		Lid closed
 0x5001		Lid closed
 0x5002		Lid opened
 0x5002		Lid opened
 0x7000		Radio Switch may have changed state
 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
 Bluetooth
 ---------
 ---------

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

@@ -407,8 +407,10 @@ Description
 		u32 length;		// Length of this frame
 		u32 length;		// Length of this frame
 		u32 offset_low;		// Offset in the file of the
 		u32 offset_low;		// Offset in the file of the
 		u32 offset_high;	// start of this frame
 		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
 					// 1=I, 2=P, 4=B
+					// 0=End of Program Index, other fields
+					//   are invalid.
 		u32 pts;		// The PTS of the frame
 		u32 pts;		// The PTS of the frame
 		u32 mask2;		// Bit 0 is bit 32 of the pts.
 		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
 #endif
 	gic_dist_init(0, __io_address(REALVIEW_GIC_DIST_BASE), 29);
 	gic_dist_init(0, __io_address(REALVIEW_GIC_DIST_BASE), 29);
 	gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE));
 	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_dist_init(1, __io_address(REALVIEW_GIC1_DIST_BASE), 64);
 	gic_cpu_init(1, __io_address(REALVIEW_GIC1_CPU_BASE));
 	gic_cpu_init(1, __io_address(REALVIEW_GIC1_CPU_BASE));
 	gic_cascade_irq(1, IRQ_EB_IRQ1);
 	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.
 	 * we just need to read the VFPSID register.
 	 */
 	 */
 	vfp_vector = vfp_testing_entry;
 	vfp_vector = vfp_testing_entry;
+	barrier();
 	vfpsid = fmrx(FPSID);
 	vfpsid = fmrx(FPSID);
 	barrier();
 	barrier();
 	vfp_vector = vfp_null_entry;
 	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;
 	return 0;
 }
 }
 
 
+static int bfin_pm_valid(suspend_state_t state)
+{
+	return (state == PM_SUSPEND_STANDBY);
+}
+
 struct pm_ops bfin_pm_ops = {
 struct pm_ops bfin_pm_ops = {
 	.prepare = bfin_pm_prepare,
 	.prepare = bfin_pm_prepare,
 	.enter = bfin_pm_enter,
 	.enter = bfin_pm_enter,
 	.finish = bfin_pm_finish,
 	.finish = bfin_pm_finish,
+	.valid	= bfin_pm_valid,
 };
 };
 
 
 static int __init bfin_pm_init(void)
 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)
 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)
 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;
 int dec_tc_bus;
 
 
-spinlock_t ioasic_ssr_lock;
+DEFINE_SPINLOCK(ioasic_ssr_lock);
 
 
 volatile u32 *ioasic_base;
 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
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * 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"
 		".endr\n\t"
 		".set	pop"
 		".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,
 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)
 		if ((c->processor_id & 0xff) <= 0x64)
 			break;
 			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;
 		break;
 	case CPU_RM9000:
 	case CPU_RM9000:
 		if ((c->processor_id & 0x00ff) >= 0x40)
 		if ((c->processor_id & 0x00ff) >= 0x40)

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

@@ -56,8 +56,6 @@ static struct chan_waitqueues {
 	struct mutex mutex;
 	struct mutex mutex;
 } channel_wqs[RTLX_CHANNELS];
 } channel_wqs[RTLX_CHANNELS];
 
 
-static struct irqaction irq;
-static int irq_num;
 static struct vpe_notifications notify;
 static struct vpe_notifications notify;
 static int sp_stopping = 0;
 static int sp_stopping = 0;
 
 
@@ -111,7 +109,7 @@ static void __used dump_rtlx(void)
 static int rtlx_init(struct rtlx_info *rtlxi)
 static int rtlx_init(struct rtlx_info *rtlxi)
 {
 {
 	if (rtlxi->id != RTLX_ID) {
 	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;
 		return -ENOEXEC;
 	}
 	}
 
 

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

@@ -375,7 +375,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_mkdirat
 	PTR	sys_mkdirat
 	PTR	sys_mknodat
 	PTR	sys_mknodat
 	PTR	sys_fchownat
 	PTR	sys_fchownat
-	PTR	sys_futimesat			/* 6255 */
+	PTR	compat_sys_futimesat		/* 6255 */
 	PTR	sys_newfstatat
 	PTR	sys_newfstatat
 	PTR	sys_unlinkat
 	PTR	sys_unlinkat
 	PTR	sys_renameat
 	PTR	sys_renameat

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

@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/param.h>
+#include <linux/profile.h>
 #include <linux/time.h>
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/timex.h>
 #include <linux/smp.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)
 	if (irq == MIPSCPU_INT_I8259A)
 		malta_hw0_irqdispatch();
 		malta_hw0_irqdispatch();
-	else if (irq > 0)
+	else if (irq >= 0)
 		do_IRQ(MIPS_CPU_IRQ_BASE + irq);
 		do_IRQ(MIPS_CPU_IRQ_BASE + irq);
 	else
 	else
 		spurious_interrupt();
 		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;
 	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
  * A little micro-assembler, intended for TLB refill handler
  * synthesizing. It is intentionally kept simple, does only support
  * 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_20KC:
 	case CPU_25KF:
 	case CPU_25KF:
 	case CPU_LOONGSON2:
 	case CPU_LOONGSON2:
+		if (m4kc_tlbp_war())
+			i_nop(p);
 		tlbw(p);
 		tlbw(p);
 		break;
 		break;
 
 
@@ -1705,7 +1722,8 @@ build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
 	l_smp_pgtable_change(l, *p);
 	l_smp_pgtable_change(l, *p);
 # endif
 # endif
 	iPTE_LW(p, l, pte, ptr); /* get even pte */
 	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
 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_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
 	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
 	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_make_valid(&p, &r, K0, K1);
 	build_r4000_tlbchange_handler_tail(&p, &l, &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_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
 	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
 	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_make_write(&p, &r, K0, K1);
 	build_r4000_tlbchange_handler_tail(&p, &l, &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_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
 	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
 	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. */
 	/* Present and writable bits set, set accessed and dirty bits. */
 	build_make_write(&p, &r, K0, K1);
 	build_make_write(&p, &r, K0, K1);
 	build_r4000_tlbchange_handler_tail(&p, &l, &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);
 	struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
-	p->tb = mftb();
+	p->tb = get_tb_or_rtc();
 	p->purr = mfspr(SPRN_PURR);
 	p->purr = mfspr(SPRN_PURR);
 	wmb();
 	wmb();
 	p->initialized = 1;
 	p->initialized = 1;
@@ -316,7 +316,7 @@ static void snapshot_purr(void)
  */
  */
 void snapshot_timebase(void)
 void snapshot_timebase(void)
 {
 {
-	__get_cpu_var(last_jiffy) = get_tb();
+	__get_cpu_var(last_jiffy) = get_tb_or_rtc();
 	snapshot_purr();
 	snapshot_purr();
 }
 }
 
 
@@ -683,6 +683,8 @@ void timer_interrupt(struct pt_regs * regs)
 
 
 		write_seqlock(&xtime_lock);
 		write_seqlock(&xtime_lock);
 		tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
 		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) {
 		if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
 			tb_last_jiffy = tb_next_jiffy;
 			tb_last_jiffy = tb_next_jiffy;
 			do_timer(1);
 			do_timer(1);
@@ -976,7 +978,7 @@ void __init time_init(void)
 	tb_to_ns_scale = scale;
 	tb_to_ns_scale = scale;
 	tb_to_ns_shift = shift;
 	tb_to_ns_shift = shift;
 	/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
 	/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
-	boot_tb = get_tb();
+	boot_tb = get_tb_or_rtc();
 
 
 	tm = get_boot_time();
 	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,
 		CPU_FTR_USE_TB, 0,
 		"__kernel_gettimeofday", NULL
 		"__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) {
 		list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) {
 			struct spu_context *tmp = spu->ctx;
 			struct spu_context *tmp = spu->ctx;
 
 
-			if (tmp->prio > ctx->prio &&
+			if (tmp && tmp->prio > ctx->prio &&
 			    (!victim || tmp->prio > victim->prio))
 			    (!victim || tmp->prio > victim->prio))
 				victim = spu->ctx;
 				victim = spu->ctx;
 		}
 		}
@@ -626,9 +626,9 @@ static struct spu *find_victim(struct spu_context *ctx)
 
 
 			mutex_lock(&cbe_spu_info[node].list_mutex);
 			mutex_lock(&cbe_spu_info[node].list_mutex);
 			cbe_spu_info[node].nr_active--;
 			cbe_spu_info[node].nr_active--;
+			spu_unbind_context(spu, victim);
 			mutex_unlock(&cbe_spu_info[node].list_mutex);
 			mutex_unlock(&cbe_spu_info[node].list_mutex);
 
 
-			spu_unbind_context(spu, victim);
 			victim->stats.invol_ctx_switch++;
 			victim->stats.invol_ctx_switch++;
 			spu->stats.invol_ctx_switch++;
 			spu->stats.invol_ctx_switch++;
 			mutex_unlock(&victim->state_mutex);
 			mutex_unlock(&victim->state_mutex);

+ 5 - 11
arch/sparc64/defconfig

@@ -1,7 +1,7 @@
 #
 #
 # Automatically generated make config: don't edit
 # 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_SPARC=y
 CONFIG_SPARC64=y
 CONFIG_SPARC64=y
@@ -32,15 +32,11 @@ CONFIG_HZ=100
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 
 #
 #
-# Code maturity level options
+# General setup
 #
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SWAP=y
@@ -555,6 +551,7 @@ CONFIG_E1000_NAPI=y
 # CONFIG_SIS190 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
 # CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 CONFIG_TIGON3=m
 CONFIG_BNX2=m
 CONFIG_BNX2=m
@@ -809,6 +806,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -1162,10 +1160,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_MMC is not set
 # CONFIG_MMC is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_INFINIBAND is not set
-
-#
-# Real Time Clock
-#
 # CONFIG_RTC_CLASS is not set
 # 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_mapped_pc, prom_boot_mapping_mode
 	.globl	prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
 	.globl	prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
 	.globl	prom_compatible_name, prom_cpu_path, prom_cpu_compatible
 	.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:
 prom_peer_name:
 	.asciz	"peer"
 	.asciz	"peer"
 prom_compatible_name:
 prom_compatible_name:
@@ -121,6 +121,8 @@ prom_map_name:
 	.asciz	"map"
 	.asciz	"map"
 prom_unmap_name:
 prom_unmap_name:
 	.asciz	"unmap"
 	.asciz	"unmap"
+prom_set_trap_table_name:
+	.asciz	"SUNW,set-trap-table"
 prom_sun4v_name:
 prom_sun4v_name:
 	.asciz	"sun4v"
 	.asciz	"sun4v"
 prom_niagara_prefix:
 prom_niagara_prefix:
@@ -691,15 +693,38 @@ setup_trap_table:
 	sethi	%hi(kern_base), %g3
 	sethi	%hi(kern_base), %g3
 	ldx	[%g3 + %lo(kern_base)], %g3
 	ldx	[%g3 + %lo(kern_base)], %g3
 	add	%g2, %g3, %o1
 	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
 	ba,pt	%xcc, 2f
 	 nop
 	 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.  */
 	/* Start using proper page size encodings in ctx register.  */
 2:	sethi	%hi(sparc64_kern_pri_context), %g3
 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;
 		cpuid = *id;
 
 
 #ifdef CONFIG_SMP
 #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;
 			continue;
+		}
 		if (!cpu_isset(cpuid, mask))
 		if (!cpu_isset(cpuid, mask))
 			continue;
 			continue;
 #else
 #else

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

@@ -1583,8 +1583,12 @@ static void __init of_fill_in_cpu_data(void)
 		ncpus_probed++;
 		ncpus_probed++;
 
 
 #ifdef CONFIG_SMP
 #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;
 			continue;
+		}
 #else
 #else
 		/* On uniprocessor we only want the values for the
 		/* On uniprocessor we only want the values for the
 		 * real physical cpu the kernel booted onto, however
 		 * 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
 	sethi		%hi(tramp_stack), %g1
 	or		%g1, %lo(tramp_stack), %g1
 	or		%g1, %lo(tramp_stack), %g1
 	add		%g1, TRAMP_STACK_SIZE, %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
 	mov		0, %fp
 
 
 	/* Put garbage in these registers to trap any access to them.  */
 	/* Put garbage in these registers to trap any access to them.  */
@@ -411,15 +411,38 @@ after_lock_tlb:
 	sethi		%hi(kern_base), %g3
 	sethi		%hi(kern_base), %g3
 	ldx		[%g3 + %lo(kern_base)], %g3
 	ldx		[%g3 + %lo(kern_base)], %g3
 	add		%g2, %g3, %o1
 	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
 	ba,pt		%xcc, 2f
 	 nop
 	 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
 2:	ldx		[%l0], %g6
 	ldx		[%g6 + TI_TASK], %g4
 	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;
 	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 prom_get_mmu_ihandle(void)
 {
 {
 	int node, ret;
 	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);
 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);
 unsigned long from_irq_stack(int nested);
 
 
 #endif
 #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;
 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;
 	struct thread_info *ti;
 	unsigned long mask, old;
 	unsigned long mask, old;
 	int nested;
 	int nested;
 
 
-	mask = xchg(&pending_mask, 1 << sig);
+	mask = xchg(&pending_mask, *mask_out);
 	if(mask != 0){
 	if(mask != 0){
 		/* If any interrupts come in at this point, we want to
 		/* If any interrupts come in at this point, we want to
 		 * make sure that their bits aren't lost by our
 		 * 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
 		 * and pending_mask contains a bit for each interrupt
 		 * that came in.
 		 * that came in.
 		 */
 		 */
-		old = 1 << sig;
+		old = *mask_out;
 		do {
 		do {
 			old |= mask;
 			old |= mask;
 			mask = xchg(&pending_mask, old);
 			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;
 		task = cpu_tasks[ti->cpu].task;
 		tti = task_thread_info(task);
 		tti = task_thread_info(task);
+
 		*ti = *tti;
 		*ti = *tti;
 		ti->real_thread = tti;
 		ti->real_thread = tti;
 		task->stack = ti;
 		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)){
 	if(S_ISBLK(buf.ust_mode)){
-		int fd, blocks;
+		int fd;
+		long blocks;
 
 
 		fd = os_open_file(file, of_read(OPENFLAGS()), 0);
 		fd = os_open_file(file, of_read(OPENFLAGS()), 0);
 		if(fd < 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)
 void handle_signal(int sig, struct sigcontext *sc)
 {
 {
-	unsigned long pending = 0;
+	unsigned long pending = 1UL << sig;
 
 
 	do {
 	do {
 		int nested, bail;
 		int nested, bail;
@@ -134,7 +134,7 @@ void handle_signal(int sig, struct sigcontext *sc)
 		 * have to return, and the upper handler will deal
 		 * have to return, and the upper handler will deal
 		 * with this interrupt.
 		 * with this interrupt.
 		 */
 		 */
-		bail = to_irq_stack(sig, &pending);
+		bail = to_irq_stack(&pending);
 		if(bail)
 		if(bail)
 			return;
 			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))
 	if (unlikely(in_atomic() || !mm))
 		goto bad_area_nosemaphore;
 		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:
  again:
 	/* When running in the kernel we expect faults to occur only to
 	/* When running in the kernel we expect faults to occur only to
 	 * addresses in user space.  All other faults represent errors in the
 	 * 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)
 PLATFORM = $(platform-y)
 export PLATFORM
 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
 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  \
 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  \
 	 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
 ## windowspill.o
 
 

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

@@ -18,12 +18,13 @@
 #include <linux/stddef.h>
 #include <linux/stddef.h>
 #include <linux/thread_info.h>
 #include <linux/thread_info.h>
 #include <linux/ptrace.h>
 #include <linux/ptrace.h>
+#include <linux/mm.h>
+
 #include <asm/ptrace.h>
 #include <asm/ptrace.h>
 #include <asm/processor.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 
 
 #define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 #define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
-#define BLANK() asm volatile("\n->" : : )
 
 
 int main(void)
 int main(void)
 {
 {
@@ -63,7 +64,6 @@ int main(void)
 	DEFINE(PT_SIZE, sizeof(struct pt_regs));
 	DEFINE(PT_SIZE, sizeof(struct pt_regs));
 	DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS]));
 	DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS]));
 	DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS]));
 	DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS]));
-	BLANK();
 
 
 	/* struct task_struct */
 	/* struct task_struct */
 	DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace));
 	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, offsetof (struct task_struct, thread));
 	DEFINE(TASK_THREAD_INFO, offsetof (struct task_struct, stack));
 	DEFINE(TASK_THREAD_INFO, offsetof (struct task_struct, stack));
 	DEFINE(TASK_STRUCT_SIZE, sizeof (struct task_struct));
 	DEFINE(TASK_STRUCT_SIZE, sizeof (struct task_struct));
-	BLANK();
 
 
 	/* struct thread_info (offset from start_struct) */
 	/* struct thread_info (offset from start_struct) */
 	DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
 	DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
 	DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
 	DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
 	DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save));
 	DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save));
 	DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
 	DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
-	BLANK();
 
 
 	/* struct mm_struct */
 	/* struct mm_struct */
 	DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users));
 	DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users));
 	DEFINE(MM_PGD, offsetof (struct mm_struct, pgd));
 	DEFINE(MM_PGD, offsetof (struct mm_struct, pgd));
 	DEFINE(MM_CONTEXT, offsetof (struct mm_struct, context));
 	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 */
 	/* constants */
 	DEFINE(_CLONE_VM, CLONE_VM);
 	DEFINE(_CLONE_VM, CLONE_VM);
 	DEFINE(_CLONE_UNTRACED, CLONE_UNTRACED);
 	DEFINE(_CLONE_UNTRACED, CLONE_UNTRACED);
+	DEFINE(PG_ARCH_1, PG_arch_1);
 
 
 	return 0;
 	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
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  * for more details.
  *
  *
- * Copyright (C) 2004-2005 by Tensilica Inc.
+ * Copyright (C) 2004-2007 by Tensilica Inc.
  *
  *
  * Chris Zankel <chris@zankel.net>
  * Chris Zankel <chris@zankel.net>
  *
  *
@@ -169,7 +169,7 @@ _user_exception:
 	 * We have to save all registers up to the first '1' from
 	 * We have to save all registers up to the first '1' from
 	 * the right, except the current frame (bit 0).
 	 * the right, except the current frame (bit 0).
 	 * Assume a2 is:  001001000110001
 	 * 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.
 	 * must be saved.
 	 */
 	 */
 
 
@@ -1572,10 +1572,12 @@ ENTRY(fast_second_level_miss)
 	l32i	a0, a1, TASK_MM		# tsk->mm
 	l32i	a0, a1, TASK_MM		# tsk->mm
 	beqz	a0, 9f
 	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
 	l32i	a0, a0, 0		# read pmdval
-	//beqi	a0, _PAGE_USER, 2f
 	beqz	a0, 2f
 	beqz	a0, 2f
 
 
 	/* Read ptevaddr and convert to top of page-table page.
 	/* 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
 	 * The messy computation for 'pteval' above really simplifies
 	 * into the following:
 	 * into the following:
 	 *
 	 *
-	 * pteval = ((pmdval - PAGE_OFFSET) & PAGE_MASK) | PAGE_KERNEL
+	 * pteval = ((pmdval - PAGE_OFFSET) & PAGE_MASK) | PAGE_DIRECTORY
 	 */
 	 */
 
 
 	movi	a1, -PAGE_OFFSET
 	movi	a1, -PAGE_OFFSET
@@ -1596,20 +1598,34 @@ ENTRY(fast_second_level_miss)
 	extui	a1, a0, 0, PAGE_SHIFT	# ... & PAGE_MASK
 	extui	a1, a0, 0, PAGE_SHIFT	# ... & PAGE_MASK
 	xor	a0, a0, a1
 	xor	a0, a0, a1
 
 
-
-	movi	a1, PAGE_DIRECTORY
+	movi	a1, _PAGE_DIRECTORY
 	or	a0, a0, 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
 	rsr	a1, PTEVADDR
+	addx2	a3, a3, a3		# ->			0,3,6,9
 	srli	a1, a1, PAGE_SHIFT
 	srli	a1, a1, PAGE_SHIFT
+	extui	a3, a3, 2, 2		# ->			0,0,1,2
 	slli	a1, a1, PAGE_SHIFT	# ptevaddr & PAGE_MASK
 	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
 	dsync
 
 
 	/* Exit critical section. */
 	/* Exit critical section. */
 
 
+4:	movi	a3, exc_table		# restore a3
 	movi	a0, 0
 	movi	a0, 0
 	s32i	a0, a3, EXC_TABLE_FIXUP
 	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
 9:	l32i	a0, a1, TASK_ACTIVE_MM	# unlikely case mm == 0
 	j	8b
 	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 */
 2:	/* Invalid PGD, default exception handling */
 
 
+	movi	a3, exc_table
 	rsr	a1, DEPC
 	rsr	a1, DEPC
 	xsr	a3, EXCSAVE_1
 	xsr	a3, EXCSAVE_1
 	s32i	a1, a2, PT_AREG2
 	s32i	a1, a2, PT_AREG2
@@ -1682,15 +1766,15 @@ ENTRY(fast_store_prohibited)
 8:	rsr	a1, EXCVADDR		# fault address
 8:	rsr	a1, EXCVADDR		# fault address
 	_PGD_OFFSET(a0, a1, a4)
 	_PGD_OFFSET(a0, a1, a4)
 	l32i	a0, a0, 0
 	l32i	a0, a0, 0
-	//beqi	a0, _PAGE_USER, 2f	# FIXME use _PAGE_INVALID
 	beqz	a0, 2f
 	beqz	a0, 2f
 
 
+	/* Note that we assume _PAGE_WRITABLE_BIT is only set if pte is valid.*/
+
 	_PTE_OFFSET(a0, a1, a4)
 	_PTE_OFFSET(a0, a1, a4)
 	l32i	a4, a0, 0		# read pteval
 	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
 	or	a4, a4, a1
 	rsr	a1, EXCVADDR
 	rsr	a1, EXCVADDR
 	s32i	a4, a0, 0
 	s32i	a4, a0, 0
@@ -1700,10 +1784,7 @@ ENTRY(fast_store_prohibited)
 	dhwb	a0, 0
 	dhwb	a0, 0
 #endif
 #endif
 	pdtlb	a0, a1
 	pdtlb	a0, a1
-	beqz	a0, 1f
-	idtlb	a0		// FIXME do we need this?
 	wdtlb	a4, a0
 	wdtlb	a4, a0
-1:
 
 
 	/* Exit critical section. */
 	/* 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
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  * for more details.
  *
  *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2006 Tensilica Inc.
  *
  *
  * Chris Zankel <chris@zankel.net>
  * Chris Zankel <chris@zankel.net>
  *
  *
@@ -22,57 +22,216 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/cache.h>
 #include <linux/cache.h>
 
 
-LIST_HEAD(module_buf_list);
+#undef DEBUG_RELOCATE
 
 
 void *module_alloc(unsigned long size)
 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)
 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,
 int module_frob_arch_sections(Elf32_Ehdr *hdr,
     			      Elf32_Shdr *sechdrs,
     			      Elf32_Shdr *sechdrs,
 			      char *secstrings,
 			      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,
 int apply_relocate(Elf32_Shdr *sechdrs,
     		   const char *strtab,
     		   const char *strtab,
 		   unsigned int symindex,
 		   unsigned int symindex,
 		   unsigned int relsec,
 		   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,
 int apply_relocate_add(Elf32_Shdr *sechdrs,
 		       const char *strtab,
 		       const char *strtab,
 		       unsigned int symindex,
 		       unsigned int symindex,
 		       unsigned int relsec,
 		       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,
 int module_finalize(const Elf_Ehdr *hdr,
     		    const Elf_Shdr *sechdrs,
     		    const Elf_Shdr *sechdrs,
-		    struct module *me)
+		    struct module *mod)
 {
 {
-  panic ("module_finalize not implemented");
+	return 0;
 }
 }
 
 
 void module_arch_cleanup(struct module *mod)
 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;
 	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);
 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, };
 struct task_struct *current_set[NR_CPUS] = {&init_task, };
 
 
 void (*pm_power_off)(void) = NULL;
 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;
 	return ret;
 }
 }
 
 
-spinlock_t semaphore_wake_lock;
+DEFINE_SPINLOCK(semaphore_wake_lock);
 
 
 /*
 /*
  * Semaphores are implemented using a two-way counter:
  * 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;
 	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
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 unsigned long ccount_per_jiffy;		/* per 1/HZ */
 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
 #endif
 
 
-unsigned int last_ccount_stamp;
 static long last_rtc_update = 0;
 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 irqreturn_t timer_interrupt(int irq, void *dev_id);
 static struct irqaction timer_irqaction = {
 static struct irqaction timer_irqaction = {
 	.handler =	timer_interrupt,
 	.handler =	timer_interrupt,
@@ -69,7 +77,6 @@ void __init time_init(void)
 
 
 	xtime.tv_nsec = 0;
 	xtime.tv_nsec = 0;
 	last_rtc_update = xtime.tv_sec = sec_n;
 	last_rtc_update = xtime.tv_sec = sec_n;
-	last_ccount_stamp = get_ccount();
 
 
 	set_normalized_timespec(&wall_to_monotonic,
 	set_normalized_timespec(&wall_to_monotonic,
 		-xtime.tv_sec, -xtime.tv_nsec);
 		-xtime.tv_sec, -xtime.tv_nsec);
@@ -85,7 +92,7 @@ int do_settimeofday(struct timespec *tv)
 {
 {
 	time_t wtm_sec, sec = tv->tv_sec;
 	time_t wtm_sec, sec = tv->tv_sec;
 	long wtm_nsec, nsec = tv->tv_nsec;
 	long wtm_nsec, nsec = tv->tv_nsec;
-	unsigned long ccount;
+	unsigned long delta;
 
 
 	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
 	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
 		return -EINVAL;
 		return -EINVAL;
@@ -97,8 +104,10 @@ int do_settimeofday(struct timespec *tv)
 	 * wall time.  Discover what correction gettimeofday() would have
 	 * wall time.  Discover what correction gettimeofday() would have
 	 * made, and then undo it!
 	 * 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_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
 	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
 	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)
 void do_gettimeofday(struct timeval *tv)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
-	unsigned long sec, usec, delta, seq;
+	unsigned long volatile sec, usec, delta, seq;
 
 
 	do {
 	do {
 		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 		seq = read_seqbegin_irqsave(&xtime_lock, flags);
 
 
-		delta = get_ccount() - last_ccount_stamp;
 		sec = xtime.tv_sec;
 		sec = xtime.tv_sec;
 		usec = (xtime.tv_nsec / NSEC_PER_USEC);
 		usec = (xtime.tv_nsec / NSEC_PER_USEC);
+
+		delta = get_linux_timer() - get_ccount();
+
 	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
 	} 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)
 	for (; usec >= 1000000; sec++, usec -= 1000000)
 		;
 		;
 
 
@@ -158,9 +171,12 @@ again:
 
 
 		write_seqlock(&xtime_lock);
 		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;
 		next += CCOUNT_PER_JIFFY;
-		do_timer (1); /* Linux handler in kernel/timer.c */
+		set_linux_timer(next);
 
 
 		if (ntp_synced() &&
 		if (ntp_synced() &&
 		    xtime.tv_sec - last_rtc_update >= 659 &&
 		    xtime.tv_sec - last_rtc_update >= 659 &&
@@ -175,19 +191,15 @@ again:
 		write_sequnlock(&xtime_lock);
 		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... */
 	/* Make sure we didn't miss any tick... */
 
 
 	if ((signed long)(get_ccount() - next) > 0)
 	if ((signed long)(get_ccount() - next) > 0)
 		goto again;
 		goto again;
 
 
-	/* Allow platform to do something useful (Wdog). */
-
-	platform_heartbeat();
-
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 

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

@@ -83,7 +83,7 @@ typedef struct {
 	void* handler;
 	void* handler;
 } dispatch_init_table_t;
 } 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_ILLEGAL_INSTRUCTION,	0,	   do_illegal_instruction},
 { EXCCAUSE_SYSTEM_CALL,		KRNL,	   fast_syscall_kernel },
 { 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))
 #define set_handler(idx,handler) (exc_table[idx] = (unsigned long) (handler))
 
 
-void trap_init(void)
+void __init trap_init(void)
 {
 {
 	int i;
 	int i;
 
 

+ 1 - 5
arch/xtensa/mm/Makefile

@@ -5,9 +5,5 @@
 # removes any old dependencies. DON'T put your own dependencies here
 # removes any old dependencies. DON'T put your own dependencies here
 # unless it's something special (ie not a .c file).
 # 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;
 unsigned long asid_cache = ASID_USER_FIRST;
 void bad_page_fault(struct pt_regs*, unsigned long, int);
 void bad_page_fault(struct pt_regs*, unsigned long, int);
 
 
+#undef DEBUG_PAGE_FAULT
+
 /*
 /*
  * This routine handles page faults.  It determines the address,
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
  * 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_ITLB_MISS ||
 		    exccause == EXCCAUSE_FETCH_CACHE_ATTRIBUTE) ? 1 : 0;
 		    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,
 	printk("[%s:%d:%08x:%d:%08x:%s%s]\n", current->comm, current->pid,
 	       address, exccause, regs->pc, is_write? "w":"", is_exec? "x":"");
 	       address, exccause, regs->pc, is_write? "w":"", is_exec? "x":"");
 #endif
 #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?  */
 	/* Are we prepared to handle this kernel fault?  */
 	if ((entry = search_exception_tables(regs->pc)) != NULL) {
 	if ((entry = search_exception_tables(regs->pc)) != NULL) {
-#if 1
+#ifdef DEBUG_PAGE_FAULT
 		printk(KERN_DEBUG "%s: Exception at pc=%#010lx (%lx)\n",
 		printk(KERN_DEBUG "%s: Exception at pc=%#010lx (%lx)\n",
 				current->comm, regs->pc, entry->fixup);
 				current->comm, regs->pc, entry->fixup);
 #endif
 #endif

+ 15 - 237
arch/xtensa/mm/init.c

@@ -15,40 +15,24 @@
  * Kevin Chea
  * Kevin Chea
  */
  */
 
 
-#include <linux/init.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
 #include <linux/bootmem.h>
 #include <linux/bootmem.h>
 #include <linux/swap.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/pgtable.h>
 #include <asm/bootparam.h>
 #include <asm/bootparam.h>
 #include <asm/mmu_context.h>
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
 #include <asm/tlb.h>
-#include <asm/tlbflush.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
-#include <asm/pgtable.h>
-
 
 
-#define DEBUG 0
 
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 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 */
 /* References to section boundaries */
 
 
@@ -323,228 +307,22 @@ void show_mem(void)
 	printk("%d free pages\n", free);
 	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
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  * for more details.
  *
  *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001 - 2007 Tensilica Inc.
  *
  *
  * Chris Zankel	<chris@zankel.net>
  * 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 <linux/linkage.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 #include <asm/asmmacro.h>
 #include <asm/asmmacro.h>
 #include <asm/cacheasm.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(clear_page)
 	entry	a1, 16
 	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, 4
 	s32i	a3, a2, 8
 	s32i	a3, a2, 8
 	s32i	a3, a2, 12
 	s32i	a3, a2, 12
@@ -37,42 +41,277 @@ ENTRY(clear_page)
 	s32i	a3, a2, 20
 	s32i	a3, a2, 20
 	s32i	a3, a2, 24
 	s32i	a3, a2, 24
 	s32i	a3, a2, 28
 	s32i	a3, a2, 28
-	addi	a2, a2, 32
-	blt	a2, a4, 1b
+	__endla	a2, a7, 32
 
 
 	retw
 	retw
 
 
 /*
 /*
+ * copy_page and copy_user_page are the same for non-cache-aliased configs.
+ *
  * copy_page (void *to, void *from)
  * copy_page (void *to, void *from)
- *                  a2        a3
+ *               a2          a3
  */
  */
 
 
 ENTRY(copy_page)
 ENTRY(copy_page)
 	entry	a1, 16
 	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
 	retw
 
 
+#endif
+
+/* End of special treatment in tlb miss exception */
+
+ENTRY(__tlbtemp_mapping_end)
+
 /*
 /*
  * void __invalidate_icache_page(ulong start)
  * void __invalidate_icache_page(ulong start)
  */
  */
@@ -121,8 +360,6 @@ ENTRY(__flush_dcache_page)
 	dsync
 	dsync
 	retw
 	retw
 
 
-
-
 /*
 /*
  * void __invalidate_icache_range(ulong start, ulong size)
  * void __invalidate_icache_range(ulong start, ulong size)
  */
  */
@@ -168,7 +405,6 @@ ENTRY(__invalidate_dcache_range)
 
 
 	___invalidate_dcache_range a2 a3 a4
 	___invalidate_dcache_range a2 a3 a4
 
 
-
 	retw
 	retw
 
 
 /*
 /*

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

@@ -20,7 +20,6 @@
 #include <linux/param.h>
 #include <linux/param.h>
 #include <linux/serial.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
 #include <linux/serialP.h>
-#include <linux/console.h>
 
 
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/irq.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;
 		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);
 	list_del_init(&rq->queuelist);
 	rq->cmd_flags &= ~REQ_QUEUED;
 	rq->cmd_flags &= ~REQ_QUEUED;
 	rq->tag = -1;
 	rq->tag = -1;
@@ -1090,6 +1084,19 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
 		       __FUNCTION__, tag);
 		       __FUNCTION__, tag);
 
 
 	bqt->tag_index[tag] = NULL;
 	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--;
 	bqt->busy--;
 }
 }
 
 
@@ -1136,6 +1143,10 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
 			return 1;
 			return 1;
 
 
 	} while (test_and_set_bit(tag, bqt->tag_map));
 	} 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->cmd_flags |= REQ_QUEUED;
 	rq->tag = tag;
 	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;
 	return 0;
 }
 }
 
 
-EXPORT_SYMBOL(acpi_generate_netlink_event);
+EXPORT_SYMBOL(acpi_bus_generate_netlink_event);
 
 
 static int acpi_event_genetlink_init(void)
 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;
 	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)
 static int acpi_processor_add(struct acpi_device *device)
 {
 {
 	struct acpi_processor *pr = NULL;
 	struct acpi_processor *pr = NULL;
@@ -987,6 +1006,7 @@ void acpi_processor_install_hotplug_notify(void)
 			    ACPI_UINT32_MAX,
 			    ACPI_UINT32_MAX,
 			    processor_walk_namespace_cb, &action, NULL);
 			    processor_walk_namespace_cb, &action, NULL);
 #endif
 #endif
+	register_hotcpu_notifier(&acpi_cpu_notifier);
 }
 }
 
 
 static
 static
@@ -999,6 +1019,7 @@ void acpi_processor_uninstall_hotplug_notify(void)
 			    ACPI_UINT32_MAX,
 			    ACPI_UINT32_MAX,
 			    processor_walk_namespace_cb, &action, NULL);
 			    processor_walk_namespace_cb, &action, NULL);
 #endif
 #endif
+	unregister_hotcpu_notifier(&acpi_cpu_notifier);
 }
 }
 
 
 /*
 /*

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

@@ -23,7 +23,7 @@
  */
  */
 
 
 ACPI_MODULE_NAME("sleep")
 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)
 static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
 {
 {
 	int i;
 	int i;
@@ -76,7 +76,7 @@ acpi_system_write_sleep(struct file *file,
       Done:
       Done:
 	return error ? error : count;
 	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)
 #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 */
 /* 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,
 	.release = single_release,
 };
 };
 
 
-#ifdef	CONFIG_ACPI_PROCFS_SLEEP
+#ifdef	CONFIG_ACPI_PROCFS
 static const struct file_operations acpi_system_sleep_fops = {
 static const struct file_operations acpi_system_sleep_fops = {
 	.open = acpi_system_sleep_open_fs,
 	.open = acpi_system_sleep_open_fs,
 	.read = seq_read,
 	.read = seq_read,
@@ -479,7 +479,7 @@ static const struct file_operations acpi_system_sleep_fops = {
 	.llseek = seq_lseek,
 	.llseek = seq_lseek,
 	.release = single_release,
 	.release = single_release,
 };
 };
-#endif				/* CONFIG_ACPI_PROCFS_SLEEP */
+#endif				/* CONFIG_ACPI_PROCFS */
 
 
 #ifdef	HAVE_ACPI_LEGACY_ALARM
 #ifdef	HAVE_ACPI_LEGACY_ALARM
 static const struct file_operations acpi_system_alarm_fops = {
 static const struct file_operations acpi_system_alarm_fops = {
@@ -506,7 +506,7 @@ static int __init acpi_sleep_proc_init(void)
 	if (acpi_disabled)
 	if (acpi_disabled)
 		return 0;
 		return 0;
 
 
-#ifdef	CONFIG_ACPI_PROCFS_SLEEP
+#ifdef	CONFIG_ACPI_PROCFS
 	/* 'sleep' [R/W] */
 	/* 'sleep' [R/W] */
 	entry =
 	entry =
 	    create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR,
 	    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;
 			goto out_subsys;
 	}
 	}
 	if (dev->parent) {
 	if (dev->parent) {
-		error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
-					  "device");
-		if (error)
-			goto out_busid;
 #ifdef CONFIG_SYSFS_DEPRECATED
 #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)
 			if (class_name)
 				error = sysfs_create_link(&dev->parent->kobj,
 				error = sysfs_create_link(&dev->parent->kobj,
 							&dev->kobj, class_name);
 							&dev->kobj, class_name);
@@ -694,6 +706,11 @@ static int device_add_class_symlinks(struct device *dev)
 			if (error)
 			if (error)
 				goto out_device;
 				goto out_device;
 		}
 		}
+#else
+		error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
+					  "device");
+		if (error)
+			goto out_busid;
 #endif
 #endif
 	}
 	}
 	return 0;
 	return 0;

+ 1 - 0
drivers/block/DAC960.c

@@ -31,6 +31,7 @@
 #include <linux/genhd.h>
 #include <linux/genhd.h>
 #include <linux/hdreg.h>
 #include <linux/hdreg.h>
 #include <linux/blkpg.h>
 #include <linux/blkpg.h>
+#include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/ioport.h>
 #include <linux/mm.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_MASK		0x1
 #define I830_GMCH_MEM_64M		0x1
 #define I830_GMCH_MEM_64M		0x1
 #define I830_GMCH_MEM_128M		0
 #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_DISABLED		0x00
 #define I830_GMCH_GMS_LOCAL		0x10
 #define I830_GMCH_GMS_LOCAL		0x10
 #define I830_GMCH_GMS_STOLEN_512	0x20
 #define I830_GMCH_GMS_STOLEN_512	0x20
@@ -190,6 +190,7 @@ struct agp_bridge_data {
 #define INTEL_I830_ERRSTS	0x92
 #define INTEL_I830_ERRSTS	0x92
 
 
 /* Intel 855GM/852GM registers */
 /* Intel 855GM/852GM registers */
+#define I855_GMCH_GMS_MASK		0xF0
 #define I855_GMCH_GMS_STOLEN_0M		0x0
 #define I855_GMCH_GMS_STOLEN_0M		0x0
 #define I855_GMCH_GMS_STOLEN_1M		(0x1 << 4)
 #define I855_GMCH_GMS_STOLEN_1M		(0x1 << 4)
 #define I855_GMCH_GMS_STOLEN_4M		(0x2 << 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)
 		if (IS_G33)
 			size = 0;
 			size = 0;
-		switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
+		switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
 		case I855_GMCH_GMS_STOLEN_1M:
 		case I855_GMCH_GMS_STOLEN_1M:
 			gtt_entries = MB(1) - KB(size);
 			gtt_entries = MB(1) - KB(size);
 			break;
 			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[] = {
 static struct pci_device_id ipmi_pci_devices[] = {
 	{ PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
 	{ 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);
 MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
 
 

+ 48 - 21
drivers/char/mspec.c

@@ -67,7 +67,7 @@
 /*
 /*
  * Page types allocated by the device.
  * Page types allocated by the device.
  */
  */
-enum {
+enum mspec_page_type {
 	MSPEC_FETCHOP = 1,
 	MSPEC_FETCHOP = 1,
 	MSPEC_CACHED,
 	MSPEC_CACHED,
 	MSPEC_UNCACHED
 	MSPEC_UNCACHED
@@ -83,15 +83,25 @@ static int is_sn2;
  * One of these structures is allocated when an mspec region is mmaped. The
  * 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.
  * 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 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 {
 struct vma_data {
 	atomic_t refcnt;	/* Number of vmas sharing the 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 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. */
 	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 */
 /* used on shub2 to clear FOP cache in the HUB */
 static unsigned long scratch_page[MAX_NUMNODES];
 static unsigned long scratch_page[MAX_NUMNODES];
 #define SH2_AMO_CACHE_ENTRIES	4
 #define SH2_AMO_CACHE_ENTRIES	4
@@ -129,8 +139,8 @@ mspec_zero_block(unsigned long addr, int len)
  * mspec_open
  * mspec_open
  *
  *
  * Called when a device mapping is created by a means other than mmap
  * 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
 static void
 mspec_open(struct vm_area_struct *vma)
 mspec_open(struct vm_area_struct *vma)
@@ -151,34 +161,44 @@ static void
 mspec_close(struct vm_area_struct *vma)
 mspec_close(struct vm_area_struct *vma)
 {
 {
 	struct vma_data *vdata;
 	struct vma_data *vdata;
-	int i, pages, result, vdata_size;
+	int index, last_index, result;
+	unsigned long my_page;
 
 
 	vdata = vma->vm_private_data;
 	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;
 			continue;
 		/*
 		/*
 		 * Clear the page before sticking it back
 		 * Clear the page before sticking it back
 		 * into the pool.
 		 * 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)
 		if (!result)
-			uncached_free_page(vdata->maddr[i]);
+			uncached_free_page(my_page);
 		else
 		else
 			printk(KERN_WARNING "mspec_close(): "
 			printk(KERN_WARNING "mspec_close(): "
 			       "failed to zero page %i\n",
 			       "failed to zero page %i\n",
 			       result);
 			       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);
 		vfree(vdata);
+	else
+		kfree(vdata);
 }
 }
 
 
 
 
@@ -195,7 +215,8 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address)
 	int index;
 	int index;
 	struct vma_data *vdata = vma->vm_private_data;
 	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];
 	maddr = (volatile unsigned long) vdata->maddr[index];
 	if (maddr == 0) {
 	if (maddr == 0) {
 		maddr = uncached_alloc_page(numa_node_id());
 		maddr = uncached_alloc_page(numa_node_id());
@@ -237,10 +258,11 @@ static struct vm_operations_struct mspec_vm_ops = {
  * underlying pages.
  * underlying pages.
  */
  */
 static int
 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;
 	struct vma_data *vdata;
-	int pages, vdata_size;
+	int pages, vdata_size, flags = 0;
 
 
 	if (vma->vm_pgoff != 0)
 	if (vma->vm_pgoff != 0)
 		return -EINVAL;
 		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);
 	vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
 	if (vdata_size <= PAGE_SIZE)
 	if (vdata_size <= PAGE_SIZE)
 		vdata = kmalloc(vdata_size, GFP_KERNEL);
 		vdata = kmalloc(vdata_size, GFP_KERNEL);
-	else
+	else {
 		vdata = vmalloc(vdata_size);
 		vdata = vmalloc(vdata_size);
+		flags = VMD_VMALLOCED;
+	}
 	if (!vdata)
 	if (!vdata)
 		return -ENOMEM;
 		return -ENOMEM;
 	memset(vdata, 0, vdata_size);
 	memset(vdata, 0, vdata_size);
 
 
+	vdata->vm_start = vma->vm_start;
+	vdata->vm_end = vma->vm_end;
+	vdata->flags = flags;
 	vdata->type = type;
 	vdata->type = type;
 	spin_lock_init(&vdata->lock);
 	spin_lock_init(&vdata->lock);
 	vdata->refcnt = ATOMIC_INIT(1);
 	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))
 			if (L_ICANON(tty))
 				retval = inq_canon(tty);
 				retval = inq_canon(tty);
 			return put_user(retval, (unsigned int __user *) arg);
 			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:
 		case TIOCGLCKTRMIOS:
 			if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
 			if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
 				return -EFAULT;
 				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))
 			if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg))
 				return -EFAULT;
 				return -EFAULT;
 			return 0;
 			return 0;
+#endif
 
 
 		case TIOCPKT:
 		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[] = {
 static const struct drive_list_entry hpa_list[] = {
 	{ "ST340823A",	NULL },
 	{ "ST340823A",	NULL },
+	{ "ST320413A",	NULL },
 	{ NULL,		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;
 	struct hd_driveid *id = drive->id;
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_hwif_t *hwif = HWIF(drive);
-	pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
 	int enable = 1;
 	int enable = 1;
-	int map;
 	drive->using_dma = 0;
 	drive->using_dma = 0;
 	
 	
 	if (drive->media == ide_floppy)
 	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,
 void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
 		       const u8 *old, const u8 *new, int bytes);
 		       const u8 *old, const u8 *new, int bytes);
 int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva);
 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);
 int kvm_mmu_load(struct kvm_vcpu *vcpu);
 void kvm_mmu_unload(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,
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 				     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);
 	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)
 static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu)
 {
 {
 	if (likely(vcpu->mmu.root_hpa != INVALID_PAGE))
 	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;
 	int r;
 
 
 	r = __mmu_topup_memory_caches(vcpu, GFP_NOWAIT);
 	r = __mmu_topup_memory_caches(vcpu, GFP_NOWAIT);
+	kvm_mmu_free_some_pages(vcpu);
 	if (r < 0) {
 	if (r < 0) {
 		spin_unlock(&vcpu->kvm->lock);
 		spin_unlock(&vcpu->kvm->lock);
 		kvm_arch_ops->vcpu_put(vcpu);
 		kvm_arch_ops->vcpu_put(vcpu);
 		r = __mmu_topup_memory_caches(vcpu, GFP_KERNEL);
 		r = __mmu_topup_memory_caches(vcpu, GFP_KERNEL);
 		kvm_arch_ops->vcpu_load(vcpu);
 		kvm_arch_ops->vcpu_load(vcpu);
 		spin_lock(&vcpu->kvm->lock);
 		spin_lock(&vcpu->kvm->lock);
+		kvm_mmu_free_some_pages(vcpu);
 	}
 	}
 	return r;
 	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);
 	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) {
 	while (vcpu->kvm->n_free_mmu_pages < KVM_REFILL_PAGES) {
 		struct kvm_mmu_page *page;
 		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);
 		kvm_mmu_zap_page(vcpu->kvm, page);
 	}
 	}
 }
 }
-EXPORT_SYMBOL_GPL(kvm_mmu_free_some_pages);
 
 
 static void free_mmu_pages(struct kvm_vcpu *vcpu)
 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>
 #include <linux/bio.h>
 
 
+#ifdef CONFIG_BLOCK
+
 struct bio_list {
 struct bio_list {
 	struct bio *head;
 	struct bio *head;
 	struct bio *tail;
 	struct bio *tail;
@@ -106,4 +108,5 @@ static inline struct bio *bio_list_get(struct bio_list *bl)
 	return bio;
 	return bio;
 }
 }
 
 
+#endif /* CONFIG_BLOCK */
 #endif
 #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) {
 	list_for_each(list,&cx8802_devlist) {
 		h = list_entry(list, struct cx8802_dev, 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;
 			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;
 		int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
 		struct v4l2_enc_idx_entry *e = itv->pgm_info + idx;
 		struct v4l2_enc_idx_entry *e = itv->pgm_info + idx;
 		u32 addr = itv->pgm_info_offset + 4 + idx * 24;
 		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);
 		e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32);
 		if (e->offset > itv->mpg_data_received) {
 		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->offset += itv->vbi_data_inserted;
 		e->length = read_enc(addr);
 		e->length = read_enc(addr);
 		e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32);
 		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++;
 		i++;
 	}
 	}
 	itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
 	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: {
 	case VIDIOC_G_ENC_INDEX: {
 		struct v4l2_enc_idx *idx = arg;
 		struct v4l2_enc_idx *idx = arg;
+		struct v4l2_enc_idx_entry *e = idx->entry;
+		int entries;
 		int i;
 		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;
 					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;
 		itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
 		break;
 		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);
 				PWC_ERROR("Failed to power down camera (%d)\n", i);
 		}
 		}
 		pdev->vopen--;
 		pdev->vopen--;
-		PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i);
+		PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
 	} else {
 	} else {
 		pwc_cleanup(pdev);
 		pwc_cleanup(pdev);
 		/* Free memory (don't set pdev to 0 just yet) */
 		/* 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,
 			.name = name_comp1,
 			.vmux = 0,
 			.vmux = 0,
-			.amux = LINE2,
-			.gpio = 0x00,
+			.amux = LINE1,
+			.gpio = 0x02,
 		},{
 		},{
 			.name = name_comp2,
 			.name = name_comp2,
 			.vmux = 3,
 			.vmux = 3,
-			.amux = LINE2,
-			.gpio = 0x00,
+			.amux = LINE1,
+			.gpio = 0x02,
 		},{
 		},{
 			.name = name_svideo,
 			.name = name_svideo,
 			.vmux = 8,
 			.vmux = 8,
-			.amux = LINE2,
-			.gpio = 0x00,
+			.amux = LINE1,
+			.gpio = 0x02,
 		}},
 		}},
 		.radio = {
 		.radio = {
 			.name = name_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) */
 /* the first byte of data must be the first subaddress number (register) */
 static int saa7191_write_block(struct i2c_client *client,
 static int saa7191_write_block(struct i2c_client *client,
-			       u8 length, u8 *data)
+			       u8 length, const u8 *data)
 {
 {
 	int i;
 	int i;
 	int ret;
 	int ret;
@@ -592,7 +592,7 @@ static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
 	if (err)
 	if (err)
 		goto out_free_decoder;
 		goto out_free_decoder;
 
 
-	err = saa7191_write_block(client, sizeof(initseq), (u8 *)initseq);
+	err = saa7191_write_block(client, sizeof(initseq), initseq);
 	if (err) {
 	if (err) {
 		printk(KERN_ERR "SAA7191 initialization failed\n");
 		printk(KERN_ERR "SAA7191 initialization failed\n");
 		goto out_detach_client;
 		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, 0x0301), .driver_info=PINNA_LINX_VD_IN_CAB_PAL },
 	{ USB_DEVICE(0x2304, 0x0419), .driver_info=PINNA_PCTV_BUNGEE_PAL_FM },
 	{ USB_DEVICE(0x2304, 0x0419), .driver_info=PINNA_PCTV_BUNGEE_PAL_FM },
 	{ USB_DEVICE(0x2400, 0x4200), .driver_info=HPG_WINTV },
 	{ USB_DEVICE(0x2400, 0x4200), .driver_info=HPG_WINTV },
+	{ },    /* terminate list */
 };
 };
 
 
 MODULE_DEVICE_TABLE (usb, usbvision_table);
 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.
 	  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
 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))
 	if (IS_ERR(msibl_device))
 		return PTR_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);
 	ret = platform_driver_register(&msipf_driver);
 	if (ret)
 	if (ret)

+ 87 - 57
drivers/misc/thinkpad_acpi.c

@@ -21,7 +21,7 @@
  *  02110-1301, USA.
  *  02110-1301, USA.
  */
  */
 
 
-#define IBM_VERSION "0.15"
+#define IBM_VERSION "0.16"
 #define TPACPI_SYSFS_VERSION 0x010000
 #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 =
 static struct device_attribute dev_attr_hotkey_radio_sw =
 	__ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
 	__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_mask.attr,
 	&dev_attr_hotkey_bios_enabled.attr,
 	&dev_attr_hotkey_bios_enabled.attr,
 	&dev_attr_hotkey_bios_mask.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));
 		str_supported(tp_features.hotkey));
 
 
 	if (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)
 		if (!hotkey_dev_attributes)
 			return -ENOMEM;
 			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)
 		if (res)
 			return res;
 			return res;
 
 
@@ -1055,11 +1073,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 				TPACPI_HOTKEY_MAP_SIZE);
 				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_KEY, tpacpi_inputdev->evbit);
 		set_bit(EV_MSC, tpacpi_inputdev->evbit);
 		set_bit(EV_MSC, tpacpi_inputdev->evbit);
 		set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
 		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);
 			set_bit(SW_RADIO, tpacpi_inputdev->swbit);
 		}
 		}
 
 
-#ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
 		dbg_printk(TPACPI_DBG_INIT,
 		dbg_printk(TPACPI_DBG_INIT,
 				"enabling hot key handling\n");
 				"enabling hot key handling\n");
 		res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)
 		res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)
 					| hotkey_orig_mask);
 					| hotkey_orig_mask);
 		if (res)
 		if (res)
 			return 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;
 	return (tp_features.hotkey)? 0 : 1;
@@ -1142,58 +1158,65 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 {
 {
 	u32 hkey;
 	u32 hkey;
 	unsigned int keycode, scancode;
 	unsigned int keycode, scancode;
-	int sendacpi = 1;
+	int send_acpi_ev = 0;
 
 
 	if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
 	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;
 				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 {
 	} else {
 		printk(IBM_ERR "unknown hotkey notification event %d\n", event);
 		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;
 static int brightness_mode;
 module_param_named(brightness_mode, brightness_mode, int, 0);
 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) \
 #define IBM_PARAM(feature) \
 	module_param_call(feature, set_ibm_param, NULL, NULL, 0)
 	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;
 	int ret, i;
 
 
+	/* Parameter checking */
+	if (hotkey_report_mode > 2)
+		return -EINVAL;
+
 	/* Driver-level probe */
 	/* Driver-level probe */
 
 
 	get_thinkpad_model_data(&thinkpad_id);
 	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 int experimental;
 static u32 dbg_level;
 static u32 dbg_level;
 static int force_load;
 static int force_load;
+static unsigned int hotkey_report_mode;
 
 
 static int thinkpad_acpi_module_init(void);
 static int thinkpad_acpi_module_init(void);
 static void thinkpad_acpi_module_exit(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[] = {
 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);
 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.
 	  with better performance and more complete ethtool support.
 
 
 	  It does not support the link failover and network management 
 	  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:
 	  This driver supports adapters based on the original Yukon chipset:
 	  Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
 	  Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
@@ -2215,6 +2215,93 @@ config SKY2_DEBUG
 
 
 	 If unsure, say N.
 	 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
 config VIA_VELOCITY
 	tristate "VIA Velocity support"
 	tristate "VIA Velocity support"
 	depends on PCI
 	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_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKY2) += sky2.o
 obj-$(CONFIG_SKY2) += sky2.o
+obj-$(CONFIG_SK98LIN) += sk98lin/
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
 obj-$(CONFIG_VIA_VELOCITY) += via-velocity.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 net_device *netdev;
 	struct atl1_adapter *adapter;
 	struct atl1_adapter *adapter;
 	static int cards_found = 0;
 	static int cards_found = 0;
-	bool pci_using_64 = true;
 	int err;
 	int err;
 
 
 	err = pci_enable_device(pdev);
 	err = pci_enable_device(pdev);
 	if (err)
 	if (err)
 		return 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) {
 	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
 	/* Mark all PCI regions associated with PCI device
 	 * pdev as being reserved by owner atl1_driver_name
 	 * 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;
 	netdev->ethtool_ops = &atl1_ethtool_ops;
 	adapter->bd_number = cards_found;
 	adapter->bd_number = cards_found;
-	adapter->pci_using_64 = pci_using_64;
 
 
 	/* setup the private structure */
 	/* setup the private structure */
 	err = atl1_sw_init(adapter);
 	err = atl1_sw_init(adapter);
@@ -2299,9 +2297,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 	 */
 	 */
 	/* netdev->features |= NETIF_F_TSO; */
 	/* netdev->features |= NETIF_F_TSO; */
 
 
-	if (pci_using_64)
-		netdev->features |= NETIF_F_HIGHDMA;
-
 	netdev->features |= NETIF_F_LLTX;
 	netdev->features |= NETIF_F_LLTX;
 
 
 	/*
 	/*

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

@@ -39,7 +39,7 @@
 #include <asm/io.h>
 #include <asm/io.h>
 
 
 #define DRV_NAME	"ehea"
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0073"
+#define DRV_VERSION	"EHEA_0074"
 
 
 /* eHEA capability flags */
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
 #define DLPAR_PORT_ADD_REM 1
@@ -402,6 +402,8 @@ struct ehea_mc_list {
 
 
 #define EHEA_PORT_UP 1
 #define EHEA_PORT_UP 1
 #define EHEA_PORT_DOWN 0
 #define EHEA_PORT_DOWN 0
+#define EHEA_PHY_LINK_UP 1
+#define EHEA_PHY_LINK_DOWN 0
 #define EHEA_MAX_PORT_RES 16
 #define EHEA_MAX_PORT_RES 16
 struct ehea_port {
 struct ehea_port {
 	struct ehea_adapter *adapter;	 /* adapter that owns this port */
 	struct ehea_adapter *adapter;	 /* adapter that owns this port */
@@ -427,6 +429,7 @@ struct ehea_port {
 	u32 msg_enable;
 	u32 msg_enable;
 	u32 sig_comp_iv;
 	u32 sig_comp_iv;
 	u32 state;
 	u32 state;
+	u8 phy_link;
 	u8 full_duplex;
 	u8 full_duplex;
 	u8 autoneg;
 	u8 autoneg;
 	u8 num_def_qps;
 	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 sq_entries = EHEA_DEF_ENTRIES_SQ;
 static int use_mcs = 0;
 static int use_mcs = 0;
 static int num_tx_qps = EHEA_NUM_TX_QP;
 static int num_tx_qps = EHEA_NUM_TX_QP;
+static int prop_carrier_state = 0;
 
 
 module_param(msg_level, int, 0);
 module_param(msg_level, int, 0);
 module_param(rq1_entries, int, 0);
 module_param(rq1_entries, int, 0);
 module_param(rq2_entries, int, 0);
 module_param(rq2_entries, int, 0);
 module_param(rq3_entries, int, 0);
 module_param(rq3_entries, int, 0);
 module_param(sq_entries, int, 0);
 module_param(sq_entries, int, 0);
+module_param(prop_carrier_state, int, 0);
 module_param(use_mcs, int, 0);
 module_param(use_mcs, int, 0);
 module_param(num_tx_qps, int, 0);
 module_param(num_tx_qps, int, 0);
 
 
 MODULE_PARM_DESC(num_tx_qps, "Number of TX-QPS");
 MODULE_PARM_DESC(num_tx_qps, "Number of TX-QPS");
 MODULE_PARM_DESC(msg_level, "msg_level");
 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 "
 MODULE_PARM_DESC(rq3_entries, "Number of entries for Receive Queue 3 "
 		 "[2^x - 1], x = [6..14]. Default = "
 		 "[2^x - 1], x = [6..14]. Default = "
 		 __MODULE_STRING(EHEA_DEF_ENTRIES_RQ3) ")");
 		 __MODULE_STRING(EHEA_DEF_ENTRIES_RQ3) ")");
@@ -467,7 +471,7 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
 			else
 			else
 				netif_receive_skb(skb);
 				netif_receive_skb(skb);
 
 
-			dev->last_rx = jiffies;
+			port->netdev->last_rx = jiffies;
 		} else {
 		} else {
 			pr->p_stats.poll_receive_errors++;
 			pr->p_stats.poll_receive_errors++;
 			port_reset = ehea_treat_poll_error(pr, rq, cqe,
 			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");
 			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);
 	kfree(cb4);
 out:
 out:
 	return ret;
 	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)) {
 		if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PORT_UP, eqe)) {
+			port->phy_link = EHEA_PHY_LINK_UP;
 			if (netif_msg_link(port))
 			if (netif_msg_link(port))
 				ehea_info("%s: Physical port up",
 				ehea_info("%s: Physical port up",
 					  port->netdev->name);
 					  port->netdev->name);
+			if (prop_carrier_state)
+				netif_carrier_on(port->netdev);
 		} else {
 		} else {
+			port->phy_link = EHEA_PHY_LINK_DOWN;
 			if (netif_msg_link(port))
 			if (netif_msg_link(port))
 				ehea_info("%s: Physical port down",
 				ehea_info("%s: Physical port down",
 					  port->netdev->name);
 					  port->netdev->name);
+			if (prop_carrier_state)
+				netif_carrier_off(port->netdev);
 		}
 		}
 
 
 		if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PRIMARY, eqe))
 		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);
 	spin_lock_irqsave(&mp->lock, flags);
 
 
 	eth_tx_submit_descs_for_skb(mp, skb);
 	eth_tx_submit_descs_for_skb(mp, skb);
-	stats->tx_bytes = skb->len;
+	stats->tx_bytes += skb->len;
 	stats->tx_packets++;
 	stats->tx_packets++;
 	dev->trans_start = jiffies;
 	dev->trans_start = jiffies;
 
 

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

@@ -116,7 +116,7 @@ struct el3_private {
     spinlock_t		lock;
     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)
 void phy_start(struct phy_device *phydev)
 {
 {
-	spin_lock(&phydev->lock);
+	spin_lock_bh(&phydev->lock);
 
 
 	switch (phydev->state) {
 	switch (phydev->state) {
 		case PHY_STARTING:
 		case PHY_STARTING:
@@ -769,7 +769,7 @@ void phy_start(struct phy_device *phydev)
 		default:
 		default:
 			break;
 			break;
 	}
 	}
-	spin_unlock(&phydev->lock);
+	spin_unlock_bh(&phydev->lock);
 }
 }
 EXPORT_SYMBOL(phy_stop);
 EXPORT_SYMBOL(phy_stop);
 EXPORT_SYMBOL(phy_start);
 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))
 	if (!(phydrv->flags & PHY_HAS_INTERRUPT))
 		phydev->irq = PHY_POLL;
 		phydev->irq = PHY_POLL;
 
 
-	spin_lock(&phydev->lock);
+	spin_lock_bh(&phydev->lock);
 
 
 	/* Start out supporting everything. Eventually,
 	/* Start out supporting everything. Eventually,
 	 * a controller will attach, and may modify one
 	 * a controller will attach, and may modify one
@@ -658,7 +658,7 @@ static int phy_probe(struct device *dev)
 	if (phydev->drv->probe)
 	if (phydev->drv->probe)
 		err = phydev->drv->probe(phydev);
 		err = phydev->drv->probe(phydev);
 
 
-	spin_unlock(&phydev->lock);
+	spin_unlock_bh(&phydev->lock);
 
 
 	return err;
 	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,
 	/* Put the 2-byte PPP protocol number on the front,
 	   making sure there is room for the address and control fields. */
 	   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);
 	pp = skb_push(skb, 2);
 	proto = npindex_to_proto[npi];
 	proto = npindex_to_proto[npi];
 	pp[0] = proto >> 8;
 	pp[0] = proto >> 8;
@@ -1533,7 +1525,7 @@ ppp_input_error(struct ppp_channel *chan, int code)
 static void
 static void
 ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 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
 #ifdef CONFIG_PPP_MULTILINK
 		/* XXX do channel-level decompression here */
 		/* XXX do channel-level decompression here */
 		if (PPP_PROTO(skb) == PPP_MP)
 		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))
 		if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP))
 			goto err;
 			goto err;
 
 
-		if (skb_tailroom(skb) < 124) {
+		if (skb_tailroom(skb) < 124 || skb_cloned(skb)) {
 			/* copy to a new sk_buff with more tailroom */
 			/* copy to a new sk_buff with more tailroom */
 			ns = dev_alloc_skb(skb->len + 128);
 			ns = dev_alloc_skb(skb->len + 128);
 			if (ns == 0) {
 			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 */
 		/* check if the packet passes the pass and active filters */
 		/* the filter instructions are constructed assuming
 		/* the filter instructions are constructed assuming
 		   a four-byte PPP header on each packet */
 		   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 */
 #endif /* CONFIG_PPP_FILTER */
+			ppp->last_recv = jiffies;
 
 
 		if ((ppp->dev->flags & IFF_UP) == 0
 		if ((ppp->dev->flags & IFF_UP) == 0
 		    || ppp->npmode[npi] != NPMODE_PASS) {
 		    || 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;
 	struct channel *ch;
 	int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
 	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 */
 		goto err;		/* no good, throw it away */
 
 
 	/* Decode sequence number and begin/end bits */
 	/* 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 pppoe_hdr *ph;
 	struct pppox_sock *po;
 	struct pppox_sock *po;
 
 
-	if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
-		goto drop;
-
 	if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
 	if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
 		goto out;
 		goto out;
 
 
+	if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
+		goto drop;
+
 	ph = pppoe_hdr(skb);
 	ph = pppoe_hdr(skb);
 
 
 	po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
 	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 pppox_sock *po = pppox_sk(sk);
 	struct net_device *dev = po->pppoe_dev;
 	struct net_device *dev = po->pppoe_dev;
-	struct pppoe_hdr hdr;
 	struct pppoe_hdr *ph;
 	struct pppoe_hdr *ph;
-	int headroom = skb_headroom(skb);
 	int data_len = skb->len;
 	int data_len = skb->len;
-	struct sk_buff *skb2;
 
 
 	if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
 	if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
 		goto abort;
 		goto abort;
 
 
-	hdr.ver	= 1;
-	hdr.type = 1;
-	hdr.code = 0;
-	hdr.sid	= po->num;
-	hdr.length = htons(skb->len);
-
 	if (!dev)
 	if (!dev)
 		goto abort;
 		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);
 			 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;
 		goto abort;
 
 
-	kfree_skb(skb);
 	return 1;
 	return 1;
 
 
 abort:
 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_ */

Some files were not shown because too many files changed in this diff