[kernel] r11033 - in dists/trunk/linux-2.6/debian/patches: bugfix/all series

Maximilian Attems maks at alioth.debian.org
Thu Apr 3 10:34:53 UTC 2008


Author: maks
Date: Thu Apr  3 10:34:52 2008
New Revision: 11033

Log:
update to 2.6.25-rc8-git2

fixed conflict with ip2 patch snippet.
important bugfixes..


Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.25-rc8-git2
Modified:
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.1

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.25-rc8-git2
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.25-rc8-git2	Thu Apr  3 10:34:52 2008
@@ -0,0 +1,5349 @@
+diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
+index 08a1ed1..47a539c 100644
+--- a/Documentation/SubmittingPatches
++++ b/Documentation/SubmittingPatches
+@@ -512,7 +512,7 @@ They provide type safety, have no length limitations, no formatting
+ limitations, and under gcc they are as cheap as macros.
+ 
+ Macros should only be used for cases where a static inline is clearly
+-suboptimal [there a few, isolated cases of this in fast paths],
++suboptimal [there are a few, isolated cases of this in fast paths],
+ or where it is impossible to use a static inline function [such as
+ string-izing].
+ 
+diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
+index 02e56d4..c485ee0 100644
+--- a/Documentation/networking/00-INDEX
++++ b/Documentation/networking/00-INDEX
+@@ -84,9 +84,6 @@ policy-routing.txt
+ 	- IP policy-based routing
+ ray_cs.txt
+ 	- Raylink Wireless LAN card driver info.
+-sk98lin.txt
+-	- Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit
+-	  Ethernet Adapter family driver info
+ skfp.txt
+ 	- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
+ smc9.txt
+diff --git a/Documentation/networking/sk98lin.txt b/Documentation/networking/sk98lin.txt
+deleted file mode 100644
+index 8590a95..0000000
+--- a/Documentation/networking/sk98lin.txt
++++ /dev/null
+@@ -1,568 +0,0 @@
+-(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 at 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***
+diff --git a/Documentation/unaligned-memory-access.txt b/Documentation/unaligned-memory-access.txt
+index 6223eac..b0472ac 100644
+--- a/Documentation/unaligned-memory-access.txt
++++ b/Documentation/unaligned-memory-access.txt
+@@ -57,7 +57,7 @@ here; a summary of the common scenarios is presented below:
+    unaligned access to be corrected.
+  - Some architectures are not capable of unaligned memory access, but will
+    silently perform a different memory access to the one that was requested,
+-   resulting a a subtle code bug that is hard to detect!
++   resulting in a subtle code bug that is hard to detect!
+ 
+ It should be obvious from the above that if your code causes unaligned
+ memory accesses to happen, your code will not work correctly on certain
+@@ -209,7 +209,7 @@ memory and you wish to avoid unaligned access, its usage is as follows:
+ 
+ 	u32 value = get_unaligned((u32 *) data);
+ 
+-These macros work work for memory accesses of any length (not just 32 bits as
++These macros work for memory accesses of any length (not just 32 bits as
+ in the examples above). Be aware that when compared to standard access of
+ aligned memory, using these macros to access unaligned memory can be costly in
+ terms of performance.
+diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
+index 4e1c086..dd6e334 100644
+--- a/arch/alpha/kernel/pci_iommu.c
++++ b/arch/alpha/kernel/pci_iommu.c
+@@ -424,11 +424,13 @@ EXPORT_SYMBOL(pci_unmap_page);
+    else DMA_ADDRP is undefined.  */
+ 
+ void *
+-pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
++__pci_alloc_consistent(struct pci_dev *pdev, size_t size,
++		       dma_addr_t *dma_addrp, gfp_t gfp)
+ {
+ 	void *cpu_addr;
+ 	long order = get_order(size);
+-	gfp_t gfp = GFP_ATOMIC;
++
++	gfp &= ~GFP_DMA;
+ 
+ try_again:
+ 	cpu_addr = (void *)__get_free_pages(gfp, order);
+@@ -458,7 +460,7 @@ try_again:
+ 
+ 	return cpu_addr;
+ }
+-EXPORT_SYMBOL(pci_alloc_consistent);
++EXPORT_SYMBOL(__pci_alloc_consistent);
+ 
+ /* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
+    be values that were returned from pci_alloc_consistent.  SIZE must
+diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
+index b781d3d..756fa24 100644
+--- a/arch/sparc64/kernel/iommu.c
++++ b/arch/sparc64/kernel/iommu.c
+@@ -516,9 +516,11 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
+ 	unsigned long flags, handle, prot, ctx;
+ 	dma_addr_t dma_next = 0, dma_addr;
+ 	unsigned int max_seg_size;
++	unsigned long seg_boundary_size;
+ 	int outcount, incount, i;
+ 	struct strbuf *strbuf;
+ 	struct iommu *iommu;
++	unsigned long base_shift;
+ 
+ 	BUG_ON(direction == DMA_NONE);
+ 
+@@ -549,8 +551,11 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
+ 	outs->dma_length = 0;
+ 
+ 	max_seg_size = dma_get_max_seg_size(dev);
++	seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
++				  IO_PAGE_SIZE) >> IO_PAGE_SHIFT;
++	base_shift = iommu->page_table_map_base >> IO_PAGE_SHIFT;
+ 	for_each_sg(sglist, s, nelems, i) {
+-		unsigned long paddr, npages, entry, slen;
++		unsigned long paddr, npages, entry, out_entry = 0, slen;
+ 		iopte_t *base;
+ 
+ 		slen = s->length;
+@@ -593,7 +598,9 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
+ 			 * - allocated dma_addr isn't contiguous to previous allocation
+ 			 */
+ 			if ((dma_addr != dma_next) ||
+-			    (outs->dma_length + s->length > max_seg_size)) {
++			    (outs->dma_length + s->length > max_seg_size) ||
++			    (is_span_boundary(out_entry, base_shift,
++					      seg_boundary_size, outs, s))) {
+ 				/* Can't merge: create a new segment */
+ 				segstart = s;
+ 				outcount++;
+@@ -607,6 +614,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
+ 			/* This is a new segment, fill entries */
+ 			outs->dma_address = dma_addr;
+ 			outs->dma_length = slen;
++			out_entry = entry;
+ 		}
+ 
+ 		/* Calculate next page pointer for contiguous check */
+diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h
+index 0713bd5..f3575a6 100644
+--- a/arch/sparc64/kernel/iommu_common.h
++++ b/arch/sparc64/kernel/iommu_common.h
+@@ -12,6 +12,7 @@
+ #include <linux/mm.h>
+ #include <linux/scatterlist.h>
+ #include <linux/device.h>
++#include <linux/iommu-helper.h>
+ 
+ #include <asm/iommu.h>
+ #include <asm/scatterlist.h>
+@@ -45,17 +46,16 @@ static inline unsigned long iommu_num_pages(unsigned long vaddr,
+ 	return npages;
+ }
+ 
+-static inline unsigned long calc_npages(struct scatterlist *sglist, int nelems)
++static inline int is_span_boundary(unsigned long entry,
++				   unsigned long shift,
++				   unsigned long boundary_size,
++				   struct scatterlist *outs,
++				   struct scatterlist *sg)
+ {
+-	unsigned long i, npages = 0;
+-	struct scatterlist *sg;
++	unsigned long paddr = SG_ENT_PHYS_ADDRESS(outs);
++	int nr = iommu_num_pages(paddr, outs->dma_length + sg->length);
+ 
+-	for_each_sg(sglist, sg, nelems, i) {
+-		unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg);
+-		npages += iommu_num_pages(paddr, sg->length);
+-	}
+-
+-	return npages;
++	return iommu_is_span_boundary(entry, nr, shift, boundary_size);
+ }
+ 
+ extern unsigned long iommu_range_alloc(struct device *dev,
+diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
+index ddca6c6..0183970 100644
+--- a/arch/sparc64/kernel/pci_sun4v.c
++++ b/arch/sparc64/kernel/pci_sun4v.c
+@@ -335,8 +335,10 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
+ 	unsigned long flags, handle, prot;
+ 	dma_addr_t dma_next = 0, dma_addr;
+ 	unsigned int max_seg_size;
++	unsigned long seg_boundary_size;
+ 	int outcount, incount, i;
+ 	struct iommu *iommu;
++	unsigned long base_shift;
+ 	long err;
+ 
+ 	BUG_ON(direction == DMA_NONE);
+@@ -362,8 +364,11 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
+ 	iommu_batch_start(dev, prot, ~0UL);
+ 
+ 	max_seg_size = dma_get_max_seg_size(dev);
++	seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
++				  IO_PAGE_SIZE) >> IO_PAGE_SHIFT;
++	base_shift = iommu->page_table_map_base >> IO_PAGE_SHIFT;
+ 	for_each_sg(sglist, s, nelems, i) {
+-		unsigned long paddr, npages, entry, slen;
++		unsigned long paddr, npages, entry, out_entry = 0, slen;
+ 
+ 		slen = s->length;
+ 		/* Sanity check */
+@@ -406,7 +411,9 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
+ 			 * - allocated dma_addr isn't contiguous to previous allocation
+ 			 */
+ 			if ((dma_addr != dma_next) ||
+-			    (outs->dma_length + s->length > max_seg_size)) {
++			    (outs->dma_length + s->length > max_seg_size) ||
++			    (is_span_boundary(out_entry, base_shift,
++					      seg_boundary_size, outs, s))) {
+ 				/* Can't merge: create a new segment */
+ 				segstart = s;
+ 				outcount++;
+@@ -420,6 +427,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
+ 			/* This is a new segment, fill entries */
+ 			outs->dma_address = dma_addr;
+ 			outs->dma_length = slen;
++			out_entry = entry;
+ 		}
+ 
+ 		/* Calculate next page pointer for contiguous check */
+diff --git a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c
+index a0f000b..ae24919 100644
+--- a/arch/sparc64/mm/tlb.c
++++ b/arch/sparc64/mm/tlb.c
+@@ -23,11 +23,8 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) = { 0, };
+ 
+ void flush_tlb_pending(void)
+ {
+-	struct mmu_gather *mp;
++	struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
+ 
+-	preempt_disable();
+-
+-	mp = &__get_cpu_var(mmu_gathers);
+ 	if (mp->tlb_nr) {
+ 		flush_tsb_user(mp);
+ 
+@@ -43,7 +40,7 @@ void flush_tlb_pending(void)
+ 		mp->tlb_nr = 0;
+ 	}
+ 
+-	preempt_enable();
++	put_cpu_var(mmu_gathers);
+ }
+ 
+ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig)
+diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
+index 236d2f8..576a03d 100644
+--- a/arch/x86/kernel/machine_kexec_64.c
++++ b/arch/x86/kernel/machine_kexec_64.c
+@@ -233,6 +233,7 @@ NORET_TYPE void machine_kexec(struct kimage *image)
+ 
+ void arch_crash_save_vmcoreinfo(void)
+ {
++	VMCOREINFO_SYMBOL(phys_base);
+ 	VMCOREINFO_SYMBOL(init_level4_pgt);
+ 
+ #ifdef CONFIG_NUMA
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index 1344a0e..5713f7e 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -140,7 +140,7 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_addr)
+ 	/* Assume anything <= 4GB can be handled by IOMMU.
+ 	   Actually some IOMMUs can handle everything, but I don't
+ 	   know of a way to test this here. */
+-	if (b_pfn <= (min_t(u64, 0xffffffff, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
++	if (b_pfn < (min_t(u64, 0x100000000UL, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
+ 		dma = 1;
+ 	q->bounce_pfn = max_low_pfn;
+ #else
+diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
+index 0f962ec..f26da2b 100644
+--- a/block/cfq-iosched.c
++++ b/block/cfq-iosched.c
+@@ -1143,24 +1143,37 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
+ }
+ 
+ /*
+- * Call func for each cic attached to this ioc. Returns number of cic's seen.
++ * Call func for each cic attached to this ioc.
+  */
+-static unsigned int
++static void
+ call_for_each_cic(struct io_context *ioc,
+ 		  void (*func)(struct io_context *, struct cfq_io_context *))
+ {
+ 	struct cfq_io_context *cic;
+ 	struct hlist_node *n;
+-	int called = 0;
+ 
+ 	rcu_read_lock();
+-	hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) {
++	hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
+ 		func(ioc, cic);
+-		called++;
+-	}
+ 	rcu_read_unlock();
++}
++
++static void cfq_cic_free_rcu(struct rcu_head *head)
++{
++	struct cfq_io_context *cic;
++
++	cic = container_of(head, struct cfq_io_context, rcu_head);
++
++	kmem_cache_free(cfq_ioc_pool, cic);
++	elv_ioc_count_dec(ioc_count);
++
++	if (ioc_gone && !elv_ioc_count_read(ioc_count))
++		complete(ioc_gone);
++}
+ 
+-	return called;
++static void cfq_cic_free(struct cfq_io_context *cic)
++{
++	call_rcu(&cic->rcu_head, cfq_cic_free_rcu);
+ }
+ 
+ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
+@@ -1174,24 +1187,18 @@ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
+ 	hlist_del_rcu(&cic->cic_list);
+ 	spin_unlock_irqrestore(&ioc->lock, flags);
+ 
+-	kmem_cache_free(cfq_ioc_pool, cic);
++	cfq_cic_free(cic);
+ }
+ 
+ static void cfq_free_io_context(struct io_context *ioc)
+ {
+-	int freed;
+-
+ 	/*
+-	 * ioc->refcount is zero here, so no more cic's are allowed to be
+-	 * linked into this ioc. So it should be ok to iterate over the known
+-	 * list, we will see all cic's since no new ones are added.
++	 * ioc->refcount is zero here, or we are called from elv_unregister(),
++	 * so no more cic's are allowed to be linked into this ioc.  So it
++	 * should be ok to iterate over the known list, we will see all cic's
++	 * since no new ones are added.
+ 	 */
+-	freed = call_for_each_cic(ioc, cic_free_func);
+-
+-	elv_ioc_count_mod(ioc_count, -freed);
+-
+-	if (ioc_gone && !elv_ioc_count_read(ioc_count))
+-		complete(ioc_gone);
++	call_for_each_cic(ioc, cic_free_func);
+ }
+ 
+ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+@@ -1458,15 +1465,6 @@ cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc,
+ 	return cfqq;
+ }
+ 
+-static void cfq_cic_free(struct cfq_io_context *cic)
+-{
+-	kmem_cache_free(cfq_ioc_pool, cic);
+-	elv_ioc_count_dec(ioc_count);
+-
+-	if (ioc_gone && !elv_ioc_count_read(ioc_count))
+-		complete(ioc_gone);
+-}
+-
+ /*
+  * We drop cfq io contexts lazily, so we may find a dead one.
+  */
+@@ -2138,7 +2136,7 @@ static int __init cfq_slab_setup(void)
+ 	if (!cfq_pool)
+ 		goto fail;
+ 
+-	cfq_ioc_pool = KMEM_CACHE(cfq_io_context, SLAB_DESTROY_BY_RCU);
++	cfq_ioc_pool = KMEM_CACHE(cfq_io_context, 0);
+ 	if (!cfq_ioc_pool)
+ 		goto fail;
+ 
+@@ -2286,7 +2284,6 @@ static void __exit cfq_exit(void)
+ 	smp_wmb();
+ 	if (elv_ioc_count_read(ioc_count))
+ 		wait_for_completion(ioc_gone);
+-	synchronize_rcu();
+ 	cfq_slab_kill();
+ }
+ 
+diff --git a/crypto/xcbc.c b/crypto/xcbc.c
+index 2feb0f2..b63b633 100644
+--- a/crypto/xcbc.c
++++ b/crypto/xcbc.c
+@@ -116,13 +116,11 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
+ 	struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent);
+ 	struct crypto_cipher *tfm = ctx->child;
+ 	int bs = crypto_hash_blocksize(parent);
+-	unsigned int i = 0;
+ 
+-	do {
+-
+-		struct page *pg = sg_page(&sg[i]);
+-		unsigned int offset = sg[i].offset;
+-		unsigned int slen = sg[i].length;
++	for (;;) {
++		struct page *pg = sg_page(sg);
++		unsigned int offset = sg->offset;
++		unsigned int slen = sg->length;
+ 
+ 		if (unlikely(slen > nbytes))
+ 			slen = nbytes;
+@@ -182,8 +180,11 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
+ 			offset = 0;
+ 			pg++;
+ 		}
+-		i++;
+-	} while (nbytes>0);
++
++		if (!nbytes)
++			break;
++		sg = scatterwalk_sg_next(sg);
++	}
+ 
+ 	return 0;
+ }
+diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
+index 47c57a4..98099f5 100644
+--- a/drivers/atm/firestream.c
++++ b/drivers/atm/firestream.c
+@@ -978,6 +978,7 @@ static int fs_open(struct atm_vcc *atm_vcc)
+ 		/* Docs are vague about this atm_hdr field. By the way, the FS
+ 		 * chip makes odd errors if lower bits are set.... -- REW */
+ 		tc->atm_hdr =  (vpi << 20) | (vci << 4); 
++		tmc0 = 0;
+ 		{
+ 			int pcr = atm_pcr_goal (txtp);
+ 
+diff --git a/drivers/atm/he.c b/drivers/atm/he.c
+index 2e3395b..ffc4a5a 100644
+--- a/drivers/atm/he.c
++++ b/drivers/atm/he.c
+@@ -3000,8 +3000,7 @@ he_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
+ 
+ /* eeprom routines  -- see 4.7 */
+ 
+-u8
+-read_prom_byte(struct he_dev *he_dev, int addr)
++static u8 read_prom_byte(struct he_dev *he_dev, int addr)
+ {
+ 	u32 val = 0, tmp_read = 0;
+ 	int i, j = 0;
+diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
+index b967919..28d77b5 100644
+--- a/drivers/atm/idt77252.c
++++ b/drivers/atm/idt77252.c
+@@ -2016,8 +2016,7 @@ idt77252_send_skb(struct atm_vcc *vcc, struct sk_buff *skb, int oam)
+ 	return 0;
+ }
+ 
+-int
+-idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb)
++static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb)
+ {
+ 	return idt77252_send_skb(vcc, skb, 0);
+ }
+@@ -3072,8 +3071,7 @@ idt77252_dev_open(struct idt77252_dev *card)
+ 	return 0;
+ }
+ 
+-void
+-idt77252_dev_close(struct atm_dev *dev)
++static void idt77252_dev_close(struct atm_dev *dev)
+ {
+ 	struct idt77252_dev *card = dev->dev_data;
+ 	u32 conf;
+diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
+index ef52452..670c093 100644
+--- a/drivers/atm/iphase.c
++++ b/drivers/atm/iphase.c
+@@ -958,6 +958,7 @@ static void ia_suni_pm7345_init (IADEV *iadev)
+ 
+ /***************************** IA_LIB END *****************************/
+     
++#ifdef CONFIG_ATM_IA_DEBUG
+ static int tcnter = 0;
+ static void xdump( u_char*  cp, int  length, char*  prefix )
+ {
+@@ -992,6 +993,7 @@ static void xdump( u_char*  cp, int  length, char*  prefix )
+     }
+ 
+ }  /* close xdump(... */
++#endif /* CONFIG_ATM_IA_DEBUG */
+ 
+   
+ static struct atm_dev *ia_boards = NULL;  
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index b53fdb0..60cc543 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -153,6 +153,12 @@ static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size,
+ 	struct kvec iov;
+ 	sigset_t blocked, oldset;
+ 
++	if (unlikely(!sock)) {
++		printk(KERN_ERR "%s: Attempted %s on closed socket in sock_xmit\n",
++		       lo->disk->disk_name, (send ? "send" : "recv"));
++		return -EINVAL;
++	}
++
+ 	/* Allow interception of SIGKILL only
+ 	 * Don't allow other signals to interrupt the transmission */
+ 	siginitsetinv(&blocked, sigmask(SIGKILL));
+diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
+index 991119c..9b52892 100644
+--- a/drivers/char/rio/riotable.c
++++ b/drivers/char/rio/riotable.c
+@@ -425,8 +425,10 @@ int RIOApel(struct rio_info *p)
+ 
+ 		MapP = &p->RIOConnectTable[Next++];
+ 		MapP->HostUniqueNum = HostP->UniqueNum;
+-		if ((HostP->Flags & RUN_STATE) != RC_RUNNING)
++		if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
++			rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
+ 			continue;
++		}
+ 		MapP->RtaUniqueNum = 0;
+ 		MapP->ID = 0;
+ 		MapP->Flags = SLOT_IN_USE;
+diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
+index a4f0b1e..cfa5436 100644
+--- a/drivers/char/rio/riotty.c
++++ b/drivers/char/rio/riotty.c
+@@ -319,6 +319,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
+ 			PortP->State |= RIO_WOPEN;
+ 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+ 			if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
++				rio_spin_lock_irqsave(&PortP->portSem, flags);
+ 				/*
+ 				 ** ACTION: verify that this is a good thing
+ 				 ** to do here. -- ???
+@@ -334,6 +335,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
+ 				func_exit();
+ 				return -EINTR;
+ 			}
++			rio_spin_lock_irqsave(&PortP->portSem, flags);
+ 		}
+ 		PortP->State &= ~RIO_WOPEN;
+ 	}
+@@ -493,6 +495,7 @@ int riotclose(void *ptr)
+ 
+ 	if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
+ 		RIOPreemptiveCmd(p, PortP, FCLOSE);
++		rio_spin_lock_irqsave(&PortP->portSem, flags);
+ 		goto close_end;
+ 	}
+ 
+@@ -508,6 +511,7 @@ int riotclose(void *ptr)
+ 
+ 			if (p->RIOHalted) {
+ 				RIOClearUp(PortP);
++				rio_spin_lock_irqsave(&PortP->portSem, flags);
+ 				goto close_end;
+ 			}
+ 			if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
+diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
+index 43a70e9..be9ff73 100644
+--- a/drivers/ide/arm/ide_arm.c
++++ b/drivers/ide/arm/ide_arm.c
+@@ -46,3 +46,5 @@ static int __init ide_arm_init(void)
+ }
+ 
+ module_init(ide_arm_init);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
+index e79bf8f..c8ffbaf 100644
+--- a/drivers/ide/cris/ide-cris.c
++++ b/drivers/ide/cris/ide-cris.c
+@@ -1067,3 +1067,5 @@ static void cris_dma_start(ide_drive_t *drive)
+ }
+ 
+ module_init(init_e100_ide);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
+index 520aec0..4108ec4 100644
+--- a/drivers/ide/h8300/ide-h8300.c
++++ b/drivers/ide/h8300/ide-h8300.c
+@@ -110,6 +110,7 @@ static int __init h8300_ide_init(void)
+ 	ide_init_port_data(hwif, index);
+ 	ide_init_port_hw(hwif, &hw);
+ 	hwif_setup(hwif);
++	hwif->host_flags = IDE_HFLAG_NO_IO_32BIT;
+ 	printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", index);
+ 
+ 	idx[0] = index;
+@@ -125,3 +126,5 @@ out_busy:
+ }
+ 
+ module_init(h8300_ide_init);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
+index 01b9220..e77cee0 100644
+--- a/drivers/ide/ide-iops.c
++++ b/drivers/ide/ide-iops.c
+@@ -658,7 +658,7 @@ int ide_driveid_update(ide_drive_t *drive)
+ 		local_irq_restore(flags);
+ 		return 0;
+ 	}
+-	ata_input_data(drive, id, SECTOR_WORDS);
++	hwif->ata_input_data(drive, id, SECTOR_WORDS);
+ 	(void)ide_read_status(drive);	/* clear drive IRQ */
+ 	local_irq_enable();
+ 	local_irq_restore(flags);
+diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
+index b163b2e..c14bb53 100644
+--- a/drivers/ide/ide-pnp.c
++++ b/drivers/ide/ide-pnp.c
+@@ -86,3 +86,5 @@ static void __exit pnpide_exit(void)
+ 
+ module_init(pnpide_init);
+ module_exit(pnpide_exit);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
+index 50ffa87..fdd3791 100644
+--- a/drivers/ide/legacy/buddha.c
++++ b/drivers/ide/legacy/buddha.c
+@@ -241,3 +241,5 @@ fail_base2:
+ }
+ 
+ module_init(buddha_init);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
+index 8949ce7..e950afa 100644
+--- a/drivers/ide/legacy/falconide.c
++++ b/drivers/ide/legacy/falconide.c
+@@ -93,3 +93,5 @@ static int __init falconide_init(void)
+ }
+ 
+ module_init(falconide_init);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
+index b7d8109..e3b4638 100644
+--- a/drivers/ide/legacy/gayle.c
++++ b/drivers/ide/legacy/gayle.c
+@@ -195,3 +195,5 @@ found:
+ }
+ 
+ module_init(gayle_init);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
+index 9a79098..eaf5dbe 100644
+--- a/drivers/ide/legacy/macide.c
++++ b/drivers/ide/legacy/macide.c
+@@ -137,3 +137,5 @@ static int __init macide_init(void)
+ }
+ 
+ module_init(macide_init);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
+index 1381b91..2da2875 100644
+--- a/drivers/ide/legacy/q40ide.c
++++ b/drivers/ide/legacy/q40ide.c
+@@ -153,3 +153,5 @@ static int __init q40ide_init(void)
+ }
+ 
+ module_init(q40ide_init);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
+index ec66798..29fbc5e 100644
+--- a/drivers/ide/pci/cmd640.c
++++ b/drivers/ide/pci/cmd640.c
+@@ -881,3 +881,5 @@ module_param_named(probe_vlb, cmd640_vlb, bool, 0);
+ MODULE_PARM_DESC(probe_vlb, "probe for VLB version of CMD640 chipset");
+ 
+ module_init(cmd640x_init);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
+index 38fbfb8..ebaba01 100644
+--- a/drivers/ide/ppc/mpc8xx.c
++++ b/drivers/ide/ppc/mpc8xx.c
+@@ -853,3 +853,5 @@ static int __init mpc8xx_ide_probe(void)
+ }
+ 
+ module_init(mpc8xx_ide_probe);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
+index 78c9eeb..d9ca52e 100644
+--- a/drivers/ide/ppc/pmac.c
++++ b/drivers/ide/ppc/pmac.c
+@@ -1771,3 +1771,5 @@ static int __devinit pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+ #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+ 
+ module_init(pmac_ide_probe);
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
+index 34e317c..57b9e3a 100644
+--- a/drivers/media/radio/radio-cadet.c
++++ b/drivers/media/radio/radio-cadet.c
+@@ -587,6 +587,8 @@ static struct video_device cadet_radio=
+ 	.vidioc_s_input     = vidioc_s_input,
+ };
+ 
++#ifdef CONFIG_PNP
++
+ static struct pnp_device_id cadet_pnp_devices[] = {
+ 	/* ADS Cadet AM/FM Radio Card */
+ 	{.id = "MSM0c24", .driver_data = 0},
+@@ -621,6 +623,10 @@ static struct pnp_driver cadet_pnp_driver = {
+ 	.remove		= NULL,
+ };
+ 
++#else
++static struct pnp_driver cadet_pnp_driver;
++#endif
++
+ static int cadet_probe(void)
+ {
+ 	static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
+diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
+index a080c14..fcf8f2d 100644
+--- a/drivers/media/video/bt8xx/bttv-driver.c
++++ b/drivers/media/video/bt8xx/bttv-driver.c
+@@ -1990,7 +1990,7 @@ static int bttv_g_frequency(struct file *file, void *priv,
+ 	if (0 != err)
+ 		return err;
+ 
+-	f->type = V4L2_TUNER_ANALOG_TV;
++	f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ 	f->frequency = btv->freq;
+ 
+ 	return 0;
+@@ -2009,7 +2009,8 @@ static int bttv_s_frequency(struct file *file, void *priv,
+ 
+ 	if (unlikely(f->tuner != 0))
+ 		return -EINVAL;
+-	if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
++	if (unlikely(f->type != (btv->radio_user
++		? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV)))
+ 		return -EINVAL;
+ 	mutex_lock(&btv->lock);
+ 	btv->freq = f->frequency;
+@@ -3415,6 +3416,7 @@ static int radio_open(struct inode *inode, struct file *file)
+ {
+ 	int minor = iminor(inode);
+ 	struct bttv *btv = NULL;
++	struct bttv_fh *fh;
+ 	unsigned int i;
+ 
+ 	dprintk("bttv: open minor=%d\n",minor);
+@@ -3429,12 +3431,19 @@ static int radio_open(struct inode *inode, struct file *file)
+ 		return -ENODEV;
+ 
+ 	dprintk("bttv%d: open called (radio)\n",btv->c.nr);
++
++	/* allocate per filehandle data */
++	fh = kmalloc(sizeof(*fh), GFP_KERNEL);
++	if (NULL == fh)
++		return -ENOMEM;
++	file->private_data = fh;
++	*fh = btv->init;
++	v4l2_prio_open(&btv->prio, &fh->prio);
++
+ 	mutex_lock(&btv->lock);
+ 
+ 	btv->radio_user++;
+ 
+-	file->private_data = btv;
+-
+ 	bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
+ 	audio_input(btv,TVAUDIO_INPUT_RADIO);
+ 
+@@ -3444,7 +3453,8 @@ static int radio_open(struct inode *inode, struct file *file)
+ 
+ static int radio_release(struct inode *inode, struct file *file)
+ {
+-	struct bttv *btv = file->private_data;
++	struct bttv_fh *fh = file->private_data;
++	struct bttv *btv = fh->btv;
+ 	struct rds_command cmd;
+ 
+ 	btv->radio_user--;
+@@ -3508,8 +3518,12 @@ static int radio_enum_input(struct file *file, void *priv,
+ static int radio_g_audio(struct file *file, void *priv,
+ 					struct v4l2_audio *a)
+ {
++	if (a->index != 0)
++		return -EINVAL;
++
+ 	memset(a, 0, sizeof(*a));
+ 	strcpy(a->name, "Radio");
++
+ 	return 0;
+ }
+ 
+@@ -3569,7 +3583,8 @@ static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
+ static ssize_t radio_read(struct file *file, char __user *data,
+ 			 size_t count, loff_t *ppos)
+ {
+-	struct bttv    *btv = file->private_data;
++	struct bttv_fh *fh = file->private_data;
++	struct bttv *btv = fh->btv;
+ 	struct rds_command cmd;
+ 	cmd.block_count = count/3;
+ 	cmd.buffer = data;
+@@ -3583,7 +3598,8 @@ static ssize_t radio_read(struct file *file, char __user *data,
+ 
+ static unsigned int radio_poll(struct file *file, poll_table *wait)
+ {
+-	struct bttv    *btv = file->private_data;
++	struct bttv_fh *fh = file->private_data;
++	struct bttv *btv = fh->btv;
+ 	struct rds_command cmd;
+ 	cmd.instance = file;
+ 	cmd.event_list = wait;
+@@ -3599,6 +3615,7 @@ static const struct file_operations radio_fops =
+ 	.open	  = radio_open,
+ 	.read     = radio_read,
+ 	.release  = radio_release,
++	.compat_ioctl	= v4l_compat_ioctl32,
+ 	.ioctl	  = video_ioctl2,
+ 	.llseek	  = no_llseek,
+ 	.poll     = radio_poll,
+diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
+index 2d414da..dfa2698 100644
+--- a/drivers/media/video/cx23885/cx23885-cards.c
++++ b/drivers/media/video/cx23885/cx23885-cards.c
+@@ -232,6 +232,7 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
+ 	case 78631: /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */
+ 	case 79001: /* WinTV-HVR1250 (PCIe, Retail, IR, full height, ATSC and Basic analog */
+ 	case 79101: /* WinTV-HVR1250 (PCIe, Retail, IR, half height, ATSC and Basic analog */
++	case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */
+ 	case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */
+ 	case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */
+ 		break;
+@@ -347,10 +348,13 @@ void cx23885_card_setup(struct cx23885_dev *dev)
+ 	case CX23885_BOARD_HAUPPAUGE_HVR1250:
+ 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
+ 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
++		if (dev->i2c_bus[0].i2c_rc == 0)
++			hauppauge_eeprom(dev, eeprom+0x80);
++		break;
+ 	case CX23885_BOARD_HAUPPAUGE_HVR1800:
+ 	case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
+ 		if (dev->i2c_bus[0].i2c_rc == 0)
+-			hauppauge_eeprom(dev, eeprom+0x80);
++			hauppauge_eeprom(dev, eeprom+0xc0);
+ 		break;
+ 	}
+ 
+diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
+index 8e40c7b..7f10b27 100644
+--- a/drivers/media/video/cx23885/cx23885-core.c
++++ b/drivers/media/video/cx23885/cx23885-core.c
+@@ -56,137 +56,6 @@ LIST_HEAD(cx23885_devlist);
+ 
+ #define NO_SYNC_LINE (-1U)
+ 
+-/*
+- * CX23885 Assumptions
+- * 1 line = 16 bytes of CDT
+- * cmds size = 80
+- * cdt size = 16 * linesize
+- * iqsize = 64
+- * maxlines = 6
+- *
+- * Address Space:
+- * 0x00000000 0x00008fff FIFO clusters
+- * 0x00010000 0x000104af Channel Management Data Structures
+- * 0x000104b0 0x000104ff Free
+- * 0x00010500 0x000108bf 15 channels * iqsize
+- * 0x000108c0 0x000108ff Free
+- * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables
+- *                       15 channels * (iqsize + (maxlines * linesize))
+- * 0x00010ea0 0x00010xxx Free
+- */
+-
+-static struct sram_channel cx23885_sram_channels[] = {
+-	[SRAM_CH01] = {
+-		.name		= "VID A",
+-		.cmds_start	= 0x10000,
+-		.ctrl_start	= 0x105b0,
+-		.cdt		= 0x107b0,
+-		.fifo_start	= 0x40,
+-		.fifo_size	= 0x2800,
+-		.ptr1_reg	= DMA1_PTR1,
+-		.ptr2_reg	= DMA1_PTR2,
+-		.cnt1_reg	= DMA1_CNT1,
+-		.cnt2_reg	= DMA1_CNT2,
+-		.jumponly	= 1,
+-	},
+-	[SRAM_CH02] = {
+-		.name		= "ch2",
+-		.cmds_start	= 0x0,
+-		.ctrl_start	= 0x0,
+-		.cdt		= 0x0,
+-		.fifo_start	= 0x0,
+-		.fifo_size	= 0x0,
+-		.ptr1_reg	= DMA2_PTR1,
+-		.ptr2_reg	= DMA2_PTR2,
+-		.cnt1_reg	= DMA2_CNT1,
+-		.cnt2_reg	= DMA2_CNT2,
+-	},
+-	[SRAM_CH03] = {
+-		.name		= "TS1 B",
+-		.cmds_start	= 0x100A0,
+-		.ctrl_start	= 0x10630,
+-		.cdt		= 0x10870,
+-		.fifo_start	= 0x5000,
+-		.fifo_size	= 0x1000,
+-		.ptr1_reg	= DMA3_PTR1,
+-		.ptr2_reg	= DMA3_PTR2,
+-		.cnt1_reg	= DMA3_CNT1,
+-		.cnt2_reg	= DMA3_CNT2,
+-	},
+-	[SRAM_CH04] = {
+-		.name		= "ch4",
+-		.cmds_start	= 0x0,
+-		.ctrl_start	= 0x0,
+-		.cdt		= 0x0,
+-		.fifo_start	= 0x0,
+-		.fifo_size	= 0x0,
+-		.ptr1_reg	= DMA4_PTR1,
+-		.ptr2_reg	= DMA4_PTR2,
+-		.cnt1_reg	= DMA4_CNT1,
+-		.cnt2_reg	= DMA4_CNT2,
+-	},
+-	[SRAM_CH05] = {
+-		.name		= "ch5",
+-		.cmds_start	= 0x0,
+-		.ctrl_start	= 0x0,
+-		.cdt		= 0x0,
+-		.fifo_start	= 0x0,
+-		.fifo_size	= 0x0,
+-		.ptr1_reg	= DMA5_PTR1,
+-		.ptr2_reg	= DMA5_PTR2,
+-		.cnt1_reg	= DMA5_CNT1,
+-		.cnt2_reg	= DMA5_CNT2,
+-	},
+-	[SRAM_CH06] = {
+-		.name		= "TS2 C",
+-		.cmds_start	= 0x10140,
+-		.ctrl_start	= 0x10680,
+-		.cdt		= 0x108d0,
+-		.fifo_start	= 0x6000,
+-		.fifo_size	= 0x1000,
+-		.ptr1_reg	= DMA5_PTR1,
+-		.ptr2_reg	= DMA5_PTR2,
+-		.cnt1_reg	= DMA5_CNT1,
+-		.cnt2_reg	= DMA5_CNT2,
+-	},
+-	[SRAM_CH07] = {
+-		.name		= "ch7",
+-		.cmds_start	= 0x0,
+-		.ctrl_start	= 0x0,
+-		.cdt		= 0x0,
+-		.fifo_start	= 0x0,
+-		.fifo_size	= 0x0,
+-		.ptr1_reg	= DMA6_PTR1,
+-		.ptr2_reg	= DMA6_PTR2,
+-		.cnt1_reg	= DMA6_CNT1,
+-		.cnt2_reg	= DMA6_CNT2,
+-	},
+-	[SRAM_CH08] = {
+-		.name		= "ch8",
+-		.cmds_start	= 0x0,
+-		.ctrl_start	= 0x0,
+-		.cdt		= 0x0,
+-		.fifo_start	= 0x0,
+-		.fifo_size	= 0x0,
+-		.ptr1_reg	= DMA7_PTR1,
+-		.ptr2_reg	= DMA7_PTR2,
+-		.cnt1_reg	= DMA7_CNT1,
+-		.cnt2_reg	= DMA7_CNT2,
+-	},
+-	[SRAM_CH09] = {
+-		.name		= "ch9",
+-		.cmds_start	= 0x0,
+-		.ctrl_start	= 0x0,
+-		.cdt		= 0x0,
+-		.fifo_start	= 0x0,
+-		.fifo_size	= 0x0,
+-		.ptr1_reg	= DMA8_PTR1,
+-		.ptr2_reg	= DMA8_PTR2,
+-		.cnt1_reg	= DMA8_CNT1,
+-		.cnt2_reg	= DMA8_CNT2,
+-	},
+-};
+-
+ /* FIXME, these allocations will change when
+  * analog arrives. The be reviewed.
+  * CX23887 Assumptions
+@@ -754,6 +623,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
+ 	atomic_inc(&dev->refcount);
+ 
+ 	dev->nr = cx23885_devcount++;
++	dev->sram_channels = cx23887_sram_channels;
+ 	sprintf(dev->name, "cx23885[%d]", dev->nr);
+ 
+ 	mutex_lock(&devlist);
+@@ -763,13 +633,11 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
+ 	/* Configure the internal memory */
+ 	if(dev->pci->device == 0x8880) {
+ 		dev->bridge = CX23885_BRIDGE_887;
+-		dev->sram_channels = cx23887_sram_channels;
+ 		/* Apply a sensible clock frequency for the PCIe bridge */
+ 		dev->clk_freq = 25000000;
+ 	} else
+ 	if(dev->pci->device == 0x8852) {
+ 		dev->bridge = CX23885_BRIDGE_885;
+-		dev->sram_channels = cx23885_sram_channels;
+ 		/* Apply a sensible clock frequency for the PCIe bridge */
+ 		dev->clk_freq = 28000000;
+ 	} else
+diff --git a/drivers/media/video/v4l2-int-device.c b/drivers/media/video/v4l2-int-device.c
+index a545dca..0e45499 100644
+--- a/drivers/media/video/v4l2-int-device.c
++++ b/drivers/media/video/v4l2-int-device.c
+@@ -156,3 +156,5 @@ int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg)
+ 		find_ioctl(d->u.slave, cmd,
+ 			   (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg);
+ }
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index fe7b5ec..3a0b20a 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -2635,7 +2635,7 @@ config NIU
+ 
+ config PASEMI_MAC
+ 	tristate "PA Semi 1/10Gbit MAC"
+-	depends on PPC64 && PCI
++	depends on PPC_PASEMI && PCI
+ 	select PHYLIB
+ 	select INET_LRO
+ 	help
+diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
+index c993a32..26b2dd5 100644
+--- a/drivers/net/bfin_mac.c
++++ b/drivers/net/bfin_mac.c
+@@ -575,7 +575,6 @@ adjust_head:
+ static int bf537mac_hard_start_xmit(struct sk_buff *skb,
+ 				struct net_device *dev)
+ {
+-	struct bf537mac_local *lp = netdev_priv(dev);
+ 	unsigned int data;
+ 
+ 	current_tx_ptr->skb = skb;
+@@ -634,7 +633,6 @@ out:
+ static void bf537mac_rx(struct net_device *dev)
+ {
+ 	struct sk_buff *skb, *new_skb;
+-	struct bf537mac_local *lp = netdev_priv(dev);
+ 	unsigned short len;
+ 
+ 	/* allocate a new skb for next time receive */
+diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
+index 90a1f31..979c2d0 100644
+--- a/drivers/net/bonding/bond_sysfs.c
++++ b/drivers/net/bonding/bond_sysfs.c
+@@ -341,6 +341,7 @@ static ssize_t bonding_store_slaves(struct device *d,
+ 
+ 	if (command[0] == '-') {
+ 		dev = NULL;
++		original_mtu = 0;
+ 		bond_for_each_slave(bond, slave, i)
+ 			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
+ 				dev = slave->dev;
+diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
+index 6f7e3fd..980c2c2 100644
+--- a/drivers/net/forcedeth.c
++++ b/drivers/net/forcedeth.c
+@@ -1854,6 +1854,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	struct ring_desc* start_tx;
+ 	struct ring_desc* prev_tx;
+ 	struct nv_skb_map* prev_tx_ctx;
++	unsigned long flags;
+ 
+ 	/* add fragments to entries count */
+ 	for (i = 0; i < fragments; i++) {
+@@ -1863,10 +1864,10 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 
+ 	empty_slots = nv_get_empty_tx_slots(np);
+ 	if (unlikely(empty_slots <= entries)) {
+-		spin_lock_irq(&np->lock);
++		spin_lock_irqsave(&np->lock, flags);
+ 		netif_stop_queue(dev);
+ 		np->tx_stop = 1;
+-		spin_unlock_irq(&np->lock);
++		spin_unlock_irqrestore(&np->lock, flags);
+ 		return NETDEV_TX_BUSY;
+ 	}
+ 
+@@ -1929,13 +1930,13 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 		tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ?
+ 			 NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0;
+ 
+-	spin_lock_irq(&np->lock);
++	spin_lock_irqsave(&np->lock, flags);
+ 
+ 	/* set tx flags */
+ 	start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
+ 	np->put_tx.orig = put_tx;
+ 
+-	spin_unlock_irq(&np->lock);
++	spin_unlock_irqrestore(&np->lock, flags);
+ 
+ 	dprintk(KERN_DEBUG "%s: nv_start_xmit: entries %d queued for transmission. tx_flags_extra: %x\n",
+ 		dev->name, entries, tx_flags_extra);
+@@ -1971,6 +1972,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
+ 	struct ring_desc_ex* prev_tx;
+ 	struct nv_skb_map* prev_tx_ctx;
+ 	struct nv_skb_map* start_tx_ctx;
++	unsigned long flags;
+ 
+ 	/* add fragments to entries count */
+ 	for (i = 0; i < fragments; i++) {
+@@ -1980,10 +1982,10 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
+ 
+ 	empty_slots = nv_get_empty_tx_slots(np);
+ 	if (unlikely(empty_slots <= entries)) {
+-		spin_lock_irq(&np->lock);
++		spin_lock_irqsave(&np->lock, flags);
+ 		netif_stop_queue(dev);
+ 		np->tx_stop = 1;
+-		spin_unlock_irq(&np->lock);
++		spin_unlock_irqrestore(&np->lock, flags);
+ 		return NETDEV_TX_BUSY;
+ 	}
+ 
+@@ -2059,7 +2061,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
+ 			start_tx->txvlan = 0;
+ 	}
+ 
+-	spin_lock_irq(&np->lock);
++	spin_lock_irqsave(&np->lock, flags);
+ 
+ 	if (np->tx_limit) {
+ 		/* Limit the number of outstanding tx. Setup all fragments, but
+@@ -2085,7 +2087,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
+ 	start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
+ 	np->put_tx.ex = put_tx;
+ 
+-	spin_unlock_irq(&np->lock);
++	spin_unlock_irqrestore(&np->lock, flags);
+ 
+ 	dprintk(KERN_DEBUG "%s: nv_start_xmit_optimized: entries %d queued for transmission. tx_flags_extra: %x\n",
+ 		dev->name, entries, tx_flags_extra);
+diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
+index 0789802..378a239 100644
+--- a/drivers/net/ibm_newemac/core.c
++++ b/drivers/net/ibm_newemac/core.c
+@@ -1242,8 +1242,8 @@ static int emac_close(struct net_device *ndev)
+ static inline u16 emac_tx_csum(struct emac_instance *dev,
+ 			       struct sk_buff *skb)
+ {
+-	if (emac_has_feature(dev, EMAC_FTR_HAS_TAH &&
+-			     skb->ip_summed == CHECKSUM_PARTIAL)) {
++	if (emac_has_feature(dev, EMAC_FTR_HAS_TAH) &&
++		(skb->ip_summed == CHECKSUM_PARTIAL)) {
+ 		++dev->stats.tx_packets_csum;
+ 		return EMAC_TX_CTRL_TAH_CSUM;
+ 	}
+diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
+index 3c915b8..c082cf0 100644
+--- a/drivers/net/s2io.c
++++ b/drivers/net/s2io.c
+@@ -84,7 +84,7 @@
+ #include "s2io.h"
+ #include "s2io-regs.h"
+ 
+-#define DRV_VERSION "2.0.26.15-2"
++#define DRV_VERSION "2.0.26.20"
+ 
+ /* S2io Driver name & version. */
+ static char s2io_driver_name[] = "Neterion";
+diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
+index 54c6626..853bce0 100644
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -4329,10 +4329,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
+ 	if (!hw)
+ 		return 0;
+ 
++	del_timer_sync(&hw->watchdog_timer);
++	cancel_work_sync(&hw->restart_work);
++
+ 	for (i = 0; i < hw->ports; i++) {
+ 		struct net_device *dev = hw->dev[i];
+ 		struct sky2_port *sky2 = netdev_priv(dev);
+ 
++		netif_device_detach(dev);
+ 		if (netif_running(dev))
+ 			sky2_down(dev);
+ 
+@@ -4383,6 +4387,8 @@ static int sky2_resume(struct pci_dev *pdev)
+ 
+ 	for (i = 0; i < hw->ports; i++) {
+ 		struct net_device *dev = hw->dev[i];
++
++		netif_device_attach(dev);
+ 		if (netif_running(dev)) {
+ 			err = sky2_up(dev);
+ 			if (err) {
+diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
+index 206918b..da2206f 100644
+--- a/drivers/net/tulip/eeprom.c
++++ b/drivers/net/tulip/eeprom.c
+@@ -343,6 +343,12 @@ int __devinit tulip_read_eeprom(struct net_device *dev, int location, int addr_l
+ 	void __iomem *ee_addr = tp->base_addr + CSR9;
+ 	int read_cmd = location | (EE_READ_CMD << addr_len);
+ 
++	/* If location is past the end of what we can address, don't
++	 * read some other location (ie truncate). Just return zero.
++	 */
++	if (location > (1 << addr_len) - 1)
++		return 0;
++
+ 	iowrite32(EE_ENB & ~EE_CS, ee_addr);
+ 	iowrite32(EE_ENB, ee_addr);
+ 
+diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
+index ed600bf..82f404b 100644
+--- a/drivers/net/tulip/tulip_core.c
++++ b/drivers/net/tulip/tulip_core.c
+@@ -1437,6 +1437,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
+ 	   EEPROM.
+ 	   */
+ 	ee_data = tp->eeprom;
++	memset(ee_data, 0, sizeof(tp->eeprom));
+ 	sum = 0;
+ 	if (chip_idx == LC82C168) {
+ 		for (i = 0; i < 3; i++) {
+@@ -1458,8 +1459,12 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
+ 		/* A serial EEPROM interface, we read now and sort it out later. */
+ 		int sa_offset = 0;
+ 		int ee_addr_size = tulip_read_eeprom(dev, 0xff, 8) & 0x40000 ? 8 : 6;
++		int ee_max_addr = ((1 << ee_addr_size) - 1) * sizeof(u16);
+ 
+-		for (i = 0; i < sizeof(tp->eeprom); i+=2) {
++		if (ee_max_addr > sizeof(tp->eeprom))
++			ee_max_addr = sizeof(tp->eeprom);
++
++		for (i = 0; i < ee_max_addr ; i += sizeof(u16)) {
+ 			u16 data = tulip_read_eeprom(dev, i/2, ee_addr_size);
+ 			ee_data[i] = data & 0xff;
+ 			ee_data[i + 1] = data >> 8;
+diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
+index a12c9c4..0604f3f 100644
+--- a/drivers/net/usb/Kconfig
++++ b/drivers/net/usb/Kconfig
+@@ -129,7 +129,7 @@ config USB_USBNET
+ 
+ config USB_NET_AX8817X
+ 	tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
+-	depends on USB_USBNET && NET_ETHERNET
++	depends on USB_USBNET
+ 	select CRC32
+ 	default y
+ 	help
+diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
+index 0343b00..01660f6 100644
+--- a/drivers/net/usb/dm9601.c
++++ b/drivers/net/usb/dm9601.c
+@@ -354,7 +354,7 @@ static void dm9601_set_multicast(struct net_device *net)
+ 		struct dev_mc_list *mc_list = net->mc_list;
+ 		int i;
+ 
+-		for (i = 0; i < net->mc_count; i++) {
++		for (i = 0; i < net->mc_count; i++, mc_list = mc_list->next) {
+ 			u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
+ 			hashes[crc >> 3] |= 1 << (crc & 0x7);
+ 		}
+diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
+index d1ed68a..b588c89 100644
+--- a/drivers/net/usb/pegasus.c
++++ b/drivers/net/usb/pegasus.c
+@@ -1128,12 +1128,8 @@ pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+ {
+ 	pegasus_t *pegasus;
+ 
+-	if (in_atomic())
+-		return 0;
+-
+ 	pegasus = netdev_priv(dev);
+ 	mii_ethtool_gset(&pegasus->mii, ecmd);
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
+index fb37b80..824df3b 100644
+--- a/drivers/net/wan/lapbether.c
++++ b/drivers/net/wan/lapbether.c
+@@ -58,7 +58,7 @@ struct lapbethdev {
+ 	struct net_device_stats stats;		/* some statistics */
+ };
+ 
+-static struct list_head lapbeth_devices = LIST_HEAD_INIT(lapbeth_devices);
++static LIST_HEAD(lapbeth_devices);
+ 
+ /* ------------------------------------------------------------------------ */
+ 
+diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
+index cfbc1a2..948eb1f 100644
+--- a/drivers/net/wireless/b43/dma.c
++++ b/drivers/net/wireless/b43/dma.c
+@@ -619,6 +619,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
+ 	}
+ 
+ 	if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
++		b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
+ 		dev_kfree_skb_any(skb);
+ 		return -EIO;
+ 	}
+@@ -874,8 +875,12 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
+ 						  DMA_TO_DEVICE);
+ 
+ 			if (b43_dma_mapping_error(ring, dma_test,
+-						  b43_txhdr_size(dev), 1))
++						  b43_txhdr_size(dev), 1)) {
++
++				b43err(dev->wl,
++				       "TXHDR DMA allocation failed\n");
+ 				goto err_kfree_txhdr_cache;
++			}
+ 		}
+ 
+ 		dma_unmap_single(dev->dev->dev,
+diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
+index b79a6bd..371e4a1 100644
+--- a/drivers/net/wireless/b43/pcmcia.c
++++ b/drivers/net/wireless/b43/pcmcia.c
+@@ -91,6 +91,8 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
+ 
+ 	dev->conf.ConfigBase = parse.config.base;
+ 	dev->conf.Present = parse.config.rmask[0];
++	dev->conf.Attributes = CONF_ENABLE_IRQ;
++	dev->conf.IntType = INT_MEMORY_AND_IO;
+ 
+ 	dev->io.BasePort2 = 0;
+ 	dev->io.NumPorts2 = 0;
+@@ -112,8 +114,8 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
+ 	if (res != CS_SUCCESS)
+ 		goto err_disable;
+ 
+-	dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED;
+-	dev->irq.IRQInfo1 = IRQ_LEVEL_ID | IRQ_SHARE_ID;
++	dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
++	dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ 	dev->irq.Handler = NULL; /* The handler is registered later. */
+ 	dev->irq.Instance = NULL;
+ 	res = pcmcia_request_irq(dev, &dev->irq);
+diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
+index d727de8..6576757 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
++++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
+@@ -4589,7 +4589,7 @@ static u8 iwl4965_is_fat_tx_allowed(struct iwl4965_priv *priv,
+ 
+ 	if (sta_ht_inf) {
+ 		if ((!sta_ht_inf->ht_supported) ||
+-		   (!sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))
++		   (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH)))
+ 			return 0;
+ 	}
+ 
+diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
+index 5a9cadb..038c66a 100644
+--- a/drivers/net/wireless/libertas/if_cs.c
++++ b/drivers/net/wireless/libertas/if_cs.c
+@@ -677,9 +677,7 @@ sbi_get_int_status_exit:
+ 
+ 	/* Card has a command result for us */
+ 	if (*ireg & IF_CS_C_S_CMD_UPLD_RDY) {
+-		spin_lock(&priv->driver_lock);
+ 		ret = if_cs_receive_cmdres(priv, priv->upld_buf, &priv->upld_len);
+-		spin_unlock(&priv->driver_lock);
+ 		if (ret < 0)
+ 			lbs_pr_err("could not receive cmd from card\n");
+ 	}
+diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
+index bd305f7..e873a39 100644
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -1393,11 +1393,20 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
+ 
+ exit:
+ 	/*
+-	 * Set device mode to sleep for power management.
++	 * Set device mode to sleep for power management,
++	 * on some hardware this call seems to consistently fail.
++	 * From the specifications it is hard to tell why it fails,
++	 * and if this is a "bad thing".
++	 * Overall it is safe to just ignore the failure and
++	 * continue suspending. The only downside is that the
++	 * device will not be in optimal power save mode, but with
++	 * the radio and the other components already disabled the
++	 * device is as good as disabled.
+ 	 */
+ 	retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP);
+ 	if (retval)
+-		return retval;
++		WARNING(rt2x00dev, "Device failed to enter sleep state, "
++			"continue suspending.\n");
+ 
+ 	return 0;
+ }
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+index 880c78b..ed7e0a1 100644
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -218,18 +218,24 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
+ 
+ 	get_device(&shost->shost_gendev);
+ 
+-	if (shost->transportt->host_size &&
+-	    (shost->shost_data = kzalloc(shost->transportt->host_size,
+-					 GFP_KERNEL)) == NULL)
+-		goto out_del_classdev;
++	if (shost->transportt->host_size) {
++		shost->shost_data = kzalloc(shost->transportt->host_size,
++					 GFP_KERNEL);
++		if (shost->shost_data == NULL) {
++			error = -ENOMEM;
++			goto out_del_classdev;
++		}
++	}
+ 
+ 	if (shost->transportt->create_work_queue) {
+ 		snprintf(shost->work_q_name, KOBJ_NAME_LEN, "scsi_wq_%d",
+ 			shost->host_no);
+ 		shost->work_q = create_singlethread_workqueue(
+ 					shost->work_q_name);
+-		if (!shost->work_q)
++		if (!shost->work_q) {
++			error = -EINVAL;
+ 			goto out_free_shost_data;
++		}
+ 	}
+ 
+ 	error = scsi_sysfs_add_host(shost);
+diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
+index 31b9af2..709a6f7 100644
+--- a/drivers/scsi/libsas/sas_discover.c
++++ b/drivers/scsi/libsas/sas_discover.c
+@@ -295,11 +295,14 @@ static void sas_discover_domain(struct work_struct *work)
+ 	case FANOUT_DEV:
+ 		error = sas_discover_root_expander(dev);
+ 		break;
+-#ifdef CONFIG_SCSI_SAS_ATA
+ 	case SATA_DEV:
+ 	case SATA_PM:
++#ifdef CONFIG_SCSI_SAS_ATA
+ 		error = sas_discover_sata(dev);
+ 		break;
++#else
++		SAS_DPRINTK("ATA device seen but CONFIG_SCSI_SAS_ATA=N so cannot attach\n");
++		/* Fall through */
+ #endif
+ 	default:
+ 		error = -ENXIO;
+diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c
+index 5ec0665..e55b903 100644
+--- a/drivers/scsi/mvsas.c
++++ b/drivers/scsi/mvsas.c
+@@ -37,11 +37,13 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/ctype.h>
+ #include <scsi/libsas.h>
++#include <scsi/scsi_tcq.h>
++#include <scsi/sas_ata.h>
+ #include <asm/io.h>
+ 
+ #define DRV_NAME	"mvsas"
+-#define DRV_VERSION	"0.5.1"
+-#define _MV_DUMP 0
++#define DRV_VERSION	"0.5.2"
++#define _MV_DUMP	0
+ #define MVS_DISABLE_NVRAM
+ #define MVS_DISABLE_MSI
+ 
+@@ -52,7 +54,7 @@
+ 	readl(regs + MVS_##reg);		\
+ 	} while (0)
+ 
+-#define MVS_ID_NOT_MAPPED	0xff
++#define MVS_ID_NOT_MAPPED	0x7f
+ #define MVS_CHIP_SLOT_SZ	(1U << mvi->chip->slot_width)
+ 
+ /* offset for D2H FIS in the Received FIS List Structure */
+@@ -84,6 +86,7 @@ enum driver_configuration {
+ 	MVS_RX_FIS_COUNT	= 17,	/* Optional rx'd FISs (max 17) */
+ 
+ 	MVS_QUEUE_SIZE		= 30,	/* Support Queue depth */
++	MVS_CAN_QUEUE		= MVS_SLOTS - 1,	/* SCSI Queue depth */
+ };
+ 
+ /* unchangeable hardware details */
+@@ -358,7 +361,20 @@ enum hw_register_bits {
+ 
+ 	/* VSR */
+ 	/* PHYMODE 6 (CDB) */
+-	PHY_MODE6_DTL_SPEED	= (1U << 27),
++	PHY_MODE6_LATECLK	= (1U << 29),	/* Lock Clock */
++	PHY_MODE6_DTL_SPEED	= (1U << 27),	/* Digital Loop Speed */
++	PHY_MODE6_FC_ORDER	= (1U << 26),	/* Fibre Channel Mode Order*/
++	PHY_MODE6_MUCNT_EN	= (1U << 24),	/* u Count Enable */
++	PHY_MODE6_SEL_MUCNT_LEN	= (1U << 22),	/* Training Length Select */
++	PHY_MODE6_SELMUPI	= (1U << 20),	/* Phase Multi Select (init) */
++	PHY_MODE6_SELMUPF	= (1U << 18),	/* Phase Multi Select (final) */
++	PHY_MODE6_SELMUFF	= (1U << 16),	/* Freq Loop Multi Sel(final) */
++	PHY_MODE6_SELMUFI	= (1U << 14),	/* Freq Loop Multi Sel(init) */
++	PHY_MODE6_FREEZE_LOOP	= (1U << 12),	/* Freeze Rx CDR Loop */
++	PHY_MODE6_INT_RXFOFFS	= (1U << 3),	/* Rx CDR Freq Loop Enable */
++	PHY_MODE6_FRC_RXFOFFS	= (1U << 2),	/* Initial Rx CDR Offset */
++	PHY_MODE6_STAU_0D8	= (1U << 1),	/* Rx CDR Freq Loop Saturate */
++	PHY_MODE6_RXSAT_DIS	= (1U << 0),	/* Saturate Ctl */
+ };
+ 
+ enum mvs_info_flags {
+@@ -511,7 +527,43 @@ enum status_buffer {
+ };
+ 
+ enum error_info_rec {
+-	CMD_ISS_STPD	=  (1U << 31),	/* Cmd Issue Stopped */
++	CMD_ISS_STPD	= (1U << 31),	/* Cmd Issue Stopped */
++	CMD_PI_ERR	= (1U << 30),	/* Protection info error.  see flags2 */
++	RSP_OVER	= (1U << 29),	/* rsp buffer overflow */
++	RETRY_LIM	= (1U << 28),	/* FIS/frame retry limit exceeded */
++	UNK_FIS 	= (1U << 27),	/* unknown FIS */
++	DMA_TERM	= (1U << 26),	/* DMA terminate primitive rx'd */
++	SYNC_ERR	= (1U << 25),	/* SYNC rx'd during frame xmit */
++	TFILE_ERR	= (1U << 24),	/* SATA taskfile Error bit set */
++	R_ERR		= (1U << 23),	/* SATA returned R_ERR prim */
++	RD_OFS		= (1U << 20),	/* Read DATA frame invalid offset */
++	XFER_RDY_OFS	= (1U << 19),	/* XFER_RDY offset error */
++	UNEXP_XFER_RDY	= (1U << 18),	/* unexpected XFER_RDY error */
++	DATA_OVER_UNDER = (1U << 16),	/* data overflow/underflow */
++	INTERLOCK	= (1U << 15),	/* interlock error */
++	NAK		= (1U << 14),	/* NAK rx'd */
++	ACK_NAK_TO	= (1U << 13),	/* ACK/NAK timeout */
++	CXN_CLOSED	= (1U << 12),	/* cxn closed w/out ack/nak */
++	OPEN_TO 	= (1U << 11),	/* I_T nexus lost, open cxn timeout */
++	PATH_BLOCKED	= (1U << 10),	/* I_T nexus lost, pathway blocked */
++	NO_DEST 	= (1U << 9),	/* I_T nexus lost, no destination */
++	STP_RES_BSY	= (1U << 8),	/* STP resources busy */
++	BREAK		= (1U << 7),	/* break received */
++	BAD_DEST	= (1U << 6),	/* bad destination */
++	BAD_PROTO	= (1U << 5),	/* protocol not supported */
++	BAD_RATE	= (1U << 4),	/* cxn rate not supported */
++	WRONG_DEST	= (1U << 3),	/* wrong destination error */
++	CREDIT_TO	= (1U << 2),	/* credit timeout */
++	WDOG_TO 	= (1U << 1),	/* watchdog timeout */
++	BUF_PAR 	= (1U << 0),	/* buffer parity error */
++};
++
++enum error_info_rec_2 {
++	SLOT_BSY_ERR	= (1U << 31),	/* Slot Busy Error */
++	GRD_CHK_ERR	= (1U << 14),	/* Guard Check Error */
++	APP_CHK_ERR	= (1U << 13),	/* Application Check error */
++	REF_CHK_ERR	= (1U << 12),	/* Reference Check Error */
++	USR_BLK_NM	= (1U << 0),	/* User Block Number */
+ };
+ 
+ struct mvs_chip_info {
+@@ -543,28 +595,12 @@ struct mvs_cmd_hdr {
+ 	__le32			reserved[4];
+ };
+ 
+-struct mvs_slot_info {
+-	struct sas_task		*task;
+-	u32			n_elem;
+-	u32			tx;
+-
+-	/* DMA buffer for storing cmd tbl, open addr frame, status buffer,
+-	 * and PRD table
+-	 */
+-	void			*buf;
+-	dma_addr_t		buf_dma;
+-#if _MV_DUMP
+-	u32			cmd_size;
+-#endif
+-
+-	void			*response;
+-};
+-
+ struct mvs_port {
+ 	struct asd_sas_port	sas_port;
+ 	u8			port_attached;
+ 	u8			taskfileset;
+ 	u8			wide_port_phymap;
++	struct list_head	list;
+ };
+ 
+ struct mvs_phy {
+@@ -582,6 +618,27 @@ struct mvs_phy {
+ 	u32		frame_rcvd_size;
+ 	u8		frame_rcvd[32];
+ 	u8		phy_attached;
++	enum sas_linkrate	minimum_linkrate;
++	enum sas_linkrate	maximum_linkrate;
++};
++
++struct mvs_slot_info {
++	struct list_head	list;
++	struct sas_task		*task;
++	u32			n_elem;
++	u32			tx;
++
++	/* DMA buffer for storing cmd tbl, open addr frame, status buffer,
++	 * and PRD table
++	 */
++	void			*buf;
++	dma_addr_t		buf_dma;
++#if _MV_DUMP
++	u32			cmd_size;
++#endif
++
++	void			*response;
++	struct mvs_port		*port;
+ };
+ 
+ struct mvs_info {
+@@ -612,21 +669,14 @@ struct mvs_info {
+ 
+ 	const struct mvs_chip_info *chip;
+ 
+-	unsigned long		tags[MVS_SLOTS];
++	u8			tags[MVS_SLOTS];
+ 	struct mvs_slot_info	slot_info[MVS_SLOTS];
+ 				/* further per-slot information */
+ 	struct mvs_phy		phy[MVS_MAX_PHYS];
+ 	struct mvs_port		port[MVS_MAX_PHYS];
+-
+-	u32			can_queue;	/* per adapter */
+-	u32			tag_out;	/*Get*/
+-	u32			tag_in;		/*Give*/
+-};
+-
+-struct mvs_queue_task {
+-	struct list_head list;
+-
+-	void   *uldd_task;
++#ifdef MVS_USE_TASKLET
++	struct tasklet_struct	tasklet;
++#endif
+ };
+ 
+ static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
+@@ -641,10 +691,11 @@ static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port);
+ static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i);
+ static void mvs_detect_porttype(struct mvs_info *mvi, int i);
+ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st);
++static void mvs_release_task(struct mvs_info *mvi, int phy_no);
+ 
+ static int mvs_scan_finished(struct Scsi_Host *, unsigned long);
+ static void mvs_scan_start(struct Scsi_Host *);
+-static int mvs_sas_slave_alloc(struct scsi_device *scsi_dev);
++static int mvs_slave_configure(struct scsi_device *sdev);
+ 
+ static struct scsi_transport_template *mvs_stt;
+ 
+@@ -659,7 +710,7 @@ static struct scsi_host_template mvs_sht = {
+ 	.name			= DRV_NAME,
+ 	.queuecommand		= sas_queuecommand,
+ 	.target_alloc		= sas_target_alloc,
+-	.slave_configure	= sas_slave_configure,
++	.slave_configure	= mvs_slave_configure,
+ 	.slave_destroy		= sas_slave_destroy,
+ 	.scan_finished		= mvs_scan_finished,
+ 	.scan_start		= mvs_scan_start,
+@@ -674,7 +725,7 @@ static struct scsi_host_template mvs_sht = {
+ 	.use_clustering		= ENABLE_CLUSTERING,
+ 	.eh_device_reset_handler	= sas_eh_device_reset_handler,
+ 	.eh_bus_reset_handler	= sas_eh_bus_reset_handler,
+-	.slave_alloc		= mvs_sas_slave_alloc,
++	.slave_alloc		= sas_slave_alloc,
+ 	.target_destroy		= sas_target_destroy,
+ 	.ioctl			= sas_ioctl,
+ };
+@@ -709,10 +760,10 @@ static void mvs_hexdump(u32 size, u8 *data, u32 baseaddr)
+ 	printk("\n");
+ }
+ 
++#if _MV_DUMP
+ static void mvs_hba_sb_dump(struct mvs_info *mvi, u32 tag,
+ 				   enum sas_protocol proto)
+ {
+-#if _MV_DUMP
+ 	u32 offset;
+ 	struct pci_dev *pdev = mvi->pdev;
+ 	struct mvs_slot_info *slot = &mvi->slot_info[tag];
+@@ -723,14 +774,14 @@ static void mvs_hba_sb_dump(struct mvs_info *mvi, u32 tag,
+ 			tag);
+ 	mvs_hexdump(32, (u8 *) slot->response,
+ 		    (u32) slot->buf_dma + offset);
+-#endif
+ }
++#endif
+ 
+ static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag,
+ 				enum sas_protocol proto)
+ {
+ #if _MV_DUMP
+-	u32 sz, w_ptr, r_ptr;
++	u32 sz, w_ptr;
+ 	u64 addr;
+ 	void __iomem *regs = mvi->regs;
+ 	struct pci_dev *pdev = mvi->pdev;
+@@ -738,12 +789,10 @@ static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag,
+ 
+ 	/*Delivery Queue */
+ 	sz = mr32(TX_CFG) & TX_RING_SZ_MASK;
+-	w_ptr = mr32(TX_PROD_IDX) & TX_RING_SZ_MASK;
+-	r_ptr = mr32(TX_CONS_IDX) & TX_RING_SZ_MASK;
++	w_ptr = slot->tx;
+ 	addr = mr32(TX_HI) << 16 << 16 | mr32(TX_LO);
+ 	dev_printk(KERN_DEBUG, &pdev->dev,
+-		"Delivery Queue Size=%04d , WRT_PTR=%04X , RD_PTR=%04X\n",
+-		sz, w_ptr, r_ptr);
++		"Delivery Queue Size=%04d , WRT_PTR=%04X\n", sz, w_ptr);
+ 	dev_printk(KERN_DEBUG, &pdev->dev,
+ 		"Delivery Queue Base Address=0x%llX (PA)"
+ 		"(tx_dma=0x%llX), Entry=%04d\n",
+@@ -751,11 +800,11 @@ static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag,
+ 	mvs_hexdump(sizeof(u32), (u8 *)(&mvi->tx[mvi->tx_prod]),
+ 			(u32) mvi->tx_dma + sizeof(u32) * w_ptr);
+ 	/*Command List */
+-	addr = mr32(CMD_LIST_HI) << 16 << 16 | mr32(CMD_LIST_LO);
++	addr = mvi->slot_dma;
+ 	dev_printk(KERN_DEBUG, &pdev->dev,
+ 		"Command List Base Address=0x%llX (PA)"
+ 		"(slot_dma=0x%llX), Header=%03d\n",
+-		addr, mvi->slot_dma, tag);
++		addr, slot->buf_dma, tag);
+ 	dev_printk(KERN_DEBUG, &pdev->dev, "Command Header[%03d]:\n", tag);
+ 	/*mvs_cmd_hdr */
+ 	mvs_hexdump(sizeof(struct mvs_cmd_hdr), (u8 *)(&mvi->slot[tag]),
+@@ -779,7 +828,7 @@ static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag,
+ 
+ static void mvs_hba_cq_dump(struct mvs_info *mvi)
+ {
+-#if _MV_DUMP
++#if (_MV_DUMP > 2)
+ 	u64 addr;
+ 	void __iomem *regs = mvi->regs;
+ 	struct pci_dev *pdev = mvi->pdev;
+@@ -788,8 +837,8 @@ static void mvs_hba_cq_dump(struct mvs_info *mvi)
+ 
+ 	/*Completion Queue */
+ 	addr = mr32(RX_HI) << 16 << 16 | mr32(RX_LO);
+-	dev_printk(KERN_DEBUG, &pdev->dev, "Completion Task = 0x%08X\n",
+-		   (u32) mvi->slot_info[rx_desc & RXQ_SLOT_MASK].task);
++	dev_printk(KERN_DEBUG, &pdev->dev, "Completion Task = 0x%p\n",
++		   mvi->slot_info[rx_desc & RXQ_SLOT_MASK].task);
+ 	dev_printk(KERN_DEBUG, &pdev->dev,
+ 		"Completion List Base Address=0x%llX (PA), "
+ 		"CQ_Entry=%04d, CQ_WP=0x%08X\n",
+@@ -854,34 +903,53 @@ static int pci_go_64(struct pci_dev *pdev)
+ 	return rc;
+ }
+ 
++static int mvs_find_tag(struct mvs_info *mvi, struct sas_task *task, u32 *tag)
++{
++	if (task->lldd_task) {
++		struct mvs_slot_info *slot;
++		slot = (struct mvs_slot_info *) task->lldd_task;
++		*tag = slot - mvi->slot_info;
++		return 1;
++	}
++	return 0;
++}
++
+ static void mvs_tag_clear(struct mvs_info *mvi, u32 tag)
+ {
+-	mvi->tag_in = (mvi->tag_in + 1) & (MVS_SLOTS - 1);
+-	mvi->tags[mvi->tag_in] = tag;
++	void *bitmap = (void *) &mvi->tags;
++	clear_bit(tag, bitmap);
+ }
+ 
+ static void mvs_tag_free(struct mvs_info *mvi, u32 tag)
+ {
+-	mvi->tag_out = (mvi->tag_out - 1) & (MVS_SLOTS - 1);
++	mvs_tag_clear(mvi, tag);
++}
++
++static void mvs_tag_set(struct mvs_info *mvi, unsigned int tag)
++{
++	void *bitmap = (void *) &mvi->tags;
++	set_bit(tag, bitmap);
+ }
+ 
+ static int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out)
+ {
+-	if (mvi->tag_out != mvi->tag_in) {
+-		*tag_out = mvi->tags[mvi->tag_out];
+-		mvi->tag_out = (mvi->tag_out + 1) & (MVS_SLOTS - 1);
+-		return 0;
+-	}
+-	return -EBUSY;
++	unsigned int index, tag;
++	void *bitmap = (void *) &mvi->tags;
++
++	index = find_first_zero_bit(bitmap, MVS_SLOTS);
++	tag = index;
++	if (tag >= MVS_SLOTS)
++		return -SAS_QUEUE_FULL;
++	mvs_tag_set(mvi, tag);
++	*tag_out = tag;
++	return 0;
+ }
+ 
+ static void mvs_tag_init(struct mvs_info *mvi)
+ {
+ 	int i;
+ 	for (i = 0; i < MVS_SLOTS; ++i)
+-		mvi->tags[i] = i;
+-	mvi->tag_out = 0;
+-	mvi->tag_in = MVS_SLOTS - 1;
++		mvs_tag_clear(mvi, i);
+ }
+ 
+ #ifndef MVS_DISABLE_NVRAM
+@@ -1013,10 +1081,21 @@ err_out:
+ static void mvs_bytes_dmaed(struct mvs_info *mvi, int i)
+ {
+ 	struct mvs_phy *phy = &mvi->phy[i];
++	struct asd_sas_phy *sas_phy = mvi->sas.sas_phy[i];
+ 
+ 	if (!phy->phy_attached)
+ 		return;
+ 
++	if (sas_phy->phy) {
++		struct sas_phy *sphy = sas_phy->phy;
++
++		sphy->negotiated_linkrate = sas_phy->linkrate;
++		sphy->minimum_linkrate = phy->minimum_linkrate;
++		sphy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
++		sphy->maximum_linkrate = phy->maximum_linkrate;
++		sphy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
++	}
++
+ 	if (phy->phy_type & PORT_TYPE_SAS) {
+ 		struct sas_identify_frame *id;
+ 
+@@ -1053,80 +1132,149 @@ static void mvs_scan_start(struct Scsi_Host *shost)
+ 	}
+ }
+ 
+-static int mvs_sas_slave_alloc(struct scsi_device *scsi_dev)
++static int mvs_slave_configure(struct scsi_device *sdev)
+ {
+-	int rc;
++	struct domain_device *dev = sdev_to_domain_dev(sdev);
++	int ret = sas_slave_configure(sdev);
+ 
+-	rc = sas_slave_alloc(scsi_dev);
++	if (ret)
++		return ret;
+ 
+-	return rc;
++	if (dev_is_sata(dev)) {
++		/* struct ata_port *ap = dev->sata_dev.ap; */
++		/* struct ata_device *adev = ap->link.device; */
++
++		/* clamp at no NCQ for the time being */
++		/* adev->flags |= ATA_DFLAG_NCQ_OFF; */
++		scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, 1);
++	}
++	return 0;
+ }
+ 
+-static void mvs_int_port(struct mvs_info *mvi, int port_no, u32 events)
++static void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
+ {
+ 	struct pci_dev *pdev = mvi->pdev;
+ 	struct sas_ha_struct *sas_ha = &mvi->sas;
+-	struct mvs_phy *phy = &mvi->phy[port_no];
++	struct mvs_phy *phy = &mvi->phy[phy_no];
+ 	struct asd_sas_phy *sas_phy = &phy->sas_phy;
+ 
+-	phy->irq_status = mvs_read_port_irq_stat(mvi, port_no);
++	phy->irq_status = mvs_read_port_irq_stat(mvi, phy_no);
+ 	/*
+ 	* events is port event now ,
+ 	* we need check the interrupt status which belongs to per port.
+ 	*/
+ 	dev_printk(KERN_DEBUG, &pdev->dev,
+ 		"Port %d Event = %X\n",
+-		port_no, phy->irq_status);
++		phy_no, phy->irq_status);
+ 
+ 	if (phy->irq_status & (PHYEV_POOF | PHYEV_DEC_ERR)) {
+-		if (!mvs_is_phy_ready(mvi, port_no)) {
++		mvs_release_task(mvi, phy_no);
++		if (!mvs_is_phy_ready(mvi, phy_no)) {
+ 			sas_phy_disconnected(sas_phy);
+ 			sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL);
++			dev_printk(KERN_INFO, &pdev->dev,
++				"Port %d Unplug Notice\n", phy_no);
++
+ 		} else
+ 			mvs_phy_control(sas_phy, PHY_FUNC_LINK_RESET, NULL);
+ 	}
+ 	if (!(phy->irq_status & PHYEV_DEC_ERR)) {
+ 		if (phy->irq_status & PHYEV_COMWAKE) {
+-			u32 tmp = mvs_read_port_irq_mask(mvi, port_no);
+-			mvs_write_port_irq_mask(mvi, port_no,
++			u32 tmp = mvs_read_port_irq_mask(mvi, phy_no);
++			mvs_write_port_irq_mask(mvi, phy_no,
+ 						tmp | PHYEV_SIG_FIS);
+ 		}
+ 		if (phy->irq_status & (PHYEV_SIG_FIS | PHYEV_ID_DONE)) {
+-			phy->phy_status = mvs_is_phy_ready(mvi, port_no);
++			phy->phy_status = mvs_is_phy_ready(mvi, phy_no);
+ 			if (phy->phy_status) {
+-				mvs_detect_porttype(mvi, port_no);
++				mvs_detect_porttype(mvi, phy_no);
+ 
+ 				if (phy->phy_type & PORT_TYPE_SATA) {
+ 					u32 tmp = mvs_read_port_irq_mask(mvi,
+-								port_no);
++								phy_no);
+ 					tmp &= ~PHYEV_SIG_FIS;
+ 					mvs_write_port_irq_mask(mvi,
+-								port_no, tmp);
++								phy_no, tmp);
+ 				}
+ 
+-				mvs_update_phyinfo(mvi, port_no, 0);
++				mvs_update_phyinfo(mvi, phy_no, 0);
+ 				sas_ha->notify_phy_event(sas_phy,
+ 							PHYE_OOB_DONE);
+-				mvs_bytes_dmaed(mvi, port_no);
++				mvs_bytes_dmaed(mvi, phy_no);
+ 			} else {
+ 				dev_printk(KERN_DEBUG, &pdev->dev,
+ 					"plugin interrupt but phy is gone\n");
+ 				mvs_phy_control(sas_phy, PHY_FUNC_LINK_RESET,
+ 							NULL);
+ 			}
+-		} else if (phy->irq_status & PHYEV_BROAD_CH)
++		} else if (phy->irq_status & PHYEV_BROAD_CH) {
++			mvs_release_task(mvi, phy_no);
+ 			sas_ha->notify_port_event(sas_phy,
+ 						PORTE_BROADCAST_RCVD);
++		}
+ 	}
+-	mvs_write_port_irq_stat(mvi, port_no, phy->irq_status);
++	mvs_write_port_irq_stat(mvi, phy_no, phy->irq_status);
+ }
+ 
+ static void mvs_int_sata(struct mvs_info *mvi)
+ {
+-	/* FIXME */
++	u32 tmp;
++	void __iomem *regs = mvi->regs;
++	tmp = mr32(INT_STAT_SRS);
++	mw32(INT_STAT_SRS, tmp & 0xFFFF);
++}
++
++static void mvs_slot_reset(struct mvs_info *mvi, struct sas_task *task,
++				u32 slot_idx)
++{
++	void __iomem *regs = mvi->regs;
++	struct domain_device *dev = task->dev;
++	struct asd_sas_port *sas_port = dev->port;
++	struct mvs_port *port = mvi->slot_info[slot_idx].port;
++	u32 reg_set, phy_mask;
++
++	if (!sas_protocol_ata(task->task_proto)) {
++		reg_set = 0;
++		phy_mask = (port->wide_port_phymap) ? port->wide_port_phymap :
++				sas_port->phy_mask;
++	} else {
++		reg_set = port->taskfileset;
++		phy_mask = sas_port->phy_mask;
++	}
++	mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | slot_idx |
++					(TXQ_CMD_SLOT_RESET << TXQ_CMD_SHIFT) |
++					(phy_mask << TXQ_PHY_SHIFT) |
++					(reg_set << TXQ_SRS_SHIFT));
++
++	mw32(TX_PROD_IDX, mvi->tx_prod);
++	mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1);
++}
++
++static int mvs_sata_done(struct mvs_info *mvi, struct sas_task *task,
++			u32 slot_idx, int err)
++{
++	struct mvs_port *port = mvi->slot_info[slot_idx].port;
++	struct task_status_struct *tstat = &task->task_status;
++	struct ata_task_resp *resp = (struct ata_task_resp *)tstat->buf;
++	int stat = SAM_GOOD;
++
++	resp->frame_len = sizeof(struct dev_to_host_fis);
++	memcpy(&resp->ending_fis[0],
++	       SATA_RECEIVED_D2H_FIS(port->taskfileset),
++	       sizeof(struct dev_to_host_fis));
++	tstat->buf_valid_size = sizeof(*resp);
++	if (unlikely(err))
++		stat = SAS_PROTO_RESPONSE;
++	return stat;
+ }
+ 
+-static void mvs_slot_free(struct mvs_info *mvi, struct sas_task *task,
++static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc)
++{
++	u32 slot_idx = rx_desc & RXQ_SLOT_MASK;
++	mvs_tag_clear(mvi, slot_idx);
++}
++
++static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task,
+ 			  struct mvs_slot_info *slot, u32 slot_idx)
+ {
+ 	if (!sas_protocol_ata(task->task_proto))
+@@ -1149,38 +1297,58 @@ static void mvs_slot_free(struct mvs_info *mvi, struct sas_task *task,
+ 		/* do nothing */
+ 		break;
+ 	}
+-
++	list_del(&slot->list);
++	task->lldd_task = NULL;
+ 	slot->task = NULL;
+-	mvs_tag_clear(mvi, slot_idx);
++	slot->port = NULL;
+ }
+ 
+-static void mvs_slot_err(struct mvs_info *mvi, struct sas_task *task,
++static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task,
+ 			 u32 slot_idx)
+ {
+ 	struct mvs_slot_info *slot = &mvi->slot_info[slot_idx];
+-	u64 err_dw0 = *(u32 *) slot->response;
+-	void __iomem *regs = mvi->regs;
+-	u32 tmp;
++	u32 err_dw0 = le32_to_cpu(*(u32 *) (slot->response));
++	u32 err_dw1 = le32_to_cpu(*(u32 *) (slot->response + 4));
++	int stat = SAM_CHECK_COND;
+ 
+-	if (err_dw0 & CMD_ISS_STPD)
+-		if (sas_protocol_ata(task->task_proto)) {
+-			tmp = mr32(INT_STAT_SRS);
+-			mw32(INT_STAT_SRS, tmp & 0xFFFF);
+-		}
++	if (err_dw1 & SLOT_BSY_ERR) {
++		stat = SAS_QUEUE_FULL;
++		mvs_slot_reset(mvi, task, slot_idx);
++	}
++	switch (task->task_proto) {
++	case SAS_PROTOCOL_SSP:
++		break;
++	case SAS_PROTOCOL_SMP:
++		break;
++	case SAS_PROTOCOL_SATA:
++	case SAS_PROTOCOL_STP:
++	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
++		if (err_dw0 & TFILE_ERR)
++			stat = mvs_sata_done(mvi, task, slot_idx, 1);
++		break;
++	default:
++		break;
++	}
+ 
+-	mvs_hba_sb_dump(mvi, slot_idx, task->task_proto);
++	mvs_hexdump(16, (u8 *) slot->response, 0);
++	return stat;
+ }
+ 
+-static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc)
++static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
+ {
+ 	u32 slot_idx = rx_desc & RXQ_SLOT_MASK;
+ 	struct mvs_slot_info *slot = &mvi->slot_info[slot_idx];
+ 	struct sas_task *task = slot->task;
+-	struct task_status_struct *tstat = &task->task_status;
+-	struct mvs_port *port = &mvi->port[task->dev->port->id];
++	struct task_status_struct *tstat;
++	struct mvs_port *port;
+ 	bool aborted;
+ 	void *to;
+ 
++	if (unlikely(!task || !task->lldd_task))
++		return -1;
++
++	mvs_hba_cq_dump(mvi);
++
+ 	spin_lock(&task->task_state_lock);
+ 	aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED;
+ 	if (!aborted) {
+@@ -1190,22 +1358,27 @@ static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc)
+ 	}
+ 	spin_unlock(&task->task_state_lock);
+ 
+-	if (aborted)
++	if (aborted) {
++		mvs_slot_task_free(mvi, task, slot, slot_idx);
++		mvs_slot_free(mvi, rx_desc);
+ 		return -1;
++	}
+ 
++	port = slot->port;
++	tstat = &task->task_status;
+ 	memset(tstat, 0, sizeof(*tstat));
+ 	tstat->resp = SAS_TASK_COMPLETE;
+ 
+-
+-	if (unlikely(!port->port_attached)) {
+-		tstat->stat = SAS_PHY_DOWN;
++	if (unlikely(!port->port_attached || flags)) {
++		mvs_slot_err(mvi, task, slot_idx);
++		if (!sas_protocol_ata(task->task_proto))
++			tstat->stat = SAS_PHY_DOWN;
+ 		goto out;
+ 	}
+ 
+ 	/* error info record present */
+-	if ((rx_desc & RXQ_ERR) && (*(u64 *) slot->response)) {
+-		tstat->stat = SAM_CHECK_COND;
+-		mvs_slot_err(mvi, task, slot_idx);
++	if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) {
++		tstat->stat = mvs_slot_err(mvi, task, slot_idx);
+ 		goto out;
+ 	}
+ 
+@@ -1242,21 +1415,7 @@ static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc)
+ 	case SAS_PROTOCOL_SATA:
+ 	case SAS_PROTOCOL_STP:
+ 	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: {
+-			struct ata_task_resp *resp =
+-			    (struct ata_task_resp *)tstat->buf;
+-
+-			if ((rx_desc & (RXQ_DONE | RXQ_ERR | RXQ_ATTN)) ==
+-			    RXQ_DONE)
+-				tstat->stat = SAM_GOOD;
+-			else
+-				tstat->stat = SAM_CHECK_COND;
+-
+-			resp->frame_len = sizeof(struct dev_to_host_fis);
+-			memcpy(&resp->ending_fis[0],
+-			       SATA_RECEIVED_D2H_FIS(port->taskfileset),
+-			       sizeof(struct dev_to_host_fis));
+-			if (resp->ending_fis[2] & ATA_ERR)
+-				mvs_hexdump(16, resp->ending_fis, 0);
++			tstat->stat = mvs_sata_done(mvi, task, slot_idx, 0);
+ 			break;
+ 		}
+ 
+@@ -1266,11 +1425,34 @@ static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc)
+ 	}
+ 
+ out:
+-	mvs_slot_free(mvi, task, slot, slot_idx);
++	mvs_slot_task_free(mvi, task, slot, slot_idx);
++	if (unlikely(tstat->stat != SAS_QUEUE_FULL))
++		mvs_slot_free(mvi, rx_desc);
++
++	spin_unlock(&mvi->lock);
+ 	task->task_done(task);
++	spin_lock(&mvi->lock);
+ 	return tstat->stat;
+ }
+ 
++static void mvs_release_task(struct mvs_info *mvi, int phy_no)
++{
++	struct list_head *pos, *n;
++	struct mvs_slot_info *slot;
++	struct mvs_phy *phy = &mvi->phy[phy_no];
++	struct mvs_port *port = phy->port;
++	u32 rx_desc;
++
++	if (!port)
++		return;
++
++	list_for_each_safe(pos, n, &port->list) {
++		slot = container_of(pos, struct mvs_slot_info, list);
++		rx_desc = (u32) (slot - mvi->slot_info);
++		mvs_slot_complete(mvi, rx_desc, 1);
++	}
++}
++
+ static void mvs_int_full(struct mvs_info *mvi)
+ {
+ 	void __iomem *regs = mvi->regs;
+@@ -1305,40 +1487,43 @@ static int mvs_int_rx(struct mvs_info *mvi, bool self_clear)
+ 	 * we don't have to stall the CPU reading that register.
+ 	 * The actual RX ring is offset by one dword, due to this.
+ 	 */
+-	rx_prod_idx = mr32(RX_CONS_IDX) & RX_RING_SZ_MASK;
+-	if (rx_prod_idx == 0xfff) {	/* h/w hasn't touched RX ring yet */
+-		mvi->rx_cons = 0xfff;
++	rx_prod_idx = mvi->rx_cons;
++	mvi->rx_cons = le32_to_cpu(mvi->rx[0]);
++	if (mvi->rx_cons == 0xfff)	/* h/w hasn't touched RX ring yet */
+ 		return 0;
+-	}
+ 
+ 	/* The CMPL_Q may come late, read from register and try again
+ 	* note: if coalescing is enabled,
+ 	* it will need to read from register every time for sure
+ 	*/
+ 	if (mvi->rx_cons == rx_prod_idx)
+-		return 0;
++		mvi->rx_cons = mr32(RX_CONS_IDX) & RX_RING_SZ_MASK;
+ 
+-	if (mvi->rx_cons == 0xfff)
+-		mvi->rx_cons = MVS_RX_RING_SZ - 1;
++	if (mvi->rx_cons == rx_prod_idx)
++		return 0;
+ 
+ 	while (mvi->rx_cons != rx_prod_idx) {
+ 
+ 		/* increment our internal RX consumer pointer */
+-		mvi->rx_cons = (mvi->rx_cons + 1) & (MVS_RX_RING_SZ - 1);
++		rx_prod_idx = (rx_prod_idx + 1) & (MVS_RX_RING_SZ - 1);
+ 
+-		rx_desc = le32_to_cpu(mvi->rx[mvi->rx_cons + 1]);
+-
+-		mvs_hba_cq_dump(mvi);
++		rx_desc = le32_to_cpu(mvi->rx[rx_prod_idx + 1]);
+ 
+ 		if (likely(rx_desc & RXQ_DONE))
+-			mvs_slot_complete(mvi, rx_desc);
++			mvs_slot_complete(mvi, rx_desc, 0);
+ 		if (rx_desc & RXQ_ATTN) {
+ 			attn = true;
+ 			dev_printk(KERN_DEBUG, &pdev->dev, "ATTN %X\n",
+ 				rx_desc);
+ 		} else if (rx_desc & RXQ_ERR) {
++			if (!(rx_desc & RXQ_DONE))
++				mvs_slot_complete(mvi, rx_desc, 0);
+ 			dev_printk(KERN_DEBUG, &pdev->dev, "RXQ_ERR %X\n",
+ 				rx_desc);
++		} else if (rx_desc & RXQ_SLOT_RESET) {
++			dev_printk(KERN_DEBUG, &pdev->dev, "Slot reset[%X]\n",
++				rx_desc);
++			mvs_slot_free(mvi, rx_desc);
+ 		}
+ 	}
+ 
+@@ -1348,6 +1533,23 @@ static int mvs_int_rx(struct mvs_info *mvi, bool self_clear)
+ 	return 0;
+ }
+ 
++#ifdef MVS_USE_TASKLET
++static void mvs_tasklet(unsigned long data)
++{
++	struct mvs_info *mvi = (struct mvs_info *) data;
++	unsigned long flags;
++
++	spin_lock_irqsave(&mvi->lock, flags);
++
++#ifdef MVS_DISABLE_MSI
++	mvs_int_full(mvi);
++#else
++	mvs_int_rx(mvi, true);
++#endif
++	spin_unlock_irqrestore(&mvi->lock, flags);
++}
++#endif
++
+ static irqreturn_t mvs_interrupt(int irq, void *opaque)
+ {
+ 	struct mvs_info *mvi = opaque;
+@@ -1356,18 +1558,21 @@ static irqreturn_t mvs_interrupt(int irq, void *opaque)
+ 
+ 	stat = mr32(GBL_INT_STAT);
+ 
+-	/* clear CMD_CMPLT ASAP */
+-	mw32_f(INT_STAT, CINT_DONE);
+-
+ 	if (stat == 0 || stat == 0xffffffff)
+ 		return IRQ_NONE;
+ 
++	/* clear CMD_CMPLT ASAP */
++	mw32_f(INT_STAT, CINT_DONE);
++
++#ifndef MVS_USE_TASKLET
+ 	spin_lock(&mvi->lock);
+ 
+ 	mvs_int_full(mvi);
+ 
+ 	spin_unlock(&mvi->lock);
+-
++#else
++	tasklet_schedule(&mvi->tasklet);
++#endif
+ 	return IRQ_HANDLED;
+ }
+ 
+@@ -1376,12 +1581,15 @@ static irqreturn_t mvs_msi_interrupt(int irq, void *opaque)
+ {
+ 	struct mvs_info *mvi = opaque;
+ 
++#ifndef MVS_USE_TASKLET
+ 	spin_lock(&mvi->lock);
+ 
+ 	mvs_int_rx(mvi, true);
+ 
+ 	spin_unlock(&mvi->lock);
+-
++#else
++	tasklet_schedule(&mvi->tasklet);
++#endif
+ 	return IRQ_HANDLED;
+ }
+ #endif
+@@ -1576,15 +1784,19 @@ static u8 mvs_assign_reg_set(struct mvs_info *mvi, struct mvs_port *port)
+ 	return MVS_ID_NOT_MAPPED;
+ }
+ 
+-static u32 mvs_get_ncq_tag(struct sas_task *task)
++static u32 mvs_get_ncq_tag(struct sas_task *task, u32 *tag)
+ {
+-	u32 tag = 0;
+ 	struct ata_queued_cmd *qc = task->uldd_task;
+ 
+-	if (qc)
+-		tag = qc->tag;
++	if (qc) {
++		if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
++			qc->tf.command == ATA_CMD_FPDMA_READ) {
++			*tag = qc->tag;
++			return 1;
++		}
++	}
+ 
+-	return tag;
++	return 0;
+ }
+ 
+ static int mvs_task_prep_ata(struct mvs_info *mvi,
+@@ -1628,11 +1840,9 @@ static int mvs_task_prep_ata(struct mvs_info *mvi,
+ 	hdr->flags = cpu_to_le32(flags);
+ 
+ 	/* FIXME: the low order order 5 bits for the TAG if enable NCQ */
+-	if (task->ata_task.use_ncq) {
+-		hdr->tags = cpu_to_le32(mvs_get_ncq_tag(task));
+-		/*Fill in task file */
+-		task->ata_task.fis.sector_count = hdr->tags << 3;
+-	} else
++	if (task->ata_task.use_ncq && mvs_get_ncq_tag(task, &hdr->tags))
++		task->ata_task.fis.sector_count |= hdr->tags << 3;
++	else
+ 		hdr->tags = cpu_to_le32(tag);
+ 	hdr->data_len = cpu_to_le32(task->total_xfer_len);
+ 
+@@ -1725,13 +1935,16 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi,
+ 	u32 flags;
+ 	u32 resp_len, req_len, i, tag = tei->tag;
+ 	const u32 max_resp_len = SB_RFB_MAX;
++	u8 phy_mask;
+ 
+ 	slot = &mvi->slot_info[tag];
+ 
++	phy_mask = (port->wide_port_phymap) ? port->wide_port_phymap :
++		task->dev->port->phy_mask;
+ 	slot->tx = mvi->tx_prod;
+ 	mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | tag |
+ 				(TXQ_CMD_SSP << TXQ_CMD_SHIFT) |
+-				(port->wide_port_phymap << TXQ_PHY_SHIFT));
++				(phy_mask << TXQ_PHY_SHIFT));
+ 
+ 	flags = MCH_RETRY;
+ 	if (task->ssp_task.enable_first_burst) {
+@@ -1832,22 +2045,32 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags)
+ 	void __iomem *regs = mvi->regs;
+ 	struct mvs_task_exec_info tei;
+ 	struct sas_task *t = task;
++	struct mvs_slot_info *slot;
+ 	u32 tag = 0xdeadbeef, rc, n_elem = 0;
+ 	unsigned long flags;
+ 	u32 n = num, pass = 0;
+ 
+ 	spin_lock_irqsave(&mvi->lock, flags);
+-
+ 	do {
++		dev = t->dev;
+ 		tei.port = &mvi->port[dev->port->id];
+ 
+ 		if (!tei.port->port_attached) {
+-			struct task_status_struct *ts = &t->task_status;
+-			ts->stat = SAS_PHY_DOWN;
+-			t->task_done(t);
+-			rc = 0;
+-			goto exec_exit;
++			if (sas_protocol_ata(t->task_proto)) {
++				rc = SAS_PHY_DOWN;
++				goto out_done;
++			} else {
++				struct task_status_struct *ts = &t->task_status;
++				ts->resp = SAS_TASK_UNDELIVERED;
++				ts->stat = SAS_PHY_DOWN;
++				t->task_done(t);
++				if (n > 1)
++					t = list_entry(t->list.next,
++							struct sas_task, list);
++				continue;
++			}
+ 		}
++
+ 		if (!sas_protocol_ata(t->task_proto)) {
+ 			if (t->num_scatter) {
+ 				n_elem = pci_map_sg(mvi->pdev, t->scatter,
+@@ -1866,9 +2089,10 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags)
+ 		if (rc)
+ 			goto err_out;
+ 
+-		mvi->slot_info[tag].task = t;
+-		mvi->slot_info[tag].n_elem = n_elem;
+-		memset(mvi->slot_info[tag].buf, 0, MVS_SLOT_BUF_SZ);
++		slot = &mvi->slot_info[tag];
++		t->lldd_task = NULL;
++		slot->n_elem = n_elem;
++		memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
+ 		tei.task = t;
+ 		tei.hdr = &mvi->slot[tag];
+ 		tei.tag = tag;
+@@ -1897,28 +2121,26 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags)
+ 		if (rc)
+ 			goto err_out_tag;
+ 
++		slot->task = t;
++		slot->port = tei.port;
++		t->lldd_task = (void *) slot;
++		list_add_tail(&slot->list, &slot->port->list);
+ 		/* TODO: select normal or high priority */
+ 
+ 		spin_lock(&t->task_state_lock);
+ 		t->task_state_flags |= SAS_TASK_AT_INITIATOR;
+ 		spin_unlock(&t->task_state_lock);
+ 
+-		if (n == 1) {
+-			spin_unlock_irqrestore(&mvi->lock, flags);
+-			mw32(TX_PROD_IDX, mvi->tx_prod);
+-		}
+ 		mvs_hba_memory_dump(mvi, tag, t->task_proto);
+ 
+ 		++pass;
+ 		mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1);
+-
+-		if (n == 1)
+-			break;
+-
+-		t = list_entry(t->list.next, struct sas_task, list);
++		if (n > 1)
++			t = list_entry(t->list.next, struct sas_task, list);
+ 	} while (--n);
+ 
+-	return 0;
++	rc = 0;
++	goto out_done;
+ 
+ err_out_tag:
+ 	mvs_tag_free(mvi, tag);
+@@ -1928,7 +2150,7 @@ err_out:
+ 		if (n_elem)
+ 			pci_unmap_sg(mvi->pdev, t->scatter, n_elem,
+ 				     t->data_dir);
+-exec_exit:
++out_done:
+ 	if (pass)
+ 		mw32(TX_PROD_IDX, (mvi->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
+ 	spin_unlock_irqrestore(&mvi->lock, flags);
+@@ -1937,42 +2159,59 @@ exec_exit:
+ 
+ static int mvs_task_abort(struct sas_task *task)
+ {
+-	int rc = 1;
++	int rc;
+ 	unsigned long flags;
+ 	struct mvs_info *mvi = task->dev->port->ha->lldd_ha;
+ 	struct pci_dev *pdev = mvi->pdev;
++	int tag;
+ 
+ 	spin_lock_irqsave(&task->task_state_lock, flags);
+ 	if (task->task_state_flags & SAS_TASK_STATE_DONE) {
+ 		rc = TMF_RESP_FUNC_COMPLETE;
++		spin_unlock_irqrestore(&task->task_state_lock, flags);
+ 		goto out_done;
+ 	}
+ 	spin_unlock_irqrestore(&task->task_state_lock, flags);
+ 
+-	/*FIXME*/
+-	rc = TMF_RESP_FUNC_COMPLETE;
+-
+ 	switch (task->task_proto) {
+ 	case SAS_PROTOCOL_SMP:
+-		dev_printk(KERN_DEBUG, &pdev->dev, "SMP Abort! ");
++		dev_printk(KERN_DEBUG, &pdev->dev, "SMP Abort! \n");
+ 		break;
+ 	case SAS_PROTOCOL_SSP:
+-		dev_printk(KERN_DEBUG, &pdev->dev, "SSP Abort! ");
++		dev_printk(KERN_DEBUG, &pdev->dev, "SSP Abort! \n");
+ 		break;
+ 	case SAS_PROTOCOL_SATA:
+ 	case SAS_PROTOCOL_STP:
+ 	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:{
+-		dev_printk(KERN_DEBUG, &pdev->dev, "STP Abort! "
+-			"Dump D2H FIS: \n");
++		dev_printk(KERN_DEBUG, &pdev->dev, "STP Abort! \n");
++#if _MV_DUMP
++		dev_printk(KERN_DEBUG, &pdev->dev, "Dump D2H FIS: \n");
+ 		mvs_hexdump(sizeof(struct host_to_dev_fis),
+ 				(void *)&task->ata_task.fis, 0);
+ 		dev_printk(KERN_DEBUG, &pdev->dev, "Dump ATAPI Cmd : \n");
+ 		mvs_hexdump(16, task->ata_task.atapi_packet, 0);
++#endif
++		spin_lock_irqsave(&task->task_state_lock, flags);
++		if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET) {
++			/* TODO */
++			;
++		}
++		spin_unlock_irqrestore(&task->task_state_lock, flags);
+ 		break;
+ 	}
+ 	default:
+ 		break;
+ 	}
++
++	if (mvs_find_tag(mvi, task, &tag)) {
++		spin_lock_irqsave(&mvi->lock, flags);
++		mvs_slot_task_free(mvi, task, &mvi->slot_info[tag], tag);
++		spin_unlock_irqrestore(&mvi->lock, flags);
++	}
++	if (!mvs_task_exec(task, 1, GFP_ATOMIC))
++		rc = TMF_RESP_FUNC_COMPLETE;
++	else
++		rc = TMF_RESP_FUNC_FAILED;
+ out_done:
+ 	return rc;
+ }
+@@ -2001,7 +2240,7 @@ static void mvs_free(struct mvs_info *mvi)
+ 				  mvi->rx_fis, mvi->rx_fis_dma);
+ 	if (mvi->rx)
+ 		dma_free_coherent(&mvi->pdev->dev,
+-				  sizeof(*mvi->rx) * MVS_RX_RING_SZ,
++				  sizeof(*mvi->rx) * (MVS_RX_RING_SZ + 1),
+ 				  mvi->rx, mvi->rx_dma);
+ 	if (mvi->slot)
+ 		dma_free_coherent(&mvi->pdev->dev,
+@@ -2109,6 +2348,9 @@ static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev,
+ 		return NULL;
+ 
+ 	spin_lock_init(&mvi->lock);
++#ifdef MVS_USE_TASKLET
++	tasklet_init(&mvi->tasklet, mvs_tasklet, (unsigned long)mvi);
++#endif
+ 	mvi->pdev = pdev;
+ 	mvi->chip = chip;
+ 
+@@ -2132,6 +2374,10 @@ static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev,
+ 		mvs_phy_init(mvi, i);
+ 		arr_phy[i] = &mvi->phy[i].sas_phy;
+ 		arr_port[i] = &mvi->port[i].sas_port;
++		mvi->port[i].taskfileset = MVS_ID_NOT_MAPPED;
++		mvi->port[i].wide_port_phymap = 0;
++		mvi->port[i].port_attached = 0;
++		INIT_LIST_HEAD(&mvi->port[i].list);
+ 	}
+ 
+ 	SHOST_TO_SAS_HA(mvi->shost) = &mvi->sas;
+@@ -2148,9 +2394,10 @@ static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev,
+ 	mvi->sas.sas_phy = arr_phy;
+ 	mvi->sas.sas_port = arr_port;
+ 	mvi->sas.num_phys = chip->n_phy;
+-	mvi->sas.lldd_max_execute_num = MVS_CHIP_SLOT_SZ - 1;
++	mvi->sas.lldd_max_execute_num = 1;
+ 	mvi->sas.lldd_queue_size = MVS_QUEUE_SIZE;
+-	mvi->can_queue = (MVS_CHIP_SLOT_SZ >> 1) - 1;
++	mvi->shost->can_queue = MVS_CAN_QUEUE;
++	mvi->shost->cmd_per_lun = MVS_SLOTS / mvi->sas.num_phys;
+ 	mvi->sas.lldd_ha = mvi;
+ 	mvi->sas.core.shost = mvi->shost;
+ 
+@@ -2203,11 +2450,11 @@ static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev,
+ 	memset(mvi->rx_fis, 0, MVS_RX_FISL_SZ);
+ 
+ 	mvi->rx = dma_alloc_coherent(&pdev->dev,
+-				     sizeof(*mvi->rx) * MVS_RX_RING_SZ,
++				     sizeof(*mvi->rx) * (MVS_RX_RING_SZ + 1),
+ 				     &mvi->rx_dma, GFP_KERNEL);
+ 	if (!mvi->rx)
+ 		goto err_out;
+-	memset(mvi->rx, 0, sizeof(*mvi->rx) * MVS_RX_RING_SZ);
++	memset(mvi->rx, 0, sizeof(*mvi->rx) * (MVS_RX_RING_SZ + 1));
+ 
+ 	mvi->rx[0] = cpu_to_le32(0xfff);
+ 	mvi->rx_cons = 0xfff;
+@@ -2357,7 +2604,7 @@ static void __devinit mvs_phy_hacks(struct mvs_info *mvi)
+ 	mvs_cw32(regs, CMD_SAS_CTL0, tmp);
+ 
+ 	/* workaround for WDTIMEOUT , set to 550 ms */
+-	mvs_cw32(regs, CMD_WD_TIMER, 0xffffff);
++	mvs_cw32(regs, CMD_WD_TIMER, 0x86470);
+ 
+ 	/* not to halt for different port op during wideport link change */
+ 	mvs_cw32(regs, CMD_APP_ERR_CONFIG, 0xffefbf7d);
+@@ -2465,17 +2712,16 @@ static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i)
+ {
+ 	u32 tmp;
+ 	struct mvs_phy *phy = &mvi->phy[i];
+-	struct mvs_port *port;
++	struct mvs_port *port = phy->port;;
+ 
+ 	tmp = mvs_read_phy_ctl(mvi, i);
+ 
+ 	if ((tmp & PHY_READY_MASK) && !(phy->irq_status & PHYEV_POOF)) {
+-		if (!phy->port)
++		if (!port)
+ 			phy->phy_attached = 1;
+ 		return tmp;
+ 	}
+ 
+-	port = phy->port;
+ 	if (port) {
+ 		if (phy->phy_type & PORT_TYPE_SAS) {
+ 			port->wide_port_phymap &= ~(1U << i);
+@@ -2497,7 +2743,7 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i,
+ {
+ 	struct mvs_phy *phy = &mvi->phy[i];
+ 	struct pci_dev *pdev = mvi->pdev;
+-	u32 tmp, j;
++	u32 tmp;
+ 	u64 tmp64;
+ 
+ 	mvs_write_port_cfg_addr(mvi, i, PHYR_IDENTIFY);
+@@ -2524,46 +2770,20 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i,
+ 		sas_phy->linkrate =
+ 			(phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>
+ 				PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET;
+-
+-		/* Updated attached_sas_addr */
+-		mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI);
+-		phy->att_dev_sas_addr =
+-				(u64) mvs_read_port_cfg_data(mvi, i) << 32;
+-
+-		mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO);
+-		phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i);
+-
+-		dev_printk(KERN_DEBUG, &pdev->dev,
+-			"phy[%d] Get Attached Address 0x%llX ,"
+-			" SAS Address 0x%llX\n",
+-			i, phy->att_dev_sas_addr, phy->dev_sas_addr);
+-		dev_printk(KERN_DEBUG, &pdev->dev,
+-			"Rate = %x , type = %d\n",
+-			sas_phy->linkrate, phy->phy_type);
+-
+-#if 1
+-		/*
+-		* If the device is capable of supporting a wide port
+-		* on its phys, it may configure the phys as a wide port.
+-		*/
+-		if (phy->phy_type & PORT_TYPE_SAS)
+-			for (j = 0; j < mvi->chip->n_phy && j != i; ++j) {
+-				if ((mvi->phy[j].phy_attached) &&
+-					(mvi->phy[j].phy_type & PORT_TYPE_SAS))
+-					if (phy->att_dev_sas_addr ==
+-					mvi->phy[j].att_dev_sas_addr - 1) {
+-						phy->att_dev_sas_addr =
+-						mvi->phy[j].att_dev_sas_addr;
+-						break;
+-					}
+-			}
+-
+-#endif
+-
+-		tmp64 = cpu_to_be64(phy->att_dev_sas_addr);
+-		memcpy(sas_phy->attached_sas_addr, &tmp64, SAS_ADDR_SIZE);
++		phy->minimum_linkrate =
++			(phy->phy_status &
++				PHY_MIN_SPP_PHYS_LINK_RATE_MASK) >> 8;
++		phy->maximum_linkrate =
++			(phy->phy_status &
++				PHY_MAX_SPP_PHYS_LINK_RATE_MASK) >> 12;
+ 
+ 		if (phy->phy_type & PORT_TYPE_SAS) {
++			/* Updated attached_sas_addr */
++			mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI);
++			phy->att_dev_sas_addr =
++				(u64) mvs_read_port_cfg_data(mvi, i) << 32;
++			mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO);
++			phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i);
+ 			mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_DEV_INFO);
+ 			phy->att_dev_info = mvs_read_port_cfg_data(mvi, i);
+ 			phy->identify.device_type =
+@@ -2582,6 +2802,7 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i,
+ 		} else if (phy->phy_type & PORT_TYPE_SATA) {
+ 			phy->identify.target_port_protocols = SAS_PROTOCOL_STP;
+ 			if (mvs_is_sig_fis_received(phy->irq_status)) {
++				phy->att_dev_sas_addr = i;	/* temp */
+ 				if (phy_st & PHY_OOB_DTCTD)
+ 					sas_phy->oob_mode = SATA_OOB_MODE;
+ 				phy->frame_rcvd_size =
+@@ -2591,20 +2812,34 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i,
+ 			} else {
+ 				dev_printk(KERN_DEBUG, &pdev->dev,
+ 					"No sig fis\n");
++				phy->phy_type &= ~(PORT_TYPE_SATA);
++				goto out_done;
+ 			}
+ 		}
++		tmp64 = cpu_to_be64(phy->att_dev_sas_addr);
++		memcpy(sas_phy->attached_sas_addr, &tmp64, SAS_ADDR_SIZE);
++
++		dev_printk(KERN_DEBUG, &pdev->dev,
++			"phy[%d] Get Attached Address 0x%llX ,"
++			" SAS Address 0x%llX\n",
++			i, phy->att_dev_sas_addr, phy->dev_sas_addr);
++		dev_printk(KERN_DEBUG, &pdev->dev,
++			"Rate = %x , type = %d\n",
++			sas_phy->linkrate, phy->phy_type);
++
+ 		/* workaround for HW phy decoding error on 1.5g disk drive */
+ 		mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6);
+ 		tmp = mvs_read_port_vsr_data(mvi, i);
+ 		if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>
+ 		     PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET) ==
+ 			SAS_LINK_RATE_1_5_GBPS)
+-			tmp &= ~PHY_MODE6_DTL_SPEED;
++			tmp &= ~PHY_MODE6_LATECLK;
+ 		else
+-			tmp |= PHY_MODE6_DTL_SPEED;
++			tmp |= PHY_MODE6_LATECLK;
+ 		mvs_write_port_vsr_data(mvi, i, tmp);
+ 
+ 	}
++out_done:
+ 	if (get_st)
+ 		mvs_write_port_irq_stat(mvi, i, phy->irq_status);
+ }
+@@ -2629,6 +2864,11 @@ static void mvs_port_formed(struct asd_sas_phy *sas_phy)
+ 	spin_unlock_irqrestore(&mvi->lock, flags);
+ }
+ 
++static int mvs_I_T_nexus_reset(struct domain_device *dev)
++{
++	return TMF_RESP_FUNC_FAILED;
++}
++
+ static int __devinit mvs_hw_init(struct mvs_info *mvi)
+ {
+ 	void __iomem *regs = mvi->regs;
+@@ -2790,13 +3030,12 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi)
+ 	/* enable CMD/CMPL_Q/RESP mode */
+ 	mw32(PCS, PCS_SATA_RETRY | PCS_FIS_RX_EN | PCS_CMD_EN);
+ 
+-	/* re-enable interrupts globally */
+-	mvs_hba_interrupt_enable(mvi);
+-
+ 	/* enable completion queue interrupt */
+-	tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM);
++	tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS);
+ 	mw32(INT_MASK, tmp);
+ 
++	/* Enable SRS interrupt */
++	mw32(INT_MASK_SRS, 0xFF);
+ 	return 0;
+ }
+ 
+@@ -2870,6 +3109,8 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev,
+ 
+ 	mvs_print_info(mvi);
+ 
++	mvs_hba_interrupt_enable(mvi);
++
+ 	scsi_scan_host(mvi->shost);
+ 
+ 	return 0;
+@@ -2915,12 +3156,22 @@ static struct sas_domain_function_template mvs_transport_ops = {
+ 	.lldd_execute_task	= mvs_task_exec,
+ 	.lldd_control_phy	= mvs_phy_control,
+ 	.lldd_abort_task	= mvs_task_abort,
+-	.lldd_port_formed	= mvs_port_formed
++	.lldd_port_formed	= mvs_port_formed,
++	.lldd_I_T_nexus_reset	= mvs_I_T_nexus_reset,
+ };
+ 
+ static struct pci_device_id __devinitdata mvs_pci_table[] = {
+ 	{ PCI_VDEVICE(MARVELL, 0x6320), chip_6320 },
+ 	{ PCI_VDEVICE(MARVELL, 0x6340), chip_6440 },
++	{
++		.vendor 	= PCI_VENDOR_ID_MARVELL,
++		.device 	= 0x6440,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= 0x6480,
++		.class		= 0,
++		.class_mask	= 0,
++		.driver_data	= chip_6480,
++	},
+ 	{ PCI_VDEVICE(MARVELL, 0x6440), chip_6440 },
+ 	{ PCI_VDEVICE(MARVELL, 0x6480), chip_6480 },
+ 
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index b9b09a7..ed83cdb 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -294,7 +294,6 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
+ 	}
+ 
+ 	if (sdev->request_queue) {
+-		bsg_unregister_queue(sdev->request_queue);
+ 		sdev->request_queue->queuedata = NULL;
+ 		/* user context needed to free queue */
+ 		scsi_free_queue(sdev->request_queue);
+@@ -858,6 +857,7 @@ void __scsi_remove_device(struct scsi_device *sdev)
+ 	if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
+ 		return;
+ 
++	bsg_unregister_queue(sdev->request_queue);
+ 	class_device_unregister(&sdev->sdev_classdev);
+ 	transport_remove_device(dev);
+ 	device_del(dev);
+diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
+index d57bf3e..430997e 100644
+--- a/drivers/serial/atmel_serial.c
++++ b/drivers/serial/atmel_serial.c
+@@ -96,6 +96,7 @@
+ 
+  /* PDC registers */
+ #define UART_PUT_PTCR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_PTCR)
++#define UART_GET_TCR(port)      __raw_readl((port)->membase + ATMEL_PDC_TCR)
+ #define UART_GET_PTSR(port)	__raw_readl((port)->membase + ATMEL_PDC_PTSR)
+ 
+ #define UART_PUT_RPR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_RPR)
+@@ -106,6 +107,7 @@
+ 
+ #define UART_PUT_TPR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_TPR)
+ #define UART_PUT_TCR(port,v)	__raw_writel(v, (port)->membase + ATMEL_PDC_TCR)
++#define UART_GET_TCR(port)	__raw_readl((port)->membase + ATMEL_PDC_TCR)
+ 
+ static int (*atmel_open_hook)(struct uart_port *);
+ static void (*atmel_close_hook)(struct uart_port *);
+@@ -562,17 +564,22 @@ static void atmel_tx_dma(struct uart_port *port)
+ 	struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
+ 	int count;
+ 
++	/* nothing left to transmit? */
++	if (UART_GET_TCR(port))
++		return;
++
+ 	xmit->tail += pdc->ofs;
+ 	xmit->tail &= UART_XMIT_SIZE - 1;
+ 
+ 	port->icount.tx += pdc->ofs;
+ 	pdc->ofs = 0;
+ 
+-	if (!uart_circ_empty(xmit)) {
+-		/* more to transmit - setup next transfer */
++	/* more to transmit - setup next transfer */
+ 
+-		/* disable PDC transmit */
+-		UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS);
++	/* disable PDC transmit */
++	UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS);
++
++	if (!uart_circ_empty(xmit)) {
+ 		dma_sync_single_for_device(port->dev,
+ 					   pdc->dma_addr,
+ 					   pdc->dma_size,
+@@ -586,11 +593,6 @@ static void atmel_tx_dma(struct uart_port *port)
+ 		/* re-enable PDC transmit and interrupts */
+ 		UART_PUT_PTCR(port, ATMEL_PDC_TXTEN);
+ 		UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
+-	} else {
+-		/* nothing left to transmit - disable the transmitter */
+-
+-		/* disable PDC transmit */
+-		UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS);
+ 	}
+ 
+ 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+@@ -1274,6 +1276,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)
+ {
+ 	struct uart_port *port = &atmel_ports[co->index].uart;
+ 	unsigned int status, imr;
++	unsigned int pdc_tx;
+ 
+ 	/*
+ 	 * First, save IMR and then disable interrupts
+@@ -1281,6 +1284,10 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)
+ 	imr = UART_GET_IMR(port);
+ 	UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY);
+ 
++	/* Store PDC transmit status and disable it */
++	pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN;
++	UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS);
++
+ 	uart_console_write(port, s, count, atmel_console_putchar);
+ 
+ 	/*
+@@ -1290,6 +1297,11 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)
+ 	do {
+ 		status = UART_GET_CSR(port);
+ 	} while (!(status & ATMEL_US_TXRDY));
++
++	/* Restore PDC transmit status */
++	if (pdc_tx)
++		UART_PUT_PTCR(port, ATMEL_PDC_TXTEN);
++
+ 	/* set interrupts back the way they were */
+ 	UART_PUT_IER(port, imr);
+ }
+diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
+index 40e8240..4e065e5 100644
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -135,8 +135,6 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
+ 		hcd->state = HC_STATE_QUIESCING;
+ 	}
+ 	ehci->command = ehci_readl(ehci, &ehci->regs->command);
+-	if (ehci->reclaim)
+-		end_unlink_async(ehci);
+ 	ehci_work(ehci);
+ 
+ 	/* Unlike other USB host controller types, EHCI doesn't have
+@@ -180,6 +178,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
+ 	ehci_halt (ehci);
+ 	hcd->state = HC_STATE_SUSPENDED;
+ 
++	if (ehci->reclaim)
++		end_unlink_async(ehci);
++
+ 	/* allow remote wakeup */
+ 	mask = INTR_MASK;
+ 	if (!device_may_wakeup(&hcd->self.root_hub->dev))
+diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
+index dd4798e..33f1c1c 100644
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -467,7 +467,7 @@ static void unlink_watchdog_func(unsigned long _ohci)
+ out:
+ 	kfree(seen);
+ 	if (ohci->eds_scheduled)
+-		mod_timer(&ohci->unlink_watchdog, round_jiffies_relative(HZ));
++		mod_timer(&ohci->unlink_watchdog, round_jiffies(jiffies + HZ));
+ done:
+ 	spin_unlock_irqrestore(&ohci->lock, flags);
+ }
+diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
+index 5181732..9c9f3b5 100644
+--- a/drivers/usb/host/ohci-q.c
++++ b/drivers/usb/host/ohci-q.c
+@@ -169,7 +169,7 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
+ 	if (quirk_zfmicro(ohci)
+ 			&& (ed->type == PIPE_INTERRUPT)
+ 			&& !(ohci->eds_scheduled++))
+-		mod_timer(&ohci->unlink_watchdog, round_jiffies_relative(HZ));
++		mod_timer(&ohci->unlink_watchdog, round_jiffies(jiffies + HZ));
+ 	wmb ();
+ 
+ 	/* we care about rm_list when setting CLE/BLE in case the HC was at
+diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
+index da922df..b6b5b2a 100644
+--- a/drivers/usb/misc/usbtest.c
++++ b/drivers/usb/misc/usbtest.c
+@@ -378,6 +378,7 @@ alloc_sglist (int nents, int max, int vary)
+ 	sg = kmalloc (nents * sizeof *sg, GFP_KERNEL);
+ 	if (!sg)
+ 		return NULL;
++	sg_init_table(sg, nents);
+ 
+ 	for (i = 0; i < nents; i++) {
+ 		char		*buf;
+@@ -390,7 +391,7 @@ alloc_sglist (int nents, int max, int vary)
+ 		}
+ 
+ 		/* kmalloc pages are always physically contiguous! */
+-		sg_init_one(&sg[i], buf, size);
++		sg_set_buf(&sg[i], buf, size);
+ 
+ 		switch (pattern) {
+ 		case 0:
+diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
+index f3ca660..324bb61 100644
+--- a/drivers/usb/serial/cp2101.c
++++ b/drivers/usb/serial/cp2101.c
+@@ -75,6 +75,7 @@ static struct usb_device_id id_table [] = {
+ 	{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
+ 	{ USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
+ 	{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
++	{ USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
+ 	{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
+ 	{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
+ 	{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
+diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
+index 8a0d174..74ce8bc 100644
+--- a/drivers/usb/serial/keyspan.h
++++ b/drivers/usb/serial/keyspan.h
+@@ -637,6 +637,7 @@ static struct usb_serial_driver keyspan_pre_device = {
+ 	.description		= "Keyspan - (without firmware)",
+ 	.id_table		= keyspan_pre_ids,
+ 	.num_interrupt_in	= NUM_DONT_CARE,
++	.num_interrupt_out	= NUM_DONT_CARE,
+ 	.num_bulk_in		= NUM_DONT_CARE,
+ 	.num_bulk_out		= NUM_DONT_CARE,
+ 	.num_ports		= 1,
+@@ -651,6 +652,7 @@ static struct usb_serial_driver keyspan_1port_device = {
+ 	.description		= "Keyspan 1 port adapter",
+ 	.id_table		= keyspan_1port_ids,
+ 	.num_interrupt_in	= NUM_DONT_CARE,
++	.num_interrupt_out	= NUM_DONT_CARE,
+ 	.num_bulk_in		= NUM_DONT_CARE,
+ 	.num_bulk_out		= NUM_DONT_CARE,
+ 	.num_ports		= 1,
+@@ -678,6 +680,7 @@ static struct usb_serial_driver keyspan_2port_device = {
+ 	.description		= "Keyspan 2 port adapter",
+ 	.id_table		= keyspan_2port_ids,
+ 	.num_interrupt_in	= NUM_DONT_CARE,
++	.num_interrupt_out	= NUM_DONT_CARE,
+ 	.num_bulk_in		= NUM_DONT_CARE,
+ 	.num_bulk_out		= NUM_DONT_CARE,
+ 	.num_ports		= 2,
+@@ -705,6 +708,7 @@ static struct usb_serial_driver keyspan_4port_device = {
+ 	.description		= "Keyspan 4 port adapter",
+ 	.id_table		= keyspan_4port_ids,
+ 	.num_interrupt_in	= NUM_DONT_CARE,
++	.num_interrupt_out	= NUM_DONT_CARE,
+ 	.num_bulk_in		= NUM_DONT_CARE,
+ 	.num_bulk_out		= NUM_DONT_CARE,
+ 	.num_ports		= 4,
+diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
+index b517f93..e3d241f 100644
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -265,8 +265,8 @@ static struct usb_serial_driver ti_1port_device = {
+ 	.description		= "TI USB 3410 1 port adapter",
+ 	.usb_driver		= &ti_usb_driver,
+ 	.id_table		= ti_id_table_3410,
+-	.num_interrupt_in	= 1,
+-	.num_bulk_in		= 1,
++	.num_interrupt_in	= NUM_DONT_CARE,
++	.num_bulk_in		= NUM_DONT_CARE,
+ 	.num_bulk_out		= 1,
+ 	.num_ports		= 1,
+ 	.attach			= ti_startup,
+diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
+index 22b3f78..c2b01f7 100644
+--- a/drivers/usb/serial/visor.c
++++ b/drivers/usb/serial/visor.c
+@@ -191,7 +191,7 @@ static struct usb_serial_driver handspring_device = {
+ 	.id_table =		id_table,
+ 	.num_interrupt_in =	NUM_DONT_CARE,
+ 	.num_bulk_in =		2,
+-	.num_bulk_out =		2,
++	.num_bulk_out =		NUM_DONT_CARE,
+ 	.num_ports =		2,
+ 	.open =			visor_open,
+ 	.close =		visor_close,
+diff --git a/fs/afs/cell.c b/fs/afs/cell.c
+index 788865d..584bb0f 100644
+--- a/fs/afs/cell.c
++++ b/fs/afs/cell.c
+@@ -138,6 +138,7 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist)
+ 	cell = afs_cell_alloc(name, vllist);
+ 	if (IS_ERR(cell)) {
+ 		_leave(" = %ld", PTR_ERR(cell));
++		up_write(&afs_cells_sem);
+ 		return cell;
+ 	}
+ 
+diff --git a/fs/efs/inode.c b/fs/efs/inode.c
+index 79e19e5..a8e7797 100644
+--- a/fs/efs/inode.c
++++ b/fs/efs/inode.c
+@@ -140,7 +140,7 @@ struct inode *efs_iget(struct super_block *super, unsigned long ino)
+ 	brelse(bh);
+    
+ #ifdef DEBUG
+-	printk(KERN_DEBUG "EFS: read_inode(): inode %lu, extents %d, mode %o\n",
++	printk(KERN_DEBUG "EFS: efs_iget(): inode %lu, extents %d, mode %o\n",
+ 		inode->i_ino, in->numextents, inode->i_mode);
+ #endif
+ 
+diff --git a/include/asm-alpha/current.h b/include/asm-alpha/current.h
+index 8d88a13..094d285 100644
+--- a/include/asm-alpha/current.h
++++ b/include/asm-alpha/current.h
+@@ -3,7 +3,7 @@
+ 
+ #include <linux/thread_info.h>
+ 
+-#define get_current()	(current_thread_info()->task + 0)
++#define get_current()	(current_thread_info()->task)
+ #define current		get_current()
+ 
+ #endif /* _ALPHA_CURRENT_H */
+diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
+index 75a1aff..db351d1 100644
+--- a/include/asm-alpha/dma-mapping.h
++++ b/include/asm-alpha/dma-mapping.h
+@@ -11,7 +11,7 @@
+ #define dma_unmap_single(dev, addr, size, dir)		\
+ 		pci_unmap_single(alpha_gendev_to_pci(dev), addr, size, dir)
+ #define dma_alloc_coherent(dev, size, addr, gfp)	\
+-		pci_alloc_consistent(alpha_gendev_to_pci(dev), size, addr)
++	      __pci_alloc_consistent(alpha_gendev_to_pci(dev), size, addr, gfp)
+ #define dma_free_coherent(dev, size, va, addr)		\
+ 		pci_free_consistent(alpha_gendev_to_pci(dev), size, va, addr)
+ #define dma_map_page(dev, page, off, size, dir)		\
+diff --git a/include/asm-alpha/kvm.h b/include/asm-alpha/kvm.h
+new file mode 100644
+index 0000000..b9daec4
+--- /dev/null
++++ b/include/asm-alpha/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_ALPHA_H
++#define __LINUX_KVM_ALPHA_H
++
++/* alpha does not support KVM */
++
++#endif
+diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
+index d5b10ef..d31fd49 100644
+--- a/include/asm-alpha/pci.h
++++ b/include/asm-alpha/pci.h
+@@ -76,7 +76,13 @@ extern inline void pcibios_penalize_isa_irq(int irq, int active)
+    successful and sets *DMA_ADDRP to the pci side dma address as well,
+    else DMA_ADDRP is undefined.  */
+ 
+-extern void *pci_alloc_consistent(struct pci_dev *, size_t, dma_addr_t *);
++extern void *__pci_alloc_consistent(struct pci_dev *, size_t,
++				    dma_addr_t *, gfp_t);
++static inline void *
++pci_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma)
++{
++	return __pci_alloc_consistent(dev, size, dma, GFP_ATOMIC);
++}
+ 
+ /* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
+    be values that were returned from pci_alloc_consistent.  SIZE must
+diff --git a/include/asm-arm/kvm.h b/include/asm-arm/kvm.h
+new file mode 100644
+index 0000000..cb3c08c
+--- /dev/null
++++ b/include/asm-arm/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_ARM_H
++#define __LINUX_KVM_ARM_H
++
++/* arm does not support KVM */
++
++#endif
+diff --git a/include/asm-avr32/kvm.h b/include/asm-avr32/kvm.h
+new file mode 100644
+index 0000000..8c57770
+--- /dev/null
++++ b/include/asm-avr32/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_AVR32_H
++#define __LINUX_KVM_AVR32_H
++
++/* avr32 does not support KVM */
++
++#endif
+diff --git a/include/asm-blackfin/kvm.h b/include/asm-blackfin/kvm.h
+new file mode 100644
+index 0000000..e3477d7
+--- /dev/null
++++ b/include/asm-blackfin/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_BLACKFIN_H
++#define __LINUX_KVM_BLACKFIN_H
++
++/* blackfin does not support KVM */
++
++#endif
+diff --git a/include/asm-cris/kvm.h b/include/asm-cris/kvm.h
+new file mode 100644
+index 0000000..c860f51
+--- /dev/null
++++ b/include/asm-cris/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_CRIS_H
++#define __LINUX_KVM_CRIS_H
++
++/* cris does not support KVM */
++
++#endif
+diff --git a/include/asm-frv/kvm.h b/include/asm-frv/kvm.h
+new file mode 100644
+index 0000000..9c8a4f0
+--- /dev/null
++++ b/include/asm-frv/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_FRV_H
++#define __LINUX_KVM_FRV_H
++
++/* frv does not support KVM */
++
++#endif
+diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
+index fd9dcfd..92a6d91 100644
+--- a/include/asm-generic/Kbuild.asm
++++ b/include/asm-generic/Kbuild.asm
+@@ -1,3 +1,5 @@
++header-y  += kvm.h
++
+ ifeq ($(wildcard include/asm-$(SRCARCH)/a.out.h),include/asm-$(SRCARCH)/a.out.h)
+ unifdef-y += a.out.h
+ endif
+diff --git a/include/asm-h8300/kvm.h b/include/asm-h8300/kvm.h
+new file mode 100644
+index 0000000..bdbed7b
+--- /dev/null
++++ b/include/asm-h8300/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_H8300_H
++#define __LINUX_KVM_H8300_H
++
++/* h8300 does not support KVM */
++
++#endif
+diff --git a/include/asm-ia64/kvm.h b/include/asm-ia64/kvm.h
+new file mode 100644
+index 0000000..030d29b
+--- /dev/null
++++ b/include/asm-ia64/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_IA64_H
++#define __LINUX_KVM_IA64_H
++
++/* ia64 does not support KVM */
++
++#endif
+diff --git a/include/asm-m32r/kvm.h b/include/asm-m32r/kvm.h
+new file mode 100644
+index 0000000..99a4051
+--- /dev/null
++++ b/include/asm-m32r/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_M32R_H
++#define __LINUX_KVM_M32R_H
++
++/* m32r does not support KVM */
++
++#endif
+diff --git a/include/asm-m68k/kvm.h b/include/asm-m68k/kvm.h
+new file mode 100644
+index 0000000..7ed27fc
+--- /dev/null
++++ b/include/asm-m68k/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_M68K_H
++#define __LINUX_KVM_M68K_H
++
++/* m68k does not support KVM */
++
++#endif
+diff --git a/include/asm-m68knommu/kvm.h b/include/asm-m68knommu/kvm.h
+new file mode 100644
+index 0000000..b49d425
+--- /dev/null
++++ b/include/asm-m68knommu/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_M68KNOMMU_H
++#define __LINUX_KVM_M68KNOMMU_H
++
++/* m68knommu does not support KVM */
++
++#endif
+diff --git a/include/asm-mips/kvm.h b/include/asm-mips/kvm.h
+new file mode 100644
+index 0000000..093a5b7
+--- /dev/null
++++ b/include/asm-mips/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_MIPS_H
++#define __LINUX_KVM_MIPS_H
++
++/* mips does not support KVM */
++
++#endif
+diff --git a/include/asm-mn10300/kvm.h b/include/asm-mn10300/kvm.h
+new file mode 100644
+index 0000000..f6b609f
+--- /dev/null
++++ b/include/asm-mn10300/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_MN10300_H
++#define __LINUX_KVM_MN10300_H
++
++/* mn10300 does not support KVM */
++
++#endif
+diff --git a/include/asm-parisc/kvm.h b/include/asm-parisc/kvm.h
+new file mode 100644
+index 0000000..00cc458
+--- /dev/null
++++ b/include/asm-parisc/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_PARISC_H
++#define __LINUX_KVM_PARISC_H
++
++/* parisc does not support KVM */
++
++#endif
+diff --git a/include/asm-powerpc/kvm.h b/include/asm-powerpc/kvm.h
+new file mode 100644
+index 0000000..d1b530f
+--- /dev/null
++++ b/include/asm-powerpc/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_POWERPC_H
++#define __LINUX_KVM_POWERPC_H
++
++/* powerpc does not support KVM */
++
++#endif
+diff --git a/include/asm-s390/kvm.h b/include/asm-s390/kvm.h
+new file mode 100644
+index 0000000..573f2a3
+--- /dev/null
++++ b/include/asm-s390/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_S390_H
++#define __LINUX_KVM_S390_H
++
++/* s390 does not support KVM */
++
++#endif
+diff --git a/include/asm-sh/kvm.h b/include/asm-sh/kvm.h
+new file mode 100644
+index 0000000..6af51db
+--- /dev/null
++++ b/include/asm-sh/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_SH_H
++#define __LINUX_KVM_SH_H
++
++/* sh does not support KVM */
++
++#endif
+diff --git a/include/asm-sparc/kvm.h b/include/asm-sparc/kvm.h
+new file mode 100644
+index 0000000..2e5478d
+--- /dev/null
++++ b/include/asm-sparc/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_SPARC_H
++#define __LINUX_KVM_SPARC_H
++
++/* sparc does not support KVM */
++
++#endif
+diff --git a/include/asm-sparc64/kvm.h b/include/asm-sparc64/kvm.h
+new file mode 100644
+index 0000000..380537a
+--- /dev/null
++++ b/include/asm-sparc64/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_SPARC64_H
++#define __LINUX_KVM_SPARC64_H
++
++/* sparc64 does not support KVM */
++
++#endif
+diff --git a/include/asm-um/kvm.h b/include/asm-um/kvm.h
+new file mode 100644
+index 0000000..66aa770
+--- /dev/null
++++ b/include/asm-um/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_UM_H
++#define __LINUX_KVM_UM_H
++
++/* um does not support KVM */
++
++#endif
+diff --git a/include/asm-v850/kvm.h b/include/asm-v850/kvm.h
+new file mode 100644
+index 0000000..3f729b7
+--- /dev/null
++++ b/include/asm-v850/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_V850_H
++#define __LINUX_KVM_V850_H
++
++/* v850 does not support KVM */
++
++#endif
+diff --git a/include/asm-xtensa/kvm.h b/include/asm-xtensa/kvm.h
+new file mode 100644
+index 0000000..bda4e33
+--- /dev/null
++++ b/include/asm-xtensa/kvm.h
+@@ -0,0 +1,6 @@
++#ifndef __LINUX_KVM_XTENSA_H
++#define __LINUX_KVM_XTENSA_H
++
++/* xtensa does not support KVM */
++
++#endif
+diff --git a/include/linux/Kbuild b/include/linux/Kbuild
+index 4a446a1..9cdd12a 100644
+--- a/include/linux/Kbuild
++++ b/include/linux/Kbuild
+@@ -253,7 +253,7 @@ unifdef-y += kd.h
+ unifdef-y += kernelcapi.h
+ unifdef-y += kernel.h
+ unifdef-y += keyboard.h
+-unifdef-$(CONFIG_HAVE_KVM) += kvm.h
++unifdef-y += kvm.h
+ unifdef-y += llc.h
+ unifdef-y += loop.h
+ unifdef-y += lp.h
+diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h
+index 1b4ccf2..cac4b36 100644
+--- a/include/linux/iocontext.h
++++ b/include/linux/iocontext.h
+@@ -2,6 +2,7 @@
+ #define IOCONTEXT_H
+ 
+ #include <linux/radix-tree.h>
++#include <linux/rcupdate.h>
+ 
+ /*
+  * This is the per-process anticipatory I/O scheduler state.
+@@ -54,6 +55,8 @@ struct cfq_io_context {
+ 
+ 	void (*dtor)(struct io_context *); /* destructor */
+ 	void (*exit)(struct io_context *); /* called on task exit */
++
++	struct rcu_head rcu_head;
+ };
+ 
+ /*
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index a2f0032..ee81906 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -383,9 +383,11 @@ static inline void __napi_complete(struct napi_struct *n)
+ 
+ static inline void napi_complete(struct napi_struct *n)
+ {
+-	local_irq_disable();
++	unsigned long flags;
++
++	local_irq_save(flags);
+ 	__napi_complete(n);
+-	local_irq_enable();
++	local_irq_restore(flags);
+ }
+ 
+ /**
+@@ -1072,12 +1074,14 @@ static inline int netif_is_multiqueue(const struct net_device *dev)
+ }
+ 
+ /* Use this variant when it is known for sure that it
+- * is executing from interrupt context.
++ * is executing from hardware interrupt context or with hardware interrupts
++ * disabled.
+  */
+ extern void dev_kfree_skb_irq(struct sk_buff *skb);
+ 
+ /* Use this variant in places where it could be invoked
+- * either from interrupt or non-interrupt context.
++ * from either hardware interrupt or other context, with hardware interrupts
++ * either disabled or enabled.
+  */
+ extern void dev_kfree_skb_any(struct sk_buff *skb);
+ 
+diff --git a/include/net/llc.h b/include/net/llc.h
+index f502458..7940da1 100644
+--- a/include/net/llc.h
++++ b/include/net/llc.h
+@@ -65,7 +65,6 @@ struct llc_sap {
+ 
+ extern struct list_head llc_sap_list;
+ extern rwlock_t llc_sap_list_lock;
+-extern unsigned char llc_station_mac_sa[ETH_ALEN];
+ 
+ extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
+ 		   struct packet_type *pt, struct net_device *orig_dev);
+diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h
+index 4a8f58b..75b8e29 100644
+--- a/include/net/llc_pdu.h
++++ b/include/net/llc_pdu.h
+@@ -381,7 +381,7 @@ static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
+ 	xid_info->fmt_id = LLC_XID_FMT_ID;	/* 0x81 */
+ 	xid_info->type	 = svcs_supported;
+ 	xid_info->rw	 = rx_window << 1;	/* size of receive window */
+-	skb_put(skb, 3);
++	skb_put(skb, sizeof(struct llc_xid_info));
+ }
+ 
+ /**
+@@ -406,7 +406,7 @@ static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb,
+ 	xid_info->fmt_id = LLC_XID_FMT_ID;
+ 	xid_info->type	 = svcs_supported;
+ 	xid_info->rw	 = rx_window << 1;
+-	skb_put(skb, 3);
++	skb_put(skb, sizeof(struct llc_xid_info));
+ }
+ 
+ /* LLC Type 2 FRMR response information field format */
+diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h
+index 2c56dbe..ed25bec 100644
+--- a/include/net/llc_sap.h
++++ b/include/net/llc_sap.h
+@@ -1,5 +1,8 @@
+ #ifndef LLC_SAP_H
+ #define LLC_SAP_H
++
++#include <asm/types.h>
++
+ /*
+  * Copyright (c) 1997 by Procom Technology,Inc.
+  * 		 2001-2003 by Arnaldo Carvalho de Melo <acme at conectiva.com.br>
+@@ -19,8 +22,8 @@ struct sock;
+ extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
+ extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb,
+ 			       unsigned char prim);
+-extern struct sk_buff *llc_alloc_frame(struct sock *sk,
+-				       struct net_device *dev);
++extern struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
++				       u8 type, u32 data_size);
+ 
+ extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
+ 				        struct sk_buff *skb,
+diff --git a/kernel/marker.c b/kernel/marker.c
+index 041c33e..005b959 100644
+--- a/kernel/marker.c
++++ b/kernel/marker.c
+@@ -671,6 +671,9 @@ int marker_probe_register(const char *name, const char *format,
+ 	entry->rcu_pending = 1;
+ 	/* write rcu_pending before calling the RCU callback */
+ 	smp_wmb();
++#ifdef CONFIG_PREEMPT_RCU
++	synchronize_sched();	/* Until we have the call_rcu_sched() */
++#endif
+ 	call_rcu(&entry->rcu, free_old_closure);
+ end:
+ 	mutex_unlock(&markers_mutex);
+@@ -714,6 +717,9 @@ int marker_probe_unregister(const char *name,
+ 	entry->rcu_pending = 1;
+ 	/* write rcu_pending before calling the RCU callback */
+ 	smp_wmb();
++#ifdef CONFIG_PREEMPT_RCU
++	synchronize_sched();	/* Until we have the call_rcu_sched() */
++#endif
+ 	call_rcu(&entry->rcu, free_old_closure);
+ 	remove_marker(name);	/* Ignore busy error message */
+ 	ret = 0;
+@@ -792,6 +798,9 @@ int marker_probe_unregister_private_data(marker_probe_func *probe,
+ 	entry->rcu_pending = 1;
+ 	/* write rcu_pending before calling the RCU callback */
+ 	smp_wmb();
++#ifdef CONFIG_PREEMPT_RCU
++	synchronize_sched();	/* Until we have the call_rcu_sched() */
++#endif
+ 	call_rcu(&entry->rcu, free_old_closure);
+ 	remove_marker(entry->name);	/* Ignore busy error message */
+ end:
+diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
+index dbc81b9..b33410a 100644
+--- a/net/8021q/vlan.c
++++ b/net/8021q/vlan.c
+@@ -374,17 +374,35 @@ static void vlan_sync_address(struct net_device *dev,
+ 	memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
+ }
+ 
++static void __vlan_device_event(struct net_device *dev, unsigned long event)
++{
++	switch (event) {
++	case NETDEV_CHANGENAME:
++		vlan_proc_rem_dev(dev);
++		if (vlan_proc_add_dev(dev) < 0)
++			pr_warning("8021q: failed to change proc name for %s\n",
++					dev->name);
++		break;
++	}
++}
++
+ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
+ 			     void *ptr)
+ {
+ 	struct net_device *dev = ptr;
+-	struct vlan_group *grp = __vlan_find_group(dev->ifindex);
++	struct vlan_group *grp;
+ 	int i, flgs;
+ 	struct net_device *vlandev;
+ 
+ 	if (dev->nd_net != &init_net)
+ 		return NOTIFY_DONE;
+ 
++	if (is_vlan_dev(dev)) {
++		__vlan_device_event(dev, event);
++		goto out;
++	}
++
++	grp = __vlan_find_group(dev->ifindex);
+ 	if (!grp)
+ 		goto out;
+ 
+diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
+index 73efcc7..51271ae 100644
+--- a/net/8021q/vlan.h
++++ b/net/8021q/vlan.h
+@@ -45,4 +45,9 @@ void vlan_netlink_fini(void);
+ 
+ extern struct rtnl_link_ops vlan_link_ops;
+ 
++static inline int is_vlan_dev(struct net_device *dev)
++{
++	return dev->priv_flags & IFF_802_1Q_VLAN;
++}
++
+ #endif /* !(__BEN_VLAN_802_1Q_INC__) */
+diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
+index 146cfb0..9671aa5 100644
+--- a/net/8021q/vlanproc.c
++++ b/net/8021q/vlanproc.c
+@@ -210,11 +210,6 @@ int vlan_proc_rem_dev(struct net_device *vlandev)
+  * The following few functions build the content of /proc/net/vlan/config
+  */
+ 
+-static inline int is_vlan_dev(struct net_device *dev)
+-{
+-	return dev->priv_flags & IFF_802_1Q_VLAN;
+-}
+-
+ /* start read of /proc/net/vlan/config */
+ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
+ 	__acquires(dev_base_lock)
+diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
+index 1220d8a..d366423 100644
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -53,6 +53,30 @@
+ /* Bluetooth sockets */
+ #define BT_MAX_PROTO	8
+ static struct net_proto_family *bt_proto[BT_MAX_PROTO];
++
++static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
++static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
++static const char *bt_key_strings[BT_MAX_PROTO] = {
++	"sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
++	"sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
++	"sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
++	"sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
++	"sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
++	"sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
++	"sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
++	"sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
++};
++
++static const char *bt_slock_key_strings[BT_MAX_PROTO] = {
++	"slock-AF_BLUETOOTH-BTPROTO_L2CAP",
++	"slock-AF_BLUETOOTH-BTPROTO_HCI",
++	"slock-AF_BLUETOOTH-BTPROTO_SCO",
++	"slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
++	"slock-AF_BLUETOOTH-BTPROTO_BNEP",
++	"slock-AF_BLUETOOTH-BTPROTO_CMTP",
++	"slock-AF_BLUETOOTH-BTPROTO_HIDP",
++	"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
++};
+ static DEFINE_RWLOCK(bt_proto_lock);
+ 
+ int bt_sock_register(int proto, struct net_proto_family *ops)
+@@ -95,6 +119,21 @@ int bt_sock_unregister(int proto)
+ }
+ EXPORT_SYMBOL(bt_sock_unregister);
+ 
++static void bt_reclassify_sock_lock(struct socket *sock, int proto)
++{
++	struct sock *sk = sock->sk;
++
++	if (!sk)
++		return;
++	BUG_ON(sock_owned_by_user(sk));
++
++	sock_lock_init_class_and_name(sk,
++			bt_slock_key_strings[proto],
++			&bt_slock_key[proto],
++			bt_key_strings[proto],
++			&bt_lock_key[proto]);
++}
++
+ static int bt_sock_create(struct net *net, struct socket *sock, int proto)
+ {
+ 	int err;
+@@ -117,6 +156,7 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto)
+ 
+ 	if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
+ 		err = bt_proto[proto]->create(net, sock, proto);
++		bt_reclassify_sock_lock(sock, proto);
+ 		module_put(bt_proto[proto]->owner);
+ 	}
+ 
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index b5d4019..1d36c09 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -84,7 +84,7 @@ static struct hci_sec_filter hci_sec_filter = {
+ };
+ 
+ static struct bt_sock_list hci_sk_list = {
+-	.lock = RW_LOCK_UNLOCKED
++	.lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
+ };
+ 
+ /* Send frame to RAW socket */
+diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
+index 34f8bf9..2957df4 100644
+--- a/net/bluetooth/l2cap.c
++++ b/net/bluetooth/l2cap.c
+@@ -62,7 +62,7 @@ static u32 l2cap_feat_mask = 0x0000;
+ static const struct proto_ops l2cap_sock_ops;
+ 
+ static struct bt_sock_list l2cap_sk_list = {
+-	.lock = RW_LOCK_UNLOCKED
++	.lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
+ };
+ 
+ static void __l2cap_sock_close(struct sock *sk, int reason);
+diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
+index 0c2c937..eb62558 100644
+--- a/net/bluetooth/rfcomm/core.c
++++ b/net/bluetooth/rfcomm/core.c
+@@ -423,8 +423,8 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
+ 
+ 		rfcomm_dlc_lock(d);
+ 		d->state = BT_CLOSED;
+-		d->state_change(d, err);
+ 		rfcomm_dlc_unlock(d);
++		d->state_change(d, err);
+ 
+ 		skb_queue_purge(&d->tx_queue);
+ 		rfcomm_dlc_unlink(d);
+diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
+index c46d510..af4e393 100644
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -60,7 +60,7 @@
+ static const struct proto_ops rfcomm_sock_ops;
+ 
+ static struct bt_sock_list rfcomm_sk_list = {
+-	.lock = RW_LOCK_UNLOCKED
++	.lock = __RW_LOCK_UNLOCKED(rfcomm_sk_list.lock)
+ };
+ 
+ static void rfcomm_sock_close(struct sock *sk);
+diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
+index e4c779b..c3f749a 100644
+--- a/net/bluetooth/rfcomm/tty.c
++++ b/net/bluetooth/rfcomm/tty.c
+@@ -570,12 +570,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
+ 					return;
+ 
+ 				rfcomm_dev_del(dev);
+-				/* We have to drop DLC lock here, otherwise
+-				   rfcomm_dev_put() will dead lock if it's
+-				   the last reference. */
+-				rfcomm_dlc_unlock(dlc);
+ 				rfcomm_dev_put(dev);
+-				rfcomm_dlc_lock(dlc);
+ 			}
+ 		} else
+ 			tty_hangup(dev->tty);
+diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
+index b91d3c8..cd887cd 100644
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -58,7 +58,7 @@
+ static const struct proto_ops sco_sock_ops;
+ 
+ static struct bt_sock_list sco_sk_list = {
+-	.lock = RW_LOCK_UNLOCKED
++	.lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock)
+ };
+ 
+ static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
+diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
+index f3ceca3..4e73e57 100644
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -336,7 +336,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
+ 	struct scatterlist *asg;
+ 	int err = -EINVAL;
+ 
+-	if (!pskb_may_pull(skb, sizeof(*esph)))
++	if (!pskb_may_pull(skb, sizeof(*esph) + crypto_aead_ivsize(aead)))
+ 		goto out;
+ 
+ 	if (elen <= 0)
+diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
+index 724d69a..a0a3c78 100644
+--- a/net/ipv4/inet_fragment.c
++++ b/net/ipv4/inet_fragment.c
+@@ -86,7 +86,10 @@ EXPORT_SYMBOL(inet_frags_fini);
+ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
+ {
+ 	nf->low_thresh = 0;
++
++	local_bh_disable();
+ 	inet_frag_evictor(nf, f);
++	local_bh_enable();
+ }
+ EXPORT_SYMBOL(inet_frags_exit_net);
+ 
+diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
+index 0b3b328..a4506c8 100644
+--- a/net/ipv4/ip_forward.c
++++ b/net/ipv4/ip_forward.c
+@@ -85,7 +85,7 @@ int ip_forward(struct sk_buff *skb)
+ 	if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
+ 		goto sr_failed;
+ 
+-	if (unlikely(skb->len > dst_mtu(&rt->u.dst) &&
++	if (unlikely(skb->len > dst_mtu(&rt->u.dst) && !skb_is_gso(skb) &&
+ 		     (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) {
+ 		IP_INC_STATS(IPSTATS_MIB_FRAGFAILS);
+ 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
+index fe05da4..4dc1628 100644
+--- a/net/ipv4/netfilter/ip_queue.c
++++ b/net/ipv4/netfilter/ip_queue.c
+@@ -588,11 +588,9 @@ static int __init ip_queue_init(void)
+ 	}
+ 
+ #ifdef CONFIG_PROC_FS
+-	proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
+-	if (proc) {
+-		proc->owner = THIS_MODULE;
+-		proc->proc_fops = &ip_queue_proc_fops;
+-	} else {
++	proc = proc_create(IPQ_PROC_FS_NAME, 0, init_net.proc_net,
++			   &ip_queue_proc_fops);
++	if (!proc) {
+ 		printk(KERN_ERR "ip_queue: failed to create proc entry\n");
+ 		goto cleanup_ipqnl;
+ 	}
+diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+index c6cf84c..52926c8 100644
+--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+@@ -167,14 +167,13 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip,
+ 
+ 		/* create proc dir entry */
+ 		sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip));
+-		c->pde = create_proc_entry(buffer, S_IWUSR|S_IRUSR,
+-					   clusterip_procdir);
++		c->pde = proc_create(buffer, S_IWUSR|S_IRUSR,
++				     clusterip_procdir, &clusterip_proc_fops);
+ 		if (!c->pde) {
+ 			kfree(c);
+ 			return NULL;
+ 		}
+ 	}
+-	c->pde->proc_fops = &clusterip_proc_fops;
+ 	c->pde->data = c;
+ #endif
+ 
+diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
+index 8e8f042..50e0669 100644
+--- a/net/ipv4/netfilter/ipt_recent.c
++++ b/net/ipv4/netfilter/ipt_recent.c
+@@ -276,12 +276,11 @@ recent_mt_check(const char *tablename, const void *ip,
+ 	for (i = 0; i < ip_list_hash_size; i++)
+ 		INIT_LIST_HEAD(&t->iphash[i]);
+ #ifdef CONFIG_PROC_FS
+-	t->proc = create_proc_entry(t->name, ip_list_perms, proc_dir);
++	t->proc = proc_create(t->name, ip_list_perms, proc_dir, &recent_fops);
+ 	if (t->proc == NULL) {
+ 		kfree(t);
+ 		goto out;
+ 	}
+-	t->proc->proc_fops = &recent_fops;
+ 	t->proc->uid       = ip_list_uid;
+ 	t->proc->gid       = ip_list_gid;
+ 	t->proc->data      = t;
+diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+index 089252e..f500b0f 100644
+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+@@ -395,13 +395,10 @@ int __init nf_conntrack_ipv4_compat_init(void)
+ 	if (!proc_exp)
+ 		goto err2;
+ 
+-	proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, init_net.proc_net_stat);
++	proc_stat = proc_create("ip_conntrack", S_IRUGO,
++				init_net.proc_net_stat, &ct_cpu_seq_fops);
+ 	if (!proc_stat)
+ 		goto err3;
+-
+-	proc_stat->proc_fops = &ct_cpu_seq_fops;
+-	proc_stat->owner = THIS_MODULE;
+-
+ 	return 0;
+ 
+ err3:
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 7ea1b67..1704c14 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1556,14 +1556,14 @@ static void *udp_seq_start(struct seq_file *seq, loff_t *pos)
+ 	__acquires(udp_hash_lock)
+ {
+ 	read_lock(&udp_hash_lock);
+-	return *pos ? udp_get_idx(seq, *pos-1) : (void *)1;
++	return *pos ? udp_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
+ }
+ 
+ static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ 	struct sock *sk;
+ 
+-	if (v == (void *)1)
++	if (v == SEQ_START_TOKEN)
+ 		sk = udp_get_idx(seq, 0);
+ 	else
+ 		sk = udp_get_next(seq, v);
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 101e0e7..e7a1882 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -776,6 +776,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
+ 	struct inet6_dev *idev = ifp->idev;
+ 	struct in6_addr addr, *tmpaddr;
+ 	unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp;
++	unsigned long regen_advance;
+ 	int tmp_plen;
+ 	int ret = 0;
+ 	int max_addresses;
+@@ -836,8 +837,23 @@ retry:
+ 	tmp_tstamp = ifp->tstamp;
+ 	spin_unlock_bh(&ifp->lock);
+ 
++	regen_advance = idev->cnf.regen_max_retry *
++	                idev->cnf.dad_transmits *
++	                idev->nd_parms->retrans_time / HZ;
+ 	write_unlock(&idev->lock);
+ 
++	/* A temporary address is created only if this calculated Preferred
++	 * Lifetime is greater than REGEN_ADVANCE time units.  In particular,
++	 * an implementation must not create a temporary address with a zero
++	 * Preferred Lifetime.
++	 */
++	if (tmp_prefered_lft <= regen_advance) {
++		in6_ifa_put(ifp);
++		in6_dev_put(idev);
++		ret = -1;
++		goto out;
++	}
++
+ 	addr_flags = IFA_F_TEMPORARY;
+ 	/* set in addrconf_prefix_rcv() */
+ 	if (ifp->flags & IFA_F_OPTIMISTIC)
+@@ -1831,6 +1847,9 @@ ok:
+ 				 * lifetimes of an existing temporary address
+ 				 * when processing a Prefix Information Option.
+ 				 */
++				if (ifp != ift->ifpub)
++					continue;
++
+ 				spin_lock(&ift->lock);
+ 				flags = ift->flags;
+ 				if (ift->valid_lft > valid_lft &&
+diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
+index 0ec1402..c6bb4c6 100644
+--- a/net/ipv6/esp6.c
++++ b/net/ipv6/esp6.c
+@@ -282,7 +282,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
+ 	struct scatterlist *sg;
+ 	struct scatterlist *asg;
+ 
+-	if (!pskb_may_pull(skb, sizeof(*esph))) {
++	if (!pskb_may_pull(skb, sizeof(*esph) + crypto_aead_ivsize(aead))) {
+ 		ret = -EINVAL;
+ 		goto out;
+ 	}
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
+index 121d517..f204a72 100644
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -436,10 +436,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
+ 	}
+ 
+ 	if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6))
+-		goto out;
++		goto out_dst_release;
+ 
+ 	if (ip6_dst_lookup(sk, &dst2, &fl))
+-		goto out;
++		goto out_dst_release;
+ 
+ 	err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP);
+ 	if (err == -ENOENT) {
+diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
+index 178aebc..98ab4f4 100644
+--- a/net/ipv6/ip6_input.c
++++ b/net/ipv6/ip6_input.c
+@@ -239,8 +239,7 @@ int ip6_mc_input(struct sk_buff *skb)
+ 	IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
+ 
+ 	hdr = ipv6_hdr(skb);
+-	deliver = unlikely(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) ||
+-	    ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
++	deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
+ 
+ 	/*
+ 	 *	IPv6 multicast router mode isnt currently supported.
+diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
+index cc2f9af..8d366f7 100644
+--- a/net/ipv6/netfilter/ip6_queue.c
++++ b/net/ipv6/netfilter/ip6_queue.c
+@@ -591,11 +591,9 @@ static int __init ip6_queue_init(void)
+ 	}
+ 
+ #ifdef CONFIG_PROC_FS
+-	proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
+-	if (proc) {
+-		proc->owner = THIS_MODULE;
+-		proc->proc_fops = &ip6_queue_proc_fops;
+-	} else {
++	proc = proc_create(IPQ_PROC_FS_NAME, 0, init_net.proc_net,
++			   &ip6_queue_proc_fops);
++	if (!proc) {
+ 		printk(KERN_ERR "ip6_queue: failed to create proc entry\n");
+ 		goto cleanup_ipqnl;
+ 	}
+diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
+index 2a0d698..24c0d03 100644
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
+@@ -171,7 +171,9 @@ static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
+ 
+ static void nf_ct_frag6_evictor(void)
+ {
++	local_bh_disable();
+ 	inet_frag_evictor(&nf_init_frags, &nf_frags);
++	local_bh_enable();
+ }
+ 
+ static void nf_ct_frag6_expire(unsigned long data)
+diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
+index 46cf962..8c50eb4 100644
+--- a/net/llc/af_llc.c
++++ b/net/llc/af_llc.c
+@@ -155,6 +155,9 @@ static int llc_ui_create(struct net *net, struct socket *sock, int protocol)
+ 	struct sock *sk;
+ 	int rc = -ESOCKTNOSUPPORT;
+ 
++	if (!capable(CAP_NET_RAW))
++		return -EPERM;
++
+ 	if (net != &init_net)
+ 		return -EAFNOSUPPORT;
+ 
+diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
+index 860140c..71a0022 100644
+--- a/net/llc/llc_c_ac.c
++++ b/net/llc/llc_c_ac.c
+@@ -198,7 +198,7 @@ int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -223,7 +223,7 @@ int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -249,7 +249,7 @@ int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -282,7 +282,8 @@ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
+ 		llc_pdu_decode_pf_bit(skb, &f_bit);
+ 	else
+ 		f_bit = 0;
+-	nskb = llc_alloc_frame(sk, llc->dev);
++	nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U,
++			       sizeof(struct llc_frmr_info));
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+ 
+@@ -306,7 +307,8 @@ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U,
++					       sizeof(struct llc_frmr_info));
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -336,7 +338,8 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
+ 	struct llc_sock *llc = llc_sk(sk);
+ 
+ 	llc_pdu_decode_pf_bit(skb, &f_bit);
+-	nskb = llc_alloc_frame(sk, llc->dev);
++	nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U,
++			       sizeof(struct llc_frmr_info));
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+ 		struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+@@ -424,7 +427,7 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
+ 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -459,7 +462,7 @@ int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -483,7 +486,7 @@ int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -507,7 +510,7 @@ int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -531,7 +534,7 @@ int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -555,7 +558,7 @@ int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -579,7 +582,7 @@ int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -615,7 +618,7 @@ int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -639,7 +642,7 @@ int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -663,7 +666,7 @@ int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -688,7 +691,7 @@ int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -712,7 +715,7 @@ int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -736,7 +739,7 @@ int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -770,7 +773,7 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+@@ -799,7 +802,7 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
+ 	u8 f_bit;
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
+ 
+ 	llc_pdu_decode_pf_bit(skb, &f_bit);
+ 	if (nskb) {
+@@ -956,7 +959,7 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
+ {
+ 	int rc = -ENOBUFS;
+ 	struct llc_sock *llc = llc_sk(sk);
+-	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
++	struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
+ 
+ 	if (nskb) {
+ 		struct llc_sap *sap = llc->sap;
+diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c
+index 248b590..50d5b10 100644
+--- a/net/llc/llc_core.c
++++ b/net/llc/llc_core.c
+@@ -25,8 +25,6 @@
+ LIST_HEAD(llc_sap_list);
+ DEFINE_RWLOCK(llc_sap_list_lock);
+ 
+-unsigned char llc_station_mac_sa[ETH_ALEN];
+-
+ /**
+  *	llc_sap_alloc - allocates and initializes sap.
+  *
+@@ -37,8 +35,8 @@ static struct llc_sap *llc_sap_alloc(void)
+ 	struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC);
+ 
+ 	if (sap) {
++		/* sap->laddr.mac - leave as a null, it's filled by bind */
+ 		sap->state = LLC_SAP_STATE_ACTIVE;
+-		memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
+ 		rwlock_init(&sap->sk_list.lock);
+ 		atomic_set(&sap->refcnt, 1);
+ 	}
+@@ -167,10 +165,6 @@ static int __init llc_init(void)
+ 	if (dev != NULL)
+ 		dev = next_net_device(dev);
+ 
+-	if (dev != NULL)
+-		memcpy(llc_station_mac_sa, dev->dev_addr, ETH_ALEN);
+-	else
+-		memset(llc_station_mac_sa, 0, ETH_ALEN);
+ 	dev_add_pack(&llc_packet_type);
+ 	dev_add_pack(&llc_tr_packet_type);
+ 	return 0;
+@@ -185,7 +179,6 @@ static void __exit llc_exit(void)
+ module_init(llc_init);
+ module_exit(llc_exit);
+ 
+-EXPORT_SYMBOL(llc_station_mac_sa);
+ EXPORT_SYMBOL(llc_sap_list);
+ EXPORT_SYMBOL(llc_sap_list_lock);
+ EXPORT_SYMBOL(llc_sap_find);
+diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c
+index c40c9b2..bfd2567 100644
+--- a/net/llc/llc_input.c
++++ b/net/llc/llc_input.c
+@@ -117,8 +117,12 @@ static inline int llc_fixup_skb(struct sk_buff *skb)
+ 	skb_pull(skb, llc_len);
+ 	if (skb->protocol == htons(ETH_P_802_2)) {
+ 		__be16 pdulen = eth_hdr(skb)->h_proto;
+-		u16 data_size = ntohs(pdulen) - llc_len;
++		s32 data_size = ntohs(pdulen) - llc_len;
+ 
++		if (data_size < 0 ||
++		    ((skb_tail_pointer(skb) -
++		      (u8 *)pdu) - llc_len) < data_size)
++			return 0;
+ 		if (unlikely(pskb_trim_rcsum(skb, data_size)))
+ 			return 0;
+ 	}
+diff --git a/net/llc/llc_pdu.c b/net/llc/llc_pdu.c
+index fa83243..2e6cb79 100644
+--- a/net/llc/llc_pdu.c
++++ b/net/llc/llc_pdu.c
+@@ -241,7 +241,7 @@ void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
+ 	FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw);
+ 	FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw);
+ 	FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw);
+-	skb_put(skb, 5);
++	skb_put(skb, sizeof(struct llc_frmr_info));
+ }
+ 
+ /**
+diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
+index ac3d93b..a94bd56 100644
+--- a/net/llc/llc_s_ac.c
++++ b/net/llc/llc_s_ac.c
+@@ -103,7 +103,8 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
+ 	llc_pdu_decode_sa(skb, mac_da);
+ 	llc_pdu_decode_da(skb, mac_sa);
+ 	llc_pdu_decode_ssap(skb, &dsap);
+-	nskb = llc_alloc_frame(NULL, skb->dev);
++	nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
++			       sizeof(struct llc_xid_info));
+ 	if (!nskb)
+ 		goto out;
+ 	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
+@@ -144,11 +145,15 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
+ 	u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
+ 	struct sk_buff *nskb;
+ 	int rc = 1;
++	u32 data_size;
+ 
+ 	llc_pdu_decode_sa(skb, mac_da);
+ 	llc_pdu_decode_da(skb, mac_sa);
+ 	llc_pdu_decode_ssap(skb, &dsap);
+-	nskb = llc_alloc_frame(NULL, skb->dev);
++
++	/* The test request command is type U (llc_len = 3) */
++	data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
++	nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
+ 	if (!nskb)
+ 		goto out;
+ 	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
+diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
+index 2525165..e2ddde7 100644
+--- a/net/llc/llc_sap.c
++++ b/net/llc/llc_sap.c
+@@ -24,20 +24,41 @@
+ #include <net/tcp_states.h>
+ #include <linux/llc.h>
+ 
++static int llc_mac_header_len(unsigned short devtype)
++{
++	switch (devtype) {
++	case ARPHRD_ETHER:
++	case ARPHRD_LOOPBACK:
++		return sizeof(struct ethhdr);
++#ifdef CONFIG_TR
++	case ARPHRD_IEEE802_TR:
++		return sizeof(struct trh_hdr);
++#endif
++	}
++	return 0;
++}
++
+ /**
+  *	llc_alloc_frame - allocates sk_buff for frame
+  *	@dev: network device this skb will be sent over
++ *	@type: pdu type to allocate
++ *	@data_size: data size to allocate
+  *
+  *	Allocates an sk_buff for frame and initializes sk_buff fields.
+  *	Returns allocated skb or %NULL when out of memory.
+  */
+-struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev)
++struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
++				u8 type, u32 data_size)
+ {
+-	struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
++	int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
++	struct sk_buff *skb;
++
++	hlen += llc_mac_header_len(dev->type);
++	skb = alloc_skb(hlen + data_size, GFP_ATOMIC);
+ 
+ 	if (skb) {
+ 		skb_reset_mac_header(skb);
+-		skb_reserve(skb, 50);
++		skb_reserve(skb, hlen);
+ 		skb_reset_network_header(skb);
+ 		skb_reset_transport_header(skb);
+ 		skb->protocol = htons(ETH_P_802_2);
+diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c
+index 6f2ea20..83da133 100644
+--- a/net/llc/llc_station.c
++++ b/net/llc/llc_station.c
+@@ -253,13 +253,14 @@ static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb)
+ static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
+ {
+ 	int rc = 1;
+-	struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
++	struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
++					       sizeof(struct llc_xid_info));
+ 
+ 	if (!nskb)
+ 		goto out;
+ 	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
+ 	llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
+-	rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa);
++	rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, skb->dev->dev_addr);
+ 	if (unlikely(rc))
+ 		goto free;
+ 	llc_station_send_pdu(nskb);
+@@ -274,7 +275,8 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
+ {
+ 	u8 mac_da[ETH_ALEN], dsap;
+ 	int rc = 1;
+-	struct sk_buff* nskb = llc_alloc_frame(NULL, skb->dev);
++	struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
++					       sizeof(struct llc_xid_info));
+ 
+ 	if (!nskb)
+ 		goto out;
+@@ -283,7 +285,7 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
+ 	llc_pdu_decode_ssap(skb, &dsap);
+ 	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
+ 	llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
+-	rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
++	rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
+ 	if (unlikely(rc))
+ 		goto free;
+ 	llc_station_send_pdu(nskb);
+@@ -298,7 +300,12 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
+ {
+ 	u8 mac_da[ETH_ALEN], dsap;
+ 	int rc = 1;
+-	struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
++	u32 data_size;
++	struct sk_buff *nskb;
++
++	/* The test request command is type U (llc_len = 3) */
++	data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
++	nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
+ 
+ 	if (!nskb)
+ 		goto out;
+@@ -307,7 +314,7 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
+ 	llc_pdu_decode_ssap(skb, &dsap);
+ 	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
+ 	llc_pdu_init_as_test_rsp(nskb, skb);
+-	rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
++	rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
+ 	if (unlikely(rc))
+ 		goto free;
+ 	llc_station_send_pdu(nskb);
+diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
+index 28bcdf9..8e58639 100644
+--- a/net/mac80211/ieee80211.c
++++ b/net/mac80211/ieee80211.c
+@@ -286,6 +286,18 @@ static int ieee80211_open(struct net_device *dev)
+ 	if (need_hw_reconfig)
+ 		ieee80211_hw_config(local);
+ 
++	/*
++	 * ieee80211_sta_work is disabled while network interface
++	 * is down. Therefore, some configuration changes may not
++	 * yet be effective. Trigger execution of ieee80211_sta_work
++	 * to fix this.
++	 */
++	if(sdata->vif.type == IEEE80211_IF_TYPE_STA ||
++	   sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
++		struct ieee80211_if_sta *ifsta = &sdata->u.sta;
++		queue_work(local->hw.workqueue, &ifsta->work);
++	}
++
+ 	netif_start_queue(dev);
+ 
+ 	return 0;
+diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
+index 9aeed53..e0c72d0 100644
+--- a/net/mac80211/ieee80211_sta.c
++++ b/net/mac80211/ieee80211_sta.c
+@@ -319,7 +319,7 @@ static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
+ 	struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
+ 	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
+ 	bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
+-	bool preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0;
++	bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;
+ 	DECLARE_MAC_BUF(mac);
+ 	u32 changed = 0;
+ 
+@@ -335,16 +335,15 @@ static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
+ 		changed |= BSS_CHANGED_ERP_CTS_PROT;
+ 	}
+ 
+-	if (preamble_mode != bss_conf->use_short_preamble) {
++	if (use_short_preamble != bss_conf->use_short_preamble) {
+ 		if (net_ratelimit()) {
+ 			printk(KERN_DEBUG "%s: switched to %s barker preamble"
+ 			       " (BSSID=%s)\n",
+ 			       sdata->dev->name,
+-			       (preamble_mode == WLAN_ERP_PREAMBLE_SHORT) ?
+-					"short" : "long",
++			       use_short_preamble ? "short" : "long",
+ 			       print_mac(mac, ifsta->bssid));
+ 		}
+-		bss_conf->use_short_preamble = preamble_mode;
++		bss_conf->use_short_preamble = use_short_preamble;
+ 		changed |= BSS_CHANGED_ERP_PREAMBLE;
+ 	}
+ 
+diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
+index e88e96a..8599068 100644
+--- a/net/netfilter/nf_conntrack_standalone.c
++++ b/net/netfilter/nf_conntrack_standalone.c
+@@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(nf_ct_log_invalid);
+ static int __init nf_conntrack_standalone_init(void)
+ {
+ #ifdef CONFIG_PROC_FS
+-	struct proc_dir_entry *proc, *proc_stat;
++	struct proc_dir_entry *proc;
+ #endif
+ 	int ret = 0;
+ 
+@@ -407,12 +407,9 @@ static int __init nf_conntrack_standalone_init(void)
+ 	proc = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops);
+ 	if (!proc) goto cleanup_init;
+ 
+-	proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, init_net.proc_net_stat);
+-	if (!proc_stat)
++	if (!proc_create("nf_conntrack", S_IRUGO,
++			 init_net.proc_net_stat, &ct_cpu_seq_fops))
+ 		goto cleanup_proc;
+-
+-	proc_stat->proc_fops = &ct_cpu_seq_fops;
+-	proc_stat->owner = THIS_MODULE;
+ #endif
+ #ifdef CONFIG_SYSCTL
+ 	nf_ct_sysctl_header = register_sysctl_paths(nf_ct_path,
+diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
+index cec9976..bc11d70 100644
+--- a/net/netfilter/nf_log.c
++++ b/net/netfilter/nf_log.c
+@@ -168,13 +168,9 @@ static const struct file_operations nflog_file_ops = {
+ int __init netfilter_log_init(void)
+ {
+ #ifdef CONFIG_PROC_FS
+-	struct proc_dir_entry *pde;
+-
+-	pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter);
+-	if (!pde)
++	if (!proc_create("nf_log", S_IRUGO,
++			 proc_net_netfilter, &nflog_file_ops))
+ 		return -1;
+-
+-	pde->proc_fops = &nflog_file_ops;
+ #endif
+ 	return 0;
+ }
+diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
+index ddc80ea..bbd2689 100644
+--- a/net/netfilter/nf_queue.c
++++ b/net/netfilter/nf_queue.c
+@@ -348,12 +348,9 @@ static const struct file_operations nfqueue_file_ops = {
+ int __init netfilter_queue_init(void)
+ {
+ #ifdef CONFIG_PROC_FS
+-	struct proc_dir_entry *pde;
+-
+-	pde = create_proc_entry("nf_queue", S_IRUGO, proc_net_netfilter);
+-	if (!pde)
++	if (!proc_create("nf_queue", S_IRUGO,
++			 proc_net_netfilter, &nfqueue_file_ops))
+ 		return -1;
+-	pde->proc_fops = &nfqueue_file_ops;
+ #endif
+ 	return 0;
+ }
+diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
+index bf3f19b..b8173af 100644
+--- a/net/netfilter/nfnetlink_log.c
++++ b/net/netfilter/nfnetlink_log.c
+@@ -923,9 +923,6 @@ static const struct file_operations nful_file_ops = {
+ static int __init nfnetlink_log_init(void)
+ {
+ 	int i, status = -ENOMEM;
+-#ifdef CONFIG_PROC_FS
+-	struct proc_dir_entry *proc_nful;
+-#endif
+ 
+ 	for (i = 0; i < INSTANCE_BUCKETS; i++)
+ 		INIT_HLIST_HEAD(&instance_table[i]);
+@@ -943,11 +940,9 @@ static int __init nfnetlink_log_init(void)
+ 	}
+ 
+ #ifdef CONFIG_PROC_FS
+-	proc_nful = create_proc_entry("nfnetlink_log", 0440,
+-				      proc_net_netfilter);
+-	if (!proc_nful)
++	if (!proc_create("nfnetlink_log", 0440,
++			 proc_net_netfilter, &nful_file_ops))
+ 		goto cleanup_subsys;
+-	proc_nful->proc_fops = &nful_file_ops;
+ #endif
+ 	return status;
+ 
+diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
+index 012cb69..10522c0 100644
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -896,9 +896,6 @@ static const struct file_operations nfqnl_file_ops = {
+ static int __init nfnetlink_queue_init(void)
+ {
+ 	int i, status = -ENOMEM;
+-#ifdef CONFIG_PROC_FS
+-	struct proc_dir_entry *proc_nfqueue;
+-#endif
+ 
+ 	for (i = 0; i < INSTANCE_BUCKETS; i++)
+ 		INIT_HLIST_HEAD(&instance_table[i]);
+@@ -911,11 +908,9 @@ static int __init nfnetlink_queue_init(void)
+ 	}
+ 
+ #ifdef CONFIG_PROC_FS
+-	proc_nfqueue = create_proc_entry("nfnetlink_queue", 0440,
+-					 proc_net_netfilter);
+-	if (!proc_nfqueue)
++	if (!proc_create("nfnetlink_queue", 0440,
++			 proc_net_netfilter, &nfqnl_file_ops))
+ 		goto cleanup_subsys;
+-	proc_nfqueue->proc_fops = &nfqnl_file_ops;
+ #endif
+ 
+ 	register_netdevice_notifier(&nfqnl_dev_notifier);
+diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
+index 5418ce5..dc29007 100644
+--- a/net/netfilter/xt_hashlimit.c
++++ b/net/netfilter/xt_hashlimit.c
+@@ -237,14 +237,14 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
+ 	hinfo->family = family;
+ 	hinfo->rnd_initialized = 0;
+ 	spin_lock_init(&hinfo->lock);
+-	hinfo->pde = create_proc_entry(minfo->name, 0,
+-				       family == AF_INET ? hashlimit_procdir4 :
+-							   hashlimit_procdir6);
++	hinfo->pde = proc_create(minfo->name, 0,
++				 family == AF_INET ? hashlimit_procdir4 :
++						     hashlimit_procdir6,
++				 &dl_file_ops);
+ 	if (!hinfo->pde) {
+ 		vfree(hinfo);
+ 		return -1;
+ 	}
+-	hinfo->pde->proc_fops = &dl_file_ops;
+ 	hinfo->pde->data = hinfo;
+ 
+ 	setup_timer(&hinfo->timer, htable_gc, (unsigned long )hinfo);
+@@ -301,14 +301,14 @@ static int htable_create(struct xt_hashlimit_mtinfo1 *minfo,
+ 	hinfo->rnd_initialized = 0;
+ 	spin_lock_init(&hinfo->lock);
+ 
+-	hinfo->pde = create_proc_entry(minfo->name, 0,
+-				       family == AF_INET ? hashlimit_procdir4 :
+-							   hashlimit_procdir6);
++	hinfo->pde = proc_create(minfo->name, 0,
++				 family == AF_INET ? hashlimit_procdir4 :
++						     hashlimit_procdir6,
++				 &dl_file_ops);
+ 	if (hinfo->pde == NULL) {
+ 		vfree(hinfo);
+ 		return -1;
+ 	}
+-	hinfo->pde->proc_fops = &dl_file_ops;
+ 	hinfo->pde->data = hinfo;
+ 
+ 	setup_timer(&hinfo->timer, htable_gc, (unsigned long)hinfo);
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index 4a31a81..063cbc5 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -598,17 +598,24 @@ static int rose_release(struct socket *sock)
+ 
+ 	if (sk == NULL) return 0;
+ 
++	sock_hold(sk);
++	sock_orphan(sk);
++	lock_sock(sk);
+ 	rose = rose_sk(sk);
+ 
+ 	switch (rose->state) {
+ 	case ROSE_STATE_0:
++		release_sock(sk);
+ 		rose_disconnect(sk, 0, -1, -1);
++		lock_sock(sk);
+ 		rose_destroy_socket(sk);
+ 		break;
+ 
+ 	case ROSE_STATE_2:
+ 		rose->neighbour->use--;
++		release_sock(sk);
+ 		rose_disconnect(sk, 0, -1, -1);
++		lock_sock(sk);
+ 		rose_destroy_socket(sk);
+ 		break;
+ 
+@@ -633,6 +640,8 @@ static int rose_release(struct socket *sock)
+ 	}
+ 
+ 	sock->sk = NULL;
++	release_sock(sk);
++	sock_put(sk);
+ 
+ 	return 0;
+ }
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 10b5c08..b741618 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -184,10 +184,22 @@ static inline int qdisc_restart(struct net_device *dev)
+ 
+ void __qdisc_run(struct net_device *dev)
+ {
+-	do {
+-		if (!qdisc_restart(dev))
++	unsigned long start_time = jiffies;
++
++	while (qdisc_restart(dev)) {
++		if (netif_queue_stopped(dev))
++			break;
++
++		/*
++		 * Postpone processing if
++		 * 1. another process needs the CPU;
++		 * 2. we've been doing it for too long.
++		 */
++		if (need_resched() || jiffies != start_time) {
++			netif_schedule(dev);
+ 			break;
+-	} while (!netif_queue_stopped(dev));
++		}
++	}
+ 
+ 	clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
+ }
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+index 41a049f..c2fef7b 100644
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -1630,6 +1630,12 @@ static inline u32 file_to_av(struct file *file)
+ 		else
+ 			av |= FILE__WRITE;
+ 	}
++	if (!av) {
++		/*
++		 * Special file opened with flags 3 for ioctl-only use.
++		 */
++		av = FILE__IOCTL;
++	}
+ 
+ 	return av;
+ }

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	(original)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	Thu Apr  3 10:34:52 2008
@@ -1,3 +1,4 @@
++ bugfix/all/patch-2.6.25-rc8-git2
 + debian/version.patch
 + debian/kernelvariables.patch
 + debian/doc-build-parallel.patch



More information about the Kernel-svn-changes mailing list